4 #include <readline/readline.h>
5 #include <readline/history.h>
9 static char *cs_answer
= (char *)NULL
;
10 static char **cs_tokens
= (char **)NULL
;
11 static int num_tokens
= 0;
12 HISTORY_STATE
*history_state
= NULL
;
15 char *cleanStringToCString(CleanString s
)
17 unsigned long len
= CleanStringLength(s
);
18 char *cs
= (char *)malloc(len
+1);
20 printf("malloc failed...\n");
23 memcpy(cs
, CleanStringCharacters(s
), len
);
28 void cleanSetReadLineName(CleanString name
)
30 rl_readline_name
= cleanStringToCString(name
);
35 CleanString prompt
, int history
, CleanString
*result
, int *eof
)
37 char *cs_prompt
= cleanStringToCString(prompt
);
39 //Get the answer and add to history if not empty
42 cs_answer
= (char *)NULL
;
44 cs_answer
= readline(cs_prompt
);
46 if(cs_answer
&& *cs_answer
&& history
){
47 add_history(cs_answer
);
51 if(!cs_answer
){ //In case of an EOF
52 cs_answer
= (char *)malloc(1);
56 CleanStringVariable(answer
, strlen(cs_answer
));
57 *result
= (CleanString
) answer
;
58 memcpy(CleanStringCharacters(answer
), cs_answer
, strlen(cs_answer
));
59 CleanStringLength(answer
) = strlen(cs_answer
);
63 //Initializing History and State Management
64 void cleanUsingHistory()
69 void cleanGetState(int *offset
, int *num
, int *flags
)
71 *offset
= history_get_history_state()->offset
;
72 *num
= history_get_history_state()->length
;
73 *flags
= history_get_history_state()->flags
;
76 void cleanGetHistoryItem(int num
, CleanString
*line
, CleanString
*timestamp
)
78 char *cs_line
= history_get_history_state()->entries
[num
]->line
;
79 char *cs_stamp
= history_get_history_state()->entries
[num
]->timestamp
;
81 CleanStringVariable(cleanLine
, strlen(cs_line
));
82 *line
= (CleanString
) cleanLine
;
83 memcpy(CleanStringCharacters(cleanLine
), cs_line
, strlen(cs_line
));
84 CleanStringLength(cleanLine
) = strlen(cs_line
);
86 CleanStringVariable(cleanTimestamp
, strlen(cs_stamp
));
87 *timestamp
= (CleanString
) cleanTimestamp
;
88 memcpy(CleanStringCharacters(cleanTimestamp
), cs_stamp
, strlen(cs_stamp
));
89 CleanStringLength(cleanTimestamp
) = strlen(cs_stamp
);
92 void cleanInitNewHistoryState(int offset
, int flags
, int num
)
94 if(history_state
!= NULL
){
95 //we should test if we can recursively free the object
98 history_state
= (HISTORY_STATE
*)malloc(sizeof(HISTORY_STATE
));
99 if(history_state
== NULL
){
100 printf("Not enough memory...\n");
103 HIST_ENTRY
**entries
= (HIST_ENTRY
**)malloc(sizeof(HIST_ENTRY
*)*num
);
105 printf("Not enough memory...\n");
108 for(int i
= 0; i
<num
; i
++){
109 entries
[i
] = (HIST_ENTRY
*)malloc(sizeof(HIST_ENTRY
));
111 history_state
->offset
= offset
;
112 history_state
->entries
= entries
;
113 history_state
->length
= num
;
114 history_state
->size
= num
;
115 history_state
->flags
= 0;
118 void cleanSetNewHistoryEntry(int i
, CleanString line
, CleanString timestamp
)
120 char *cs_line
= cleanStringToCString(line
);
121 char *cs_timestamp
= cleanStringToCString(timestamp
);
122 history_state
->entries
[i
]->line
= cs_line
;
123 history_state
->entries
[i
]->timestamp
= cs_timestamp
;
126 void cleanCommitSetHistory(void)
128 history_set_history_state(history_state
);
131 //History List Management
132 void cleanAddHistoryTime(CleanString timestamp
)
134 char *cs_timestamp
= cleanStringToCString(timestamp
);
135 add_history_time(cs_timestamp
);
139 void cleanAddHistory(CleanString entry
)
141 char *cs_entry
= cleanStringToCString(entry
);
142 add_history(cs_entry
);
146 void cleanRemoveHistory(int which
, CleanString
*line
, CleanString
*timestamp
)
148 HIST_ENTRY
*entry
= remove_history(which
);
149 char *cs_line
= entry
->line
;
150 char *cs_stamp
= entry
->timestamp
;
152 CleanStringVariable(cleanLine
, strlen(cs_line
));
153 *line
= (CleanString
) cleanLine
;
154 memcpy(CleanStringCharacters(cleanLine
), cs_line
, strlen(cs_line
));
155 CleanStringLength(cleanLine
) = strlen(cs_line
);
157 CleanStringVariable(cleanTimestamp
, strlen(cs_stamp
));
158 *timestamp
= (CleanString
) cleanTimestamp
;
159 memcpy(CleanStringCharacters(cleanTimestamp
), cs_stamp
, strlen(cs_stamp
));
160 CleanStringLength(cleanTimestamp
) = strlen(cs_stamp
);
162 histdata_t tofree
= free_history_entry(entry
);
166 void cleanReplaceHistoryEntry(
167 int which
, CleanString l
, CleanString
*line
, CleanString
*timestamp
)
169 char *cs_l
= cleanStringToCString(l
);
170 HIST_ENTRY
*entry
= replace_history_entry(which
, cs_l
, NULL
);
173 printf("invalid which\n");
176 char *cs_line
= entry
->line
;
177 char *cs_stamp
= entry
->timestamp
;
179 CleanStringVariable(cleanLine
, strlen(cs_line
));
180 *line
= (CleanString
) cleanLine
;
181 memcpy(CleanStringCharacters(cleanLine
), cs_line
, strlen(cs_line
));
182 CleanStringLength(cleanLine
) = strlen(cs_line
);
184 CleanStringVariable(cleanTimestamp
, strlen(cs_stamp
));
185 *timestamp
= (CleanString
) cleanTimestamp
;
186 memcpy(CleanStringCharacters(cleanTimestamp
), cs_stamp
, strlen(cs_stamp
));
187 CleanStringLength(cleanTimestamp
) = strlen(cs_stamp
);
189 histdata_t tofree
= free_history_entry(entry
);
194 void cleanClearHistory()
199 void cleanStifleHistory(int max
)
204 int cleanUnstifleHistory()
206 return unstifle_history();
209 int cleanHistoryIsStifled()
211 return history_is_stifled();
214 //Information About the History List
215 int cleanHistoryTotalBytes()
217 return history_total_bytes();
220 //Moving Around the History List
221 int cleanHistorySetPos(int pos
)
223 return history_set_pos(pos
);
226 void cleanPreviousHistory(
227 CleanString
*line
, CleanString
*timestamp
, int *null
)
230 HIST_ENTRY
*entry
= previous_history();
237 cs_line
= entry
->line
;
238 cs_stamp
= entry
->timestamp
;
241 CleanStringVariable(cleanLine
, strlen(cs_line
));
242 *line
= (CleanString
) cleanLine
;
243 memcpy(CleanStringCharacters(cleanLine
), cs_line
, strlen(cs_line
));
244 CleanStringLength(cleanLine
) = strlen(cs_line
);
246 CleanStringVariable(cleanTimestamp
, strlen(cs_stamp
));
247 *timestamp
= (CleanString
) cleanTimestamp
;
248 memcpy(CleanStringCharacters(cleanTimestamp
), cs_stamp
, strlen(cs_stamp
));
249 CleanStringLength(cleanTimestamp
) = strlen(cs_stamp
);
252 void cleanNextHistory(CleanString
*line
, CleanString
*timestamp
, int *null
)
255 HIST_ENTRY
*entry
= next_history();
262 cs_line
= entry
->line
;
263 cs_stamp
= entry
->timestamp
;
266 CleanStringVariable(cleanLine
, strlen(cs_line
));
267 *line
= (CleanString
) cleanLine
;
268 memcpy(CleanStringCharacters(cleanLine
), cs_line
, strlen(cs_line
));
269 CleanStringLength(cleanLine
) = strlen(cs_line
);
271 CleanStringVariable(cleanTimestamp
, strlen(cs_stamp
));
272 *timestamp
= (CleanString
) cleanTimestamp
;
273 memcpy(CleanStringCharacters(cleanTimestamp
), cs_stamp
, strlen(cs_stamp
));
274 CleanStringLength(cleanTimestamp
) = strlen(cs_stamp
);
277 //Searching the History List
278 int cleanHistorySearch(CleanString s
, int dir
)
280 char *cs_s
= cleanStringToCString(s
);
281 int ret
= history_search(cs_s
, dir
);
286 int cleanHistorySearchPrefix(CleanString s
, int dir
)
288 char *cs_s
= cleanStringToCString(s
);
289 int ret
= history_search_prefix(cs_s
, dir
);
294 int cleanHistorySearchPos(CleanString s
, int dir
, int pos
)
296 char *cs_s
= cleanStringToCString(s
);
297 int ret
= history_search_pos(cs_s
, dir
, pos
);
302 //Managing the History File
303 int cleanReadHistory(CleanString path
)
305 char *cs_path
= cleanStringToCString(path
);
306 int errno
= read_history(cs_path
);
311 int cleanReadHistoryRange(CleanString path
, int from
, int to
)
313 char *cs_path
= cleanStringToCString(path
);
314 int errno
= read_history_range(cs_path
, from
, to
);
319 int cleanWriteHistory(CleanString path
)
321 char *cs_path
= cleanStringToCString(path
);
322 int errno
= write_history(cs_path
);
327 int cleanAppendHistory(int n
, CleanString path
)
329 char *cs_path
= cleanStringToCString(path
);
330 int errno
= append_history(n
, cs_path
);
335 int cleanHistoryTruncateFile(CleanString path
, int nlines
)
337 char *cs_path
= cleanStringToCString(path
);
338 int errno
= history_truncate_file(cs_path
, nlines
);
344 void cleanHistoryExpand(CleanString string
, CleanString
*output
, int *ret
)
347 char *cs_string
= cleanStringToCString(string
);
348 *ret
= history_expand(cs_string
, &cs_output
);
350 CleanStringVariable(cleanOutput
, strlen(cs_output
));
351 *output
= (CleanString
) cleanOutput
;
352 memcpy(CleanStringCharacters(cleanOutput
), cs_output
, strlen(cs_output
));
353 CleanStringLength(cleanOutput
) = strlen(cs_output
);
358 void cleanGetHistoryEvent(
359 CleanString string
, int qchar
, int cindex
, CleanString
*output
,
360 int *retcindex
, int *null
)
362 char *cs_string
= cleanStringToCString(string
);
363 char *cs_output
= get_history_event(cs_string
, &cindex
, qchar
);
365 if(cs_output
== NULL
){
372 CleanStringVariable(cleanOutput
, strlen(cs_output
));
373 *output
= (CleanString
) cleanOutput
;
374 memcpy(CleanStringCharacters(cleanOutput
), cs_output
, strlen(cs_output
));
375 CleanStringLength(cleanOutput
) = strlen(cs_output
);
383 int cleanHistoryTokenizeInit(CleanString string
)
386 for(int i
= 0; i
<num_tokens
; i
++){
391 char *cs_string
= cleanStringToCString(string
);
392 cs_tokens
= history_tokenize(cs_string
);
396 for(; cs_tokens
[num_tokens
]; num_tokens
++);
400 void cleanHistoryTokenizeItem(int num
, CleanString
*output
)
402 char *cs_output
= cs_tokens
[num
];
403 CleanStringVariable(cleanOutput
, strlen(cs_output
));
404 *output
= (CleanString
) cleanOutput
;
405 memcpy(CleanStringCharacters(cleanOutput
), cs_output
, strlen(cs_output
));
406 CleanStringLength(cleanOutput
) = strlen(cs_output
);
409 void cleanHistoryArgExtract(
410 int first
, int last
, CleanString string
, CleanString
*output
, int *null
)
412 char *cs_string
= cleanStringToCString(string
);
413 char *cs_output
= history_arg_extract(first
, last
, cs_string
);
414 if(cs_output
== NULL
){
421 CleanStringVariable(cleanOutput
, strlen(cs_output
));
422 *output
= (CleanString
) cleanOutput
;
423 memcpy(CleanStringCharacters(cleanOutput
), cs_output
, strlen(cs_output
));
424 CleanStringLength(cleanOutput
) = strlen(cs_output
);