move all code relative to readline into separate file
[calc.git] / readline.c
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 }