126 lines
No EOL
2 KiB
C
126 lines
No EOL
2 KiB
C
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);
|
|
} |