Diff for /embedaddon/readline/history.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2014/07/30 08:16:45 version 1.1.1.2, 2021/03/17 01:01:01
Line 1 Line 1
 /* history.c -- standalone history library */  /* history.c -- standalone history library */
   
/* Copyright (C) 1989-2011 Free Software Foundation, Inc./* Copyright (C) 1989-2017 Free Software Foundation, Inc.
   
    This file contains the GNU History Library (History), a set of     This file contains the GNU History Library (History), a set of
    routines for managing the text of previously typed lines.     routines for managing the text of previously typed lines.
Line 43 Line 43
 #  include <unistd.h>  #  include <unistd.h>
 #endif  #endif
   
   #include <errno.h>
   
 #include "history.h"  #include "history.h"
 #include "histlib.h"  #include "histlib.h"
   
 #include "xmalloc.h"  #include "xmalloc.h"
   
   #if !defined (errno)
   extern int errno;
   #endif
   
   /* How big to make the_history when we first allocate it. */
   #define DEFAULT_HISTORY_INITIAL_SIZE    502
   
   #define MAX_HISTORY_INITIAL_SIZE        8192
   
 /* The number of slots to increase the_history by. */  /* The number of slots to increase the_history by. */
 #define DEFAULT_HISTORY_GROW_SIZE 50  #define DEFAULT_HISTORY_GROW_SIZE 50
   
Line 86  int history_base = 1; Line 97  int history_base = 1;
   
 /* Return the current HISTORY_STATE of the history. */  /* Return the current HISTORY_STATE of the history. */
 HISTORY_STATE *  HISTORY_STATE *
history_get_history_state ()history_get_history_state (void)
 {  {
   HISTORY_STATE *state;    HISTORY_STATE *state;
   
Line 104  history_get_history_state () Line 115  history_get_history_state ()
   
 /* Set the state of the current history array to STATE. */  /* Set the state of the current history array to STATE. */
 void  void
history_set_history_state (state)history_set_history_state (HISTORY_STATE *state)
     HISTORY_STATE *state; 
 {  {
   the_history = state->entries;    the_history = state->entries;
   history_offset = state->offset;    history_offset = state->offset;
Line 118  history_set_history_state (state) Line 128  history_set_history_state (state)
 /* Begin a session in which the history functions might be used.  This  /* Begin a session in which the history functions might be used.  This
    initializes interactive variables. */     initializes interactive variables. */
 void  void
using_history ()using_history (void)
 {  {
   history_offset = history_length;    history_offset = history_length;
 }  }
Line 127  using_history () Line 137  using_history ()
    This just adds up the lengths of the_history->lines and the associated     This just adds up the lengths of the_history->lines and the associated
    timestamps. */     timestamps. */
 int  int
history_total_bytes ()history_total_bytes (void)
 {  {
   register int i, result;    register int i, result;
   
Line 140  history_total_bytes () Line 150  history_total_bytes ()
 /* Returns the magic number which says what history element we are  /* Returns the magic number which says what history element we are
    looking at now.  In this implementation, it returns history_offset. */     looking at now.  In this implementation, it returns history_offset. */
 int  int
where_history ()where_history (void)
 {  {
   return (history_offset);    return (history_offset);
 }  }
Line 148  where_history () Line 158  where_history ()
 /* Make the current history item be the one at POS, an absolute index.  /* Make the current history item be the one at POS, an absolute index.
    Returns zero if POS is out of range, else non-zero. */     Returns zero if POS is out of range, else non-zero. */
 int  int
history_set_pos (pos)history_set_pos (int pos)
     int pos; 
 {  {
   if (pos > history_length || pos < 0 || !the_history)    if (pos > history_length || pos < 0 || !the_history)
     return (0);      return (0);
Line 161  history_set_pos (pos) Line 170  history_set_pos (pos)
    is the actual array of data, and could be bashed or made corrupt easily.     is the actual array of data, and could be bashed or made corrupt easily.
    The array is terminated with a NULL pointer. */     The array is terminated with a NULL pointer. */
 HIST_ENTRY **  HIST_ENTRY **
history_list ()history_list (void)
 {  {
   return (the_history);    return (the_history);
 }  }
Line 169  history_list () Line 178  history_list ()
 /* Return the history entry at the current position, as determined by  /* Return the history entry at the current position, as determined by
    history_offset.  If there is no entry there, return a NULL pointer. */     history_offset.  If there is no entry there, return a NULL pointer. */
 HIST_ENTRY *  HIST_ENTRY *
current_history ()current_history (void)
 {  {
   return ((history_offset == history_length) || the_history == 0)    return ((history_offset == history_length) || the_history == 0)
                 ? (HIST_ENTRY *)NULL                  ? (HIST_ENTRY *)NULL
Line 180  current_history () Line 189  current_history ()
    a pointer to that entry.  If there is no previous entry then return     a pointer to that entry.  If there is no previous entry then return
    a NULL pointer. */     a NULL pointer. */
 HIST_ENTRY *  HIST_ENTRY *
previous_history ()previous_history (void)
 {  {
   return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;    return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
 }  }
Line 189  previous_history () Line 198  previous_history ()
    a pointer to that entry.  If there is no next entry then return a     a pointer to that entry.  If there is no next entry then return a
    NULL pointer. */     NULL pointer. */
 HIST_ENTRY *  HIST_ENTRY *
next_history ()next_history (void)
 {  {
   return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];    return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
 }  }
Line 197  next_history () Line 206  next_history ()
 /* Return the history entry which is logically at OFFSET in the history array.  /* Return the history entry which is logically at OFFSET in the history array.
    OFFSET is relative to history_base. */     OFFSET is relative to history_base. */
 HIST_ENTRY *  HIST_ENTRY *
history_get (offset)history_get (int offset)
     int offset; 
 {  {
   int local_index;    int local_index;
   
Line 209  history_get (offset) Line 217  history_get (offset)
 }  }
   
 HIST_ENTRY *  HIST_ENTRY *
alloc_history_entry (string, ts)alloc_history_entry (char *string, char *ts)
     char *string; 
     char *ts; 
 {  {
   HIST_ENTRY *temp;    HIST_ENTRY *temp;
   
Line 225  alloc_history_entry (string, ts) Line 231  alloc_history_entry (string, ts)
 }  }
   
 time_t  time_t
history_get_time (hist)history_get_time (HIST_ENTRY *hist)
     HIST_ENTRY *hist; 
 {  {
   char *ts;    char *ts;
   time_t t;    time_t t;
Line 236  history_get_time (hist) Line 241  history_get_time (hist)
   ts = hist->timestamp;    ts = hist->timestamp;
   if (ts[0] != history_comment_char)    if (ts[0] != history_comment_char)
     return 0;      return 0;
     errno = 0;
   t = (time_t) strtol (ts + 1, (char **)NULL, 10);              /* XXX - should use strtol() here */    t = (time_t) strtol (ts + 1, (char **)NULL, 10);              /* XXX - should use strtol() here */
     if (errno == ERANGE)
       return (time_t)0;
   return t;    return t;
 }  }
   
 static char *  static char *
hist_inittime ()hist_inittime (void)
 {  {
   time_t t;    time_t t;
   char ts[64], *ret;    char ts[64], *ret;
Line 261  hist_inittime () Line 269  hist_inittime ()
 /* Place STRING at the end of the history list.  The data field  /* Place STRING at the end of the history list.  The data field
    is  set to NULL. */     is  set to NULL. */
 void  void
add_history (string)add_history (const char *string)
     const char *string; 
 {  {
   HIST_ENTRY *temp;    HIST_ENTRY *temp;
     int new_length;
   
   if (history_stifled && (history_length == history_max_entries))    if (history_stifled && (history_length == history_max_entries))
     {      {
Line 279  add_history (string) Line 287  add_history (string)
       if (the_history[0])        if (the_history[0])
         (void) free_history_entry (the_history[0]);          (void) free_history_entry (the_history[0]);
   
      /* Copy the rest of the entries, moving down one slot. */      /* Copy the rest of the entries, moving down one slot.  Copy includes
      for (i = 0; i < history_length; i++)         trailing NULL.  */
        the_history[i] = the_history[i + 1];      memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
   
         new_length = history_length;
       history_base++;        history_base++;
     }      }
   else    else
     {      {
       if (history_size == 0)        if (history_size == 0)
         {          {
          history_size = DEFAULT_HISTORY_GROW_SIZE;          if (history_stifled && history_max_entries > 0)
             history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
                                 ? MAX_HISTORY_INITIAL_SIZE
                                 : history_max_entries + 2;
           else
             history_size = DEFAULT_HISTORY_INITIAL_SIZE;
           the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));            the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
          history_length = 1;          new_length = 1;
         }          }
       else        else
         {          {
Line 301  add_history (string) Line 315  add_history (string)
               the_history = (HIST_ENTRY **)                the_history = (HIST_ENTRY **)
                 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));                  xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
             }              }
          history_length++;          new_length = history_length + 1;
         }          }
     }      }
   
  temp = alloc_history_entry (string, hist_inittime ());  temp = alloc_history_entry ((char *)string, hist_inittime ());
   
  the_history[history_length] = (HIST_ENTRY *)NULL;  the_history[new_length] = (HIST_ENTRY *)NULL;
  the_history[history_length - 1] = temp;  the_history[new_length - 1] = temp;
   history_length = new_length;
 }  }
   
 /* Change the time stamp of the most recent history entry to STRING. */  /* Change the time stamp of the most recent history entry to STRING. */
 void  void
add_history_time (string)add_history_time (const char *string)
     const char *string; 
 {  {
   HIST_ENTRY *hs;    HIST_ENTRY *hs;
   
Line 328  add_history_time (string) Line 342  add_history_time (string)
 /* Free HIST and return the data so the calling application can free it  /* Free HIST and return the data so the calling application can free it
    if necessary and desired. */     if necessary and desired. */
 histdata_t  histdata_t
free_history_entry (hist)free_history_entry (HIST_ENTRY *hist)
     HIST_ENTRY *hist; 
 {  {
   histdata_t x;    histdata_t x;
   
Line 343  free_history_entry (hist) Line 356  free_history_entry (hist)
 }  }
   
 HIST_ENTRY *  HIST_ENTRY *
copy_history_entry (hist)copy_history_entry (HIST_ENTRY *hist)
     HIST_ENTRY *hist; 
 {  {
   HIST_ENTRY *ret;    HIST_ENTRY *ret;
   char *ts;    char *ts;
Line 366  copy_history_entry (hist) Line 378  copy_history_entry (hist)
    the old entry so you can dispose of the data.  In the case of an     the old entry so you can dispose of the data.  In the case of an
    invalid WHICH, a NULL pointer is returned. */     invalid WHICH, a NULL pointer is returned. */
 HIST_ENTRY *  HIST_ENTRY *
replace_history_entry (which, line, data)replace_history_entry (int which, const char *line, histdata_t data)
     int which; 
     const char *line; 
     histdata_t data; 
 {  {
   HIST_ENTRY *temp, *old_value;    HIST_ENTRY *temp, *old_value;
   
Line 387  replace_history_entry (which, line, data) Line 396  replace_history_entry (which, line, data)
   return (old_value);    return (old_value);
 }  }
   
   /* Append LINE to the history line at offset WHICH, adding a newline to the
      end of the current line first.  This can be used to construct multi-line
      history entries while reading lines from the history file. */
   void
   _hs_append_history_line (int which, const char *line)
   {
     HIST_ENTRY *hent;
     size_t newlen, curlen, minlen;
     char *newline;
   
     hent = the_history[which];
     curlen = strlen (hent->line);
     minlen = curlen + strlen (line) + 2;  /* min space needed */
     if (curlen > 256)             /* XXX - for now */
       {
         newlen = 512;             /* now realloc in powers of 2 */
         /* we recalcluate every time; the operations are cheap */
         while (newlen < minlen)
           newlen <<= 1;
       }
     else
       newlen = minlen;
     /* Assume that realloc returns the same pointer and doesn't try a new
        alloc/copy if the new size is the same as the one last passed. */
     newline = realloc (hent->line, newlen);
     if (newline)
       {
         hent->line = newline;
         hent->line[curlen++] = '\n';
         strcpy (hent->line + curlen, line);
       }
   }
   
 /* Replace the DATA in the specified history entries, replacing OLD with  /* Replace the DATA in the specified history entries, replacing OLD with
    NEW.  WHICH says which one(s) to replace:  WHICH == -1 means to replace     NEW.  WHICH says which one(s) to replace:  WHICH == -1 means to replace
    all of the history entries where entry->data == OLD; WHICH == -2 means     all of the history entries where entry->data == OLD; WHICH == -2 means
Line 394  replace_history_entry (which, line, data) Line 436  replace_history_entry (which, line, data)
    WHICH >= 0 means to replace that particular history entry's data, as     WHICH >= 0 means to replace that particular history entry's data, as
    long as it matches OLD. */     long as it matches OLD. */
 void  void
replace_history_data (which, old, new)_hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
     int which; 
     histdata_t *old, *new; 
 {  {
   HIST_ENTRY *entry;    HIST_ENTRY *entry;
   register int i, last;    register int i, last;
Line 436  replace_history_data (which, old, new) Line 476  replace_history_data (which, old, new)
    element is returned to you so you can free the line, data,     element is returned to you so you can free the line, data,
    and containing structure. */     and containing structure. */
 HIST_ENTRY *  HIST_ENTRY *
remove_history (which)remove_history (int which)
     int which; 
 {  {
   HIST_ENTRY *return_value;    HIST_ENTRY *return_value;
   register int i;    register int i;
   #if 1
     int nentries;
     HIST_ENTRY **start, **end;
   #endif
   
   if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)    if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)
     return ((HIST_ENTRY *)NULL);      return ((HIST_ENTRY *)NULL);
   
   return_value = the_history[which];    return_value = the_history[which];
   
   #if 1
     /* Copy the rest of the entries, moving down one slot.  Copy includes
        trailing NULL.  */
     nentries = history_length - which;
     start = the_history + which;
     end = start + 1;
     memmove (start, end, nentries * sizeof (HIST_ENTRY *));
   #else
   for (i = which; i < history_length; i++)    for (i = which; i < history_length; i++)
     the_history[i] = the_history[i + 1];      the_history[i] = the_history[i + 1];
   #endif
   
   history_length--;    history_length--;
   
   return (return_value);    return (return_value);
 }  }
   
   HIST_ENTRY **
   remove_history_range (int first, int last)
   {
     HIST_ENTRY **return_value;
     register int i;
     int nentries;
     HIST_ENTRY **start, **end;
   
     if (the_history == 0 || history_length == 0)
       return ((HIST_ENTRY **)NULL);
     if (first < 0 || first >= history_length || last < 0 || last >= history_length)
       return ((HIST_ENTRY **)NULL);
     if (first > last)
       return (HIST_ENTRY **)NULL;
   
     nentries = last - first + 1;
     return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
     if (return_value == 0)
       return return_value;
   
     /* Return all the deleted entries in a list */
     for (i = first ; i <= last; i++)
       return_value[i - first] = the_history[i];
     return_value[i - first] = (HIST_ENTRY *)NULL;
   
     /* Copy the rest of the entries, moving down NENTRIES slots.  Copy includes
        trailing NULL.  */
     start = the_history + first;
     end = the_history + last + 1;
     memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
   
     history_length -= nentries;
   
     return (return_value);
   }
   
 /* Stifle the history list, remembering only MAX number of lines. */  /* Stifle the history list, remembering only MAX number of lines. */
 void  void
stifle_history (max)stifle_history (int max)
     int max; 
 {  {
   register int i, j;    register int i, j;
   
Line 486  stifle_history (max) Line 573  stifle_history (max)
    number of history entries.  The value is positive if the history     number of history entries.  The value is positive if the history
    was stifled, negative if it wasn't. */     was stifled, negative if it wasn't. */
 int  int
unstifle_history ()unstifle_history (void)
 {  {
   if (history_stifled)    if (history_stifled)
     {      {
Line 498  unstifle_history () Line 585  unstifle_history ()
 }  }
   
 int  int
history_is_stifled ()history_is_stifled (void)
 {  {
   return (history_stifled);    return (history_stifled);
 }  }
   
 void  void
clear_history ()clear_history (void)
 {  {
   register int i;    register int i;
   
Line 516  clear_history () Line 603  clear_history ()
     }      }
   
   history_offset = history_length = 0;    history_offset = history_length = 0;
     history_base = 1;             /* reset history base to default */
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>