Rewritten to drop the readline dependency.
Showing
1 changed file
with
117 additions
and
97 deletions
... | @@ -29,9 +29,12 @@ | ... | @@ -29,9 +29,12 @@ |
29 | #include <stdlib.h> | 29 | #include <stdlib.h> |
30 | #include <termios.h> | 30 | #include <termios.h> |
31 | #include <signal.h> | 31 | #include <signal.h> |
32 | #include <ctype.h> | ||
32 | 33 | ||
33 | #include <readline/readline.h> | 34 | #ifdef WITH_READLINE |
34 | #include <readline/history.h> | 35 | # include <readline/readline.h> |
36 | # include <readline/history.h> | ||
37 | #endif | ||
35 | 38 | ||
36 | #include <mailutils/pop3.h> | 39 | #include <mailutils/pop3.h> |
37 | #include <mailutils/iterator.h> | 40 | #include <mailutils/iterator.h> |
... | @@ -68,7 +71,6 @@ int com_verbose (char *); | ... | @@ -68,7 +71,6 @@ int com_verbose (char *); |
68 | void initialize_readline (void); | 71 | void initialize_readline (void); |
69 | char *stripwhite (char *); | 72 | char *stripwhite (char *); |
70 | COMMAND *find_command (char *); | 73 | COMMAND *find_command (char *); |
71 | void *xmalloc (size_t); | ||
72 | char *dupstr (const char *); | 74 | char *dupstr (const char *); |
73 | int execute_line (char *); | 75 | int execute_line (char *); |
74 | int valid_argument (const char *, char *); | 76 | int valid_argument (const char *, char *); |
... | @@ -110,30 +112,123 @@ int verbose; | ... | @@ -110,30 +112,123 @@ int verbose; |
110 | /* When non-zero, this global means the user is done using this program. */ | 112 | /* When non-zero, this global means the user is done using this program. */ |
111 | int done; | 113 | int done; |
112 | 114 | ||
113 | #if 0 | 115 | char * |
114 | void * | 116 | dupstr (const char *s) |
115 | xmalloc (size_t size) | ||
116 | { | 117 | { |
117 | void *m = malloc (size); | 118 | char *r; |
118 | if (!m) | 119 | |
120 | r = malloc (strlen (s) + 1); | ||
121 | if (!r) | ||
119 | { | 122 | { |
120 | fprintf (stderr, "Memory exhausted\n"); | 123 | fprintf (stderr, "Memory exhausted\n"); |
121 | exit (1); | 124 | exit (1); |
122 | } | 125 | } |
123 | return m; | 126 | strcpy (r, s); |
127 | return r; | ||
128 | } | ||
129 | |||
130 | |||
131 | #ifdef WITH_READLINE | ||
132 | /* Interface to Readline Completion */ | ||
133 | |||
134 | char *command_generator (const char *, int); | ||
135 | char **pop_completion (char *, int, int); | ||
136 | |||
137 | /* Tell the GNU Readline library how to complete. We want to try to complete | ||
138 | on command names if this is the first word in the line, or on filenames | ||
139 | if not. */ | ||
140 | void | ||
141 | initialize_readline () | ||
142 | { | ||
143 | /* Allow conditional parsing of the ~/.inputrc file. */ | ||
144 | rl_readline_name = (char *)"pop3"; | ||
145 | |||
146 | /* Tell the completer that we want a crack first. */ | ||
147 | rl_attempted_completion_function = (CPPFunction *)pop_completion; | ||
148 | } | ||
149 | |||
150 | /* Attempt to complete on the contents of TEXT. START and END bound the | ||
151 | region of rl_line_buffer that contains the word to complete. TEXT is | ||
152 | the word to complete. We can use the entire contents of rl_line_buffer | ||
153 | in case we want to do some simple parsing. Return the array of matches, | ||
154 | or NULL if there aren't any. */ | ||
155 | char ** | ||
156 | pop_completion (char *text, int start, int end) | ||
157 | { | ||
158 | char **matches; | ||
159 | |||
160 | (void)end; | ||
161 | matches = (char **)NULL; | ||
162 | |||
163 | /* If this word is at the start of the line, then it is a command | ||
164 | to complete. Otherwise it is the name of a file in the current | ||
165 | directory. */ | ||
166 | if (start == 0) | ||
167 | matches = completion_matches (text, command_generator); | ||
168 | |||
169 | return (matches); | ||
124 | } | 170 | } |
125 | #endif | ||
126 | 171 | ||
172 | /* Generator function for command completion. STATE lets us know whether | ||
173 | to start from scratch; without any state (i.e. STATE == 0), then we | ||
174 | start at the top of the list. */ | ||
127 | char * | 175 | char * |
128 | dupstr (const char *s) | 176 | command_generator (const char *text, int state) |
129 | { | 177 | { |
130 | char *r; | 178 | static int list_index, len; |
179 | const char *name; | ||
131 | 180 | ||
132 | r = xmalloc (strlen (s) + 1); | 181 | /* If this is a new word to complete, initialize now. This includes |
133 | strcpy (r, s); | 182 | saving the length of TEXT for efficiency, and initializing the index |
134 | return r; | 183 | variable to 0. */ |
184 | if (!state) | ||
185 | { | ||
186 | list_index = 0; | ||
187 | len = strlen (text); | ||
188 | } | ||
189 | |||
190 | /* Return the next name which partially matches from the command list. */ | ||
191 | while ((name = commands[list_index].name)) | ||
192 | { | ||
193 | list_index++; | ||
194 | |||
195 | if (strncmp (name, text, len) == 0) | ||
196 | return (dupstr(name)); | ||
197 | } | ||
198 | |||
199 | /* If no names matched, then return NULL. */ | ||
200 | return ((char *)NULL); | ||
201 | } | ||
202 | |||
203 | #else | ||
204 | void | ||
205 | initialize_readline () | ||
206 | { | ||
135 | } | 207 | } |
136 | 208 | ||
209 | char * | ||
210 | readline (char *prompt) | ||
211 | { | ||
212 | char buf[255]; | ||
213 | |||
214 | if (prompt) | ||
215 | { | ||
216 | printf ("%s", prompt); | ||
217 | fflush (stdout); | ||
218 | } | ||
219 | |||
220 | if (!fgets (buf, sizeof (buf), stdin)) | ||
221 | return NULL; | ||
222 | return strdup (buf); | ||
223 | } | ||
224 | |||
225 | void | ||
226 | add_history (const char *s) | ||
227 | { | ||
228 | } | ||
229 | #endif | ||
230 | |||
231 | |||
137 | int | 232 | int |
138 | main (int argc, char **argv) | 233 | main (int argc, char **argv) |
139 | { | 234 | { |
... | @@ -186,11 +281,11 @@ execute_line (char *line) | ... | @@ -186,11 +281,11 @@ execute_line (char *line) |
186 | 281 | ||
187 | /* Isolate the command word. */ | 282 | /* Isolate the command word. */ |
188 | i = 0; | 283 | i = 0; |
189 | while (line[i] && whitespace (line[i])) | 284 | while (line[i] && isspace (line[i])) |
190 | i++; | 285 | i++; |
191 | word = line + i; | 286 | word = line + i; |
192 | 287 | ||
193 | while (line[i] && !whitespace (line[i])) | 288 | while (line[i] && !isspace (line[i])) |
194 | i++; | 289 | i++; |
195 | 290 | ||
196 | if (line[i]) | 291 | if (line[i]) |
... | @@ -205,7 +300,7 @@ execute_line (char *line) | ... | @@ -205,7 +300,7 @@ execute_line (char *line) |
205 | } | 300 | } |
206 | 301 | ||
207 | /* Get argument to command, if any. */ | 302 | /* Get argument to command, if any. */ |
208 | while (whitespace (line[i])) | 303 | while (isspace (line[i])) |
209 | i++; | 304 | i++; |
210 | 305 | ||
211 | word = line + i; | 306 | word = line + i; |
... | @@ -236,95 +331,20 @@ stripwhite (char *string) | ... | @@ -236,95 +331,20 @@ stripwhite (char *string) |
236 | { | 331 | { |
237 | register char *s, *t; | 332 | register char *s, *t; |
238 | 333 | ||
239 | for (s = string; whitespace (*s); s++) | 334 | for (s = string; isspace (*s); s++) |
240 | ; | 335 | ; |
241 | 336 | ||
242 | if (*s == 0) | 337 | if (*s == 0) |
243 | return (s); | 338 | return (s); |
244 | 339 | ||
245 | t = s + strlen (s) - 1; | 340 | t = s + strlen (s) - 1; |
246 | while (t > s && whitespace (*t)) | 341 | while (t > s && isspace (*t)) |
247 | t--; | 342 | t--; |
248 | *++t = '\0'; | 343 | *++t = '\0'; |
249 | 344 | ||
250 | return s; | 345 | return s; |
251 | } | 346 | } |
252 | 347 | ||
253 | /* **************************************************************** */ | ||
254 | /* */ | ||
255 | /* Interface to Readline Completion */ | ||
256 | /* */ | ||
257 | /* **************************************************************** */ | ||
258 | |||
259 | char *command_generator (const char *, int); | ||
260 | char **pop_completion (char *, int, int); | ||
261 | |||
262 | /* Tell the GNU Readline library how to complete. We want to try to complete | ||
263 | on command names if this is the first word in the line, or on filenames | ||
264 | if not. */ | ||
265 | void | ||
266 | initialize_readline () | ||
267 | { | ||
268 | /* Allow conditional parsing of the ~/.inputrc file. */ | ||
269 | rl_readline_name = (char *)"pop3"; | ||
270 | |||
271 | /* Tell the completer that we want a crack first. */ | ||
272 | rl_attempted_completion_function = (CPPFunction *)pop_completion; | ||
273 | } | ||
274 | |||
275 | /* Attempt to complete on the contents of TEXT. START and END bound the | ||
276 | region of rl_line_buffer that contains the word to complete. TEXT is | ||
277 | the word to complete. We can use the entire contents of rl_line_buffer | ||
278 | in case we want to do some simple parsing. Return the array of matches, | ||
279 | or NULL if there aren't any. */ | ||
280 | char ** | ||
281 | pop_completion (char *text, int start, int end) | ||
282 | { | ||
283 | char **matches; | ||
284 | |||
285 | (void)end; | ||
286 | matches = (char **)NULL; | ||
287 | |||
288 | /* If this word is at the start of the line, then it is a command | ||
289 | to complete. Otherwise it is the name of a file in the current | ||
290 | directory. */ | ||
291 | if (start == 0) | ||
292 | matches = completion_matches (text, command_generator); | ||
293 | |||
294 | return (matches); | ||
295 | } | ||
296 | |||
297 | /* Generator function for command completion. STATE lets us know whether | ||
298 | to start from scratch; without any state (i.e. STATE == 0), then we | ||
299 | start at the top of the list. */ | ||
300 | char * | ||
301 | command_generator (const char *text, int state) | ||
302 | { | ||
303 | static int list_index, len; | ||
304 | const char *name; | ||
305 | |||
306 | /* If this is a new word to complete, initialize now. This includes | ||
307 | saving the length of TEXT for efficiency, and initializing the index | ||
308 | variable to 0. */ | ||
309 | if (!state) | ||
310 | { | ||
311 | list_index = 0; | ||
312 | len = strlen (text); | ||
313 | } | ||
314 | |||
315 | /* Return the next name which partially matches from the command list. */ | ||
316 | while ((name = commands[list_index].name)) | ||
317 | { | ||
318 | list_index++; | ||
319 | |||
320 | if (strncmp (name, text, len) == 0) | ||
321 | return (dupstr(name)); | ||
322 | } | ||
323 | |||
324 | /* If no names matched, then return NULL. */ | ||
325 | return ((char *)NULL); | ||
326 | } | ||
327 | |||
328 | int | 348 | int |
329 | com_verbose (char *arg) | 349 | com_verbose (char *arg) |
330 | { | 350 | { |
... | @@ -525,8 +545,7 @@ com_stat (char *arg) | ... | @@ -525,8 +545,7 @@ com_stat (char *arg) |
525 | } | 545 | } |
526 | 546 | ||
527 | int | 547 | int |
528 | com_dele (arg) | 548 | com_dele (char *arg) |
529 | char *arg; | ||
530 | { | 549 | { |
531 | unsigned msgno; | 550 | unsigned msgno; |
532 | if (!valid_argument ("dele", arg)) | 551 | if (!valid_argument ("dele", arg)) |
... | @@ -739,3 +758,4 @@ valid_argument (const char *caller, char *arg) | ... | @@ -739,3 +758,4 @@ valid_argument (const char *caller, char *arg) |
739 | 758 | ||
740 | return 1; | 759 | return 1; |
741 | } | 760 | } |
761 | ... | ... |
-
Please register or sign in to post a comment