[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.71 and 1.87

version 1.71, 2007/05/27 19:45:37 version 1.87, 2009/12/30 23:54:52
Line 15 
Line 15 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. Neither the name of The NetBSD Foundation nor the names of its  
  *    contributors may be used to endorse or promote products derived  
  *    from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS   * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
Line 55  __RCSID("$NetBSD$");
Line 52  __RCSID("$NetBSD$");
 #else  #else
 #include "np/vis.h"  #include "np/vis.h"
 #endif  #endif
 #ifdef HAVE_ALLOCA_H  #include "readline/readline.h"
 #include <alloca.h>  
 #endif  
 #include "el.h"  #include "el.h"
 #include "fcns.h"               /* for EL_NUM_FCNS */  #include "fcns.h"               /* for EL_NUM_FCNS */
 #include "histedit.h"  #include "histedit.h"
 #include "readline/readline.h"  
 #include "filecomplete.h"  #include "filecomplete.h"
   
 void rl_prep_terminal(int);  void rl_prep_terminal(int);
Line 76  void rl_deprep_terminal(void);
Line 70  void rl_deprep_terminal(void);
 /* readline compatibility stuff - look at readline sources/documentation */  /* readline compatibility stuff - look at readline sources/documentation */
 /* to see what these variables mean */  /* to see what these variables mean */
 const char *rl_library_version = "EditLine wrapper";  const char *rl_library_version = "EditLine wrapper";
   int rl_readline_version = RL_READLINE_VERSION;
 static char empty[] = { '\0' };  static char empty[] = { '\0' };
 static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };  static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
 static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',  static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
Line 111  Function *rl_completion_entry_function =
Line 106  Function *rl_completion_entry_function =
 CPPFunction *rl_attempted_completion_function = NULL;  CPPFunction *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;
 Function *rl_getc_function = NULL;  int (*rl_getc_function)(FILE *) = NULL;
 char *rl_terminal_name = NULL;  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;
Line 124  Function *rl_startup_hook = NULL;
Line 119  Function *rl_startup_hook = NULL;
 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;
   
   #ifdef WIDECHAR
   static ct_buffer_t conv;
   #endif
   
 /*  /*
  * The current prompt string.   * The current prompt string.
Line 157  int rl_completion_append_character = ' '
Line 157  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 History *h = NULL;  static TYPE(History) *h = NULL;
 static EditLine *e = NULL;  static EditLine *e = NULL;
 static Function *map[256];  static Function *map[256];
 static jmp_buf topbuf;  static jmp_buf topbuf;
Line 191  _get_prompt(EditLine *el __attribute__((
Line 191  _get_prompt(EditLine *el __attribute__((
 static HIST_ENTRY *  static HIST_ENTRY *
 _move_history(int op)  _move_history(int op)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         static HIST_ENTRY rl_he;          static HIST_ENTRY rl_he;
   
         if (history(h, &ev, op) != 0)          if (FUNW(history)(h, &ev, op) != 0)
                 return (HIST_ENTRY *) NULL;                  return (HIST_ENTRY *) NULL;
   
         rl_he.line = ev.str;          rl_he.line = ct_encode_string(ev.str, &conv);
         rl_he.data = NULL;          rl_he.data = NULL;
   
         return (&rl_he);          return (&rl_he);
Line 213  _getc_function(EditLine *el, char *c)
Line 213  _getc_function(EditLine *el, char *c)
 {  {
         int i;          int i;
   
         i = (*rl_getc_function)(NULL, 0);          i = (*rl_getc_function)(NULL);
         if (i == -1)          if (i == -1)
                 return 0;                  return 0;
         *c = i;          *c = i;
         return 1;          return 1;
 }  }
   
   static const char _dothistory[] = "/.history";
   
   static const char *
   _default_history_file(void)
   {
           struct passwd *p;
           static char path[PATH_MAX];
   
           if (*path)
                   return path;
           if ((p = getpwuid(getuid())) == NULL)
                   return NULL;
           strlcpy(path, p->pw_dir, PATH_MAX);
           strlcat(path, _dothistory, PATH_MAX);
           return path;
   }
   
 /*  /*
  * READLINE compatibility stuff   * READLINE compatibility stuff
  */   */
   
 /*  /*
    * Set the prompt
    */
   int
   rl_set_prompt(const char *prompt)
   {
           char *p;
   
           if (!prompt)
                   prompt = "";
           if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
                   return 0;
           if (rl_prompt)
                   free(rl_prompt);
           rl_prompt = strdup(prompt);
           if (rl_prompt == NULL)
                   return -1;
   
           while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
                   *p = RL_PROMPT_START_IGNORE;
   
           return 0;
   }
   
   /*
  * initialize rl compat stuff   * initialize rl compat stuff
  */   */
 int  int
 rl_initialize(void)  rl_initialize(void)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         const LineInfo *li;          const LineInfo *li;
         int editmode = 1;          int editmode = 1;
         struct termios t;          struct termios t;
Line 239  rl_initialize(void)
Line 279  rl_initialize(void)
         if (e != NULL)          if (e != NULL)
                 el_end(e);                  el_end(e);
         if (h != NULL)          if (h != NULL)
                 history_end(h);                  FUN(history,end)(h);
   
         if (!rl_instream)          if (!rl_instream)
                 rl_instream = stdin;                  rl_instream = stdin;
Line 255  rl_initialize(void)
Line 295  rl_initialize(void)
         e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);          e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
   
         if (!editmode)          if (!editmode)
                 el_set(e, EL_EDITMODE, 0);                  FUN(el,set)(e, EL_EDITMODE, 0);
   
         h = history_init();          h = FUN(history,init)();
         if (!e || !h)          if (!e || !h)
                 return (-1);                  return (-1);
   
         history(h, &ev, H_SETSIZE, INT_MAX);    /* unlimited */          FUNW(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);
Line 271  rl_initialize(void)
Line 311  rl_initialize(void)
                 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() */
         rl_prompt = strdup("");          if (rl_set_prompt("") == -1) {
         if (rl_prompt == NULL) {                  FUN(history,end)(h);
                 history_end(h);  
                 el_end(e);                  el_end(e);
                 return -1;                  return -1;
         }          }
         el_set(e, EL_PROMPT, _get_prompt);          el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
         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 */
Line 331  rl_initialize(void)
Line 370  rl_initialize(void)
 char *  char *
 readline(const char *p)  readline(const char *p)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         const char * volatile prompt = p;          const char * volatile prompt = p;
         int count;          int count;
         const char *ret;          const char *ret;
Line 346  readline(const char *p)
Line 385  readline(const char *p)
         (void)setjmp(topbuf);          (void)setjmp(topbuf);
   
         /* update prompt accordingly to what has been passed */          /* update prompt accordingly to what has been passed */
         if (!prompt)          if (rl_set_prompt(prompt) == -1)
                 prompt = "";                  return NULL;
         if (strcmp(rl_prompt, prompt) != 0) {  
                 free(rl_prompt);  
                 rl_prompt = strdup(prompt);  
                 if (rl_prompt == NULL)  
                         return NULL;  
         }  
   
         if (rl_pre_input_hook)          if (rl_pre_input_hook)
                 (*rl_pre_input_hook)(NULL, 0);                  (*rl_pre_input_hook)(NULL, 0);
Line 385  readline(const char *p)
Line 418  readline(const char *p)
         } else          } else
                 buf = NULL;                  buf = NULL;
   
         history(h, &ev, H_GETSIZE);          FUNW(history)(h, &ev, H_GETSIZE);
         history_length = ev.num;          history_length = ev.num;
   
         return buf;          return buf;
Line 451  _rl_compat_sub(const char *str, const ch
Line 484  _rl_compat_sub(const char *str, const ch
                 } else                  } else
                         *r++ = *s++;                          *r++ = *s++;
         }          }
         *r = 0;          *r = '\0';
         return(result);          return(result);
 }  }
   
Line 465  get_history_event(const char *cmd, int *
Line 498  get_history_event(const char *cmd, int *
         size_t len;          size_t len;
         char    *pat;          char    *pat;
         const char *rptr;          const char *rptr;
         HistEvent ev;          TYPE(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 (history(h, &ev, H_FIRST) != 0)                  if (FUNW(history)(h, &ev, H_FIRST) != 0)
                         return(NULL);                          return(NULL);
                 *cindex = cmd[idx]? (idx + 1):idx;                  *cindex = cmd[idx]? (idx + 1):idx;
                 return(ev.str);                  return ct_encode_string(ev.str, &conv);
         }          }
         sign = 0;          sign = 0;
         if (cmd[idx] == '-') {          if (cmd[idx] == '-') {
Line 531  get_history_event(const char *cmd, int *
Line 564  get_history_event(const char *cmd, int *
                 pat[len] = '\0';                  pat[len] = '\0';
         }          }
   
         if (history(h, &ev, H_CURR) != 0) {          if (FUNW(history)(h, &ev, H_CURR) != 0) {
                 if (pat != last_search_pat)                  if (pat != last_search_pat)
                         free(pat);                          free(pat);
                 return (NULL);                  return (NULL);
Line 550  get_history_event(const char *cmd, int *
Line 583  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 */
                 history(h, &ev, H_FIRST);                  FUNW(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);                          free(pat);
Line 566  get_history_event(const char *cmd, int *
Line 599  get_history_event(const char *cmd, int *
         if (pat != last_search_pat)          if (pat != last_search_pat)
                 free(pat);                  free(pat);
   
         if (history(h, &ev, H_CURR) != 0)          if (FUNW(history)(h, &ev, H_CURR) != 0)
                 return(NULL);                  return(NULL);
         *cindex = idx;          *cindex = idx;
         rptr = ev.str;          rptr = ct_encode_string(ev.str, &conv);
   
         /* roll back to original position */          /* roll back to original position */
         (void)history(h, &ev, H_SET, num);          (void)FUNW(history)(h, &ev, H_SET, num);
   
         return rptr;          return rptr;
 }  }
Line 637  _history_expand_command(const char *comm
Line 670  _history_expand_command(const char *comm
                 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);                          free(aptr);
                   if (*result == NULL)
                           return -1;
                 return(1);                  return(1);
         }          }
   
Line 694  _history_expand_command(const char *comm
Line 729  _history_expand_command(const char *comm
         if (aptr)          if (aptr)
                 free(aptr);                  free(aptr);
   
         if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) {          if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
                 *result = tmp;                  *result = tmp;
                 return(1);                  return(1);
         }          }
Line 704  _history_expand_command(const char *comm
Line 739  _history_expand_command(const char *comm
                         continue;                          continue;
                 else if (*cmd == 'h') {         /* remove trailing path */                  else if (*cmd == 'h') {         /* remove trailing path */
                         if ((aptr = strrchr(tmp, '/')) != NULL)                          if ((aptr = strrchr(tmp, '/')) != NULL)
                                 *aptr = 0;                                  *aptr = '\0';
                 } 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);
Line 713  _history_expand_command(const char *comm
Line 748  _history_expand_command(const char *comm
                         }                          }
                 } else if (*cmd == 'r') {       /* remove trailing suffix */                  } else if (*cmd == 'r') {       /* remove trailing suffix */
                         if ((aptr = strrchr(tmp, '.')) != NULL)                          if ((aptr = strrchr(tmp, '.')) != NULL)
                                 *aptr = 0;                                  *aptr = '\0';
                 } 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);
Line 966  char *
Line 1001  char *
 history_arg_extract(int start, int end, const char *str)  history_arg_extract(int start, int end, const char *str)
 {  {
         size_t  i, len, max;          size_t  i, len, max;
         char    **arr, *result;          char    **arr, *result = NULL;
   
         arr = history_tokenize(str);          arr = history_tokenize(str);
         if (!arr)          if (!arr)
                 return(NULL);                  return NULL;
         if (arr && *arr == NULL) {          if (arr && *arr == NULL)
                 free(arr);                  goto out;
                 return(NULL);  
         }  
   
         for (max = 0; arr[max]; max++)          for (max = 0; arr[max]; max++)
                 continue;                  continue;
         max--;          max--;
   
         if (start == '$')          if (start == '$')
                 start = max;                  start = (int)max;
         if (end == '$')          if (end == '$')
                 end = max;                  end = (int)max;
         if (end < 0)          if (end < 0)
                 end = max + end + 1;                  end = (int)max + end + 1;
         if (start < 0)          if (start < 0)
                 start = end;                  start = end;
   
         if (start < 0 || end < 0 || start > max || end > max || start > end)          if (start < 0 || end < 0 || (size_t)start > max ||
                 return(NULL);              (size_t)end > max || start > end)
                   goto out;
   
         for (i = start, len = 0; i <= end; i++)          for (i = start, len = 0; i <= (size_t)end; i++)
                 len += strlen(arr[i]) + 1;                  len += strlen(arr[i]) + 1;
         len++;          len++;
         result = malloc(len);          result = malloc(len);
         if (result == NULL)          if (result == NULL)
                 return NULL;                  goto out;
   
         for (i = start, len = 0; i <= end; i++) {          for (i = 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 < end)                  if (i < (size_t)end)
                         result[len++] = ' ';                          result[len++] = ' ';
         }          }
         result[len] = 0;          result[len] = '\0';
   
   out:
         for (i = 0; arr[i]; i++)          for (i = 0; arr[i]; i++)
                 free(arr[i]);                  free(arr[i]);
         free(arr);          free(arr);
   
         return(result);          return result;
 }  }
   
 /*  /*
Line 1080  history_tokenize(const char *str)
Line 1115  history_tokenize(const char *str)
 void  void
 stifle_history(int max)  stifle_history(int max)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if (history(h, &ev, H_SETSIZE, max) == 0)          if (FUNW(history)(h, &ev, H_SETSIZE, max) == 0)
                 max_input_history = max;                  max_input_history = max;
 }  }
   
Line 1096  stifle_history(int max)
Line 1131  stifle_history(int max)
 int  int
 unstifle_history(void)  unstifle_history(void)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         int omax;          int omax;
   
         history(h, &ev, H_SETSIZE, INT_MAX);          FUNW(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 1114  history_is_stifled(void)
Line 1149  history_is_stifled(void)
         return (max_input_history != INT_MAX);          return (max_input_history != INT_MAX);
 }  }
   
   static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
   
   int
   history_truncate_file (const char *filename, int nlines)
   {
           int ret = 0;
           FILE *fp, *tp;
           char template[sizeof(_history_tmp_template)];
           char buf[4096];
           int fd;
           char *cp;
           off_t off;
           int count = 0;
           ssize_t left = 0;
   
           if (filename == NULL && (filename = _default_history_file()) == NULL)
                   return errno;
           if ((fp = fopen(filename, "r+")) == NULL)
                   return errno;
           strcpy(template, _history_tmp_template);
           if ((fd = mkstemp(template)) == -1) {
                   ret = errno;
                   goto out1;
           }
   
           if ((tp = fdopen(fd, "r+")) == NULL) {
                   close(fd);
                   ret = errno;
                   goto out2;
           }
   
           for(;;) {
                   if (fread(buf, sizeof(buf), 1, fp) != 1) {
                           if (ferror(fp)) {
                                   ret = errno;
                                   break;
                           }
                           if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
                               (off_t)-1) {
                                   ret = errno;
                                   break;
                           }
                           left = fread(buf, 1, sizeof(buf), fp);
                           if (ferror(fp)) {
                                   ret = errno;
                                   break;
                           }
                           if (left == 0) {
                                   count--;
                                   left = sizeof(buf);
                           } else if (fwrite(buf, (size_t)left, 1, tp) != 1) {
                                   ret = errno;
                                   break;
                           }
                           fflush(tp);
                           break;
                   }
                   if (fwrite(buf, sizeof(buf), 1, tp) != 1) {
                           ret = errno;
                           break;
                   }
                   count++;
           }
           if (ret)
                   goto out3;
           cp = buf + left - 1;
           if(*cp != '\n')
                   cp++;
           for(;;) {
                   while (--cp >= buf) {
                           if (*cp == '\n') {
                                   if (--nlines == 0) {
                                           if (++cp >= buf + sizeof(buf)) {
                                                   count++;
                                                   cp = buf;
                                           }
                                           break;
                                   }
                           }
                   }
                   if (nlines <= 0 || count == 0)
                           break;
                   count--;
                   if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
                           ret = errno;
                           break;
                   }
                   if (fread(buf, sizeof(buf), 1, tp) != 1) {
                           if (ferror(tp)) {
                                   ret = errno;
                                   break;
                           }
                           ret = EAGAIN;
                           break;
                   }
                   cp = buf + sizeof(buf);
           }
   
           if (ret || nlines > 0)
                   goto out3;
   
           if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) {
                   ret = errno;
                   goto out3;
           }
   
           if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
               (off_t)-1) {
                   ret = errno;
                   goto out3;
           }
   
           for(;;) {
                   if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) {
                           if (ferror(fp))
                                   ret = errno;
                           break;
                   }
                   if (fwrite(buf, (size_t)left, 1, fp) != 1) {
                           ret = errno;
                           break;
                   }
           }
           fflush(fp);
           if((off = ftello(fp)) > 0)
                   (void)ftruncate(fileno(fp), off);
   out3:
           fclose(tp);
   out2:
           unlink(template);
   out1:
           fclose(fp);
   
           return ret;
   }
   
   
 /*  /*
  * read history from a file given   * read history from a file given
Line 1121  history_is_stifled(void)
Line 1292  history_is_stifled(void)
 int  int
 read_history(const char *filename)  read_history(const char *filename)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
         return (history(h, &ev, H_LOAD, filename) == -1);          if (filename == NULL && (filename = _default_history_file()) == NULL)
                   return errno;
           return (FUNW(history)(h, &ev, H_LOAD, filename) == -1 ? (errno ? errno : EINVAL) : 0);
 }  }
   
   
Line 1135  read_history(const char *filename)
Line 1308  read_history(const char *filename)
 int  int
 write_history(const char *filename)  write_history(const char *filename)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
         return (history(h, &ev, H_SAVE, filename) == -1);          if (filename == NULL && (filename = _default_history_file()) == NULL)
                   return errno;
           return (FUNW(history)(h, &ev, H_SAVE, filename) == -1 ? (errno ? errno : EINVAL) : 0);
 }  }
   
   
Line 1152  HIST_ENTRY *
Line 1327  HIST_ENTRY *
 history_get(int num)  history_get(int num)
 {  {
         static HIST_ENTRY she;          static HIST_ENTRY she;
         HistEvent ev;          TYPE(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 (history(h, &ev, H_CURR) != 0)          if (FUNW(history)(h, &ev, H_CURR) != 0)
                 return (NULL);                  return (NULL);
         curr_num = ev.num;          curr_num = ev.num;
   
         /* start from most recent */          /* start from the oldest */
         if (history(h, &ev, H_FIRST) != 0)          if (FUNW(history)(h, &ev, H_LAST) != 0)
                 return (NULL);  /* error */                  return (NULL);  /* error */
   
         /* look backwards for event matching specified offset */          /* look forwards for event matching specified offset */
         if (history(h, &ev, H_NEXT_EVENT, num))          if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &she.data))
                 return (NULL);                  return (NULL);
   
         she.line = ev.str;          she.line = ct_encode_string(ev.str, &conv);
         she.data = NULL;  
   
         /* restore pointer to where it was */          /* restore pointer to where it was */
         (void)history(h, &ev, H_SET, curr_num);          (void)FUNW(history)(h, &ev, H_SET, curr_num);
   
         return (&she);          return (&she);
 }  }
Line 1187  history_get(int num)
Line 1361  history_get(int num)
 int  int
 add_history(const char *line)  add_history(const char *line)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         (void)history(h, &ev, H_ENTER, line);          (void)FUNW(history)(h, &ev, H_ENTER, line);
         if (history(h, &ev, H_GETSIZE) == 0)          if (FUNW(history)(h, &ev, H_GETSIZE) == 0)
                 history_length = ev.num;                  history_length = ev.num;
   
         return (!(history_length > 0)); /* return 0 if all is okay */          return (!(history_length > 0)); /* return 0 if all is okay */
Line 1206  add_history(const char *line)
Line 1380  add_history(const char *line)
 HIST_ENTRY *  HIST_ENTRY *
 remove_history(int num)  remove_history(int num)
 {  {
         HIST_ENTRY *she;          HIST_ENTRY *he;
         HistEvent ev;          TYPE(HistEvent) ev;
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if (history(h, &ev, H_DEL, num) != 0)          if ((he = malloc(sizeof(*he))) == NULL)
                 return NULL;                  return NULL;
   
         if ((she = malloc(sizeof(*she))) == NULL)          if (FUNW(history)(h, &ev, H_DELDATA, num, &he->data) != 0) {
                   free(he);
                 return NULL;                  return NULL;
           }
   
         she->line = ev.str;          he->line = ct_encode_string(ev.str, &conv);
         she->data = NULL;          if (FUNW(history)(h, &ev, H_GETSIZE) == 0)
                   history_length = ev.num;
   
         return she;          return he;
 }  }
   
   
 /*  /*
    * replace the line and data of the num-th entry
    */
   HIST_ENTRY *
   replace_history_entry(int num, const char *line, histdata_t data)
   {
           HIST_ENTRY *he;
           TYPE(HistEvent) ev;
           int curr_num;
   
           if (h == NULL || e == NULL)
                   rl_initialize();
   
           /* save current position */
           if (FUNW(history)(h, &ev, H_CURR) != 0)
                   return NULL;
           curr_num = ev.num;
   
           /* start from the oldest */
           if (FUNW(history)(h, &ev, H_LAST) != 0)
                   return NULL;    /* error */
   
           if ((he = malloc(sizeof(*he))) == NULL)
                   return NULL;
   
           /* look forwards for event matching specified offset */
           if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &he->data))
                   goto out;
   
           he->line = strdup(ct_encode_string(ev.str, &e->el_scratch));
           if (he->line == NULL)
                   goto out;
   
           if (FUNW(history)(h, &ev, H_REPLACE, line, data))
                   goto out;
   
           /* restore pointer to where it was */
           if (FUNW(history)(h, &ev, H_SET, curr_num))
                   goto out;
   
           return he;
   out:
           free(he);
           return NULL;
   }
   
   /*
  * clear the history list - delete all entries   * clear the history list - delete all entries
  */   */
 void  void
 clear_history(void)  clear_history(void)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
   
         history(h, &ev, H_CLEAR);          FUNW(history)(h, &ev, H_CLEAR);
           history_length = 0;
 }  }
   
   
Line 1243  clear_history(void)
Line 1467  clear_history(void)
 int  int
 where_history(void)  where_history(void)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         int curr_num, off;          int curr_num, off;
   
         if (history(h, &ev, H_CURR) != 0)          if (FUNW(history)(h, &ev, H_CURR) != 0)
                 return (0);                  return (0);
         curr_num = ev.num;          curr_num = ev.num;
   
         history(h, &ev, H_FIRST);          FUNW(history)(h, &ev, H_FIRST);
         off = 1;          off = 1;
         while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)          while (ev.num != curr_num && FUNW(history)(h, &ev, H_NEXT) == 0)
                 off++;                  off++;
   
         return (off);          return (off);
Line 1276  current_history(void)
Line 1500  current_history(void)
 int  int
 history_total_bytes(void)  history_total_bytes(void)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         int curr_num, size;          int curr_num;
           size_t size;
   
         if (history(h, &ev, H_CURR) != 0)          if (FUNW(history)(h, &ev, H_CURR) != 0)
                 return (-1);                  return (-1);
         curr_num = ev.num;          curr_num = ev.num;
   
         history(h, &ev, H_FIRST);          FUNW(history)(h, &ev, H_FIRST);
         size = 0;          size = 0;
         do          do
                 size += strlen(ev.str);                  size += Strlen(ev.str) * sizeof(*ev.str);
         while (history(h, &ev, H_NEXT) == 0);          while (FUNW(history)(h, &ev, H_NEXT) == 0);
   
         /* get to the same position as before */          /* get to the same position as before */
         history(h, &ev, H_PREV_EVENT, curr_num);          FUNW(history)(h, &ev, H_PREV_EVENT, curr_num);
   
         return (size);          return (int)(size);
 }  }
   
   
Line 1302  history_total_bytes(void)
Line 1527  history_total_bytes(void)
 int  int
 history_set_pos(int pos)  history_set_pos(int pos)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         int curr_num;          int curr_num;
   
         if (pos > history_length || pos < 0)          if (pos >= history_length || pos < 0)
                 return (-1);                  return (-1);
   
         history(h, &ev, H_CURR);          FUNW(history)(h, &ev, H_CURR);
         curr_num = ev.num;          curr_num = ev.num;
   
         if (history(h, &ev, H_SET, pos)) {          /*
                 history(h, &ev, H_SET, curr_num);           * use H_DELDATA to set to nth history (without delete) by passing
            * (void **)-1
            */
           if (FUNW(history)(h, &ev, H_DELDATA, pos, (void **)-1)) {
                   FUNW(history)(h, &ev, H_SET, curr_num);
                 return(-1);                  return(-1);
         }          }
         return (0);          return (0);
Line 1347  next_history(void)
Line 1576  next_history(void)
 int  int
 history_search(const char *str, int direction)  history_search(const char *str, int direction)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
         const char *strp;          const Char *strp;
           const Char *wstr;
         int curr_num;          int curr_num;
   
         if (history(h, &ev, H_CURR) != 0)          if (FUNW(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, str)) != NULL)                  if ((strp = Strstr(ev.str, wstr)) != NULL)
                         return (int) (strp - ev.str);                          return (int) (strp - ev.str);
                 if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)                  if (FUNW(history)(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
                         break;                          break;
         }          }
         history(h, &ev, H_SET, curr_num);          FUNW(history)(h, &ev, H_SET, curr_num);
         return (-1);          return (-1);
 }  }
   
Line 1372  history_search(const char *str, int dire
Line 1603  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)
 {  {
         HistEvent ev;          TYPE(HistEvent) ev;
   
         return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str));          return (FUNW(history)(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str));
 }  }
   
   
Line 1387  int
Line 1618  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)
 {  {
         HistEvent ev;          TYPE(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 (history(h, &ev, H_CURR) != 0)          if (FUNW(history)(h, &ev, H_CURR) != 0)
                 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) != 0 || FUNW(history)(h, &ev, H_CURR) != 0)
                 return (-1);                  return (-1);
   
           wstr = ct_decode_string(str, &conv);
         for (;;) {          for (;;) {
                 if (strstr(ev.str, str))                  if (Strstr(ev.str, wstr))
                         return (off);                          return (off);
                 if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)                  if (FUNW(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 */
         history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);          FUNW(history)(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
   
         return (-1);          return (-1);
 }  }
Line 1458  username_completion_function(const char 
Line 1690  username_completion_function(const char 
   
         if (pwd == NULL) {          if (pwd == NULL) {
                 endpwent();                  endpwent();
                 return (NULL);                  return NULL;
         }          }
         return (strdup(pwd->pw_name));          return strdup(pwd->pw_name);
 }  }
   
   
Line 1484  void
Line 1716  void
 rl_display_match_list(char **matches, int len, int max)  rl_display_match_list(char **matches, int len, int max)
 {  {
   
         fn_display_match_list(e, matches, len, max);          fn_display_match_list(e, matches, (size_t)len, (size_t)max);
 }  }
   
 static const char *  static const char *
Line 1493  _rl_completion_append_character_function
Line 1725  _rl_completion_append_character_function
     __attribute__((__unused__)))      __attribute__((__unused__)))
 {  {
         static char buf[2];          static char buf[2];
         buf[1] = rl_completion_append_character;          buf[0] = rl_completion_append_character;
           buf[1] = '\0';
         return buf;          return buf;
 }  }
   
Line 1505  _rl_completion_append_character_function
Line 1738  _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;
   #endif
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
Line 1520  rl_complete(int ignore __attribute__((__
Line 1757  rl_complete(int ignore __attribute__((__
         return fn_complete(e,          return fn_complete(e,
             (CPFunction *)rl_completion_entry_function,              (CPFunction *)rl_completion_entry_function,
             rl_attempted_completion_function,              rl_attempted_completion_function,
             rl_basic_word_break_characters, rl_special_prefixes,              ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
             _rl_completion_append_character_function, rl_completion_query_items,              ct_decode_string(rl_special_prefixes, &sprefix_conv),
               _rl_completion_append_character_function,
               (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 1542  _el_rl_complete(EditLine *el __attribute
Line 1781  _el_rl_complete(EditLine *el __attribute
  * bind key c to readline-type function func   * bind key c to readline-type function func
  */   */
 int  int
 rl_bind_key(int c, int func(int, int))  rl_bind_key(int c, rl_command_func_t *func)
 {  {
         int retval = -1;          int retval = -1;
   
Line 1609  rl_insert(int count, int c)
Line 1848  rl_insert(int count, int c)
         return (0);          return (0);
 }  }
   
   int
   rl_insert_text(const char *text)
   {
           if (!text || *text == 0)
                   return (0);
   
           if (h == NULL || e == NULL)
                   rl_initialize();
   
           if (el_insertstr(e, text) < 0)
                   return (0);
           return (int)strlen(text);
   }
   
 /*ARGSUSED*/  /*ARGSUSED*/
 int  int
 rl_newline(int count, int c)  rl_newline(int count, int c)
Line 1641  int
Line 1894  int
 rl_add_defun(const char *name, Function *fun, int c)  rl_add_defun(const char *name, Function *fun, int c)
 {  {
         char dest[8];          char dest[8];
         if (c >= sizeof(map) / sizeof(map[0]) || c < 0)          if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
                 return -1;                  return -1;
         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);
Line 1672  rl_callback_read_char()
Line 1925  rl_callback_read_char()
                 } 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, VCPFunction *linefunc)
 {  {
         if (e == NULL) {          if (e == NULL) {
                 rl_initialize();                  rl_initialize();
         }          }
         if (rl_prompt)          (void)rl_set_prompt(prompt);
                 free(rl_prompt);  
         rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL;  
         rl_linefunc = linefunc;          rl_linefunc = linefunc;
         el_set(e, EL_UNBUFFERED, 1);          el_set(e, EL_UNBUFFERED, 1);
 }  }
Line 1693  void 
Line 1944  void 
 rl_callback_handler_remove(void)  rl_callback_handler_remove(void)
 {  {
         el_set(e, EL_UNBUFFERED, 0);          el_set(e, EL_UNBUFFERED, 0);
           rl_linefunc = NULL;
 }  }
   
 void  void
Line 1771  rl_stuff_char(int c)
Line 2023  rl_stuff_char(int c)
 static int  static int
 _rl_event_read_char(EditLine *el, char *cp)  _rl_event_read_char(EditLine *el, char *cp)
 {  {
         int     n, num_read = 0;          int     n;
           ssize_t num_read = 0;
   
         *cp = 0;          *cp = '\0';
         while (rl_event_hook) {          while (rl_event_hook) {
   
                 (*rl_event_hook)();                  (*rl_event_hook)();
Line 1807  _rl_event_read_char(EditLine *el, char *
Line 2060  _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);
         return(num_read);          return (int)num_read;
 }  }
   
 static void  static void
Line 1815  _rl_update_pos(void)
Line 2068  _rl_update_pos(void)
 {  {
         const LineInfo *li = el_line(e);          const LineInfo *li = el_line(e);
   
         rl_point = li->cursor - li->buffer;          rl_point = (int)(li->cursor - li->buffer);
         rl_end = li->lastchar - li->buffer;          rl_end = (int)(li->lastchar - li->buffer);
 }  }
   
 void  void
Line 1850  rl_completion_matches(const char *str, r
Line 2103  rl_completion_matches(const char *str, r
                 return NULL;                  return NULL;
   
         while ((match = (*fun)(str, (int)(len - 1))) != NULL) {          while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
                   list[len++] = match;
                 if (len == max) {                  if (len == max) {
                         char **nl;                          char **nl;
                         max += 10;                          max += 10;
Line 1857  rl_completion_matches(const char *str, r
Line 2111  rl_completion_matches(const char *str, r
                                 goto out;                                  goto out;
                         list = nl;                          list = nl;
                 }                  }
                 list[len++] = match;  
         }          }
         if (len == 1)          if (len == 1)
                 goto out;                  goto out;
Line 1899  rl_filename_completion_function (const c
Line 2152  rl_filename_completion_function (const c
         return fn_filename_completion_function(text, state);          return fn_filename_completion_function(text, state);
 }  }
   
   void
   rl_forced_update_display(void)
   {
           el_set(e, EL_REFRESH);
   }
   
 int  int
 _rl_abort_internal(void)  _rl_abort_internal(void)
 {  {
Line 1913  _rl_qsort_string_compare(char **s1, char
Line 2172  _rl_qsort_string_compare(char **s1, char
         return strcoll(*s1, *s2);          return strcoll(*s1, *s2);
 }  }
   
   HISTORY_STATE *
   history_get_history_state(void)
   {
           HISTORY_STATE *hs;
   
           if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL)
                   return (NULL);
           hs->length = history_length;
           return (hs);
   }
   
 int  int
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_kill_text(int from, int to)  rl_kill_text(int from, int to)
Line 1947  rl_generic_bind(int type, const char * k
Line 2217  rl_generic_bind(int type, const char * k
   
 int  int
 /*ARGSUSED*/  /*ARGSUSED*/
 rl_bind_key_in_map(int key, Function *fun, Keymap k)  rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k)
 {  {
         return 0;          return 0;
 }  }
   
   /* unsupported, but needed by python */
   void
   rl_cleanup_after_signal(void)
   {
   }

Legend:
Removed from v.1.71  
changed lines
  Added in v.1.87

CVSweb <webmaster@jp.NetBSD.org>