summaryrefslogtreecommitdiffstats
path: root/lib/libedit/history.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1997-06-25 08:14:24 +0000
committermsmith <msmith@FreeBSD.org>1997-06-25 08:14:24 +0000
commitf4312c45dc5fb1b4831e63087e8563fa0fa4601f (patch)
treebfe4a6c5e19e7694273d28cb1b36a820a5ebad0d /lib/libedit/history.c
parentd2cf9d630277a4d4f8601691fb1ac28b727e417e (diff)
downloadFreeBSD-src-f4312c45dc5fb1b4831e63087e8563fa0fa4601f.zip
FreeBSD-src-f4312c45dc5fb1b4831e63087e8563fa0fa4601f.tar.gz
Update libedit with changes from NetBSD. Includes history load/save,
some buffer overflow guards and some stylistic cleanups. Also adds manpages. Obtained from: NetBSD
Diffstat (limited to 'lib/libedit/history.c')
-rw-r--r--lib/libedit/history.c165
1 files changed, 124 insertions, 41 deletions
diff --git a/lib/libedit/history.c b/lib/libedit/history.c
index d60a7a9..ac9c3a9 100644
--- a/lib/libedit/history.c
+++ b/lib/libedit/history.c
@@ -51,10 +51,13 @@ static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#include <varargs.h>
#endif
+static const char hist_cookie[] = "_HiStOrY_V1_\n";
+
#include "histedit.h"
typedef const HistEvent * (*history_gfun_t) __P((ptr_t));
typedef const HistEvent * (*history_efun_t) __P((ptr_t, const char *));
+typedef void (*history_vfun_t) __P((ptr_t));
struct history {
ptr_t h_ref; /* Argument for history fcns */
@@ -63,6 +66,7 @@ struct history {
history_gfun_t h_last; /* Get the last element */
history_gfun_t h_prev; /* Get the previous element */
history_gfun_t h_curr; /* Get the current element */
+ history_vfun_t h_clear; /* Clear the history list */
history_efun_t h_enter; /* Add an element */
history_efun_t h_add; /* Append to an element */
};
@@ -72,6 +76,7 @@ struct history {
#define HPREV(h) (*(h)->h_prev)((h)->h_ref)
#define HLAST(h) (*(h)->h_last)((h)->h_ref)
#define HCURR(h) (*(h)->h_curr)((h)->h_ref)
+#define HCLEAR(h) (*(h)->h_clear)((h)->h_ref)
#define HENTER(h, str) (*(h)->h_enter)((h)->h_ref, str)
#define HADD(h, str) (*(h)->h_add)((h)->h_ref, str)
@@ -80,13 +85,9 @@ struct history {
private int history_set_num __P((History *, int));
-private int history_set_fun __P((History *, history_gfun_t,
- history_gfun_t,
- history_gfun_t,
- history_gfun_t,
- history_gfun_t,
- history_efun_t,
- history_efun_t, ptr_t));
+private int history_set_fun __P((History *, History *));
+private int history_load __P((History *, const char *));
+private int history_save __P((History *, const char *));
private const HistEvent *history_prev_event __P((History *, int));
private const HistEvent *history_next_event __P((History *, int));
private const HistEvent *history_next_string __P((History *, const char *));
@@ -120,7 +121,7 @@ private const HistEvent *history_def_curr __P((ptr_t));
private const HistEvent *history_def_enter __P((ptr_t, const char *));
private const HistEvent *history_def_add __P((ptr_t, const char *));
private void history_def_init __P((ptr_t *, int));
-private void history_def_end __P((ptr_t));
+private void history_def_clear __P((ptr_t));
private const HistEvent *history_def_insert __P((history_t *, const char *));
private void history_def_delete __P((history_t *, hentry_t *));
@@ -231,8 +232,8 @@ history_def_add(p, str)
return (history_def_enter(p, str));
len = strlen(h->cursor->ev.str) + strlen(str) + 1;
s = (char *) h_malloc(len);
- (void) strcpy(s, h->cursor->ev.str);
- (void) strcat(s, str);
+ (void)strcpy(s, h->cursor->ev.str); /* XXX strcpy is safe */
+ (void)strcat(s, str); /* XXX strcat is safe */
h_free((ptr_t) h->cursor->ev.str);
h->cursor->ev.str = s;
return &h->cursor->ev;
@@ -324,17 +325,19 @@ history_def_init(p, n)
}
-/* history_def_end():
+/* history_def_clear():
* Default history cleanup function
*/
private void
-history_def_end(p)
+history_def_clear(p)
ptr_t p;
{
history_t *h = (history_t *) p;
while (h->list.prev != &h->list)
history_def_delete(h, h->list.prev);
+ h->eventno = 0;
+ h->cur = 0;
}
/************************************************************************/
@@ -354,6 +357,7 @@ history_init()
h->h_last = history_def_last;
h->h_prev = history_def_prev;
h->h_curr = history_def_curr;
+ h->h_clear = history_def_clear;
h->h_enter = history_def_enter;
h->h_add = history_def_add;
@@ -369,7 +373,7 @@ history_end(h)
History *h;
{
if (h->h_next == history_def_next)
- history_def_end(h->h_ref);
+ history_def_clear(h->h_ref);
}
@@ -393,16 +397,13 @@ history_set_num(h, num)
* Set history functions
*/
private int
-history_set_fun(h, first, next, last, prev, curr, enter, add, ptr)
- History *h;
- history_gfun_t first, next, last, prev, curr;
- history_efun_t enter, add;
- ptr_t ptr;
+history_set_fun(h, nh)
+ History *h, *nh;
{
- if (first == NULL || next == NULL ||
- last == NULL || prev == NULL || curr == NULL ||
- enter == NULL || add == NULL ||
- ptr == NULL ) {
+ if (nh->h_first == NULL || nh->h_next == NULL ||
+ nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL ||
+ nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
+ nh->h_ref == NULL) {
if (h->h_next != history_def_next) {
history_def_init(&h->h_ref, 0);
h->h_first = history_def_first;
@@ -410,6 +411,7 @@ history_set_fun(h, first, next, last, prev, curr, enter, add, ptr)
h->h_last = history_def_last;
h->h_prev = history_def_prev;
h->h_curr = history_def_curr;
+ h->h_clear = history_def_clear;
h->h_enter = history_def_enter;
h->h_add = history_def_add;
}
@@ -417,16 +419,78 @@ history_set_fun(h, first, next, last, prev, curr, enter, add, ptr)
}
if (h->h_next == history_def_next)
- history_def_end(h->h_ref);
-
- h->h_next = next;
- h->h_first = first;
- h->h_enter = enter;
- h->h_add = add;
+ history_def_clear(h->h_ref);
+
+ h->h_first = nh->h_first;
+ h->h_next = nh->h_next;
+ h->h_last = nh->h_last;
+ h->h_prev = nh->h_prev;
+ h->h_curr = nh->h_curr;
+ h->h_clear = nh->h_clear;
+ h->h_enter = nh->h_enter;
+ h->h_add = nh->h_add;
return 0;
}
+/* history_load():
+ * History load function
+ */
+private int
+history_load(h, fname)
+ History *h;
+ const char *fname;
+{
+ FILE *fp;
+ char *line;
+ size_t sz;
+ int i = -1;
+
+ if ((fp = fopen(fname, "r")) == NULL)
+ return i;
+
+ if ((line = fgetln(fp, &sz)) == NULL)
+ goto done;
+
+ if (strncmp(line, hist_cookie, sz) != 0)
+ goto done;
+
+ for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
+ char c = line[sz];
+ line[sz] = '\0';
+ HENTER(h, line);
+ line[sz] = c;
+ }
+
+done:
+ (void) fclose(fp);
+ return i;
+}
+
+
+/* history_save():
+ * History save function
+ */
+private int
+history_save(h, fname)
+ History *h;
+ const char *fname;
+{
+ FILE *fp;
+ const HistEvent *ev;
+ int i = 0;
+
+ if ((fp = fopen(fname, "w")) == NULL)
+ return -1;
+
+ (void) fputs(hist_cookie, fp);
+ for (ev = HLAST(h); ev != NULL; ev = HPREV(h), i++)
+ (void) fprintf(fp, "%s", ev->str);
+ (void) fclose(fp);
+ return i;
+}
+
+
/* history_prev_event():
* Find the previous event, with number given
*/
@@ -509,7 +573,7 @@ history(va_alist)
va_list va;
const HistEvent *ev = NULL;
const char *str;
- static const HistEvent sev = { 0, "" };
+ static HistEvent sev = { 0, "" };
#if __STDC__
va_start(va, fun);
@@ -552,6 +616,20 @@ history(va_alist)
ev = HCURR(h);
break;
+ case H_CLEAR:
+ HCLEAR(h);
+ break;
+
+ case H_LOAD:
+ sev.num = history_load(h, va_arg(va, const char *));
+ ev = &sev;
+ break;
+
+ case H_SAVE:
+ sev.num = history_save(h, va_arg(va, const char *));
+ ev = &sev;
+ break;
+
case H_PREV_EVENT:
ev = history_prev_event(h, va_arg(va, int));
break;
@@ -569,24 +647,29 @@ history(va_alist)
break;
case H_EVENT:
- if (history_set_num(h, va_arg(va, int)) == 0)
+ if (history_set_num(h, va_arg(va, int)) == 0) {
+ sev.num = -1;
ev = &sev;
+ }
break;
case H_FUNC:
{
- history_gfun_t first = va_arg(va, history_gfun_t);
- history_gfun_t next = va_arg(va, history_gfun_t);
- history_gfun_t last = va_arg(va, history_gfun_t);
- history_gfun_t prev = va_arg(va, history_gfun_t);
- history_gfun_t curr = va_arg(va, history_gfun_t);
- history_efun_t enter = va_arg(va, history_efun_t);
- history_efun_t add = va_arg(va, history_efun_t);
- ptr_t ptr = va_arg(va, ptr_t);
-
- if (history_set_fun(h, first, next, last, prev,
- curr, enter, add, ptr) == 0)
+ History hf;
+ hf.h_ref = va_arg(va, ptr_t);
+ hf.h_first = va_arg(va, history_gfun_t);
+ hf.h_next = va_arg(va, history_gfun_t);
+ hf.h_last = va_arg(va, history_gfun_t);
+ hf.h_prev = va_arg(va, history_gfun_t);
+ hf.h_curr = va_arg(va, history_gfun_t);
+ hf.h_clear = va_arg(va, history_vfun_t);
+ hf.h_enter = va_arg(va, history_efun_t);
+ hf.h_add = va_arg(va, history_efun_t);
+
+ if (history_set_fun(h, &hf) == 0) {
+ sev.num = -1;
ev = &sev;
+ }
}
break;
OpenPOWER on IntegriCloud