Commit f5067f47 f5067f47f68548f401863d16248836b5fa498b85 by Sergey Poznyakoff

Rewritten to drop the readline dependency.

1 parent 2909cbe1
...@@ -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
......