GNU Binutils with patches for OS216
Révision | b69d38afdea34e4fecab5ea47ffe1e594e0b6233 (tree) |
---|---|
l'heure | 2016-03-10 03:25:00 |
Auteur | Pedro Alves <palves@redh...> |
Commiter | Pedro Alves |
Command line input handling TLC
I didn't manage to usefully split this further into smaller
independent pieces, so:
gdb/ChangeLog
2016-03-09 Pedro Alves <palves@redhat.com>
* event-top.c (more_to_come): Delete.
(struct readline_input_state): Delete.
(readline_input_state): Delete.
(get_command_line_buffer): New function.
(command_handler): Update comments. Don't handle NULL commands
here. Do not execute commented lines.
(command_line_append_input_line): New function.
(handle_line_of_input): New function, partly based on
command_line_handler and command_line_input.
(command_line_handler): Rewrite.
* event-top.h (command_handler): New declaration.
(command_loop): Defer command execution to command_handler.
(command_line_input): Update comments. Simplify, using struct
buffer and handle_line_of_input.
* top.h (struct buffer): New forward declaration.
(handle_line_of_input): New declaration.
@@ -1,5 +1,24 @@ | ||
1 | 1 | 2016-03-09 Pedro Alves <palves@redhat.com> |
2 | 2 | |
3 | + * event-top.c (more_to_come): Delete. | |
4 | + (struct readline_input_state): Delete. | |
5 | + (readline_input_state): Delete. | |
6 | + (get_command_line_buffer): New function. | |
7 | + (command_handler): Update comments. Don't handle NULL commands | |
8 | + here. Do not execute commented lines. | |
9 | + (command_line_append_input_line): New function. | |
10 | + (handle_line_of_input): New function, partly based on | |
11 | + command_line_handler and command_line_input. | |
12 | + (command_line_handler): Rewrite. | |
13 | + * event-top.h (command_handler): New declaration. | |
14 | + (command_loop): Defer command execution to command_handler. | |
15 | + (command_line_input): Update comments. Simplify, using struct | |
16 | + buffer and handle_line_of_input. | |
17 | + * top.h (struct buffer): New forward declaration. | |
18 | + (handle_line_of_input): New declaration. | |
19 | + | |
20 | +2016-03-09 Pedro Alves <palves@redhat.com> | |
21 | + | |
3 | 22 | * event-top.c (command_line_handler): Use xfree + xstrdup instead |
4 | 23 | of xrealloc + strcpy. |
5 | 24 | * main.c (captured_main): Use xstrdup instead of xmalloc plus |
@@ -49,7 +49,6 @@ | ||
49 | 49 | static void rl_callback_read_char_wrapper (gdb_client_data client_data); |
50 | 50 | static void command_line_handler (char *rl); |
51 | 51 | static void change_line_handler (void); |
52 | -static void command_handler (char *command); | |
53 | 52 | static char *top_level_prompt (void); |
54 | 53 | |
55 | 54 | /* Signal handlers. */ |
@@ -140,20 +139,6 @@ static struct async_signal_handler *sigtstp_token; | ||
140 | 139 | #endif |
141 | 140 | static struct async_signal_handler *async_sigterm_token; |
142 | 141 | |
143 | -/* Structure to save a partially entered command. This is used when | |
144 | - the user types '\' at the end of a command line. This is necessary | |
145 | - because each line of input is handled by a different call to | |
146 | - command_line_handler, and normally there is no state retained | |
147 | - between different calls. */ | |
148 | -static int more_to_come = 0; | |
149 | - | |
150 | -struct readline_input_state | |
151 | - { | |
152 | - char *linebuffer; | |
153 | - char *linebuffer_ptr; | |
154 | - } | |
155 | -readline_input_state; | |
156 | - | |
157 | 142 | /* This hook is called by rl_callback_read_char_wrapper after each |
158 | 143 | character is processed. */ |
159 | 144 | void (*after_char_processing_hook) (void); |
@@ -383,6 +368,24 @@ top_level_prompt (void) | ||
383 | 368 | return xstrdup (prompt); |
384 | 369 | } |
385 | 370 | |
371 | +/* Get a pointer to the command line buffer. This is used to | |
372 | + construct a whole line of input from partial input. */ | |
373 | + | |
374 | +static struct buffer * | |
375 | +get_command_line_buffer (void) | |
376 | +{ | |
377 | + static struct buffer line_buffer; | |
378 | + static int line_buffer_initialized; | |
379 | + | |
380 | + if (!line_buffer_initialized) | |
381 | + { | |
382 | + buffer_init (&line_buffer); | |
383 | + line_buffer_initialized = 1; | |
384 | + } | |
385 | + | |
386 | + return &line_buffer; | |
387 | +} | |
388 | + | |
386 | 389 | /* When there is an event ready on the stdin file descriptor, instead |
387 | 390 | of calling readline directly throught the callback function, or |
388 | 391 | instead of calling gdb_readline_no_editing_callback, give gdb a |
@@ -436,152 +439,122 @@ async_disable_stdin (void) | ||
436 | 439 | } |
437 | 440 | |
438 | 441 | |
439 | -/* Handles a gdb command. This function is called by | |
440 | - command_line_handler, which has processed one or more input lines | |
441 | - into COMMAND. */ | |
442 | -/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop | |
443 | - function. The command_loop function will be obsolete when we | |
444 | - switch to use the event loop at every execution of gdb. */ | |
445 | -static void | |
442 | +/* Handle a gdb command line. This function is called when | |
443 | + handle_line_of_input has concatenated one or more input lines into | |
444 | + a whole command. */ | |
445 | + | |
446 | +void | |
446 | 447 | command_handler (char *command) |
447 | 448 | { |
448 | 449 | struct cleanup *stat_chain; |
450 | + char *c; | |
449 | 451 | |
450 | 452 | clear_quit_flag (); |
451 | 453 | if (instream == stdin) |
452 | 454 | reinitialize_more_filter (); |
453 | 455 | |
454 | - /* If readline returned a NULL command, it means that the connection | |
455 | - with the terminal is gone. This happens at the end of a | |
456 | - testsuite run, after Expect has hung up but GDB is still alive. | |
457 | - In such a case, we just quit gdb killing the inferior program | |
458 | - too. */ | |
459 | - if (command == 0) | |
460 | - { | |
461 | - printf_unfiltered ("quit\n"); | |
462 | - execute_command ("quit", stdin == instream); | |
463 | - } | |
464 | - | |
465 | 456 | stat_chain = make_command_stats_cleanup (1); |
466 | 457 | |
467 | - execute_command (command, instream == stdin); | |
458 | + /* Do not execute commented lines. */ | |
459 | + for (c = command; *c == ' ' || *c == '\t'; c++) | |
460 | + ; | |
461 | + if (c[0] != '#') | |
462 | + { | |
463 | + execute_command (command, instream == stdin); | |
468 | 464 | |
469 | - /* Do any commands attached to breakpoint we stopped at. */ | |
470 | - bpstat_do_actions (); | |
465 | + /* Do any commands attached to breakpoint we stopped at. */ | |
466 | + bpstat_do_actions (); | |
467 | + } | |
471 | 468 | |
472 | 469 | do_cleanups (stat_chain); |
473 | 470 | } |
474 | 471 | |
475 | -/* Handle a complete line of input. This is called by the callback | |
476 | - mechanism within the readline library. Deal with incomplete | |
477 | - commands as well, by saving the partial input in a global | |
478 | - buffer. */ | |
472 | +/* Append RL, an input line returned by readline or one of its | |
473 | + emulations, to CMD_LINE_BUFFER. Returns the command line if we | |
474 | + have a whole command line ready to be processed by the command | |
475 | + interpreter or NULL if the command line isn't complete yet (input | |
476 | + line ends in a backslash). Takes ownership of RL. */ | |
479 | 477 | |
480 | -/* NOTE: 1999-04-30 This is the asynchronous version of the | |
481 | - command_line_input function; command_line_input will become | |
482 | - obsolete once we use the event loop as the default mechanism in | |
483 | - GDB. */ | |
484 | -static void | |
485 | -command_line_handler (char *rl) | |
478 | +static char * | |
479 | +command_line_append_input_line (struct buffer *cmd_line_buffer, char *rl) | |
486 | 480 | { |
487 | - static char *linebuffer = 0; | |
488 | - static unsigned linelength = 0; | |
489 | - char *p; | |
490 | - char *p1; | |
491 | - char *nline; | |
492 | - int repeat = (instream == stdin); | |
481 | + char *cmd; | |
482 | + size_t len; | |
493 | 483 | |
494 | - if (annotation_level > 1 && instream == stdin) | |
495 | - printf_unfiltered (("\n\032\032post-prompt\n")); | |
484 | + len = strlen (rl); | |
496 | 485 | |
497 | - if (linebuffer == 0) | |
486 | + if (len > 0 && rl[len - 1] == '\\') | |
498 | 487 | { |
499 | - linelength = 80; | |
500 | - linebuffer = (char *) xmalloc (linelength); | |
501 | - linebuffer[0] = '\0'; | |
488 | + /* Don't copy the backslash and wait for more. */ | |
489 | + buffer_grow (cmd_line_buffer, rl, len - 1); | |
490 | + cmd = NULL; | |
502 | 491 | } |
503 | - | |
504 | - p = linebuffer; | |
505 | - | |
506 | - if (more_to_come) | |
492 | + else | |
507 | 493 | { |
508 | - strcpy (linebuffer, readline_input_state.linebuffer); | |
509 | - p = readline_input_state.linebuffer_ptr; | |
510 | - xfree (readline_input_state.linebuffer); | |
511 | - more_to_come = 0; | |
494 | + /* Copy whole line including terminating null, and we're | |
495 | + done. */ | |
496 | + buffer_grow (cmd_line_buffer, rl, len + 1); | |
497 | + cmd = cmd_line_buffer->buffer; | |
512 | 498 | } |
513 | 499 | |
514 | -#ifdef STOP_SIGNAL | |
515 | - if (job_control) | |
516 | - signal (STOP_SIGNAL, handle_stop_sig); | |
517 | -#endif | |
500 | + /* Allocated in readline. */ | |
501 | + xfree (rl); | |
518 | 502 | |
519 | - /* Make sure that all output has been output. Some machines may let | |
520 | - you get away with leaving out some of the gdb_flush, but not | |
521 | - all. */ | |
522 | - wrap_here (""); | |
523 | - gdb_flush (gdb_stdout); | |
524 | - gdb_flush (gdb_stderr); | |
503 | + return cmd; | |
504 | +} | |
525 | 505 | |
526 | - if (source_file_name != NULL) | |
527 | - ++source_line_number; | |
506 | +/* Handle a line of input coming from readline. | |
528 | 507 | |
529 | - /* If we are in this case, then command_handler will call quit | |
530 | - and exit from gdb. */ | |
531 | - if (!rl || rl == (char *) EOF) | |
532 | - { | |
533 | - command_handler (0); | |
534 | - return; /* Lint. */ | |
535 | - } | |
536 | - if (strlen (rl) + 1 + (p - linebuffer) > linelength) | |
537 | - { | |
538 | - linelength = strlen (rl) + 1 + (p - linebuffer); | |
539 | - nline = (char *) xrealloc (linebuffer, linelength); | |
540 | - p += nline - linebuffer; | |
541 | - linebuffer = nline; | |
542 | - } | |
543 | - p1 = rl; | |
544 | - /* Copy line. Don't copy null at end. (Leaves line alone | |
545 | - if this was just a newline). */ | |
546 | - while (*p1) | |
547 | - *p++ = *p1++; | |
508 | + If the read line ends with a continuation character (backslash), | |
509 | + save the partial input in CMD_LINE_BUFFER (except the backslash), | |
510 | + and return NULL. Otherwise, save the partial input and return a | |
511 | + pointer to CMD_LINE_BUFFER's buffer (null terminated), indicating a | |
512 | + whole command line is ready to be executed. | |
548 | 513 | |
549 | - xfree (rl); /* Allocated in readline. */ | |
514 | + Returns EOF on end of file. | |
550 | 515 | |
551 | - if (p > linebuffer && *(p - 1) == '\\') | |
552 | - { | |
553 | - *p = '\0'; | |
554 | - p--; /* Put on top of '\'. */ | |
516 | + If REPEAT, handle command repetitions: | |
555 | 517 | |
556 | - readline_input_state.linebuffer = xstrdup (linebuffer); | |
557 | - readline_input_state.linebuffer_ptr = p; | |
518 | + - If the input command line is NOT empty, the command returned is | |
519 | + copied into the global 'saved_command_line' var so that it can | |
520 | + be repeated later. | |
558 | 521 | |
559 | - /* We will not invoke a execute_command if there is more | |
560 | - input expected to complete the command. So, we need to | |
561 | - print an empty prompt here. */ | |
562 | - more_to_come = 1; | |
563 | - display_gdb_prompt (""); | |
564 | - return; | |
565 | - } | |
522 | + - OTOH, if the input command line IS empty, return the previously | |
523 | + saved command instead of the empty input line. | |
524 | +*/ | |
566 | 525 | |
567 | -#ifdef STOP_SIGNAL | |
568 | - if (job_control) | |
569 | - signal (STOP_SIGNAL, SIG_DFL); | |
570 | -#endif | |
526 | +char * | |
527 | +handle_line_of_input (struct buffer *cmd_line_buffer, | |
528 | + char *rl, int repeat, char *annotation_suffix) | |
529 | +{ | |
530 | + char *p1; | |
531 | + char *cmd; | |
532 | + | |
533 | + if (rl == NULL) | |
534 | + return (char *) EOF; | |
535 | + | |
536 | + cmd = command_line_append_input_line (cmd_line_buffer, rl); | |
537 | + if (cmd == NULL) | |
538 | + return NULL; | |
539 | + | |
540 | + /* We have a complete command line now. Prepare for the next | |
541 | + command, but leave ownership of memory to the buffer . */ | |
542 | + cmd_line_buffer->used_size = 0; | |
543 | + | |
544 | + if (annotation_level > 1 && instream == stdin) | |
545 | + { | |
546 | + printf_unfiltered (("\n\032\032post-")); | |
547 | + puts_unfiltered (annotation_suffix); | |
548 | + printf_unfiltered (("\n")); | |
549 | + } | |
571 | 550 | |
572 | -#define SERVER_COMMAND_LENGTH 7 | |
573 | - server_command = | |
574 | - (p - linebuffer > SERVER_COMMAND_LENGTH) | |
575 | - && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; | |
576 | - if (server_command) | |
551 | +#define SERVER_COMMAND_PREFIX "server " | |
552 | + if (startswith (cmd, SERVER_COMMAND_PREFIX)) | |
577 | 553 | { |
578 | - /* Note that we don't set `line'. Between this and the check in | |
579 | - dont_repeat, this insures that repeating will still do the | |
580 | - right thing. */ | |
581 | - *p = '\0'; | |
582 | - command_handler (linebuffer + SERVER_COMMAND_LENGTH); | |
583 | - display_gdb_prompt (0); | |
584 | - return; | |
554 | + /* Note that we don't set `saved_command_line'. Between this | |
555 | + and the check in dont_repeat, this insures that repeating | |
556 | + will still do the right thing. */ | |
557 | + return cmd + strlen (SERVER_COMMAND_PREFIX); | |
585 | 558 | } |
586 | 559 | |
587 | 560 | /* Do history expansion if that is wished. */ |
@@ -591,10 +564,11 @@ command_line_handler (char *rl) | ||
591 | 564 | char *history_value; |
592 | 565 | int expanded; |
593 | 566 | |
594 | - *p = '\0'; /* Insert null now. */ | |
595 | - expanded = history_expand (linebuffer, &history_value); | |
567 | + expanded = history_expand (cmd, &history_value); | |
596 | 568 | if (expanded) |
597 | 569 | { |
570 | + size_t len; | |
571 | + | |
598 | 572 | /* Print the changes. */ |
599 | 573 | printf_unfiltered ("%s\n", history_value); |
600 | 574 |
@@ -602,67 +576,81 @@ command_line_handler (char *rl) | ||
602 | 576 | if (expanded < 0) |
603 | 577 | { |
604 | 578 | xfree (history_value); |
605 | - return; | |
579 | + return cmd; | |
606 | 580 | } |
607 | - if (strlen (history_value) > linelength) | |
608 | - { | |
609 | - linelength = strlen (history_value) + 1; | |
610 | - linebuffer = (char *) xrealloc (linebuffer, linelength); | |
611 | - } | |
612 | - strcpy (linebuffer, history_value); | |
613 | - p = linebuffer + strlen (linebuffer); | |
581 | + | |
582 | + /* history_expand returns an allocated string. Just replace | |
583 | + our buffer with it. */ | |
584 | + len = strlen (history_value); | |
585 | + xfree (buffer_finish (cmd_line_buffer)); | |
586 | + cmd_line_buffer->buffer = history_value; | |
587 | + cmd_line_buffer->buffer_size = len + 1; | |
588 | + cmd = history_value; | |
614 | 589 | } |
615 | - xfree (history_value); | |
616 | 590 | } |
617 | 591 | |
618 | 592 | /* If we just got an empty line, and that is supposed to repeat the |
619 | - previous command, return the value in the global buffer. */ | |
620 | - if (repeat && p == linebuffer && *p != '\\') | |
621 | - { | |
622 | - command_handler (saved_command_line); | |
623 | - display_gdb_prompt (0); | |
624 | - return; | |
625 | - } | |
593 | + previous command, return the previously saved command. */ | |
594 | + for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++) | |
595 | + ; | |
596 | + if (repeat && *p1 == '\0') | |
597 | + return saved_command_line; | |
598 | + | |
599 | + /* Add command to history if appropriate. Note: lines consisting | |
600 | + solely of comments are also added to the command history. This | |
601 | + is useful when you type a command, and then realize you don't | |
602 | + want to execute it quite yet. You can comment out the command | |
603 | + and then later fetch it from the value history and remove the | |
604 | + '#'. The kill ring is probably better, but some people are in | |
605 | + the habit of commenting things out. */ | |
606 | + if (*cmd != '\0' && input_from_terminal_p ()) | |
607 | + gdb_add_history (cmd); | |
626 | 608 | |
627 | - for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++); | |
628 | - if (repeat && !*p1) | |
609 | + /* Save into global buffer if appropriate. */ | |
610 | + if (repeat) | |
629 | 611 | { |
630 | - command_handler (saved_command_line); | |
631 | - display_gdb_prompt (0); | |
632 | - return; | |
612 | + xfree (saved_command_line); | |
613 | + saved_command_line = xstrdup (cmd); | |
614 | + return saved_command_line; | |
633 | 615 | } |
616 | + else | |
617 | + return cmd; | |
618 | +} | |
634 | 619 | |
635 | - *p = 0; | |
620 | +/* Handle a complete line of input. This is called by the callback | |
621 | + mechanism within the readline library. Deal with incomplete | |
622 | + commands as well, by saving the partial input in a global | |
623 | + buffer. | |
636 | 624 | |
637 | - /* Add line to history if appropriate. */ | |
638 | - if (*linebuffer && input_from_terminal_p ()) | |
639 | - gdb_add_history (linebuffer); | |
625 | + NOTE: This is the asynchronous version of the command_line_input | |
626 | + function. */ | |
640 | 627 | |
641 | - /* Note: lines consisting solely of comments are added to the command | |
642 | - history. This is useful when you type a command, and then | |
643 | - realize you don't want to execute it quite yet. You can comment | |
644 | - out the command and then later fetch it from the value history | |
645 | - and remove the '#'. The kill ring is probably better, but some | |
646 | - people are in the habit of commenting things out. */ | |
647 | - if (*p1 == '#') | |
648 | - *p1 = '\0'; /* Found a comment. */ | |
628 | +void | |
629 | +command_line_handler (char *rl) | |
630 | +{ | |
631 | + struct buffer *line_buffer = get_command_line_buffer (); | |
632 | + char *cmd; | |
649 | 633 | |
650 | - /* Save into global buffer if appropriate. */ | |
651 | - if (repeat) | |
634 | + cmd = handle_line_of_input (line_buffer, rl, instream == stdin, "prompt"); | |
635 | + if (cmd == (char *) EOF) | |
652 | 636 | { |
653 | - xfree (saved_command_line); | |
654 | - saved_command_line = xstrdup (linebuffer); | |
655 | - if (!more_to_come) | |
656 | - { | |
657 | - command_handler (saved_command_line); | |
658 | - display_gdb_prompt (0); | |
659 | - } | |
660 | - return; | |
637 | + /* stdin closed. The connection with the terminal is gone. | |
638 | + This happens at the end of a testsuite run, after Expect has | |
639 | + hung up but GDB is still alive. In such a case, we just quit | |
640 | + gdb killing the inferior program too. */ | |
641 | + printf_unfiltered ("quit\n"); | |
642 | + execute_command ("quit", stdin == instream); | |
643 | + } | |
644 | + else if (cmd == NULL) | |
645 | + { | |
646 | + /* We don't have a full line yet. Print an empty prompt. */ | |
647 | + display_gdb_prompt (""); | |
648 | + } | |
649 | + else | |
650 | + { | |
651 | + command_handler (cmd); | |
652 | + display_gdb_prompt (0); | |
661 | 653 | } |
662 | - | |
663 | - command_handler (linebuffer); | |
664 | - display_gdb_prompt (0); | |
665 | - return; | |
666 | 654 | } |
667 | 655 | |
668 | 656 | /* Does reading of input from terminal w/o the editing features |
@@ -34,6 +34,8 @@ extern void async_init_signals (void); | ||
34 | 34 | extern void set_async_editing_command (char *args, int from_tty, |
35 | 35 | struct cmd_list_element *c); |
36 | 36 | |
37 | +extern void command_handler (char *command); | |
38 | + | |
37 | 39 | /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ |
38 | 40 | #ifndef STOP_SIGNAL |
39 | 41 | #include <signal.h> |
@@ -533,37 +533,17 @@ execute_command_to_string (char *p, int from_tty) | ||
533 | 533 | void |
534 | 534 | command_loop (void) |
535 | 535 | { |
536 | - struct cleanup *old_chain; | |
537 | - char *command; | |
538 | - | |
539 | 536 | while (instream && !feof (instream)) |
540 | 537 | { |
541 | - clear_quit_flag (); | |
542 | - if (instream == stdin) | |
543 | - reinitialize_more_filter (); | |
544 | - old_chain = make_cleanup (null_cleanup, 0); | |
538 | + char *command; | |
545 | 539 | |
546 | 540 | /* Get a command-line. This calls the readline package. */ |
547 | 541 | command = command_line_input (instream == stdin ? |
548 | 542 | get_prompt () : (char *) NULL, |
549 | 543 | instream == stdin, "prompt"); |
550 | - if (command == 0) | |
551 | - { | |
552 | - do_cleanups (old_chain); | |
553 | - return; | |
554 | - } | |
555 | - | |
556 | - make_command_stats_cleanup (1); | |
557 | - | |
558 | - /* Do not execute commented lines. */ | |
559 | - if (command[0] != '#') | |
560 | - { | |
561 | - execute_command (command, instream == stdin); | |
562 | - | |
563 | - /* Do any commands attached to breakpoint we are stopped at. */ | |
564 | - bpstat_do_actions (); | |
565 | - } | |
566 | - do_cleanups (old_chain); | |
544 | + if (command == NULL) | |
545 | + return; | |
546 | + command_handler (command); | |
567 | 547 | } |
568 | 548 | } |
569 | 549 |
@@ -1016,32 +996,26 @@ gdb_safe_append_history (void) | ||
1016 | 996 | do_cleanups (old_chain); |
1017 | 997 | } |
1018 | 998 | |
1019 | -/* Read one line from the command input stream `instream' | |
1020 | - into the local static buffer `linebuffer' (whose current length | |
1021 | - is `linelength'). | |
1022 | - The buffer is made bigger as necessary. | |
1023 | - Returns the address of the start of the line. | |
999 | +/* Read one line from the command input stream `instream' into a local | |
1000 | + static buffer. The buffer is made bigger as necessary. Returns | |
1001 | + the address of the start of the line. | |
1024 | 1002 | |
1025 | 1003 | NULL is returned for end of file. |
1026 | 1004 | |
1027 | - *If* the instream == stdin & stdin is a terminal, the line read | |
1028 | - is copied into the file line saver (global var char *line, | |
1029 | - length linesize) so that it can be duplicated. | |
1005 | + *If* the instream == stdin & stdin is a terminal, the line read is | |
1006 | + copied into the global 'saved_command_line' so that it can be | |
1007 | + repeated. | |
1030 | 1008 | |
1031 | - This routine either uses fancy command line editing or | |
1032 | - simple input as the user has requested. */ | |
1009 | + This routine either uses fancy command line editing or simple input | |
1010 | + as the user has requested. */ | |
1033 | 1011 | |
1034 | 1012 | char * |
1035 | 1013 | command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) |
1036 | 1014 | { |
1037 | - static char *linebuffer = 0; | |
1038 | - static unsigned linelength = 0; | |
1015 | + static struct buffer cmd_line_buffer; | |
1016 | + static int cmd_line_buffer_initialized; | |
1039 | 1017 | const char *prompt = prompt_arg; |
1040 | - char *p; | |
1041 | - char *p1; | |
1042 | - char *rl; | |
1043 | - char *nline; | |
1044 | - char got_eof = 0; | |
1018 | + char *cmd; | |
1045 | 1019 | |
1046 | 1020 | /* The annotation suffix must be non-NULL. */ |
1047 | 1021 | if (annotation_suffix == NULL) |
@@ -1065,13 +1039,14 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) | ||
1065 | 1039 | prompt = local_prompt; |
1066 | 1040 | } |
1067 | 1041 | |
1068 | - if (linebuffer == 0) | |
1042 | + if (!cmd_line_buffer_initialized) | |
1069 | 1043 | { |
1070 | - linelength = 80; | |
1071 | - linebuffer = (char *) xmalloc (linelength); | |
1044 | + buffer_init (&cmd_line_buffer); | |
1045 | + cmd_line_buffer_initialized = 1; | |
1072 | 1046 | } |
1073 | 1047 | |
1074 | - p = linebuffer; | |
1048 | + /* Starting a new command line. */ | |
1049 | + cmd_line_buffer.used_size = 0; | |
1075 | 1050 | |
1076 | 1051 | /* Control-C quits instantly if typed while in this loop |
1077 | 1052 | since it should not wait until the user types a newline. */ |
@@ -1084,6 +1059,8 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) | ||
1084 | 1059 | |
1085 | 1060 | while (1) |
1086 | 1061 | { |
1062 | + char *rl; | |
1063 | + | |
1087 | 1064 | /* Make sure that all output has been output. Some machines may |
1088 | 1065 | let you get away with leaving out some of the gdb_flush, but |
1089 | 1066 | not all. */ |
@@ -1115,37 +1092,16 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) | ||
1115 | 1092 | rl = gdb_readline_no_editing (prompt); |
1116 | 1093 | } |
1117 | 1094 | |
1118 | - if (annotation_level > 1 && instream == stdin) | |
1095 | + cmd = handle_line_of_input (&cmd_line_buffer, rl, | |
1096 | + repeat, annotation_suffix); | |
1097 | + if (cmd == (char *) EOF) | |
1119 | 1098 | { |
1120 | - puts_unfiltered ("\n\032\032post-"); | |
1121 | - puts_unfiltered (annotation_suffix); | |
1122 | - puts_unfiltered ("\n"); | |
1123 | - } | |
1124 | - | |
1125 | - if (!rl || rl == (char *) EOF) | |
1126 | - { | |
1127 | - got_eof = 1; | |
1099 | + cmd = NULL; | |
1128 | 1100 | break; |
1129 | 1101 | } |
1130 | - if (strlen (rl) + 1 + (p - linebuffer) > linelength) | |
1131 | - { | |
1132 | - linelength = strlen (rl) + 1 + (p - linebuffer); | |
1133 | - nline = (char *) xrealloc (linebuffer, linelength); | |
1134 | - p += nline - linebuffer; | |
1135 | - linebuffer = nline; | |
1136 | - } | |
1137 | - p1 = rl; | |
1138 | - /* Copy line. Don't copy null at end. (Leaves line alone | |
1139 | - if this was just a newline). */ | |
1140 | - while (*p1) | |
1141 | - *p++ = *p1++; | |
1142 | - | |
1143 | - xfree (rl); /* Allocated in readline. */ | |
1144 | - | |
1145 | - if (p == linebuffer || *(p - 1) != '\\') | |
1102 | + if (cmd != NULL) | |
1146 | 1103 | break; |
1147 | 1104 | |
1148 | - p--; /* Put on top of '\'. */ | |
1149 | 1105 | prompt = NULL; |
1150 | 1106 | } |
1151 | 1107 |
@@ -1155,77 +1111,7 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) | ||
1155 | 1111 | #endif |
1156 | 1112 | immediate_quit--; |
1157 | 1113 | |
1158 | - if (got_eof) | |
1159 | - return NULL; | |
1160 | - | |
1161 | -#define SERVER_COMMAND_LENGTH 7 | |
1162 | - server_command = | |
1163 | - (p - linebuffer > SERVER_COMMAND_LENGTH) | |
1164 | - && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; | |
1165 | - if (server_command) | |
1166 | - { | |
1167 | - /* Note that we don't set `line'. Between this and the check in | |
1168 | - dont_repeat, this insures that repeating will still do the | |
1169 | - right thing. */ | |
1170 | - *p = '\0'; | |
1171 | - return linebuffer + SERVER_COMMAND_LENGTH; | |
1172 | - } | |
1173 | - | |
1174 | - /* Do history expansion if that is wished. */ | |
1175 | - if (history_expansion_p && instream == stdin | |
1176 | - && ISATTY (instream)) | |
1177 | - { | |
1178 | - char *history_value; | |
1179 | - int expanded; | |
1180 | - | |
1181 | - *p = '\0'; /* Insert null now. */ | |
1182 | - expanded = history_expand (linebuffer, &history_value); | |
1183 | - if (expanded) | |
1184 | - { | |
1185 | - /* Print the changes. */ | |
1186 | - printf_unfiltered ("%s\n", history_value); | |
1187 | - | |
1188 | - /* If there was an error, call this function again. */ | |
1189 | - if (expanded < 0) | |
1190 | - { | |
1191 | - xfree (history_value); | |
1192 | - return command_line_input (prompt, repeat, | |
1193 | - annotation_suffix); | |
1194 | - } | |
1195 | - if (strlen (history_value) > linelength) | |
1196 | - { | |
1197 | - linelength = strlen (history_value) + 1; | |
1198 | - linebuffer = (char *) xrealloc (linebuffer, linelength); | |
1199 | - } | |
1200 | - strcpy (linebuffer, history_value); | |
1201 | - p = linebuffer + strlen (linebuffer); | |
1202 | - } | |
1203 | - xfree (history_value); | |
1204 | - } | |
1205 | - | |
1206 | - /* If we just got an empty line, and that is supposed to repeat the | |
1207 | - previous command, return the value in the global buffer. */ | |
1208 | - if (repeat && p == linebuffer) | |
1209 | - return saved_command_line; | |
1210 | - for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++); | |
1211 | - if (repeat && !*p1) | |
1212 | - return saved_command_line; | |
1213 | - | |
1214 | - *p = 0; | |
1215 | - | |
1216 | - /* Add line to history if appropriate. */ | |
1217 | - if (*linebuffer && input_from_terminal_p ()) | |
1218 | - gdb_add_history (linebuffer); | |
1219 | - | |
1220 | - /* Save into global buffer if appropriate. */ | |
1221 | - if (repeat) | |
1222 | - { | |
1223 | - xfree (saved_command_line); | |
1224 | - saved_command_line = xstrdup (linebuffer); | |
1225 | - return saved_command_line; | |
1226 | - } | |
1227 | - | |
1228 | - return linebuffer; | |
1114 | + return cmd; | |
1229 | 1115 | } |
1230 | 1116 | |
1231 | 1117 | /* Print the GDB banner. */ |
@@ -20,6 +20,8 @@ | ||
20 | 20 | #ifndef TOP_H |
21 | 21 | #define TOP_H |
22 | 22 | |
23 | +struct buffer; | |
24 | + | |
23 | 25 | /* From top.c. */ |
24 | 26 | extern char *saved_command_line; |
25 | 27 | extern FILE *instream; |
@@ -97,4 +99,8 @@ extern void set_verbose (char *, int, struct cmd_list_element *); | ||
97 | 99 | |
98 | 100 | extern void do_restore_instream_cleanup (void *stream); |
99 | 101 | |
102 | +extern char *handle_line_of_input (struct buffer *cmd_line_buffer, | |
103 | + char *rl, int repeat, | |
104 | + char *annotation_suffix); | |
105 | + | |
100 | 106 | #endif |