home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / gdb-4.12-src.lha / src / amiga / gdb-4.12 / readline / readline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-15  |  154.8 KB  |  6,658 lines

  1. /* readline.c -- a general facility for reading lines of input
  2.    with emacs style editing and completion.  */
  3.  
  4. /* Copyright 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
  5.  
  6.    This file contains the Readline Library (the Library), a set of
  7.    routines for providing Emacs style line input to programs that ask
  8.    for it.
  9.  
  10.    The Library is free software; you can redistribute it and/or modify
  11.    it under the terms of the GNU General Public License as published by
  12.    the Free Software Foundation; either version 2 of the License, or
  13.    (at your option) any later version.
  14.  
  15.    The Library is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.    You should have received a copy of the GNU General Public License
  21.    along with this program; if not, write to the Free Software
  22.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  23.  
  24. /* Remove these declarations when we have a complete libgnu.a. */
  25. /* #define STATIC_MALLOC */
  26. #if !defined (STATIC_MALLOC)
  27. extern char *xmalloc (), *xrealloc ();
  28. #else
  29. static char *xmalloc (), *xrealloc ();
  30. #endif /* STATIC_MALLOC */
  31.  
  32. #include "sysdep.h"
  33. #include <stdio.h>
  34. #include <fcntl.h>
  35. #ifndef    NO_SYS_FILE
  36. #include <sys/file.h>
  37. #endif
  38. #include <signal.h>
  39.  
  40. #if defined (HAVE_UNISTD_H)
  41. #  include <unistd.h>
  42. #endif
  43.  
  44. #define NEW_TTY_DRIVER
  45. #define HAVE_BSD_SIGNALS
  46. /* #define USE_XON_XOFF */
  47.  
  48. #ifdef __MSDOS__
  49. #undef NEW_TTY_DRIVER
  50. #undef HAVE_BSD_SIGNALS
  51. #endif
  52.  
  53. /* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
  54. #if defined (USG) && !defined (hpux)
  55. #undef HAVE_BSD_SIGNALS
  56. #endif
  57.  
  58. /* System V machines use termio. */
  59. #if !defined (_POSIX_VERSION)
  60. #  if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX) || defined (__H3050R) || defined (__H3050RX)
  61. #    undef NEW_TTY_DRIVER
  62. #    define TERMIO_TTY_DRIVER
  63. #    include <termio.h>
  64. #    if !defined (TCOON)
  65. #      define TCOON 1
  66. #    endif
  67. #  endif /* USG || hpux || Xenix || sgi || DUGX */
  68. #endif /* !_POSIX_VERSION */
  69.  
  70. /* Posix systems use termios and the Posix signal functions. */
  71. #if defined (_POSIX_VERSION)
  72. #  if !defined (TERMIOS_MISSING)
  73. #    undef NEW_TTY_DRIVER
  74. #    define TERMIOS_TTY_DRIVER
  75. #    include <termios.h>
  76. #  endif /* !TERMIOS_MISSING */
  77. #  define HAVE_POSIX_SIGNALS
  78. #  if !defined (O_NDELAY)
  79. #    define O_NDELAY O_NONBLOCK    /* Posix-style non-blocking i/o */
  80. #  endif /* O_NDELAY */
  81. #endif /* _POSIX_VERSION */
  82.  
  83. /* Other (BSD) machines use sgtty. */
  84. #if defined (NEW_TTY_DRIVER)
  85. #include <sgtty.h>
  86. #endif
  87.  
  88. /* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
  89.    it is not already defined.  It is used both to determine if a
  90.    special character is disabled and to disable certain special
  91.    characters.  Posix systems should set to 0, USG systems to -1. */
  92. #if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
  93. #  if defined (_POSIX_VERSION)
  94. #    define _POSIX_VDISABLE 0
  95. #  else /* !_POSIX_VERSION */
  96. #    define _POSIX_VDISABLE -1
  97. #  endif /* !_POSIX_VERSION */
  98. #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
  99.  
  100. /* Define some macros for dealing with assorted signalling disciplines.
  101.  
  102.    These macros provide a way to use signal blocking and disabling
  103.    without smothering your code in a pile of #ifdef's.
  104.  
  105.    SIGNALS_UNBLOCK;            Stop blocking all signals.
  106.  
  107.    {
  108.      SIGNALS_DECLARE_SAVED (name);    Declare a variable to save the 
  109.                     signal blocking state.
  110.     ...
  111.      SIGNALS_BLOCK (SIGSTOP, name);    Block a signal, and save the previous
  112.                     state for restoration later.
  113.     ...
  114.      SIGNALS_RESTORE (name);        Restore previous signals.
  115.    }
  116.  
  117. */
  118.  
  119. #ifdef HAVE_POSIX_SIGNALS
  120.                             /* POSIX signals */
  121.  
  122. #define    SIGNALS_UNBLOCK \
  123.       do { sigset_t set;    \
  124.     sigemptyset (&set);    \
  125.     sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);    \
  126.       } while (0)
  127.  
  128. #define    SIGNALS_DECLARE_SAVED(name)    sigset_t name
  129.  
  130. #define    SIGNALS_BLOCK(SIG, saved)    \
  131.     do { sigset_t set;        \
  132.       sigemptyset (&set);        \
  133.       sigaddset (&set, SIG);    \
  134.       sigprocmask (SIG_BLOCK, &set, &saved);    \
  135.     } while (0)
  136.  
  137. #define    SIGNALS_RESTORE(saved)        \
  138.   sigprocmask (SIG_SETMASK, &saved, (sigset_t *)NULL)
  139.  
  140.  
  141. #else    /* HAVE_POSIX_SIGNALS */
  142. #ifdef HAVE_BSD_SIGNALS
  143.                             /* BSD signals */
  144.  
  145. #define    SIGNALS_UNBLOCK            sigsetmask (0)
  146. #define    SIGNALS_DECLARE_SAVED(name)    int name
  147. #define    SIGNALS_BLOCK(SIG, saved)    saved = sigblock (sigmask (SIG))
  148. #define    SIGNALS_RESTORE(saved)        sigsetmask (saved)
  149.  
  150.  
  151. #else  /* HAVE_BSD_SIGNALS */
  152.                             /* None of the Above */
  153.  
  154. #define    SIGNALS_UNBLOCK            /* nothing */
  155. #define    SIGNALS_DECLARE_SAVED(name)    /* nothing */
  156. #define    SIGNALS_BLOCK(SIG, saved)    /* nothing */
  157. #define    SIGNALS_RESTORE(saved)        /* nothing */
  158.  
  159.  
  160. #endif /* HAVE_BSD_SIGNALS */
  161. #endif /* HAVE_POSIX_SIGNALS */
  162.  
  163. /*  End of signal handling definitions.  */
  164.  
  165.  
  166. #include <errno.h>
  167. extern int errno;
  168.  
  169. #include <setjmp.h>
  170. #include <sys/stat.h>
  171.  
  172. /* Posix macro to check file in statbuf for directory-ness. */
  173. #if defined (S_IFDIR) && !defined (S_ISDIR)
  174. #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
  175. #endif
  176.  
  177. #ifndef __MSDOS__
  178. /* These next are for filename completion.  Perhaps this belongs
  179.    in a different place. */
  180. #include <pwd.h>
  181. #endif /* __MSDOS__ */
  182.  
  183. #ifdef amigados
  184. #define tcflow(a,b)    /* Hack, this is missing from ixemul.library */
  185. #define tcsetattr(a,b,c)    /* But this isn't? */
  186. #endif
  187.  
  188. #if defined (USG) && !defined (isc386) && !defined (sgi)
  189. struct passwd *getpwuid (), *getpwent ();
  190. #endif
  191.  
  192. /* #define HACK_TERMCAP_MOTION */
  193.  
  194. /* Some standard library routines. */
  195. #include "readline.h"
  196. #include "history.h"
  197.  
  198. #ifndef digit
  199. #define digit(c)  ((c) >= '0' && (c) <= '9')
  200. #endif
  201.  
  202. #ifndef isletter
  203. #define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
  204. #endif
  205.  
  206. #ifndef digit_value
  207. #define digit_value(c) ((c) - '0')
  208. #endif
  209.  
  210. #ifndef member
  211. #define member(c, s) ((c) ? index ((s), (c)) : 0)
  212. #endif
  213.  
  214. #ifndef isident
  215. #define isident(c) ((isletter(c) || digit(c) || c == '_'))
  216. #endif
  217.  
  218. #ifndef exchange
  219. #define exchange(x, y) {int temp = x; x = y; y = temp;}
  220. #endif
  221.  
  222. #if !defined (rindex)
  223. extern char *rindex ();
  224. #endif /* rindex */
  225.  
  226. #if !defined (index)
  227. extern char *index ();
  228. #endif /* index */
  229.  
  230. extern char *getenv ();
  231. extern char *tilde_expand ();
  232.  
  233. static update_line ();
  234. static void output_character_function ();
  235. static delete_chars ();
  236. static void insert_some_chars ();
  237.  
  238. #if defined (VOID_SIGHANDLER)
  239. #  define sighandler void
  240. #else
  241. #  define sighandler int
  242. #endif /* VOID_SIGHANDLER */
  243.  
  244. /* This typedef is equivalant to the one for Function; it allows us
  245.    to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
  246. typedef sighandler SigHandler ();
  247.  
  248. /* If on, then readline handles signals in a way that doesn't screw. */
  249. #define HANDLE_SIGNALS
  250.  
  251. #ifdef __GO32__
  252. #include <sys/pc.h>
  253. #undef HANDLE_SIGNALS
  254. #endif
  255.  
  256.  
  257. /* **************************************************************** */
  258. /*                                    */
  259. /*            Line editing input utility            */
  260. /*                                    */
  261. /* **************************************************************** */
  262.  
  263. /* A pointer to the keymap that is currently in use.
  264.    By default, it is the standard emacs keymap. */
  265. Keymap keymap = emacs_standard_keymap;
  266.  
  267. #define no_mode -1
  268. #define vi_mode 0
  269. #define emacs_mode 1
  270.  
  271. /* The current style of editing. */
  272. int rl_editing_mode = emacs_mode;
  273.  
  274. /* Non-zero if the previous command was a kill command. */
  275. static int last_command_was_kill = 0;
  276.  
  277. /* The current value of the numeric argument specified by the user. */
  278. int rl_numeric_arg = 1;
  279.  
  280. /* Non-zero if an argument was typed. */
  281. int rl_explicit_arg = 0;
  282.  
  283. /* Temporary value used while generating the argument. */
  284. int rl_arg_sign = 1;
  285.  
  286. /* Non-zero means we have been called at least once before. */
  287. static int rl_initialized = 0;
  288.  
  289. /* If non-zero, this program is running in an EMACS buffer. */
  290. static char *running_in_emacs = (char *)NULL;
  291.  
  292. /* The current offset in the current input line. */
  293. int rl_point;
  294.  
  295. /* Mark in the current input line. */
  296. int rl_mark;
  297.  
  298. /* Length of the current input line. */
  299. int rl_end;
  300.  
  301. /* Make this non-zero to return the current input_line. */
  302. int rl_done;
  303.  
  304. /* The last function executed by readline. */
  305. Function *rl_last_func = (Function *)NULL;
  306.  
  307. /* Top level environment for readline_internal (). */
  308. static jmp_buf readline_top_level;
  309.  
  310. /* The streams we interact with. */
  311. static FILE *in_stream, *out_stream;
  312.  
  313. /* The names of the streams that we do input and output to. */
  314. FILE *rl_instream, *rl_outstream;
  315.  
  316. /* Non-zero means echo characters as they are read. */
  317. int readline_echoing_p = 1;
  318.  
  319. /* Current prompt. */
  320. char *rl_prompt;
  321.  
  322. /* The number of characters read in order to type this complete command. */
  323. int rl_key_sequence_length = 0;
  324.  
  325. /* If non-zero, then this is the address of a function to call just
  326.    before readline_internal () prints the first prompt. */
  327. Function *rl_startup_hook = (Function *)NULL;
  328.  
  329. /* If non-zero, then this is the address of a function to call when
  330.    completing on a directory name.  The function is called with
  331.    the address of a string (the current directory name) as an arg. */
  332. Function *rl_symbolic_link_hook = (Function *)NULL;
  333.  
  334. /* What we use internally.  You should always refer to RL_LINE_BUFFER. */
  335. static char *the_line;
  336.  
  337. /* The character that can generate an EOF.  Really read from
  338.    the terminal driver... just defaulted here. */
  339. static int eof_char = CTRL ('D');
  340.  
  341. /* Non-zero makes this the next keystroke to read. */
  342. int rl_pending_input = 0;
  343.  
  344. /* Pointer to a useful terminal name. */
  345. char *rl_terminal_name = (char *)NULL;
  346.  
  347. /* Line buffer and maintenence. */
  348. char *rl_line_buffer = (char *)NULL;
  349. int rl_line_buffer_len = 0;
  350. #define DEFAULT_BUFFER_SIZE 256
  351.  
  352.  
  353. /* **************************************************************** */
  354. /*                                    */
  355. /*            `Forward' declarations              */
  356. /*                                    */
  357. /* **************************************************************** */
  358.  
  359. /* Non-zero means do not parse any lines other than comments and
  360.    parser directives. */
  361. static unsigned char parsing_conditionalized_out = 0;
  362.  
  363. /* Caseless strcmp (). */
  364. static int stricmp (), strnicmp ();
  365. static char *strpbrk ();
  366.  
  367. /* Non-zero means to save keys that we dispatch on in a kbd macro. */
  368. static int defining_kbd_macro = 0;
  369.  
  370.  
  371. /* **************************************************************** */
  372. /*                                    */
  373. /*            Top Level Functions                */
  374. /*                                    */
  375. /* **************************************************************** */
  376.  
  377. static void rl_prep_terminal (), rl_deprep_terminal ();
  378. static void clear_to_eol (), rl_generic_bind ();
  379.  
  380. /* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means
  381.    none.  A return value of NULL means that EOF was encountered. */
  382. char *
  383. readline (prompt)
  384.      char *prompt;
  385. {
  386.   char *readline_internal ();
  387.   char *value;
  388.  
  389.   rl_prompt = prompt;
  390.  
  391.   /* If we are at EOF return a NULL string. */
  392.   if (rl_pending_input == EOF)
  393.     {
  394.       rl_pending_input = 0;
  395.       return ((char *)NULL);
  396.     }
  397.  
  398.   rl_initialize ();
  399.   rl_prep_terminal ();
  400.  
  401. #if defined (HANDLE_SIGNALS)
  402.   rl_set_signals ();
  403. #endif
  404.  
  405.   value = readline_internal ();
  406.   rl_deprep_terminal ();
  407.  
  408. #if defined (HANDLE_SIGNALS)
  409.   rl_clear_signals ();
  410. #endif
  411.  
  412.   return (value);
  413. }
  414.  
  415. /* Read a line of input from the global rl_instream, doing output on
  416.    the global rl_outstream.
  417.    If rl_prompt is non-null, then that is our prompt. */
  418. char *
  419. readline_internal ()
  420. {
  421.   int lastc, c, eof_found;
  422.  
  423.   in_stream  = rl_instream;
  424.   out_stream = rl_outstream;
  425.  
  426.   lastc = -1;
  427.   eof_found = 0;
  428.  
  429.   if (rl_startup_hook)
  430.     (*rl_startup_hook) ();
  431.  
  432.   if (!readline_echoing_p)
  433.     {
  434.       if (rl_prompt)
  435.     {
  436.       fprintf (out_stream, "%s", rl_prompt);
  437.       fflush (out_stream);
  438.     }
  439.     }
  440.   else
  441.     {
  442.       rl_on_new_line ();
  443.       rl_redisplay ();
  444. #if defined (VI_MODE)
  445.       if (rl_editing_mode == vi_mode)
  446.     rl_vi_insertion_mode ();
  447. #endif /* VI_MODE */
  448.     }
  449.  
  450.   while (!rl_done)
  451.     {
  452.       int lk = last_command_was_kill;
  453.       int code = setjmp (readline_top_level);
  454.  
  455.       if (code)
  456.     rl_redisplay ();
  457.  
  458.       if (!rl_pending_input)
  459.     {
  460.       /* Then initialize the argument and number of keys read. */
  461.       rl_init_argument ();
  462.       rl_key_sequence_length = 0;
  463.     }
  464.  
  465.       c = rl_read_key ();
  466.  
  467.       /* EOF typed to a non-blank line is a <NL>. */
  468.       if (c == EOF && rl_end)
  469.     c = NEWLINE;
  470.  
  471.       /* The character eof_char typed to blank line, and not as the
  472.      previous character is interpreted as EOF. */
  473.       if (((c == eof_char && lastc != c) || c == EOF) && !rl_end)
  474.     {
  475.       eof_found = 1;
  476.       break;
  477.     }
  478.  
  479.       lastc = c;
  480.       rl_dispatch (c, keymap);
  481.  
  482.       /* If there was no change in last_command_was_kill, then no kill
  483.      has taken place.  Note that if input is pending we are reading
  484.      a prefix command, so nothing has changed yet. */
  485.       if (!rl_pending_input)
  486.     {
  487.       if (lk == last_command_was_kill)
  488.         last_command_was_kill = 0;
  489.     }
  490.  
  491. #if defined (VI_MODE)
  492.       /* In vi mode, when you exit insert mode, the cursor moves back
  493.      over the previous character.  We explicitly check for that here. */
  494.       if (rl_editing_mode == vi_mode && keymap == vi_movement_keymap)
  495.     rl_vi_check ();
  496. #endif /* VI_MODE */
  497.  
  498.       if (!rl_done)
  499.     rl_redisplay ();
  500.     }
  501.  
  502.   /* Restore the original of this history line, iff the line that we
  503.      are editing was originally in the history, AND the line has changed. */
  504.   {
  505.     HIST_ENTRY *entry = current_history ();
  506.  
  507.     if (entry && rl_undo_list)
  508.       {
  509.     char *temp = savestring (the_line);
  510.     rl_revert_line ();
  511.     entry = replace_history_entry (where_history (), the_line,
  512.                        (HIST_ENTRY *)NULL);
  513.     free_history_entry (entry);
  514.  
  515.     strcpy (the_line, temp);
  516.     free (temp);
  517.       }
  518.   }
  519.  
  520.   /* At any rate, it is highly likely that this line has an undo list.  Get
  521.      rid of it now. */
  522.   if (rl_undo_list)
  523.     free_undo_list ();
  524.  
  525.   if (eof_found)
  526.     return (char *)NULL;
  527.   else
  528.     return (savestring (the_line));
  529. }
  530.  
  531.  
  532. /* **************************************************************** */
  533. /*                                        */
  534. /*               Signal Handling                          */
  535. /*                                    */
  536. /* **************************************************************** */
  537.  
  538. #if defined (SIGWINCH)
  539. static SigHandler *old_sigwinch = (SigHandler *)NULL;
  540.  
  541. static sighandler
  542. rl_handle_sigwinch (sig)
  543.      int sig;
  544. {
  545.   char *term;
  546.  
  547.   term = rl_terminal_name;
  548.  
  549.   if (readline_echoing_p)
  550.     {
  551.       if (!term)
  552.     term = getenv ("TERM");
  553.       if (!term)
  554.     term = "dumb";
  555.       rl_reset_terminal (term);
  556. #if defined (NOTDEF)
  557.       crlf ();
  558.       rl_forced_update_display ();
  559. #endif /* NOTDEF */
  560.     }
  561.  
  562.   if (old_sigwinch &&
  563.       old_sigwinch != (SigHandler *)SIG_IGN &&
  564.       old_sigwinch != (SigHandler *)SIG_DFL)
  565.     (*old_sigwinch) (sig);
  566. #if !defined (VOID_SIGHANDLER)
  567.   return (0);
  568. #endif /* VOID_SIGHANDLER */
  569. }
  570. #endif  /* SIGWINCH */
  571.  
  572. #if defined (HANDLE_SIGNALS)
  573. /* Interrupt handling. */
  574. static SigHandler
  575.   *old_int  = (SigHandler *)NULL,
  576.   *old_tstp = (SigHandler *)NULL,
  577.   *old_ttou = (SigHandler *)NULL,
  578.   *old_ttin = (SigHandler *)NULL,
  579.   *old_cont = (SigHandler *)NULL,
  580.   *old_alrm = (SigHandler *)NULL;
  581.  
  582. /* Handle an interrupt character. */
  583. static sighandler
  584. rl_signal_handler (sig)
  585.      int sig;
  586. {
  587. #if !defined (HAVE_BSD_SIGNALS)
  588.   /* Since the signal will not be blocked while we are in the signal
  589.      handler, ignore it until rl_clear_signals resets the catcher. */
  590.   if (sig == SIGINT)
  591.     signal (sig, SIG_IGN);
  592. #endif /* !HAVE_BSD_SIGNALS */
  593.  
  594.   switch (sig)
  595.     {
  596.     case SIGINT:
  597.       free_undo_list ();
  598.       rl_clear_message ();
  599.       rl_init_argument ();
  600.  
  601. #if defined (SIGTSTP)
  602.     case SIGTSTP:
  603.     case SIGTTOU:
  604.     case SIGTTIN:
  605. #endif /* SIGTSTP */
  606.     case SIGALRM:
  607.       rl_clean_up_for_exit ();
  608.       rl_deprep_terminal ();
  609.       rl_clear_signals ();
  610.       rl_pending_input = 0;
  611.  
  612.       kill (getpid (), sig);
  613.  
  614.       SIGNALS_UNBLOCK;
  615.  
  616.       rl_prep_terminal ();
  617.       rl_set_signals ();
  618.     }
  619.  
  620. #if !defined (VOID_SIGHANDLER)
  621.   return (0);
  622. #endif /* !VOID_SIGHANDLER */
  623. }
  624.  
  625. rl_set_signals ()
  626. {
  627.   old_int = (SigHandler *)signal (SIGINT, rl_signal_handler);
  628.   if (old_int == (SigHandler *)SIG_IGN)
  629.     signal (SIGINT, SIG_IGN);
  630.  
  631.   old_alrm = (SigHandler *)signal (SIGALRM, rl_signal_handler);
  632.   if (old_alrm == (SigHandler *)SIG_IGN)
  633.     signal (SIGALRM, SIG_IGN);
  634.  
  635. #if defined (SIGTSTP)
  636.   old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler);
  637.   if (old_tstp == (SigHandler *)SIG_IGN)
  638.     signal (SIGTSTP, SIG_IGN);
  639. #endif
  640. #if defined (SIGTTOU)
  641.   old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler);
  642.   old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler);
  643.  
  644.   if (old_tstp == (SigHandler *)SIG_IGN)
  645.     {
  646.       signal (SIGTTOU, SIG_IGN);
  647.       signal (SIGTTIN, SIG_IGN);
  648.     }
  649. #endif
  650.  
  651. #if defined (SIGWINCH)
  652.   old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);
  653. #endif
  654. }
  655.  
  656. rl_clear_signals ()
  657. {
  658.   signal (SIGINT, old_int);
  659.   signal (SIGALRM, old_alrm);
  660.  
  661. #if defined (SIGTSTP)
  662.   signal (SIGTSTP, old_tstp);
  663. #endif
  664.  
  665. #if defined (SIGTTOU)
  666.   signal (SIGTTOU, old_ttou);
  667.   signal (SIGTTIN, old_ttin);
  668. #endif
  669.  
  670. #if defined (SIGWINCH)
  671.       signal (SIGWINCH, old_sigwinch);
  672. #endif
  673. }
  674. #endif  /* HANDLE_SIGNALS */
  675.  
  676.  
  677. /* **************************************************************** */
  678. /*                                    */
  679. /*            Character Input Buffering               */
  680. /*                                    */
  681. /* **************************************************************** */
  682.  
  683. #if defined (USE_XON_XOFF)
  684. /* If the terminal was in xoff state when we got to it, then xon_char
  685.    contains the character that is supposed to start it again. */
  686. static int xon_char, xoff_state;
  687. #endif /* USE_XON_XOFF */
  688.  
  689. static int pop_index = 0, push_index = 0, ibuffer_len = 511;
  690. static unsigned char ibuffer[512];
  691.  
  692. /* Non-null means it is a pointer to a function to run while waiting for
  693.    character input. */
  694. Function *rl_event_hook = (Function *)NULL;
  695.  
  696. #define any_typein (push_index != pop_index)
  697.  
  698. /* Add KEY to the buffer of characters to be read. */
  699. rl_stuff_char (key)
  700.      int key;
  701. {
  702.   if (key == EOF)
  703.     {
  704.       key = NEWLINE;
  705.       rl_pending_input = EOF;
  706.     }
  707.   ibuffer[push_index++] = key;
  708.   if (push_index >= ibuffer_len)
  709.     push_index = 0;
  710. }
  711.  
  712. /* Return the amount of space available in the
  713.    buffer for stuffing characters. */
  714. int
  715. ibuffer_space ()
  716. {
  717.   if (pop_index > push_index)
  718.     return (pop_index - push_index);
  719.   else
  720.     return (ibuffer_len - (push_index - pop_index));
  721. }
  722.  
  723. /* Get a key from the buffer of characters to be read.
  724.    Return the key in KEY.
  725.    Result is KEY if there was a key, or 0 if there wasn't. */
  726. int
  727. rl_get_char (key)
  728.      int *key;
  729. {
  730.   if (push_index == pop_index)
  731.     return (0);
  732.  
  733.   *key = ibuffer[pop_index++];
  734.  
  735.   if (pop_index >= ibuffer_len)
  736.     pop_index = 0;
  737.  
  738.   return (1);
  739. }
  740.  
  741. /* Stuff KEY into the *front* of the input buffer.
  742.    Returns non-zero if successful, zero if there is
  743.    no space left in the buffer. */
  744. int
  745. rl_unget_char (key)
  746.      int key;
  747. {
  748.   if (ibuffer_space ())
  749.     {
  750.       pop_index--;
  751.       if (pop_index < 0)
  752.     pop_index = ibuffer_len - 1;
  753.       ibuffer[pop_index] = key;
  754.       return (1);
  755.     }
  756.   return (0);
  757. }
  758.  
  759. /* If a character is available to be read, then read it
  760.    and stuff it into IBUFFER.  Otherwise, just return. */
  761. rl_gather_tyi ()
  762. {
  763. #ifdef __GO32__
  764.   char input;
  765.   if (isatty(0))
  766.   {
  767.     int i = rl_getc();
  768.     if (i != EOF)
  769.       rl_stuff_char(i);
  770.   }
  771.   else
  772.     if (kbhit() && ibuffer_space())
  773.       rl_stuff_char(getkey());
  774. #else
  775.   int tty = fileno (in_stream);
  776.   register int tem, result = -1;
  777.   long chars_avail;
  778.   char input;
  779.  
  780. #if defined (FIONREAD)
  781.   result = ioctl (tty, FIONREAD, &chars_avail);
  782. #endif
  783.  
  784.   if (result == -1)
  785.     {
  786.       int flags;
  787.  
  788.       flags = fcntl (tty, F_GETFL, 0);
  789.  
  790.       fcntl (tty, F_SETFL, (flags | O_NDELAY));
  791.       chars_avail = read (tty, &input, 1);
  792.  
  793.       fcntl (tty, F_SETFL, flags);
  794.       if (chars_avail == -1 && errno == EAGAIN)
  795.     return;
  796.     }
  797.  
  798.   /* If there's nothing available, don't waste time trying to read
  799.      something. */
  800.   if (chars_avail == 0)
  801.     return;
  802.  
  803.   tem = ibuffer_space ();
  804.  
  805.   if (chars_avail > tem)
  806.     chars_avail = tem;
  807.  
  808.   /* One cannot read all of the available input.  I can only read a single
  809.      character at a time, or else programs which require input can be
  810.      thwarted.  If the buffer is larger than one character, I lose.
  811.      Damn! */
  812.   if (tem < ibuffer_len)
  813.     chars_avail = 0;
  814.  
  815.   if (result != -1)
  816.     {
  817.       while (chars_avail--)
  818.     rl_stuff_char (rl_getc (in_stream));
  819.     }
  820.   else
  821.     {
  822.       if (chars_avail)
  823.     rl_stuff_char (input);
  824.     }
  825. #endif /* def __GO32__/else */
  826. }
  827.  
  828. static int next_macro_key ();
  829. /* Read a key, including pending input. */
  830. int
  831. rl_read_key ()
  832. {
  833.   int c;
  834.  
  835.   rl_key_sequence_length++;
  836.  
  837.   if (rl_pending_input)
  838.     {
  839.       c = rl_pending_input;
  840.       rl_pending_input = 0;
  841.     }
  842.   else
  843.     {
  844.       /* If input is coming from a macro, then use that. */
  845.       if (c = next_macro_key ())
  846.     return (c);
  847.  
  848.       /* If the user has an event function, then call it periodically. */
  849.       if (rl_event_hook)
  850.     {
  851.       while (rl_event_hook && !rl_get_char (&c))
  852.         {
  853.           (*rl_event_hook) ();
  854.           rl_gather_tyi ();
  855.         }
  856.     }
  857.       else
  858.     {
  859.       if (!rl_get_char (&c))
  860.         c = rl_getc (in_stream);
  861.     }
  862.     }
  863.  
  864.   return (c);
  865. }
  866.  
  867. /* I'm beginning to hate the declaration rules for various compilers. */
  868. static void add_macro_char (), with_macro_input ();
  869.  
  870. /* Do the command associated with KEY in MAP.
  871.    If the associated command is really a keymap, then read
  872.    another key, and dispatch into that map. */
  873. rl_dispatch (key, map)
  874.      register int key;
  875.      Keymap map;
  876. {
  877.  
  878.   if (defining_kbd_macro)
  879.     add_macro_char (key);
  880.  
  881.   if (key > 127 && key < 256)
  882.     {
  883.       if (map[ESC].type == ISKMAP)
  884.     {
  885.       map = (Keymap)map[ESC].function;
  886.       key -= 128;
  887.       rl_dispatch (key, map);
  888.     }
  889.       else
  890.     ding ();
  891.       return;
  892.     }
  893.  
  894.   switch (map[key].type)
  895.     {
  896.     case ISFUNC:
  897.       {
  898.     Function *func = map[key].function;
  899.  
  900.     if (func != (Function *)NULL)
  901.       {
  902.         /* Special case rl_do_lowercase_version (). */
  903.         if (func == rl_do_lowercase_version)
  904.           {
  905.         rl_dispatch (to_lower (key), map);
  906.         return;
  907.           }
  908.  
  909.         (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
  910.  
  911.         /* If we have input pending, then the last command was a prefix
  912.            command.  Don't change the state of rl_last_func.  Otherwise,
  913.            remember the last command executed in this variable. */
  914.         if (!rl_pending_input)
  915.           rl_last_func = map[key].function;
  916.       }
  917.     else
  918.       {
  919.         rl_abort ();
  920.         return;
  921.       }
  922.       }
  923.       break;
  924.  
  925.     case ISKMAP:
  926.       if (map[key].function != (Function *)NULL)
  927.     {
  928.       int newkey;
  929.  
  930.       rl_key_sequence_length++;
  931.       newkey = rl_read_key ();
  932.       rl_dispatch (newkey, (Keymap)map[key].function);
  933.     }
  934.       else
  935.     {
  936.       rl_abort ();
  937.       return;
  938.     }
  939.       break;
  940.  
  941.     case ISMACR:
  942.       if (map[key].function != (Function *)NULL)
  943.     {
  944.       char *macro;
  945.  
  946.       macro = savestring ((char *)map[key].function);
  947.       with_macro_input (macro);
  948.       return;
  949.     }
  950.       break;
  951.     }
  952. }
  953.  
  954.  
  955. /* **************************************************************** */
  956. /*                                    */
  957. /*            Hacking Keyboard Macros             */
  958. /*                                    */
  959. /* **************************************************************** */
  960.  
  961. /* The currently executing macro string.  If this is non-zero,
  962.    then it is a malloc ()'ed string where input is coming from. */
  963. static char *executing_macro = (char *)NULL;
  964.  
  965. /* The offset in the above string to the next character to be read. */
  966. static int executing_macro_index = 0;
  967.  
  968. /* The current macro string being built.  Characters get stuffed
  969.    in here by add_macro_char (). */
  970. static char *current_macro = (char *)NULL;
  971.  
  972. /* The size of the buffer allocated to current_macro. */
  973. static int current_macro_size = 0;
  974.  
  975. /* The index at which characters are being added to current_macro. */
  976. static int current_macro_index = 0;
  977.  
  978. /* A structure used to save nested macro strings.
  979.    It is a linked list of string/index for each saved macro. */
  980. struct saved_macro {
  981.   struct saved_macro *next;
  982.   char *string;
  983.   int index;
  984. };
  985.  
  986. /* The list of saved macros. */
  987. struct saved_macro *macro_list = (struct saved_macro *)NULL;
  988.  
  989. /* Forward declarations of static functions.  Thank you C. */
  990. static void push_executing_macro (), pop_executing_macro ();
  991.  
  992. /* This one has to be declared earlier in the file. */
  993. /* static void add_macro_char (); */
  994.  
  995. /* Set up to read subsequent input from STRING.
  996.    STRING is free ()'ed when we are done with it. */
  997. static void
  998. with_macro_input (string)
  999.      char *string;
  1000. {
  1001.   push_executing_macro ();
  1002.   executing_macro = string;
  1003.   executing_macro_index = 0;
  1004. }
  1005.  
  1006. /* Return the next character available from a macro, or 0 if
  1007.    there are no macro characters. */
  1008. static int
  1009. next_macro_key ()
  1010. {
  1011.   if (!executing_macro)
  1012.     return (0);
  1013.  
  1014.   if (!executing_macro[executing_macro_index])
  1015.     {
  1016.       pop_executing_macro ();
  1017.       return (next_macro_key ());
  1018.     }
  1019.  
  1020.   return (executing_macro[executing_macro_index++]);
  1021. }
  1022.  
  1023. /* Save the currently executing macro on a stack of saved macros. */
  1024. static void
  1025. push_executing_macro ()
  1026. {
  1027.   struct saved_macro *saver;
  1028.  
  1029.   saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
  1030.   saver->next = macro_list;
  1031.   saver->index = executing_macro_index;
  1032.   saver->string = executing_macro;
  1033.  
  1034.   macro_list = saver;
  1035. }
  1036.  
  1037. /* Discard the current macro, replacing it with the one
  1038.    on the top of the stack of saved macros. */
  1039. static void
  1040. pop_executing_macro ()
  1041. {
  1042.   if (executing_macro)
  1043.     free (executing_macro);
  1044.  
  1045.   executing_macro = (char *)NULL;
  1046.   executing_macro_index = 0;
  1047.  
  1048.   if (macro_list)
  1049.     {
  1050.       struct saved_macro *disposer = macro_list;
  1051.       executing_macro = macro_list->string;
  1052.       executing_macro_index = macro_list->index;
  1053.       macro_list = macro_list->next;
  1054.       free (disposer);
  1055.     }
  1056. }
  1057.  
  1058. /* Add a character to the macro being built. */
  1059. static void
  1060. add_macro_char (c)
  1061.      int c;
  1062. {
  1063.   if (current_macro_index + 1 >= current_macro_size)
  1064.     {
  1065.       if (!current_macro)
  1066.     current_macro = (char *)xmalloc (current_macro_size = 25);
  1067.       else
  1068.     current_macro =
  1069.       (char *)xrealloc (current_macro, current_macro_size += 25);
  1070.     }
  1071.  
  1072.   current_macro[current_macro_index++] = c;
  1073.   current_macro[current_macro_index] = '\0';
  1074. }
  1075.  
  1076. /* Begin defining a keyboard macro.
  1077.    Keystrokes are recorded as they are executed.
  1078.    End the definition with rl_end_kbd_macro ().
  1079.    If a numeric argument was explicitly typed, then append this
  1080.    definition to the end of the existing macro, and start by
  1081.    re-executing the existing macro. */
  1082. rl_start_kbd_macro (ignore1, ignore2)
  1083.      int ignore1, ignore2;
  1084. {
  1085.   if (defining_kbd_macro)
  1086.     rl_abort ();
  1087.  
  1088.   if (rl_explicit_arg)
  1089.     {
  1090.       if (current_macro)
  1091.     with_macro_input (savestring (current_macro));
  1092.     }
  1093.   else
  1094.     current_macro_index = 0;
  1095.  
  1096.   defining_kbd_macro = 1;
  1097. }
  1098.  
  1099. /* Stop defining a keyboard macro.
  1100.    A numeric argument says to execute the macro right now,
  1101.    that many times, counting the definition as the first time. */
  1102. rl_end_kbd_macro (count, ignore)
  1103.      int count, ignore;
  1104. {
  1105.   if (!defining_kbd_macro)
  1106.     rl_abort ();
  1107.  
  1108.   current_macro_index -= (rl_key_sequence_length - 1);
  1109.   current_macro[current_macro_index] = '\0';
  1110.  
  1111.   defining_kbd_macro = 0;
  1112.  
  1113.   rl_call_last_kbd_macro (--count, 0);
  1114. }
  1115.  
  1116. /* Execute the most recently defined keyboard macro.
  1117.    COUNT says how many times to execute it. */
  1118. rl_call_last_kbd_macro (count, ignore)
  1119.      int count, ignore;
  1120. {
  1121.   if (!current_macro)
  1122.     rl_abort ();
  1123.  
  1124.   while (count--)
  1125.     with_macro_input (savestring (current_macro));
  1126. }
  1127.  
  1128.  
  1129. /* **************************************************************** */
  1130. /*                                    */
  1131. /*            Initializations                 */
  1132. /*                                    */
  1133. /* **************************************************************** */
  1134.  
  1135. /* Initliaze readline (and terminal if not already). */
  1136. rl_initialize ()
  1137. {
  1138.   extern char *rl_display_prompt;
  1139.  
  1140.   /* If we have never been called before, initialize the
  1141.      terminal and data structures. */
  1142.   if (!rl_initialized)
  1143.     {
  1144.       readline_initialize_everything ();
  1145.       rl_initialized++;
  1146.     }
  1147.  
  1148.   /* Initalize the current line information. */
  1149.   rl_point = rl_end = 0;
  1150.   the_line = rl_line_buffer;
  1151.   the_line[0] = 0;
  1152.  
  1153.   /* We aren't done yet.  We haven't even gotten started yet! */
  1154.   rl_done = 0;
  1155.  
  1156.   /* Tell the history routines what is going on. */
  1157.   start_using_history ();
  1158.  
  1159.   /* Make the display buffer match the state of the line. */
  1160.   {
  1161.     extern char *rl_display_prompt;
  1162.     extern int forced_display;
  1163.  
  1164.     rl_on_new_line ();
  1165.  
  1166.     rl_display_prompt = rl_prompt ? rl_prompt : "";
  1167.     forced_display = 1;
  1168.   }
  1169.  
  1170.   /* No such function typed yet. */
  1171.   rl_last_func = (Function *)NULL;
  1172.  
  1173.   /* Parsing of key-bindings begins in an enabled state. */
  1174.   parsing_conditionalized_out = 0;
  1175. }
  1176.  
  1177. /* Initialize the entire state of the world. */
  1178. readline_initialize_everything ()
  1179. {
  1180.   /* Find out if we are running in Emacs. */
  1181.   running_in_emacs = getenv ("EMACS");
  1182.  
  1183.   /* Set up input and output if they aren't already.  */
  1184.   if (!rl_instream)
  1185.     rl_instream = stdin;
  1186.   if (!rl_outstream)
  1187.     rl_outstream = stdout;
  1188.  
  1189.   /* Allocate data structures. */
  1190.   if (!rl_line_buffer)
  1191.     rl_line_buffer =
  1192.       (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
  1193.  
  1194.   /* Initialize the terminal interface. */
  1195.   init_terminal_io ((char *)NULL);
  1196.  
  1197.   /* Bind tty characters to readline functions. */
  1198.   readline_default_bindings ();
  1199.  
  1200.   /* Initialize the function names. */
  1201.   rl_initialize_funmap ();
  1202.  
  1203.   /* Read in the init file. */
  1204.   rl_read_init_file ((char *)NULL);
  1205.  
  1206.   /* If the completion parser's default word break characters haven't
  1207.      been set yet, then do so now. */
  1208.   {
  1209.     extern char *rl_completer_word_break_characters;
  1210.     extern char *rl_basic_word_break_characters;
  1211.  
  1212.     if (rl_completer_word_break_characters == (char *)NULL)
  1213.       rl_completer_word_break_characters = rl_basic_word_break_characters;
  1214.   }
  1215. }
  1216.  
  1217. /* If this system allows us to look at the values of the regular
  1218.    input editing characters, then bind them to their readline
  1219.    equivalents, iff the characters are not bound to keymaps. */
  1220. readline_default_bindings ()
  1221. {
  1222. #ifndef __GO32__
  1223.  
  1224. #if defined (NEW_TTY_DRIVER)
  1225.   struct sgttyb ttybuff;
  1226.   int tty = fileno (rl_instream);
  1227.  
  1228.   if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
  1229.     {
  1230.       int erase, kill;
  1231.  
  1232.       erase = ttybuff.sg_erase;
  1233.       kill  = ttybuff.sg_kill;
  1234.  
  1235.       if (erase != -1 && keymap[erase].type == ISFUNC)
  1236.     keymap[erase].function = rl_rubout;
  1237.  
  1238.       if (kill != -1 && keymap[kill].type == ISFUNC)
  1239.     keymap[kill].function = rl_unix_line_discard;
  1240.     }
  1241.  
  1242. #if defined (TIOCGLTC)
  1243.   {
  1244.     struct ltchars lt;
  1245.  
  1246.     if (ioctl (tty, TIOCGLTC, <) != -1)
  1247.       {
  1248.     int erase, nextc;
  1249.  
  1250.     erase = lt.t_werasc;
  1251.     nextc = lt.t_lnextc;
  1252.  
  1253.     if (erase != -1 && keymap[erase].type == ISFUNC)
  1254.       keymap[erase].function = rl_unix_word_rubout;
  1255.  
  1256.     if (nextc != -1 && keymap[nextc].type == ISFUNC)
  1257.       keymap[nextc].function = rl_quoted_insert;
  1258.       }
  1259.   }
  1260. #endif /* TIOCGLTC */
  1261. #else /* not NEW_TTY_DRIVER */
  1262.  
  1263. #if defined (TERMIOS_TTY_DRIVER)
  1264.   struct termios ttybuff;
  1265. #else
  1266.   struct termio ttybuff;
  1267. #endif /* TERMIOS_TTY_DRIVER */
  1268.   int tty = fileno (rl_instream);
  1269.  
  1270. #if defined (TERMIOS_TTY_DRIVER)
  1271.   if (tcgetattr (tty, &ttybuff) != -1)
  1272. #else
  1273.   if (ioctl (tty, TCGETA, &ttybuff) != -1)
  1274. #endif /* !TERMIOS_TTY_DRIVER */
  1275.     {
  1276.       int erase, kill;
  1277.  
  1278.       erase = ttybuff.c_cc[VERASE];
  1279.       kill = ttybuff.c_cc[VKILL];
  1280.  
  1281.       if (erase != _POSIX_VDISABLE &&
  1282.       keymap[(unsigned char)erase].type == ISFUNC)
  1283.     keymap[(unsigned char)erase].function = rl_rubout;
  1284.  
  1285.       if (kill != _POSIX_VDISABLE &&
  1286.       keymap[(unsigned char)kill].type == ISFUNC)
  1287.     keymap[(unsigned char)kill].function = rl_unix_line_discard;
  1288.  
  1289. #if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
  1290.       {
  1291.     int nextc;
  1292.  
  1293.     nextc = ttybuff.c_cc[VLNEXT];
  1294.  
  1295.     if (nextc != _POSIX_VDISABLE &&
  1296.         keymap[(unsigned char)nextc].type == ISFUNC)
  1297.       keymap[(unsigned char)nextc].function = rl_quoted_insert;
  1298.       }
  1299. #endif /* VLNEXT && TERMIOS_TTY_DRIVER */
  1300.  
  1301. #if defined (VWERASE)
  1302.       {
  1303.     int werase;
  1304.  
  1305.     werase = ttybuff.c_cc[VWERASE];
  1306.  
  1307.     if (werase != _POSIX_VDISABLE &&
  1308.         keymap[(unsigned char)werase].type == ISFUNC)
  1309.       keymap[(unsigned char)werase].function = rl_unix_word_rubout;
  1310.       }
  1311. #endif /* VWERASE */
  1312.     }
  1313. #endif /* !NEW_TTY_DRIVER */
  1314. #endif /* def __GO32__ */
  1315. }
  1316.  
  1317.  
  1318. /* **************************************************************** */
  1319. /*                                    */
  1320. /*            Numeric Arguments                */
  1321. /*                                    */
  1322. /* **************************************************************** */
  1323.  
  1324. /* Handle C-u style numeric args, as well as M--, and M-digits. */
  1325.  
  1326. /* Add the current digit to the argument in progress. */
  1327. rl_digit_argument (ignore, key)
  1328.      int ignore, key;
  1329. {
  1330.   rl_pending_input = key;
  1331.   rl_digit_loop ();
  1332. }
  1333.  
  1334. /* What to do when you abort reading an argument. */
  1335. rl_discard_argument ()
  1336. {
  1337.   ding ();
  1338.   rl_clear_message ();
  1339.   rl_init_argument ();
  1340. }
  1341.  
  1342. /* Create a default argument. */
  1343. rl_init_argument ()
  1344. {
  1345.   rl_numeric_arg = rl_arg_sign = 1;
  1346.   rl_explicit_arg = 0;
  1347. }
  1348.  
  1349. /* C-u, universal argument.  Multiply the current argument by 4.
  1350.    Read a key.  If the key has nothing to do with arguments, then
  1351.    dispatch on it.  If the key is the abort character then abort. */
  1352. rl_universal_argument ()
  1353. {
  1354.   rl_numeric_arg *= 4;
  1355.   rl_digit_loop ();
  1356. }
  1357.  
  1358. rl_digit_loop ()
  1359. {
  1360.   int key, c;
  1361.   while (1)
  1362.     {
  1363.       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
  1364.       key = c = rl_read_key ();
  1365.  
  1366.       if (keymap[c].type == ISFUNC &&
  1367.       keymap[c].function == rl_universal_argument)
  1368.     {
  1369.       rl_numeric_arg *= 4;
  1370.       continue;
  1371.     }
  1372.       c = UNMETA (c);
  1373.       if (numeric (c))
  1374.     {
  1375.       if (rl_explicit_arg)
  1376.         rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
  1377.       else
  1378.         rl_numeric_arg = (c - '0');
  1379.       rl_explicit_arg = 1;
  1380.     }
  1381.       else
  1382.     {
  1383.       if (c == '-' && !rl_explicit_arg)
  1384.         {
  1385.           rl_numeric_arg = 1;
  1386.           rl_arg_sign = -1;
  1387.         }
  1388.       else
  1389.         {
  1390.           rl_clear_message ();
  1391.           rl_dispatch (key, keymap);
  1392.           return;
  1393.         }
  1394.     }
  1395.     }
  1396. }
  1397.  
  1398.  
  1399. /* **************************************************************** */
  1400. /*                                    */
  1401. /*            Display stuff                    */
  1402. /*                                    */
  1403. /* **************************************************************** */
  1404.  
  1405. /* This is the stuff that is hard for me.  I never seem to write good
  1406.    display routines in C.  Let's see how I do this time. */
  1407.  
  1408. /* (PWP) Well... Good for a simple line updater, but totally ignores
  1409.    the problems of input lines longer than the screen width.
  1410.  
  1411.    update_line and the code that calls it makes a multiple line,
  1412.    automatically wrapping line update.  Carefull attention needs
  1413.    to be paid to the vertical position variables.
  1414.  
  1415.    handling of terminals with autowrap on (incl. DEC braindamage)
  1416.    could be improved a bit.  Right now I just cheat and decrement
  1417.    screenwidth by one. */
  1418.  
  1419. /* Keep two buffers; one which reflects the current contents of the
  1420.    screen, and the other to draw what we think the new contents should
  1421.    be.  Then compare the buffers, and make whatever changes to the
  1422.    screen itself that we should.  Finally, make the buffer that we
  1423.    just drew into be the one which reflects the current contents of the
  1424.    screen, and place the cursor where it belongs.
  1425.  
  1426.    Commands that want to can fix the display themselves, and then let
  1427.    this function know that the display has been fixed by setting the
  1428.    RL_DISPLAY_FIXED variable.  This is good for efficiency. */
  1429.  
  1430. /* Termcap variables: */
  1431. extern char *term_up, *term_dc, *term_cr;
  1432. extern int screenheight, screenwidth, terminal_can_insert;
  1433.  
  1434. /* What YOU turn on when you have handled all redisplay yourself. */
  1435. int rl_display_fixed = 0;
  1436.  
  1437. /* The visible cursor position.  If you print some text, adjust this. */
  1438. int last_c_pos = 0;
  1439. int last_v_pos = 0;
  1440.  
  1441. /* The last left edge of text that was displayed.  This is used when
  1442.    doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
  1443. static int last_lmargin = 0;
  1444.  
  1445. /* The line display buffers.  One is the line currently displayed on
  1446.    the screen.  The other is the line about to be displayed. */
  1447. static char *visible_line = (char *)NULL;
  1448. static char *invisible_line = (char *)NULL;
  1449.  
  1450. /* Number of lines currently on screen minus 1. */
  1451. int vis_botlin = 0;
  1452.  
  1453. /* A buffer for `modeline' messages. */
  1454. char msg_buf[128];
  1455.  
  1456. /* Non-zero forces the redisplay even if we thought it was unnecessary. */
  1457. int forced_display = 0;
  1458.  
  1459. /* The stuff that gets printed out before the actual text of the line.
  1460.    This is usually pointing to rl_prompt. */
  1461. char *rl_display_prompt = (char *)NULL;
  1462.  
  1463. /* Default and initial buffer size.  Can grow. */
  1464. static int line_size = 1024;
  1465.  
  1466. /* Non-zero means to always use horizontal scrolling in line display. */
  1467. static int horizontal_scroll_mode = 0;
  1468.  
  1469. /* Non-zero means to display an asterisk at the starts of history lines
  1470.    which have been modified. */
  1471. static int mark_modified_lines = 0;
  1472.  
  1473. /* Non-zero means to use a visible bell if one is available rather than
  1474.    simply ringing the terminal bell. */
  1475. static int prefer_visible_bell = 0;
  1476.  
  1477. /* I really disagree with this, but my boss (among others) insists that we
  1478.    support compilers that don't work.  I don't think we are gaining by doing
  1479.    so; what is the advantage in producing better code if we can't use it? */
  1480. /* The following two declarations belong inside the
  1481.    function block, not here. */
  1482. static void move_cursor_relative ();
  1483. static void output_some_chars ();
  1484. static void output_character_function ();
  1485. static int compare_strings ();
  1486.  
  1487. /* Basic redisplay algorithm. */
  1488. rl_redisplay ()
  1489. {
  1490.   register int in, out, c, linenum;
  1491.   register char *line = invisible_line;
  1492.   char *prompt_this_line;
  1493.   int c_pos = 0;
  1494.   int inv_botlin = 0;        /* Number of lines in newly drawn buffer. */
  1495.  
  1496.   extern int readline_echoing_p;
  1497.  
  1498.   if (!readline_echoing_p)
  1499.     return;
  1500.  
  1501.   if (!rl_display_prompt)
  1502.     rl_display_prompt = "";
  1503.  
  1504.   if (!invisible_line)
  1505.     {
  1506.       visible_line = (char *)xmalloc (line_size);
  1507.       invisible_line = (char *)xmalloc (line_size);
  1508.       line = invisible_line;
  1509.       for (in = 0; in < line_size; in++)
  1510.     {
  1511.       visible_line[in] = 0;
  1512.       invisible_line[in] = 1;
  1513.     }
  1514.       rl_on_new_line ();
  1515.     }
  1516.  
  1517.   /* Draw the line into the buffer. */
  1518.   c_pos = -1;
  1519.  
  1520.   /* Mark the line as modified or not.  We only do this for history
  1521.      lines. */
  1522.   out = 0;
  1523.   if (mark_modified_lines && current_history () && rl_undo_list)
  1524.     {
  1525.       line[out++] = '*';
  1526.       line[out] = '\0';
  1527.     }
  1528.  
  1529.   /* If someone thought that the redisplay was handled, but the currently
  1530.      visible line has a different modification state than the one about
  1531.      to become visible, then correct the callers misconception. */
  1532.   if (visible_line[0] != invisible_line[0])
  1533.     rl_display_fixed = 0;
  1534.  
  1535.   prompt_this_line = rindex (rl_display_prompt, '\n');
  1536.   if (!prompt_this_line)
  1537.     prompt_this_line = rl_display_prompt;
  1538.   else
  1539.     {
  1540.       prompt_this_line++;
  1541.       if (forced_display)
  1542.     output_some_chars (rl_display_prompt,
  1543.                prompt_this_line - rl_display_prompt);
  1544.     }
  1545.  
  1546.   strncpy (line + out,  prompt_this_line, strlen (prompt_this_line));
  1547.   out += strlen (prompt_this_line);
  1548.   line[out] = '\0';
  1549.  
  1550.   for (in = 0; in < rl_end; in++)
  1551.     {
  1552.       c = (unsigned char)the_line[in];
  1553.  
  1554.       if (out + 1 >= line_size)
  1555.     {
  1556.       line_size *= 2;
  1557.       visible_line = (char *)xrealloc (visible_line, line_size);
  1558.       invisible_line = (char *)xrealloc (invisible_line, line_size);
  1559.       line = invisible_line;
  1560.     }
  1561.  
  1562.       if (in == rl_point)
  1563.     c_pos = out;
  1564.  
  1565.       if (c > 127)
  1566.     {
  1567.       line[out++] = 'M';
  1568.       line[out++] = '-';
  1569.       line[out++] = c - 128;
  1570.     }
  1571. #define DISPLAY_TABS
  1572. #if defined (DISPLAY_TABS)
  1573.       else if (c == '\t')
  1574.     {
  1575.       register int newout = (out | (int)7) + 1;
  1576.       while (out < newout)
  1577.         line[out++] = ' ';
  1578.     }
  1579. #endif
  1580.       else if (c < 32)
  1581.     {
  1582.       line[out++] = 'C';
  1583.       line[out++] = '-';
  1584.       line[out++] = c + 64;
  1585.     }
  1586.       else if (c == 127)
  1587.     {
  1588.       line[out++] = 'C';
  1589.       line[out++] = '-';
  1590.       line[out++] = '?';
  1591.     }
  1592.       else
  1593.     line[out++] = c;
  1594.     }
  1595.   line[out] = '\0';
  1596.   if (c_pos < 0)
  1597.     c_pos = out;
  1598.  
  1599.   /* PWP: now is when things get a bit hairy.  The visible and invisible
  1600.      line buffers are really multiple lines, which would wrap every
  1601.      (screenwidth - 1) characters.  Go through each in turn, finding
  1602.      the changed region and updating it.  The line order is top to bottom. */
  1603.  
  1604.   /* If we can move the cursor up and down, then use multiple lines,
  1605.      otherwise, let long lines display in a single terminal line, and
  1606.      horizontally scroll it. */
  1607.  
  1608.   if (!horizontal_scroll_mode && term_up && *term_up)
  1609.     {
  1610.       int total_screen_chars = (screenwidth * screenheight);
  1611.  
  1612.       if (!rl_display_fixed || forced_display)
  1613.     {
  1614.       forced_display = 0;
  1615.  
  1616.       /* If we have more than a screenful of material to display, then
  1617.          only display a screenful.  We should display the last screen,
  1618.          not the first.  I'll fix this in a minute. */
  1619.       if (out >= total_screen_chars)
  1620.         out = total_screen_chars - 1;
  1621.  
  1622.       /* Number of screen lines to display. */
  1623.       inv_botlin = out / screenwidth;
  1624.  
  1625.       /* For each line in the buffer, do the updating display. */
  1626.       for (linenum = 0; linenum <= inv_botlin; linenum++)
  1627.         update_line (linenum > vis_botlin ? ""
  1628.              : &visible_line[linenum * screenwidth],
  1629.              &invisible_line[linenum * screenwidth],
  1630.              linenum);
  1631.  
  1632.       /* We may have deleted some lines.  If so, clear the left over
  1633.          blank ones at the bottom out. */
  1634.       if (vis_botlin > inv_botlin)
  1635.         {
  1636.           char *tt;
  1637.           for (; linenum <= vis_botlin; linenum++)
  1638.         {
  1639.           tt = &visible_line[linenum * screenwidth];
  1640.           move_vert (linenum);
  1641.           move_cursor_relative (0, tt);
  1642.           clear_to_eol ((linenum == vis_botlin)?
  1643.                 strlen (tt) : screenwidth);
  1644.         }
  1645.         }
  1646.       vis_botlin = inv_botlin;
  1647.  
  1648.       /* Move the cursor where it should be. */
  1649.       move_vert (c_pos / screenwidth);
  1650.       move_cursor_relative (c_pos % screenwidth,
  1651.                 &invisible_line[(c_pos / screenwidth) * screenwidth]);
  1652.     }
  1653.     }
  1654.   else                /* Do horizontal scrolling. */
  1655.     {
  1656.       int lmargin;
  1657.  
  1658.       /* Always at top line. */
  1659.       last_v_pos = 0;
  1660.  
  1661.       /* If the display position of the cursor would be off the edge
  1662.      of the screen, start the display of this line at an offset that
  1663.      leaves the cursor on the screen. */
  1664.       if (c_pos - last_lmargin > screenwidth - 2)
  1665.     lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
  1666.       else if (c_pos - last_lmargin < 1)
  1667.     lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
  1668.       else
  1669.     lmargin = last_lmargin;
  1670.  
  1671.       /* If the first character on the screen isn't the first character
  1672.      in the display line, indicate this with a special character. */
  1673.       if (lmargin > 0)
  1674.     line[lmargin] = '<';
  1675.  
  1676.       if (lmargin + screenwidth < out)
  1677.     line[lmargin + screenwidth - 1] = '>';
  1678.  
  1679.       if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
  1680.     {
  1681.       forced_display = 0;
  1682.       update_line (&visible_line[last_lmargin],
  1683.                &invisible_line[lmargin], 0);
  1684.  
  1685.       move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
  1686.       last_lmargin = lmargin;
  1687.     }
  1688.     }
  1689.   fflush (out_stream);
  1690.  
  1691.   /* Swap visible and non-visible lines. */
  1692.   {
  1693.     char *temp = visible_line;
  1694.     visible_line = invisible_line;
  1695.     invisible_line = temp;
  1696.     rl_display_fixed = 0;
  1697.   }
  1698. }
  1699.  
  1700. /* PWP: update_line() is based on finding the middle difference of each
  1701.    line on the screen; vis:
  1702.  
  1703.                  /old first difference
  1704.     /beginning of line   |              /old last same       /old EOL
  1705.     v             v              v                    v
  1706. old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
  1707. new:    eddie> Oh, my little buggy says to me, as lurgid as
  1708.     ^             ^        ^               ^
  1709.     \beginning of line   |        \new last same       \new end of line
  1710.                  \new first difference
  1711.  
  1712.    All are character pointers for the sake of speed.  Special cases for
  1713.    no differences, as well as for end of line additions must be handeled.
  1714.  
  1715.    Could be made even smarter, but this works well enough */
  1716. static
  1717. update_line (old, new, current_line)
  1718.      register char *old, *new;
  1719.      int current_line;
  1720. {
  1721.   register char *ofd, *ols, *oe, *nfd, *nls, *ne;
  1722.   int lendiff, wsatend;
  1723.  
  1724.   /* Find first difference. */
  1725.   for (ofd = old, nfd = new;
  1726.        (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
  1727.        ofd++, nfd++)
  1728.     ;
  1729.  
  1730.   /* Move to the end of the screen line. */
  1731.   for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
  1732.   for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
  1733.  
  1734.   /* If no difference, continue to next line. */
  1735.   if (ofd == oe && nfd == ne)
  1736.     return;
  1737.  
  1738.   wsatend = 1;            /* flag for trailing whitespace */
  1739.   ols = oe - 1;            /* find last same */
  1740.   nls = ne - 1;
  1741.   while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
  1742.     {
  1743.       if (*ols != ' ')
  1744.     wsatend = 0;
  1745.       ols--;
  1746.       nls--;
  1747.     }
  1748.  
  1749.   if (wsatend)
  1750.     {
  1751.       ols = oe;
  1752.       nls = ne;
  1753.     }
  1754.   else if (*ols != *nls)
  1755.     {
  1756.       if (*ols)            /* don't step past the NUL */
  1757.     ols++;
  1758.       if (*nls)
  1759.     nls++;
  1760.     }
  1761.  
  1762.   move_vert (current_line);
  1763.   move_cursor_relative (ofd - old, old);
  1764.  
  1765.   /* if (len (new) > len (old)) */
  1766.   lendiff = (nls - nfd) - (ols - ofd);
  1767.  
  1768.   /* Insert (diff(len(old),len(new)) ch */
  1769.   if (lendiff > 0)
  1770.     {
  1771.       if (terminal_can_insert)
  1772.     {
  1773.       extern char *term_IC;
  1774.  
  1775.       /* Sometimes it is cheaper to print the characters rather than
  1776.          use the terminal's capabilities. */
  1777.       if ((2 * (ne - nfd)) < lendiff && !term_IC)
  1778.         {
  1779.           output_some_chars (nfd, (ne - nfd));
  1780.           last_c_pos += (ne - nfd);
  1781.         }
  1782.       else
  1783.         {
  1784.           if (*ols)
  1785.         {
  1786.           insert_some_chars (nfd, lendiff);
  1787.           last_c_pos += lendiff;
  1788.         }
  1789.           else
  1790.         {
  1791.           /* At the end of a line the characters do not have to
  1792.              be "inserted".  They can just be placed on the screen. */
  1793.           output_some_chars (nfd, lendiff);
  1794.           last_c_pos += lendiff;
  1795.         }
  1796.           /* Copy (new) chars to screen from first diff to last match. */
  1797.           if (((nls - nfd) - lendiff) > 0)
  1798.         {
  1799.           output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
  1800.           last_c_pos += ((nls - nfd) - lendiff);
  1801.         }
  1802.         }
  1803.     }
  1804.       else
  1805.     {        /* cannot insert chars, write to EOL */
  1806.       output_some_chars (nfd, (ne - nfd));
  1807.       last_c_pos += (ne - nfd);
  1808.     }
  1809.     }
  1810.   else                /* Delete characters from line. */
  1811.     {
  1812.       /* If possible and inexpensive to use terminal deletion, then do so. */
  1813.       if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
  1814.     {
  1815.       if (lendiff)
  1816.         delete_chars (-lendiff); /* delete (diff) characters */
  1817.  
  1818.       /* Copy (new) chars to screen from first diff to last match */
  1819.       if ((nls - nfd) > 0)
  1820.         {
  1821.           output_some_chars (nfd, (nls - nfd));
  1822.           last_c_pos += (nls - nfd);
  1823.         }
  1824.     }
  1825.       /* Otherwise, print over the existing material. */
  1826.       else
  1827.     {
  1828.       output_some_chars (nfd, (ne - nfd));
  1829.       last_c_pos += (ne - nfd);
  1830.       clear_to_eol ((oe - old) - (ne - new));
  1831.     }
  1832.     }
  1833. }
  1834.  
  1835. /* (PWP) tell the update routines that we have moved onto a
  1836.    new (empty) line. */
  1837. rl_on_new_line ()
  1838. {
  1839.   if (visible_line)
  1840.     visible_line[0] = '\0';
  1841.  
  1842.   last_c_pos = last_v_pos = 0;
  1843.   vis_botlin = last_lmargin = 0;
  1844. }
  1845.  
  1846. /* Actually update the display, period. */
  1847. rl_forced_update_display ()
  1848. {
  1849.   if (visible_line)
  1850.     {
  1851.       register char *temp = visible_line;
  1852.  
  1853.       while (*temp) *temp++ = '\0';
  1854.     }
  1855.   rl_on_new_line ();
  1856.   forced_display++;
  1857.   rl_redisplay ();
  1858. }
  1859.  
  1860. /* Move the cursor from last_c_pos to NEW, which are buffer indices.
  1861.    DATA is the contents of the screen line of interest; i.e., where
  1862.    the movement is being done. */
  1863. static void
  1864. move_cursor_relative (new, data)
  1865.      int new;
  1866.      char *data;
  1867. {
  1868.   register int i;
  1869.  
  1870.   /* It may be faster to output a CR, and then move forwards instead
  1871.      of moving backwards. */
  1872.   if (new + 1 < last_c_pos - new)
  1873.     {
  1874. #ifdef __MSDOS__
  1875.       putc('\r', out_stream);
  1876. #else
  1877.       tputs (term_cr, 1, output_character_function);
  1878. #endif
  1879.       last_c_pos = 0;
  1880.     }
  1881.  
  1882.   if (last_c_pos == new) return;
  1883.  
  1884.   if (last_c_pos < new)
  1885.     {
  1886.       /* Move the cursor forward.  We do it by printing the command
  1887.      to move the cursor forward if there is one, else print that
  1888.      portion of the output buffer again.  Which is cheaper? */
  1889.  
  1890.       /* The above comment is left here for posterity.  It is faster
  1891.      to print one character (non-control) than to print a control
  1892.      sequence telling the terminal to move forward one character.
  1893.      That kind of control is for people who don't know what the
  1894.      data is underneath the cursor. */
  1895. #if defined (HACK_TERMCAP_MOTION)
  1896.       extern char *term_forward_char;
  1897.  
  1898.       if (term_forward_char)
  1899.     for (i = last_c_pos; i < new; i++)
  1900.       tputs (term_forward_char, 1, output_character_function);
  1901.       else
  1902.     for (i = last_c_pos; i < new; i++)
  1903.       putc (data[i], out_stream);
  1904. #else
  1905.       for (i = last_c_pos; i < new; i++)
  1906.     putc (data[i], out_stream);
  1907. #endif                /* HACK_TERMCAP_MOTION */
  1908.     }
  1909.   else
  1910.     backspace (last_c_pos - new);
  1911.   last_c_pos = new;
  1912. }
  1913.  
  1914. /* PWP: move the cursor up or down. */
  1915. move_vert (to)
  1916.      int to;
  1917. {
  1918.   void output_character_function ();
  1919.   register int delta, i;
  1920.  
  1921.   if (last_v_pos == to) return;
  1922.  
  1923.   if (to > screenheight)
  1924.     return;
  1925.  
  1926. #ifdef __GO32__
  1927.   {
  1928.     int cur_r, cur_c;
  1929.     ScreenGetCursor(&cur_r, &cur_c);
  1930.     ScreenSetCursor(cur_r+to-last_v_pos, cur_c);
  1931.   }
  1932. #else /* __GO32__ */
  1933.   if ((delta = to - last_v_pos) > 0)
  1934.     {
  1935.       for (i = 0; i < delta; i++)
  1936.     putc ('\n', out_stream);
  1937.       tputs (term_cr, 1, output_character_function);
  1938.       last_c_pos = 0;
  1939.     }
  1940.   else
  1941.     {            /* delta < 0 */
  1942.       if (term_up && *term_up)
  1943.     for (i = 0; i < -delta; i++)
  1944.       tputs (term_up, 1, output_character_function);
  1945.     }
  1946. #endif /* __GO32__ */
  1947.   last_v_pos = to;        /* now to is here */
  1948. }
  1949.  
  1950. /* Physically print C on out_stream.  This is for functions which know
  1951.    how to optimize the display. */
  1952. rl_show_char (c)
  1953.      int c;
  1954. {
  1955.   if (c > 127)
  1956.     {
  1957.       fprintf (out_stream, "M-");
  1958.       c -= 128;
  1959.     }
  1960.  
  1961. #if defined (DISPLAY_TABS)
  1962.   if (c < 32 && c != '\t')
  1963. #else
  1964.   if (c < 32)
  1965. #endif
  1966.     {
  1967.  
  1968.       c += 64;
  1969.     }
  1970.  
  1971.   putc (c, out_stream);
  1972.   fflush (out_stream);
  1973. }
  1974.  
  1975. #if defined (DISPLAY_TABS)
  1976. int
  1977. rl_character_len (c, pos)
  1978.      register int c, pos;
  1979. {
  1980.   if (c < ' ' || c > 126)
  1981.     {
  1982.       if (c == '\t')
  1983.     return (((pos | (int)7) + 1) - pos);
  1984.       else
  1985.     return (3);
  1986.     }
  1987.   else
  1988.     return (1);
  1989. }
  1990. #else
  1991. int
  1992. rl_character_len (c)
  1993.      int c;
  1994. {
  1995.   if (c < ' ' || c > 126)
  1996.     return (3);
  1997.   else
  1998.     return (1);
  1999. }
  2000. #endif  /* DISPLAY_TAB */
  2001.  
  2002. /* How to print things in the "echo-area".  The prompt is treated as a
  2003.    mini-modeline. */
  2004. rl_message (string, arg1, arg2)
  2005.      char *string;
  2006. {
  2007.   sprintf (msg_buf, string, arg1, arg2);
  2008.   rl_display_prompt = msg_buf;
  2009.   rl_redisplay ();
  2010. }
  2011.  
  2012. /* How to clear things from the "echo-area". */
  2013. rl_clear_message ()
  2014. {
  2015.   rl_display_prompt = rl_prompt;
  2016.   rl_redisplay ();
  2017. }
  2018.  
  2019. /* **************************************************************** */
  2020. /*                                    */
  2021. /*            Terminal and Termcap                */
  2022. /*                                    */
  2023. /* **************************************************************** */
  2024.  
  2025. static char *term_buffer = (char *)NULL;
  2026. static char *term_string_buffer = (char *)NULL;
  2027.  
  2028. /* Non-zero means this terminal can't really do anything. */
  2029. int dumb_term = 0;
  2030.  
  2031. /* On Solaris2, sys/types.h brings in sys/reg.h,
  2032.    which screws up the Termcap variable PC, used below.  */
  2033.  
  2034. #undef    PC    
  2035.  
  2036. char PC;
  2037. char *BC, *UP;
  2038.  
  2039. /* Some strings to control terminal actions.  These are output by tputs (). */
  2040. char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
  2041.  
  2042. int screenwidth, screenheight;
  2043.  
  2044. /* Non-zero if we determine that the terminal can do character insertion. */
  2045. int terminal_can_insert = 0;
  2046.  
  2047. /* How to insert characters. */
  2048. char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
  2049.  
  2050. /* How to delete characters. */
  2051. char *term_dc, *term_DC;
  2052.  
  2053. #if defined (HACK_TERMCAP_MOTION)
  2054. char *term_forward_char;
  2055. #endif  /* HACK_TERMCAP_MOTION */
  2056.  
  2057. /* How to go up a line. */
  2058. char *term_up;
  2059.  
  2060. /* A visible bell, if the terminal can be made to flash the screen. */
  2061. char *visible_bell;
  2062.  
  2063. /* Re-initialize the terminal considering that the TERM/TERMCAP variable
  2064.    has changed. */
  2065. rl_reset_terminal (terminal_name)
  2066.      char *terminal_name;
  2067. {
  2068.   init_terminal_io (terminal_name);
  2069. }
  2070.  
  2071. init_terminal_io (terminal_name)
  2072.      char *terminal_name;
  2073. {
  2074. #ifdef __GO32__
  2075.   screenwidth = ScreenCols();
  2076.   screenheight = ScreenRows();
  2077.   term_cr = "\r";
  2078.   term_im = term_ei = term_ic = term_IC = (char *)NULL;
  2079.   term_up = term_dc = term_DC = visible_bell = (char *)NULL;
  2080. #if defined (HACK_TERMCAP_MOTION)
  2081.       term_forward_char = (char *)NULL;
  2082. #endif
  2083.   terminal_can_insert = 0;
  2084.   return;
  2085. #else
  2086.   extern char *tgetstr ();
  2087.   char *term, *buffer;
  2088. #if defined (TIOCGWINSZ) && !defined (TIOCGWINSZ_BROKEN)
  2089.   struct winsize window_size;
  2090. #endif
  2091.   int tty;
  2092.  
  2093.   term = terminal_name ? terminal_name : getenv ("TERM");
  2094.  
  2095.   if (!term_string_buffer)
  2096.     term_string_buffer = (char *)xmalloc (2048);
  2097.  
  2098.   if (!term_buffer)
  2099.     term_buffer = (char *)xmalloc (2048);
  2100.  
  2101.   buffer = term_string_buffer;
  2102.  
  2103.   term_clrpag = term_cr = term_clreol = (char *)NULL;
  2104.  
  2105.   if (!term)
  2106.     term = "dumb";
  2107.  
  2108.   if (tgetent (term_buffer, term) <= 0)
  2109.     {
  2110.       dumb_term = 1;
  2111.       screenwidth = 79;
  2112.       screenheight = 24;
  2113.       term_cr = "\r";
  2114.       term_im = term_ei = term_ic = term_IC = (char *)NULL;
  2115.       term_up = term_dc = term_DC = visible_bell = (char *)NULL;
  2116. #if defined (HACK_TERMCAP_MOTION)
  2117.       term_forward_char = (char *)NULL;
  2118. #endif
  2119.       terminal_can_insert = 0;
  2120.       return;
  2121.     }
  2122.  
  2123.   BC = tgetstr ("pc", &buffer);
  2124.   PC = buffer ? *buffer : 0;
  2125.  
  2126.   term_backspace = tgetstr ("le", &buffer);
  2127.  
  2128.   term_cr = tgetstr ("cr", &buffer);
  2129.   term_clreol = tgetstr ("ce", &buffer);
  2130.   term_clrpag = tgetstr ("cl", &buffer);
  2131.  
  2132.   if (!term_cr)
  2133.     term_cr =  "\r";
  2134.  
  2135. #if defined (HACK_TERMCAP_MOTION)
  2136.   term_forward_char = tgetstr ("nd", &buffer);
  2137. #endif  /* HACK_TERMCAP_MOTION */
  2138.  
  2139.   if (rl_instream)
  2140.     tty = fileno (rl_instream);
  2141.   else
  2142.     tty = 0;
  2143.  
  2144.   screenwidth = screenheight = 0;
  2145. #if defined (TIOCGWINSZ) && !defined (TIOCGWINSZ_BROKEN)
  2146.   if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
  2147.     {
  2148.       screenwidth = (int) window_size.ws_col;
  2149.       screenheight = (int) window_size.ws_row;
  2150.     }
  2151. #endif
  2152.  
  2153.   if (screenwidth <= 0 || screenheight <= 0)
  2154.     {
  2155.       screenwidth = tgetnum ("co");
  2156.       screenheight = tgetnum ("li");
  2157.     }
  2158.  
  2159.   screenwidth--;
  2160.  
  2161.   if (screenwidth <= 0)
  2162.     screenwidth = 79;
  2163.  
  2164.   if (screenheight <= 0)
  2165.     screenheight = 24;
  2166.  
  2167.   term_im = tgetstr ("im", &buffer);
  2168.   term_ei = tgetstr ("ei", &buffer);
  2169.   term_IC = tgetstr ("IC", &buffer);
  2170.   term_ic = tgetstr ("ic", &buffer);
  2171.  
  2172.   /* "An application program can assume that the terminal can do
  2173.       character insertion if *any one of* the capabilities `IC',
  2174.       `im', `ic' or `ip' is provided."  But we can't do anything if
  2175.       only `ip' is provided, so... */
  2176.   terminal_can_insert = (term_IC || term_im || term_ic);
  2177.  
  2178.   term_up = tgetstr ("up", &buffer);
  2179.   term_dc = tgetstr ("dc", &buffer);
  2180.   term_DC = tgetstr ("DC", &buffer);
  2181.  
  2182.   visible_bell = tgetstr ("vb", &buffer);
  2183. #endif /* !__GO32__ */
  2184. }
  2185.  
  2186. /* A function for the use of tputs () */
  2187. static void
  2188. output_character_function (c)
  2189.      int c;
  2190. {
  2191.   putc (c, out_stream);
  2192. }
  2193.  
  2194. /* Write COUNT characters from STRING to the output stream. */
  2195. static void
  2196. output_some_chars (string, count)
  2197.      char *string;
  2198.      int count;
  2199. {
  2200.   fwrite (string, 1, count, out_stream);
  2201. }
  2202.  
  2203. /* Delete COUNT characters from the display line. */
  2204. static
  2205. delete_chars (count)
  2206.      int count;
  2207. {
  2208. #ifdef __GO32__
  2209.   int r, c, w;
  2210.   ScreenGetCursor(&r, &c);
  2211.   w = ScreenCols();
  2212.   memcpy(ScreenPrimary+r*w+c, ScreenPrimary+r*w+c+count, w-c-count);
  2213.   memset(ScreenPrimary+r*w+w-count, 0, count*2);
  2214. #else /* __GO32__ */
  2215.   if (count > screenwidth)
  2216.     return;
  2217.  
  2218.   if (term_DC && *term_DC)
  2219.     {
  2220.       char *tgoto (), *buffer;
  2221.       buffer = tgoto (term_DC, 0, count);
  2222.       tputs (buffer, 1, output_character_function);
  2223.     }
  2224.   else
  2225.     {
  2226.       if (term_dc && *term_dc)
  2227.     while (count--)
  2228.       tputs (term_dc, 1, output_character_function);
  2229.     }
  2230. #endif /* __GO32__ */
  2231. }
  2232.  
  2233. /* Insert COUNT characters from STRING to the output stream. */
  2234. static void
  2235. insert_some_chars (string, count)
  2236.      char *string;
  2237.      int count;
  2238. {
  2239. #ifdef __GO32__
  2240.   int r, c, w;
  2241.   ScreenGetCursor(&r, &c);
  2242.   w = ScreenCols();
  2243.   memcpy(ScreenPrimary+r*w+c+count, ScreenPrimary+r*w+c, w-c-count);
  2244.   /* Print the text. */
  2245.   output_some_chars (string, count);
  2246. #else /* __GO32__ */
  2247.   /* If IC is defined, then we do not have to "enter" insert mode. */
  2248.   if (term_IC)
  2249.     {
  2250.       char *tgoto (), *buffer;
  2251.       buffer = tgoto (term_IC, 0, count);
  2252.       tputs (buffer, 1, output_character_function);
  2253.       output_some_chars (string, count);
  2254.     }
  2255.   else
  2256.     {
  2257.       register int i;
  2258.  
  2259.       /* If we have to turn on insert-mode, then do so. */
  2260.       if (term_im && *term_im)
  2261.     tputs (term_im, 1, output_character_function);
  2262.  
  2263.       /* If there is a special command for inserting characters, then
  2264.      use that first to open up the space. */
  2265.       if (term_ic && *term_ic)
  2266.     {
  2267.       for (i = count; i--; )
  2268.         tputs (term_ic, 1, output_character_function);
  2269.     }
  2270.  
  2271.       /* Print the text. */
  2272.       output_some_chars (string, count);
  2273.  
  2274.       /* If there is a string to turn off insert mode, we had best use
  2275.      it now. */
  2276.       if (term_ei && *term_ei)
  2277.     tputs (term_ei, 1, output_character_function);
  2278.     }
  2279. #endif /* __GO32__ */
  2280. }
  2281.  
  2282. /* Move the cursor back. */
  2283. backspace (count)
  2284.      int count;
  2285. {
  2286.   register int i;
  2287.  
  2288. #ifndef __GO32__
  2289.   if (term_backspace)
  2290.     for (i = 0; i < count; i++)
  2291.       tputs (term_backspace, 1, output_character_function);
  2292.   else
  2293. #endif /* !__GO32__ */
  2294.     for (i = 0; i < count; i++)
  2295.       putc ('\b', out_stream);
  2296. }
  2297.  
  2298. /* Move to the start of the next line. */
  2299. crlf ()
  2300. {
  2301. #if defined (NEW_TTY_DRIVER)
  2302.   tputs (term_cr, 1, output_character_function);
  2303. #endif /* NEW_TTY_DRIVER */
  2304.   putc ('\n', out_stream);
  2305. }
  2306.  
  2307. /* Clear to the end of the line.  COUNT is the minimum
  2308.    number of character spaces to clear, */
  2309. static void
  2310. clear_to_eol (count)
  2311.      int count;
  2312. {
  2313. #ifndef __GO32__
  2314.   if (term_clreol)
  2315.     {
  2316.       tputs (term_clreol, 1, output_character_function);
  2317.     }
  2318.   else
  2319. #endif /* !__GO32__ */
  2320.     {
  2321.       register int i;
  2322.  
  2323.       /* Do one more character space. */
  2324.       count++;
  2325.  
  2326.       for (i = 0; i < count; i++)
  2327.     putc (' ', out_stream);
  2328.  
  2329.       backspace (count);
  2330.     }
  2331. }
  2332.  
  2333.  
  2334. /* **************************************************************** */
  2335. /*                                    */
  2336. /*              Saving and Restoring the TTY                */
  2337. /*                                    */
  2338. /* **************************************************************** */
  2339.  
  2340. /* Non-zero means that the terminal is in a prepped state. */
  2341. static int terminal_prepped = 0;
  2342.  
  2343. #if defined (NEW_TTY_DRIVER)
  2344.  
  2345. /* Standard flags, including ECHO. */
  2346. static int original_tty_flags = 0;
  2347.  
  2348. /* Local mode flags, like LPASS8. */
  2349. static int local_mode_flags = 0;
  2350.  
  2351. /* Terminal characters.  This has C-s and C-q in it. */
  2352. static struct tchars original_tchars;
  2353.  
  2354. /* Local special characters.  This has the interrupt characters in it. */
  2355. #if defined (TIOCGLTC)
  2356. static struct ltchars original_ltchars;
  2357. #endif
  2358.  
  2359. /* We use this to get and set the tty_flags. */
  2360. static struct sgttyb the_ttybuff;
  2361.  
  2362. /* Put the terminal in CBREAK mode so that we can detect key presses. */
  2363. static void
  2364. rl_prep_terminal ()
  2365. {
  2366. #ifndef __GO32__
  2367.   int tty = fileno (rl_instream);
  2368.   SIGNALS_DECLARE_SAVED (saved_signals);
  2369.  
  2370.   if (terminal_prepped)
  2371.     return;
  2372.  
  2373.   SIGNALS_BLOCK (SIGINT, saved_signals);
  2374.  
  2375.   /* We always get the latest tty values.  Maybe stty changed them. */
  2376.   ioctl (tty, TIOCGETP, &the_ttybuff);
  2377.   original_tty_flags = the_ttybuff.sg_flags;
  2378.  
  2379.   readline_echoing_p = (original_tty_flags & ECHO);
  2380.  
  2381. #if defined (TIOCLGET)
  2382.   ioctl (tty, TIOCLGET, &local_mode_flags);
  2383. #endif
  2384.  
  2385. #if !defined (ANYP)
  2386. #  define ANYP (EVENP | ODDP)
  2387. #endif
  2388.  
  2389.   /* If this terminal doesn't care how the 8th bit is used,
  2390.      then we can use it for the meta-key.  We check by seeing
  2391.      if BOTH odd and even parity are allowed. */
  2392.   if (the_ttybuff.sg_flags & ANYP)
  2393.     {
  2394. #if defined (PASS8)
  2395.       the_ttybuff.sg_flags |= PASS8;
  2396. #endif
  2397.  
  2398.       /* Hack on local mode flags if we can. */
  2399. #if defined (TIOCLGET) && defined (LPASS8)
  2400.       {
  2401.     int flags;
  2402.     flags = local_mode_flags | LPASS8;
  2403.     ioctl (tty, TIOCLSET, &flags);
  2404.       }
  2405. #endif /* TIOCLGET && LPASS8 */
  2406.     }
  2407.  
  2408. #if defined (TIOCGETC)
  2409.   {
  2410.     struct tchars temp;
  2411.  
  2412.     ioctl (tty, TIOCGETC, &original_tchars);
  2413.     temp = original_tchars;
  2414.  
  2415. #if defined (USE_XON_XOFF)
  2416.     /* Get rid of C-s and C-q.
  2417.        We remember the value of startc (C-q) so that if the terminal is in
  2418.        xoff state, the user can xon it by pressing that character. */
  2419.     xon_char = temp.t_startc;
  2420.     temp.t_stopc = -1;
  2421.     temp.t_startc = -1;
  2422.  
  2423.     /* If there is an XON character, bind it to restart the output. */
  2424.     if (xon_char != -1)
  2425.       rl_bind_key (xon_char, rl_restart_output);
  2426. #endif /* USE_XON_XOFF */
  2427.  
  2428.     /* If there is an EOF char, bind eof_char to it. */
  2429.     if (temp.t_eofc != -1)
  2430.       eof_char = temp.t_eofc;
  2431.  
  2432. #if defined (NO_KILL_INTR)
  2433.     /* Get rid of C-\ and C-c. */
  2434.     temp.t_intrc = temp.t_quitc = -1;
  2435. #endif /* NO_KILL_INTR */
  2436.  
  2437.     ioctl (tty, TIOCSETC, &temp);
  2438.   }
  2439. #endif /* TIOCGETC */
  2440.  
  2441. #if defined (TIOCGLTC)
  2442.   {
  2443.     struct ltchars temp;
  2444.  
  2445.     ioctl (tty, TIOCGLTC, &original_ltchars);
  2446.     temp = original_ltchars;
  2447.  
  2448.     /* Make the interrupt keys go away.  Just enough to make people
  2449.        happy. */
  2450.     temp.t_dsuspc = -1;    /* C-y */
  2451.     temp.t_lnextc = -1;    /* C-v */
  2452.  
  2453.     ioctl (tty, TIOCSLTC, &temp);
  2454.   }
  2455. #endif /* TIOCGLTC */
  2456.  
  2457.   the_ttybuff.sg_flags &= ~(ECHO | CRMOD);
  2458.   the_ttybuff.sg_flags |= CBREAK;
  2459.   ioctl (tty, TIOCSETN, &the_ttybuff);
  2460.  
  2461.   terminal_prepped = 1;
  2462.  
  2463.   SIGNALS_RESTORE (saved_signals);
  2464. #endif /* !__GO32__ */
  2465. }
  2466.  
  2467. /* Restore the terminal to its original state. */
  2468. static void
  2469. rl_deprep_terminal ()
  2470. {
  2471. #ifndef __GO32__
  2472.   int tty = fileno (rl_instream);
  2473.   SIGNALS_DECLARE_SAVED (saved_signals);
  2474.  
  2475.   if (!terminal_prepped)
  2476.     return;
  2477.  
  2478.   SIGNALS_BLOCK (SIGINT, saved_signals);
  2479.  
  2480.   the_ttybuff.sg_flags = original_tty_flags;
  2481.   ioctl (tty, TIOCSETN, &the_ttybuff);
  2482.   readline_echoing_p = 1;
  2483.  
  2484. #if defined (TIOCLGET)
  2485.   ioctl (tty, TIOCLSET, &local_mode_flags);
  2486. #endif
  2487.  
  2488. #if defined (TIOCSLTC)
  2489.   ioctl (tty, TIOCSLTC, &original_ltchars);
  2490. #endif
  2491.  
  2492. #if defined (TIOCSETC)
  2493.   ioctl (tty, TIOCSETC, &original_tchars);
  2494. #endif
  2495.   terminal_prepped = 0;
  2496.  
  2497.   SIGNALS_RESTORE (saved_signals);
  2498. #endif /* !__GO32 */
  2499. }
  2500.  
  2501. #else  /* !defined (NEW_TTY_DRIVER) */
  2502.  
  2503. #if !defined (VMIN)
  2504. #define VMIN VEOF
  2505. #endif
  2506.  
  2507. #if !defined (VTIME)
  2508. #define VTIME VEOL
  2509. #endif
  2510.  
  2511. #ifndef __GO32__
  2512. #if defined (TERMIOS_TTY_DRIVER)
  2513. static struct termios otio;
  2514. #else
  2515. static struct termio otio;
  2516. #endif /* !TERMIOS_TTY_DRIVER */
  2517. #endif /* __GO32__ */
  2518.  
  2519. static void
  2520. rl_prep_terminal ()
  2521. {
  2522. #ifndef __GO32__
  2523.   int tty = fileno (rl_instream);
  2524. #if defined (TERMIOS_TTY_DRIVER)
  2525.   struct termios tio;
  2526. #else
  2527.   struct termio tio;
  2528. #endif /* !TERMIOS_TTY_DRIVER */
  2529.  
  2530.   SIGNALS_DECLARE_SAVED (saved_signals);
  2531.  
  2532.   if (terminal_prepped)
  2533.     return;
  2534.  
  2535.   /* Try to keep this function from being INTerrupted.  We can do it
  2536.      on POSIX and systems with BSD-like signal handling. */
  2537.   SIGNALS_BLOCK (SIGINT, saved_signals);
  2538.  
  2539. #if defined (TERMIOS_TTY_DRIVER)
  2540.   tcgetattr (tty, &tio);
  2541. #else
  2542.   ioctl (tty, TCGETA, &tio);
  2543. #endif /* !TERMIOS_TTY_DRIVER */
  2544.  
  2545.   otio = tio;
  2546.  
  2547.   readline_echoing_p = (tio.c_lflag & ECHO);
  2548.  
  2549.   tio.c_lflag &= ~(ICANON|ECHO);
  2550.  
  2551.   if (otio.c_cc[VEOF] != _POSIX_VDISABLE)
  2552.     eof_char = otio.c_cc[VEOF];
  2553.  
  2554. #if defined (USE_XON_XOFF)
  2555. #if defined (IXANY)
  2556.   tio.c_iflag &= ~(IXON|IXOFF|IXANY);
  2557. #else
  2558.   /* `strict' Posix systems do not define IXANY. */
  2559.   tio.c_iflag &= ~(IXON|IXOFF);
  2560. #endif /* IXANY */
  2561. #endif /* USE_XON_XOFF */
  2562.  
  2563.   /* Only turn this off if we are using all 8 bits. */
  2564.   /* |ISTRIP|INPCK */
  2565.   tio.c_iflag &= ~(ISTRIP | INPCK);
  2566.  
  2567.   /* Make sure we differentiate between CR and NL on input. */
  2568.   tio.c_iflag &= ~(ICRNL | INLCR);
  2569.  
  2570. #if !defined (HANDLE_SIGNALS)
  2571.   tio.c_lflag &= ~ISIG;
  2572. #else
  2573.   tio.c_lflag |= ISIG;
  2574. #endif
  2575.  
  2576.   tio.c_cc[VMIN] = 1;
  2577.   tio.c_cc[VTIME] = 0;
  2578.  
  2579.   /* Turn off characters that we need on Posix systems with job control,
  2580.      just to be sure.  This includes ^Y and ^V.  This should not really
  2581.      be necessary.  */
  2582. #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_JOB_CONTROL)
  2583.  
  2584. #if defined (VLNEXT)
  2585.   tio.c_cc[VLNEXT] = _POSIX_VDISABLE;
  2586. #endif
  2587.  
  2588. #if defined (VDSUSP)
  2589.   tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
  2590. #endif
  2591.  
  2592. #endif /* POSIX && JOB_CONTROL */
  2593.  
  2594. #if defined (TERMIOS_TTY_DRIVER)
  2595.   tcsetattr (tty, TCSADRAIN, &tio);
  2596.   tcflow (tty, TCOON);        /* Simulate a ^Q. */
  2597. #else
  2598.   ioctl (tty, TCSETAW, &tio);
  2599.   ioctl (tty, TCXONC, 1);    /* Simulate a ^Q. */
  2600. #endif /* !TERMIOS_TTY_DRIVER */
  2601.  
  2602.   terminal_prepped = 1;
  2603.  
  2604.   SIGNALS_RESTORE (saved_signals);
  2605. #endif /* !__GO32__ */
  2606. }
  2607.  
  2608. static void
  2609. rl_deprep_terminal ()
  2610. {
  2611. #ifndef __GO32__ 
  2612.   int tty = fileno (rl_instream);
  2613.  
  2614.   /* Try to keep this function from being INTerrupted.  We can do it
  2615.      on POSIX and systems with BSD-like signal handling. */
  2616.   SIGNALS_DECLARE_SAVED (saved_signals);
  2617.  
  2618.   if (!terminal_prepped)
  2619.     return;
  2620.  
  2621.   SIGNALS_BLOCK (SIGINT, saved_signals);
  2622.  
  2623. #if defined (TERMIOS_TTY_DRIVER)
  2624.   tcsetattr (tty, TCSADRAIN, &otio);
  2625.   tcflow (tty, TCOON);        /* Simulate a ^Q. */
  2626. #else /* TERMIOS_TTY_DRIVER */
  2627.   ioctl (tty, TCSETAW, &otio);
  2628.   ioctl (tty, TCXONC, 1);    /* Simulate a ^Q. */
  2629. #endif /* !TERMIOS_TTY_DRIVER */
  2630.  
  2631.   terminal_prepped = 0;
  2632.  
  2633.   SIGNALS_RESTORE (saved_signals);
  2634. #endif /* !__GO32__ */
  2635. }
  2636. #endif  /* NEW_TTY_DRIVER */
  2637.  
  2638.  
  2639. /* **************************************************************** */
  2640. /*                                    */
  2641. /*            Utility Functions                */
  2642. /*                                    */
  2643. /* **************************************************************** */
  2644.  
  2645. /* Return 0 if C is not a member of the class of characters that belong
  2646.    in words, or 1 if it is. */
  2647.  
  2648. int allow_pathname_alphabetic_chars = 0;
  2649. char *pathname_alphabetic_chars = "/-_=~.#$";
  2650.  
  2651. int
  2652. alphabetic (c)
  2653.      int c;
  2654. {
  2655.   if (pure_alphabetic (c) || (numeric (c)))
  2656.     return (1);
  2657.  
  2658.   if (allow_pathname_alphabetic_chars)
  2659.     return ((int)rindex (pathname_alphabetic_chars, c));
  2660.   else
  2661.     return (0);
  2662. }
  2663.  
  2664. /* Return non-zero if C is a numeric character. */
  2665. int
  2666. numeric (c)
  2667.      int c;
  2668. {
  2669.   return (c >= '0' && c <= '9');
  2670. }
  2671.  
  2672. /* Ring the terminal bell. */
  2673. int
  2674. ding ()
  2675. {
  2676.   if (readline_echoing_p)
  2677.     {
  2678. #ifndef __GO32__
  2679.       if (prefer_visible_bell && visible_bell)
  2680.     tputs (visible_bell, 1, output_character_function);
  2681.       else
  2682. #endif /* !__GO32__ */
  2683.     {
  2684.       fprintf (stderr, "\007");
  2685.       fflush (stderr);
  2686.     }
  2687.     }
  2688.   return (-1);
  2689. }
  2690.  
  2691. /* How to abort things. */
  2692. rl_abort ()
  2693. {
  2694.   ding ();
  2695.   rl_clear_message ();
  2696.   rl_init_argument ();
  2697.   rl_pending_input = 0;
  2698.  
  2699.   defining_kbd_macro = 0;
  2700.   while (executing_macro)
  2701.     pop_executing_macro ();
  2702.  
  2703.   rl_last_func = (Function *)NULL;
  2704.   longjmp (readline_top_level, 1);
  2705. }
  2706.  
  2707. /* Return a copy of the string between FROM and TO.
  2708.    FROM is inclusive, TO is not. */
  2709. #if defined (sun) /* Yes, that's right, some crufty function in sunview is
  2710.              called rl_copy (). */
  2711. static
  2712. #endif
  2713. char *
  2714. rl_copy (from, to)
  2715.      int from, to;
  2716. {
  2717.   register int length;
  2718.   char *copy;
  2719.  
  2720.   /* Fix it if the caller is confused. */
  2721.   if (from > to)
  2722.     {
  2723.       int t = from;
  2724.       from = to;
  2725.       to = t;
  2726.     }
  2727.  
  2728.   length = to - from;
  2729.   copy = (char *)xmalloc (1 + length);
  2730.   strncpy (copy, the_line + from, length);
  2731.   copy[length] = '\0';
  2732.   return (copy);
  2733. }
  2734.  
  2735. /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
  2736.    LEN characters. */
  2737. void
  2738. rl_extend_line_buffer (len)
  2739.      int len;
  2740. {
  2741.   while (len >= rl_line_buffer_len)
  2742.     rl_line_buffer =
  2743.       (char *)xrealloc
  2744.     (rl_line_buffer, rl_line_buffer_len += DEFAULT_BUFFER_SIZE);
  2745.  
  2746.   the_line = rl_line_buffer;
  2747. }
  2748.  
  2749.  
  2750. /* **************************************************************** */
  2751. /*                                    */
  2752. /*            Insert and Delete                */
  2753. /*                                    */
  2754. /* **************************************************************** */
  2755.  
  2756. /* Insert a string of text into the line at point.  This is the only
  2757.    way that you should do insertion.  rl_insert () calls this
  2758.    function. */
  2759. rl_insert_text (string)
  2760.      char *string;
  2761. {
  2762.   extern int doing_an_undo;
  2763.   register int i, l = strlen (string);
  2764.  
  2765.   if (rl_end + l >= rl_line_buffer_len)
  2766.     rl_extend_line_buffer (rl_end + l);
  2767.  
  2768.   for (i = rl_end; i >= rl_point; i--)
  2769.     the_line[i + l] = the_line[i];
  2770.   strncpy (the_line + rl_point, string, l);
  2771.  
  2772.   /* Remember how to undo this if we aren't undoing something. */
  2773.   if (!doing_an_undo)
  2774.     {
  2775.       /* If possible and desirable, concatenate the undos. */
  2776.       if ((strlen (string) == 1) &&
  2777.       rl_undo_list &&
  2778.       (rl_undo_list->what == UNDO_INSERT) &&
  2779.       (rl_undo_list->end == rl_point) &&
  2780.       (rl_undo_list->end - rl_undo_list->start < 20))
  2781.     rl_undo_list->end++;
  2782.       else
  2783.     rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
  2784.     }
  2785.   rl_point += l;
  2786.   rl_end += l;
  2787.   the_line[rl_end] = '\0';
  2788. }
  2789.  
  2790. /* Delete the string between FROM and TO.  FROM is
  2791.    inclusive, TO is not. */
  2792. rl_delete_text (from, to)
  2793.      int from, to;
  2794. {
  2795.   extern int doing_an_undo;
  2796.   register char *text;
  2797.  
  2798.   /* Fix it if the caller is confused. */
  2799.   if (from > to)
  2800.     {
  2801.       int t = from;
  2802.       from = to;
  2803.       to = t;
  2804.     }
  2805.   text = rl_copy (from, to);
  2806.   strncpy (the_line + from, the_line + to, rl_end - to);
  2807.  
  2808.   /* Remember how to undo this delete. */
  2809.   if (!doing_an_undo)
  2810.     rl_add_undo (UNDO_DELETE, from, to, text);
  2811.   else
  2812.     free (text);
  2813.  
  2814.   rl_end -= (to - from);
  2815.   the_line[rl_end] = '\0';
  2816. }
  2817.  
  2818.  
  2819. /* **************************************************************** */
  2820. /*                                    */
  2821. /*            Readline character functions            */
  2822. /*                                    */
  2823. /* **************************************************************** */
  2824.  
  2825. /* This is not a gap editor, just a stupid line input routine.  No hair
  2826.    is involved in writing any of the functions, and none should be. */
  2827.  
  2828. /* Note that:
  2829.  
  2830.    rl_end is the place in the string that we would place '\0';
  2831.    i.e., it is always safe to place '\0' there.
  2832.  
  2833.    rl_point is the place in the string where the cursor is.  Sometimes
  2834.    this is the same as rl_end.
  2835.  
  2836.    Any command that is called interactively receives two arguments.
  2837.    The first is a count: the numeric arg pased to this command.
  2838.    The second is the key which invoked this command.
  2839. */
  2840.  
  2841.  
  2842. /* **************************************************************** */
  2843. /*                                    */
  2844. /*            Movement Commands                */
  2845. /*                                    */
  2846. /* **************************************************************** */
  2847.  
  2848. /* Note that if you `optimize' the display for these functions, you cannot
  2849.    use said functions in other functions which do not do optimizing display.
  2850.    I.e., you will have to update the data base for rl_redisplay, and you
  2851.    might as well let rl_redisplay do that job. */
  2852.  
  2853. /* Move forward COUNT characters. */
  2854. rl_forward (count)
  2855.      int count;
  2856. {
  2857.   if (count < 0)
  2858.     rl_backward (-count);
  2859.   else
  2860.     while (count)
  2861.       {
  2862. #if defined (VI_MODE)
  2863.     if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
  2864. #else
  2865.     if (rl_point == rl_end)
  2866. #endif /* VI_MODE */
  2867.       {
  2868.         ding ();
  2869.         return;
  2870.       }
  2871.     else
  2872.       rl_point++;
  2873.     --count;
  2874.       }
  2875. }
  2876.  
  2877. /* Move backward COUNT characters. */
  2878. rl_backward (count)
  2879.      int count;
  2880. {
  2881.   if (count < 0)
  2882.     rl_forward (-count);
  2883.   else
  2884.     while (count)
  2885.       {
  2886.     if (!rl_point)
  2887.       {
  2888.         ding ();
  2889.         return;
  2890.       }
  2891.     else
  2892.       --rl_point;
  2893.     --count;
  2894.       }
  2895. }
  2896.  
  2897. /* Move to the beginning of the line. */
  2898. rl_beg_of_line ()
  2899. {
  2900.   rl_point = 0;
  2901. }
  2902.  
  2903. /* Move to the end of the line. */
  2904. rl_end_of_line ()
  2905. {
  2906.   rl_point = rl_end;
  2907. }
  2908.  
  2909. /* Move forward a word.  We do what Emacs does. */
  2910. rl_forward_word (count)
  2911.      int count;
  2912. {
  2913.   int c;
  2914.  
  2915.   if (count < 0)
  2916.     {
  2917.       rl_backward_word (-count);
  2918.       return;
  2919.     }
  2920.  
  2921.   while (count)
  2922.     {
  2923.       if (rl_point == rl_end)
  2924.     return;
  2925.  
  2926.       /* If we are not in a word, move forward until we are in one.
  2927.      Then, move forward until we hit a non-alphabetic character. */
  2928.       c = the_line[rl_point];
  2929.       if (!alphabetic (c))
  2930.     {
  2931.       while (++rl_point < rl_end)
  2932.         {
  2933.           c = the_line[rl_point];
  2934.           if (alphabetic (c)) break;
  2935.         }
  2936.     }
  2937.       if (rl_point == rl_end) return;
  2938.       while (++rl_point < rl_end)
  2939.     {
  2940.       c = the_line[rl_point];
  2941.       if (!alphabetic (c)) break;
  2942.     }
  2943.       --count;
  2944.     }
  2945. }
  2946.  
  2947. /* Move backward a word.  We do what Emacs does. */
  2948. rl_backward_word (count)
  2949.      int count;
  2950. {
  2951.   int c;
  2952.  
  2953.   if (count < 0)
  2954.     {
  2955.       rl_forward_word (-count);
  2956.       return;
  2957.     }
  2958.  
  2959.   while (count)
  2960.     {
  2961.       if (!rl_point)
  2962.     return;
  2963.  
  2964.       /* Like rl_forward_word (), except that we look at the characters
  2965.      just before point. */
  2966.  
  2967.       c = the_line[rl_point - 1];
  2968.       if (!alphabetic (c))
  2969.     {
  2970.       while (--rl_point)
  2971.         {
  2972.           c = the_line[rl_point - 1];
  2973.           if (alphabetic (c)) break;
  2974.         }
  2975.     }
  2976.  
  2977.       while (rl_point)
  2978.     {
  2979.       c = the_line[rl_point - 1];
  2980.       if (!alphabetic (c))
  2981.         break;
  2982.       else --rl_point;
  2983.     }
  2984.       --count;
  2985.     }
  2986. }
  2987.  
  2988. /* Clear the current line.  Numeric argument to C-l does this. */
  2989. rl_refresh_line ()
  2990. {
  2991.   int curr_line = last_c_pos / screenwidth;
  2992.   extern char *term_clreol;
  2993.  
  2994.   move_vert(curr_line);
  2995.   move_cursor_relative (0, the_line);   /* XXX is this right */
  2996.  
  2997. #ifdef __GO32__
  2998.   {
  2999.   int r, c, w;
  3000.   ScreenGetCursor(&r, &c);
  3001.   w = ScreenCols();
  3002.   memset(ScreenPrimary+r*w+c, 0, (w-c)*2);
  3003.   }
  3004. #else /* __GO32__ */
  3005.   if (term_clreol)
  3006.     tputs (term_clreol, 1, output_character_function);
  3007. #endif /* __GO32__/else */
  3008.  
  3009.   rl_forced_update_display ();
  3010.   rl_display_fixed = 1;
  3011. }
  3012.  
  3013. /* C-l typed to a line without quoting clears the screen, and then reprints
  3014.    the prompt and the current input line.  Given a numeric arg, redraw only
  3015.    the current line. */
  3016. rl_clear_screen ()
  3017. {
  3018.   extern char *term_clrpag;
  3019.  
  3020.   if (rl_explicit_arg)
  3021.     {
  3022.       rl_refresh_line ();
  3023.       return;
  3024.     }
  3025.  
  3026. #ifndef __GO32__
  3027.   if (term_clrpag)
  3028.     tputs (term_clrpag, 1, output_character_function);
  3029.   else
  3030. #endif /* !__GO32__ */
  3031.     crlf ();
  3032.  
  3033.   rl_forced_update_display ();
  3034.   rl_display_fixed = 1;
  3035. }
  3036.  
  3037. rl_arrow_keys (count, c)
  3038.      int count, c;
  3039. {
  3040.   int ch;
  3041.  
  3042.   ch = rl_read_key ();
  3043.  
  3044.   switch (to_upper (ch))
  3045.     {
  3046.     case 'A':
  3047.       rl_get_previous_history (count);
  3048.       break;
  3049.  
  3050.     case 'B':
  3051.       rl_get_next_history (count);
  3052.       break;
  3053.  
  3054.     case 'C':
  3055.       rl_forward (count);
  3056.       break;
  3057.  
  3058.     case 'D':
  3059.       rl_backward (count);
  3060.       break;
  3061.  
  3062.     default:
  3063.       ding ();
  3064.     }
  3065. }
  3066.  
  3067.  
  3068. /* **************************************************************** */
  3069. /*                                    */
  3070. /*            Text commands                    */
  3071. /*                                    */
  3072. /* **************************************************************** */
  3073.  
  3074. /* Insert the character C at the current location, moving point forward. */
  3075. rl_insert (count, c)
  3076.      int count, c;
  3077. {
  3078.   register int i;
  3079.   char *string;
  3080.  
  3081.   if (count <= 0)
  3082.     return;
  3083.  
  3084.   /* If we can optimize, then do it.  But don't let people crash
  3085.      readline because of extra large arguments. */
  3086.   if (count > 1 && count < 1024)
  3087.     {
  3088.       string = (char *)alloca (1 + count);
  3089.  
  3090.       for (i = 0; i < count; i++)
  3091.     string[i] = c;
  3092.  
  3093.       string[i] = '\0';
  3094.       rl_insert_text (string);
  3095.       return;
  3096.     }
  3097.  
  3098.   if (count > 1024)
  3099.     {
  3100.       int decreaser;
  3101.  
  3102.       string = (char *)alloca (1024 + 1);
  3103.  
  3104.       for (i = 0; i < 1024; i++)
  3105.     string[i] = c;
  3106.  
  3107.       while (count)
  3108.     {
  3109.       decreaser = (count > 1024 ? 1024 : count);
  3110.       string[decreaser] = '\0';
  3111.       rl_insert_text (string);
  3112.       count -= decreaser;
  3113.     }
  3114.       return;
  3115.     }
  3116.  
  3117.   /* We are inserting a single character.
  3118.      If there is pending input, then make a string of all of the
  3119.      pending characters that are bound to rl_insert, and insert
  3120.      them all. */
  3121.   if (any_typein)
  3122.     {
  3123.       int key = 0, t;
  3124.  
  3125.       i = 0;
  3126.       string = (char *)alloca (ibuffer_len + 1);
  3127.       string[i++] = c;
  3128.  
  3129.       while ((t = rl_get_char (&key)) &&
  3130.          (keymap[key].type == ISFUNC &&
  3131.           keymap[key].function == rl_insert))
  3132.     string[i++] = key;
  3133.  
  3134.       if (t)
  3135.     rl_unget_char (key);
  3136.  
  3137.       string[i] = '\0';
  3138.       rl_insert_text (string);
  3139.       return;
  3140.     }
  3141.   else
  3142.     {
  3143.       /* Inserting a single character. */
  3144.       string = (char *)alloca (2);
  3145.  
  3146.       string[1] = '\0';
  3147.       string[0] = c;
  3148.       rl_insert_text (string);
  3149.     }
  3150. }
  3151.  
  3152. /* Insert the next typed character verbatim. */
  3153. rl_quoted_insert (count)
  3154.      int count;
  3155. {
  3156.   int c = rl_read_key ();
  3157.   rl_insert (count, c);
  3158. }
  3159.  
  3160. /* Insert a tab character. */
  3161. rl_tab_insert (count)
  3162.      int count;
  3163. {
  3164.   rl_insert (count, '\t');
  3165. }
  3166.  
  3167. /* What to do when a NEWLINE is pressed.  We accept the whole line.
  3168.    KEY is the key that invoked this command.  I guess it could have
  3169.    meaning in the future. */
  3170. rl_newline (count, key)
  3171.      int count, key;
  3172. {
  3173.  
  3174.   rl_done = 1;
  3175.  
  3176. #if defined (VI_MODE)
  3177.   {
  3178.     extern int vi_doing_insert;
  3179.     if (vi_doing_insert)
  3180.       {
  3181.     rl_end_undo_group ();
  3182.     vi_doing_insert = 0;
  3183.       }
  3184.   }
  3185. #endif /* VI_MODE */
  3186.  
  3187.   if (readline_echoing_p)
  3188.     {
  3189.       move_vert (vis_botlin);
  3190.       vis_botlin = 0;
  3191.       crlf ();
  3192.       fflush (out_stream);
  3193.       rl_display_fixed++;
  3194.     }
  3195. }
  3196.  
  3197. rl_clean_up_for_exit ()
  3198. {
  3199.   if (readline_echoing_p)
  3200.     {
  3201.       move_vert (vis_botlin);
  3202.       vis_botlin = 0;
  3203.       fflush (out_stream);
  3204.       rl_restart_output ();
  3205.     }
  3206. }
  3207.  
  3208. /* What to do for some uppercase characters, like meta characters,
  3209.    and some characters appearing in emacs_ctlx_keymap.  This function
  3210.    is just a stub, you bind keys to it and the code in rl_dispatch ()
  3211.    is special cased. */
  3212. rl_do_lowercase_version (ignore1, ignore2)
  3213.      int ignore1, ignore2;
  3214. {
  3215. }
  3216.  
  3217. /* Rubout the character behind point. */
  3218. rl_rubout (count)
  3219.      int count;
  3220. {
  3221.   if (count < 0)
  3222.     {
  3223.       rl_delete (-count);
  3224.       return;
  3225.     }
  3226.  
  3227.   if (!rl_point)
  3228.     {
  3229.       ding ();
  3230.       return;
  3231.     }
  3232.  
  3233.   if (count > 1)
  3234.     {
  3235.       int orig_point = rl_point;
  3236.       rl_backward (count);
  3237.       rl_kill_text (orig_point, rl_point);
  3238.     }
  3239.   else
  3240.     {
  3241.       int c = the_line[--rl_point];
  3242.       rl_delete_text (rl_point, rl_point + 1);
  3243.  
  3244.       if (rl_point == rl_end && alphabetic (c) && last_c_pos)
  3245.     {
  3246.       backspace (1);
  3247.       putc (' ', out_stream);
  3248.       backspace (1);
  3249.       last_c_pos--;
  3250.       visible_line[last_c_pos] = '\0';
  3251.       rl_display_fixed++;
  3252.     }
  3253.     }
  3254. }
  3255.  
  3256. /* Delete the character under the cursor.  Given a numeric argument,
  3257.    kill that many characters instead. */
  3258. rl_delete (count, invoking_key)
  3259.      int count, invoking_key;
  3260. {
  3261.   if (count < 0)
  3262.     {
  3263.       rl_rubout (-count);
  3264.       return;
  3265.     }
  3266.  
  3267.   if (rl_point == rl_end)
  3268.     {
  3269.       ding ();
  3270.       return;
  3271.     }
  3272.  
  3273.   if (count > 1)
  3274.     {
  3275.       int orig_point = rl_point;
  3276.       rl_forward (count);
  3277.       rl_kill_text (orig_point, rl_point);
  3278.       rl_point = orig_point;
  3279.     }
  3280.   else
  3281.     rl_delete_text (rl_point, rl_point + 1);
  3282. }
  3283.  
  3284.  
  3285. /* **************************************************************** */
  3286. /*                                    */
  3287. /*            Kill commands                    */
  3288. /*                                    */
  3289. /* **************************************************************** */
  3290.  
  3291. /* The next two functions mimic unix line editing behaviour, except they
  3292.    save the deleted text on the kill ring.  This is safer than not saving
  3293.    it, and since we have a ring, nobody should get screwed. */
  3294.  
  3295. /* This does what C-w does in Unix.  We can't prevent people from
  3296.    using behaviour that they expect. */
  3297. rl_unix_word_rubout ()
  3298. {
  3299.   if (!rl_point) ding ();
  3300.   else {
  3301.     int orig_point = rl_point;
  3302.     while (rl_point && whitespace (the_line[rl_point - 1]))
  3303.       rl_point--;
  3304.     while (rl_point && !whitespace (the_line[rl_point - 1]))
  3305.       rl_point--;
  3306.     rl_kill_text (rl_point, orig_point);
  3307.   }
  3308. }
  3309.  
  3310. /* Here is C-u doing what Unix does.  You don't *have* to use these
  3311.    key-bindings.  We have a choice of killing the entire line, or
  3312.    killing from where we are to the start of the line.  We choose the
  3313.    latter, because if you are a Unix weenie, then you haven't backspaced
  3314.    into the line at all, and if you aren't, then you know what you are
  3315.    doing. */
  3316. rl_unix_line_discard ()
  3317. {
  3318.   if (!rl_point) ding ();
  3319.   else {
  3320.     rl_kill_text (rl_point, 0);
  3321.     rl_point = 0;
  3322.   }
  3323. }
  3324.  
  3325.  
  3326.  
  3327. /* **************************************************************** */
  3328. /*                                    */
  3329. /*            Commands For Typos                */
  3330. /*                                    */
  3331. /* **************************************************************** */
  3332.  
  3333. /* Random and interesting things in here.  */
  3334.  
  3335. /* **************************************************************** */
  3336. /*                                    */
  3337. /*            Changing Case                    */
  3338. /*                                    */
  3339. /* **************************************************************** */
  3340.  
  3341. /* The three kinds of things that we know how to do. */
  3342. #define UpCase 1
  3343. #define DownCase 2
  3344. #define CapCase 3
  3345.  
  3346. /* Uppercase the word at point. */
  3347. rl_upcase_word (count)
  3348.      int count;
  3349. {
  3350.   rl_change_case (count, UpCase);
  3351. }
  3352.  
  3353. /* Lowercase the word at point. */
  3354. rl_downcase_word (count)
  3355.      int count;
  3356. {
  3357.   rl_change_case (count, DownCase);
  3358. }
  3359.  
  3360. /* Upcase the first letter, downcase the rest. */
  3361. rl_capitalize_word (count)
  3362.      int count;
  3363. {
  3364.   rl_change_case (count, CapCase);
  3365. }
  3366.  
  3367. /* The meaty function.
  3368.    Change the case of COUNT words, performing OP on them.
  3369.    OP is one of UpCase, DownCase, or CapCase.
  3370.    If a negative argument is given, leave point where it started,
  3371.    otherwise, leave it where it moves to. */
  3372. rl_change_case (count, op)
  3373.      int count, op;
  3374. {
  3375.   register int start = rl_point, end;
  3376.   int state = 0;
  3377.  
  3378.   rl_forward_word (count);
  3379.   end = rl_point;
  3380.  
  3381.   if (count < 0)
  3382.     {
  3383.       int temp = start;
  3384.       start = end;
  3385.       end = temp;
  3386.     }
  3387.  
  3388.   /* We are going to modify some text, so let's prepare to undo it. */
  3389.   rl_modifying (start, end);
  3390.  
  3391.   for (; start < end; start++)
  3392.     {
  3393.       switch (op)
  3394.     {
  3395.     case UpCase:
  3396.       the_line[start] = to_upper (the_line[start]);
  3397.       break;
  3398.  
  3399.     case DownCase:
  3400.       the_line[start] = to_lower (the_line[start]);
  3401.       break;
  3402.  
  3403.     case CapCase:
  3404.       if (state == 0)
  3405.         {
  3406.           the_line[start] = to_upper (the_line[start]);
  3407.           state = 1;
  3408.         }
  3409.       else
  3410.         {
  3411.           the_line[start] = to_lower (the_line[start]);
  3412.         }
  3413.       if (!pure_alphabetic (the_line[start]))
  3414.         state = 0;
  3415.       break;
  3416.  
  3417.     default:
  3418.       abort ();
  3419.     }
  3420.     }
  3421.   rl_point = end;
  3422. }
  3423.  
  3424. /* **************************************************************** */
  3425. /*                                    */
  3426. /*            Transposition                    */
  3427. /*                                    */
  3428. /* **************************************************************** */
  3429.  
  3430. /* Transpose the words at point. */
  3431. rl_transpose_words (count)
  3432.      int count;
  3433. {
  3434.   char *word1, *word2;
  3435.   int w1_beg, w1_end, w2_beg, w2_end;
  3436.   int orig_point = rl_point;
  3437.  
  3438.   if (!count) return;
  3439.  
  3440.   /* Find the two words. */
  3441.   rl_forward_word (count);
  3442.   w2_end = rl_point;
  3443.   rl_backward_word (1);
  3444.   w2_beg = rl_point;
  3445.   rl_backward_word (count);
  3446.   w1_beg = rl_point;
  3447.   rl_forward_word (1);
  3448.   w1_end = rl_point;
  3449.  
  3450.   /* Do some check to make sure that there really are two words. */
  3451.   if ((w1_beg == w2_beg) || (w2_beg < w1_end))
  3452.     {
  3453.       ding ();
  3454.       rl_point = orig_point;
  3455.       return;
  3456.     }
  3457.  
  3458.   /* Get the text of the words. */
  3459.   word1 = rl_copy (w1_beg, w1_end);
  3460.   word2 = rl_copy (w2_beg, w2_end);
  3461.  
  3462.   /* We are about to do many insertions and deletions.  Remember them
  3463.      as one operation. */
  3464.   rl_begin_undo_group ();
  3465.  
  3466.   /* Do the stuff at word2 first, so that we don't have to worry
  3467.      about word1 moving. */
  3468.   rl_point = w2_beg;
  3469.   rl_delete_text (w2_beg, w2_end);
  3470.   rl_insert_text (word1);
  3471.  
  3472.   rl_point = w1_beg;
  3473.   rl_delete_text (w1_beg, w1_end);
  3474.   rl_insert_text (word2);
  3475.  
  3476.   /* This is exactly correct since the text before this point has not
  3477.      changed in length. */
  3478.   rl_point = w2_end;
  3479.  
  3480.   /* I think that does it. */
  3481.   rl_end_undo_group ();
  3482.   free (word1); free (word2);
  3483. }
  3484.  
  3485. /* Transpose the characters at point.  If point is at the end of the line,
  3486.    then transpose the characters before point. */
  3487. rl_transpose_chars (count)
  3488.      int count;
  3489. {
  3490.   if (!count)
  3491.     return;
  3492.  
  3493.   if (!rl_point || rl_end < 2) {
  3494.     ding ();
  3495.     return;
  3496.   }
  3497.  
  3498.   while (count)
  3499.     {
  3500.       if (rl_point == rl_end)
  3501.     {
  3502.       int t = the_line[rl_point - 1];
  3503.  
  3504.       the_line[rl_point - 1] = the_line[rl_point - 2];
  3505.       the_line[rl_point - 2] = t;
  3506.     }
  3507.       else
  3508.     {
  3509.       int t = the_line[rl_point];
  3510.  
  3511.       the_line[rl_point] = the_line[rl_point - 1];
  3512.       the_line[rl_point - 1] = t;
  3513.  
  3514.       if (count < 0 && rl_point)
  3515.         rl_point--;
  3516.       else
  3517.         rl_point++;
  3518.     }
  3519.  
  3520.       if (count < 0)
  3521.     count++;
  3522.       else
  3523.     count--;
  3524.     }
  3525. }
  3526.  
  3527.  
  3528. /* **************************************************************** */
  3529. /*                                    */
  3530. /*            Bogus Flow Control                  */
  3531. /*                                    */
  3532. /* **************************************************************** */
  3533.  
  3534. rl_restart_output (count, key)
  3535.      int count, key;
  3536. {
  3537.   int fildes = fileno (rl_outstream);
  3538. #if defined (TIOCSTART)
  3539. #if defined (apollo)
  3540.   ioctl (&fildes, TIOCSTART, 0);
  3541. #else
  3542.   ioctl (fildes, TIOCSTART, 0);
  3543. #endif /* apollo */
  3544.  
  3545. #else
  3546. #  if defined (TERMIOS_TTY_DRIVER)
  3547.         tcflow (fildes, TCOON);
  3548. #  else
  3549. #    if defined (TCXONC)
  3550.         ioctl (fildes, TCXONC, TCOON);
  3551. #    endif /* TCXONC */
  3552. #  endif /* !TERMIOS_TTY_DRIVER */
  3553. #endif /* TIOCSTART */
  3554. }
  3555.  
  3556. rl_stop_output (count, key)
  3557.      int count, key;
  3558. {
  3559.   int fildes = fileno (rl_instream);
  3560.  
  3561. #if defined (TIOCSTOP)
  3562. # if defined (apollo)
  3563.   ioctl (&fildes, TIOCSTOP, 0);
  3564. # else
  3565.   ioctl (fildes, TIOCSTOP, 0);
  3566. # endif /* apollo */
  3567. #else
  3568. # if defined (TERMIOS_TTY_DRIVER)
  3569.   tcflow (fildes, TCOOFF);
  3570. # else
  3571. #   if defined (TCXONC)
  3572.   ioctl (fildes, TCXONC, TCOON);
  3573. #   endif /* TCXONC */
  3574. # endif /* !TERMIOS_TTY_DRIVER */
  3575. #endif /* TIOCSTOP */
  3576. }
  3577.  
  3578. /* **************************************************************** */
  3579. /*                                    */
  3580. /*    Completion matching, from readline's point of view.        */
  3581. /*                                    */
  3582. /* **************************************************************** */
  3583.  
  3584. /* Pointer to the generator function for completion_matches ().
  3585.    NULL means to use filename_entry_function (), the default filename
  3586.    completer. */
  3587. Function *rl_completion_entry_function = (Function *)NULL;
  3588.  
  3589. /* Pointer to alternative function to create matches.
  3590.    Function is called with TEXT, START, and END.
  3591.    START and END are indices in RL_LINE_BUFFER saying what the boundaries
  3592.    of TEXT are.
  3593.    If this function exists and returns NULL then call the value of
  3594.    rl_completion_entry_function to try to match, otherwise use the
  3595.    array of strings returned. */
  3596. Function *rl_attempted_completion_function = (Function *)NULL;
  3597.  
  3598. /* Local variable states what happened during the last completion attempt. */
  3599. static int completion_changed_buffer = 0;
  3600.  
  3601. /* Complete the word at or before point.  You have supplied the function
  3602.    that does the initial simple matching selection algorithm (see
  3603.    completion_matches ()).  The default is to do filename completion. */
  3604.  
  3605. rl_complete (ignore, invoking_key)
  3606.      int ignore, invoking_key;
  3607. {
  3608.   if (rl_last_func == rl_complete && !completion_changed_buffer)
  3609.     rl_complete_internal ('?');
  3610.   else
  3611.     rl_complete_internal (TAB);
  3612. }
  3613.  
  3614. /* List the possible completions.  See description of rl_complete (). */
  3615. rl_possible_completions ()
  3616. {
  3617.   rl_complete_internal ('?');
  3618. }
  3619.  
  3620. /* The user must press "y" or "n". Non-zero return means "y" pressed. */
  3621. get_y_or_n ()
  3622. {
  3623.   int c;
  3624.  loop:
  3625.   c = rl_read_key ();
  3626.   if (c == 'y' || c == 'Y') return (1);
  3627.   if (c == 'n' || c == 'N') return (0);
  3628.   if (c == ABORT_CHAR) rl_abort ();
  3629.   ding (); goto loop;
  3630. }
  3631.  
  3632. /* Up to this many items will be displayed in response to a
  3633.    possible-completions call.  After that, we ask the user if
  3634.    she is sure she wants to see them all. */
  3635. int rl_completion_query_items = 100;
  3636.  
  3637. /* The basic list of characters that signal a break between words for the
  3638.    completer routine.  The contents of this variable is what breaks words
  3639.    in the shell, i.e. " \t\n\"\\'`@$><=" */
  3640. char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
  3641.  
  3642. /* The list of characters that signal a break between words for
  3643.    rl_complete_internal.  The default list is the contents of
  3644.    rl_basic_word_break_characters.  */
  3645. char *rl_completer_word_break_characters = (char *)NULL;
  3646.  
  3647. /* The list of characters which are used to quote a substring of the command
  3648.    line.  Command completion occurs on the entire substring, and within the
  3649.    substring rl_completer_word_break_characters are treated as any other
  3650.    character, unless they also appear within this list. */
  3651. char *rl_completer_quote_characters = (char *)NULL;
  3652.  
  3653. /* List of characters that are word break characters, but should be left
  3654.    in TEXT when it is passed to the completion function.  The shell uses
  3655.    this to help determine what kind of completing to do. */
  3656. char *rl_special_prefixes = (char *)NULL;
  3657.  
  3658. /* If non-zero, then disallow duplicates in the matches. */
  3659. int rl_ignore_completion_duplicates = 1;
  3660.  
  3661. /* Non-zero means that the results of the matches are to be treated
  3662.    as filenames.  This is ALWAYS zero on entry, and can only be changed
  3663.    within a completion entry finder function. */
  3664. int rl_filename_completion_desired = 0;
  3665.  
  3666. /* This function, if defined, is called by the completer when real
  3667.    filename completion is done, after all the matching names have been
  3668.    generated. It is passed a (char**) known as matches in the code below.
  3669.    It consists of a NULL-terminated array of pointers to potential
  3670.    matching strings.  The 1st element (matches[0]) is the maximal
  3671.    substring that is common to all matches. This function can re-arrange
  3672.    the list of matches as required, but all elements of the array must be
  3673.    free()'d if they are deleted. The main intent of this function is
  3674.    to implement FIGNORE a la SunOS csh. */
  3675. Function *rl_ignore_some_completions_function = (Function *)NULL;
  3676.  
  3677. /* Complete the word at or before point.
  3678.    WHAT_TO_DO says what to do with the completion.
  3679.    `?' means list the possible completions.
  3680.    TAB means do standard completion.
  3681.    `*' means insert all of the possible completions. */
  3682. rl_complete_internal (what_to_do)
  3683.      int what_to_do;
  3684. {
  3685.   char *filename_completion_function ();
  3686.   char **completion_matches (), **matches;
  3687.   Function *our_func;
  3688.   int start, scan, end, delimiter = 0;
  3689.   char *text, *saved_line_buffer;
  3690.   char quote_char = '\0';
  3691.   char *replacement;
  3692.  
  3693.   if (the_line)
  3694.     saved_line_buffer = savestring (the_line);
  3695.   else
  3696.     saved_line_buffer = (char *)NULL;
  3697.  
  3698.   if (rl_completion_entry_function)
  3699.     our_func = rl_completion_entry_function;
  3700.   else
  3701.     our_func = (int (*)())filename_completion_function;
  3702.  
  3703.   /* Only the completion entry function can change this. */
  3704.   rl_filename_completion_desired = 0;
  3705.  
  3706.   /* We now look backwards for the start of a filename/variable word. */
  3707.   end = rl_point;
  3708.  
  3709.   if (rl_point)
  3710.     {
  3711.       if (rl_completer_quote_characters)
  3712.     {
  3713.       /* We have a list of characters which can be used in pairs to quote
  3714.          substrings for completion.  Try to find the start of an unclosed
  3715.          quoted substring.
  3716.          FIXME:  Doesn't yet handle '\' escapes to hid embedded quotes */
  3717.       for (scan = 0; scan < end; scan++)
  3718.         {
  3719.           if (quote_char != '\0')
  3720.         {
  3721.           /* Ignore everything until the matching close quote char */
  3722.           if (the_line[scan] == quote_char)
  3723.             {
  3724.               /* Found matching close quote. Abandon this substring. */
  3725.               quote_char = '\0';
  3726.               rl_point = end;
  3727.             }
  3728.         }
  3729.           else if (rindex (rl_completer_quote_characters, the_line[scan]))
  3730.         {
  3731.           /* Found start of a quoted substring. */
  3732.           quote_char = the_line[scan];
  3733.           rl_point = scan + 1;
  3734.         }
  3735.         }
  3736.     }
  3737.       if (rl_point == end)
  3738.     {
  3739.       /* We didn't find an unclosed quoted substring upon which to do
  3740.          completion, so use the word break characters to find the
  3741.          substring on which to do completion. */
  3742.       while (--rl_point &&
  3743.          !rindex (rl_completer_word_break_characters,
  3744.               the_line[rl_point])) {;}
  3745.     }
  3746.  
  3747.       /* If we are at a word break, then advance past it. */
  3748.       if (rindex (rl_completer_word_break_characters, the_line[rl_point]))
  3749.     {
  3750.       /* If the character that caused the word break was a quoting
  3751.          character, then remember it as the delimiter. */
  3752.       if (rindex ("\"'", the_line[rl_point]) && (end - rl_point) > 1)
  3753.         delimiter = the_line[rl_point];
  3754.  
  3755.       /* If the character isn't needed to determine something special
  3756.          about what kind of completion to perform, then advance past it. */
  3757.  
  3758.       if (!rl_special_prefixes ||
  3759.           !rindex (rl_special_prefixes, the_line[rl_point]))
  3760.         rl_point++;
  3761.     }
  3762.     }
  3763.  
  3764.   start = rl_point;
  3765.   rl_point = end;
  3766.   text = rl_copy (start, end);
  3767.  
  3768.   /* If the user wants to TRY to complete, but then wants to give
  3769.      up and use the default completion function, they set the
  3770.      variable rl_attempted_completion_function. */
  3771.   if (rl_attempted_completion_function)
  3772.     {
  3773.       matches =
  3774.     (char **)(*rl_attempted_completion_function) (text, start, end);
  3775.  
  3776.       if (matches)
  3777.     {
  3778.       our_func = (Function *)NULL;
  3779.       goto after_usual_completion;
  3780.     }
  3781.     }
  3782.  
  3783.   matches = completion_matches (text, our_func);
  3784.  
  3785.  after_usual_completion:
  3786.   free (text);
  3787.  
  3788.   if (!matches)
  3789.     ding ();
  3790.   else
  3791.     {
  3792.       register int i;
  3793.  
  3794.     some_matches:
  3795.  
  3796.       /* It seems to me that in all the cases we handle we would like
  3797.      to ignore duplicate possibilities.  Scan for the text to
  3798.      insert being identical to the other completions. */
  3799.       if (rl_ignore_completion_duplicates)
  3800.     {
  3801.       char *lowest_common;
  3802.       int j, newlen = 0;
  3803.  
  3804.       /* Sort the items. */
  3805.       /* It is safe to sort this array, because the lowest common
  3806.          denominator found in matches[0] will remain in place. */
  3807.       for (i = 0; matches[i]; i++);
  3808.       qsort (matches, i, sizeof (char *), compare_strings);
  3809.  
  3810.       /* Remember the lowest common denominator for it may be unique. */
  3811.       lowest_common = savestring (matches[0]);
  3812.  
  3813.       for (i = 0; matches[i + 1]; i++)
  3814.         {
  3815.           if (strcmp (matches[i], matches[i + 1]) == 0)
  3816.         {
  3817.           free (matches[i]);
  3818.           matches[i] = (char *)-1;
  3819.         }
  3820.           else
  3821.         newlen++;
  3822.         }
  3823.  
  3824.       /* We have marked all the dead slots with (char *)-1.
  3825.          Copy all the non-dead entries into a new array. */
  3826.       {
  3827.         char **temp_array =
  3828.           (char **)malloc ((3 + newlen) * sizeof (char *));
  3829.  
  3830.         for (i = 1, j = 1; matches[i]; i++)
  3831.           {
  3832.         if (matches[i] != (char *)-1)
  3833.           temp_array[j++] = matches[i];
  3834.           }
  3835.  
  3836.         temp_array[j] = (char *)NULL;
  3837.  
  3838.         if (matches[0] != (char *)-1)
  3839.           free (matches[0]);
  3840.  
  3841.         free (matches);
  3842.  
  3843.         matches = temp_array;
  3844.       }
  3845.  
  3846.       /* Place the lowest common denominator back in [0]. */
  3847.       matches[0] = lowest_common;
  3848.  
  3849.       /* If there is one string left, and it is identical to the
  3850.          lowest common denominator, then the LCD is the string to
  3851.          insert. */
  3852.       if (j == 2 && strcmp (matches[0], matches[1]) == 0)
  3853.         {
  3854.           free (matches[1]);
  3855.           matches[1] = (char *)NULL;
  3856.         }
  3857.     }
  3858.  
  3859.       switch (what_to_do)
  3860.     {
  3861.     case TAB:
  3862.       /* If we are matching filenames, then here is our chance to
  3863.          do clever processing by re-examining the list.  Call the
  3864.          ignore function with the array as a parameter.  It can
  3865.          munge the array, deleting matches as it desires. */
  3866.       if (rl_ignore_some_completions_function &&
  3867.           our_func == (int (*)())filename_completion_function)
  3868.         (void)(*rl_ignore_some_completions_function)(matches);
  3869.  
  3870.       /* If we are doing completions on quoted substrings, and any matches
  3871.          contain any of the completer word break characters, then auto-
  3872.          matically prepend the substring with a quote character (just
  3873.          pick the first one from the list of such) if it does not already
  3874.          begin with a quote string.  FIXME:  Need to remove any such
  3875.          automatically inserted quote character when it no longer is
  3876.          necessary, such as if we change the string we are completing on
  3877.          and the new set of matches don't require a quoted substring? */
  3878.  
  3879.       replacement = matches[0];
  3880.       if (matches[0] != NULL
  3881.           && rl_completer_quote_characters != NULL
  3882.           && (quote_char == '\0'))
  3883.         {
  3884.           for (i = 1; matches[i] != NULL; i++)
  3885.         {
  3886.           if (strpbrk (matches[i], rl_completer_word_break_characters))
  3887.             {
  3888.               /* Found an embedded word break character in a potential
  3889.              match, so need to prepend a quote character if we are
  3890.              replacing the completion string. */
  3891.               replacement = (char *)alloca (strlen (matches[0]) + 2);
  3892.               quote_char = *rl_completer_quote_characters;
  3893.               *replacement = quote_char;
  3894.               strcpy (replacement + 1, matches[0]);
  3895.               break;
  3896.             }
  3897.         }
  3898.         }
  3899.       if (replacement)
  3900.         {
  3901.           rl_delete_text (start, rl_point);
  3902.           rl_point = start;
  3903.           rl_insert_text (replacement);
  3904.         }
  3905.  
  3906.       /* If there are more matches, ring the bell to indicate.
  3907.          If this was the only match, and we are hacking files,
  3908.          check the file to see if it was a directory.  If so,
  3909.          add a '/' to the name.  If not, and we are at the end
  3910.          of the line, then add a space. */
  3911.       if (matches[1])
  3912.         {
  3913.           ding ();        /* There are other matches remaining. */
  3914.         }
  3915.       else
  3916.         {
  3917.           char temp_string[16];
  3918.           int temp_index = 0;
  3919.  
  3920.           if (quote_char)
  3921.         {
  3922.           temp_string[temp_index++] = quote_char;
  3923.         }
  3924.           temp_string[temp_index++] = delimiter ? delimiter : ' ';
  3925.           temp_string[temp_index++] = '\0';
  3926.  
  3927.           if (rl_filename_completion_desired)
  3928.         {
  3929.           struct stat finfo;
  3930.           char *filename = tilde_expand (matches[0]);
  3931.  
  3932.           if ((stat (filename, &finfo) == 0) &&
  3933.               S_ISDIR (finfo.st_mode))
  3934.             {
  3935.               if (the_line[rl_point] != '/')
  3936.             rl_insert_text ("/");
  3937.             }
  3938.           else
  3939.             {
  3940.               if (rl_point == rl_end)
  3941.             rl_insert_text (temp_string);
  3942.             }
  3943.           free (filename);
  3944.         }
  3945.           else
  3946.         {
  3947.           if (rl_point == rl_end)
  3948.             rl_insert_text (temp_string);
  3949.         }
  3950.         }
  3951.       break;
  3952.  
  3953.     case '*':
  3954.       {
  3955.         int i = 1;
  3956.  
  3957.         rl_delete_text (start, rl_point);
  3958.         rl_point = start;
  3959.         rl_begin_undo_group ();
  3960.         if (matches[1])
  3961.           {
  3962.         while (matches[i])
  3963.           {
  3964.             rl_insert_text (matches[i++]);
  3965.             rl_insert_text (" ");
  3966.           }
  3967.           }
  3968.         else
  3969.           {
  3970.         rl_insert_text (matches[0]);
  3971.         rl_insert_text (" ");
  3972.           }
  3973.         rl_end_undo_group ();
  3974.       }
  3975.       break;
  3976.  
  3977.     case '?':
  3978.       {
  3979.         int len, count, limit, max = 0;
  3980.         int j, k, l;
  3981.  
  3982.         /* Handle simple case first.  What if there is only one answer? */
  3983.         if (!matches[1])
  3984.           {
  3985.         char *temp;
  3986.  
  3987.         if (rl_filename_completion_desired)
  3988.           temp = rindex (matches[0], '/');
  3989.         else
  3990.           temp = (char *)NULL;
  3991.  
  3992.         if (!temp)
  3993.           temp = matches[0];
  3994.         else
  3995.           temp++;
  3996.  
  3997.         crlf ();
  3998.         fprintf (out_stream, "%s", temp);
  3999.         crlf ();
  4000.         goto restart;
  4001.           }
  4002.  
  4003.         /* There is more than one answer.  Find out how many there are,
  4004.            and find out what the maximum printed length of a single entry
  4005.            is. */
  4006.         for (i = 1; matches[i]; i++)
  4007.           {
  4008.         char *temp = (char *)NULL;
  4009.  
  4010.         /* If we are hacking filenames, then only count the characters
  4011.            after the last slash in the pathname. */
  4012.         if (rl_filename_completion_desired)
  4013.           temp = rindex (matches[i], '/');
  4014.         else
  4015.           temp = (char *)NULL;
  4016.  
  4017.         if (!temp)
  4018.           temp = matches[i];
  4019.         else
  4020.           temp++;
  4021.  
  4022.         if (strlen (temp) > max)
  4023.           max = strlen (temp);
  4024.           }
  4025.  
  4026.         len = i;
  4027.  
  4028.         /* If there are many items, then ask the user if she
  4029.            really wants to see them all. */
  4030.         if (len >= rl_completion_query_items)
  4031.           {
  4032.         crlf ();
  4033.         fprintf (out_stream,
  4034.              "There are %d possibilities.  Do you really", len);
  4035.         crlf ();
  4036.         fprintf (out_stream, "wish to see them all? (y or n)");
  4037.         fflush (out_stream);
  4038.         if (!get_y_or_n ())
  4039.           {
  4040.             crlf ();
  4041.             goto restart;
  4042.           }
  4043.           }
  4044.         /* How many items of MAX length can we fit in the screen window? */
  4045.         max += 2;
  4046.         limit = screenwidth / max;
  4047.         if (limit != 1 && (limit * max == screenwidth))
  4048.           limit--;
  4049.  
  4050.         /* Avoid a possible floating exception.  If max > screenwidth,
  4051.            limit will be 0 and a divide-by-zero fault will result. */
  4052.         if (limit == 0)
  4053.           limit = 1;
  4054.  
  4055.         /* How many iterations of the printing loop? */
  4056.         count = (len + (limit - 1)) / limit;
  4057.  
  4058.         /* Watch out for special case.  If LEN is less than LIMIT, then
  4059.            just do the inner printing loop. */
  4060.         if (len < limit) count = 1;
  4061.  
  4062.         /* Sort the items if they are not already sorted. */
  4063.         if (!rl_ignore_completion_duplicates)
  4064.           qsort (matches, len, sizeof (char *), compare_strings);
  4065.  
  4066.         /* Print the sorted items, up-and-down alphabetically, like
  4067.            ls might. */
  4068.         crlf ();
  4069.  
  4070.         for (i = 1; i < count + 1; i++)
  4071.           {
  4072.         for (j = 0, l = i; j < limit; j++)
  4073.           {
  4074.             if (l > len || !matches[l])
  4075.               {
  4076.             break;
  4077.               }
  4078.             else
  4079.               {
  4080.             char *temp = (char *)NULL;
  4081.  
  4082.             if (rl_filename_completion_desired)
  4083.               temp = rindex (matches[l], '/');
  4084.             else
  4085.               temp = (char *)NULL;
  4086.  
  4087.             if (!temp)
  4088.               temp = matches[l];
  4089.             else
  4090.               temp++;
  4091.  
  4092.             fprintf (out_stream, "%s", temp);
  4093.             for (k = 0; k < max - strlen (temp); k++)
  4094.               putc (' ', out_stream);
  4095.               }
  4096.             l += count;
  4097.           }
  4098.         crlf ();
  4099.           }
  4100.       restart:
  4101.  
  4102.         rl_on_new_line ();
  4103.       }
  4104.       break;
  4105.  
  4106.     default:
  4107.       abort ();
  4108.     }
  4109.  
  4110.       for (i = 0; matches[i]; i++)
  4111.     free (matches[i]);
  4112.       free (matches);
  4113.     }
  4114.  
  4115.   /* Check to see if the line has changed through all of this manipulation. */
  4116.   if (saved_line_buffer)
  4117.     {
  4118.       if (strcmp (the_line, saved_line_buffer) != 0)
  4119.     completion_changed_buffer = 1;
  4120.       else
  4121.     completion_changed_buffer = 0;
  4122.  
  4123.       free (saved_line_buffer);
  4124.     }
  4125. }
  4126.  
  4127. /* Stupid comparison routine for qsort () ing strings. */
  4128. static int
  4129. compare_strings (s1, s2)
  4130.   char **s1, **s2;
  4131. {
  4132.   return (strcmp (*s1, *s2));
  4133. }
  4134.  
  4135. /* A completion function for usernames.
  4136.    TEXT contains a partial username preceded by a random
  4137.    character (usually `~').  */
  4138. char *
  4139. username_completion_function (text, state)
  4140.      int state;
  4141.      char *text;
  4142. {
  4143. #if defined (__GO32__) || defined (NOT_MULTIUSER)
  4144.   return (char *)NULL;
  4145. #else /* !__GO32__ */
  4146.   static char *username = (char *)NULL;
  4147.   static struct passwd *entry;
  4148.   static int namelen, first_char, first_char_loc;
  4149.  
  4150.   if (!state)
  4151.     {
  4152.       if (username)
  4153.     free (username);
  4154.  
  4155.       first_char = *text;
  4156.  
  4157.       if (first_char == '~')
  4158.     first_char_loc = 1;
  4159.       else
  4160.     first_char_loc = 0;
  4161.  
  4162.       username = savestring (&text[first_char_loc]);
  4163.       namelen = strlen (username);
  4164.       setpwent ();
  4165.     }
  4166.  
  4167.   while (entry = getpwent ())
  4168.     {
  4169.       if (strncmp (username, entry->pw_name, namelen) == 0)
  4170.     break;
  4171.     }
  4172.  
  4173.   if (!entry)
  4174.     {
  4175.       endpwent ();
  4176.       return ((char *)NULL);
  4177.     }
  4178.   else
  4179.     {
  4180.       char *value = (char *)xmalloc (2 + strlen (entry->pw_name));
  4181.  
  4182.       *value = *text;
  4183.  
  4184.       strcpy (value + first_char_loc, entry->pw_name);
  4185.  
  4186.       if (first_char == '~')
  4187.     rl_filename_completion_desired = 1;
  4188.  
  4189.       return (value);
  4190.     }
  4191. #endif /* !__GO32__ */
  4192. }
  4193.  
  4194. /* **************************************************************** */
  4195. /*                                    */
  4196. /*            Undo, and Undoing                */
  4197. /*                                    */
  4198. /* **************************************************************** */
  4199.  
  4200. /* Non-zero tells rl_delete_text and rl_insert_text to not add to
  4201.    the undo list. */
  4202. int doing_an_undo = 0;
  4203.  
  4204. /* The current undo list for THE_LINE. */
  4205. UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
  4206.  
  4207. /* Remember how to undo something.  Concatenate some undos if that
  4208.    seems right. */
  4209. rl_add_undo (what, start, end, text)
  4210.      enum undo_code what;
  4211.      int start, end;
  4212.      char *text;
  4213. {
  4214.   UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
  4215.   temp->what = what;
  4216.   temp->start = start;
  4217.   temp->end = end;
  4218.   temp->text = text;
  4219.   temp->next = rl_undo_list;
  4220.   rl_undo_list = temp;
  4221. }
  4222.  
  4223. /* Free the existing undo list. */
  4224. free_undo_list ()
  4225. {
  4226.   while (rl_undo_list) {
  4227.     UNDO_LIST *release = rl_undo_list;
  4228.     rl_undo_list = rl_undo_list->next;
  4229.  
  4230.     if (release->what == UNDO_DELETE)
  4231.       free (release->text);
  4232.  
  4233.     free (release);
  4234.   }
  4235. }
  4236.  
  4237. /* Undo the next thing in the list.  Return 0 if there
  4238.    is nothing to undo, or non-zero if there was. */
  4239. int
  4240. rl_do_undo ()
  4241. {
  4242.   UNDO_LIST *release;
  4243.   int waiting_for_begin = 0;
  4244.  
  4245. undo_thing:
  4246.   if (!rl_undo_list)
  4247.     return (0);
  4248.  
  4249.   doing_an_undo = 1;
  4250.  
  4251.   switch (rl_undo_list->what) {
  4252.  
  4253.     /* Undoing deletes means inserting some text. */
  4254.   case UNDO_DELETE:
  4255.     rl_point = rl_undo_list->start;
  4256.     rl_insert_text (rl_undo_list->text);
  4257.     free (rl_undo_list->text);
  4258.     break;
  4259.  
  4260.     /* Undoing inserts means deleting some text. */
  4261.   case UNDO_INSERT:
  4262.     rl_delete_text (rl_undo_list->start, rl_undo_list->end);
  4263.     rl_point = rl_undo_list->start;
  4264.     break;
  4265.  
  4266.     /* Undoing an END means undoing everything 'til we get to
  4267.        a BEGIN. */
  4268.   case UNDO_END:
  4269.     waiting_for_begin++;
  4270.     break;
  4271.  
  4272.     /* Undoing a BEGIN means that we are done with this group. */
  4273.   case UNDO_BEGIN:
  4274.     if (waiting_for_begin)
  4275.       waiting_for_begin--;
  4276.     else
  4277.       abort ();
  4278.     break;
  4279.   }
  4280.  
  4281.   doing_an_undo = 0;
  4282.  
  4283.   release = rl_undo_list;
  4284.   rl_undo_list = rl_undo_list->next;
  4285.   free (release);
  4286.  
  4287.   if (waiting_for_begin)
  4288.     goto undo_thing;
  4289.  
  4290.   return (1);
  4291. }
  4292.  
  4293. /* Begin a group.  Subsequent undos are undone as an atomic operation. */
  4294. rl_begin_undo_group ()
  4295. {
  4296.   rl_add_undo (UNDO_BEGIN, 0, 0, 0);
  4297. }
  4298.  
  4299. /* End an undo group started with rl_begin_undo_group (). */
  4300. rl_end_undo_group ()
  4301. {
  4302.   rl_add_undo (UNDO_END, 0, 0, 0);
  4303. }
  4304.  
  4305. /* Save an undo entry for the text from START to END. */
  4306. rl_modifying (start, end)
  4307.      int start, end;
  4308. {
  4309.   if (start > end)
  4310.     {
  4311.       int t = start;
  4312.       start = end;
  4313.       end = t;
  4314.     }
  4315.  
  4316.   if (start != end)
  4317.     {
  4318.       char *temp = rl_copy (start, end);
  4319.       rl_begin_undo_group ();
  4320.       rl_add_undo (UNDO_DELETE, start, end, temp);
  4321.       rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
  4322.       rl_end_undo_group ();
  4323.     }
  4324. }
  4325.  
  4326. /* Revert the current line to its previous state. */
  4327. rl_revert_line ()
  4328. {
  4329.   if (!rl_undo_list) ding ();
  4330.   else {
  4331.     while (rl_undo_list)
  4332.       rl_do_undo ();
  4333.   }
  4334. }
  4335.  
  4336. /* Do some undoing of things that were done. */
  4337. rl_undo_command (count)
  4338. {
  4339.   if (count < 0) return;    /* Nothing to do. */
  4340.  
  4341.   while (count)
  4342.     {
  4343.       if (rl_do_undo ())
  4344.     {
  4345.       count--;
  4346.     }
  4347.       else
  4348.     {
  4349.       ding ();
  4350.       break;
  4351.     }
  4352.     }
  4353. }
  4354.  
  4355. /* **************************************************************** */
  4356. /*                                    */
  4357. /*            History Utilities                */
  4358. /*                                    */
  4359. /* **************************************************************** */
  4360.  
  4361. /* We already have a history library, and that is what we use to control
  4362.    the history features of readline.  However, this is our local interface
  4363.    to the history mechanism. */
  4364.  
  4365. /* While we are editing the history, this is the saved
  4366.    version of the original line. */
  4367. HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
  4368.  
  4369. /* Set the history pointer back to the last entry in the history. */
  4370. start_using_history ()
  4371. {
  4372.   using_history ();
  4373.   if (saved_line_for_history)
  4374.     free_history_entry (saved_line_for_history);
  4375.  
  4376.   saved_line_for_history = (HIST_ENTRY *)NULL;
  4377. }
  4378.  
  4379. /* Free the contents (and containing structure) of a HIST_ENTRY. */
  4380. free_history_entry (entry)
  4381.      HIST_ENTRY *entry;
  4382. {
  4383.   if (!entry) return;
  4384.   if (entry->line)
  4385.     free (entry->line);
  4386.   free (entry);
  4387. }
  4388.  
  4389. /* Perhaps put back the current line if it has changed. */
  4390. maybe_replace_line ()
  4391. {
  4392.   HIST_ENTRY *temp = current_history ();
  4393.  
  4394.   /* If the current line has changed, save the changes. */
  4395.   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
  4396.     {
  4397.       temp = replace_history_entry (where_history (), the_line, rl_undo_list);
  4398.       free (temp->line);
  4399.       free (temp);
  4400.     }
  4401. }
  4402.  
  4403. /* Put back the saved_line_for_history if there is one. */
  4404. maybe_unsave_line ()
  4405. {
  4406.   if (saved_line_for_history)
  4407.     {
  4408.       int line_len;
  4409.  
  4410.       line_len = strlen (saved_line_for_history->line);
  4411.  
  4412.       if (line_len >= rl_line_buffer_len)
  4413.     rl_extend_line_buffer (line_len);
  4414.  
  4415.       strcpy (the_line, saved_line_for_history->line);
  4416.       rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
  4417.       free_history_entry (saved_line_for_history);
  4418.       saved_line_for_history = (HIST_ENTRY *)NULL;
  4419.       rl_end = rl_point = strlen (the_line);
  4420.     }
  4421.   else
  4422.     ding ();
  4423. }
  4424.  
  4425. /* Save the current line in saved_line_for_history. */
  4426. maybe_save_line ()
  4427. {
  4428.   if (!saved_line_for_history)
  4429.     {
  4430.       saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
  4431.       saved_line_for_history->line = savestring (the_line);
  4432.       saved_line_for_history->data = (char *)rl_undo_list;
  4433.     }
  4434. }
  4435.  
  4436. /* **************************************************************** */
  4437. /*                                    */
  4438. /*            History Commands                */
  4439. /*                                    */
  4440. /* **************************************************************** */
  4441.  
  4442. /* Meta-< goes to the start of the history. */
  4443. rl_beginning_of_history ()
  4444. {
  4445.   rl_get_previous_history (1 + where_history ());
  4446. }
  4447.  
  4448. /* Meta-> goes to the end of the history.  (The current line). */
  4449. rl_end_of_history ()
  4450. {
  4451.   maybe_replace_line ();
  4452.   using_history ();
  4453.   maybe_unsave_line ();
  4454. }
  4455.  
  4456. /* Move down to the next history line. */
  4457. rl_get_next_history (count)
  4458.      int count;
  4459. {
  4460.   HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
  4461.  
  4462.   if (count < 0)
  4463.     {
  4464.       rl_get_previous_history (-count);
  4465.       return;
  4466.     }
  4467.  
  4468.   if (!count)
  4469.     return;
  4470.  
  4471.   maybe_replace_line ();
  4472.  
  4473.   while (count)
  4474.     {
  4475.       temp = next_history ();
  4476.       if (!temp)
  4477.     break;
  4478.       --count;
  4479.     }
  4480.  
  4481.   if (!temp)
  4482.     maybe_unsave_line ();
  4483.   else
  4484.     {
  4485.       int line_len;
  4486.  
  4487.       line_len = strlen (temp->line);
  4488.  
  4489.       if (line_len >= rl_line_buffer_len)
  4490.     rl_extend_line_buffer (line_len);
  4491.  
  4492.       strcpy (the_line, temp->line);
  4493.       rl_undo_list = (UNDO_LIST *)temp->data;
  4494.       rl_end = rl_point = strlen (the_line);
  4495. #if defined (VI_MODE)
  4496.       if (rl_editing_mode == vi_mode)
  4497.     rl_point = 0;
  4498. #endif /* VI_MODE */
  4499.     }
  4500. }
  4501.  
  4502. /* Get the previous item out of our interactive history, making it the current
  4503.    line.  If there is no previous history, just ding. */
  4504. rl_get_previous_history (count)
  4505.      int count;
  4506. {
  4507.   HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
  4508.   HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
  4509.  
  4510.   if (count < 0)
  4511.     {
  4512.       rl_get_next_history (-count);
  4513.       return;
  4514.     }
  4515.  
  4516.   if (!count)
  4517.     return;
  4518.  
  4519.   /* If we don't have a line saved, then save this one. */
  4520.   maybe_save_line ();
  4521.  
  4522.   /* If the current line has changed, save the changes. */
  4523.   maybe_replace_line ();
  4524.  
  4525.   while (count)
  4526.     {
  4527.       temp = previous_history ();
  4528.       if (!temp)
  4529.     break;
  4530.       else
  4531.     old_temp = temp;
  4532.       --count;
  4533.     }
  4534.  
  4535.   /* If there was a large argument, and we moved back to the start of the
  4536.      history, that is not an error.  So use the last value found. */
  4537.   if (!temp && old_temp)
  4538.     temp = old_temp;
  4539.  
  4540.   if (!temp)
  4541.     ding ();
  4542.   else
  4543.     {
  4544.       int line_len;
  4545.  
  4546.       line_len = strlen (temp->line);
  4547.  
  4548.       if (line_len >= rl_line_buffer_len)
  4549.     rl_extend_line_buffer (line_len);
  4550.  
  4551.       strcpy (the_line, temp->line);
  4552.       rl_undo_list = (UNDO_LIST *)temp->data;
  4553.       rl_end = rl_point = line_len;
  4554.  
  4555. #if defined (VI_MODE)
  4556.       if (rl_editing_mode == vi_mode)
  4557.     rl_point = 0;
  4558. #endif /* VI_MODE */
  4559.     }
  4560. }
  4561.  
  4562.  
  4563. /* **************************************************************** */
  4564. /*                                    */
  4565. /*            I-Search and Searching                */
  4566. /*                                    */
  4567. /* **************************************************************** */
  4568.  
  4569. /* Search backwards through the history looking for a string which is typed
  4570.    interactively.  Start with the current line. */
  4571. rl_reverse_search_history (sign, key)
  4572.      int sign;
  4573.      int key;
  4574. {
  4575.   rl_search_history (-sign, key);
  4576. }
  4577.  
  4578. /* Search forwards through the history looking for a string which is typed
  4579.    interactively.  Start with the current line. */
  4580. rl_forward_search_history (sign, key)
  4581.      int sign;
  4582.      int key;
  4583. {
  4584.   rl_search_history (sign, key);
  4585. }
  4586.  
  4587. /* Display the current state of the search in the echo-area.
  4588.    SEARCH_STRING contains the string that is being searched for,
  4589.    DIRECTION is zero for forward, or 1 for reverse,
  4590.    WHERE is the history list number of the current line.  If it is
  4591.    -1, then this line is the starting one. */
  4592. rl_display_search (search_string, reverse_p, where)
  4593.      char *search_string;
  4594.      int reverse_p, where;
  4595. {
  4596.   char *message = (char *)NULL;
  4597.  
  4598.   message =
  4599.     (char *)alloca (1 + (search_string ? strlen (search_string) : 0) + 30);
  4600.  
  4601.   *message = '\0';
  4602.  
  4603. #if defined (NOTDEF)
  4604.   if (where != -1)
  4605.     sprintf (message, "[%d]", where + history_base);
  4606. #endif /* NOTDEF */
  4607.  
  4608.   strcat (message, "(");
  4609.  
  4610.   if (reverse_p)
  4611.     strcat (message, "reverse-");
  4612.  
  4613.   strcat (message, "i-search)`");
  4614.  
  4615.   if (search_string)
  4616.     strcat (message, search_string);
  4617.  
  4618.   strcat (message, "': ");
  4619.   rl_message (message, 0, 0);
  4620.   rl_redisplay ();
  4621. }
  4622.  
  4623. /* Search through the history looking for an interactively typed string.
  4624.    This is analogous to i-search.  We start the search in the current line.
  4625.    DIRECTION is which direction to search; >= 0 means forward, < 0 means
  4626.    backwards. */
  4627. rl_search_history (direction, invoking_key)
  4628.      int direction;
  4629.      int invoking_key;
  4630. {
  4631.   /* The string that the user types in to search for. */
  4632.   char *search_string = (char *)alloca (128);
  4633.  
  4634.   /* The current length of SEARCH_STRING. */
  4635.   int search_string_index;
  4636.  
  4637.   /* The list of lines to search through. */
  4638.   char **lines;
  4639.  
  4640.   /* The length of LINES. */
  4641.   int hlen;
  4642.  
  4643.   /* Where we get LINES from. */
  4644.   HIST_ENTRY **hlist = history_list ();
  4645.  
  4646.   register int i = 0;
  4647.   int orig_point = rl_point;
  4648.   int orig_line = where_history ();
  4649.   int last_found_line = orig_line;
  4650.   int c, done = 0;
  4651.  
  4652.   /* The line currently being searched. */
  4653.   char *sline;
  4654.  
  4655.   /* Offset in that line. */
  4656.   int index;
  4657.  
  4658.   /* Non-zero if we are doing a reverse search. */
  4659.   int reverse = (direction < 0);
  4660.  
  4661.   /* Create an arrary of pointers to the lines that we want to search. */
  4662.   maybe_replace_line ();
  4663.   if (hlist)
  4664.     for (i = 0; hlist[i]; i++);
  4665.  
  4666.   /* Allocate space for this many lines, +1 for the current input line,
  4667.      and remember those lines. */
  4668.   lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *));
  4669.   for (i = 0; i < hlen; i++)
  4670.     lines[i] = hlist[i]->line;
  4671.  
  4672.   if (saved_line_for_history)
  4673.     lines[i] = saved_line_for_history->line;
  4674.   else
  4675.     /* So I have to type it in this way instead. */
  4676.     {
  4677.       char *alloced_line;
  4678.  
  4679.       /* Keep that mips alloca happy. */
  4680.       alloced_line = (char *)alloca (1 + strlen (the_line));
  4681.       lines[i] = alloced_line;
  4682.       strcpy (lines[i], &the_line[0]);
  4683.     }
  4684.  
  4685.   hlen++;
  4686.  
  4687.   /* The line where we start the search. */
  4688.   i = orig_line;
  4689.  
  4690.   /* Initialize search parameters. */
  4691.   *search_string = '\0';
  4692.   search_string_index = 0;
  4693.  
  4694.   /* Normalize DIRECTION into 1 or -1. */
  4695.   if (direction >= 0)
  4696.     direction = 1;
  4697.   else
  4698.     direction = -1;
  4699.  
  4700.   rl_display_search (search_string, reverse, -1);
  4701.  
  4702.   sline = the_line;
  4703.   index = rl_point;
  4704.  
  4705.   while (!done)
  4706.     {
  4707.       c = rl_read_key ();
  4708.  
  4709.       /* Hack C to Do What I Mean. */
  4710.       {
  4711.     Function *f = (Function *)NULL;
  4712.  
  4713.     if (keymap[c].type == ISFUNC)
  4714.       {
  4715.         f = keymap[c].function;
  4716.  
  4717.         if (f == rl_reverse_search_history)
  4718.           c = reverse ? -1 : -2;
  4719.         else if (f == rl_forward_search_history)
  4720.           c =  !reverse ? -1 : -2;
  4721.       }
  4722.       }
  4723.  
  4724.       switch (c)
  4725.     {
  4726.     case ESC:
  4727.       done = 1;
  4728.       continue;
  4729.  
  4730.       /* case invoking_key: */
  4731.     case -1:
  4732.       goto search_again;
  4733.  
  4734.       /* switch directions */
  4735.     case -2:
  4736.       direction = -direction;
  4737.       reverse = (direction < 0);
  4738.  
  4739.       goto do_search;
  4740.  
  4741.     case CTRL ('G'):
  4742.       strcpy (the_line, lines[orig_line]);
  4743.       rl_point = orig_point;
  4744.       rl_end = strlen (the_line);
  4745.       rl_clear_message ();
  4746.       return;
  4747.  
  4748.     default:
  4749.       if (c < 32 || c > 126)
  4750.         {
  4751.           rl_execute_next (c);
  4752.           done = 1;
  4753.           continue;
  4754.         }
  4755.       else
  4756.         {
  4757.           search_string[search_string_index++] = c;
  4758.           search_string[search_string_index] = '\0';
  4759.           goto do_search;
  4760.  
  4761.         search_again:
  4762.  
  4763.           if (!search_string_index)
  4764.         continue;
  4765.           else
  4766.         {
  4767.           if (reverse)
  4768.             --index;
  4769.           else
  4770.             if (index != strlen (sline))
  4771.               ++index;
  4772.             else
  4773.               ding ();
  4774.         }
  4775.         do_search:
  4776.  
  4777.           while (1)
  4778.         {
  4779.           if (reverse)
  4780.             {
  4781.               while (index >= 0)
  4782.             if (strncmp
  4783.                 (search_string, sline + index, search_string_index)
  4784.                 == 0)
  4785.               goto string_found;
  4786.             else
  4787.               index--;
  4788.             }
  4789.           else
  4790.             {
  4791.               register int limit =
  4792.             (strlen (sline) - search_string_index) + 1;
  4793.  
  4794.               while (index < limit)
  4795.             {
  4796.               if (strncmp (search_string,
  4797.                        sline + index,
  4798.                        search_string_index) == 0)
  4799.                 goto string_found;
  4800.               index++;
  4801.             }
  4802.             }
  4803.  
  4804.         next_line:
  4805.           i += direction;
  4806.  
  4807.           /* At limit for direction? */
  4808.           if ((reverse && i < 0) ||
  4809.               (!reverse && i == hlen))
  4810.             goto search_failed;
  4811.  
  4812.           sline = lines[i];
  4813.           if (reverse)
  4814.             index = strlen (sline);
  4815.           else
  4816.             index = 0;
  4817.  
  4818.           /* If the search string is longer than the current
  4819.              line, no match. */
  4820.           if (search_string_index > strlen (sline))
  4821.             goto next_line;
  4822.  
  4823.           /* Start actually searching. */
  4824.           if (reverse)
  4825.             index -= search_string_index;
  4826.         }
  4827.  
  4828.         search_failed:
  4829.           /* We cannot find the search string.  Ding the bell. */
  4830.           ding ();
  4831.           i = last_found_line;
  4832.           break;
  4833.  
  4834.         string_found:
  4835.           /* We have found the search string.  Just display it.  But don't
  4836.          actually move there in the history list until the user accepts
  4837.          the location. */
  4838.           {
  4839.         int line_len;
  4840.  
  4841.         line_len = strlen (lines[i]);
  4842.  
  4843.         if (line_len >= rl_line_buffer_len)
  4844.           rl_extend_line_buffer (line_len);
  4845.  
  4846.         strcpy (the_line, lines[i]);
  4847.         rl_point = index;
  4848.         rl_end = line_len;
  4849.         last_found_line = i;
  4850.         rl_display_search
  4851.           (search_string, reverse, (i == orig_line) ? -1 : i);
  4852.           }
  4853.         }
  4854.     }
  4855.       continue;
  4856.     }
  4857.  
  4858.   /* The searching is over.  The user may have found the string that she
  4859.      was looking for, or else she may have exited a failing search.  If
  4860.      INDEX is -1, then that shows that the string searched for was not
  4861.      found.  We use this to determine where to place rl_point. */
  4862.   {
  4863.     int now = last_found_line;
  4864.  
  4865.     /* First put back the original state. */
  4866.     strcpy (the_line, lines[orig_line]);
  4867.  
  4868.     if (now < orig_line)
  4869.       rl_get_previous_history (orig_line - now);
  4870.     else
  4871.       rl_get_next_history (now - orig_line);
  4872.  
  4873.     /* If the index of the "matched" string is less than zero, then the
  4874.        final search string was never matched, so put point somewhere
  4875.        reasonable. */
  4876.     if (index < 0)
  4877.       index = strlen (the_line);
  4878.  
  4879.     rl_point = index;
  4880.     rl_clear_message ();
  4881.   }
  4882. }
  4883.  
  4884. /* Make C be the next command to be executed. */
  4885. rl_execute_next (c)
  4886.      int c;
  4887. {
  4888.   rl_pending_input = c;
  4889. }
  4890.  
  4891. /* **************************************************************** */
  4892. /*                                    */
  4893. /*            Killing Mechanism                */
  4894. /*                                    */
  4895. /* **************************************************************** */
  4896.  
  4897. /* What we assume for a max number of kills. */
  4898. #define DEFAULT_MAX_KILLS 10
  4899.  
  4900. /* The real variable to look at to find out when to flush kills. */
  4901. int rl_max_kills = DEFAULT_MAX_KILLS;
  4902.  
  4903. /* Where to store killed text. */
  4904. char **rl_kill_ring = (char **)NULL;
  4905.  
  4906. /* Where we are in the kill ring. */
  4907. int rl_kill_index = 0;
  4908.  
  4909. /* How many slots we have in the kill ring. */
  4910. int rl_kill_ring_length = 0;
  4911.  
  4912. /* How to say that you only want to save a certain amount
  4913.    of kill material. */
  4914. rl_set_retained_kills (num)
  4915.      int num;
  4916. {}
  4917.  
  4918. /* The way to kill something.  This appends or prepends to the last
  4919.    kill, if the last command was a kill command.  if FROM is less
  4920.    than TO, then the text is appended, otherwise prepended.  If the
  4921.    last command was not a kill command, then a new slot is made for
  4922.    this kill. */
  4923. rl_kill_text (from, to)
  4924.      int from, to;
  4925. {
  4926.   int slot;
  4927.   char *text = rl_copy (from, to);
  4928.  
  4929.   /* Is there anything to kill? */
  4930.   if (from == to)
  4931.     {
  4932.       free (text);
  4933.       last_command_was_kill++;
  4934.       return;
  4935.     }
  4936.  
  4937.   /* Delete the copied text from the line. */
  4938.   rl_delete_text (from, to);
  4939.  
  4940.   /* First, find the slot to work with. */
  4941.   if (!last_command_was_kill)
  4942.     {
  4943.       /* Get a new slot.  */
  4944.       if (!rl_kill_ring)
  4945.     {
  4946.       /* If we don't have any defined, then make one. */
  4947.       rl_kill_ring = (char **)
  4948.         xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
  4949.       slot = 1;
  4950.     }
  4951.       else
  4952.     {
  4953.       /* We have to add a new slot on the end, unless we have
  4954.          exceeded the max limit for remembering kills. */
  4955.       slot = rl_kill_ring_length;
  4956.       if (slot == rl_max_kills)
  4957.         {
  4958.           register int i;
  4959.           free (rl_kill_ring[0]);
  4960.           for (i = 0; i < slot; i++)
  4961.         rl_kill_ring[i] = rl_kill_ring[i + 1];
  4962.         }
  4963.       else
  4964.         {
  4965.           rl_kill_ring =
  4966.         (char **)
  4967.           xrealloc (rl_kill_ring,
  4968.                 ((slot = (rl_kill_ring_length += 1)) + 1)
  4969.                 * sizeof (char *));
  4970.         }
  4971.     }
  4972.       slot--;
  4973.     }
  4974.   else
  4975.     {
  4976.       slot = rl_kill_ring_length - 1;
  4977.     }
  4978.  
  4979.   /* If the last command was a kill, prepend or append. */
  4980.   if (last_command_was_kill && rl_editing_mode != vi_mode)
  4981.     {
  4982.       char *old = rl_kill_ring[slot];
  4983.       char *new = (char *)xmalloc (1 + strlen (old) + strlen (text));
  4984.  
  4985.       if (from < to)
  4986.     {
  4987.       strcpy (new, old);
  4988.       strcat (new, text);
  4989.     }
  4990.       else
  4991.     {
  4992.       strcpy (new, text);
  4993.       strcat (new, old);
  4994.     }
  4995.       free (old);
  4996.       free (text);
  4997.       rl_kill_ring[slot] = new;
  4998.     }
  4999.   else
  5000.     {
  5001.       rl_kill_ring[slot] = text;
  5002.     }
  5003.   rl_kill_index = slot;
  5004.   last_command_was_kill++;
  5005. }
  5006.  
  5007. /* Now REMEMBER!  In order to do prepending or appending correctly, kill
  5008.    commands always make rl_point's original position be the FROM argument,
  5009.    and rl_point's extent be the TO argument. */
  5010.  
  5011. /* **************************************************************** */
  5012. /*                                    */
  5013. /*            Killing Commands                */
  5014. /*                                    */
  5015. /* **************************************************************** */
  5016.  
  5017. /* Delete the word at point, saving the text in the kill ring. */
  5018. rl_kill_word (count)
  5019.      int count;
  5020. {
  5021.   int orig_point = rl_point;
  5022.  
  5023.   if (count < 0)
  5024.     rl_backward_kill_word (-count);
  5025.   else
  5026.     {
  5027.       rl_forward_word (count);
  5028.  
  5029.       if (rl_point != orig_point)
  5030.     rl_kill_text (orig_point, rl_point);
  5031.  
  5032.       rl_point = orig_point;
  5033.     }
  5034. }
  5035.  
  5036. /* Rubout the word before point, placing it on the kill ring. */
  5037. rl_backward_kill_word (count)
  5038.      int count;
  5039. {
  5040.   int orig_point = rl_point;
  5041.  
  5042.   if (count < 0)
  5043.     rl_kill_word (-count);
  5044.   else
  5045.     {
  5046.       rl_backward_word (count);
  5047.  
  5048.       if (rl_point != orig_point)
  5049.     rl_kill_text (orig_point, rl_point);
  5050.     }
  5051. }
  5052.  
  5053. /* Kill from here to the end of the line.  If DIRECTION is negative, kill
  5054.    back to the line start instead. */
  5055. rl_kill_line (direction)
  5056.      int direction;
  5057. {
  5058.   int orig_point = rl_point;
  5059.  
  5060.   if (direction < 0)
  5061.     rl_backward_kill_line (1);
  5062.   else
  5063.     {
  5064.       rl_end_of_line ();
  5065.       if (orig_point != rl_point)
  5066.     rl_kill_text (orig_point, rl_point);
  5067.       rl_point = orig_point;
  5068.     }
  5069. }
  5070.  
  5071. /* Kill backwards to the start of the line.  If DIRECTION is negative, kill
  5072.    forwards to the line end instead. */
  5073. rl_backward_kill_line (direction)
  5074.      int direction;
  5075. {
  5076.   int orig_point = rl_point;
  5077.  
  5078.   if (direction < 0)
  5079.     rl_kill_line (1);
  5080.   else
  5081.     {
  5082.       if (!rl_point)
  5083.     ding ();
  5084.       else
  5085.     {
  5086.       rl_beg_of_line ();
  5087.       rl_kill_text (orig_point, rl_point);
  5088.     }
  5089.     }
  5090. }
  5091.  
  5092. /* Yank back the last killed text.  This ignores arguments. */
  5093. rl_yank ()
  5094. {
  5095.   if (!rl_kill_ring) rl_abort ();
  5096.   rl_insert_text (rl_kill_ring[rl_kill_index]);
  5097. }
  5098.  
  5099. /* If the last command was yank, or yank_pop, and the text just
  5100.    before point is identical to the current kill item, then
  5101.    delete that text from the line, rotate the index down, and
  5102.    yank back some other text. */
  5103. rl_yank_pop ()
  5104. {
  5105.   int l;
  5106.  
  5107.   if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
  5108.       !rl_kill_ring)
  5109.     {
  5110.       rl_abort ();
  5111.     }
  5112.  
  5113.   l = strlen (rl_kill_ring[rl_kill_index]);
  5114.   if (((rl_point - l) >= 0) &&
  5115.       (strncmp (the_line + (rl_point - l),
  5116.         rl_kill_ring[rl_kill_index], l) == 0))
  5117.     {
  5118.       rl_delete_text ((rl_point - l), rl_point);
  5119.       rl_point -= l;
  5120.       rl_kill_index--;
  5121.       if (rl_kill_index < 0)
  5122.     rl_kill_index = rl_kill_ring_length - 1;
  5123.       rl_yank ();
  5124.     }
  5125.   else
  5126.     rl_abort ();
  5127.  
  5128. }
  5129.  
  5130. /* Yank the COUNTth argument from the previous history line. */
  5131. rl_yank_nth_arg (count, ignore)
  5132.      int count;
  5133. {
  5134.   register HIST_ENTRY *entry = previous_history ();
  5135.   char *arg;
  5136.  
  5137.   if (entry)
  5138.     next_history ();
  5139.   else
  5140.     {
  5141.       ding ();
  5142.       return;
  5143.     }
  5144.  
  5145.   arg = history_arg_extract (count, count, entry->line);
  5146.   if (!arg || !*arg)
  5147.     {
  5148.       ding ();
  5149.       return;
  5150.     }
  5151.  
  5152.   rl_begin_undo_group ();
  5153.  
  5154. #if defined (VI_MODE)
  5155.   /* Vi mode always inserts a space befoe yanking the argument, and it
  5156.      inserts it right *after* rl_point. */
  5157.   if (rl_editing_mode == vi_mode)
  5158.     rl_point++;
  5159. #endif /* VI_MODE */
  5160.  
  5161.   if (rl_point && the_line[rl_point - 1] != ' ')
  5162.     rl_insert_text (" ");
  5163.  
  5164.   rl_insert_text (arg);
  5165.   free (arg);
  5166.  
  5167.   rl_end_undo_group ();
  5168. }
  5169.  
  5170. /* How to toggle back and forth between editing modes. */
  5171. rl_vi_editing_mode ()
  5172. {
  5173. #if defined (VI_MODE)
  5174.   rl_editing_mode = vi_mode;
  5175.   rl_vi_insertion_mode ();
  5176. #endif /* VI_MODE */
  5177. }
  5178.  
  5179. rl_emacs_editing_mode ()
  5180. {
  5181.   rl_editing_mode = emacs_mode;
  5182.   keymap = emacs_standard_keymap;
  5183. }
  5184.  
  5185.  
  5186. /* **************************************************************** */
  5187. /*                                    */
  5188. /*                 Completion                    */
  5189. /*                                    */
  5190. /* **************************************************************** */
  5191.  
  5192. /* Non-zero means that case is not significant in completion. */
  5193. int completion_case_fold = 0;
  5194.  
  5195. /* Return an array of (char *) which is a list of completions for TEXT.
  5196.    If there are no completions, return a NULL pointer.
  5197.    The first entry in the returned array is the substitution for TEXT.
  5198.    The remaining entries are the possible completions.
  5199.    The array is terminated with a NULL pointer.
  5200.  
  5201.    ENTRY_FUNCTION is a function of two args, and returns a (char *).
  5202.      The first argument is TEXT.
  5203.      The second is a state argument; it should be zero on the first call, and
  5204.      non-zero on subsequent calls.  It returns a NULL pointer to the caller
  5205.      when there are no more matches.
  5206.  */
  5207. char **
  5208. completion_matches (text, entry_function)
  5209.      char *text;
  5210.      char *(*entry_function) ();
  5211. {
  5212.   /* Number of slots in match_list. */
  5213.   int match_list_size;
  5214.  
  5215.   /* The list of matches. */
  5216.   char **match_list =
  5217.     (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
  5218.  
  5219.   /* Number of matches actually found. */
  5220.   int matches = 0;
  5221.  
  5222.   /* Temporary string binder. */
  5223.   char *string;
  5224.  
  5225.   match_list[1] = (char *)NULL;
  5226.  
  5227.   while (string = (*entry_function) (text, matches))
  5228.     {
  5229.       if (matches + 1 == match_list_size)
  5230.     match_list = (char **)xrealloc
  5231.       (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
  5232.  
  5233.       match_list[++matches] = string;
  5234.       match_list[matches + 1] = (char *)NULL;
  5235.     }
  5236.  
  5237.   /* If there were any matches, then look through them finding out the
  5238.      lowest common denominator.  That then becomes match_list[0]. */
  5239.   if (matches)
  5240.     {
  5241.       register int i = 1;
  5242.       int low = 100000;        /* Count of max-matched characters. */
  5243.  
  5244.       /* If only one match, just use that. */
  5245.       if (matches == 1)
  5246.     {
  5247.       match_list[0] = match_list[1];
  5248.       match_list[1] = (char *)NULL;
  5249.     }
  5250.       else
  5251.     {
  5252.       /* Otherwise, compare each member of the list with
  5253.          the next, finding out where they stop matching. */
  5254.  
  5255.       while (i < matches)
  5256.         {
  5257.           register int c1, c2, si;
  5258.  
  5259.           if (completion_case_fold)
  5260.         {
  5261.           for (si = 0;
  5262.                (c1 = to_lower(match_list[i][si])) &&
  5263.                (c2 = to_lower(match_list[i + 1][si]));
  5264.                si++)
  5265.             if (c1 != c2) break;
  5266.         }
  5267.           else
  5268.         {
  5269.           for (si = 0;
  5270.                (c1 = match_list[i][si]) &&
  5271.                (c2 = match_list[i + 1][si]);
  5272.                si++)
  5273.             if (c1 != c2) break;
  5274.         }
  5275.  
  5276.           if (low > si) low = si;
  5277.           i++;
  5278.         }
  5279.       match_list[0] = (char *)xmalloc (low + 1);
  5280.       strncpy (match_list[0], match_list[1], low);
  5281.       match_list[0][low] = '\0';
  5282.     }
  5283.     }
  5284.   else                /* There were no matches. */
  5285.     {
  5286.       free (match_list);
  5287.       match_list = (char **)NULL;
  5288.     }
  5289.   return (match_list);
  5290. }
  5291.  
  5292. /* Okay, now we write the entry_function for filename completion.  In the
  5293.    general case.  Note that completion in the shell is a little different
  5294.    because of all the pathnames that must be followed when looking up the
  5295.    completion for a command. */
  5296. char *
  5297. filename_completion_function (text, state)
  5298.      int state;
  5299.      char *text;
  5300. {
  5301.   static DIR *directory;
  5302.   static char *filename = (char *)NULL;
  5303.   static char *dirname = (char *)NULL;
  5304.   static char *users_dirname = (char *)NULL;
  5305.   static int filename_len;
  5306.  
  5307.   dirent *entry = (dirent *)NULL;
  5308.  
  5309.   /* If we don't have any state, then do some initialization. */
  5310.   if (!state)
  5311.     {
  5312.       char *temp;
  5313.  
  5314.       if (dirname) free (dirname);
  5315.       if (filename) free (filename);
  5316.       if (users_dirname) free (users_dirname);
  5317.  
  5318.       filename = savestring (text);
  5319.       if (!*text) text = ".";
  5320.       dirname = savestring (text);
  5321.  
  5322.       temp = rindex (dirname, '/');
  5323.  
  5324.       if (temp)
  5325.     {
  5326.       strcpy (filename, ++temp);
  5327.       *temp = '\0';
  5328.     }
  5329.       else
  5330.     strcpy (dirname, ".");
  5331.  
  5332.       /* We aren't done yet.  We also support the "~user" syntax. */
  5333.  
  5334.       /* Save the version of the directory that the user typed. */
  5335.       users_dirname = savestring (dirname);
  5336.       {
  5337.     char *temp_dirname;
  5338.  
  5339.     temp_dirname = tilde_expand (dirname);
  5340.     free (dirname);
  5341.     dirname = temp_dirname;
  5342.  
  5343.     if (rl_symbolic_link_hook)
  5344.       (*rl_symbolic_link_hook) (&dirname);
  5345.       }
  5346.       directory = opendir (dirname);
  5347.       filename_len = strlen (filename);
  5348.  
  5349.       rl_filename_completion_desired = 1;
  5350.     }
  5351.  
  5352.   /* At this point we should entertain the possibility of hacking wildcarded
  5353.      filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name
  5354.      contains globbing characters, then build an array of directories to
  5355.      glob on, and glob on the first one. */
  5356.  
  5357.   /* Now that we have some state, we can read the directory. */
  5358.  
  5359.   while (directory && (entry = readdir (directory)))
  5360.     {
  5361.       /* Special case for no filename.
  5362.      All entries except "." and ".." match. */
  5363.       if (!filename_len)
  5364.     {
  5365.       if ((strcmp (entry->d_name, ".") != 0) &&
  5366.           (strcmp (entry->d_name, "..") != 0))
  5367.         break;
  5368.     }
  5369.       else
  5370.     {
  5371.       /* Otherwise, if these match upto the length of filename, then
  5372.          it is a match. */
  5373.         if (entry->d_name[0] == filename[0] && /* Quick test */
  5374.         (strncmp (filename, entry->d_name, filename_len) == 0))
  5375.           {
  5376.         break;
  5377.           }
  5378.     }
  5379.     }
  5380.  
  5381.   if (!entry)
  5382.     {
  5383.       if (directory)
  5384.     {
  5385.       closedir (directory);
  5386.       directory = (DIR *)NULL;
  5387.     }
  5388.       return (char *)NULL;
  5389.     }
  5390.   else
  5391.     {
  5392.       char *temp;
  5393.  
  5394.       if (dirname && (strcmp (dirname, ".") != 0))
  5395.     {
  5396.       temp = (char *)
  5397.         xmalloc (1 + strlen (users_dirname) + strlen (entry->d_name));
  5398.       strcpy (temp, users_dirname);
  5399.       strcat (temp, entry->d_name);
  5400.     }
  5401.       else
  5402.     {
  5403.       temp = (savestring (entry->d_name));
  5404.     }
  5405.       return (temp);
  5406.     }
  5407. }
  5408.  
  5409.  
  5410. /* **************************************************************** */
  5411. /*                                    */
  5412. /*            Binding keys                    */
  5413. /*                                    */
  5414. /* **************************************************************** */
  5415.  
  5416. /* rl_add_defun (char *name, Function *function, int key)
  5417.    Add NAME to the list of named functions.  Make FUNCTION
  5418.    be the function that gets called.
  5419.    If KEY is not -1, then bind it. */
  5420. rl_add_defun (name, function, key)
  5421.      char *name;
  5422.      Function *function;
  5423.      int key;
  5424. {
  5425.   if (key != -1)
  5426.     rl_bind_key (key, function);
  5427.   rl_add_funmap_entry (name, function);
  5428. }
  5429.  
  5430. /* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
  5431. int
  5432. rl_bind_key (key, function)
  5433.      int key;
  5434.      Function *function;
  5435. {
  5436.   if (key < 0)
  5437.     return (key);
  5438.  
  5439.   if (key > 127 && key < 256)
  5440.     {
  5441.       if (keymap[ESC].type == ISKMAP)
  5442.     {
  5443.       Keymap escmap = (Keymap)keymap[ESC].function;
  5444.  
  5445.       key -= 128;
  5446.       escmap[key].type = ISFUNC;
  5447.       escmap[key].function = function;
  5448.       return (0);
  5449.     }
  5450.       return (key);
  5451.     }
  5452.  
  5453.   keymap[key].type = ISFUNC;
  5454.   keymap[key].function = function;
  5455.  return (0);
  5456. }
  5457.  
  5458. /* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
  5459.    KEY. */
  5460. int
  5461. rl_bind_key_in_map (key, function, map)
  5462.      int key;
  5463.      Function *function;
  5464.      Keymap map;
  5465. {
  5466.   int result;
  5467.   Keymap oldmap = keymap;
  5468.  
  5469.   keymap = map;
  5470.   result = rl_bind_key (key, function);
  5471.   keymap = oldmap;
  5472.   return (result);
  5473. }
  5474.  
  5475. /* Make KEY do nothing in the currently selected keymap.
  5476.    Returns non-zero in case of error. */
  5477. int
  5478. rl_unbind_key (key)
  5479.      int key;
  5480. {
  5481.   return (rl_bind_key (key, (Function *)NULL));
  5482. }
  5483.  
  5484. /* Make KEY do nothing in MAP.
  5485.    Returns non-zero in case of error. */
  5486. int
  5487. rl_unbind_key_in_map (key, map)
  5488.      int key;
  5489.      Keymap map;
  5490. {
  5491.   return (rl_bind_key_in_map (key, (Function *)NULL, map));
  5492. }
  5493.  
  5494. /* Bind the key sequence represented by the string KEYSEQ to
  5495.    FUNCTION.  This makes new keymaps as necessary.  The initial
  5496.    place to do bindings is in MAP. */
  5497. rl_set_key (keyseq, function, map)
  5498.      char *keyseq;
  5499.      Function *function;
  5500.      Keymap map;
  5501. {
  5502.   rl_generic_bind (ISFUNC, keyseq, function, map);
  5503. }
  5504.  
  5505. /* Bind the key sequence represented by the string KEYSEQ to
  5506.    the string of characters MACRO.  This makes new keymaps as
  5507.    necessary.  The initial place to do bindings is in MAP. */
  5508. rl_macro_bind (keyseq, macro, map)
  5509.      char *keyseq, *macro;
  5510.      Keymap map;
  5511. {
  5512.   char *macro_keys;
  5513.   int macro_keys_len;
  5514.  
  5515.   macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
  5516.  
  5517.   if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len))
  5518.     {
  5519.       free (macro_keys);
  5520.       return;
  5521.     }
  5522.   rl_generic_bind (ISMACR, keyseq, macro_keys, map);
  5523. }
  5524.  
  5525. /* Bind the key sequence represented by the string KEYSEQ to
  5526.    the arbitrary pointer DATA.  TYPE says what kind of data is
  5527.    pointed to by DATA, right now this can be a function (ISFUNC),
  5528.    a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
  5529.    as necessary.  The initial place to do bindings is in MAP. */
  5530.  
  5531. static void
  5532. rl_generic_bind (type, keyseq, data, map)
  5533.      int type;
  5534.      char *keyseq, *data;
  5535.      Keymap map;
  5536. {
  5537.   char *keys;
  5538.   int keys_len;
  5539.   register int i;
  5540.  
  5541.   /* If no keys to bind to, exit right away. */
  5542.   if (!keyseq || !*keyseq)
  5543.     {
  5544.       if (type == ISMACR)
  5545.     free (data);
  5546.       return;
  5547.     }
  5548.  
  5549.   keys = (char *)alloca (1 + (2 * strlen (keyseq)));
  5550.  
  5551.   /* Translate the ASCII representation of KEYSEQ into an array
  5552.      of characters.  Stuff the characters into ARRAY, and the
  5553.      length of ARRAY into LENGTH. */
  5554.   if (rl_translate_keyseq (keyseq, keys, &keys_len))
  5555.     return;
  5556.  
  5557.   /* Bind keys, making new keymaps as necessary. */
  5558.   for (i = 0; i < keys_len; i++)
  5559.     {
  5560.       if (i + 1 < keys_len)
  5561.     {
  5562.       if (map[keys[i]].type != ISKMAP)
  5563.         {
  5564.           if (map[i].type == ISMACR)
  5565.         free ((char *)map[i].function);
  5566.  
  5567.           map[keys[i]].type = ISKMAP;
  5568.           map[keys[i]].function = (Function *)rl_make_bare_keymap ();
  5569.         }
  5570.       map = (Keymap)map[keys[i]].function;
  5571.     }
  5572.       else
  5573.     {
  5574.       if (map[keys[i]].type == ISMACR)
  5575.         free ((char *)map[keys[i]].function);
  5576.  
  5577.       map[keys[i]].function = (Function *)data;
  5578.       map[keys[i]].type = type;
  5579.     }
  5580.     }
  5581. }
  5582.  
  5583. /* Translate the ASCII representation of SEQ, stuffing the
  5584.    values into ARRAY, an array of characters.  LEN gets the
  5585.    final length of ARRAY.  Return non-zero if there was an
  5586.    error parsing SEQ. */
  5587. rl_translate_keyseq (seq, array, len)
  5588.      char *seq, *array;
  5589.      int *len;
  5590. {
  5591.   register int i, c, l = 0;
  5592.  
  5593.   for (i = 0; c = seq[i]; i++)
  5594.     {
  5595.       if (c == '\\')
  5596.     {
  5597.       c = seq[++i];
  5598.  
  5599.       if (!c)
  5600.         break;
  5601.  
  5602.       if (((c == 'C' || c == 'M') &&  seq[i + 1] == '-') ||
  5603.           (c == 'e'))
  5604.         {
  5605.           /* Handle special case of backwards define. */
  5606.           if (strncmp (&seq[i], "C-\\M-", 5) == 0)
  5607.         {
  5608.           array[l++] = ESC;
  5609.           i += 5;
  5610.           array[l++] = CTRL (to_upper (seq[i]));
  5611.           if (!seq[i])
  5612.             i--;
  5613.           continue;
  5614.         }
  5615.  
  5616.           switch (c)
  5617.         {
  5618.         case 'M':
  5619.           i++;
  5620.           array[l++] = ESC;
  5621.           break;
  5622.  
  5623.         case 'C':
  5624.           i += 2;
  5625.           /* Special hack for C-?... */
  5626.           if (seq[i] == '?')
  5627.             array[l++] = RUBOUT;
  5628.           else
  5629.             array[l++] = CTRL (to_upper (seq[i]));
  5630.           break;
  5631.  
  5632.         case 'e':
  5633.           array[l++] = ESC;
  5634.         }
  5635.  
  5636.           continue;
  5637.         }
  5638.     }
  5639.       array[l++] = c;
  5640.     }
  5641.  
  5642.   *len = l;
  5643.   array[l] = '\0';
  5644.   return (0);
  5645. }
  5646.  
  5647. /* Return a pointer to the function that STRING represents.
  5648.    If STRING doesn't have a matching function, then a NULL pointer
  5649.    is returned. */
  5650. Function *
  5651. rl_named_function (string)
  5652.      char *string;
  5653. {
  5654.   register int i;
  5655.  
  5656.   for (i = 0; funmap[i]; i++)
  5657.     if (stricmp (funmap[i]->name, string) == 0)
  5658.       return (funmap[i]->function);
  5659.   return ((Function *)NULL);
  5660. }
  5661.  
  5662. /* The last key bindings file read. */
  5663. #ifdef __MSDOS__
  5664. /* Don't know what to do, but this is a guess */
  5665. static char *last_readline_init_file = "/INPUTRC";
  5666. #else
  5667. static char *last_readline_init_file = "~/.inputrc";
  5668. #endif
  5669.  
  5670. /* Re-read the current keybindings file. */
  5671. rl_re_read_init_file (count, ignore)
  5672.      int count, ignore;
  5673. {
  5674.   rl_read_init_file ((char *)NULL);
  5675. }
  5676.  
  5677. /* Do key bindings from a file.  If FILENAME is NULL it defaults
  5678.    to `~/.inputrc'.  If the file existed and could be opened and
  5679.    read, 0 is returned, otherwise errno is returned. */
  5680. int
  5681. rl_read_init_file (filename)
  5682.      char *filename;
  5683. {
  5684.   register int i;
  5685.   char *buffer, *openname, *line, *end;
  5686.   struct stat finfo;
  5687.   int file;
  5688.  
  5689.   /* Default the filename. */
  5690.   if (!filename)
  5691.     filename = last_readline_init_file;
  5692.  
  5693.   openname = tilde_expand (filename);
  5694.  
  5695.   if (!openname || *openname == '\000')
  5696.     return ENOENT;
  5697.  
  5698.   if ((stat (openname, &finfo) < 0) ||
  5699.       (file = open (openname, O_RDONLY, 0666)) < 0)
  5700.     {
  5701.       free (openname);
  5702.       return (errno);
  5703.     }
  5704.   else
  5705.     free (openname);
  5706.  
  5707.   last_readline_init_file = filename;
  5708.  
  5709.   /* Read the file into BUFFER. */
  5710.   buffer = (char *)xmalloc (finfo.st_size + 1);
  5711.   i = read (file, buffer, finfo.st_size);
  5712.   close (file);
  5713.  
  5714.   if (i != finfo.st_size)
  5715.     return (errno);
  5716.  
  5717.   /* Loop over the lines in the file.  Lines that start with `#' are
  5718.      comments; all other lines are commands for readline initialization. */
  5719.   line = buffer;
  5720.   end = buffer + finfo.st_size;
  5721.   while (line < end)
  5722.     {
  5723.       /* Find the end of this line. */
  5724.       for (i = 0; line + i != end && line[i] != '\n'; i++);
  5725.  
  5726.       /* Mark end of line. */
  5727.       line[i] = '\0';
  5728.  
  5729.       /* If the line is not a comment, then parse it. */
  5730.       if (*line != '#')
  5731.     rl_parse_and_bind (line);
  5732.  
  5733.       /* Move to the next line. */
  5734.       line += i + 1;
  5735.     }
  5736.   return (0);
  5737. }
  5738.  
  5739. /* **************************************************************** */
  5740. /*                                    */
  5741. /*            Parser Directives                   */
  5742. /*                                    */
  5743. /* **************************************************************** */
  5744.  
  5745. /* Conditionals. */
  5746.  
  5747. /* Calling programs set this to have their argv[0]. */
  5748. char *rl_readline_name = "other";
  5749.  
  5750. /* Stack of previous values of parsing_conditionalized_out. */
  5751. static unsigned char *if_stack = (unsigned char *)NULL;
  5752. static int if_stack_depth = 0;
  5753. static int if_stack_size = 0;
  5754.  
  5755. /* Push parsing_conditionalized_out, and set parser state based on ARGS. */
  5756. parser_if (args)
  5757.      char *args;
  5758. {
  5759.   register int i;
  5760.  
  5761.   /* Push parser state. */
  5762.   if (if_stack_depth + 1 >= if_stack_size)
  5763.     {
  5764.       if (!if_stack)
  5765.     if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
  5766.       else
  5767.     if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
  5768.     }
  5769.   if_stack[if_stack_depth++] = parsing_conditionalized_out;
  5770.  
  5771.   /* If parsing is turned off, then nothing can turn it back on except
  5772.      for finding the matching endif.  In that case, return right now. */
  5773.   if (parsing_conditionalized_out)
  5774.     return;
  5775.  
  5776.   /* Isolate first argument. */
  5777.   for (i = 0; args[i] && !whitespace (args[i]); i++);
  5778.  
  5779.   if (args[i])
  5780.     args[i++] = '\0';
  5781.  
  5782.   /* Handle "if term=foo" and "if mode=emacs" constructs.  If this
  5783.      isn't term=foo, or mode=emacs, then check to see if the first
  5784.      word in ARGS is the same as the value stored in rl_readline_name. */
  5785.   if (rl_terminal_name && strnicmp (args, "term=", 5) == 0)
  5786.     {
  5787.       char *tem, *tname;
  5788.  
  5789.       /* Terminals like "aaa-60" are equivalent to "aaa". */
  5790.       tname = savestring (rl_terminal_name);
  5791.       tem = rindex (tname, '-');
  5792.       if (tem)
  5793.     *tem = '\0';
  5794.  
  5795.       if (stricmp (args + 5, tname) == 0)
  5796.     parsing_conditionalized_out = 0;
  5797.       else
  5798.     parsing_conditionalized_out = 1;
  5799.  
  5800.       free (tname);
  5801.     }
  5802. #if defined (VI_MODE)
  5803.   else if (strnicmp (args, "mode=", 5) == 0)
  5804.     {
  5805.       int mode;
  5806.  
  5807.       if (stricmp (args + 5, "emacs") == 0)
  5808.     mode = emacs_mode;
  5809.       else if (stricmp (args + 5, "vi") == 0)
  5810.     mode = vi_mode;
  5811.       else
  5812.     mode = no_mode;
  5813.  
  5814.       if (mode == rl_editing_mode)
  5815.     parsing_conditionalized_out = 0;
  5816.       else
  5817.     parsing_conditionalized_out = 1;
  5818.     }
  5819. #endif /* VI_MODE */
  5820.   /* Check to see if the first word in ARGS is the same as the
  5821.      value stored in rl_readline_name. */
  5822.   else if (stricmp (args, rl_readline_name) == 0)
  5823.     parsing_conditionalized_out = 0;
  5824.   else
  5825.     parsing_conditionalized_out = 1;
  5826. }
  5827.  
  5828. /* Invert the current parser state if there is anything on the stack. */
  5829. parser_else (args)
  5830.      char *args;
  5831. {
  5832.   register int i;
  5833.  
  5834.   if (!if_stack_depth)
  5835.     {
  5836.       /* Error message? */
  5837.       return;
  5838.     }
  5839.  
  5840.   /* Check the previous (n - 1) levels of the stack to make sure that
  5841.      we haven't previously turned off parsing. */
  5842.   for (i = 0; i < if_stack_depth - 1; i++)
  5843.     if (if_stack[i] == 1)
  5844.       return;
  5845.  
  5846.   /* Invert the state of parsing if at top level. */
  5847.   parsing_conditionalized_out = !parsing_conditionalized_out;
  5848. }
  5849.  
  5850. /* Terminate a conditional, popping the value of
  5851.    parsing_conditionalized_out from the stack. */
  5852. parser_endif (args)
  5853.      char *args;
  5854. {
  5855.   if (if_stack_depth)
  5856.     parsing_conditionalized_out = if_stack[--if_stack_depth];
  5857.   else
  5858.     {
  5859.       /* *** What, no error message? *** */
  5860.     }
  5861. }
  5862.  
  5863. /* Associate textual names with actual functions. */
  5864. static struct {
  5865.   char *name;
  5866.   Function *function;
  5867. } parser_directives [] = {
  5868.   { "if", parser_if },
  5869.   { "endif", parser_endif },
  5870.   { "else", parser_else },
  5871.   { (char *)0x0, (Function *)0x0 }
  5872. };
  5873.  
  5874. /* Handle a parser directive.  STATEMENT is the line of the directive
  5875.    without any leading `$'. */
  5876. static int
  5877. handle_parser_directive (statement)
  5878.      char *statement;
  5879. {
  5880.   register int i;
  5881.   char *directive, *args;
  5882.  
  5883.   /* Isolate the actual directive. */
  5884.  
  5885.   /* Skip whitespace. */
  5886.   for (i = 0; whitespace (statement[i]); i++);
  5887.  
  5888.   directive = &statement[i];
  5889.  
  5890.   for (; statement[i] && !whitespace (statement[i]); i++);
  5891.  
  5892.   if (statement[i])
  5893.     statement[i++] = '\0';
  5894.  
  5895.   for (; statement[i] && whitespace (statement[i]); i++);
  5896.  
  5897.   args = &statement[i];
  5898.  
  5899.   /* Lookup the command, and act on it. */
  5900.   for (i = 0; parser_directives[i].name; i++)
  5901.     if (stricmp (directive, parser_directives[i].name) == 0)
  5902.       {
  5903.     (*parser_directives[i].function) (args);
  5904.     return (0);
  5905.       }
  5906.  
  5907.   /* *** Should an error message be output? */
  5908.   return (1);
  5909. }
  5910.  
  5911. /* Ugly but working hack for binding prefix meta. */
  5912. #define PREFIX_META_HACK
  5913.  
  5914. static int substring_member_of_array ();
  5915.  
  5916. /* Read the binding command from STRING and perform it.
  5917.    A key binding command looks like: Keyname: function-name\0,
  5918.    a variable binding command looks like: set variable value.
  5919.    A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
  5920. rl_parse_and_bind (string)
  5921.      char *string;
  5922. {
  5923.   extern char *possible_control_prefixes[], *possible_meta_prefixes[];
  5924.   char *funname, *kname;
  5925.   register int c;
  5926.   int key, i;
  5927.  
  5928.   while (string && whitespace (*string))
  5929.     string++;
  5930.  
  5931.   if (!string || !*string || *string == '#')
  5932.     return;
  5933.  
  5934.   /* If this is a parser directive, act on it. */
  5935.   if (*string == '$')
  5936.     {
  5937.       handle_parser_directive (&string[1]);
  5938.       return;
  5939.     }
  5940.  
  5941.   /* If we are supposed to be skipping parsing right now, then do it. */
  5942.   if (parsing_conditionalized_out)
  5943.     return;
  5944.  
  5945.   i = 0;
  5946.   /* If this keyname is a complex key expression surrounded by quotes,
  5947.      advance to after the matching close quote. */
  5948.   if (*string == '"')
  5949.     {
  5950.       for (i = 1; c = string[i]; i++)
  5951.     {
  5952.       if (c == '"' && string[i - 1] != '\\')
  5953.         break;
  5954.     }
  5955.     }
  5956.  
  5957.   /* Advance to the colon (:) or whitespace which separates the two objects. */
  5958.   for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
  5959.  
  5960.   /* Mark the end of the command (or keyname). */
  5961.   if (string[i])
  5962.     string[i++] = '\0';
  5963.  
  5964.   /* If this is a command to set a variable, then do that. */
  5965.   if (stricmp (string, "set") == 0)
  5966.     {
  5967.       char *var = string + i;
  5968.       char *value;
  5969.  
  5970.       /* Make VAR point to start of variable name. */
  5971.       while (*var && whitespace (*var)) var++;
  5972.  
  5973.       /* Make value point to start of value string. */
  5974.       value = var;
  5975.       while (*value && !whitespace (*value)) value++;
  5976.       if (*value)
  5977.     *value++ = '\0';
  5978.       while (*value && whitespace (*value)) value++;
  5979.  
  5980.       rl_variable_bind (var, value);
  5981.       return;
  5982.     }
  5983.  
  5984.   /* Skip any whitespace between keyname and funname. */
  5985.   for (; string[i] && whitespace (string[i]); i++);
  5986.   funname = &string[i];
  5987.  
  5988.   /* Now isolate funname.
  5989.      For straight function names just look for whitespace, since
  5990.      that will signify the end of the string.  But this could be a
  5991.      macro definition.  In that case, the string is quoted, so skip
  5992.      to the matching delimiter. */
  5993.   if (*funname == '\'' || *funname == '"')
  5994.     {
  5995.       int delimiter = string[i++];
  5996.  
  5997.       for (; c = string[i]; i++)
  5998.     {
  5999.       if (c == delimiter && string[i - 1] != '\\')
  6000.         break;
  6001.     }
  6002.       if (c)
  6003.     i++;
  6004.     }
  6005.  
  6006.   /* Advance to the end of the string.  */
  6007.   for (; string[i] && !whitespace (string[i]); i++);
  6008.  
  6009.   /* No extra whitespace at the end of the string. */
  6010.   string[i] = '\0';
  6011.  
  6012.   /* If this is a new-style key-binding, then do the binding with
  6013.      rl_set_key ().  Otherwise, let the older code deal with it. */
  6014.   if (*string == '"')
  6015.     {
  6016.       char *seq = (char *)alloca (1 + strlen (string));
  6017.       register int j, k = 0;
  6018.  
  6019.       for (j = 1; string[j]; j++)
  6020.     {
  6021.       if (string[j] == '"' && string[j - 1] != '\\')
  6022.         break;
  6023.  
  6024.       seq[k++] = string[j];
  6025.     }
  6026.       seq[k] = '\0';
  6027.  
  6028.       /* Binding macro? */
  6029.       if (*funname == '\'' || *funname == '"')
  6030.     {
  6031.       j = strlen (funname);
  6032.  
  6033.       if (j && funname[j - 1] == *funname)
  6034.         funname[j - 1] = '\0';
  6035.  
  6036.       rl_macro_bind (seq, &funname[1], keymap);
  6037.     }
  6038.       else
  6039.     rl_set_key (seq, rl_named_function (funname), keymap);
  6040.  
  6041.       return;
  6042.     }
  6043.  
  6044.   /* Get the actual character we want to deal with. */
  6045.   kname = rindex (string, '-');
  6046.   if (!kname)
  6047.     kname = string;
  6048.   else
  6049.     kname++;
  6050.  
  6051.   key = glean_key_from_name (kname);
  6052.  
  6053.   /* Add in control and meta bits. */
  6054.   if (substring_member_of_array (string, possible_control_prefixes))
  6055.     key = CTRL (to_upper (key));
  6056.  
  6057.   if (substring_member_of_array (string, possible_meta_prefixes))
  6058.     key = META (key);
  6059.  
  6060.   /* Temporary.  Handle old-style keyname with macro-binding. */
  6061.   if (*funname == '\'' || *funname == '"')
  6062.     {
  6063.       char seq[2];
  6064.       int fl = strlen (funname);
  6065.  
  6066.       seq[0] = key; seq[1] = '\0';
  6067.       if (fl && funname[fl - 1] == *funname)
  6068.     funname[fl - 1] = '\0';
  6069.  
  6070.       rl_macro_bind (seq, &funname[1], keymap);
  6071.     }
  6072. #if defined (PREFIX_META_HACK)
  6073.   /* Ugly, but working hack to keep prefix-meta around. */
  6074.   else if (stricmp (funname, "prefix-meta") == 0)
  6075.     {
  6076.       char seq[2];
  6077.  
  6078.       seq[0] = key;
  6079.       seq[1] = '\0';
  6080.       rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, keymap);
  6081.     }
  6082. #endif /* PREFIX_META_HACK */
  6083.   else
  6084.     rl_bind_key (key, rl_named_function (funname));
  6085. }
  6086.  
  6087. rl_variable_bind (name, value)
  6088.      char *name, *value;
  6089. {
  6090.   if (stricmp (name, "editing-mode") == 0)
  6091.     {
  6092.       if (strnicmp (value, "vi", 2) == 0)
  6093.     {
  6094. #if defined (VI_MODE)
  6095.       keymap = vi_insertion_keymap;
  6096.       rl_editing_mode = vi_mode;
  6097. #else
  6098. #if defined (NOTDEF)
  6099.       /* What state is the terminal in?  I'll tell you:
  6100.          non-determinate!  That means we cannot do any output. */
  6101.       ding ();
  6102. #endif /* NOTDEF */
  6103. #endif /* VI_MODE */
  6104.     }
  6105.       else if (strnicmp (value, "emacs", 5) == 0)
  6106.     {
  6107.       keymap = emacs_standard_keymap;
  6108.       rl_editing_mode = emacs_mode;
  6109.     }
  6110.     }
  6111.   else if (stricmp (name, "horizontal-scroll-mode") == 0)
  6112.     {
  6113.       if (!*value || stricmp (value, "On") == 0)
  6114.     horizontal_scroll_mode = 1;
  6115.       else
  6116.     horizontal_scroll_mode = 0;
  6117.     }
  6118.   else if (stricmp (name, "mark-modified-lines") == 0)
  6119.     {
  6120.       if (!*value || stricmp (value, "On") == 0)
  6121.     mark_modified_lines = 1;
  6122.       else
  6123.     mark_modified_lines = 0;
  6124.     }
  6125.   else if (stricmp (name, "prefer-visible-bell") == 0)
  6126.     {
  6127.       if (!*value || stricmp (value, "On") == 0)
  6128.         prefer_visible_bell = 1;
  6129.       else
  6130.         prefer_visible_bell = 0;
  6131.     }
  6132.   else if (stricmp (name, "comment-begin") == 0)
  6133.     {
  6134. #if defined (VI_MODE)
  6135.       extern char *rl_vi_comment_begin;
  6136.  
  6137.       if (*value)
  6138.     {
  6139.       if (rl_vi_comment_begin)
  6140.         free (rl_vi_comment_begin);
  6141.  
  6142.       rl_vi_comment_begin = savestring (value);
  6143.     }
  6144. #endif /* VI_MODE */
  6145.     }
  6146. }
  6147.  
  6148. /* Return the character which matches NAME.
  6149.    For example, `Space' returns ' '. */
  6150.  
  6151. typedef struct {
  6152.   char *name;
  6153.   int value;
  6154. } assoc_list;
  6155.  
  6156. assoc_list name_key_alist[] = {
  6157.   { "DEL", 0x7f },
  6158.   { "ESC", '\033' },
  6159.   { "Escape", '\033' },
  6160.   { "LFD", '\n' },
  6161.   { "Newline", '\n' },
  6162.   { "RET", '\r' },
  6163.   { "Return", '\r' },
  6164.   { "Rubout", 0x7f },
  6165.   { "SPC", ' ' },
  6166.   { "Space", ' ' },
  6167.   { "Tab", 0x09 },
  6168.   { (char *)0x0, 0 }
  6169. };
  6170.  
  6171. int
  6172. glean_key_from_name (name)
  6173.      char *name;
  6174. {
  6175.   register int i;
  6176.  
  6177.   for (i = 0; name_key_alist[i].name; i++)
  6178.     if (stricmp (name, name_key_alist[i].name) == 0)
  6179.       return (name_key_alist[i].value);
  6180.  
  6181.   return (*name);
  6182. }
  6183.  
  6184.  
  6185. /* **************************************************************** */
  6186. /*                                    */
  6187. /*          Key Binding and Function Information            */
  6188. /*                                    */
  6189. /* **************************************************************** */
  6190.  
  6191. /* Each of the following functions produces information about the
  6192.    state of keybindings and functions known to Readline.  The info
  6193.    is always printed to rl_outstream, and in such a way that it can
  6194.    be read back in (i.e., passed to rl_parse_and_bind (). */
  6195.  
  6196. /* Print the names of functions known to Readline. */
  6197. void
  6198. rl_list_funmap_names (ignore)
  6199.      int ignore;
  6200. {
  6201.   register int i;
  6202.   char **funmap_names;
  6203.   extern char **rl_funmap_names ();
  6204.  
  6205.   funmap_names = rl_funmap_names ();
  6206.  
  6207.   if (!funmap_names)
  6208.     return;
  6209.  
  6210.   for (i = 0; funmap_names[i]; i++)
  6211.     fprintf (rl_outstream, "%s\n", funmap_names[i]);
  6212.  
  6213.   free (funmap_names);
  6214. }
  6215.  
  6216. /* Return a NULL terminated array of strings which represent the key
  6217.    sequences that are used to invoke FUNCTION in MAP. */
  6218. static char **
  6219. invoking_keyseqs_in_map (function, map)
  6220.      Function *function;
  6221.      Keymap map;
  6222. {
  6223.   register int key;
  6224.   char **result;
  6225.   int result_index, result_size;
  6226.  
  6227.   result = (char **)NULL;
  6228.   result_index = result_size = 0;
  6229.  
  6230.   for (key = 0; key < 128; key++)
  6231.     {
  6232.       switch (map[key].type)
  6233.     {
  6234.     case ISMACR:
  6235.       /* Macros match, if, and only if, the pointers are identical.
  6236.          Thus, they are treated exactly like functions in here. */
  6237.     case ISFUNC:
  6238.       /* If the function in the keymap is the one we are looking for,
  6239.          then add the current KEY to the list of invoking keys. */
  6240.       if (map[key].function == function)
  6241.         {
  6242.           char *keyname = (char *)xmalloc (5);
  6243.  
  6244.           if (CTRL_P (key))
  6245.         sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
  6246.           else if (key == RUBOUT)
  6247.         sprintf (keyname, "\\C-?");
  6248.           else
  6249.         sprintf (keyname, "%c", key);
  6250.           
  6251.           if (result_index + 2 > result_size)
  6252.         {
  6253.           if (!result)
  6254.             result = (char **) xmalloc
  6255.               ((result_size = 10) * sizeof (char *));
  6256.           else
  6257.             result = (char **) xrealloc
  6258.               (result, (result_size += 10) * sizeof (char *));
  6259.         }
  6260.  
  6261.           result[result_index++] = keyname;
  6262.           result[result_index] = (char *)NULL;
  6263.         }
  6264.       break;
  6265.  
  6266.     case ISKMAP:
  6267.       {
  6268.         char **seqs = (char **)NULL;
  6269.  
  6270.         /* Find the list of keyseqs in this map which have FUNCTION as
  6271.            their target.  Add the key sequences found to RESULT. */
  6272.         if (map[key].function)
  6273.           seqs =
  6274.         invoking_keyseqs_in_map (function, (Keymap)map[key].function);
  6275.  
  6276.         if (seqs)
  6277.           {
  6278.         register int i;
  6279.  
  6280.         for (i = 0; seqs[i]; i++)
  6281.           {
  6282.             char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
  6283.  
  6284.             if (key == ESC)
  6285.               sprintf (keyname, "\\e");
  6286.             else if (CTRL_P (key))
  6287.               sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
  6288.             else if (key == RUBOUT)
  6289.               sprintf (keyname, "\\C-?");
  6290.             else
  6291.               sprintf (keyname, "%c", key);
  6292.  
  6293.             strcat (keyname, seqs[i]);
  6294.  
  6295.             if (result_index + 2 > result_size)
  6296.               {
  6297.             if (!result)
  6298.               result = (char **)
  6299.                 xmalloc ((result_size = 10) * sizeof (char *));
  6300.             else
  6301.               result = (char **)
  6302.                 xrealloc (result,
  6303.                       (result_size += 10) * sizeof (char *));
  6304.               }
  6305.  
  6306.             result[result_index++] = keyname;
  6307.             result[result_index] = (char *)NULL;
  6308.           }
  6309.           }
  6310.       }
  6311.       break;
  6312.     }
  6313.     }
  6314.   return (result);
  6315. }
  6316.  
  6317. /* Return a NULL terminated array of strings which represent the key
  6318.    sequences that can be used to invoke FUNCTION using the current keymap. */
  6319. char **
  6320. rl_invoking_keyseqs (function)
  6321.      Function *function;
  6322. {
  6323.   return (invoking_keyseqs_in_map (function, keymap));
  6324. }
  6325.  
  6326. /* Print all of the current functions and their bindings to
  6327.    rl_outstream.  If an explicit argument is given, then print
  6328.    the output in such a way that it can be read back in. */
  6329. int
  6330. rl_dump_functions (count)
  6331.      int count;
  6332. {
  6333.   void rl_function_dumper ();
  6334.  
  6335.   rl_function_dumper (rl_explicit_arg);
  6336.   rl_on_new_line ();
  6337.   return (0);
  6338. }
  6339.  
  6340. /* Print all of the functions and their bindings to rl_outstream.  If
  6341.    PRINT_READABLY is non-zero, then print the output in such a way
  6342.    that it can be read back in. */
  6343. void
  6344. rl_function_dumper (print_readably)
  6345.      int print_readably;
  6346. {
  6347.   register int i;
  6348.   char **rl_funmap_names (), **names;
  6349.   char *name;
  6350.  
  6351.   names = rl_funmap_names ();
  6352.  
  6353.   fprintf (rl_outstream, "\n");
  6354.  
  6355.   for (i = 0; name = names[i]; i++)
  6356.     {
  6357.       Function *function;
  6358.       char **invokers;
  6359.  
  6360.       function = rl_named_function (name);
  6361.       invokers = invoking_keyseqs_in_map (function, keymap);
  6362.  
  6363.       if (print_readably)
  6364.     {
  6365.       if (!invokers)
  6366.         fprintf (rl_outstream, "# %s (not bound)\n", name);
  6367.       else
  6368.         {
  6369.           register int j;
  6370.  
  6371.           for (j = 0; invokers[j]; j++)
  6372.         {
  6373.           fprintf (rl_outstream, "\"%s\": %s\n",
  6374.                invokers[j], name);
  6375.           free (invokers[j]);
  6376.         }
  6377.  
  6378.           free (invokers);
  6379.         }
  6380.     }
  6381.       else
  6382.     {
  6383.       if (!invokers)
  6384.         fprintf (rl_outstream, "%s is not bound to any keys\n",
  6385.              name);
  6386.       else
  6387.         {
  6388.           register int j;
  6389.  
  6390.           fprintf (rl_outstream, "%s can be found on ", name);
  6391.  
  6392.           for (j = 0; invokers[j] && j < 5; j++)
  6393.         {
  6394.           fprintf (rl_outstream, "\"%s\"%s", invokers[j],
  6395.                invokers[j + 1] ? ", " : ".\n");
  6396.         }
  6397.  
  6398.           if (j == 5 && invokers[j])
  6399.         fprintf (rl_outstream, "...\n");
  6400.  
  6401.           for (j = 0; invokers[j]; j++)
  6402.         free (invokers[j]);
  6403.  
  6404.           free (invokers);
  6405.         }
  6406.     }
  6407.     }
  6408. }
  6409.  
  6410.  
  6411. /* **************************************************************** */
  6412. /*                                    */
  6413. /*            String Utility Functions            */
  6414. /*                                    */
  6415. /* **************************************************************** */
  6416.  
  6417. static char *strindex ();
  6418.  
  6419. /* Return pointer to first occurance in STRING1 of any character from STRING2,
  6420.    or NULL if no occurance found. */
  6421. static char *
  6422. strpbrk (string1, string2)
  6423.      char *string1, *string2;
  6424. {
  6425.   register char *scan;
  6426.  
  6427.   for (; *string1 != '\0'; string1++)
  6428.     {
  6429.       for (scan = string2; *scan != '\0'; scan++)
  6430.     {
  6431.       if (*string1 == *scan)
  6432.         {
  6433.           return (string1);
  6434.         }
  6435.     }
  6436.     }
  6437.   return (NULL);
  6438. }
  6439.  
  6440. /* Return non-zero if any members of ARRAY are a substring in STRING. */
  6441. static int
  6442. substring_member_of_array (string, array)
  6443.      char *string, **array;
  6444. {
  6445.   while (*array)
  6446.     {
  6447.       if (strindex (string, *array))
  6448.     return (1);
  6449.       array++;
  6450.     }
  6451.   return (0);
  6452. }
  6453.  
  6454. /* Whoops, Unix doesn't have strnicmp. */
  6455.  
  6456. /* Compare at most COUNT characters from string1 to string2.  Case
  6457.    doesn't matter. */
  6458. static int
  6459. strnicmp (string1, string2, count)
  6460.      char *string1, *string2;
  6461. {
  6462.   register char ch1, ch2;
  6463.  
  6464.   while (count)
  6465.     {
  6466.       ch1 = *string1++;
  6467.       ch2 = *string2++;
  6468.       if (to_upper(ch1) == to_upper(ch2))
  6469.     count--;
  6470.       else break;
  6471.     }
  6472.   return (count);
  6473. }
  6474.  
  6475. /* strcmp (), but caseless. */
  6476. static int
  6477. stricmp (string1, string2)
  6478.      char *string1, *string2;
  6479. {
  6480.   register char ch1, ch2;
  6481.  
  6482.   while (*string1 && *string2)
  6483.     {
  6484.       ch1 = *string1++;
  6485.       ch2 = *string2++;
  6486.       if (to_upper(ch1) != to_upper(ch2))
  6487.     return (1);
  6488.     }
  6489.   return (*string1 | *string2);
  6490. }
  6491.  
  6492. /* Determine if s2 occurs in s1.  If so, return a pointer to the
  6493.    match in s1.  The compare is case insensitive. */
  6494. static char *
  6495. strindex (s1, s2)
  6496.      register char *s1, *s2;
  6497. {
  6498.   register int i, l = strlen (s2);
  6499.   register int len = strlen (s1);
  6500.  
  6501.   for (i = 0; (len - i) >= l; i++)
  6502.     if (strnicmp (&s1[i], s2, l) == 0)
  6503.       return (s1 + i);
  6504.   return ((char *)NULL);
  6505. }
  6506.  
  6507.  
  6508. /* **************************************************************** */
  6509. /*                                    */
  6510. /*            USG (System V) Support                */
  6511. /*                                    */
  6512. /* **************************************************************** */
  6513.  
  6514. /* When compiling and running in the `Posix' environment, Ultrix does
  6515.    not restart system calls, so this needs to do it. */
  6516. int
  6517. rl_getc (stream)
  6518.      FILE *stream;
  6519. {
  6520.   int result;
  6521.   unsigned char c;
  6522.  
  6523. #ifdef __GO32__
  6524.   if (isatty(0))
  6525.     return (getkey() & 0x7f);
  6526. #endif /* __GO32__ */
  6527.  
  6528.   while (1)
  6529.     {
  6530.       result = read (fileno (stream), &c, sizeof (char));
  6531.  
  6532.       if (result == sizeof (char))
  6533.     return (c);
  6534.  
  6535.       /* If zero characters are returned, then the file that we are
  6536.      reading from is empty!  Return EOF in that case. */
  6537.       if (result == 0)
  6538.     return (EOF);
  6539.  
  6540. #ifndef __GO32__
  6541.       /* If the error that we received was SIGINT, then try again,
  6542.      this is simply an interrupted system call to read ().
  6543.      Otherwise, some error ocurred, also signifying EOF. */
  6544.       if (errno != EINTR)
  6545.     return (EOF);
  6546. #endif /* !__GO32__ */
  6547.     }
  6548. }
  6549.  
  6550. #if defined (STATIC_MALLOC)
  6551.  
  6552. /* **************************************************************** */
  6553. /*                                    */
  6554. /*            xmalloc and xrealloc ()                     */
  6555. /*                                    */
  6556. /* **************************************************************** */
  6557.  
  6558. static void memory_error_and_abort ();
  6559.  
  6560. static char *
  6561. xmalloc (bytes)
  6562.      int bytes;
  6563. {
  6564.   char *temp = (char *)malloc (bytes);
  6565.  
  6566.   if (!temp)
  6567.     memory_error_and_abort ();
  6568.   return (temp);
  6569. }
  6570.  
  6571. static char *
  6572. xrealloc (pointer, bytes)
  6573.      char *pointer;
  6574.      int bytes;
  6575. {
  6576.   char *temp;
  6577.  
  6578.   if (!pointer)
  6579.     temp = (char *)malloc (bytes);
  6580.   else
  6581.     temp = (char *)realloc (pointer, bytes);
  6582.  
  6583.   if (!temp)
  6584.     memory_error_and_abort ();
  6585.  
  6586.   return (temp);
  6587. }
  6588.  
  6589. static void
  6590. memory_error_and_abort ()
  6591. {
  6592.   fprintf (stderr, "readline: Out of virtual memory!\n");
  6593.   abort ();
  6594. }
  6595. #endif /* STATIC_MALLOC */
  6596.  
  6597.  
  6598. /* **************************************************************** */
  6599. /*                                    */
  6600. /*            Testing Readline                */
  6601. /*                                    */
  6602. /* **************************************************************** */
  6603.  
  6604. #if defined (TEST)
  6605.  
  6606. main ()
  6607. {
  6608.   HIST_ENTRY **history_list ();
  6609.   char *temp = (char *)NULL;
  6610.   char *prompt = "readline% ";
  6611.   int done = 0;
  6612.  
  6613.   while (!done)
  6614.     {
  6615.       temp = readline (prompt);
  6616.  
  6617.       /* Test for EOF. */
  6618.       if (!temp)
  6619.     exit (1);
  6620.  
  6621.       /* If there is anything on the line, print it and remember it. */
  6622.       if (*temp)
  6623.     {
  6624.       fprintf (stderr, "%s\r\n", temp);
  6625.       add_history (temp);
  6626.     }
  6627.  
  6628.       /* Check for `command' that we handle. */
  6629.       if (strcmp (temp, "quit") == 0)
  6630.     done = 1;
  6631.  
  6632.       if (strcmp (temp, "list") == 0)
  6633.     {
  6634.       HIST_ENTRY **list = history_list ();
  6635.       register int i;
  6636.       if (list)
  6637.         {
  6638.           for (i = 0; list[i]; i++)
  6639.         {
  6640.           fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
  6641.           free (list[i]->line);
  6642.         }
  6643.           free (list);
  6644.         }
  6645.     }
  6646.       free (temp);
  6647.     }
  6648. }
  6649.  
  6650. #endif /* TEST */
  6651.  
  6652.  
  6653. /*
  6654.  * Local variables:
  6655.  * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap"
  6656.  * end:
  6657.  */
  6658.