📄 history.c
字号:
h->cur = 0; h->max = n; h->list.next = h->list.prev = &h->list; h->list.ev.str = NULL; h->list.ev.num = 0; h->cursor = &h->list; *p = (ptr_t) h;}/* history_def_clear(): * Default history cleanup function */private voidhistory_def_clear(ptr_t p, HistEvent *ev){ history_t *h = (history_t *) p; while (h->list.prev != &h->list) history_def_delete(h, ev, h->list.prev); h->eventid = 0; h->cur = 0;}/************************************************************************//* history_init(): * Initialization function. */public History *history_init(void){ History *h = (History *) h_malloc(sizeof(History)); HistEvent ev; history_def_init(&h->h_ref, &ev, 0); h->h_ent = -1; h->h_next = history_def_next; h->h_first = history_def_first; h->h_last = history_def_last; h->h_prev = history_def_prev; h->h_curr = history_def_curr; h->h_set = history_def_set; h->h_clear = history_def_clear; h->h_enter = history_def_enter; h->h_add = history_def_add; return (h);}/* history_end(): * clean up history; */public voidhistory_end(History *h){ HistEvent ev; if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev);}/* history_setsize(): * Set history number of events */private inthistory_setsize(History *h, HistEvent *ev, int num){ if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); return (-1); } if (num < 0) { he_seterrev(ev, _HE_BAD_PARAM); return (-1); } history_def_setsize(h->h_ref, num); return (0);}/* history_getsize(): * Get number of events currently in history */private inthistory_getsize(History *h, HistEvent *ev){ int retval = 0; if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); return (-1); } retval = history_def_getsize(h->h_ref); if (retval < -1) { he_seterrev(ev, _HE_SIZE_NEGATIVE); return (-1); } ev->num = retval; return (0);}/* history_set_fun(): * Set history functions */private inthistory_set_fun(History *h, History *nh){ HistEvent ev; if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == 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, &ev, 0); h->h_first = history_def_first; h->h_next = history_def_next; h->h_last = history_def_last; h->h_prev = history_def_prev; h->h_curr = history_def_curr; h->h_set = history_def_set; h->h_clear = history_def_clear; h->h_enter = history_def_enter; h->h_add = history_def_add; } return (-1); } if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev); h->h_ent = -1; 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_set = nh->h_set; 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 inthistory_load(History *h, const char *fname){ FILE *fp; char *line; size_t sz, max_size; char *ptr; int i = -1; HistEvent ev; 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; ptr = h_malloc(max_size = 1024); for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) { char c = line[sz]; if (sz != 0 && line[sz - 1] == '\n') line[--sz] = '\0'; else line[sz] = '\0'; if (max_size < sz) { max_size = (sz + 1023) & ~1023; ptr = h_realloc(ptr, max_size); } (void) strunvis(ptr, line); line[sz] = c; HENTER(h, &ev, ptr); } h_free(ptr);done: (void) fclose(fp); return (i);}/* history_save(): * History save function */private inthistory_save(History *h, const char *fname){ FILE *fp; HistEvent ev; int i = 0, retval; size_t len, max_size; char *ptr; if ((fp = fopen(fname, "w")) == NULL) return (-1); (void) fchmod(fileno(fp), S_IRUSR|S_IWUSR); (void) fputs(hist_cookie, fp); ptr = h_malloc(max_size = 1024); for (retval = HLAST(h, &ev); retval != -1; retval = HPREV(h, &ev), i++) { len = strlen(ev.str) * 4; if (len >= max_size) { max_size = (len + 1023) & 1023; ptr = h_realloc(ptr, max_size); } (void) strvis(ptr, ev.str, VIS_WHITE); (void) fprintf(fp, "%s\n", ev.str); } h_free(ptr); (void) fclose(fp); return (i);}/* history_prev_event(): * Find the previous event, with number given */private inthistory_prev_event(History *h, HistEvent *ev, int num){ int retval; for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) if (ev->num == num) return (0); he_seterrev(ev, _HE_NOT_FOUND); return (-1);}/* history_next_event(): * Find the next event, with number given */private inthistory_next_event(History *h, HistEvent *ev, int num){ int retval; for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) if (ev->num == num) return (0); he_seterrev(ev, _HE_NOT_FOUND); return (-1);}/* history_prev_string(): * Find the previous event beginning with string */private inthistory_prev_string(History *h, HistEvent *ev, const char *str){ size_t len = strlen(str); int retval; for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) if (strncmp(str, ev->str, len) == 0) return (0); he_seterrev(ev, _HE_NOT_FOUND); return (-1);}/* history_next_string(): * Find the next event beginning with string */private inthistory_next_string(History *h, HistEvent *ev, const char *str){ size_t len = strlen(str); int retval; for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) if (strncmp(str, ev->str, len) == 0) return (0); he_seterrev(ev, _HE_NOT_FOUND); return (-1);}/* history(): * User interface to history functions. */inthistory(History *h, HistEvent *ev, int fun, ...){ va_list va; const char *str; int retval; va_start(va, fun); he_seterrev(ev, _HE_OK); switch (fun) { case H_GETSIZE: retval = history_getsize(h, ev); break; case H_SETSIZE: retval = history_setsize(h, ev, va_arg(va, int)); break; case H_ADD: str = va_arg(va, const char *); retval = HADD(h, ev, str); break; case H_ENTER: str = va_arg(va, const char *); if ((retval = HENTER(h, ev, str)) != -1) h->h_ent = ev->num; break; case H_APPEND: str = va_arg(va, const char *); if ((retval = HSET(h, ev, h->h_ent)) != -1) retval = HADD(h, ev, str); break; case H_FIRST: retval = HFIRST(h, ev); break; case H_NEXT: retval = HNEXT(h, ev); break; case H_LAST: retval = HLAST(h, ev); break; case H_PREV: retval = HPREV(h, ev); break; case H_CURR: retval = HCURR(h, ev); break; case H_SET: retval = HSET(h, ev, va_arg(va, const int)); break; case H_CLEAR: HCLEAR(h, ev); retval = 0; break; case H_LOAD: retval = history_load(h, va_arg(va, const char *)); if (retval == -1) he_seterrev(ev, _HE_HIST_READ); break; case H_SAVE: retval = history_save(h, va_arg(va, const char *)); if (retval == -1) he_seterrev(ev, _HE_HIST_WRITE); break; case H_PREV_EVENT: retval = history_prev_event(h, ev, va_arg(va, int)); break; case H_NEXT_EVENT: retval = history_next_event(h, ev, va_arg(va, int)); break; case H_PREV_STR: retval = history_prev_string(h, ev, va_arg(va, const char *)); break; case H_NEXT_STR: retval = history_next_string(h, ev, va_arg(va, const char *)); break; case H_FUNC: { History hf; hf.h_ref = va_arg(va, ptr_t); h->h_ent = -1; 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_set = va_arg(va, history_sfun_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 ((retval = history_set_fun(h, &hf)) == -1) he_seterrev(ev, _HE_PARAM_MISSING); break; } case H_END: history_end(h); retval = 0; break; default: retval = -1; he_seterrev(ev, _HE_UNKNOWN); break; } va_end(va); return (retval);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -