Home | History | Annotate | Line # | Download | only in info
      1 /*	$NetBSD: echo-area.c,v 1.2 2016/01/14 00:34:52 christos Exp $	*/
      2 
      3 /* echo-area.c -- how to read a line in the echo area.
      4    Id: echo-area.c,v 1.7 2004/12/14 00:15:36 karl Exp
      5 
      6    Copyright (C) 1993, 1997, 1998, 1999, 2001, 2004 Free Software
      7    Foundation, Inc.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 2, or (at your option)
     12    any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program; if not, write to the Free Software
     21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     22 
     23    Written by Brian Fox (bfox (at) ai.mit.edu). */
     24 
     25 #include "info.h"
     26 
     27 #if defined (FD_SET)
     28 #  if defined (hpux)
     29 #    define fd_set_cast(x) (int *)(x)
     30 #  else
     31 #    define fd_set_cast(x) (fd_set *)(x)
     32 #  endif /* !hpux */
     33 #endif /* FD_SET */
     34 
     35 /* Non-zero means that C-g was used to quit reading input. */
     36 int info_aborted_echo_area = 0;
     37 
     38 /* Non-zero means that the echo area is being used to read input. */
     39 int echo_area_is_active = 0;
     40 
     41 /* The address of the last command executed in the echo area. */
     42 VFunction *ea_last_executed_command = (VFunction *)NULL;
     43 
     44 /* Non-zero means that the last command executed while reading input
     45    killed some text. */
     46 int echo_area_last_command_was_kill = 0;
     47 
     48 /* Variables which hold on to the current state of the input line. */
     49 static char input_line[1 + EA_MAX_INPUT];
     50 static char *input_line_prompt;
     51 static int input_line_point;
     52 static int input_line_beg;
     53 static int input_line_end;
     54 static NODE input_line_node = {
     55   (char *)NULL, (char *)NULL, (char *)NULL, input_line,
     56   EA_MAX_INPUT, 0, N_IsInternal
     57 };
     58 
     59 static void echo_area_initialize_node (void);
     60 static void push_echo_area (void), pop_echo_area (void);
     61 static int echo_area_stack_contains_completions_p (void);
     62 
     63 static void ea_kill_text (int from, int to);
     64 
     65 /* Non-zero means we force the user to complete. */
     66 static int echo_area_must_complete_p = 0;
     67 static int completions_window_p (WINDOW *window);
     68 
     69 /* If non-null, this is a window which was specifically created to display
     70    possible completions output.  We remember it so we can delete it when
     71    appropriate. */
     72 static WINDOW *echo_area_completions_window = (WINDOW *)NULL;
     73 
     74 /* Variables which keep track of the window which was active prior to
     75    entering the echo area. */
     76 static WINDOW *calling_window = (WINDOW *)NULL;
     77 static NODE *calling_window_node = (NODE *)NULL;
     78 static long calling_window_point = 0;
     79 static long calling_window_pagetop = 0;
     80 
     81 /* Remember the node and pertinent variables of the calling window. */
     82 static void
     83 remember_calling_window (WINDOW *window)
     84 {
     85   /* Only do this if the calling window is not the completions window, or,
     86      if it is the completions window and there is no other window. */
     87   if (!completions_window_p (window) ||
     88       ((window == windows) && !(window->next)))
     89     {
     90       calling_window = window;
     91       calling_window_node = window->node;
     92       calling_window_point = window->point;
     93       calling_window_pagetop = window->pagetop;
     94     }
     95 }
     96 
     97 /* Restore the caller's window so that it shows the node that it was showing
     98    on entry to info_read_xxx_echo_area (). */
     99 static void
    100 restore_calling_window (void)
    101 {
    102   register WINDOW *win, *compwin = (WINDOW *)NULL;
    103 
    104   /* If the calling window is still visible, and it is the window that
    105      we used for completions output, then restore the calling window. */
    106   for (win = windows; win; win = win->next)
    107     {
    108       if (completions_window_p (win))
    109         compwin = win;
    110 
    111       if (win == calling_window && win == compwin)
    112         {
    113           window_set_node_of_window (calling_window, calling_window_node);
    114           calling_window->point = calling_window_point;
    115           calling_window->pagetop = calling_window_pagetop;
    116           compwin = (WINDOW *)NULL;
    117           break;
    118         }
    119     }
    120 
    121   /* Delete the completions window if it is still present, it isn't the
    122      last window on the screen, and there aren't any prior echo area reads
    123      pending which created a completions window. */
    124   if (compwin)
    125     {
    126       if ((compwin != windows || windows->next) &&
    127           !echo_area_stack_contains_completions_p ())
    128         {
    129           WINDOW *next;
    130           int pagetop = 0;
    131           int start = 0;
    132           int end = 0;
    133           int amount = 0;
    134 
    135           next = compwin->next;
    136           if (next)
    137             {
    138               start = next->first_row;
    139               end = start + next->height;
    140               amount = - (compwin->height + 1);
    141               pagetop = next->pagetop;
    142             }
    143 
    144           info_delete_window_internal (compwin);
    145 
    146           /* This is not necessary because info_delete_window_internal ()
    147              calls echo_area_inform_of_deleted_window (), which does the
    148              right thing. */
    149 #if defined (UNNECESSARY)
    150           echo_area_completions_window = (WINDOW *)NULL;
    151 #endif /* UNNECESSARY */
    152 
    153           if (next)
    154             {
    155               display_scroll_display (start, end, amount);
    156               next->pagetop = pagetop;
    157               display_update_display (windows);
    158             }
    159         }
    160     }
    161 }
    162 
    163 /* Set up a new input line with PROMPT. */
    164 static void
    165 initialize_input_line (char *prompt)
    166 {
    167   input_line_prompt = prompt;
    168   if (prompt)
    169     strcpy (input_line, prompt);
    170   else
    171     input_line[0] = '\0';
    172 
    173   input_line_beg = input_line_end = input_line_point = strlen (prompt);
    174 }
    175 
    176 static char *
    177 echo_area_after_read (void)
    178 {
    179   char *return_value;
    180 
    181   if (info_aborted_echo_area)
    182     {
    183       info_aborted_echo_area = 0;
    184       return_value = (char *)NULL;
    185     }
    186   else
    187     {
    188       if (input_line_beg == input_line_end)
    189         return_value = xstrdup ("");
    190       else
    191         {
    192           int line_len = input_line_end - input_line_beg;
    193           return_value = (char *) xmalloc (1 + line_len);
    194           strncpy (return_value, &input_line[input_line_beg], line_len);
    195           return_value[line_len] = '\0';
    196         }
    197     }
    198   return (return_value);
    199 }
    200 
    201 /* Read a line of text in the echo area.  Return a malloc ()'ed string,
    202    or NULL if the user aborted out of this read.  WINDOW is the currently
    203    active window, so that we can restore it when we need to.  PROMPT, if
    204    non-null, is a prompt to print before reading the line. */
    205 char *
    206 info_read_in_echo_area (WINDOW *window, char *prompt)
    207 {
    208   char *line;
    209 
    210   /* If the echo area is already active, remember the current state. */
    211   if (echo_area_is_active)
    212     push_echo_area ();
    213 
    214   /* Initialize our local variables. */
    215   initialize_input_line (prompt);
    216 
    217   /* Initialize the echo area for the first (but maybe not the last) time. */
    218   echo_area_initialize_node ();
    219 
    220   /* Save away the original node of this window, and the window itself,
    221      so echo area commands can temporarily use this window. */
    222   remember_calling_window (window);
    223 
    224   /* Let the rest of Info know that the echo area is active. */
    225   echo_area_is_active++;
    226   active_window = the_echo_area;
    227 
    228   /* Read characters in the echo area. */
    229   info_read_and_dispatch ();
    230 
    231   echo_area_is_active--;
    232 
    233   /* Restore the original active window and show point in it. */
    234   active_window = calling_window;
    235   restore_calling_window ();
    236   display_cursor_at_point (active_window);
    237   fflush (stdout);
    238 
    239   /* Get the value of the line. */
    240   line = echo_area_after_read ();
    241 
    242   /* If there is a previous loop waiting for us, restore it now. */
    243   if (echo_area_is_active)
    244     pop_echo_area ();
    245 
    246   /* Return the results to the caller. */
    247   return (line);
    248 }
    249 
    250 /* (re) Initialize the echo area node. */
    251 static void
    252 echo_area_initialize_node (void)
    253 {
    254   register int i;
    255 
    256   for (i = input_line_end; (unsigned int) i < sizeof (input_line); i++)
    257     input_line[i] = ' ';
    258 
    259   input_line[i - 1] = '\n';
    260   window_set_node_of_window (the_echo_area, &input_line_node);
    261   input_line[input_line_end] = '\n';
    262 }
    263 
    264 /* Prepare to read characters in the echo area.  This can initialize the
    265    echo area node, but its primary purpose is to side effect the input
    266    line buffer contents. */
    267 void
    268 echo_area_prep_read (void)
    269 {
    270   if (the_echo_area->node != &input_line_node)
    271     echo_area_initialize_node ();
    272 
    273   the_echo_area->point = input_line_point;
    274   input_line[input_line_end] = '\n';
    275   display_update_one_window (the_echo_area);
    276   display_cursor_at_point (active_window);
    277 }
    278 
    279 
    280 /* **************************************************************** */
    282 /*                                                                  */
    283 /*                   Echo Area Movement Commands                    */
    284 /*                                                                  */
    285 /* **************************************************************** */
    286 
    287 DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character"))
    288 {
    289   if (count < 0)
    290     ea_backward (window, -count, key);
    291   else
    292     {
    293       input_line_point += count;
    294       if (input_line_point > input_line_end)
    295         input_line_point = input_line_end;
    296     }
    297 }
    298 
    299 DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character"))
    300 {
    301   if (count < 0)
    302     ea_forward (window, -count, key);
    303   else
    304     {
    305       input_line_point -= count;
    306       if (input_line_point < input_line_beg)
    307         input_line_point = input_line_beg;
    308     }
    309 }
    310 
    311 DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line"))
    312 {
    313   input_line_point = input_line_beg;
    314 }
    315 
    316 DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line"))
    317 {
    318   input_line_point = input_line_end;
    319 }
    320 
    321 #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
    322 
    323 /* Move forward a word in the input line. */
    324 DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word"))
    325 {
    326   int c;
    327 
    328   if (count < 0)
    329     ea_backward_word (window, -count, key);
    330   else
    331     {
    332       while (count--)
    333         {
    334           if (input_line_point == input_line_end)
    335             return;
    336 
    337           /* If we are not in a word, move forward until we are in one.
    338              Then, move forward until we hit a non-alphabetic character. */
    339           c = input_line[input_line_point];
    340 
    341           if (!alphabetic (c))
    342             {
    343               while (++input_line_point < input_line_end)
    344                 {
    345                   c = input_line[input_line_point];
    346                   if (alphabetic (c))
    347                     break;
    348                 }
    349             }
    350 
    351           if (input_line_point == input_line_end)
    352             return;
    353 
    354           while (++input_line_point < input_line_end)
    355             {
    356               c = input_line[input_line_point];
    357               if (!alphabetic (c))
    358                 break;
    359             }
    360         }
    361     }
    362 }
    363 
    364 DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word"))
    365 {
    366   int c;
    367 
    368   if (count < 0)
    369     ea_forward_word (window, -count, key);
    370   else
    371     {
    372       while (count--)
    373         {
    374           if (input_line_point == input_line_beg)
    375             return;
    376 
    377           /* Like ea_forward_word (), except that we look at the
    378              characters just before point. */
    379 
    380           c = input_line[input_line_point - 1];
    381 
    382           if (!alphabetic (c))
    383             {
    384               while ((--input_line_point) != input_line_beg)
    385                 {
    386                   c = input_line[input_line_point - 1];
    387                   if (alphabetic (c))
    388                     break;
    389                 }
    390             }
    391 
    392           while (input_line_point != input_line_beg)
    393             {
    394               c = input_line[input_line_point - 1];
    395               if (!alphabetic (c))
    396                 break;
    397               else
    398                 --input_line_point;
    399             }
    400         }
    401     }
    402 }
    403 
    404 DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor"))
    405 {
    406   register int i;
    407 
    408   if (count < 0)
    409     ea_rubout (window, -count, key);
    410   else
    411     {
    412       if (input_line_point == input_line_end)
    413         return;
    414 
    415       if (info_explicit_arg || count > 1)
    416         {
    417           int orig_point;
    418 
    419           orig_point = input_line_point;
    420           ea_forward (window, count, key);
    421           ea_kill_text (orig_point, input_line_point);
    422           input_line_point = orig_point;
    423         }
    424       else
    425         {
    426           for (i = input_line_point; i < input_line_end; i++)
    427             input_line[i] = input_line[i + 1];
    428 
    429           input_line_end--;
    430         }
    431     }
    432 }
    433 
    434 DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor"))
    435 {
    436   if (count < 0)
    437     ea_delete (window, -count, key);
    438   else
    439     {
    440       int start;
    441 
    442       if (input_line_point == input_line_beg)
    443         return;
    444 
    445       start = input_line_point;
    446       ea_backward (window, count, key);
    447 
    448       if (info_explicit_arg || count > 1)
    449         ea_kill_text (start, input_line_point);
    450       else
    451         ea_delete (window, count, key);
    452     }
    453 }
    454 
    455 DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation"))
    456 {
    457   /* If any text, just discard it, and restore the calling window's node.
    458      If no text, quit. */
    459   if (input_line_end != input_line_beg)
    460     {
    461       terminal_ring_bell ();
    462       input_line_end = input_line_point = input_line_beg;
    463       if (calling_window->node != calling_window_node)
    464         restore_calling_window ();
    465     }
    466   else
    467     info_aborted_echo_area = 1;
    468 }
    469 
    470 DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line"))
    471 {
    472   /* Stub does nothing.  Simply here to see if it has been executed. */
    473 }
    474 
    475 DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim"))
    476 {
    477   unsigned char character;
    478 
    479   character = info_get_another_input_char ();
    480   ea_insert (window, count, character);
    481 }
    482 
    483 DECLARE_INFO_COMMAND (ea_insert, _("Insert this character"))
    484 {
    485   register int i;
    486 
    487   if ((input_line_end + 1) == EA_MAX_INPUT)
    488     {
    489       terminal_ring_bell ();
    490       return;
    491     }
    492 
    493   for (i = input_line_end + 1; i != input_line_point; i--)
    494     input_line[i] = input_line[i - 1];
    495 
    496   input_line[input_line_point] = key;
    497   input_line_point++;
    498   input_line_end++;
    499 }
    500 
    501 DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character"))
    502 {
    503   ea_insert (window, count, '\t');
    504 }
    505 
    506 /* Transpose the characters at point.  If point is at the end of the line,
    507    then transpose the characters before point. */
    508 DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point"))
    509 {
    510   /* Handle conditions that would make it impossible to transpose
    511      characters. */
    512   if (!count || !input_line_point || (input_line_end - input_line_beg) < 2)
    513     return;
    514 
    515   while (count)
    516     {
    517       int t;
    518       if (input_line_point == input_line_end)
    519         {
    520           t = input_line[input_line_point - 1];
    521 
    522           input_line[input_line_point - 1] = input_line[input_line_point - 2];
    523           input_line[input_line_point - 2] = t;
    524         }
    525       else
    526         {
    527           t = input_line[input_line_point];
    528 
    529           input_line[input_line_point] = input_line[input_line_point - 1];
    530           input_line[input_line_point - 1] = t;
    531 
    532           if (count < 0 && input_line_point != input_line_beg)
    533             input_line_point--;
    534           else
    535             input_line_point++;
    536         }
    537 
    538       if (count < 0)
    539         count++;
    540       else
    541         count--;
    542     }
    543 }
    544 
    545 /* **************************************************************** */
    547 /*                                                                  */
    548 /*                   Echo Area Killing and Yanking                  */
    549 /*                                                                  */
    550 /* **************************************************************** */
    551 
    552 static char **kill_ring = (char **)NULL;
    553 static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
    554 static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
    555 static int kill_ring_loc = 0;   /* Location of current yank pointer. */
    556 
    557 /* The largest number of kills that we remember at one time. */
    558 static int max_retained_kills = 15;
    559 
    560 DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill"))
    561 {
    562   register int i;
    563   register char *text;
    564 
    565   if (!kill_ring_index)
    566     {
    567       inform_in_echo_area ((char *) _("Kill ring is empty"));
    568       return;
    569     }
    570 
    571   text = kill_ring[kill_ring_loc];
    572 
    573   for (i = 0; text[i]; i++)
    574     ea_insert (window, 1, text[i]);
    575 }
    576 
    577 /* If the last command was yank, or yank_pop, and the text just before
    578    point is identical to the current kill item, then delete that text
    579    from the line, rotate the index down, and yank back some other text. */
    580 DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill"))
    581 {
    582   register int len;
    583 
    584   if (((ea_last_executed_command != (VFunction *) ea_yank) &&
    585        (ea_last_executed_command != (VFunction *) ea_yank_pop)) ||
    586       (kill_ring_index == 0))
    587     return;
    588 
    589   len = strlen (kill_ring[kill_ring_loc]);
    590 
    591   /* Delete the last yanked item from the line. */
    592   {
    593     register int i, counter;
    594 
    595     counter = input_line_end - input_line_point;
    596 
    597     for (i = input_line_point - len; counter; i++, counter--)
    598       input_line[i] = input_line[i + len];
    599 
    600     input_line_end -= len;
    601     input_line_point -= len;
    602   }
    603 
    604   /* Get a previous kill, and yank that. */
    605   kill_ring_loc--;
    606   if (kill_ring_loc < 0)
    607     kill_ring_loc = kill_ring_index - 1;
    608 
    609   ea_yank (window, count, key);
    610 }
    611 
    612 /* Delete the text from point to end of line. */
    613 DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line"))
    614 {
    615   if (count < 0)
    616     {
    617       ea_kill_text (input_line_point, input_line_beg);
    618       input_line_point = input_line_beg;
    619     }
    620   else
    621     ea_kill_text (input_line_point, input_line_end);
    622 }
    623 
    624 /* Delete the text from point to beg of line. */
    625 DECLARE_INFO_COMMAND (ea_backward_kill_line,
    626                       _("Kill to the beginning of the line"))
    627 {
    628   if (count < 0)
    629     ea_kill_text (input_line_point, input_line_end);
    630   else
    631     {
    632       ea_kill_text (input_line_point, input_line_beg);
    633       input_line_point = input_line_beg;
    634     }
    635 }
    636 
    637 /* Delete from point to the end of the current word. */
    638 DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor"))
    639 {
    640   int orig_point = input_line_point;
    641 
    642   if (count < 0)
    643     ea_backward_kill_word (window, -count, key);
    644   else
    645     {
    646       ea_forward_word (window, count, key);
    647 
    648       if (input_line_point != orig_point)
    649         ea_kill_text (orig_point, input_line_point);
    650 
    651       input_line_point = orig_point;
    652     }
    653 }
    654 
    655 /* Delete from point to the start of the current word. */
    656 DECLARE_INFO_COMMAND (ea_backward_kill_word,
    657                       _("Kill the word preceding the cursor"))
    658 {
    659   int orig_point = input_line_point;
    660 
    661   if (count < 0)
    662     ea_kill_word (window, -count, key);
    663   else
    664     {
    665       ea_backward_word (window, count, key);
    666 
    667       if (input_line_point != orig_point)
    668         ea_kill_text (orig_point, input_line_point);
    669     }
    670 }
    671 
    672 /* The way to kill something.  This appends or prepends to the last
    673    kill, if the last command was a kill command.  If FROM is less
    674    than TO, then the killed text is appended to the most recent kill,
    675    otherwise it is prepended.  If the last command was not a kill command,
    676    then a new slot is made for this kill. */
    677 static void
    678 ea_kill_text (int from, int to)
    679 {
    680   register int i, counter, distance;
    681   int killing_backwards, slot;
    682   char *killed_text;
    683 
    684   killing_backwards = (from > to);
    685 
    686   /* If killing backwards, reverse the values of FROM and TO. */
    687   if (killing_backwards)
    688     {
    689       int temp = from;
    690       from = to;
    691       to = temp;
    692     }
    693 
    694   /* Remember the text that we are about to delete. */
    695   distance = to - from;
    696   killed_text = (char *)xmalloc (1 + distance);
    697   strncpy (killed_text, &input_line[from], distance);
    698   killed_text[distance] = '\0';
    699 
    700   /* Actually delete the text from the line. */
    701   counter = input_line_end - to;
    702 
    703   for (i = from; counter; i++, counter--)
    704     input_line[i] = input_line[i + distance];
    705 
    706   input_line_end -= distance;
    707 
    708   /* If the last command was a kill, append or prepend the killed text to
    709      the last command's killed text. */
    710   if (echo_area_last_command_was_kill)
    711     {
    712       char *old, *new;
    713 
    714       slot = kill_ring_loc;
    715       old = kill_ring[slot];
    716       new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text));
    717 
    718       if (killing_backwards)
    719         {
    720           /* Prepend TEXT to current kill. */
    721           strcpy (new, killed_text);
    722           strcat (new, old);
    723         }
    724       else
    725         {
    726           /* Append TEXT to current kill. */
    727           strcpy (new, old);
    728           strcat (new, killed_text);
    729         }
    730 
    731       free (old);
    732       free (killed_text);
    733       kill_ring[slot] = new;
    734     }
    735   else
    736     {
    737       /* Try to store the kill in a new slot, unless that would cause there
    738          to be too many remembered kills. */
    739       slot = kill_ring_index;
    740 
    741       if (slot == max_retained_kills)
    742         slot = 0;
    743 
    744       if (slot + 1 > kill_ring_slots)
    745         kill_ring = (char **) xrealloc
    746           (kill_ring,
    747            (kill_ring_slots += max_retained_kills) * sizeof (char *));
    748 
    749       if (slot != kill_ring_index)
    750         free (kill_ring[slot]);
    751       else
    752         kill_ring_index++;
    753 
    754       kill_ring[slot] = killed_text;
    755 
    756       kill_ring_loc = slot;
    757     }
    758 
    759   /* Notice that the last command was a kill. */
    760   echo_area_last_command_was_kill++;
    761 }
    762 
    763 /* **************************************************************** */
    765 /*                                                                  */
    766 /*                      Echo Area Completion                        */
    767 /*                                                                  */
    768 /* **************************************************************** */
    769 
    770 /* Pointer to an array of REFERENCE to complete over. */
    771 static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL;
    772 
    773 /* Sorted array of REFERENCE * which is the possible completions found in
    774    the variable echo_area_completion_items.  If there is only one element,
    775    it is the only possible completion. */
    776 static REFERENCE **completions_found = (REFERENCE **)NULL;
    777 static int completions_found_index = 0;
    778 static int completions_found_slots = 0;
    779 
    780 /* The lowest common denominator found while completing. */
    781 static REFERENCE *LCD_completion;
    782 
    783 /* Internal functions used by the user calls. */
    784 static void build_completions (void), completions_must_be_rebuilt (void);
    785 
    786 /* Variable which holds the output of completions. */
    787 static NODE *possible_completions_output_node = (NODE *)NULL;
    788 
    789 static char *compwin_name = "*Completions*";
    790 
    791 /* Return non-zero if WINDOW is a window used for completions output. */
    792 static int
    793 completions_window_p (WINDOW *window)
    794 {
    795   int result = 0;
    796 
    797   if (internal_info_node_p (window->node) &&
    798       (strcmp (window->node->nodename, compwin_name) == 0))
    799     result = 1;
    800 
    801   return (result);
    802 }
    803 
    804 /* Workhorse for completion readers.  If FORCE is non-zero, the user cannot
    805    exit unless the line read completes, or is empty. */
    806 char *
    807 info_read_completing_internal (WINDOW *window, char *prompt,
    808     REFERENCE **completions, int force)
    809 {
    810   char *line;
    811 
    812   /* If the echo area is already active, remember the current state. */
    813   if (echo_area_is_active)
    814     push_echo_area ();
    815 
    816   echo_area_must_complete_p = force;
    817 
    818   /* Initialize our local variables. */
    819   initialize_input_line (prompt);
    820 
    821   /* Initialize the echo area for the first (but maybe not the last) time. */
    822   echo_area_initialize_node ();
    823 
    824   /* Save away the original node of this window, and the window itself,
    825      so echo area commands can temporarily use this window. */
    826   remember_calling_window (window);
    827 
    828   /* Save away the list of items to complete over. */
    829   echo_area_completion_items = completions;
    830   completions_must_be_rebuilt ();
    831 
    832   active_window = the_echo_area;
    833   echo_area_is_active++;
    834 
    835   /* Read characters in the echo area. */
    836   while (1)
    837     {
    838       info_read_and_dispatch ();
    839 
    840       line = echo_area_after_read ();
    841 
    842       /* Force the completion to take place if the user hasn't accepted
    843          a default or aborted, and if FORCE is active. */
    844       if (force && line && *line && completions)
    845         {
    846           register int i;
    847 
    848           build_completions ();
    849 
    850           /* If there is only one completion, then make the line be that
    851              completion. */
    852           if (completions_found_index == 1)
    853             {
    854               free (line);
    855               line = xstrdup (completions_found[0]->label);
    856               break;
    857             }
    858 
    859           /* If one of the completions matches exactly, then that is okay, so
    860              return the current line. */
    861           for (i = 0; i < completions_found_index; i++)
    862             if (strcasecmp (completions_found[i]->label, line) == 0)
    863               {
    864                 free (line);
    865                 line = xstrdup (completions_found[i]->label);
    866                 break;
    867               }
    868 
    869           /* If no match, go back and try again. */
    870           if (i == completions_found_index)
    871             {
    872               if (!completions_found_index)
    873                 inform_in_echo_area ((char *) _("No completions"));
    874               else
    875                 inform_in_echo_area ((char *) _("Not complete"));
    876               continue;
    877             }
    878         }
    879       break;
    880     }
    881   echo_area_is_active--;
    882 
    883   /* Restore the original active window and show point in it. */
    884   active_window = calling_window;
    885   restore_calling_window ();
    886   display_cursor_at_point (active_window);
    887   fflush (stdout);
    888 
    889   echo_area_completion_items = (REFERENCE **)NULL;
    890   completions_must_be_rebuilt ();
    891 
    892   /* If there is a previous loop waiting for us, restore it now. */
    893   if (echo_area_is_active)
    894     pop_echo_area ();
    895 
    896   return (line);
    897 }
    898 
    899 /* Read a line in the echo area with completion over COMPLETIONS. */
    900 char *
    901 info_read_completing_in_echo_area (WINDOW *window,
    902     char *prompt, REFERENCE **completions)
    903 {
    904   return (info_read_completing_internal (window, prompt, completions, 1));
    905 }
    906 
    907 /* Read a line in the echo area allowing completion over COMPLETIONS, but
    908    not requiring it. */
    909 char *
    910 info_read_maybe_completing (WINDOW *window,
    911     char *prompt, REFERENCE **completions)
    912 {
    913   return (info_read_completing_internal (window, prompt, completions, 0));
    914 }
    915 
    916 DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
    917 {
    918   if (!echo_area_completion_items)
    919     {
    920       ea_insert (window, count, key);
    921       return;
    922     }
    923 
    924   build_completions ();
    925 
    926   if (!completions_found_index)
    927     {
    928       terminal_ring_bell ();
    929       inform_in_echo_area ((char *) _("No completions"));
    930     }
    931   else if ((completions_found_index == 1) && (key != '?'))
    932     {
    933       inform_in_echo_area ((char *) _("Sole completion"));
    934     }
    935   else
    936     {
    937       register int i, l;
    938       int limit, iterations, max_label = 0;
    939 
    940       initialize_message_buffer ();
    941       printf_to_message_buffer (completions_found_index == 1
    942                                 ? (char *) _("One completion:\n")
    943                                 : (char *) _("%d completions:\n"),
    944 				(void*)((intptr_t)completions_found_index),
    945 				NULL, NULL);
    946 
    947       /* Find the maximum length of a label. */
    948       for (i = 0; i < completions_found_index; i++)
    949         {
    950           int len = strlen (completions_found[i]->label);
    951           if (len > max_label)
    952             max_label = len;
    953         }
    954 
    955       max_label += 4;
    956 
    957       /* Find out how many columns we should print in. */
    958       limit = calling_window->width / max_label;
    959       if (limit != 1 && (limit * max_label == calling_window->width))
    960         limit--;
    961 
    962       /* Avoid a possible floating exception.  If max_label > width then
    963          the limit will be 0 and a divide-by-zero fault will result. */
    964       if (limit == 0)
    965         limit = 1;
    966 
    967       /* How many iterations of the printing loop? */
    968       iterations = (completions_found_index + (limit - 1)) / limit;
    969 
    970       /* Watch out for special case.  If the number of completions is less
    971          than LIMIT, then just do the inner printing loop. */
    972       if (completions_found_index < limit)
    973         iterations = 1;
    974 
    975       /* Print the sorted items, up-and-down alphabetically. */
    976       for (i = 0; i < iterations; i++)
    977         {
    978           register int j;
    979 
    980           for (j = 0, l = i; j < limit; j++)
    981             {
    982               if (l >= completions_found_index)
    983                 break;
    984               else
    985                 {
    986                   char *label;
    987                   int printed_length, k;
    988 
    989                   label = completions_found[l]->label;
    990                   printed_length = strlen (label);
    991                   printf_to_message_buffer ("%s", label, NULL, NULL);
    992 
    993                   if (j + 1 < limit)
    994                     {
    995                       for (k = 0; k < max_label - printed_length; k++)
    996                         printf_to_message_buffer (" ", NULL, NULL, NULL);
    997                     }
    998                 }
    999               l += iterations;
   1000             }
   1001           printf_to_message_buffer ("\n", NULL, NULL, NULL);
   1002         }
   1003 
   1004       /* Make a new node to hold onto possible completions.  Don't destroy
   1005          dangling pointers. */
   1006       {
   1007         NODE *temp;
   1008 
   1009         temp = message_buffer_to_node ();
   1010         add_gcable_pointer (temp->contents);
   1011         name_internal_node (temp, compwin_name);
   1012         possible_completions_output_node = temp;
   1013       }
   1014 
   1015       /* Find a suitable window for displaying the completions output.
   1016          First choice is an existing window showing completions output.
   1017          If there is only one window, and it is large, make another
   1018          (smaller) window, and use that one.  Otherwise, use the caller's
   1019          window. */
   1020       {
   1021         WINDOW *compwin;
   1022 
   1023         compwin = get_internal_info_window (compwin_name);
   1024 
   1025         if (!compwin)
   1026           {
   1027             /* If we can split the window to display most of the completion
   1028                items, then do so. */
   1029             if (calling_window->height > (iterations * 2)
   1030 		&& calling_window->height / 2 >= WINDOW_MIN_SIZE)
   1031               {
   1032                 int start, pagetop;
   1033 #ifdef SPLIT_BEFORE_ACTIVE
   1034                 int end;
   1035 #endif
   1036 
   1037                 active_window = calling_window;
   1038 
   1039                 /* Perhaps we can scroll this window on redisplay. */
   1040                 start = calling_window->first_row;
   1041                 pagetop = calling_window->pagetop;
   1042 
   1043                 compwin =
   1044                   window_make_window (possible_completions_output_node);
   1045                 active_window = the_echo_area;
   1046                 window_change_window_height
   1047                   (compwin, -(compwin->height - (iterations + 2)));
   1048 
   1049                 window_adjust_pagetop (calling_window);
   1050                 remember_calling_window (calling_window);
   1051 
   1052 #if defined (SPLIT_BEFORE_ACTIVE)
   1053                 /* If the pagetop hasn't changed, scrolling the calling
   1054                    window is a reasonable thing to do. */
   1055                 if (pagetop == calling_window->pagetop)
   1056                   {
   1057                     end = start + calling_window->height;
   1058                     display_scroll_display
   1059                       (start, end, calling_window->prev->height + 1);
   1060                   }
   1061 #else /* !SPLIT_BEFORE_ACTIVE */
   1062                 /* If the pagetop has changed, set the new pagetop here. */
   1063                 if (pagetop != calling_window->pagetop)
   1064                   {
   1065                     int newtop = calling_window->pagetop;
   1066                     calling_window->pagetop = pagetop;
   1067                     set_window_pagetop (calling_window, newtop);
   1068                   }
   1069 #endif /* !SPLIT_BEFORE_ACTIVE */
   1070 
   1071                 echo_area_completions_window = compwin;
   1072                 remember_window_and_node (compwin, compwin->node);
   1073               }
   1074             else
   1075               compwin = calling_window;
   1076           }
   1077 
   1078         if (compwin->node != possible_completions_output_node)
   1079           {
   1080             window_set_node_of_window
   1081               (compwin, possible_completions_output_node);
   1082             remember_window_and_node (compwin, compwin->node);
   1083           }
   1084 
   1085         display_update_display (windows);
   1086       }
   1087     }
   1088 }
   1089 
   1090 DECLARE_INFO_COMMAND (ea_complete, _("Insert completion"))
   1091 {
   1092   if (!echo_area_completion_items)
   1093     {
   1094       ea_insert (window, count, key);
   1095       return;
   1096     }
   1097 
   1098   /* If KEY is SPC, and we are not forcing completion to take place, simply
   1099      insert the key. */
   1100   if (!echo_area_must_complete_p && key == SPC)
   1101     {
   1102       ea_insert (window, count, key);
   1103       return;
   1104     }
   1105 
   1106   if (ea_last_executed_command == (VFunction *) ea_complete)
   1107     {
   1108       /* If the keypress is a SPC character, and we have already tried
   1109          completing once, and there are several completions, then check
   1110          the batch of completions to see if any continue with a space.
   1111          If there are some, insert the space character and continue. */
   1112       if (key == SPC && completions_found_index > 1)
   1113         {
   1114           register int i, offset;
   1115 
   1116           offset = input_line_end - input_line_beg;
   1117 
   1118           for (i = 0; i < completions_found_index; i++)
   1119             if (completions_found[i]->label[offset] == ' ')
   1120               break;
   1121 
   1122           if (completions_found[i])
   1123             ea_insert (window, 1, ' ');
   1124           else
   1125             {
   1126               ea_possible_completions (window, count, key);
   1127               return;
   1128             }
   1129         }
   1130       else
   1131         {
   1132           ea_possible_completions (window, count, key);
   1133           return;
   1134         }
   1135     }
   1136 
   1137   input_line_point = input_line_end;
   1138   build_completions ();
   1139 
   1140   if (!completions_found_index)
   1141     terminal_ring_bell ();
   1142   else if (LCD_completion->label[0] == '\0')
   1143     ea_possible_completions (window, count, key);
   1144   else
   1145     {
   1146       register int i;
   1147       input_line_point = input_line_end = input_line_beg;
   1148       for (i = 0; LCD_completion->label[i]; i++)
   1149         ea_insert (window, 1, LCD_completion->label[i]);
   1150     }
   1151 }
   1152 
   1153 /* Utility REFERENCE used to store possible LCD. */
   1154 static REFERENCE LCD_reference = {
   1155     (char *)NULL, (char *)NULL, (char *)NULL, 0, 0, 0
   1156 };
   1157 
   1158 static void remove_completion_duplicates (void);
   1159 
   1160 /* Variables which remember the state of the most recent call
   1161    to build_completions (). */
   1162 static char *last_completion_request = (char *)NULL;
   1163 static REFERENCE **last_completion_items = (REFERENCE **)NULL;
   1164 
   1165 /* How to tell the completion builder to reset internal state. */
   1166 static void
   1167 completions_must_be_rebuilt (void)
   1168 {
   1169   maybe_free (last_completion_request);
   1170   last_completion_request = (char *)NULL;
   1171   last_completion_items = (REFERENCE **)NULL;
   1172 }
   1173 
   1174 /* Build a list of possible completions from echo_area_completion_items,
   1175    and the contents of input_line. */
   1176 static void
   1177 build_completions (void)
   1178 {
   1179   register int i, len;
   1180   register REFERENCE *entry;
   1181   char *request;
   1182   int informed_of_lengthy_job = 0;
   1183 
   1184   /* If there are no items to complete over, exit immediately. */
   1185   if (!echo_area_completion_items)
   1186     {
   1187       completions_found_index = 0;
   1188       LCD_completion = (REFERENCE *)NULL;
   1189       return;
   1190     }
   1191 
   1192   /* Check to see if this call to build completions is the same as the last
   1193      call to build completions. */
   1194   len = input_line_end - input_line_beg;
   1195   request = (char *)xmalloc (1 + len);
   1196   strncpy (request, &input_line[input_line_beg], len);
   1197   request[len] = '\0';
   1198 
   1199   if (last_completion_request && last_completion_items &&
   1200       last_completion_items == echo_area_completion_items &&
   1201       (strcmp (last_completion_request, request) == 0))
   1202     {
   1203       free (request);
   1204       return;
   1205     }
   1206 
   1207   maybe_free (last_completion_request);
   1208   last_completion_request = request;
   1209   last_completion_items = echo_area_completion_items;
   1210 
   1211   /* Always start at the beginning of the list. */
   1212   completions_found_index = 0;
   1213   LCD_completion = (REFERENCE *)NULL;
   1214 
   1215   for (i = 0; (entry = echo_area_completion_items[i]); i++)
   1216     {
   1217       if (strncasecmp (request, entry->label, len) == 0)
   1218         add_pointer_to_array (entry, completions_found_index,
   1219                               completions_found, completions_found_slots,
   1220                               20, REFERENCE *);
   1221 
   1222       if (!informed_of_lengthy_job && completions_found_index > 100)
   1223         {
   1224           informed_of_lengthy_job = 1;
   1225           window_message_in_echo_area ((char *) _("Building completions..."),
   1226               NULL, NULL);
   1227         }
   1228     }
   1229 
   1230   if (!completions_found_index)
   1231     return;
   1232 
   1233   /* Sort and prune duplicate entries from the completions array. */
   1234   remove_completion_duplicates ();
   1235 
   1236   /* If there is only one completion, just return that. */
   1237   if (completions_found_index == 1)
   1238     {
   1239       LCD_completion = completions_found[0];
   1240       return;
   1241     }
   1242 
   1243   /* Find the least common denominator. */
   1244   {
   1245     long shortest = 100000;
   1246 
   1247     for (i = 1; i < completions_found_index; i++)
   1248       {
   1249         register int j;
   1250         int c1, c2;
   1251 
   1252         for (j = 0;
   1253              (c1 = info_tolower (completions_found[i - 1]->label[j])) &&
   1254              (c2 = info_tolower (completions_found[i]->label[j]));
   1255              j++)
   1256           if (c1 != c2)
   1257             break;
   1258 
   1259         if (shortest > j)
   1260           shortest = j;
   1261       }
   1262 
   1263     maybe_free (LCD_reference.label);
   1264     LCD_reference.label = (char *)xmalloc (1 + shortest);
   1265     /* Since both the sorting done inside remove_completion_duplicates
   1266        and all the comparisons above are case-insensitive, it's
   1267        possible that the completion we are going to return is
   1268        identical to what the user typed but for the letter-case.  This
   1269        is confusing, since the user could type FOOBAR<TAB> and get her
   1270        string change letter-case for no good reason.  So try to find a
   1271        possible completion whose letter-case is identical, and if so,
   1272        use that.  */
   1273     if (completions_found_index > 1)
   1274       {
   1275 	int req_len = strlen (request);
   1276 
   1277         for (i = 0; i < completions_found_index; i++)
   1278           if (strncmp (request, completions_found[i]->label, req_len) == 0)
   1279             break;
   1280         /* If none of the candidates match exactly, use the first one.  */
   1281         if (i >= completions_found_index)
   1282           i = 0;
   1283       }
   1284     strncpy (LCD_reference.label, completions_found[i]->label, shortest);
   1285     LCD_reference.label[shortest] = '\0';
   1286     LCD_completion = &LCD_reference;
   1287   }
   1288 
   1289   if (informed_of_lengthy_job)
   1290     echo_area_initialize_node ();
   1291 }
   1292 
   1293 /* Function called by qsort. */
   1294 static int
   1295 compare_references (const void *entry1, const void *entry2)
   1296 {
   1297   REFERENCE **e1 = (REFERENCE **) entry1;
   1298   REFERENCE **e2 = (REFERENCE **) entry2;
   1299 
   1300   return (strcasecmp ((*e1)->label, (*e2)->label));
   1301 }
   1302 
   1303 /* Prune duplicate entries from COMPLETIONS_FOUND. */
   1304 static void
   1305 remove_completion_duplicates (void)
   1306 {
   1307   register int i, j;
   1308   REFERENCE **temp;
   1309   int newlen;
   1310 
   1311   if (!completions_found_index)
   1312     return;
   1313 
   1314   /* Sort the items. */
   1315   qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
   1316          compare_references);
   1317 
   1318   for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
   1319     {
   1320       if (strcmp (completions_found[i]->label,
   1321                   completions_found[i + 1]->label) == 0)
   1322         completions_found[i] = (REFERENCE *)NULL;
   1323       else
   1324         newlen++;
   1325     }
   1326 
   1327   /* We have marked all the dead slots.  It is faster to copy the live slots
   1328      twice than to prune the dead slots one by one. */
   1329   temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *));
   1330   for (i = 0, j = 0; i < completions_found_index; i++)
   1331     if (completions_found[i])
   1332       temp[j++] = completions_found[i];
   1333 
   1334   for (i = 0; i < newlen; i++)
   1335     completions_found[i] = temp[i];
   1336 
   1337   completions_found[i] = (REFERENCE *)NULL;
   1338   completions_found_index = newlen;
   1339   free (temp);
   1340 }
   1341 
   1342 /* Scroll the "other" window.  If there is a window showing completions, scroll
   1343    that one, otherwise scroll the window which was active on entering the read
   1344    function. */
   1345 DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window"))
   1346 {
   1347   WINDOW *compwin;
   1348   int old_pagetop;
   1349 
   1350   compwin = get_internal_info_window (compwin_name);
   1351 
   1352   if (!compwin)
   1353     compwin = calling_window;
   1354 
   1355   old_pagetop = compwin->pagetop;
   1356 
   1357   /* Let info_scroll_forward () do the work, and print any messages that
   1358      need to be displayed. */
   1359   info_scroll_forward (compwin, count, key);
   1360 }
   1361 
   1362 /* Function which gets called when an Info window is deleted while the
   1363    echo area is active.  WINDOW is the window which has just been deleted. */
   1364 void
   1365 echo_area_inform_of_deleted_window (WINDOW *window)
   1366 {
   1367   /* If this is the calling_window, forget what we remembered about it. */
   1368   if (window == calling_window)
   1369     {
   1370       if (active_window != the_echo_area)
   1371         remember_calling_window (active_window);
   1372       else
   1373         remember_calling_window (windows);
   1374     }
   1375 
   1376   /* If this window was the echo_area_completions_window, then notice that
   1377      the window has been deleted. */
   1378   if (window == echo_area_completions_window)
   1379     echo_area_completions_window = (WINDOW *)NULL;
   1380 }
   1381 
   1382 /* **************************************************************** */
   1384 /*                                                                  */
   1385 /*                 Pushing and Popping the Echo Area                */
   1386 /*                                                                  */
   1387 /* **************************************************************** */
   1388 
   1389 /* Push and Pop the echo area. */
   1390 typedef struct {
   1391   char *line;
   1392   char *prompt;
   1393   REFERENCE **comp_items;
   1394   int point, beg, end;
   1395   int must_complete;
   1396   NODE node;
   1397   WINDOW *compwin;
   1398 } PUSHED_EA;
   1399 
   1400 static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
   1401 static int pushed_echo_areas_index = 0;
   1402 static int pushed_echo_areas_slots = 0;
   1403 
   1404 /* Pushing the echo_area has a side effect of zeroing the completion_items. */
   1405 static void
   1406 push_echo_area (void)
   1407 {
   1408   PUSHED_EA *pushed;
   1409 
   1410   pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA));
   1411   pushed->line = xstrdup (input_line);
   1412   pushed->prompt = input_line_prompt;
   1413   pushed->point = input_line_point;
   1414   pushed->beg = input_line_beg;
   1415   pushed->end = input_line_end;
   1416   pushed->node = input_line_node;
   1417   pushed->comp_items = echo_area_completion_items;
   1418   pushed->must_complete = echo_area_must_complete_p;
   1419   pushed->compwin = echo_area_completions_window;
   1420 
   1421   add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
   1422                         pushed_echo_areas_slots, 4, PUSHED_EA *);
   1423 
   1424   echo_area_completion_items = (REFERENCE **)NULL;
   1425 }
   1426 
   1427 static void
   1428 pop_echo_area (void)
   1429 {
   1430   PUSHED_EA *popped;
   1431 
   1432   popped = pushed_echo_areas[--pushed_echo_areas_index];
   1433 
   1434   strcpy (input_line, popped->line);
   1435   free (popped->line);
   1436   input_line_prompt = popped->prompt;
   1437   input_line_point = popped->point;
   1438   input_line_beg = popped->beg;
   1439   input_line_end = popped->end;
   1440   input_line_node = popped->node;
   1441   echo_area_completion_items = popped->comp_items;
   1442   echo_area_must_complete_p = popped->must_complete;
   1443   echo_area_completions_window = popped->compwin;
   1444   completions_must_be_rebuilt ();
   1445 
   1446   /* If the completion window no longer exists, forget about it. */
   1447   if (echo_area_completions_window)
   1448     {
   1449       register WINDOW *win;
   1450 
   1451       for (win = windows; win; win = win->next)
   1452         if (echo_area_completions_window == win)
   1453           break;
   1454 
   1455       /* If the window wasn't found, then it has already been deleted. */
   1456       if (!win)
   1457         echo_area_completions_window = (WINDOW *)NULL;
   1458     }
   1459 
   1460   free (popped);
   1461 }
   1462 
   1463 /* Returns non-zero if any of the prior stacked calls to read in the echo
   1464    area produced a completions window. */
   1465 static int
   1466 echo_area_stack_contains_completions_p (void)
   1467 {
   1468   register int i;
   1469 
   1470   for (i = 0; i < pushed_echo_areas_index; i++)
   1471     if (pushed_echo_areas[i]->compwin)
   1472       return (1);
   1473 
   1474   return (0);
   1475 }
   1476 
   1477 /* **************************************************************** */
   1479 /*                                                                  */
   1480 /*             Error Messages While Reading in Echo Area            */
   1481 /*                                                                  */
   1482 /* **************************************************************** */
   1483 
   1484 #if defined (HAVE_SYS_TIME_H)
   1485 #  include <sys/time.h>
   1486 #  define HAVE_STRUCT_TIMEVAL
   1487 #endif /* HAVE_SYS_TIME_H */
   1488 
   1489 static void
   1490 pause_or_input (void)
   1491 {
   1492 #ifdef FD_SET
   1493   struct timeval timer;
   1494   fd_set readfds;
   1495   int ready;
   1496 
   1497   FD_ZERO (&readfds);
   1498   FD_SET (fileno (stdin), &readfds);
   1499   timer.tv_sec = 2;
   1500   timer.tv_usec = 0;
   1501   ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL,
   1502                   (fd_set *) NULL, &timer);
   1503 #endif /* FD_SET */
   1504 }
   1505 
   1506 /* Print MESSAGE right after the end of the current line, and wait
   1507    for input or a couple of seconds, whichever comes first.  Then flush the
   1508    informational message that was printed. */
   1509 void
   1510 inform_in_echo_area (const char *message)
   1511 {
   1512   int i;
   1513   char *text;
   1514   int avail = EA_MAX_INPUT + 1 - input_line_end;
   1515 
   1516   text = xstrdup (message);
   1517   for (i = 0; text[i] && text[i] != '\n' && i < avail; i++)
   1518     ;
   1519   text[i] = 0;
   1520 
   1521   echo_area_initialize_node ();
   1522   sprintf (&input_line[input_line_end], "%s[%s]\n",
   1523            echo_area_is_active ? " ": "", text);
   1524   free (text);
   1525   the_echo_area->point = input_line_point;
   1526   display_update_one_window (the_echo_area);
   1527   display_cursor_at_point (active_window);
   1528   fflush (stdout);
   1529   pause_or_input ();
   1530   echo_area_initialize_node ();
   1531 }
   1532