bea7de60e5c55133d3d21367116757fdda5eb56f
[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 char *cleanStringToCString(CleanString s){
13 unsigned long len = CleanStringLength(s);
14 char *cs = (char *)malloc(len+1);
15 if(cs == NULL){
16 printf("malloc failed...\n");
17 exit(1);
18 }
19 memcpy(cs, CleanStringCharacters(s), len);
20 cs[len] = '\0';
21 return cs;
22 }
23
24 void cleanReadLine(CleanString prompt, int history, CleanString *result)
25 {
26 char *cs_prompt = cleanStringToCString(prompt);
27
28 //Get the answer and add to history if not empty
29 if(cs_answer){
30 free(cs_answer);
31 cs_answer = (char *)NULL;
32 }
33 cs_answer = readline(cs_prompt);
34 free(cs_prompt);
35 if(cs_answer && *cs_answer && history){
36 add_history(cs_answer);
37 }
38
39 if(!cs_answer){ //In case of an EOF
40 CleanStringVariable(answer, 1);
41 *result = (CleanString) answer;
42 memcpy(CleanStringCharacters(answer), "", 1);
43 CleanStringLength(answer) = 1;
44 } else { //In case of a proper response
45 CleanStringVariable(answer, strlen(cs_answer));
46 *result = (CleanString) answer;
47 memcpy(CleanStringCharacters(answer), cs_answer, strlen(cs_answer));
48 CleanStringLength(answer) = strlen(cs_answer);
49 }
50 }
51
52 void cleanSetReadLineName(CleanString name){
53 rl_readline_name = cleanStringToCString(name);
54 }
55
56 void cleanUsingHistory(){
57 using_history();
58 }
59
60 void cleanGetState(int *offset, int *num, int *flags){
61 *offset = history_get_history_state()->offset;
62 *num = history_get_history_state()->length;
63 *flags = history_get_history_state()->flags;
64 }
65
66 void cleanGetHistoryItem(int num, CleanString *line, CleanString *timestamp){
67 char *cs_line = history_get_history_state()->entries[num]->line;
68 char *cs_stamp = history_get_history_state()->entries[num]->timestamp;
69
70 CleanStringVariable(cleanLine, strlen(cs_line));
71 *line = (CleanString) cleanLine;
72 memcpy(CleanStringCharacters(cleanLine), cs_line, strlen(cs_line));
73 CleanStringLength(cleanLine) = strlen(cs_line);
74
75 CleanStringVariable(cleanTimestamp, strlen(cs_stamp));
76 *timestamp = (CleanString) cleanTimestamp;
77 memcpy(CleanStringCharacters(cleanTimestamp), cs_stamp, strlen(cs_stamp));
78 CleanStringLength(cleanTimestamp) = strlen(cs_stamp);
79 }
80
81 void cleanInitNewHistoryState(int offset, int flags, int num){
82 if(history_state != NULL){
83 //we should test if we can recursively free the object
84 free(history_state);
85 }
86 history_state = (HISTORY_STATE *)malloc(sizeof(HISTORY_STATE));
87 if(history_state == NULL){
88 printf("Not enough memory...\n");
89 exit(1);
90 }
91 HIST_ENTRY **entries = (HIST_ENTRY **)malloc(sizeof(HIST_ENTRY*)*num);
92 if(entries == NULL){
93 printf("Not enough memory...\n");
94 exit(1);
95 }
96 for(int i = 0; i<num; i++){
97 entries[i] = (HIST_ENTRY *)malloc(sizeof(HIST_ENTRY));
98 }
99 history_state->offset = offset;
100 history_state->entries = entries;
101 history_state->length = num;
102 history_state->size = num;
103 history_state->flags = 0;
104 }
105
106 void cleanSetNewHistoryEntry(int i, CleanString line, CleanString timestamp){
107 char *cs_line = cleanStringToCString(line);
108 char *cs_timestamp = cleanStringToCString(timestamp);
109 history_state->entries[i]->line = cs_line;
110 history_state->entries[i]->timestamp = cs_timestamp;
111 }
112
113 void cleanCommitSetHistory(void){
114 history_set_history_state(history_state);
115 }
116
117 void cleanAddHistory(CleanString entry){
118 char *cs_entry = cleanStringToCString(entry);
119 add_history(cs_entry);
120 free(cs_entry);
121 }
122
123 void cleanClearHistory(){
124 clear_history();
125 }
126
127 int cleanHistorySearch(CleanString s, int dir){
128 char *cs_s = cleanStringToCString(s);
129 int ret = history_search(cs_s, dir);
130 free(cs_s);
131 return ret;
132 }
133
134 int cleanHistorySearchPrefix(CleanString s, int dir){
135 char *cs_s = cleanStringToCString(s);
136 int ret = history_search_prefix(cs_s, dir);
137 free(cs_s);
138 return ret;
139 }
140
141 int cleanHistorySearchPos(CleanString s, int dir, int pos){
142 char *cs_s = cleanStringToCString(s);
143 int ret = history_search_pos(cs_s, dir, pos);
144 free(cs_s);
145 return ret;
146 }
147
148 int cleanReadHistory(CleanString path)
149 {
150 char *cs_path = cleanStringToCString(path);
151 int errno = read_history(cs_path);
152 free(cs_path);
153 return errno;
154 }
155
156 int cleanReadHistoryRange(CleanString path, int from, int to)
157 {
158 char *cs_path = cleanStringToCString(path);
159 int errno = read_history_range(cs_path, from, to);
160 free(cs_path);
161 return errno;
162 }
163
164 int cleanWriteHistory(CleanString path)
165 {
166 char *cs_path = cleanStringToCString(path);
167 int errno = write_history(cs_path);
168 free(cs_path);
169 return errno;
170 }
171
172 int cleanAppendHistory(int n, CleanString path)
173 {
174 char *cs_path = cleanStringToCString(path);
175 int errno = append_history(n, cs_path);
176 free(cs_path);
177 return errno;
178 }
179
180 int cleanHistoryTruncateFile(CleanString path, int nlines)
181 {
182 char *cs_path = cleanStringToCString(path);
183 int errno = history_truncate_file(cs_path, nlines);
184 free(cs_path);
185 return errno;
186 }