static char *histfile; static char **history; static size_t histsz, histpos; static void loadhistory(void) { FILE *fp = NULL; static size_t cap = 0; size_t llen; char *line; if (!histfile) { return; } fp = fopen(histfile, "r"); if (!fp) { return; } for (;;) { line = NULL; llen = 0; if (-1 == getline(&line, &llen, fp)) { if (ferror(fp)) { die("failed to read history"); } free(line); break; } if (cap == histsz) { cap += 64 * sizeof(char*); history = realloc(history, cap); if (!history) { die("failed to realloc memory"); } } strtok(line, "\n"); history[histsz] = line; histsz++; } histpos = histsz; if (fclose(fp)) { die("failed to close file %s", histfile); } } static void navhistory(int dir) { static char def[BUFSIZ]; char *p = NULL; size_t len = 0; if (!history || histpos + 1 == 0) return; if (histsz == histpos) { strncpy(def, text, sizeof(def)); } switch(dir) { case 1: if (histpos < histsz - 1) { p = history[++histpos]; } else if (histpos == histsz - 1) { p = def; histpos++; } break; case -1: if (histpos > 0) { p = history[--histpos]; } break; } if (p == NULL) { return; } len = MIN(strlen(p), BUFSIZ - 1); strncpy(text, p, len); text[len] = '\0'; cursor = len; match(); } static void savehistory(char *input) { unsigned int i; FILE *fp; if (!histfile || 0 == maxhist || 0 == strlen(input)) { goto out; } fp = fopen(histfile, "w"); if (!fp) { die("failed to open %s", histfile); } for (i = histsz < maxhist ? 0 : histsz - maxhist; i < histsz; i++) { if (0 >= fprintf(fp, "%s\n", history[i])) { die("failed to write to %s", histfile); } } if (histsz == 0 || !histnodup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) { /* TODO */ if (0 >= fputs(input, fp)) { die("failed to write to %s", histfile); } } if (fclose(fp)) { die("failed to close file %s", histfile); } out: for (i = 0; i < histsz; i++) { free(history[i]); } free(history); }