[BACK]Return to readline.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libedit

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libedit/readline.c between version 1.88 and 1.146.2.1

version 1.88, 2010/01/03 18:27:10 version 1.146.2.1, 2018/06/25 07:25:35
Line 36  __RCSID("$NetBSD$");
Line 36  __RCSID("$NetBSD$");
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <stdio.h>  
 #include <dirent.h>  
 #include <string.h>  
 #include <pwd.h>  
 #include <ctype.h>  #include <ctype.h>
 #include <stdlib.h>  #include <dirent.h>
 #include <unistd.h>  
 #include <limits.h>  
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
   #include <limits.h>
   #include <pwd.h>
 #include <setjmp.h>  #include <setjmp.h>
 #ifdef HAVE_VIS_H  #include <stdint.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
 #include <vis.h>  #include <vis.h>
 #else  
 #include "np/vis.h"  
 #endif  
 #include "readline/readline.h"  #include "readline/readline.h"
 #include "el.h"  #include "el.h"
 #include "fcns.h"               /* for EL_NUM_FCNS */  #include "fcns.h"
 #include "histedit.h"  
 #include "filecomplete.h"  #include "filecomplete.h"
   
 void rl_prep_terminal(int);  void rl_prep_terminal(int);
Line 81  FILE *rl_outstream = NULL;
Line 78  FILE *rl_outstream = NULL;
 int rl_point = 0;  int rl_point = 0;
 int rl_end = 0;  int rl_end = 0;
 char *rl_line_buffer = NULL;  char *rl_line_buffer = NULL;
 VCPFunction *rl_linefunc = NULL;  rl_vcpfunc_t *rl_linefunc = NULL;
 int rl_done = 0;  int rl_done = 0;
 VFunction *rl_event_hook = NULL;  rl_hook_func_t *rl_event_hook = NULL;
 KEYMAP_ENTRY_ARRAY emacs_standard_keymap,  KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
     emacs_meta_keymap,      emacs_meta_keymap,
     emacs_ctlx_keymap;      emacs_ctlx_keymap;
   /*
    * The following is not implemented; we always catch signals in the
    * libedit fashion: set handlers on entry to el_gets() and clear them
    * on the way out. This simplistic approach works for most cases; if
    * it does not work for your application, please let us know.
    */
   int rl_catch_signals = 1;
   int rl_catch_sigwinch = 1;
   
 int history_base = 1;           /* probably never subject to change */  int history_base = 1;           /* probably never subject to change */
 int history_length = 0;  int history_length = 0;
   int history_offset = 0;
 int max_input_history = 0;  int max_input_history = 0;
 char history_expansion_char = '!';  char history_expansion_char = '!';
 char history_subst_char = '^';  char history_subst_char = '^';
Line 102  int rl_attempted_completion_over = 0;
Line 108  int rl_attempted_completion_over = 0;
 char *rl_basic_word_break_characters = break_chars;  char *rl_basic_word_break_characters = break_chars;
 char *rl_completer_word_break_characters = NULL;  char *rl_completer_word_break_characters = NULL;
 char *rl_completer_quote_characters = NULL;  char *rl_completer_quote_characters = NULL;
 Function *rl_completion_entry_function = NULL;  rl_compentry_func_t *rl_completion_entry_function = NULL;
 CPPFunction *rl_attempted_completion_function = NULL;  char *(*rl_completion_word_break_hook)(void) = NULL;
   rl_completion_func_t *rl_attempted_completion_function = NULL;
 Function *rl_pre_input_hook = NULL;  Function *rl_pre_input_hook = NULL;
 Function *rl_startup1_hook = NULL;  Function *rl_startup1_hook = NULL;
 int (*rl_getc_function)(FILE *) = NULL;  int (*rl_getc_function)(FILE *) = NULL;
Line 111  char *rl_terminal_name = NULL;
Line 118  char *rl_terminal_name = NULL;
 int rl_already_prompted = 0;  int rl_already_prompted = 0;
 int rl_filename_completion_desired = 0;  int rl_filename_completion_desired = 0;
 int rl_ignore_completion_duplicates = 0;  int rl_ignore_completion_duplicates = 0;
 int rl_catch_signals = 1;  
 int readline_echoing_p = 1;  int readline_echoing_p = 1;
 int _rl_print_completions_horizontally = 0;  int _rl_print_completions_horizontally = 0;
 VFunction *rl_redisplay_function = NULL;  VFunction *rl_redisplay_function = NULL;
 Function *rl_startup_hook = NULL;  Function *rl_startup_hook = NULL;
   int rl_did_startup_hook = 0;
 VFunction *rl_completion_display_matches_hook = NULL;  VFunction *rl_completion_display_matches_hook = NULL;
 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;  VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;  VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
 KEYMAP_ENTRY_ARRAY emacs_meta_keymap;  KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
   
 #ifdef WIDECHAR  
 static ct_buffer_t conv;  
 #endif  
   
 /*  /*
  * The current prompt string.   * The current prompt string.
  */   */
Line 157  int rl_completion_append_character = ' '
Line 160  int rl_completion_append_character = ' '
   
 /* stuff below is used internally by libedit for readline emulation */  /* stuff below is used internally by libedit for readline emulation */
   
 static TYPE(History) *h = NULL;  static History *h = NULL;
 static EditLine *e = NULL;  static EditLine *e = NULL;
 static Function *map[256];  static rl_command_func_t *map[256];
 static jmp_buf topbuf;  static jmp_buf topbuf;
   
 /* internal functions */  /* internal functions */
 static unsigned char     _el_rl_complete(EditLine *, int);  static unsigned char     _el_rl_complete(EditLine *, int);
 static unsigned char     _el_rl_tstp(EditLine *, int);  static unsigned char     _el_rl_tstp(EditLine *, int);
 static char             *_get_prompt(EditLine *);  static char             *_get_prompt(EditLine *);
 static int               _getc_function(EditLine *, char *);  static int               _getc_function(EditLine *, wchar_t *);
 static HIST_ENTRY       *_move_history(int);  
 static int               _history_expand_command(const char *, size_t, size_t,  static int               _history_expand_command(const char *, size_t, size_t,
     char **);      char **);
 static char             *_rl_compat_sub(const char *, const char *,  static char             *_rl_compat_sub(const char *, const char *,
     const char *, int);      const char *, int);
 static int               _rl_event_read_char(EditLine *, char *);  static int               _rl_event_read_char(EditLine *, wchar_t *);
 static void              _rl_update_pos(void);  static void              _rl_update_pos(void);
   
   static HIST_ENTRY rl_he;
   
 /* ARGSUSED */  /* ARGSUSED */
 static char *  static char *
 _get_prompt(EditLine *el __attribute__((__unused__)))  _get_prompt(EditLine *el __attribute__((__unused__)))
 {  {
         rl_already_prompted = 1;          rl_already_prompted = 1;
         return (rl_prompt);          return rl_prompt;
 }  
   
   
 /*  
  * generic function for moving around history  
  */  
 static HIST_ENTRY *  
 _move_history(int op)  
 {  
         TYPE(HistEvent) ev;  
         static HIST_ENTRY rl_he;  
   
         if (FUNW(history)(h, &ev, op) != 0)  
                 return (HIST_ENTRY *) NULL;  
   
         rl_he.line = ct_encode_string(ev.str, &conv);  
         rl_he.data = NULL;  
   
         return (&rl_he);  
 }  }
   
   
Line 209  _move_history(int op)
Line 193  _move_history(int op)
  */   */
 static int  static int
 /*ARGSUSED*/  /*ARGSUSED*/
 _getc_function(EditLine *el, char *c)  _getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c)
 {  {
         int i;          int i;
   
         i = (*rl_getc_function)(NULL);          i = (*rl_getc_function)(rl_instream);
         if (i == -1)          if (i == -1)
                 return 0;                  return 0;
         *c = i;          *c = (wchar_t)i;
         return 1;          return 1;
 }  }
   
 static const char _dothistory[] = "/.history";  static void
   _resize_fun(EditLine *el, void *a)
   {
           const LineInfo *li;
           char **ap = a;
   
           li = el_line(el);
           /* a cheesy way to get rid of const cast. */
           *ap = memchr(li->buffer, *li->buffer, (size_t)1);
   }
   
 static const char *  static const char *
 _default_history_file(void)  _default_history_file(void)
 {  {
         struct passwd *p;          struct passwd *p;
         static char path[PATH_MAX];          static char *path;
           size_t len;
   
         if (*path)          if (path)
                 return path;                  return path;
   
         if ((p = getpwuid(getuid())) == NULL)          if ((p = getpwuid(getuid())) == NULL)
                 return NULL;                  return NULL;
         strlcpy(path, p->pw_dir, PATH_MAX);  
         strlcat(path, _dothistory, PATH_MAX);          len = strlen(p->pw_dir) + sizeof("/.history");
           if ((path = malloc(len)) == NULL)
                   return NULL;
   
           (void)snprintf(path, len, "%s/.history", p->pw_dir);
         return path;          return path;
 }  }
   
Line 251  rl_set_prompt(const char *prompt)
Line 250  rl_set_prompt(const char *prompt)
   
         if (!prompt)          if (!prompt)
                 prompt = "";                  prompt = "";
         if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)          if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
                 return 0;                  return 0;
         if (rl_prompt)          if (rl_prompt)
                 free(rl_prompt);                  el_free(rl_prompt);
         rl_prompt = strdup(prompt);          rl_prompt = strdup(prompt);
         if (rl_prompt == NULL)          if (rl_prompt == NULL)
                 return -1;                  return -1;
Line 271  rl_set_prompt(const char *prompt)
Line 270  rl_set_prompt(const char *prompt)
 int  int
 rl_initialize(void)  rl_initialize(void)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
         const LineInfo *li;  
         int editmode = 1;          int editmode = 1;
         struct termios t;          struct termios t;
   
         if (e != NULL)          if (e != NULL)
                 el_end(e);                  el_end(e);
         if (h != NULL)          if (h != NULL)
                 FUN(history,end)(h);                  history_end(h);
   
         if (!rl_instream)          if (!rl_instream)
                 rl_instream = stdin;                  rl_instream = stdin;
Line 292  rl_initialize(void)
Line 290  rl_initialize(void)
         if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)          if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
                 editmode = 0;                  editmode = 0;
   
         e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);          e = el_init_internal(rl_readline_name, rl_instream, rl_outstream,
               stderr, fileno(rl_instream), fileno(rl_outstream), fileno(stderr),
               NO_RESET);
   
         if (!editmode)          if (!editmode)
                 FUN(el,set)(e, EL_EDITMODE, 0);                  el_set(e, EL_EDITMODE, 0);
   
         h = FUN(history,init)();          h = history_init();
         if (!e || !h)          if (!e || !h)
                 return (-1);                  return -1;
   
         FUNW(history)(h, &ev, H_SETSIZE, INT_MAX);      /* unlimited */          history(h, &ev, H_SETSIZE, INT_MAX);    /* unlimited */
         history_length = 0;          history_length = 0;
         max_input_history = INT_MAX;          max_input_history = INT_MAX;
         el_set(e, EL_HIST, history, h);          el_set(e, EL_HIST, history, h);
   
           /* Setup resize function */
           el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
   
         /* setup getc function if valid */          /* setup getc function if valid */
         if (rl_getc_function)          if (rl_getc_function)
                 el_set(e, EL_GETCFN, _getc_function);                  el_set(e, EL_GETCFN, _getc_function);
   
         /* for proper prompt printing in readline() */          /* for proper prompt printing in readline() */
         if (rl_set_prompt("") == -1) {          if (rl_set_prompt("") == -1) {
                 FUN(history,end)(h);                  history_end(h);
                 el_end(e);                  el_end(e);
                 return -1;                  return -1;
         }          }
Line 320  rl_initialize(void)
Line 323  rl_initialize(void)
         el_set(e, EL_SIGNAL, rl_catch_signals);          el_set(e, EL_SIGNAL, rl_catch_signals);
   
         /* set default mode to "emacs"-style and read setting afterwards */          /* set default mode to "emacs"-style and read setting afterwards */
         /* so this can be overriden */          /* so this can be overridden */
         el_set(e, EL_EDITOR, "emacs");          el_set(e, EL_EDITOR, "emacs");
         if (rl_terminal_name != NULL)          if (rl_terminal_name != NULL)
                 el_set(e, EL_TERMINAL, rl_terminal_name);                  el_set(e, EL_TERMINAL, rl_terminal_name);
Line 343  rl_initialize(void)
Line 346  rl_initialize(void)
             "ReadLine compatible suspend function",              "ReadLine compatible suspend function",
             _el_rl_tstp);              _el_rl_tstp);
         el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);          el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
   
           /*
            * Set some readline compatible key-bindings.
            */
           el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL);
   
           /*
            * Allow the use of Home/End keys.
            */
           el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
           el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
           el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL);
           el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL);
           el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL);
           el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL);
   
           /*
            * Allow the use of the Delete/Insert keys.
            */
           el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
           el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL);
   
           /*
            * Ctrl-left-arrow and Ctrl-right-arrow for word moving.
            */
           el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
           el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
           el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL);
           el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL);
           el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
           el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
   
         /* read settings from configuration file */          /* read settings from configuration file */
         el_source(e, NULL);          el_source(e, NULL);
   
Line 351  rl_initialize(void)
Line 385  rl_initialize(void)
          * Unfortunately, some applications really do use rl_point           * Unfortunately, some applications really do use rl_point
          * and rl_line_buffer directly.           * and rl_line_buffer directly.
          */           */
         li = el_line(e);          _resize_fun(e, &rl_line_buffer);
         /* a cheesy way to get rid of const cast. */  
         rl_line_buffer = memchr(li->buffer, *li->buffer, 1);  
         _rl_update_pos();          _rl_update_pos();
   
         if (rl_startup_hook)          tty_end(e, TCSADRAIN);
                 (*rl_startup_hook)(NULL, 0);  
   
         return (0);          return 0;
 }  }
   
   
Line 370  rl_initialize(void)
Line 401  rl_initialize(void)
 char *  char *
 readline(const char *p)  readline(const char *p)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
         const char * volatile prompt = p;          const char * volatile prompt = p;
         int count;          int count;
         const char *ret;          const char *ret;
Line 379  readline(const char *p)
Line 410  readline(const char *p)
   
         if (e == NULL || h == NULL)          if (e == NULL || h == NULL)
                 rl_initialize();                  rl_initialize();
           if (rl_did_startup_hook == 0 && rl_startup_hook) {
                   rl_did_startup_hook = 1;
                   (*rl_startup_hook)(NULL, 0);
           }
           tty_init(e);
   
   
         rl_done = 0;          rl_done = 0;
   
         (void)setjmp(topbuf);          (void)setjmp(topbuf);
           buf = NULL;
   
         /* update prompt accordingly to what has been passed */          /* update prompt accordingly to what has been passed */
         if (rl_set_prompt(prompt) == -1)          if (rl_set_prompt(prompt) == -1)
                 return NULL;                  goto out;
   
         if (rl_pre_input_hook)          if (rl_pre_input_hook)
                 (*rl_pre_input_hook)(NULL, 0);                  (*rl_pre_input_hook)(NULL, 0);
   
         if (rl_event_hook && !(e->el_flags&NO_TTY)) {          if (rl_event_hook && !(e->el_flags & NO_TTY)) {
                 el_set(e, EL_GETCFN, _rl_event_read_char);                  el_set(e, EL_GETCFN, _rl_event_read_char);
                 used_event_hook = 1;                  used_event_hook = 1;
         }          }
Line 411  readline(const char *p)
Line 449  readline(const char *p)
   
                 buf = strdup(ret);                  buf = strdup(ret);
                 if (buf == NULL)                  if (buf == NULL)
                         return NULL;                          goto out;
                 lastidx = count - 1;                  lastidx = count - 1;
                 if (buf[lastidx] == '\n')                  if (buf[lastidx] == '\n')
                         buf[lastidx] = '\0';                          buf[lastidx] = '\0';
         } else          } else
                 buf = NULL;                  buf = NULL;
   
         FUNW(history)(h, &ev, H_GETSIZE);          history(h, &ev, H_GETSIZE);
         history_length = ev.num;          history_length = ev.num;
   
   out:
           tty_end(e, TCSADRAIN);
         return buf;          return buf;
 }  }
   
Line 437  using_history(void)
Line 477  using_history(void)
 {  {
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
           history_offset = history_length;
 }  }
   
   
Line 468  _rl_compat_sub(const char *str, const ch
Line 509  _rl_compat_sub(const char *str, const ch
                 } else                  } else
                         s++;                          s++;
         }          }
         r = result = malloc(len + 1);          r = result = el_malloc((len + 1) * sizeof(*r));
         if (result == NULL)          if (result == NULL)
                 return NULL;                  return NULL;
         s = str;          s = str;
Line 479  _rl_compat_sub(const char *str, const ch
Line 520  _rl_compat_sub(const char *str, const ch
                         s += what_len;                          s += what_len;
                         if (!globally) {                          if (!globally) {
                                 (void)strcpy(r, s);                                  (void)strcpy(r, s);
                                 return(result);                                  return result;
                         }                          }
                 } else                  } else
                         *r++ = *s++;                          *r++ = *s++;
         }          }
         *r = '\0';          *r = '\0';
         return(result);          return result;
 }  }
   
 static  char    *last_search_pat;       /* last !?pat[?] search pattern */  static  char    *last_search_pat;       /* last !?pat[?] search pattern */
Line 498  get_history_event(const char *cmd, int *
Line 539  get_history_event(const char *cmd, int *
         size_t len;          size_t len;
         char    *pat;          char    *pat;
         const char *rptr;          const char *rptr;
         TYPE(HistEvent) ev;          HistEvent ev;
   
         idx = *cindex;          idx = *cindex;
         if (cmd[idx++] != history_expansion_char)          if (cmd[idx++] != history_expansion_char)
                 return(NULL);                  return NULL;
   
         /* find out which event to take */          /* find out which event to take */
         if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {          if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
                 if (FUNW(history)(h, &ev, H_FIRST) != 0)                  if (history(h, &ev, H_FIRST) != 0)
                         return(NULL);                          return NULL;
                 *cindex = cmd[idx]? (idx + 1):idx;                  *cindex = cmd[idx]? (idx + 1):idx;
                 return ct_encode_string(ev.str, &conv);                  return ev.str;
         }          }
         sign = 0;          sign = 0;
         if (cmd[idx] == '-') {          if (cmd[idx] == '-') {
Line 518  get_history_event(const char *cmd, int *
Line 559  get_history_event(const char *cmd, int *
         }          }
   
         if ('0' <= cmd[idx] && cmd[idx] <= '9') {          if ('0' <= cmd[idx] && cmd[idx] <= '9') {
                 HIST_ENTRY *rl_he;                  HIST_ENTRY *he;
   
                 num = 0;                  num = 0;
                 while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {                  while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
Line 526  get_history_event(const char *cmd, int *
Line 567  get_history_event(const char *cmd, int *
                         idx++;                          idx++;
                 }                  }
                 if (sign)                  if (sign)
                         num = history_length - num + 1;                          num = history_length - num + history_base;
   
                 if (!(rl_he = history_get(num)))                  if (!(he = history_get(num)))
                         return(NULL);                          return NULL;
   
                 *cindex = idx;                  *cindex = idx;
                 return(rl_he->line);                  return he->line;
         }          }
         sub = 0;          sub = 0;
         if (cmd[idx] == '?') {          if (cmd[idx] == '?') {
Line 550  get_history_event(const char *cmd, int *
Line 591  get_history_event(const char *cmd, int *
                         break;                          break;
                 idx++;                  idx++;
         }          }
         len = idx - begin;          len = (size_t)idx - (size_t)begin;
         if (sub && cmd[idx] == '?')          if (sub && cmd[idx] == '?')
                 idx++;                  idx++;
         if (sub && len == 0 && last_search_pat && *last_search_pat)          if (sub && len == 0 && last_search_pat && *last_search_pat)
                 pat = last_search_pat;                  pat = last_search_pat;
         else if (len == 0)          else if (len == 0)
                 return(NULL);                  return NULL;
         else {          else {
                 if ((pat = malloc(len + 1)) == NULL)                  if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL)
                         return NULL;                          return NULL;
                 (void)strncpy(pat, cmd + begin, len);                  (void)strncpy(pat, cmd + begin, len);
                 pat[len] = '\0';                  pat[len] = '\0';
         }          }
   
         if (FUNW(history)(h, &ev, H_CURR) != 0) {          if (history(h, &ev, H_CURR) != 0) {
                 if (pat != last_search_pat)                  if (pat != last_search_pat)
                         free(pat);                          el_free(pat);
                 return (NULL);                  return NULL;
         }          }
         num = ev.num;          num = ev.num;
   
         if (sub) {          if (sub) {
                 if (pat != last_search_pat) {                  if (pat != last_search_pat) {
                         if (last_search_pat)                          if (last_search_pat)
                                 free(last_search_pat);                                  el_free(last_search_pat);
                         last_search_pat = pat;                          last_search_pat = pat;
                 }                  }
                 ret = history_search(pat, -1);                  ret = history_search(pat, -1);
Line 583  get_history_event(const char *cmd, int *
Line 624  get_history_event(const char *cmd, int *
   
         if (ret == -1) {          if (ret == -1) {
                 /* restore to end of list on failed search */                  /* restore to end of list on failed search */
                 FUNW(history)(h, &ev, H_FIRST);                  history(h, &ev, H_FIRST);
                 (void)fprintf(rl_outstream, "%s: Event not found\n", pat);                  (void)fprintf(rl_outstream, "%s: Event not found\n", pat);
                 if (pat != last_search_pat)                  if (pat != last_search_pat)
                         free(pat);                          el_free(pat);
                 return(NULL);                  return NULL;
         }          }
   
         if (sub && len) {          if (sub && len) {
                 if (last_search_match && last_search_match != pat)                  if (last_search_match && last_search_match != pat)
                         free(last_search_match);                          el_free(last_search_match);
                 last_search_match = pat;                  last_search_match = pat;
         }          }
   
         if (pat != last_search_pat)          if (pat != last_search_pat)
                 free(pat);                  el_free(pat);
   
         if (FUNW(history)(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_CURR) != 0)
                 return(NULL);                  return NULL;
         *cindex = idx;          *cindex = idx;
         rptr = ct_encode_string(ev.str, &conv);          rptr = ev.str;
   
         /* roll back to original position */          /* roll back to original position */
         (void)FUNW(history)(h, &ev, H_SET, num);          (void)history(h, &ev, H_SET, num);
   
         return rptr;          return rptr;
 }  }
Line 618  get_history_event(const char *cmd, int *
Line 659  get_history_event(const char *cmd, int *
  * returns 0 if data was not modified, 1 if it was and 2 if the string   * returns 0 if data was not modified, 1 if it was and 2 if the string
  * should be only printed and not executed; in case of error,   * should be only printed and not executed; in case of error,
  * returns -1 and *result points to NULL   * returns -1 and *result points to NULL
  * it's callers responsibility to free() string returned in *result   * it's the caller's responsibility to free() the string returned in *result
  */   */
 static int  static int
 _history_expand_command(const char *command, size_t offs, size_t cmdlen,  _history_expand_command(const char *command, size_t offs, size_t cmdlen,
Line 652  _history_expand_command(const char *comm
Line 693  _history_expand_command(const char *comm
         } else {          } else {
                 if (command[offs + 1] == '#') {                  if (command[offs + 1] == '#') {
                         /* use command so far */                          /* use command so far */
                         if ((aptr = malloc(offs + 1)) == NULL)                          if ((aptr = el_malloc((offs + 1) * sizeof(*aptr)))
                               == NULL)
                                 return -1;                                  return -1;
                         (void)strncpy(aptr, command, offs);                          (void)strncpy(aptr, command, offs);
                         aptr[offs] = '\0';                          aptr[offs] = '\0';
Line 663  _history_expand_command(const char *comm
Line 705  _history_expand_command(const char *comm
                         qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;                          qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
                         ptr = get_history_event(command + offs, &idx, qchar);                          ptr = get_history_event(command + offs, &idx, qchar);
                 }                  }
                 has_mods = command[offs + idx] == ':';                  has_mods = command[offs + (size_t)idx] == ':';
         }          }
   
         if (ptr == NULL && aptr == NULL)          if (ptr == NULL && aptr == NULL)
                 return(-1);                  return -1;
   
         if (!has_mods) {          if (!has_mods) {
                 *result = strdup(aptr ? aptr : ptr);                  *result = strdup(aptr ? aptr : ptr);
                 if (aptr)                  if (aptr)
                         free(aptr);                          el_free(aptr);
                 if (*result == NULL)                  if (*result == NULL)
                         return -1;                          return -1;
                 return(1);                  return 1;
         }          }
   
         cmd = command + offs + idx + 1;          cmd = command + offs + idx + 1;
Line 720  _history_expand_command(const char *comm
Line 762  _history_expand_command(const char *comm
                         (void)fprintf(rl_outstream, "%s: Bad word specifier",                          (void)fprintf(rl_outstream, "%s: Bad word specifier",
                             command + offs + idx);                              command + offs + idx);
                         if (aptr)                          if (aptr)
                                 free(aptr);                                  el_free(aptr);
                         return(-1);                          return -1;
                 }                  }
         } else          } else
                 tmp = strdup(aptr? aptr:ptr);                  tmp = strdup(aptr? aptr:ptr);
   
         if (aptr)          if (aptr)
                 free(aptr);                  el_free(aptr);
   
         if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {          if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
                 *result = tmp;                  *result = tmp;
                 return(1);                  return 1;
         }          }
   
         for (; *cmd; cmd++) {          for (; *cmd; cmd++) {
Line 743  _history_expand_command(const char *comm
Line 785  _history_expand_command(const char *comm
                 } else if (*cmd == 't') {       /* remove leading path */                  } else if (*cmd == 't') {       /* remove leading path */
                         if ((aptr = strrchr(tmp, '/')) != NULL) {                          if ((aptr = strrchr(tmp, '/')) != NULL) {
                                 aptr = strdup(aptr + 1);                                  aptr = strdup(aptr + 1);
                                 free(tmp);                                  el_free(tmp);
                                 tmp = aptr;                                  tmp = aptr;
                         }                          }
                 } else if (*cmd == 'r') {       /* remove trailing suffix */                  } else if (*cmd == 'r') {       /* remove trailing suffix */
Line 752  _history_expand_command(const char *comm
Line 794  _history_expand_command(const char *comm
                 } else if (*cmd == 'e') {       /* remove all but suffix */                  } else if (*cmd == 'e') {       /* remove all but suffix */
                         if ((aptr = strrchr(tmp, '.')) != NULL) {                          if ((aptr = strrchr(tmp, '.')) != NULL) {
                                 aptr = strdup(aptr);                                  aptr = strdup(aptr);
                                 free(tmp);                                  el_free(tmp);
                                 tmp = aptr;                                  tmp = aptr;
                         }                          }
                 } else if (*cmd == 'p')         /* print only */                  } else if (*cmd == 'p')         /* print only */
Line 769  _history_expand_command(const char *comm
Line 811  _history_expand_command(const char *comm
                         else if (*cmd == 's') {                          else if (*cmd == 's') {
                                 delim = *(++cmd), cmd++;                                  delim = *(++cmd), cmd++;
                                 size = 16;                                  size = 16;
                                 what = realloc(from, size);                                  what = el_realloc(from, size * sizeof(*what));
                                 if (what == NULL) {                                  if (what == NULL) {
                                         free(from);                                          el_free(from);
                                         free(tmp);                                          el_free(tmp);
                                         return 0;                                          return 0;
                                 }                                  }
                                 len = 0;                                  len = 0;
Line 781  _history_expand_command(const char *comm
Line 823  _history_expand_command(const char *comm
                                                 cmd++;                                                  cmd++;
                                         if (len >= size) {                                          if (len >= size) {
                                                 char *nwhat;                                                  char *nwhat;
                                                 nwhat = realloc(what,                                                  nwhat = el_realloc(what,
                                                                 (size <<= 1));                                                      (size <<= 1) *
                                                       sizeof(*nwhat));
                                                 if (nwhat == NULL) {                                                  if (nwhat == NULL) {
                                                         free(what);                                                          el_free(what);
                                                         free(tmp);                                                          el_free(tmp);
                                                         return 0;                                                          return 0;
                                                 }                                                  }
                                                 what = nwhat;                                                  what = nwhat;
Line 795  _history_expand_command(const char *comm
Line 838  _history_expand_command(const char *comm
                                 what[len] = '\0';                                  what[len] = '\0';
                                 from = what;                                  from = what;
                                 if (*what == '\0') {                                  if (*what == '\0') {
                                         free(what);                                          el_free(what);
                                         if (search) {                                          if (search) {
                                                 from = strdup(search);                                                  from = strdup(search);
                                                 if (from == NULL) {                                                  if (from == NULL) {
                                                         free(tmp);                                                          el_free(tmp);
                                                         return 0;                                                          return 0;
                                                 }                                                  }
                                         } else {                                          } else {
                                                 from = NULL;                                                  from = NULL;
                                                 free(tmp);                                                  el_free(tmp);
                                                 return (-1);                                                  return -1;
                                         }                                          }
                                 }                                  }
                                 cmd++;  /* shift after delim */                                  cmd++;  /* shift after delim */
Line 813  _history_expand_command(const char *comm
Line 856  _history_expand_command(const char *comm
                                         continue;                                          continue;
   
                                 size = 16;                                  size = 16;
                                 with = realloc(to, size);                                  with = el_realloc(to, size * sizeof(*with));
                                 if (with == NULL) {                                  if (with == NULL) {
                                         free(to);                                          el_free(to);
                                         free(tmp);                                          el_free(tmp);
                                         return -1;                                          return -1;
                                 }                                  }
                                 len = 0;                                  len = 0;
Line 825  _history_expand_command(const char *comm
Line 868  _history_expand_command(const char *comm
                                         if (len + from_len + 1 >= size) {                                          if (len + from_len + 1 >= size) {
                                                 char *nwith;                                                  char *nwith;
                                                 size += from_len + 1;                                                  size += from_len + 1;
                                                 nwith = realloc(with, size);                                                  nwith = el_realloc(with,
                                                       size * sizeof(*nwith));
                                                 if (nwith == NULL) {                                                  if (nwith == NULL) {
                                                         free(with);                                                          el_free(with);
                                                         free(tmp);                                                          el_free(tmp);
                                                         return -1;                                                          return -1;
                                                 }                                                  }
                                                 with = nwith;                                                  with = nwith;
Line 851  _history_expand_command(const char *comm
Line 895  _history_expand_command(const char *comm
   
                         aptr = _rl_compat_sub(tmp, from, to, g_on);                          aptr = _rl_compat_sub(tmp, from, to, g_on);
                         if (aptr) {                          if (aptr) {
                                 free(tmp);                                  el_free(tmp);
                                 tmp = aptr;                                  tmp = aptr;
                         }                          }
                         g_on = 0;                          g_on = 0;
                 }                  }
         }          }
         *result = tmp;          *result = tmp;
         return (p_on? 2:1);          return p_on? 2:1;
 }  }
   
   
Line 877  history_expand(char *str, char **output)
Line 921  history_expand(char *str, char **output)
   
         if (history_expansion_char == 0) {          if (history_expansion_char == 0) {
                 *output = strdup(str);                  *output = strdup(str);
                 return(0);                  return 0;
         }          }
   
         *output = NULL;          *output = NULL;
         if (str[0] == history_subst_char) {          if (str[0] == history_subst_char) {
                 /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */                  /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
                 *output = malloc(strlen(str) + 4 + 1);                  *output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output));
                 if (*output == NULL)                  if (*output == NULL)
                         return 0;                          return 0;
                 (*output)[0] = (*output)[1] = history_expansion_char;                  (*output)[0] = (*output)[1] = history_expansion_char;
Line 900  history_expand(char *str, char **output)
Line 944  history_expand(char *str, char **output)
 #define ADD_STRING(what, len, fr)                                       \  #define ADD_STRING(what, len, fr)                                       \
         {                                                               \          {                                                               \
                 if (idx + len + 1 > size) {                             \                  if (idx + len + 1 > size) {                             \
                         char *nresult = realloc(result, (size += len + 1));\                          char *nresult = el_realloc(result,              \
                               (size += len + 1) * sizeof(*nresult));      \
                         if (nresult == NULL) {                          \                          if (nresult == NULL) {                          \
                                 free(*output);                          \                                  el_free(*output);                       \
                                 if (/*CONSTCOND*/fr)                    \                                  if (/*CONSTCOND*/fr)                    \
                                         free(tmp);                      \                                          el_free(tmp);                   \
                                 return 0;                               \                                  return 0;                               \
                         }                                               \                          }                                               \
                         result = nresult;                               \                          result = nresult;                               \
Line 928  loop:
Line 973  loop:
                 for (; str[j]; j++) {                  for (; str[j]; j++) {
                         if (str[j] == '\\' &&                          if (str[j] == '\\' &&
                             str[j + 1] == history_expansion_char) {                              str[j + 1] == history_expansion_char) {
                                 (void)strcpy(&str[j], &str[j + 1]);                                  len = strlen(&str[j + 1]) + 1;
                                   memmove(&str[j], &str[j + 1], len);
                                 continue;                                  continue;
                         }                          }
                         if (!loop_again) {                          if (!loop_again) {
Line 971  loop:
Line 1017  loop:
                         ADD_STRING(tmp, len, 1);                          ADD_STRING(tmp, len, 1);
                 }                  }
                 if (tmp) {                  if (tmp) {
                         free(tmp);                          el_free(tmp);
                         tmp = NULL;                          tmp = NULL;
                 }                  }
                 i = j;                  i = j;
Line 988  loop:
Line 1034  loop:
                 ret = -1;                  ret = -1;
 #endif  #endif
         }          }
         free(*output);          el_free(*output);
         *output = result;          *output = result;
   
         return (ret);          return ret;
 }  }
   
 /*  /*
Line 1026  history_arg_extract(int start, int end, 
Line 1072  history_arg_extract(int start, int end, 
             (size_t)end > max || start > end)              (size_t)end > max || start > end)
                 goto out;                  goto out;
   
         for (i = start, len = 0; i <= (size_t)end; i++)          for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
                 len += strlen(arr[i]) + 1;                  len += strlen(arr[i]) + 1;
         len++;          len++;
         result = malloc(len);          result = el_malloc(len * sizeof(*result));
         if (result == NULL)          if (result == NULL)
                 goto out;                  goto out;
   
         for (i = start, len = 0; i <= (size_t)end; i++) {          for (i = (size_t)start, len = 0; i <= (size_t)end; i++) {
                 (void)strcpy(result + len, arr[i]);                  (void)strcpy(result + len, arr[i]);
                 len += strlen(arr[i]);                  len += strlen(arr[i]);
                 if (i < (size_t)end)                  if (i < (size_t)end)
Line 1043  history_arg_extract(int start, int end, 
Line 1089  history_arg_extract(int start, int end, 
   
 out:  out:
         for (i = 0; arr[i]; i++)          for (i = 0; arr[i]; i++)
                 free(arr[i]);                  el_free(arr[i]);
         free(arr);          el_free(arr);
   
         return result;          return result;
 }  }
Line 1083  history_tokenize(const char *str)
Line 1129  history_tokenize(const char *str)
                 if (idx + 2 >= size) {                  if (idx + 2 >= size) {
                         char **nresult;                          char **nresult;
                         size <<= 1;                          size <<= 1;
                         nresult = realloc(result, size * sizeof(char *));                          nresult = el_realloc(result, (size_t)size * sizeof(*nresult));
                         if (nresult == NULL) {                          if (nresult == NULL) {
                                 free(result);                                  el_free(result);
                                 return NULL;                                  return NULL;
                         }                          }
                         result = nresult;                          result = nresult;
                 }                  }
                 len = i - start;                  len = (size_t)i - (size_t)start;
                 temp = malloc(len + 1);                  temp = el_malloc((size_t)(len + 1) * sizeof(*temp));
                 if (temp == NULL) {                  if (temp == NULL) {
                         for (i = 0; i < idx; i++)                          for (i = 0; i < idx; i++)
                                 free(result[i]);                                  el_free(result[i]);
                         free(result);                          el_free(result);
                         return NULL;                          return NULL;
                 }                  }
                 (void)strncpy(temp, &str[start], len);                  (void)strncpy(temp, &str[start], len);
Line 1105  history_tokenize(const char *str)
Line 1151  history_tokenize(const char *str)
                 if (str[i])                  if (str[i])
                         i++;                          i++;
         }          }
         return (result);          return result;
 }  }
   
   
Line 1115  history_tokenize(const char *str)
Line 1161  history_tokenize(const char *str)
 void  void
 stifle_history(int max)  stifle_history(int max)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
           HIST_ENTRY *he;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if (FUNW(history)(h, &ev, H_SETSIZE, max) == 0)          if (history(h, &ev, H_SETSIZE, max) == 0) {
                 max_input_history = max;                  max_input_history = max;
                   if (history_length > max)
                           history_base = history_length - max;
                   while (history_length > max) {
                           he = remove_history(0);
                           el_free(he->data);
                           el_free((void *)(unsigned long)he->line);
                           el_free(he);
                   }
           }
 }  }
   
   
Line 1131  stifle_history(int max)
Line 1187  stifle_history(int max)
 int  int
 unstifle_history(void)  unstifle_history(void)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
         int omax;          int omax;
   
         FUNW(history)(h, &ev, H_SETSIZE, INT_MAX);          history(h, &ev, H_SETSIZE, INT_MAX);
         omax = max_input_history;          omax = max_input_history;
         max_input_history = INT_MAX;          max_input_history = INT_MAX;
         return (omax);          /* some value _must_ be returned */          return omax;            /* some value _must_ be returned */
 }  }
   
   
Line 1146  history_is_stifled(void)
Line 1202  history_is_stifled(void)
 {  {
   
         /* cannot return true answer */          /* cannot return true answer */
         return (max_input_history != INT_MAX);          return max_input_history != INT_MAX;
 }  }
   
 static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";  static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
Line 1181  history_truncate_file (const char *filen
Line 1237  history_truncate_file (const char *filen
         }          }
   
         for(;;) {          for(;;) {
                 if (fread(buf, sizeof(buf), 1, fp) != 1) {                  if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) {
                         if (ferror(fp)) {                          if (ferror(fp)) {
                                 ret = errno;                                  ret = errno;
                                 break;                                  break;
Line 1191  history_truncate_file (const char *filen
Line 1247  history_truncate_file (const char *filen
                                 ret = errno;                                  ret = errno;
                                 break;                                  break;
                         }                          }
                         left = fread(buf, 1, sizeof(buf), fp);                          left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp);
                         if (ferror(fp)) {                          if (ferror(fp)) {
                                 ret = errno;                                  ret = errno;
                                 break;                                  break;
Line 1199  history_truncate_file (const char *filen
Line 1255  history_truncate_file (const char *filen
                         if (left == 0) {                          if (left == 0) {
                                 count--;                                  count--;
                                 left = sizeof(buf);                                  left = sizeof(buf);
                         } else if (fwrite(buf, (size_t)left, 1, tp) != 1) {                          } else if (fwrite(buf, (size_t)left, (size_t)1, tp)
                               != 1) {
                                 ret = errno;                                  ret = errno;
                                 break;                                  break;
                         }                          }
                         fflush(tp);                          fflush(tp);
                         break;                          break;
                 }                  }
                 if (fwrite(buf, sizeof(buf), 1, tp) != 1) {                  if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) {
                         ret = errno;                          ret = errno;
                         break;                          break;
                 }                  }
Line 1236  history_truncate_file (const char *filen
Line 1293  history_truncate_file (const char *filen
                         ret = errno;                          ret = errno;
                         break;                          break;
                 }                  }
                 if (fread(buf, sizeof(buf), 1, tp) != 1) {                  if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) {
                         if (ferror(tp)) {                          if (ferror(tp)) {
                                 ret = errno;                                  ret = errno;
                                 break;                                  break;
Line 1250  history_truncate_file (const char *filen
Line 1307  history_truncate_file (const char *filen
         if (ret || nlines > 0)          if (ret || nlines > 0)
                 goto out3;                  goto out3;
   
         if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) {          if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) {
                 ret = errno;                  ret = errno;
                 goto out3;                  goto out3;
         }          }
Line 1262  history_truncate_file (const char *filen
Line 1319  history_truncate_file (const char *filen
         }          }
   
         for(;;) {          for(;;) {
                 if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) {                  if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) {
                         if (ferror(fp))                          if (ferror(fp))
                                 ret = errno;                                  ret = errno;
                         break;                          break;
                 }                  }
                 if (fwrite(buf, (size_t)left, 1, fp) != 1) {                  if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) {
                         ret = errno;                          ret = errno;
                         break;                          break;
                 }                  }
Line 1292  out1:
Line 1349  out1:
 int  int
 read_history(const char *filename)  read_history(const char *filename)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
         if (filename == NULL && (filename = _default_history_file()) == NULL)          if (filename == NULL && (filename = _default_history_file()) == NULL)
                 return errno;                  return errno;
         return (FUNW(history)(h, &ev, H_LOAD, filename) == -1 ?          errno = 0;
             (errno ? errno : EINVAL) : 0);          if (history(h, &ev, H_LOAD, filename) == -1)
               return errno ? errno : EINVAL;
           if (history(h, &ev, H_GETSIZE) == 0)
                   history_length = ev.num;
           if (history_length < 0)
                   return EINVAL;
           return 0;
 }  }
   
   
Line 1309  read_history(const char *filename)
Line 1372  read_history(const char *filename)
 int  int
 write_history(const char *filename)  write_history(const char *filename)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
         if (filename == NULL && (filename = _default_history_file()) == NULL)          if (filename == NULL && (filename = _default_history_file()) == NULL)
                 return errno;                  return errno;
         return (FUNW(history)(h, &ev, H_SAVE, filename) == -1 ?          return history(h, &ev, H_SAVE, filename) == -1 ?
             (errno ? errno : EINVAL) : 0);              (errno ? errno : EINVAL) : 0;
 }  }
   
   int
   append_history(int n, const char *filename)
   {
           HistEvent ev;
           FILE *fp;
   
           if (h == NULL || e == NULL)
                   rl_initialize();
           if (filename == NULL && (filename = _default_history_file()) == NULL)
                   return errno;
   
           if ((fp = fopen(filename, "a")) == NULL)
                   return errno;
   
           if (history(h, &ev, H_NSAVE_FP, (size_t)n,  fp) == -1) {
                   int serrno = errno ? errno : EINVAL;
                   fclose(fp);
                   return serrno;
           }
           fclose(fp);
           return 0;
   }
   
 /*  /*
  * returns history ``num''th event   * returns history ``num''th event
Line 1329  HIST_ENTRY *
Line 1414  HIST_ENTRY *
 history_get(int num)  history_get(int num)
 {  {
         static HIST_ENTRY she;          static HIST_ENTRY she;
         TYPE(HistEvent) ev;          HistEvent ev;
         int curr_num;          int curr_num;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
           if (num < history_base)
                   return NULL;
   
         /* save current position */          /* save current position */
         if (FUNW(history)(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_CURR) != 0)
                 return (NULL);                  return NULL;
         curr_num = ev.num;          curr_num = ev.num;
   
         /* start from the oldest */          /*
         if (FUNW(history)(h, &ev, H_LAST) != 0)           * use H_DELDATA to set to nth history (without delete) by passing
                 return (NULL);  /* error */           * (void **)-1  -- as in history_set_pos
            */
         /* look forwards for event matching specified offset */          if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0)
         if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &she.data))                  goto out;
                 return (NULL);  
   
         she.line = ct_encode_string(ev.str, &conv);          /* get current entry */
           if (history(h, &ev, H_CURR) != 0)
                   goto out;
           if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0)
                   goto out;
           she.line = ev.str;
   
         /* restore pointer to where it was */          /* restore pointer to where it was */
         (void)FUNW(history)(h, &ev, H_SET, curr_num);          (void)history(h, &ev, H_SET, curr_num);
   
         return (&she);          return &she;
   
   out:
           /* restore pointer to where it was */
           (void)history(h, &ev, H_SET, curr_num);
           return NULL;
 }  }
   
   
Line 1363  history_get(int num)
Line 1460  history_get(int num)
 int  int
 add_history(const char *line)  add_history(const char *line)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         (void)FUNW(history)(h, &ev, H_ENTER, line);          if (history(h, &ev, H_ENTER, line) == -1)
         if (FUNW(history)(h, &ev, H_GETSIZE) == 0)                  return 0;
                 history_length = ev.num;  
   
         return (!(history_length > 0)); /* return 0 if all is okay */          (void)history(h, &ev, H_GETSIZE);
           if (ev.num == history_length)
                   history_base++;
           else
                   history_length = ev.num;
           return 0;
 }  }
   
   
Line 1383  HIST_ENTRY *
Line 1484  HIST_ENTRY *
 remove_history(int num)  remove_history(int num)
 {  {
         HIST_ENTRY *he;          HIST_ENTRY *he;
         TYPE(HistEvent) ev;          HistEvent ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if ((he = malloc(sizeof(*he))) == NULL)          if ((he = el_malloc(sizeof(*he))) == NULL)
                 return NULL;                  return NULL;
   
         if (FUNW(history)(h, &ev, H_DELDATA, num, &he->data) != 0) {          if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
                 free(he);                  el_free(he);
                 return NULL;                  return NULL;
         }          }
   
         he->line = ct_encode_string(ev.str, &conv);          he->line = ev.str;
         if (FUNW(history)(h, &ev, H_GETSIZE) == 0)          if (history(h, &ev, H_GETSIZE) == 0)
                 history_length = ev.num;                  history_length = ev.num;
   
         return he;          return he;
Line 1411  HIST_ENTRY *
Line 1512  HIST_ENTRY *
 replace_history_entry(int num, const char *line, histdata_t data)  replace_history_entry(int num, const char *line, histdata_t data)
 {  {
         HIST_ENTRY *he;          HIST_ENTRY *he;
         TYPE(HistEvent) ev;          HistEvent ev;
         int curr_num;          int curr_num;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         /* save current position */          /* save current position */
         if (FUNW(history)(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_CURR) != 0)
                 return NULL;                  return NULL;
         curr_num = ev.num;          curr_num = ev.num;
   
         /* start from the oldest */          /* start from the oldest */
         if (FUNW(history)(h, &ev, H_LAST) != 0)          if (history(h, &ev, H_LAST) != 0)
                 return NULL;    /* error */                  return NULL;    /* error */
   
         if ((he = malloc(sizeof(*he))) == NULL)          if ((he = el_malloc(sizeof(*he))) == NULL)
                 return NULL;                  return NULL;
   
         /* look forwards for event matching specified offset */          /* look forwards for event matching specified offset */
         if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &he->data))          if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
                 goto out;                  goto out;
   
         he->line = strdup(ct_encode_string(ev.str, &e->el_scratch));          he->line = strdup(ev.str);
         if (he->line == NULL)          if (he->line == NULL)
                 goto out;                  goto out;
   
         if (FUNW(history)(h, &ev, H_REPLACE, line, data))          if (history(h, &ev, H_REPLACE, line, data))
                 goto out;                  goto out;
   
         /* restore pointer to where it was */          /* restore pointer to where it was */
         if (FUNW(history)(h, &ev, H_SET, curr_num))          if (history(h, &ev, H_SET, curr_num))
                 goto out;                  goto out;
   
         return he;          return he;
 out:  out:
         free(he);          el_free(he);
         return NULL;          return NULL;
 }  }
   
Line 1456  out:
Line 1557  out:
 void  void
 clear_history(void)  clear_history(void)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
   
         (void)FUNW(history)(h, &ev, H_CLEAR);          if (h == NULL || e == NULL)
         history_length = 0;                  rl_initialize();
   
           (void)history(h, &ev, H_CLEAR);
           history_offset = history_length = 0;
 }  }
   
   
Line 1469  clear_history(void)
Line 1573  clear_history(void)
 int  int
 where_history(void)  where_history(void)
 {  {
         TYPE(HistEvent) ev;          return history_offset;
         int curr_num, off;  }
   
         if (FUNW(history)(h, &ev, H_CURR) != 0)  static HIST_ENTRY **_history_listp;
                 return (0);  static HIST_ENTRY *_history_list;
         curr_num = ev.num;  
   
         (void)FUNW(history)(h, &ev, H_FIRST);  HIST_ENTRY **
         off = 1;  history_list(void)
         while (ev.num != curr_num && FUNW(history)(h, &ev, H_NEXT) == 0)  {
                 off++;          HistEvent ev;
           HIST_ENTRY **nlp, *nl;
           int i;
   
         return (off);          if (history(h, &ev, H_LAST) != 0)
 }                  return NULL;
   
           if ((nlp = el_realloc(_history_listp,
               (size_t)history_length * sizeof(*nlp))) == NULL)
                   return NULL;
           _history_listp = nlp;
   
           if ((nl = el_realloc(_history_list,
               (size_t)history_length * sizeof(*nl))) == NULL)
                   return NULL;
           _history_list = nl;
   
           i = 0;
           do {
                   _history_listp[i] = &_history_list[i];
                   _history_list[i].line = ev.str;
                   _history_list[i].data = NULL;
                   if (i++ == history_length)
                           abort();
           } while (history(h, &ev, H_PREV) == 0);
           return _history_listp;
   }
   
 /*  /*
  * returns current history event or NULL if there is no such event   * returns current history event or NULL if there is no such event
Line 1491  where_history(void)
Line 1616  where_history(void)
 HIST_ENTRY *  HIST_ENTRY *
 current_history(void)  current_history(void)
 {  {
           HistEvent ev;
   
         return (_move_history(H_CURR));          if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0)
                   return NULL;
   
           rl_he.line = ev.str;
           rl_he.data = NULL;
           return &rl_he;
 }  }
   
   
Line 1502  current_history(void)
Line 1633  current_history(void)
 int  int
 history_total_bytes(void)  history_total_bytes(void)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
         int curr_num;          int curr_num;
         size_t size;          size_t size;
   
         if (FUNW(history)(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_CURR) != 0)
                 return (-1);                  return -1;
         curr_num = ev.num;          curr_num = ev.num;
   
         (void)FUNW(history)(h, &ev, H_FIRST);          (void)history(h, &ev, H_FIRST);
         size = 0;          size = 0;
         do          do
                 size += Strlen(ev.str) * sizeof(*ev.str);                  size += strlen(ev.str) * sizeof(*ev.str);
         while (FUNW(history)(h, &ev, H_NEXT) == 0);          while (history(h, &ev, H_NEXT) == 0);
   
         /* get to the same position as before */          /* get to the same position as before */
         FUNW(history)(h, &ev, H_PREV_EVENT, curr_num);          history(h, &ev, H_PREV_EVENT, curr_num);
   
         return (int)(size);          return (int)size;
 }  }
   
   
Line 1529  history_total_bytes(void)
Line 1660  history_total_bytes(void)
 int  int
 history_set_pos(int pos)  history_set_pos(int pos)
 {  {
         TYPE(HistEvent) ev;  
         int curr_num;  
   
         if (pos >= history_length || pos < 0)          if (pos >= history_length || pos < 0)
                 return (-1);                  return 0;
   
         (void)FUNW(history)(h, &ev, H_CURR);  
         curr_num = ev.num;  
   
         /*          history_offset = pos;
          * use H_DELDATA to set to nth history (without delete) by passing          return 1;
          * (void **)-1  
          */  
         if (FUNW(history)(h, &ev, H_DELDATA, pos, (void **)-1)) {  
                 (void)FUNW(history)(h, &ev, H_SET, curr_num);  
                 return(-1);  
         }  
         return (0);  
 }  }
   
   
 /*  /*
  * returns previous event in history and shifts pointer accordingly   * returns previous event in history and shifts pointer accordingly
    * Note that readline and editline define directions in opposite ways.
  */   */
 HIST_ENTRY *  HIST_ENTRY *
 previous_history(void)  previous_history(void)
 {  {
           HistEvent ev;
   
           if (history_offset == 0)
                   return NULL;
   
         return (_move_history(H_PREV));          if (history(h, &ev, H_LAST) != 0)
                   return NULL;
   
           history_offset--;
           return current_history();
 }  }
   
   
Line 1567  previous_history(void)
Line 1694  previous_history(void)
 HIST_ENTRY *  HIST_ENTRY *
 next_history(void)  next_history(void)
 {  {
           HistEvent ev;
   
         return (_move_history(H_NEXT));          if (history_offset >= history_length)
                   return NULL;
   
           if (history(h, &ev, H_LAST) != 0)
                   return NULL;
   
           history_offset++;
           return current_history();
 }  }
   
   
Line 1578  next_history(void)
Line 1713  next_history(void)
 int  int
 history_search(const char *str, int direction)  history_search(const char *str, int direction)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
         const Char *strp;          const char *strp;
         const Char *wstr;  
         int curr_num;          int curr_num;
   
         if (FUNW(history)(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_CURR) != 0)
                 return (-1);                  return -1;
         curr_num = ev.num;          curr_num = ev.num;
   
         wstr = ct_decode_string(str, &conv);  
         for (;;) {          for (;;) {
                 if ((strp = Strstr(ev.str, wstr)) != NULL)                  if ((strp = strstr(ev.str, str)) != NULL)
                         return (int) (strp - ev.str);                          return (int)(strp - ev.str);
                 if (FUNW(history)(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)                  if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
                         break;                          break;
         }          }
         (void)FUNW(history)(h, &ev, H_SET, curr_num);          (void)history(h, &ev, H_SET, curr_num);
         return (-1);          return -1;
 }  }
   
   
Line 1605  history_search(const char *str, int dire
Line 1738  history_search(const char *str, int dire
 int  int
 history_search_prefix(const char *str, int direction)  history_search_prefix(const char *str, int direction)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
   
         return (FUNW(history)(h, &ev, direction < 0 ?          return (history(h, &ev, direction < 0 ?
             H_PREV_STR : H_NEXT_STR, str));              H_PREV_STR : H_NEXT_STR, str));
 }  }
   
Line 1621  int
Line 1754  int
 history_search_pos(const char *str,  history_search_pos(const char *str,
                    int direction __attribute__((__unused__)), int pos)                     int direction __attribute__((__unused__)), int pos)
 {  {
         TYPE(HistEvent) ev;          HistEvent ev;
         int curr_num, off;          int curr_num, off;
         const Char *wstr;  
   
         off = (pos > 0) ? pos : -pos;          off = (pos > 0) ? pos : -pos;
         pos = (pos > 0) ? 1 : -1;          pos = (pos > 0) ? 1 : -1;
   
         if (FUNW(history)(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_CURR) != 0)
                 return (-1);                  return -1;
         curr_num = ev.num;          curr_num = ev.num;
   
         if (history_set_pos(off) != 0 || FUNW(history)(h, &ev, H_CURR) != 0)          if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0)
                 return (-1);                  return -1;
   
         wstr = ct_decode_string(str, &conv);  
         for (;;) {          for (;;) {
                 if (Strstr(ev.str, wstr))                  if (strstr(ev.str, str))
                         return (off);                          return off;
                 if (FUNW(history)(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)                  if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
                         break;                          break;
         }          }
   
         /* set "current" pointer back to previous state */          /* set "current" pointer back to previous state */
         (void)FUNW(history)(h, &ev,          (void)history(h, &ev,
             pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);              pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
   
         return (-1);          return -1;
 }  }
   
   
Line 1670  filename_completion_function(const char 
Line 1801  filename_completion_function(const char 
  * a completion generator for usernames; returns _first_ username   * a completion generator for usernames; returns _first_ username
  * which starts with supplied text   * which starts with supplied text
  * text contains a partial username preceded by random character   * text contains a partial username preceded by random character
  * (usually '~'); state is ignored   * (usually '~'); state resets search from start (??? should we do that anyway)
  * it's callers responsibility to free returned value   * it's the caller's responsibility to free the returned value
  */   */
 char *  char *
 username_completion_function(const char *text, int state)  username_completion_function(const char *text, int state)
 {  {
         struct passwd *pwd, pwres;  #if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
           struct passwd pwres;
         char pwbuf[1024];          char pwbuf[1024];
   #endif
           struct passwd *pass = NULL;
   
         if (text[0] == '\0')          if (text[0] == '\0')
                 return (NULL);                  return NULL;
   
         if (*text == '~')          if (*text == '~')
                 text++;                  text++;
Line 1688  username_completion_function(const char 
Line 1822  username_completion_function(const char 
         if (state == 0)          if (state == 0)
                 setpwent();                  setpwent();
   
         while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0          while (
             && pwd != NULL && text[0] == pwd->pw_name[0]  #if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
             && strcmp(text, pwd->pw_name) == 0);              getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL
   #else
               (pass = getpwent()) != NULL
   #endif
               && text[0] == pass->pw_name[0]
               && strcmp(text, pass->pw_name) == 0)
                   continue;
   
         if (pwd == NULL) {          if (pass == NULL) {
                 endpwent();                  endpwent();
                 return NULL;                  return NULL;
         }          }
         return strdup(pwd->pw_name);          return strdup(pass->pw_name);
 }  }
   
   
Line 1711  _el_rl_tstp(EditLine *el __attribute__((
Line 1851  _el_rl_tstp(EditLine *el __attribute__((
         return CC_NORM;          return CC_NORM;
 }  }
   
 /*  
  * Display list of strings in columnar format on readline's output stream.  
  * 'matches' is list of strings, 'len' is number of strings in 'matches',  
  * 'max' is maximum length of string in 'matches'.  
  */  
 void  
 rl_display_match_list(char **matches, int len, int max)  
 {  
   
         fn_display_match_list(e, matches, (size_t)len, (size_t)max);  
 }  
   
 static const char *  static const char *
 /*ARGSUSED*/  /*ARGSUSED*/
 _rl_completion_append_character_function(const char *dummy  _rl_completion_append_character_function(const char *dummy
     __attribute__((__unused__)))      __attribute__((__unused__)))
 {  {
         static char buf[2];          static char buf[2];
         buf[0] = rl_completion_append_character;          buf[0] = (char)rl_completion_append_character;
         buf[1] = '\0';          buf[1] = '\0';
         return buf;          return buf;
 }  }
   
   
 /*  /*
    * Display list of strings in columnar format on readline's output stream.
    * 'matches' is list of strings, 'len' is number of strings in 'matches',
    * 'max' is maximum length of string in 'matches'.
    */
   void
   rl_display_match_list(char **matches, int len, int max)
   {
   
           fn_display_match_list(e, matches, (size_t)len, (size_t)max,
                   _rl_completion_append_character_function);
   }
   
   /*
  * complete word at current point   * complete word at current point
  */   */
 /* ARGSUSED */  /* ARGSUSED */
 int  int
 rl_complete(int ignore __attribute__((__unused__)), int invoking_key)  rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
 {  {
 #ifdef WIDECHAR  
         static ct_buffer_t wbreak_conv, sprefix_conv;          static ct_buffer_t wbreak_conv, sprefix_conv;
 #endif          char *breakchars;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
Line 1754  rl_complete(int ignore __attribute__((__
Line 1894  rl_complete(int ignore __attribute__((__
                 arr[0] = (char)invoking_key;                  arr[0] = (char)invoking_key;
                 arr[1] = '\0';                  arr[1] = '\0';
                 el_insertstr(e, arr);                  el_insertstr(e, arr);
                 return (CC_REFRESH);                  return CC_REFRESH;
         }          }
   
           if (rl_completion_word_break_hook != NULL)
                   breakchars = (*rl_completion_word_break_hook)();
           else
                   breakchars = rl_basic_word_break_characters;
   
           _rl_update_pos();
   
         /* Just look at how many global variables modify this operation! */          /* Just look at how many global variables modify this operation! */
         return fn_complete(e,          return fn_complete(e,
             (CPFunction *)rl_completion_entry_function,              (rl_compentry_func_t *)rl_completion_entry_function,
             rl_attempted_completion_function,              rl_attempted_completion_function,
             ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),              ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
             ct_decode_string(rl_special_prefixes, &sprefix_conv),              ct_decode_string(breakchars, &sprefix_conv),
             _rl_completion_append_character_function,              _rl_completion_append_character_function,
             (size_t)rl_completion_query_items,              (size_t)rl_completion_query_items,
             &rl_completion_type, &rl_attempted_completion_over,              &rl_completion_type, &rl_attempted_completion_over,
             &rl_point, &rl_end);              &rl_point, &rl_end);
   
   
 }  }
   
   
Line 1797  rl_bind_key(int c, rl_command_func_t *fu
Line 1946  rl_bind_key(int c, rl_command_func_t *fu
                 e->el_map.key[c] = ED_INSERT;                  e->el_map.key[c] = ED_INSERT;
                 retval = 0;                  retval = 0;
         }          }
         return (retval);          return retval;
 }  }
   
   
Line 1813  rl_read_key(void)
Line 1962  rl_read_key(void)
         if (e == NULL || h == NULL)          if (e == NULL || h == NULL)
                 rl_initialize();                  rl_initialize();
   
         return (el_getc(e, fooarr));          return el_getc(e, fooarr);
 }  }
   
   
Line 1843  rl_insert(int count, int c)
Line 1992  rl_insert(int count, int c)
                 rl_initialize();                  rl_initialize();
   
         /* XXX - int -> char conversion can lose on multichars */          /* XXX - int -> char conversion can lose on multichars */
         arr[0] = c;          arr[0] = (char)c;
         arr[1] = '\0';          arr[1] = '\0';
   
         for (; count > 0; count--)          for (; count > 0; count--)
                 el_push(e, arr);                  el_push(e, arr);
   
         return (0);          return 0;
 }  }
   
 int  int
 rl_insert_text(const char *text)  rl_insert_text(const char *text)
 {  {
         if (!text || *text == 0)          if (!text || *text == 0)
                 return (0);                  return 0;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if (el_insertstr(e, text) < 0)          if (el_insertstr(e, text) < 0)
                 return (0);                  return 0;
         return (int)strlen(text);          return (int)strlen(text);
 }  }
   
 /*ARGSUSED*/  /*ARGSUSED*/
 int  int
 rl_newline(int count, int c)  rl_newline(int count __attribute__((__unused__)),
       int c __attribute__((__unused__)))
 {  {
         /*          /*
          * Readline-4.0 appears to ignore the args.           * Readline-4.0 appears to ignore the args.
Line 1878  rl_newline(int count, int c)
Line 2028  rl_newline(int count, int c)
   
 /*ARGSUSED*/  /*ARGSUSED*/
 static unsigned char  static unsigned char
 rl_bind_wrapper(EditLine *el, unsigned char c)  rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c)
 {  {
         if (map[c] == NULL)          if (map[c] == NULL)
             return CC_ERROR;              return CC_ERROR;
   
         _rl_update_pos();          _rl_update_pos();
   
         (*map[c])(NULL, c);          (*map[c])(1, c);
   
         /* If rl_done was set by the above call, deal with it here */          /* If rl_done was set by the above call, deal with it here */
         if (rl_done)          if (rl_done)
Line 1895  rl_bind_wrapper(EditLine *el, unsigned c
Line 2045  rl_bind_wrapper(EditLine *el, unsigned c
 }  }
   
 int  int
 rl_add_defun(const char *name, Function *fun, int c)  rl_add_defun(const char *name, rl_command_func_t *fun, int c)
 {  {
         char dest[8];          char dest[8];
         if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)          if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
Line 1903  rl_add_defun(const char *name, Function 
Line 2053  rl_add_defun(const char *name, Function 
         map[(unsigned char)c] = fun;          map[(unsigned char)c] = fun;
         el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);          el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
         vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);          vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
         el_set(e, EL_BIND, dest, name);          el_set(e, EL_BIND, dest, name, NULL);
         return 0;          return 0;
 }  }
   
 void  void
 rl_callback_read_char()  rl_callback_read_char(void)
 {  {
         int count = 0, done = 0;          int count = 0, done = 0;
         const char *buf = el_gets(e, &count);          const char *buf = el_gets(e, &count);
Line 1924  rl_callback_read_char()
Line 2074  rl_callback_read_char()
         if (done && rl_linefunc != NULL) {          if (done && rl_linefunc != NULL) {
                 el_set(e, EL_UNBUFFERED, 0);                  el_set(e, EL_UNBUFFERED, 0);
                 if (done == 2) {                  if (done == 2) {
                     if ((wbuf = strdup(buf)) != NULL)                          if ((wbuf = strdup(buf)) != NULL)
                         wbuf[count] = '\0';                                  wbuf[count] = '\0';
                 } else                  } else
                         wbuf = NULL;                          wbuf = NULL;
                 (*(void (*)(const char *))rl_linefunc)(wbuf);                  (*(void (*)(const char *))rl_linefunc)(wbuf);
                 //el_set(e, EL_UNBUFFERED, 1);                  el_set(e, EL_UNBUFFERED, 1);
         }          }
 }  }
   
 void  void
 rl_callback_handler_install(const char *prompt, VCPFunction *linefunc)  rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc)
 {  {
         if (e == NULL) {          if (e == NULL) {
                 rl_initialize();                  rl_initialize();
Line 1942  rl_callback_handler_install(const char *
Line 2092  rl_callback_handler_install(const char *
         (void)rl_set_prompt(prompt);          (void)rl_set_prompt(prompt);
         rl_linefunc = linefunc;          rl_linefunc = linefunc;
         el_set(e, EL_UNBUFFERED, 1);          el_set(e, EL_UNBUFFERED, 1);
 }  }
   
 void  void
 rl_callback_handler_remove(void)  rl_callback_handler_remove(void)
 {  {
         el_set(e, EL_UNBUFFERED, 0);  
         rl_linefunc = NULL;          rl_linefunc = NULL;
           el_end(e);
           e = NULL;
 }  }
   
 void  void
 rl_redisplay(void)  rl_redisplay(void)
 {  {
         char a[2];          char a[2];
         a[0] = e->el_tty.t_c[TS_IO][C_REPRINT];          a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT];
         a[1] = '\0';          a[1] = '\0';
         el_push(e, a);          el_push(e, a);
 }  }
Line 1964  int
Line 2115  int
 rl_get_previous_history(int count, int key)  rl_get_previous_history(int count, int key)
 {  {
         char a[2];          char a[2];
         a[0] = key;          a[0] = (char)key;
         a[1] = '\0';          a[1] = '\0';
         while (count--)          while (count--)
                 el_push(e, a);                  el_push(e, a);
Line 1973  rl_get_previous_history(int count, int k
Line 2124  rl_get_previous_history(int count, int k
   
 void  void
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_prep_terminal(int meta_flag)  rl_prep_terminal(int meta_flag __attribute__((__unused__)))
 {  {
         el_set(e, EL_PREP_TERM, 1);          el_set(e, EL_PREP_TERM, 1);
 }  }
Line 1987  rl_deprep_terminal(void)
Line 2138  rl_deprep_terminal(void)
 int  int
 rl_read_init_file(const char *s)  rl_read_init_file(const char *s)
 {  {
         return(el_source(e, s));          return el_source(e, s);
 }  }
   
 int  int
Line 2001  rl_parse_and_bind(const char *line)
Line 2152  rl_parse_and_bind(const char *line)
         tok_str(tok, line, &argc, &argv);          tok_str(tok, line, &argc, &argv);
         argc = el_parse(e, argc, argv);          argc = el_parse(e, argc, argv);
         tok_end(tok);          tok_end(tok);
         return (argc ? 1 : 0);          return argc ? 1 : 0;
 }  }
   
 int  int
Line 2011  rl_variable_bind(const char *var, const 
Line 2162  rl_variable_bind(const char *var, const 
          * The proper return value is undocument, but this is what the           * The proper return value is undocument, but this is what the
          * readline source seems to do.           * readline source seems to do.
          */           */
         return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0);          return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0;
 }  }
   
 void  void
Line 2019  rl_stuff_char(int c)
Line 2170  rl_stuff_char(int c)
 {  {
         char buf[2];          char buf[2];
   
         buf[0] = c;          buf[0] = (char)c;
         buf[1] = '\0';          buf[1] = '\0';
         el_insertstr(e, buf);          el_insertstr(e, buf);
 }  }
   
 static int  static int
 _rl_event_read_char(EditLine *el, char *cp)  _rl_event_read_char(EditLine *el, wchar_t *wc)
 {  {
           char    ch;
         int     n;          int     n;
         ssize_t num_read = 0;          ssize_t num_read = 0;
   
         *cp = '\0';          ch = '\0';
           *wc = L'\0';
         while (rl_event_hook) {          while (rl_event_hook) {
   
                 (*rl_event_hook)();                  (*rl_event_hook)();
   
 #if defined(FIONREAD)  #if defined(FIONREAD)
                 if (ioctl(el->el_infd, FIONREAD, &n) < 0)                  if (ioctl(el->el_infd, FIONREAD, &n) < 0)
                         return(-1);                          return -1;
                 if (n)                  if (n)
                         num_read = read(el->el_infd, cp, 1);                          num_read = read(el->el_infd, &ch, (size_t)1);
                 else                  else
                         num_read = 0;                          num_read = 0;
 #elif defined(F_SETFL) && defined(O_NDELAY)  #elif defined(F_SETFL) && defined(O_NDELAY)
                 if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)                  if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
                         return(-1);                          return -1;
                 if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)                  if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
                         return(-1);                          return -1;
                 num_read = read(el->el_infd, cp, 1);                  num_read = read(el->el_infd, &ch, 1);
                 if (fcntl(el->el_infd, F_SETFL, n))                  if (fcntl(el->el_infd, F_SETFL, n))
                         return(-1);                          return -1;
 #else  #else
                 /* not non-blocking, but what you gonna do? */                  /* not non-blocking, but what you gonna do? */
                 num_read = read(el->el_infd, cp, 1);                  num_read = read(el->el_infd, &ch, 1);
                 return(-1);                  return -1;
 #endif  #endif
   
                 if (num_read < 0 && errno == EAGAIN)                  if (num_read < 0 && errno == EAGAIN)
Line 2064  _rl_event_read_char(EditLine *el, char *
Line 2217  _rl_event_read_char(EditLine *el, char *
         }          }
         if (!rl_event_hook)          if (!rl_event_hook)
                 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);                  el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
           *wc = (wchar_t)ch;
         return (int)num_read;          return (int)num_read;
 }  }
   
Line 2080  void
Line 2234  void
 rl_get_screen_size(int *rows, int *cols)  rl_get_screen_size(int *rows, int *cols)
 {  {
         if (rows)          if (rows)
                 el_get(e, EL_GETTC, "li", rows);                  el_get(e, EL_GETTC, "li", rows, (void *)0);
         if (cols)          if (cols)
                 el_get(e, EL_GETTC, "co", cols);                  el_get(e, EL_GETTC, "co", cols, (void *)0);
 }  }
   
 void  void
Line 2090  rl_set_screen_size(int rows, int cols)
Line 2244  rl_set_screen_size(int rows, int cols)
 {  {
         char buf[64];          char buf[64];
         (void)snprintf(buf, sizeof(buf), "%d", rows);          (void)snprintf(buf, sizeof(buf), "%d", rows);
         el_set(e, EL_SETTC, "li", buf);          el_set(e, EL_SETTC, "li", buf, NULL);
         (void)snprintf(buf, sizeof(buf), "%d", cols);          (void)snprintf(buf, sizeof(buf), "%d", cols);
         el_set(e, EL_SETTC, "co", buf);          el_set(e, EL_SETTC, "co", buf, NULL);
 }  }
   
 char **  char **
Line 2103  rl_completion_matches(const char *str, r
Line 2257  rl_completion_matches(const char *str, r
   
         len = 1;          len = 1;
         max = 10;          max = 10;
         if ((list = malloc(max * sizeof(*list))) == NULL)          if ((list = el_malloc(max * sizeof(*list))) == NULL)
                 return NULL;                  return NULL;
   
         while ((match = (*fun)(str, (int)(len - 1))) != NULL) {          while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
Line 2111  rl_completion_matches(const char *str, r
Line 2265  rl_completion_matches(const char *str, r
                 if (len == max) {                  if (len == max) {
                         char **nl;                          char **nl;
                         max += 10;                          max += 10;
                         if ((nl = realloc(list, max * sizeof(*nl))) == NULL)                          if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL)
                                 goto out;                                  goto out;
                         list = nl;                          list = nl;
                 }                  }
Line 2126  rl_completion_matches(const char *str, r
Line 2280  rl_completion_matches(const char *str, r
         }          }
         qsort(&list[1], len - 1, sizeof(*list),          qsort(&list[1], len - 1, sizeof(*list),
             (int (*)(const void *, const void *)) strcmp);              (int (*)(const void *, const void *)) strcmp);
         min = SIZE_T_MAX;          min = SIZE_MAX;
         for (i = 1, a = list[i]; i < len - 1; i++, a = b) {          for (i = 1, a = list[i]; i < len - 1; i++, a = b) {
                 b = list[i + 1];                  b = list[i + 1];
                 for (j = 0; a[j] && a[j] == b[j]; j++)                  for (j = 0; a[j] && a[j] == b[j]; j++)
Line 2138  rl_completion_matches(const char *str, r
Line 2292  rl_completion_matches(const char *str, r
                 if ((list[0] = strdup(str)) == NULL)                  if ((list[0] = strdup(str)) == NULL)
                         goto out;                          goto out;
         } else {          } else {
                 if ((list[0] = malloc(min + 1)) == NULL)                  if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL)
                         goto out;                          goto out;
                 (void)memcpy(list[0], list[1], min);                  (void)memcpy(list[0], list[1], min);
                 list[0][min] = '\0';                  list[0][min] = '\0';
         }          }
         return list;          return list;
   
 out:  out:
         free(list);          el_free(list);
         return NULL;          return NULL;
 }  }
   
Line 2181  history_get_history_state(void)
Line 2335  history_get_history_state(void)
 {  {
         HISTORY_STATE *hs;          HISTORY_STATE *hs;
   
         if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL)          if ((hs = el_malloc(sizeof(*hs))) == NULL)
                 return (NULL);                  return NULL;
         hs->length = history_length;          hs->length = history_length;
         return (hs);          return hs;
 }  }
   
 int  int
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_kill_text(int from, int to)  rl_kill_text(int from __attribute__((__unused__)),
       int to __attribute__((__unused__)))
 {  {
         return 0;          return 0;
 }  }
Line 2208  rl_get_keymap(void)
Line 2363  rl_get_keymap(void)
   
 void  void
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_set_keymap(Keymap k)  rl_set_keymap(Keymap k __attribute__((__unused__)))
 {  {
 }  }
   
 int  int
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k)  rl_generic_bind(int type __attribute__((__unused__)),
       const char * keyseq __attribute__((__unused__)),
       const char * data __attribute__((__unused__)),
       Keymap k __attribute__((__unused__)))
 {  {
         return 0;          return 0;
 }  }
   
 int  int
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k)  rl_bind_key_in_map(int key __attribute__((__unused__)),
       rl_command_func_t *fun __attribute__((__unused__)),
       Keymap k __attribute__((__unused__)))
 {  {
         return 0;          return 0;
 }  }
Line 2231  void
Line 2391  void
 rl_cleanup_after_signal(void)  rl_cleanup_after_signal(void)
 {  {
 }  }
   
   int
   rl_on_new_line(void)
   {
           return 0;
   }
   
   void
   rl_free_line_state(void)
   {
   }
   
   int
   /*ARGSUSED*/
   rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
   {
           return 0;
   }
   
   void
   rl_resize_terminal(void)
   {
           el_resize(e);
   }

Legend:
Removed from v.1.88  
changed lines
  Added in v.1.146.2.1

CVSweb <webmaster@jp.NetBSD.org>