[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.106 and 1.146.2.1

version 1.106, 2012/10/12 23:35:02 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>
   #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;  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 99  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 109  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;
Line 153  int rl_completion_append_character = ' '
Line 162  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 180  _get_prompt(EditLine *el __attribute__((
Line 189  _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)(rl_instream);
         if (i == -1)          if (i == -1)
                 return 0;                  return 0;
         *c = (char)i;          *c = (wchar_t)i;
         return 1;          return 1;
 }  }
   
Line 229  static const char *
Line 219  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;
         (void)snprintf(path, sizeof(path), "%s/.history", p->pw_dir);  
           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 253  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)
                 el_free(rl_prompt);                  el_free(rl_prompt);
Line 293  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)
                 el_set(e, EL_EDITMODE, 0);                  el_set(e, EL_EDITMODE, 0);
Line 324  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 347  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 358  rl_initialize(void)
Line 388  rl_initialize(void)
         _resize_fun(e, &rl_line_buffer);          _resize_fun(e, &rl_line_buffer);
         _rl_update_pos();          _rl_update_pos();
   
         if (rl_startup_hook)          tty_end(e, TCSADRAIN);
                 (*rl_startup_hook)(NULL, 0);  
   
         return 0;          return 0;
 }  }
Line 381  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 413  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';
Line 423  readline(const char *p)
Line 459  readline(const char *p)
         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 439  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 520  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 528  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 620  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 934  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 1122  void
Line 1162  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 1305  read_history(const char *filename)
Line 1355  read_history(const char *filename)
                 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 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 1326  write_history(const char *filename)
Line 1382  write_history(const char *filename)
             (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 1342  history_get(int num)
Line 1420  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 1372  add_history(const char *line)
Line 1462  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 1468  clear_history(void)
Line 1559  clear_history(void)
 {  {
         HistEvent ev;          HistEvent ev;
   
           if (h == NULL || e == NULL)
                   rl_initialize();
   
         (void)history(h, &ev, H_CLEAR);          (void)history(h, &ev, H_CLEAR);
         history_length = 0;          history_offset = history_length = 0;
 }  }
   
   
Line 1479  clear_history(void)
Line 1573  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
Line 1501  where_history(void)
Line 1616  where_history(void)
 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 1539  history_total_bytes(void)
Line 1660  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;
   
         return _move_history(H_PREV);          if (history_offset == 0)
                   return NULL;
   
           if (history(h, &ev, H_LAST) != 0)
                   return NULL;
   
           history_offset--;
           return current_history();
 }  }
   
   
Line 1577  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 1639  history_search_pos(const char *str,
Line 1764  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 1677  filename_completion_function(const char 
Line 1802  filename_completion_function(const char 
  * 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 resets search from start (??? should we do that anyway)   * (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)
Line 1726  _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
Line 1751  _rl_completion_append_character_function
Line 1864  _rl_completion_append_character_function
   
   
 /*  /*
    * 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;          char *breakchars;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
Line 1778  rl_complete(int ignore __attribute__((__
Line 1902  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 1909  rl_bind_wrapper(EditLine *el __attribute
Line 2035  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 1919  rl_bind_wrapper(EditLine *el __attribute
Line 2045  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 1948  rl_callback_read_char(void)
Line 2074  rl_callback_read_char(void)
         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 1966  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
Line 2049  rl_stuff_char(int c)
Line 2176  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 2063  _rl_event_read_char(EditLine *el, char *
Line 2192  _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 2071  _rl_event_read_char(EditLine *el, char *
Line 2200  _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 2088  _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 2104  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, NULL);                  el_get(e, EL_GETTC, "li", rows, (void *)0);
         if (cols)          if (cols)
                 el_get(e, EL_GETTC, "co", cols, NULL);                  el_get(e, EL_GETTC, "co", cols, (void *)0);
 }  }
   
 void  void
Line 2150  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 2168  rl_completion_matches(const char *str, r
Line 2298  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 2272  void
Line 2402  void
 rl_free_line_state(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.106  
changed lines
  Added in v.1.146.2.1

CVSweb <webmaster@jp.NetBSD.org>