[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.41 and 1.65

version 1.41, 2003/11/01 23:39:22 version 1.65, 2006/03/18 19:22:59
Line 61  __RCSID("$NetBSD$");
Line 61  __RCSID("$NetBSD$");
 #ifdef HAVE_ALLOCA_H  #ifdef HAVE_ALLOCA_H
 #include <alloca.h>  #include <alloca.h>
 #endif  #endif
 #include "histedit.h"  
 #include "readline/readline.h"  
 #include "el.h"  #include "el.h"
 #include "tokenizer.h"  
 #include "fcns.h"               /* for EL_NUM_FCNS */  #include "fcns.h"               /* for EL_NUM_FCNS */
   #include "histedit.h"
   #include "readline/readline.h"
   #include "filecomplete.h"
   
 /* for rl_complete() */  /* for rl_complete() */
 #define TAB             '\r'  #define TAB             '\r'
Line 86  FILE *rl_outstream = NULL;
Line 86  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;
 VFunction *rl_linefunc = NULL;  VCPFunction *rl_linefunc = NULL;
 int rl_done = 0;  int rl_done = 0;
 VFunction *rl_event_hook = NULL;  VFunction *rl_event_hook = NULL;
   
Line 142  int rl_completion_query_items = 100;
Line 142  int rl_completion_query_items = 100;
  * in the parsed text when it is passed to the completion function.   * in the parsed text when it is passed to the completion function.
  * Shell uses this to help determine what kind of completing to do.   * Shell uses this to help determine what kind of completing to do.
  */   */
 char *rl_special_prefixes = (char *)NULL;  char *rl_special_prefixes = NULL;
   
 /*  /*
  * This is the character appended to the completed words if at the end of   * This is the character appended to the completed words if at the end of
Line 152  int rl_completion_append_character = ' '
Line 152  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 */
   
 /* if not zero, non-unique completions always show list of possible matches */  
 static int _rl_complete_show_all = 0;  
   
 static History *h = NULL;  static History *h = NULL;
 static EditLine *e = NULL;  static EditLine *e = NULL;
 static Function *map[256];  static Function *map[256];
 static int el_rl_complete_cmdnum = 0;  
   
 /* 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 char             *_get_prompt(EditLine *);  static char             *_get_prompt(EditLine *);
   static int               _getc_function(EditLine *, char *);
 static HIST_ENTRY       *_move_history(int);  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_complete_internal(int);  
 static int               _rl_qsort_string_compare(const void *, const void *);  
 static int               _rl_event_read_char(EditLine *, char *);  static int               _rl_event_read_char(EditLine *, char *);
   static void              _rl_update_pos(void);
   
   
 /* ARGSUSED */  /* ARGSUSED */
Line 202  _move_history(int op)
Line 199  _move_history(int op)
   
   
 /*  /*
    * read one key from user defined input function
    */
   static int
   /*ARGSUSED*/
   _getc_function(EditLine *el, char *c)
   {
           int i;
   
           i = (*rl_getc_function)(NULL, 0);
           if (i == -1)
                   return 0;
           *c = i;
           return 1;
   }
   
   
   /*
  * READLINE compatibility stuff   * READLINE compatibility stuff
  */   */
   
Line 213  rl_initialize(void)
Line 227  rl_initialize(void)
 {  {
         HistEvent ev;          HistEvent ev;
         const LineInfo *li;          const LineInfo *li;
         int i;  
         int editmode = 1;          int editmode = 1;
         struct termios t;          struct termios t;
   
Line 247  rl_initialize(void)
Line 260  rl_initialize(void)
         max_input_history = INT_MAX;          max_input_history = INT_MAX;
         el_set(e, EL_HIST, history, h);          el_set(e, EL_HIST, history, h);
   
           /* setup getc function if valid */
           if (rl_getc_function)
                   el_set(e, EL_GETCFN, _getc_function);
   
         /* for proper prompt printing in readline() */          /* for proper prompt printing in readline() */
         rl_prompt = strdup("");          rl_prompt = strdup("");
         if (rl_prompt == NULL) {          if (rl_prompt == NULL) {
Line 273  rl_initialize(void)
Line 290  rl_initialize(void)
             "ReadLine compatible completion function",              "ReadLine compatible completion function",
             _el_rl_complete);              _el_rl_complete);
         el_set(e, EL_BIND, "^I", "rl_complete", NULL);          el_set(e, EL_BIND, "^I", "rl_complete", NULL);
   
         /*          /*
          * Find out where the rl_complete function was added; this is           * Send TSTP when ^Z is pressed.
          * used later to detect that lastcmd was also rl_complete.  
          */           */
         for(i=EL_NUM_FCNS; i < e->el_map.nfunc; i++) {          el_set(e, EL_ADDFN, "rl_tstp",
                 if (e->el_map.func[i] == _el_rl_complete) {              "ReadLine compatible suspend function",
                         el_rl_complete_cmdnum = i;              _el_rl_tstp);
                         break;          el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
                 }  
         }  
   
         /* read settings from configuration file */          /* read settings from configuration file */
         el_source(e, NULL);          el_source(e, NULL);
Line 294  rl_initialize(void)
Line 309  rl_initialize(void)
         li = el_line(e);          li = el_line(e);
         /* a cheesy way to get rid of const cast. */          /* a cheesy way to get rid of const cast. */
         rl_line_buffer = memchr(li->buffer, *li->buffer, 1);          rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
         rl_point = rl_end = 0;          _rl_update_pos();
   
         if (rl_startup_hook)          if (rl_startup_hook)
                 (*rl_startup_hook)(NULL, 0);                  (*rl_startup_hook)(NULL, 0);
Line 713  _history_expand_command(const char *comm
Line 728  _history_expand_command(const char *comm
                                 what = realloc(from, size);                                  what = realloc(from, size);
                                 if (what == NULL) {                                  if (what == NULL) {
                                         free(from);                                          free(from);
                                           free(tmp);
                                         return 0;                                          return 0;
                                 }                                  }
                                 len = 0;                                  len = 0;
Line 725  _history_expand_command(const char *comm
Line 741  _history_expand_command(const char *comm
                                                                 (size <<= 1));                                                                  (size <<= 1));
                                                 if (nwhat == NULL) {                                                  if (nwhat == NULL) {
                                                         free(what);                                                          free(what);
                                                           free(tmp);
                                                         return 0;                                                          return 0;
                                                 }                                                  }
                                                 what = nwhat;                                                  what = nwhat;
Line 737  _history_expand_command(const char *comm
Line 754  _history_expand_command(const char *comm
                                         free(what);                                          free(what);
                                         if (search) {                                          if (search) {
                                                 from = strdup(search);                                                  from = strdup(search);
                                                 if (from == NULL)                                                  if (from == NULL) {
                                                           free(tmp);
                                                         return 0;                                                          return 0;
                                                   }
                                         } else {                                          } else {
                                                 from = NULL;                                                  from = NULL;
                                                   free(tmp);
                                                 return (-1);                                                  return (-1);
                                         }                                          }
                                 }                                  }
Line 752  _history_expand_command(const char *comm
Line 772  _history_expand_command(const char *comm
                                 with = realloc(to, size);                                  with = realloc(to, size);
                                 if (with == NULL) {                                  if (with == NULL) {
                                         free(to);                                          free(to);
                                           free(tmp);
                                         return -1;                                          return -1;
                                 }                                  }
                                 len = 0;                                  len = 0;
Line 763  _history_expand_command(const char *comm
Line 784  _history_expand_command(const char *comm
                                                 nwith = realloc(with, size);                                                  nwith = realloc(with, size);
                                                 if (nwith == NULL) {                                                  if (nwith == NULL) {
                                                         free(with);                                                          free(with);
                                                           free(tmp);
                                                         return -1;                                                          return -1;
                                                 }                                                  }
                                                 with = nwith;                                                  with = nwith;
Line 831  history_expand(char *str, char **output)
Line 853  history_expand(char *str, char **output)
                         return 0;                          return 0;
         }          }
   
 #define ADD_STRING(what, len)                                           \  #define ADD_STRING(what, len, fr)                                       \
         {                                                               \          {                                                               \
                 if (idx + len + 1 > size) {                             \                  if (idx + len + 1 > size) {                             \
                         char *nresult = realloc(result, (size += len + 1));\                          char *nresult = realloc(result, (size += len + 1));\
                         if (nresult == NULL) {                          \                          if (nresult == NULL) {                          \
                                 free(*output);                          \                                  free(*output);                          \
                                   if (/*CONSTCOND*/fr)                    \
                                           free(tmp);                      \
                                 return 0;                               \                                  return 0;                               \
                         }                                               \                          }                                               \
                         result = nresult;                               \                          result = nresult;                               \
Line 848  history_expand(char *str, char **output)
Line 872  history_expand(char *str, char **output)
   
         result = NULL;          result = NULL;
         size = idx = 0;          size = idx = 0;
           tmp = NULL;
         for (i = 0; str[i];) {          for (i = 0; str[i];) {
                 int qchar, loop_again;                  int qchar, loop_again;
                 size_t len, start, j;                  size_t len, start, j;
Line 885  loop:
Line 910  loop:
                         goto loop;                          goto loop;
                 }                  }
                 len = i - start;                  len = i - start;
                 tmp = &str[start];                  ADD_STRING(&str[start], len, 0);
                 ADD_STRING(tmp, len);  
   
                 if (str[i] == '\0' || str[i] != history_expansion_char) {                  if (str[i] == '\0' || str[i] != history_expansion_char) {
                         len = j - i;                          len = j - i;
                         tmp = &str[i];                          ADD_STRING(&str[i], len, 0);
                         ADD_STRING(tmp, len);  
                         if (start == 0)                          if (start == 0)
                                 ret = 0;                                  ret = 0;
                         else                          else
                                 ret = 1;                                  ret = 1;
                         break;                          break;
                 }                  }
                   if (tmp) {
                           free(tmp);
                           tmp = NULL;
                   }
                 ret = _history_expand_command (str, i, (j - i), &tmp);                  ret = _history_expand_command (str, i, (j - i), &tmp);
                 if (ret > 0 && tmp) {                  if (ret > 0 && tmp) {
                         len = strlen(tmp);                          len = strlen(tmp);
                         ADD_STRING(tmp, len);                          ADD_STRING(tmp, len, 1);
                         free(tmp);                          free(tmp);
                           tmp = NULL;
                 }                  }
                 i = j;                  i = j;
         }          }
Line 1090  read_history(const char *filename)
Line 1118  read_history(const char *filename)
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
         return (history(h, &ev, H_LOAD, filename));          return (history(h, &ev, H_LOAD, filename) == -1);
 }  }
   
   
Line 1104  write_history(const char *filename)
Line 1132  write_history(const char *filename)
   
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
         return (history(h, &ev, H_SAVE, filename));          return (history(h, &ev, H_SAVE, filename) == -1);
 }  }
   
   
Line 1166  add_history(const char *line)
Line 1194  add_history(const char *line)
   
   
 /*  /*
    * remove the specified entry from the history list and return it.
    */
   HIST_ENTRY *
   remove_history(int num)
   {
           static HIST_ENTRY she;
           HistEvent ev;
   
           if (h == NULL || e == NULL)
                   rl_initialize();
   
           if (history(h, &ev, H_DEL, num) != 0)
                   return NULL;
   
           she.line = ev.str;
           she.data = NULL;
   
           return &she;
   }
   
   
   /*
  * clear the history list - delete all entries   * clear the history list - delete all entries
  */   */
 void  void
Line 1358  history_search_pos(const char *str,
Line 1408  history_search_pos(const char *str,
 /********************************/  /********************************/
 /* completion functions */  /* completion functions */
   
 /*  
  * does tilde expansion of strings of type ``~user/foo''  
  * if ``user'' isn't valid user name or ``txt'' doesn't start  
  * w/ '~', returns pointer to strdup()ed copy of ``txt''  
  *  
  * it's callers's responsibility to free() returned string  
  */  
 char *  char *
 tilde_expand(char *txt)  tilde_expand(char *name)
 {  {
         struct passwd *pass;          return fn_tilde_expand(name);
         char *temp;  
         size_t len = 0;  
   
         if (txt[0] != '~')  
                 return (strdup(txt));  
   
         temp = strchr(txt + 1, '/');  
         if (temp == NULL) {  
                 temp = strdup(txt + 1);  
                 if (temp == NULL)  
                         return NULL;  
         } else {  
                 len = temp - txt + 1;   /* text until string after slash */  
                 temp = malloc(len);  
                 if (temp == NULL)  
                         return NULL;  
                 (void)strncpy(temp, txt + 1, len - 2);  
                 temp[len - 2] = '\0';  
         }  
         pass = getpwnam(temp);  
         free(temp);             /* value no more needed */  
         if (pass == NULL)  
                 return (strdup(txt));  
   
         /* update pointer txt to point at string immedially following */  
         /* first slash */  
         txt += len;  
   
         temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);  
         if (temp == NULL)  
                 return NULL;  
         (void)sprintf(temp, "%s/%s", pass->pw_dir, txt);  
   
         return (temp);  
 }  }
   
   
 /*  
  * return first found file name starting by the ``text'' or NULL if no  
  * such file can be found  
  * value of ``state'' is ignored  
  *  
  * it's caller's responsibility to free returned string  
  */  
 char *  char *
 filename_completion_function(const char *text, int state)  filename_completion_function(const char *name, int state)
 {  {
         static DIR *dir = NULL;          return fn_filename_completion_function(name, state);
         static char *filename = NULL, *dirname = NULL;  
         static size_t filename_len = 0;  
         struct dirent *entry;  
         char *temp;  
         size_t len;  
   
         if (state == 0 || dir == NULL) {  
                 temp = strrchr(text, '/');  
                 if (temp) {  
                         char *nptr;  
                         temp++;  
                         nptr = realloc(filename, strlen(temp) + 1);  
                         if (nptr == NULL) {  
                                 free(filename);  
                                 return NULL;  
                         }  
                         filename = nptr;  
                         (void)strcpy(filename, temp);  
                         len = temp - text;      /* including last slash */  
                         nptr = realloc(dirname, len + 1);  
                         if (nptr == NULL) {  
                                 free(filename);  
                                 return NULL;  
                         }  
                         dirname = nptr;  
                         (void)strncpy(dirname, text, len);  
                         dirname[len] = '\0';  
                 } else {  
                         filename = strdup(text);  
                         if (filename == NULL)  
                                 return NULL;  
                         dirname = NULL;  
                 }  
   
                 /* support for ``~user'' syntax */  
                 if (dirname && *dirname == '~') {  
                         char *nptr;  
                         temp = tilde_expand(dirname);  
                         if (temp == NULL)  
                                 return NULL;  
                         nptr = realloc(dirname, strlen(temp) + 1);  
                         if (nptr == NULL) {  
                                 free(dirname);  
                                 return NULL;  
                         }  
                         dirname = nptr;  
                         (void)strcpy(dirname, temp);    /* safe */  
                         free(temp);     /* no longer needed */  
                 }  
                 /* will be used in cycle */  
                 filename_len = strlen(filename);  
                 if (filename_len == 0)  
                         return (NULL);  /* no expansion possible */  
   
                 if (dir != NULL) {  
                         (void)closedir(dir);  
                         dir = NULL;  
                 }  
                 dir = opendir(dirname ? dirname : ".");  
                 if (!dir)  
                         return (NULL);  /* cannot open the directory */  
         }  
         /* find the match */  
         while ((entry = readdir(dir)) != NULL) {  
                 /* otherwise, get first entry where first */  
                 /* filename_len characters are equal      */  
                 if (entry->d_name[0] == filename[0]  
 #if defined(__SVR4) || defined(__linux__)  
                     && strlen(entry->d_name) >= filename_len  
 #else  
                     && entry->d_namlen >= filename_len  
 #endif  
                     && strncmp(entry->d_name, filename,  
                         filename_len) == 0)  
                         break;  
         }  
   
         if (entry) {            /* match found */  
   
                 struct stat stbuf;  
 #if defined(__SVR4) || defined(__linux__)  
                 len = strlen(entry->d_name) +  
 #else  
                 len = entry->d_namlen +  
 #endif  
                     ((dirname) ? strlen(dirname) : 0) + 1 + 1;  
                 temp = malloc(len);  
                 if (temp == NULL)  
                         return NULL;  
                 (void)sprintf(temp, "%s%s",  
                     dirname ? dirname : "", entry->d_name);     /* safe */  
   
                 /* test, if it's directory */  
                 if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))  
                         strcat(temp, "/");      /* safe */  
         } else {  
                 (void)closedir(dir);  
                 dir = NULL;  
                 temp = NULL;  
         }  
   
         return (temp);  
 }  }
   
   
 /*  /*
  * a completion generator for usernames; returns _first_ username   * a completion generator for usernames; returns _first_ username
  * which starts with supplied text   * which starts with supplied text
Line 1532  filename_completion_function(const char 
Line 1430  filename_completion_function(const char 
 char *  char *
 username_completion_function(const char *text, int state)  username_completion_function(const char *text, int state)
 {  {
         struct passwd *pwd;          struct passwd *pwd, pwres;
           char pwbuf[1024];
   
         if (text[0] == '\0')          if (text[0] == '\0')
                 return (NULL);                  return (NULL);
Line 1543  username_completion_function(const char 
Line 1442  username_completion_function(const char 
         if (state == 0)          if (state == 0)
                 setpwent();                  setpwent();
   
         while ((pwd = getpwent()) && text[0] == pwd->pw_name[0]          while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0
               && pwd != NULL && text[0] == pwd->pw_name[0]
             && strcmp(text, pwd->pw_name) == 0);              && strcmp(text, pwd->pw_name) == 0);
   
         if (pwd == NULL) {          if (pwd == NULL) {
Line 1555  username_completion_function(const char 
Line 1455  username_completion_function(const char 
   
   
 /*  /*
  * el-compatible wrapper around rl_complete; needed for key binding   * el-compatible wrapper to send TSTP on ^Z
  */   */
 /* ARGSUSED */  /* ARGSUSED */
 static unsigned char  static unsigned char
 _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)  _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
 {  
         return (unsigned char) rl_complete(0, ch);  
 }  
   
   
 /*  
  * returns list of completions for text given  
  */  
 char **  
 completion_matches(const char *text, CPFunction *genfunc)  
 {  
         char **match_list = NULL, *retstr, *prevstr;  
         size_t match_list_len, max_equal, which, i;  
         size_t matches;  
   
         if (h == NULL || e == NULL)  
                 rl_initialize();  
   
         matches = 0;  
         match_list_len = 1;  
         while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {  
                 /* allow for list terminator here */  
                 if (matches + 3 >= match_list_len) {  
                         char **nmatch_list;  
                         while (matches + 3 >= match_list_len)  
                                 match_list_len <<= 1;  
                         nmatch_list = realloc(match_list,  
                             match_list_len * sizeof(char *));  
                         if (nmatch_list == NULL) {  
                                 free(match_list);  
                                 return NULL;  
                         }  
                         match_list = nmatch_list;  
   
                 }  
                 match_list[++matches] = retstr;  
         }  
   
         if (!match_list)  
                 return NULL;    /* nothing found */  
   
         /* find least denominator and insert it to match_list[0] */  
         which = 2;  
         prevstr = match_list[1];  
         max_equal = strlen(prevstr);  
         for (; which <= matches; which++) {  
                 for (i = 0; i < max_equal &&  
                     prevstr[i] == match_list[which][i]; i++)  
                         continue;  
                 max_equal = i;  
         }  
   
         retstr = malloc(max_equal + 1);  
         if (retstr == NULL) {  
                 free(match_list);  
                 return NULL;  
         }  
         (void)strncpy(retstr, match_list[1], max_equal);  
         retstr[max_equal] = '\0';  
         match_list[0] = retstr;  
   
         /* add NULL as last pointer to the array */  
         match_list[matches + 1] = (char *) NULL;  
   
         return (match_list);  
 }  
   
 /*  
  * Sort function for qsort(). Just wrapper around strcasecmp().  
  */  
 static int  
 _rl_qsort_string_compare(i1, i2)  
         const void *i1, *i2;  
 {  {
         const char *s1 = ((const char * const *)i1)[0];          (void)kill(0, SIGTSTP);
         const char *s2 = ((const char * const *)i2)[0];          return CC_NORM;
   
         return strcasecmp(s1, s2);  
 }  }
   
 /*  /*
Line 1646  _rl_qsort_string_compare(i1, i2)
Line 1471  _rl_qsort_string_compare(i1, i2)
  * 'max' is maximum length of string in 'matches'.   * 'max' is maximum length of string in 'matches'.
  */   */
 void  void
 rl_display_match_list (matches, len, max)  rl_display_match_list(char **matches, int len, int max)
      char **matches;  
      int len, max;  
 {  {
         int i, idx, limit, count;  
         int screenwidth = e->el_term.t_size.h;  
   
         /*          fn_display_match_list(e, matches, len, max);
          * Find out how many entries can be put on one line, count  
          * with two spaces between strings.  
          */  
         limit = screenwidth / (max + 2);  
         if (limit == 0)  
                 limit = 1;  
   
         /* how many lines of output */  
         count = len / limit;  
         if (count * limit < len)  
                 count++;  
   
         /* Sort the items if they are not already sorted. */  
         qsort(&matches[1], (size_t)(len - 1), sizeof(char *),  
             _rl_qsort_string_compare);  
   
         idx = 1;  
         for(; count > 0; count--) {  
                 for(i = 0; i < limit && matches[idx]; i++, idx++)  
                         (void)fprintf(e->el_outfile, "%-*s  ", max,  
                             matches[idx]);  
                 (void)fprintf(e->el_outfile, "\n");  
         }  
 }  }
   
 /*  static const char *
  * Complete the word at or before point, called by rl_complete()  /*ARGSUSED*/
  * 'what_to_do' says what to do with the completion.  _rl_completion_append_character_function(const char *dummy
  * `?' means list the possible completions.      __attribute__((__unused__)))
  * TAB means do standard completion.  
  * `*' means insert all of the possible completions.  
  * `!' means to do standard completion, and list all possible completions if  
  * there is more than one.  
  *  
  * Note: '*' support is not implemented  
  */  
 static int  
 rl_complete_internal(int what_to_do)  
 {  {
         Function *complet_func;          static char buf[2];
         const LineInfo *li;          buf[1] = rl_completion_append_character;
         char *temp, **matches;          return buf;
         const char *ctemp;  
         size_t len;  
   
         rl_completion_type = what_to_do;  
   
         if (h == NULL || e == NULL)  
                 rl_initialize();  
   
         complet_func = rl_completion_entry_function;  
         if (!complet_func)  
                 complet_func = (Function *)(void *)filename_completion_function;  
   
         /* We now look backwards for the start of a filename/variable word */  
         li = el_line(e);  
         ctemp = (const char *) li->cursor;  
         while (ctemp > li->buffer  
             && !strchr(rl_basic_word_break_characters, ctemp[-1])  
             && (!rl_special_prefixes  
                 || !strchr(rl_special_prefixes, ctemp[-1]) ) )  
                 ctemp--;  
   
         len = li->cursor - ctemp;  
         temp = alloca(len + 1);  
         (void)strncpy(temp, ctemp, len);  
         temp[len] = '\0';  
   
         /* these can be used by function called in completion_matches() */  
         /* or (*rl_attempted_completion_function)() */  
         rl_point = li->cursor - li->buffer;  
         rl_end = li->lastchar - li->buffer;  
   
         if (!rl_attempted_completion_function)  
                 matches = completion_matches(temp, (CPFunction *)complet_func);  
         else {  
                 int end = li->cursor - li->buffer;  
                 matches = (*rl_attempted_completion_function) (temp, (int)  
                     (end - len), end);  
         }  
   
         if (matches) {  
                 int i, retval = CC_REFRESH;  
                 int matches_num, maxlen, match_len, match_display=1;  
   
                 /*  
                  * Only replace the completed string with common part of  
                  * possible matches if there is possible completion.  
                  */  
                 if (matches[0][0] != '\0') {  
                         el_deletestr(e, (int) len);  
                         el_insertstr(e, matches[0]);  
                 }  
   
                 if (what_to_do == '?')  
                         goto display_matches;  
   
                 if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {  
                         /*  
                          * We found exact match. Add a space after  
                          * it, unless we do filename completion and the  
                          * object is a directory.  
                          */  
                         size_t alen = strlen(matches[0]);  
                         if ((complet_func !=  
                             (Function *)filename_completion_function  
                               || (alen > 0 && (matches[0])[alen - 1] != '/'))  
                             && rl_completion_append_character) {  
                                 char buf[2];  
                                 buf[0] = rl_completion_append_character;  
                                 buf[1] = '\0';  
                                 el_insertstr(e, buf);  
                         }  
                 } else if (what_to_do == '!') {  
     display_matches:  
                         /*  
                          * More than one match and requested to list possible  
                          * matches.  
                          */  
   
                         for(i=1, maxlen=0; matches[i]; i++) {  
                                 match_len = strlen(matches[i]);  
                                 if (match_len > maxlen)  
                                         maxlen = match_len;  
                         }  
                         matches_num = i - 1;  
   
                         /* newline to get on next line from command line */  
                         (void)fprintf(e->el_outfile, "\n");  
   
                         /*  
                          * If there are too many items, ask user for display  
                          * confirmation.  
                          */  
                         if (matches_num > rl_completion_query_items) {  
                                 (void)fprintf(e->el_outfile,  
                                     "Display all %d possibilities? (y or n) ",  
                                     matches_num);  
                                 (void)fflush(e->el_outfile);  
                                 if (getc(stdin) != 'y')  
                                         match_display = 0;  
                                 (void)fprintf(e->el_outfile, "\n");  
                         }  
   
                         if (match_display)  
                                 rl_display_match_list(matches, matches_num,  
                                         maxlen);  
                         retval = CC_REDISPLAY;  
                 } else if (matches[0][0]) {  
                         /*  
                          * There was some common match, but the name was  
                          * not complete enough. Next tab will print possible  
                          * completions.  
                          */  
                         el_beep(e);  
                 } else {  
                         /* lcd is not a valid object - further specification */  
                         /* is needed */  
                         el_beep(e);  
                         retval = CC_NORM;  
                 }  
   
                 /* free elements of array and the array itself */  
                 for (i = 0; matches[i]; i++)  
                         free(matches[i]);  
                 free(matches), matches = NULL;  
   
                 return (retval);  
         }  
         return (CC_NORM);  
 }  }
   
   
 /*  /*
  * complete word at current point   * complete word at current point
  */   */
   /* ARGSUSED */
 int  int
 rl_complete(int ignore, int invoking_key)  rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
 {  {
         if (h == NULL || e == NULL)          if (h == NULL || e == NULL)
                 rl_initialize();                  rl_initialize();
   
         if (rl_inhibit_completion) {          if (rl_inhibit_completion) {
                 rl_insert(ignore, invoking_key);                  char arr[2];
                   arr[0] = (char)invoking_key;
                   arr[1] = '\0';
                   el_insertstr(e, arr);
                 return (CC_REFRESH);                  return (CC_REFRESH);
         } else if (e->el_state.lastcmd == el_rl_complete_cmdnum)          }
                 return rl_complete_internal('?');  
         else if (_rl_complete_show_all)          /* Just look at how many global variables modify this operation! */
                 return rl_complete_internal('!');          return fn_complete(e,
         else              (CPFunction *)rl_completion_entry_function,
                 return (rl_complete_internal(TAB));              rl_attempted_completion_function,
               rl_basic_word_break_characters, rl_special_prefixes,
               _rl_completion_append_character_function, rl_completion_query_items,
               &rl_completion_type, &rl_attempted_completion_over,
               &rl_point, &rl_end);
 }  }
   
   
   /* ARGSUSED */
   static unsigned char
   _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
   {
           return (unsigned char)rl_complete(0, ch);
   }
   
 /*  /*
  * misc other functions   * misc other functions
  */   */
Line 1939  rl_bind_wrapper(EditLine *el, unsigned c
Line 1615  rl_bind_wrapper(EditLine *el, unsigned c
 {  {
         if (map[c] == NULL)          if (map[c] == NULL)
             return CC_ERROR;              return CC_ERROR;
   
           _rl_update_pos();
   
         (*map[c])(NULL, c);          (*map[c])(NULL, 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 */
Line 1970  rl_callback_read_char()
Line 1649  rl_callback_read_char()
   
         if (buf == NULL || count-- <= 0)          if (buf == NULL || count-- <= 0)
                 return;                  return;
         if (count == 0 && buf[0] == CTRL('d'))          if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
                 done = 1;                  done = 1;
         if (buf[count] == '\n' || buf[count] == '\r')          if (buf[count] == '\n' || buf[count] == '\r')
                 done = 2;                  done = 2;
Line 1983  rl_callback_read_char()
Line 1662  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);
         }          }
 }  }
   
 void  void
 rl_callback_handler_install (const char *prompt, VFunction *linefunc)  rl_callback_handler_install (const char *prompt, VCPFunction *linefunc)
 {  {
         if (e == NULL) {          if (e == NULL) {
                 rl_initialize();                  rl_initialize();
Line 2009  void
Line 1689  void
 rl_redisplay(void)  rl_redisplay(void)
 {  {
         char a[2];          char a[2];
         a[0] = CTRL('r');          a[0] = e->el_tty.t_c[TS_IO][C_REPRINT];
         a[1] = '\0';          a[1] = '\0';
         el_push(e, a);          el_push(e, a);
 }  }
Line 2052  rl_parse_and_bind(const char *line)
Line 1732  rl_parse_and_bind(const char *line)
         Tokenizer *tok;          Tokenizer *tok;
   
         tok = tok_init(NULL);          tok = tok_init(NULL);
         tok_line(tok, line, &argc, &argv);          tok_str(tok, line, &argc, &argv);
         argc = el_parse(e, argc, argv);          argc = el_parse(e, argc, argv);
         tok_end(tok);          tok_end(tok);
         return (argc ? 1 : 0);          return (argc ? 1 : 0);
 }  }
   
   int
   rl_variable_bind(const char *var, const char *value)
   {
           /*
            * The proper return value is undocument, but this is what the
            * readline source seems to do.
            */
           return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0);
   }
   
 void  void
 rl_stuff_char(int c)  rl_stuff_char(int c)
 {  {
Line 2071  rl_stuff_char(int c)
Line 1761  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;          int     n, num_read = 0;
   
         *cp = 0;          *cp = 0;
         while (rl_event_hook) {          while (rl_event_hook) {
Line 2109  _rl_event_read_char(EditLine *el, char *
Line 1799  _rl_event_read_char(EditLine *el, char *
                 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);                  el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
         return(num_read);          return(num_read);
 }  }
   
   static void
   _rl_update_pos(void)
   {
           const LineInfo *li = el_line(e);
   
           rl_point = li->cursor - li->buffer;
           rl_end = li->lastchar - li->buffer;
   }

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.65

CVSweb <webmaster@jp.NetBSD.org>