[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.111.2.1 and 1.138

version 1.111.2.1, 2015/05/13 13:33:55 version 1.138, 2016/09/01 13:23:44
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>
   #include <stdint.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
 #include <vis.h>  #include <vis.h>
   
 #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 78  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;  VFunction *rl_event_hook = NULL;
 KEYMAP_ENTRY_ARRAY emacs_standard_keymap,  KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
Line 95  int rl_catch_sigwinch = 1;
Line 95  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 107  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;
 char *(*rl_completion_word_break_hook)(void) = NULL;  char *(*rl_completion_word_break_hook)(void) = NULL;
 CPPFunction *rl_attempted_completion_function = 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 160  int rl_completion_append_character = ' '
Line 161  int rl_completion_append_character = ' '
   
 static 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 *
Line 187  _get_prompt(EditLine *el __attribute__((
Line 188  _get_prompt(EditLine *el __attribute__((
   
   
 /*  /*
  * generic function for moving around history  
  */  
 static HIST_ENTRY *  
 _move_history(int op)  
 {  
         HistEvent ev;  
         static HIST_ENTRY rl_he;  
   
         if (history(h, &ev, op) != 0)  
                 return NULL;  
   
         rl_he.line = ev.str;  
         rl_he.data = NULL;  
   
         return &rl_he;  
 }  
   
   
 /*  
  * read one key from user defined input function   * read one key from user defined input function
  */   */
 static int  static int
 /*ARGSUSED*/  /*ARGSUSED*/
 _getc_function(EditLine *el __attribute__((__unused__)), char *c)  _getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c)
 {  {
         int i;          int i;
   
         i = (*rl_getc_function)(NULL);          i = (*rl_getc_function)(NULL);
         if (i == -1)          if (i == -1)
                 return 0;                  return 0;
         *c = (char)i;          *c = (wchar_t)i;
         return 1;          return 1;
 }  }
   
Line 267  rl_set_prompt(const char *prompt)
Line 249  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)
                 el_free(rl_prompt);                  el_free(rl_prompt);
Line 361  rl_initialize(void)
Line 343  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.           * Set some readline compatible key-bindings.
          */           */
Line 484  using_history(void)
Line 466  using_history(void)
 {  {
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
           history_offset = history_length;
 }  }
   
   
Line 565  get_history_event(const char *cmd, int *
Line 548  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 575  get_history_event(const char *cmd, int *
Line 558  get_history_event(const char *cmd, int *
                 if (sign)                  if (sign)
                         num = history_length - num + 1;                          num = history_length - num + 1;
   
                 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 1168  void
Line 1151  void
 stifle_history(int max)  stifle_history(int max)
 {  {
         HistEvent ev;          HistEvent ev;
           HIST_ENTRY *he;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if (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 1388  history_get(int num)
Line 1381  history_get(int 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 (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 (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 (history(h, &ev, H_NEXT_EVDATA, num, &she.data))                  goto out;
                 return NULL;  
   
           /* 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;          she.line = ev.str;
   
         /* restore pointer to where it was */          /* restore pointer to where it was */
         (void)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 1418  add_history(const char *line)
Line 1423  add_history(const char *line)
 {  {
         HistEvent ev;          HistEvent ev;
   
         if (line == NULL)  
                 return 0;  
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         (void)history(h, &ev, H_ENTER, line);          if (history(h, &ev, H_ENTER, line) == -1)
         if (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 1518  clear_history(void)
Line 1524  clear_history(void)
                 rl_initialize();                  rl_initialize();
   
         (void)history(h, &ev, H_CLEAR);          (void)history(h, &ev, H_CLEAR);
         history_length = 0;          history_offset = history_length = 0;
 }  }
   
   
Line 1528  clear_history(void)
Line 1534  clear_history(void)
 int  int
 where_history(void)  where_history(void)
 {  {
           return history_offset;
   }
   
   static HIST_ENTRY **_history_listp;
   static HIST_ENTRY *_history_list;
   
   HIST_ENTRY **
   history_list(void)
   {
         HistEvent ev;          HistEvent ev;
         int curr_num, off;          HIST_ENTRY **nlp, *nl;
           int i;
   
         if (history(h, &ev, H_CURR) != 0)          if (history(h, &ev, H_LAST) != 0)
                 return 0;                  return NULL;
         curr_num = ev.num;  
   
         (void)history(h, &ev, H_FIRST);          if ((nlp = el_realloc(_history_listp,
         off = 1;              (size_t)history_length * sizeof(*nlp))) == NULL)
         while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)                  return NULL;
                 off++;          _history_listp = nlp;
   
         return off;          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
  */   */
 HIST_ENTRY *  HIST_ENTRY *
 current_history(void)  current_history(void)
 {  {
           HistEvent ev;
   
           if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0)
                   return NULL;
   
         return _move_history(H_CURR);          rl_he.line = ev.str;
           rl_he.data = NULL;
           return &rl_he;
 }  }
   
   
Line 1588  history_total_bytes(void)
Line 1621  history_total_bytes(void)
 int  int
 history_set_pos(int pos)  history_set_pos(int pos)
 {  {
         HistEvent ev;  
         int curr_num;  
   
         if (pos >= history_length || pos < 0)          if (pos >= history_length || pos < 0)
                 return -1;                  return 0;
   
         (void)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 (history(h, &ev, H_DELDATA, pos, (void **)-1)) {  
                 (void)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 1626  previous_history(void)
Line 1655  previous_history(void)
 HIST_ENTRY *  HIST_ENTRY *
 next_history(void)  next_history(void)
 {  {
           HistEvent ev;
   
           if (history_offset >= history_length)
                   return NULL;
   
           if (history(h, &ev, H_LAST) != 0)
                   return NULL;
   
         return _move_history(H_NEXT);          history_offset++;
           return current_history();
 }  }
   
   
Line 1688  history_search_pos(const char *str,
Line 1725  history_search_pos(const char *str,
                 return -1;                  return -1;
         curr_num = ev.num;          curr_num = ev.num;
   
         if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)          if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0)
                 return -1;                  return -1;
   
         for (;;) {          for (;;) {
Line 1806  _rl_completion_append_character_function
Line 1843  _rl_completion_append_character_function
 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;          char *breakchars;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
Line 1827  rl_complete(int ignore __attribute__((__
Line 1862  rl_complete(int ignore __attribute__((__
         else          else
                 breakchars = rl_basic_word_break_characters;                  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(breakchars, &sprefix_conv),              ct_decode_string(breakchars, &sprefix_conv),
Line 1958  rl_bind_wrapper(EditLine *el __attribute
Line 1995  rl_bind_wrapper(EditLine *el __attribute
   
         _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 1968  rl_bind_wrapper(EditLine *el __attribute
Line 2005  rl_bind_wrapper(EditLine *el __attribute
 }  }
   
 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 2006  rl_callback_read_char(void)
Line 2043  rl_callback_read_char(void)
         }          }
 }  }
   
 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 2015  rl_callback_handler_install(const char *
Line 2052  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);          el_set(e, EL_UNBUFFERED, 0);
Line 2098  rl_stuff_char(int c)
Line 2135  rl_stuff_char(int c)
 }  }
   
 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)();
Line 2112  _rl_event_read_char(EditLine *el, char *
Line 2151  _rl_event_read_char(EditLine *el, char *
                 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, (size_t)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)
Line 2120  _rl_event_read_char(EditLine *el, char *
Line 2159  _rl_event_read_char(EditLine *el, char *
                         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
   
Line 2137  _rl_event_read_char(EditLine *el, char *
Line 2176  _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 2199  rl_completion_matches(const char *str, r
Line 2239  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 2217  rl_completion_matches(const char *str, r
Line 2257  rl_completion_matches(const char *str, r
                 list[0][min] = '\0';                  list[0][min] = '\0';
         }          }
         return list;          return list;
   
 out:  out:
         el_free(list);          el_free(list);
         return NULL;          return NULL;
Line 2321  void
Line 2361  void
 rl_free_line_state(void)  rl_free_line_state(void)
 {  {
 }  }
   
   int
   /*ARGSUSED*/
   rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
   {
           return 0;
   }

Legend:
Removed from v.1.111.2.1  
changed lines
  Added in v.1.138

CVSweb <webmaster@jp.NetBSD.org>