Provide ml_reread() when compiled without readline.
Check for interrupt in (both versions of) ml_reread(). Use util_[cm]alloc() instead of [cm]alloc().
Showing
1 changed file
with
279 additions
and
11 deletions
... | @@ -54,7 +54,6 @@ ml_got_interrupt () | ... | @@ -54,7 +54,6 @@ ml_got_interrupt () |
54 | return rc; | 54 | return rc; |
55 | } | 55 | } |
56 | 56 | ||
57 | #ifdef WITH_READLINE | ||
58 | int | 57 | int |
59 | ml_getc (FILE *stream) | 58 | ml_getc (FILE *stream) |
60 | { | 59 | { |
... | @@ -75,7 +74,6 @@ ml_getc (FILE *stream) | ... | @@ -75,7 +74,6 @@ ml_getc (FILE *stream) |
75 | } | 74 | } |
76 | return EOF; | 75 | return EOF; |
77 | } | 76 | } |
78 | #endif | ||
79 | 77 | ||
80 | void | 78 | void |
81 | ml_readline_init () | 79 | ml_readline_init () |
... | @@ -111,12 +109,20 @@ ml_reread (char *prompt, char **text) | ... | @@ -111,12 +109,20 @@ ml_reread (char *prompt, char **text) |
111 | { | 109 | { |
112 | char *s; | 110 | char *s; |
113 | 111 | ||
112 | ml_clear_interrupt (); | ||
114 | insert_text = *text; | 113 | insert_text = *text; |
115 | rl_startup_hook = ml_insert_hook; | 114 | rl_startup_hook = ml_insert_hook; |
116 | s = readline (prompt); | 115 | s = readline (prompt); |
117 | if (*text) | 116 | if (!ml_got_interrupt ()) |
118 | free (*text); | 117 | { |
119 | *text = s; | 118 | if (*text) |
119 | free (*text); | ||
120 | *text = s; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | putc('\n', stdout); | ||
125 | } | ||
120 | rl_startup_hook = NULL; | 126 | rl_startup_hook = NULL; |
121 | return 0; | 127 | return 0; |
122 | } | 128 | } |
... | @@ -161,15 +167,277 @@ ml_command_generator (char *text, int state) | ... | @@ -161,15 +167,277 @@ ml_command_generator (char *text, int state) |
161 | 167 | ||
162 | #else | 168 | #else |
163 | 169 | ||
170 | #include <sys/ioctl.h> | ||
171 | |||
172 | #define STDOUT 1 | ||
173 | static int ch_erase; | ||
174 | static int ch_kill; | ||
175 | |||
176 | #if defined(TIOCSTI) | ||
177 | #elif defined(HAVE_TERMIOS_H) | ||
178 | # include <termios.h> | ||
179 | |||
180 | static struct termios term_settings; | ||
181 | |||
182 | int | ||
183 | set_tty () | ||
184 | { | ||
185 | struct termios new_settings; | ||
186 | |||
187 | if (tcgetattr(STDOUT, &term_settings) == -1) | ||
188 | return 1; | ||
189 | |||
190 | ch_erase = term_settings.c_cc[VERASE]; | ||
191 | ch_kill = term_settings.c_cc[VKILL]; | ||
192 | |||
193 | new_settings = term_settings; | ||
194 | new_settings.c_lflag &= ~(ICANON|ECHO); | ||
195 | #if defined(TAB3) | ||
196 | new_settings.c_oflag &= ~(TAB3); | ||
197 | #elif defined(OXTABS) | ||
198 | new_settings.c_oflag &= ~(OXTABS); | ||
199 | #endif | ||
200 | new_settings.c_cc[VMIN] = 1; | ||
201 | new_settings.c_cc[VTIME] = 0; | ||
202 | tcsetattr(STDOUT, TCSADRAIN, &new_settings); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | void | ||
207 | restore_tty () | ||
208 | { | ||
209 | tcsetattr (STDOUT, TCSADRAIN, &term_settings); | ||
210 | } | ||
211 | |||
212 | #elif defined(HAVE_TERMIO_H) | ||
213 | # include <termio.h> | ||
214 | |||
215 | static struct termio term_settings; | ||
216 | |||
217 | int | ||
218 | set_tty () | ||
219 | { | ||
220 | struct termio new_settings; | ||
221 | |||
222 | if (ioctl(STDOUT, TCGETA, &term_settings) < 0) | ||
223 | return -1; | ||
224 | |||
225 | ch_erase = term_settings.c_cc[VERASE]; | ||
226 | ch_kill = term_settings.c_cc[VKILL]; | ||
227 | |||
228 | new_settings = term_settings; | ||
229 | new_settings.c_lflag &= ~(ICANON | ECHO); | ||
230 | new_settings.c_oflag &= ~(TAB3); | ||
231 | new_settings.c_cc[VMIN] = 1; | ||
232 | new_settings.c_cc[VTIME] = 0; | ||
233 | ioctl(STDOUT, TCSETA, &new_settings); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | void | ||
238 | restore_tty () | ||
239 | { | ||
240 | ioctl(STDOUT, TCSETA, &term_settings); | ||
241 | } | ||
242 | |||
243 | #elif defined(HAVE_SGTTY_H) | ||
244 | # include <sgtty.h> | ||
245 | |||
246 | static struct sgttyb term_settings; | ||
247 | |||
248 | int | ||
249 | set_tty () | ||
250 | { | ||
251 | struct sgttyb new_settings; | ||
252 | |||
253 | if (ioctl(STDOUT, TIOCGETP, &term_settings) < 0) | ||
254 | return 1; | ||
255 | |||
256 | ch_erase = term_settings.sg_erase; | ||
257 | ch_kill = term_settings.sg_kill; | ||
258 | |||
259 | new_settings = term_settings; | ||
260 | new_settings.sg_flags |= CBREAK; | ||
261 | new_settings.sg_flags &= ~(ECHO | XTABS); | ||
262 | ioctl(STDOUT, TIOCSETP, &new_settings); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | void | ||
267 | restore_tty () | ||
268 | { | ||
269 | ioctl(STDOUT, TIOCSETP, &term_settings); | ||
270 | } | ||
271 | |||
272 | #else | ||
273 | # define DUMB_MODE | ||
274 | #endif | ||
275 | |||
276 | |||
277 | #define LINE_INC 80 | ||
278 | |||
164 | int | 279 | int |
165 | ml_reread (char *prompt, char **text) | 280 | ml_reread (char *prompt, char **text) |
166 | { | 281 | { |
167 | char *s; | 282 | int ch; |
168 | /*FIXME*/ | 283 | char *line; |
169 | s = readline (prompt); | 284 | int line_size; |
285 | int pos; | ||
286 | char *p; | ||
287 | |||
170 | if (*text) | 288 | if (*text) |
171 | free (*text); | 289 | { |
172 | *text = s; | 290 | line = strdup (*text); |
291 | if (line) | ||
292 | { | ||
293 | pos = strlen(line); | ||
294 | line_size = pos + 1; | ||
295 | } | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | line_size = LINE_INC; | ||
300 | line = malloc (line_size); | ||
301 | pos = 0; | ||
302 | } | ||
303 | |||
304 | if (!line) | ||
305 | { | ||
306 | util_error("not enough memory to edit the line"); | ||
307 | return -1; | ||
308 | } | ||
309 | |||
310 | line[pos] = 0; | ||
311 | |||
312 | if (prompt) | ||
313 | { | ||
314 | fputs (prompt, stdout); | ||
315 | fflush (stdout); | ||
316 | } | ||
317 | |||
318 | #ifdef TIOCSTI | ||
319 | |||
320 | for (p = line; *p; p++) | ||
321 | { | ||
322 | ioctl(0, TIOCSTI, p); | ||
323 | } | ||
324 | |||
325 | pos = 0; | ||
326 | |||
327 | while ((ch = ml_getc (stdin)) != EOF && ch != '\n') | ||
328 | { | ||
329 | if (pos >= line_size) | ||
330 | { | ||
331 | if ((p = realloc (line, line_size + LINE_INC)) == NULL) | ||
332 | { | ||
333 | fputs ("\n", stdout); | ||
334 | util_error ("not enough memory to edit the line"); | ||
335 | break; | ||
336 | } | ||
337 | else | ||
338 | { | ||
339 | line_size += LINE_INC; | ||
340 | line = p; | ||
341 | } | ||
342 | } | ||
343 | line[pos++] = ch; | ||
344 | } | ||
345 | |||
346 | #else | ||
347 | |||
348 | fputs (line, stdout); | ||
349 | fflush (stdout); | ||
350 | |||
351 | # ifndef DUMB_MODE | ||
352 | set_tty (); | ||
353 | |||
354 | while ((ch = ml_getc (stdin)) != EOF) | ||
355 | { | ||
356 | if (ch == ch_erase) | ||
357 | { | ||
358 | /* kill last char */ | ||
359 | if (pos > 0) | ||
360 | line[--pos] = 0; | ||
361 | putc('\b', stdout); | ||
362 | } | ||
363 | else if (ch == ch_kill) | ||
364 | { | ||
365 | /* kill the entire line */ | ||
366 | pos = 0; | ||
367 | line[pos] = 0; | ||
368 | putc ('\r', stdout); | ||
369 | if (prompt) | ||
370 | fputs (prompt, stdout); | ||
371 | } | ||
372 | else if (ch == '\n' || ch == EOF) | ||
373 | break; | ||
374 | else | ||
375 | { | ||
376 | if (pos >= line_size) | ||
377 | { | ||
378 | if ((p = realloc (line, line_size + LINE_INC)) == NULL) | ||
379 | { | ||
380 | fputs("\n", stdout); | ||
381 | util_error("not enough memory to edit the line"); | ||
382 | break; | ||
383 | } | ||
384 | else | ||
385 | { | ||
386 | line_size += LINE_INC; | ||
387 | line = p; | ||
388 | } | ||
389 | } | ||
390 | line[pos++] = ch; | ||
391 | putc(ch, stdout); | ||
392 | } | ||
393 | fflush (stdout); | ||
394 | } | ||
395 | |||
396 | putc ('\n', stdout); | ||
397 | restore_tty (); | ||
398 | # else | ||
399 | /* Dumb mode: the last resort */ | ||
400 | |||
401 | putc ('\n', stdout); | ||
402 | if (prompt) | ||
403 | { | ||
404 | fputs (prompt, stdout); | ||
405 | fflush (stdout); | ||
406 | } | ||
407 | |||
408 | pos = 0; | ||
409 | |||
410 | while ((ch = ml_getc (stdin)) != EOF && ch != '\n') | ||
411 | { | ||
412 | if (pos >= line_size) | ||
413 | { | ||
414 | if ((p = realloc (line, line_size + LINE_INC)) == NULL) | ||
415 | { | ||
416 | fputs ("\n", stdout); | ||
417 | util_error ("not enough memory to edit the line"); | ||
418 | break; | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | line_size += LINE_INC; | ||
423 | line = p; | ||
424 | } | ||
425 | } | ||
426 | line[pos++] = ch; | ||
427 | } | ||
428 | # endif | ||
429 | #endif | ||
430 | |||
431 | line[pos] = 0; | ||
432 | |||
433 | if (ml_got_interrupt ()) | ||
434 | free (line); | ||
435 | else | ||
436 | { | ||
437 | if (*text) | ||
438 | free (*text); | ||
439 | *text = line; | ||
440 | } | ||
173 | return 0; | 441 | return 0; |
174 | } | 442 | } |
175 | 443 | ||
... | @@ -186,7 +454,7 @@ readline (const char *prompt) | ... | @@ -186,7 +454,7 @@ readline (const char *prompt) |
186 | fflush (ofile); | 454 | fflush (ofile); |
187 | } | 455 | } |
188 | 456 | ||
189 | p = line = calloc (1, 255); | 457 | p = line = util_calloc (1, 255); |
190 | alloclen = 255; | 458 | alloclen = 255; |
191 | linelen = 0; | 459 | linelen = 0; |
192 | for (;;) | 460 | for (;;) | ... | ... |
-
Please register or sign in to post a comment