fix bracket evaluation
[calc.git] / readline.c
CommitLineData
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
24170851 8#include "alloc.h"
8fbd4651 9#include "debug.h"
24170851 10#include "element.h"
8fbd4651
LM
11
12#include "readline.h"
13
14/* constants */
15
16#define HISTORY_LEN 10
17
18/* macros */
19
20/* gobal variables */
21
22char **completion_list = NULL;
23
24/* completion function */
25
26char *generator (const char *text, int state)
27{
28 static int index, len;
29 char *name;
30
31 if (!state) {
32 index = 0;
33 len = strlen(text);
34 }
35
36 while ((name = completion_list[index++])) {
37 if (strncmp (name, text, len) == 0) {
38 return strdup (name);
39 }
40 }
41
42 return NULL;
43}
44
45char **completion (const char *text, __attribute__((unused)) int start, __attribute__((unused)) int end)
46{
47 rl_attempted_completion_over = 1;
48 return rl_completion_matches (text, generator);
49}
50
51/* edit line */
52char *edit_line = NULL;
53int edit_hook ()
54{
55 static int state = 0;
56 if (edit_line) {
57 if (state == 0) {
58 state = 1;
59 } else {
60 state = 0;
61 free (edit_line);
62 edit_line = NULL;
63 }
64 }
65 return rl_insert_text (edit_line);
66}
67
68/* history management */
69
70void history ()
71{
72 HIST_ENTRY **entries = history_list ();
73 if (entries == NULL) {
74 VERBOSE (WARNING, fprintf (stdout, "no history\n"));
75 } else {
76 int i = 0;
77 while (entries[i] != NULL) {
78 printf ("%d: %s\n", history_length - i, entries[i]->line);
79 i++;
80 }
81 }
82}
83
84/* init readline */
85
86void init_read_line ()
87{
88 /* completion list*/
89 completion_list = generate_completion_list ();
90 rl_attempted_completion_function = completion;
91
92 /* edit program */
93 rl_startup_hook = edit_hook;
94
95 /* readline parameters */
96 rl_variable_bind ("blink-matching-paren", "On");
97 //rl_set_screen_size (50, 40);
98}
99
100/* read line */
101
102int read_line (char **buffer, char *prompt)
103{
104 if ((*buffer = readline (prompt)) == NULL) {
105 return 1;
106 }
107
108 /* check empty line */
109 if (strlen (*buffer) == 0) {
110 free (*buffer);
111 *buffer = NULL;
112 }
113
114 return 0;
115}
116
117/* manage history */
118
119void manage_history (char *buffer)
120{
121 /* add line into history */
122 add_history (buffer);
123 VERBOSE (INFO, fprintf (stdout, "line (%d/%d): '%s'\n",
124 where_history (), history_length, buffer));
125 if (history_length > HISTORY_LEN) {
126 HIST_ENTRY *last = remove_history (0);
127 if (last) {
128 free_history_entry (last);
129 }
130 }
131}
132
133/* clean readline */
134
135void clean_read_line (char *buffer)
136{
137 free_completion_list (completion_list);
138 if (buffer) {
139 free (buffer);
140 }
141}
24170851
LM
142
143/* generate completion list */
144
145char **generate_completion_list ()
146{
147 int i, j, l = 0;
148 char **list = (char **) callocordie (NB_OPERATORS + NB_FUNCTIONS + NB_CONSTANTS + NB_SYMBOLS + 1, sizeof (char *));
149
150 for (i = 0; i < NB_OPERATORS; i++) {
151 list[l] = strdup ((operators + i)->keyword);
152 for (j = 0; j < (int)strlen (list[l]); j++) {
153 if (list[i][j] == '\t') {
154 list[i][j] = '\0';
155 }
156 }
157 if (list[l] != NULL) {
158 l++;
159 }
160 }
161
162 for (i = 0; i < NB_FUNCTIONS; i++) {
163 list[l] = strdup ((functions + i)->keyword);
164 if (list[l] != NULL) {
165 l++;
166 }
167 }
168
169 for (i = 0; i < NB_CONSTANTS; i++) {
170 list[l] = strdup ((constants + i)->keyword);
171 if (list[l] != NULL) {
172 l++;
173 }
174 }
175
176 for (i = 0; i < NB_SYMBOLS; i++) {
177 list[l] = strdup (symbols[i]);
178 if (list[l] != NULL) {
179 l++;
180 }
181 }
182
183 return (list);
184}
185
186/* free completion list */
187
188void free_completion_list (char **list)
189{
190 int i;
191
192 if (list) {
193 for (i = 0; i < NB_OPERATORS + NB_FUNCTIONS + NB_CONSTANTS + NB_SYMBOLS + 1; i++) {
194 if (list[i] != NULL) {
195 free (list[i]);
196 }
197 }
198 free (list);
199 }
200}
201
202/* vim: set ts=4 sw=4 et: */