Ada: merge to latest baseline
[jackhill/mal.git] / c / readline.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4
5 #if USE_READLINE
6 #include <readline/readline.h>
7 #include <readline/history.h>
8 #include <readline/tilde.h>
9 #else
10 #include <editline/readline.h>
11 #include <editline/history.h>
12 #endif
13
14 int history_loaded = 0;
15
16 char HISTORY_FILE[] = "~/.mal-history";
17
18 int load_history() {
19 if (history_loaded) { return 0; }
20 int ret;
21 char *hf = tilde_expand(HISTORY_FILE);
22 if (access(hf, F_OK) != -1) {
23 // TODO: check if file exists first, use non-static path
24 #if USE_READLINE
25 ret = read_history(hf);
26 #else
27 FILE *fp = fopen(hf, "r");
28 char *line = malloc(80); // getline reallocs as necessary
29 size_t sz = 80;
30 while ((ret = getline(&line, &sz, fp)) > 0) {
31 add_history(line); // Add line to in-memory history
32 }
33 free(line);
34 fclose(fp);
35 #endif
36 history_loaded = 1;
37 }
38 free(hf);
39 }
40
41 int append_to_history() {
42 char *hf = tilde_expand(HISTORY_FILE);
43 #ifdef USE_READLINE
44 append_history(1, hf);
45 #else
46 HIST_ENTRY *he = history_get(history_length-1);
47 FILE *fp = fopen(hf, "a");
48 if (fp) {
49 fprintf(fp, "%s\n", he->line);
50 fclose(fp);
51 }
52 #endif
53 free(hf);
54 }
55
56
57 // line must be freed by caller
58 char *_readline (char prompt[]) {
59 char *line;
60
61 load_history();
62
63 line = readline(prompt);
64 if (!line) return NULL; // EOF
65 add_history(line); // Add input to in-memory history
66
67 append_to_history(); // Flush new line of history to disk
68
69 return line;
70 }
71