#include "Clean.h"
static char *cs_answer = (char *)NULL;
+HISTORY_STATE *history_state = NULL;
-char *cleanStringToCString(CleanString s){
+//Helper functions
+char *cleanStringToCString(CleanString s)
+{
unsigned long len = CleanStringLength(s);
char *cs = (char *)malloc(len+1);
if(cs == NULL){
return cs;
}
+void cleanSetReadLineName(CleanString name)
+{
+ rl_readline_name = cleanStringToCString(name);
+}
+
+//Readline functions
+void cleanReadLine(
+ CleanString prompt, int history, CleanString *result, int *eof)
+{
+ char *cs_prompt = cleanStringToCString(prompt);
+
+ //Get the answer and add to history if not empty
+ if(cs_answer){
+ free(cs_answer);
+ cs_answer = (char *)NULL;
+ }
+ cs_answer = readline(cs_prompt);
+ free(cs_prompt);
+ if(cs_answer && *cs_answer && history){
+ add_history(cs_answer);
+ }
+
+ *eof = 0;
+ if(!cs_answer){ //In case of an EOF
+ cs_answer = (char *)malloc(1);
+ cs_answer[0] = '\0';
+ *eof = 1;
+ }
+ CleanStringVariable(answer, strlen(cs_answer));
+ *result = (CleanString) answer;
+ memcpy(CleanStringCharacters(answer), cs_answer, strlen(cs_answer));
+ CleanStringLength(answer) = strlen(cs_answer);
+}
+
+//History Functions
+//Initializing History and State Management
+void cleanUsingHistory()
+{
+ using_history();
+}
+
+void cleanGetState(int *offset, int *num, int *flags)
+{
+ *offset = history_get_history_state()->offset;
+ *num = history_get_history_state()->length;
+ *flags = history_get_history_state()->flags;
+}
+
+void cleanGetHistoryItem(int num, CleanString *line, CleanString *timestamp)
+{
+ char *cs_line = history_get_history_state()->entries[num]->line;
+ char *cs_stamp = history_get_history_state()->entries[num]->timestamp;
+
+ CleanStringVariable(cleanLine, strlen(cs_line));
+ *line = (CleanString) cleanLine;
+ memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
+ CleanStringLength(cleanLine) = strlen(cs_line);
+
+ CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
+ *timestamp = (CleanString) cleanTimestamp;
+ memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
+ CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
+}
+
+void cleanInitNewHistoryState(int offset, int flags, int num)
+{
+ if(history_state != NULL){
+ //we should test if we can recursively free the object
+ free(history_state);
+ }
+ history_state = (HISTORY_STATE *)malloc(sizeof(HISTORY_STATE));
+ if(history_state == NULL){
+ printf("Not enough memory...\n");
+ exit(1);
+ }
+ HIST_ENTRY **entries = (HIST_ENTRY **)malloc(sizeof(HIST_ENTRY*)*num);
+ if(entries == NULL){
+ printf("Not enough memory...\n");
+ exit(1);
+ }
+ for(int i = 0; i<num; i++){
+ entries[i] = (HIST_ENTRY *)malloc(sizeof(HIST_ENTRY));
+ }
+ history_state->offset = offset;
+ history_state->entries = entries;
+ history_state->length = num;
+ history_state->size = num;
+ history_state->flags = 0;
+}
+
+void cleanSetNewHistoryEntry(int i, CleanString line, CleanString timestamp)
+{
+ char *cs_line = cleanStringToCString(line);
+ char *cs_timestamp = cleanStringToCString(timestamp);
+ history_state->entries[i]->line = cs_line;
+ history_state->entries[i]->timestamp = cs_timestamp;
+}
+
+void cleanCommitSetHistory(void)
+{
+ history_set_history_state(history_state);
+}
+
+//History List Management
+void cleanAddHistoryTime(CleanString timestamp)
+{
+ char *cs_timestamp = cleanStringToCString(timestamp);
+ add_history_time(cs_timestamp);
+ free(cs_timestamp);
+}
+
+void cleanAddHistory(CleanString entry)
+{
+ char *cs_entry = cleanStringToCString(entry);
+ add_history(cs_entry);
+ free(cs_entry);
+}
+
+void cleanRemoveHistory(int which, CleanString *line, CleanString *timestamp)
+{
+ HIST_ENTRY *entry = remove_history(which);
+ char *cs_line = entry->line;
+ char *cs_stamp = entry->timestamp;
+
+ CleanStringVariable(cleanLine, strlen(cs_line));
+ *line = (CleanString) cleanLine;
+ memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
+ CleanStringLength(cleanLine) = strlen(cs_line);
+
+ CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
+ *timestamp = (CleanString) cleanTimestamp;
+ memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
+ CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
+
+ histdata_t tofree = free_history_entry(entry);
+ free(tofree);
+}
+
+void cleanReplaceHistoryEntry(
+ int which, CleanString l, CleanString *line, CleanString *timestamp)
+{
+ char *cs_l = cleanStringToCString(l);
+ HIST_ENTRY *entry = replace_history_entry(which, cs_l, NULL);
+ free(cs_l);
+ if(entry == NULL){
+ printf("invalid which\n");
+ }
+
+ char *cs_line = entry->line;
+ char *cs_stamp = entry->timestamp;
+
+ CleanStringVariable(cleanLine, strlen(cs_line));
+ *line = (CleanString) cleanLine;
+ memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
+ CleanStringLength(cleanLine) = strlen(cs_line);
+
+ CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
+ *timestamp = (CleanString) cleanTimestamp;
+ memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
+ CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
+
+ histdata_t tofree = free_history_entry(entry);
+ free(tofree);
+}
+
+
+void cleanClearHistory()
+{
+ clear_history();
+}
+
+void cleanStifleHistory(int max)
+{
+ stifle_history(max);
+}
+
+int cleanUnstifleHistory()
+{
+ return unstifle_history();
+}
+
+int cleanHistoryIsStifled()
+{
+ return history_is_stifled();
+}
+
+//Information About the History List
+int cleanHistoryTotalBytes()
+{
+ return history_total_bytes();
+}
+
+//Moving Around the History List
+int cleanHistorySetPos(int pos)
+{
+ return history_set_pos(pos);
+}
+
+void cleanPreviousHistory(
+ CleanString *line, CleanString *timestamp, int *null)
+{
+ *null = 0;
+ HIST_ENTRY *entry = previous_history();
+ char *cs_line = "";
+ char *cs_stamp = "";
+ if(entry == NULL){
+ *null = 1;
+ } else {
+ *null = 0;
+ cs_line = entry->line;
+ cs_stamp = entry->timestamp;
+ }
+
+ CleanStringVariable(cleanLine, strlen(cs_line));
+ *line = (CleanString) cleanLine;
+ memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
+ CleanStringLength(cleanLine) = strlen(cs_line);
+
+ CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
+ *timestamp = (CleanString) cleanTimestamp;
+ memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
+ CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
+}
+
+void cleanNextHistory(CleanString *line, CleanString *timestamp, int *null)
+{
+ *null = 0;
+ HIST_ENTRY *entry = next_history();
+ char *cs_line = "";
+ char *cs_stamp = "";
+ if(entry == NULL){
+ *null = 1;
+ } else {
+ *null = 0;
+ cs_line = entry->line;
+ cs_stamp = entry->timestamp;
+ }
+
+ CleanStringVariable(cleanLine, strlen(cs_line));
+ *line = (CleanString) cleanLine;
+ memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
+ CleanStringLength(cleanLine) = strlen(cs_line);
+
+ CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
+ *timestamp = (CleanString) cleanTimestamp;
+ memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
+ CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
+}
+
+//Searching the History List
+int cleanHistorySearch(CleanString s, int dir)
+{
+ char *cs_s = cleanStringToCString(s);
+ int ret = history_search(cs_s, dir);
+ free(cs_s);
+ return ret;
+}
+
+int cleanHistorySearchPrefix(CleanString s, int dir)
+{
+ char *cs_s = cleanStringToCString(s);
+ int ret = history_search_prefix(cs_s, dir);
+ free(cs_s);
+ return ret;
+}
+
+int cleanHistorySearchPos(CleanString s, int dir, int pos)
+{
+ char *cs_s = cleanStringToCString(s);
+ int ret = history_search_pos(cs_s, dir, pos);
+ free(cs_s);
+ return ret;
+}
+
+//Managing the History File
int cleanReadHistory(CleanString path)
{
char *cs_path = cleanStringToCString(path);
int errno = read_history(cs_path);
free(cs_path);
- return errno;
+ return errno == 0;
}
int cleanReadHistoryRange(CleanString path, int from, int to)
char *cs_path = cleanStringToCString(path);
int errno = read_history_range(cs_path, from, to);
free(cs_path);
- return errno;
+ return errno == 0;
}
int cleanWriteHistory(CleanString path)
char *cs_path = cleanStringToCString(path);
int errno = write_history(cs_path);
free(cs_path);
- return errno;
+ return errno == 0;
}
int cleanAppendHistory(int n, CleanString path)
char *cs_path = cleanStringToCString(path);
int errno = append_history(n, cs_path);
free(cs_path);
- return errno;
+ return errno == 0;
}
int cleanHistoryTruncateFile(CleanString path, int nlines)
char *cs_path = cleanStringToCString(path);
int errno = history_truncate_file(cs_path, nlines);
free(cs_path);
- return errno;
-}
-
-void cleanReadLine(CleanString prompt, int history, CleanString *result)
-{
- char *cs_prompt = cleanStringToCString(prompt);
-
- //Get the answer and add to history if not empty
- if(cs_answer){
- free(cs_answer);
- cs_answer = (char *)NULL;
- }
- cs_answer = readline(cs_prompt);
- free(cs_prompt);
- if(cs_answer && *cs_answer && history){
- add_history(cs_answer);
- }
-
- if(!cs_answer){
- //Transfor answer into cstring
- CleanStringVariable(answer, 1);
- *result = (CleanString) answer;
- memcpy(CleanStringCharacters(answer), "", 1);
- CleanStringLength(answer) = 1;
- } else {
- //Transfor answer into cstring
- CleanStringVariable(answer, strlen(cs_answer));
- *result = (CleanString) answer;
- memcpy(CleanStringCharacters(answer), cs_answer, strlen(cs_answer));
- CleanStringLength(answer) = strlen(cs_answer);
- }
+ return errno == 0;
}