full history API implemented
[CleanReadLine.git] / Clean System Files / readLine.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <readline/readline.h>
5 #include <readline/history.h>
6
7 #include "Clean.h"
8
9 static char *cs_answer = (char *)NULL;
10 HISTORY_STATE *history_state = NULL;
11
12 //Helper functions
13 char *cleanStringToCString(CleanString s)
14 {
15 unsigned long len = CleanStringLength(s);
16 char *cs = (char *)malloc(len+1);
17 if(cs == NULL){
18 printf("malloc failed...\n");
19 exit(1);
20 }
21 memcpy(cs, CleanStringCharacters(s), len);
22 cs[len] = '\0';
23 return cs;
24 }
25
26 void cleanSetReadLineName(CleanString name)
27 {
28 rl_readline_name = cleanStringToCString(name);
29 }
30
31 //Readline functions
32 void cleanReadLine(
33 CleanString prompt, int history, CleanString *result, int *eof)
34 {
35 char *cs_prompt = cleanStringToCString(prompt);
36
37 //Get the answer and add to history if not empty
38 if(cs_answer){
39 free(cs_answer);
40 cs_answer = (char *)NULL;
41 }
42 cs_answer = readline(cs_prompt);
43 free(cs_prompt);
44 if(cs_answer && *cs_answer && history){
45 add_history(cs_answer);
46 }
47
48 *eof = 0;
49 if(!cs_answer){ //In case of an EOF
50 cs_answer = (char *)malloc(1);
51 cs_answer[0] = '\0';
52 *eof = 1;
53 }
54 CleanStringVariable(answer, strlen(cs_answer));
55 *result = (CleanString) answer;
56 memcpy(CleanStringCharacters(answer), cs_answer, strlen(cs_answer));
57 CleanStringLength(answer) = strlen(cs_answer);
58 }
59
60 //History Functions
61 //Initializing History and State Management
62 void cleanUsingHistory()
63 {
64 using_history();
65 }
66
67 void cleanGetState(int *offset, int *num, int *flags)
68 {
69 *offset = history_get_history_state()->offset;
70 *num = history_get_history_state()->length;
71 *flags = history_get_history_state()->flags;
72 }
73
74 void cleanGetHistoryItem(int num, CleanString *line, CleanString *timestamp)
75 {
76 char *cs_line = history_get_history_state()->entries[num]->line;
77 char *cs_stamp = history_get_history_state()->entries[num]->timestamp;
78
79 CleanStringVariable(cleanLine, strlen(cs_line));
80 *line = (CleanString) cleanLine;
81 memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
82 CleanStringLength(cleanLine) = strlen(cs_line);
83
84 CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
85 *timestamp = (CleanString) cleanTimestamp;
86 memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
87 CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
88 }
89
90 void cleanInitNewHistoryState(int offset, int flags, int num)
91 {
92 if(history_state != NULL){
93 //we should test if we can recursively free the object
94 free(history_state);
95 }
96 history_state = (HISTORY_STATE *)malloc(sizeof(HISTORY_STATE));
97 if(history_state == NULL){
98 printf("Not enough memory...\n");
99 exit(1);
100 }
101 HIST_ENTRY **entries = (HIST_ENTRY **)malloc(sizeof(HIST_ENTRY*)*num);
102 if(entries == NULL){
103 printf("Not enough memory...\n");
104 exit(1);
105 }
106 for(int i = 0; i<num; i++){
107 entries[i] = (HIST_ENTRY *)malloc(sizeof(HIST_ENTRY));
108 }
109 history_state->offset = offset;
110 history_state->entries = entries;
111 history_state->length = num;
112 history_state->size = num;
113 history_state->flags = 0;
114 }
115
116 void cleanSetNewHistoryEntry(int i, CleanString line, CleanString timestamp)
117 {
118 char *cs_line = cleanStringToCString(line);
119 char *cs_timestamp = cleanStringToCString(timestamp);
120 history_state->entries[i]->line = cs_line;
121 history_state->entries[i]->timestamp = cs_timestamp;
122 }
123
124 void cleanCommitSetHistory(void)
125 {
126 history_set_history_state(history_state);
127 }
128
129 //History List Management
130 void cleanAddHistoryTime(CleanString timestamp)
131 {
132 char *cs_timestamp = cleanStringToCString(timestamp);
133 add_history_time(cs_timestamp);
134 free(cs_timestamp);
135 }
136
137 void cleanAddHistory(CleanString entry)
138 {
139 char *cs_entry = cleanStringToCString(entry);
140 add_history(cs_entry);
141 free(cs_entry);
142 }
143
144 void cleanRemoveHistory(int which, CleanString *line, CleanString *timestamp)
145 {
146 HIST_ENTRY *entry = remove_history(which);
147 char *cs_line = entry->line;
148 char *cs_stamp = entry->timestamp;
149
150 CleanStringVariable(cleanLine, strlen(cs_line));
151 *line = (CleanString) cleanLine;
152 memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
153 CleanStringLength(cleanLine) = strlen(cs_line);
154
155 CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
156 *timestamp = (CleanString) cleanTimestamp;
157 memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
158 CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
159
160 histdata_t tofree = free_history_entry(entry);
161 free(tofree);
162 }
163
164 void cleanReplaceHistoryEntry(
165 int which, CleanString l, CleanString *line, CleanString *timestamp)
166 {
167 char *cs_l = cleanStringToCString(l);
168 HIST_ENTRY *entry = replace_history_entry(which, cs_l, NULL);
169 free(cs_l);
170 if(entry == NULL){
171 printf("invalid which\n");
172 }
173
174 char *cs_line = entry->line;
175 char *cs_stamp = entry->timestamp;
176
177 CleanStringVariable(cleanLine, strlen(cs_line));
178 *line = (CleanString) cleanLine;
179 memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
180 CleanStringLength(cleanLine) = strlen(cs_line);
181
182 CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
183 *timestamp = (CleanString) cleanTimestamp;
184 memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
185 CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
186
187 histdata_t tofree = free_history_entry(entry);
188 free(tofree);
189 }
190
191
192 void cleanClearHistory()
193 {
194 clear_history();
195 }
196
197 void cleanStifleHistory(int max)
198 {
199 stifle_history(max);
200 }
201
202 int cleanUnstifleHistory()
203 {
204 return unstifle_history();
205 }
206
207 int cleanHistoryIsStifled()
208 {
209 return history_is_stifled();
210 }
211
212 //Information About the History List
213 int cleanHistoryTotalBytes()
214 {
215 return history_total_bytes();
216 }
217
218 //Moving Around the History List
219 int cleanHistorySetPos(int pos)
220 {
221 return history_set_pos(pos);
222 }
223
224 void cleanPreviousHistory(
225 CleanString *line, CleanString *timestamp, int *null)
226 {
227 *null = 0;
228 HIST_ENTRY *entry = previous_history();
229 char *cs_line = "";
230 char *cs_stamp = "";
231 if(entry == NULL){
232 *null = 1;
233 } else {
234 *null = 0;
235 cs_line = entry->line;
236 cs_stamp = entry->timestamp;
237 }
238
239 CleanStringVariable(cleanLine, strlen(cs_line));
240 *line = (CleanString) cleanLine;
241 memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
242 CleanStringLength(cleanLine) = strlen(cs_line);
243
244 CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
245 *timestamp = (CleanString) cleanTimestamp;
246 memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
247 CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
248 }
249
250 void cleanNextHistory(CleanString *line, CleanString *timestamp, int *null)
251 {
252 *null = 0;
253 HIST_ENTRY *entry = next_history();
254 char *cs_line = "";
255 char *cs_stamp = "";
256 if(entry == NULL){
257 *null = 1;
258 } else {
259 *null = 0;
260 cs_line = entry->line;
261 cs_stamp = entry->timestamp;
262 }
263
264 CleanStringVariable(cleanLine, strlen(cs_line));
265 *line = (CleanString) cleanLine;
266 memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
267 CleanStringLength(cleanLine) = strlen(cs_line);
268
269 CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
270 *timestamp = (CleanString) cleanTimestamp;
271 memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
272 CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
273 }
274
275 //Searching the History List
276 int cleanHistorySearch(CleanString s, int dir)
277 {
278 char *cs_s = cleanStringToCString(s);
279 int ret = history_search(cs_s, dir);
280 free(cs_s);
281 return ret;
282 }
283
284 int cleanHistorySearchPrefix(CleanString s, int dir)
285 {
286 char *cs_s = cleanStringToCString(s);
287 int ret = history_search_prefix(cs_s, dir);
288 free(cs_s);
289 return ret;
290 }
291
292 int cleanHistorySearchPos(CleanString s, int dir, int pos)
293 {
294 char *cs_s = cleanStringToCString(s);
295 int ret = history_search_pos(cs_s, dir, pos);
296 free(cs_s);
297 return ret;
298 }
299
300 //Managing the History File
301 int cleanReadHistory(CleanString path)
302 {
303 char *cs_path = cleanStringToCString(path);
304 int errno = read_history(cs_path);
305 free(cs_path);
306 return errno == 0;
307 }
308
309 int cleanReadHistoryRange(CleanString path, int from, int to)
310 {
311 char *cs_path = cleanStringToCString(path);
312 int errno = read_history_range(cs_path, from, to);
313 free(cs_path);
314 return errno == 0;
315 }
316
317 int cleanWriteHistory(CleanString path)
318 {
319 char *cs_path = cleanStringToCString(path);
320 int errno = write_history(cs_path);
321 free(cs_path);
322 return errno == 0;
323 }
324
325 int cleanAppendHistory(int n, CleanString path)
326 {
327 char *cs_path = cleanStringToCString(path);
328 int errno = append_history(n, cs_path);
329 free(cs_path);
330 return errno == 0;
331 }
332
333 int cleanHistoryTruncateFile(CleanString path, int nlines)
334 {
335 char *cs_path = cleanStringToCString(path);
336 int errno = history_truncate_file(cs_path, nlines);
337 free(cs_path);
338 return errno == 0;
339 }