Commit | Line | Data |
---|---|---|
8fbd4651 LM |
1 | #include <malloc.h> |
2 | #include <stdio.h> | |
3 | #include <string.h> | |
4 | ||
5 | #include <readline/readline.h> | |
6 | #include <readline/history.h> | |
7 | ||
8 | #include "debug.h" | |
9 | #include "parser.h" | |
10 | ||
11 | #include "readline.h" | |
12 | ||
13 | /* constants */ | |
14 | ||
15 | #define HISTORY_LEN 10 | |
16 | ||
17 | /* macros */ | |
18 | ||
19 | /* gobal variables */ | |
20 | ||
21 | char **completion_list = NULL; | |
22 | ||
23 | /* completion function */ | |
24 | ||
25 | char *generator (const char *text, int state) | |
26 | { | |
27 | static int index, len; | |
28 | char *name; | |
29 | ||
30 | if (!state) { | |
31 | index = 0; | |
32 | len = strlen(text); | |
33 | } | |
34 | ||
35 | while ((name = completion_list[index++])) { | |
36 | if (strncmp (name, text, len) == 0) { | |
37 | return strdup (name); | |
38 | } | |
39 | } | |
40 | ||
41 | return NULL; | |
42 | } | |
43 | ||
44 | char **completion (const char *text, __attribute__((unused)) int start, __attribute__((unused)) int end) | |
45 | { | |
46 | rl_attempted_completion_over = 1; | |
47 | return rl_completion_matches (text, generator); | |
48 | } | |
49 | ||
50 | /* edit line */ | |
51 | char *edit_line = NULL; | |
52 | int edit_hook () | |
53 | { | |
54 | static int state = 0; | |
55 | if (edit_line) { | |
56 | if (state == 0) { | |
57 | state = 1; | |
58 | } else { | |
59 | state = 0; | |
60 | free (edit_line); | |
61 | edit_line = NULL; | |
62 | } | |
63 | } | |
64 | return rl_insert_text (edit_line); | |
65 | } | |
66 | ||
67 | /* history management */ | |
68 | ||
69 | void history () | |
70 | { | |
71 | HIST_ENTRY **entries = history_list (); | |
72 | if (entries == NULL) { | |
73 | VERBOSE (WARNING, fprintf (stdout, "no history\n")); | |
74 | } else { | |
75 | int i = 0; | |
76 | while (entries[i] != NULL) { | |
77 | printf ("%d: %s\n", history_length - i, entries[i]->line); | |
78 | i++; | |
79 | } | |
80 | } | |
81 | } | |
82 | ||
83 | /* init readline */ | |
84 | ||
85 | void init_read_line () | |
86 | { | |
87 | /* completion list*/ | |
88 | completion_list = generate_completion_list (); | |
89 | rl_attempted_completion_function = completion; | |
90 | ||
91 | /* edit program */ | |
92 | rl_startup_hook = edit_hook; | |
93 | ||
94 | /* readline parameters */ | |
95 | rl_variable_bind ("blink-matching-paren", "On"); | |
96 | //rl_set_screen_size (50, 40); | |
97 | } | |
98 | ||
99 | /* read line */ | |
100 | ||
101 | int read_line (char **buffer, char *prompt) | |
102 | { | |
103 | if ((*buffer = readline (prompt)) == NULL) { | |
104 | return 1; | |
105 | } | |
106 | ||
107 | /* check empty line */ | |
108 | if (strlen (*buffer) == 0) { | |
109 | free (*buffer); | |
110 | *buffer = NULL; | |
111 | } | |
112 | ||
113 | return 0; | |
114 | } | |
115 | ||
116 | /* manage history */ | |
117 | ||
118 | void manage_history (char *buffer) | |
119 | { | |
120 | /* add line into history */ | |
121 | add_history (buffer); | |
122 | VERBOSE (INFO, fprintf (stdout, "line (%d/%d): '%s'\n", | |
123 | where_history (), history_length, buffer)); | |
124 | if (history_length > HISTORY_LEN) { | |
125 | HIST_ENTRY *last = remove_history (0); | |
126 | if (last) { | |
127 | free_history_entry (last); | |
128 | } | |
129 | } | |
130 | } | |
131 | ||
132 | /* clean readline */ | |
133 | ||
134 | void clean_read_line (char *buffer) | |
135 | { | |
136 | free_completion_list (completion_list); | |
137 | if (buffer) { | |
138 | free (buffer); | |
139 | } | |
140 | } |