xref: /netbsd-src/external/gpl3/gdb/dist/readline/readline/history.c (revision 8dffb485a119f39f727115fa0bcb569045caf7cb)
1 /* history.c -- standalone history library */
2 
3 /* Copyright (C) 1989-2017 Free Software Foundation, Inc.
4 
5    This file contains the GNU History Library (History), a set of
6    routines for managing the text of previously typed lines.
7 
8    History is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12 
13    History is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with History.  If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 /* The goal is to make the implementation transparent, so that you
23    don't have to know what data types are used, just what functions
24    you can call.  I think I have done that. */
25 #define READLINE_LIBRARY
26 
27 #if defined (HAVE_CONFIG_H)
28 #  include <config.h>
29 #endif
30 
31 #include <stdio.h>
32 
33 #if defined (HAVE_STDLIB_H)
34 #  include <stdlib.h>
35 #else
36 #  include "ansi_stdlib.h"
37 #endif /* HAVE_STDLIB_H */
38 
39 #if defined (HAVE_UNISTD_H)
40 #  ifdef _MINIX
41 #    include <sys/types.h>
42 #  endif
43 #  include <unistd.h>
44 #endif
45 
46 #include <errno.h>
47 
48 #include "history.h"
49 #include "histlib.h"
50 
51 #include "xmalloc.h"
52 
53 #if !defined (errno)
54 extern int errno;
55 #endif
56 
57 /* How big to make the_history when we first allocate it. */
58 #define DEFAULT_HISTORY_INITIAL_SIZE	502
59 
60 #define MAX_HISTORY_INITIAL_SIZE	8192
61 
62 /* The number of slots to increase the_history by. */
63 #define DEFAULT_HISTORY_GROW_SIZE 50
64 
65 static char *hist_inittime PARAMS((void));
66 
67 /* **************************************************************** */
68 /*								    */
69 /*			History Functions			    */
70 /*								    */
71 /* **************************************************************** */
72 
73 /* An array of HIST_ENTRY.  This is where we store the history. */
74 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
75 
76 /* Non-zero means that we have enforced a limit on the amount of
77    history that we save. */
78 static int history_stifled;
79 
80 /* The current number of slots allocated to the input_history. */
81 static int history_size;
82 
83 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
84    entries to remember. */
85 int history_max_entries;
86 int max_input_history;	/* backwards compatibility */
87 
88 /* The current location of the interactive history pointer.  Just makes
89    life easier for outside callers. */
90 int history_offset;
91 
92 /* The number of strings currently stored in the history list. */
93 int history_length;
94 
95 /* The logical `base' of the history array.  It defaults to 1. */
96 int history_base = 1;
97 
98 /* Return the current HISTORY_STATE of the history. */
99 HISTORY_STATE *
history_get_history_state(void)100 history_get_history_state (void)
101 {
102   HISTORY_STATE *state;
103 
104   state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
105   state->entries = the_history;
106   state->offset = history_offset;
107   state->length = history_length;
108   state->size = history_size;
109   state->flags = 0;
110   if (history_stifled)
111     state->flags |= HS_STIFLED;
112 
113   return (state);
114 }
115 
116 /* Set the state of the current history array to STATE. */
117 void
history_set_history_state(HISTORY_STATE * state)118 history_set_history_state (HISTORY_STATE *state)
119 {
120   the_history = state->entries;
121   history_offset = state->offset;
122   history_length = state->length;
123   history_size = state->size;
124   if (state->flags & HS_STIFLED)
125     history_stifled = 1;
126 }
127 
128 /* Begin a session in which the history functions might be used.  This
129    initializes interactive variables. */
130 void
using_history(void)131 using_history (void)
132 {
133   history_offset = history_length;
134 }
135 
136 /* Return the number of bytes that the primary history entries are using.
137    This just adds up the lengths of the_history->lines and the associated
138    timestamps. */
139 int
history_total_bytes(void)140 history_total_bytes (void)
141 {
142   register int i, result;
143 
144   for (i = result = 0; the_history && the_history[i]; i++)
145     result += HISTENT_BYTES (the_history[i]);
146 
147   return (result);
148 }
149 
150 /* Returns the magic number which says what history element we are
151    looking at now.  In this implementation, it returns history_offset. */
152 int
where_history(void)153 where_history (void)
154 {
155   return (history_offset);
156 }
157 
158 /* Make the current history item be the one at POS, an absolute index.
159    Returns zero if POS is out of range, else non-zero. */
160 int
history_set_pos(int pos)161 history_set_pos (int pos)
162 {
163   if (pos > history_length || pos < 0 || !the_history)
164     return (0);
165   history_offset = pos;
166   return (1);
167 }
168 
169 /* Return the current history array.  The caller has to be careful, since this
170    is the actual array of data, and could be bashed or made corrupt easily.
171    The array is terminated with a NULL pointer. */
172 HIST_ENTRY **
history_list(void)173 history_list (void)
174 {
175   return (the_history);
176 }
177 
178 /* Return the history entry at the current position, as determined by
179    history_offset.  If there is no entry there, return a NULL pointer. */
180 HIST_ENTRY *
current_history(void)181 current_history (void)
182 {
183   return ((history_offset == history_length) || the_history == 0)
184 		? (HIST_ENTRY *)NULL
185 		: the_history[history_offset];
186 }
187 
188 /* Back up history_offset to the previous history entry, and return
189    a pointer to that entry.  If there is no previous entry then return
190    a NULL pointer. */
191 HIST_ENTRY *
previous_history(void)192 previous_history (void)
193 {
194   return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
195 }
196 
197 /* Move history_offset forward to the next history entry, and return
198    a pointer to that entry.  If there is no next entry then return a
199    NULL pointer. */
200 HIST_ENTRY *
next_history(void)201 next_history (void)
202 {
203   return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
204 }
205 
206 /* Return the history entry which is logically at OFFSET in the history array.
207    OFFSET is relative to history_base. */
208 HIST_ENTRY *
history_get(int offset)209 history_get (int offset)
210 {
211   int local_index;
212 
213   local_index = offset - history_base;
214   return (local_index >= history_length || local_index < 0 || the_history == 0)
215 		? (HIST_ENTRY *)NULL
216 		: the_history[local_index];
217 }
218 
219 HIST_ENTRY *
alloc_history_entry(char * string,char * ts)220 alloc_history_entry (char *string, char *ts)
221 {
222   HIST_ENTRY *temp;
223 
224   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
225 
226   temp->line = string ? savestring (string) : string;
227   temp->data = (char *)NULL;
228   temp->timestamp = ts;
229 
230   return temp;
231 }
232 
233 time_t
history_get_time(HIST_ENTRY * hist)234 history_get_time (HIST_ENTRY *hist)
235 {
236   char *ts;
237   time_t t;
238 
239   if (hist == 0 || hist->timestamp == 0)
240     return 0;
241   ts = hist->timestamp;
242   if (ts[0] != history_comment_char)
243     return 0;
244   errno = 0;
245   t = (time_t) strtol (ts + 1, (char **)NULL, 10);		/* XXX - should use strtol() here */
246   if (errno == ERANGE)
247     return (time_t)0;
248   return t;
249 }
250 
251 static char *
hist_inittime(void)252 hist_inittime (void)
253 {
254   time_t t;
255   char ts[64], *ret;
256 
257   t = (time_t) time ((time_t *)0);
258 #if defined (HAVE_VSNPRINTF)		/* assume snprintf if vsnprintf exists */
259   snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
260 #else
261   sprintf (ts, "X%lu", (unsigned long) t);
262 #endif
263   ret = savestring (ts);
264   ret[0] = history_comment_char;
265 
266   return ret;
267 }
268 
269 /* Place STRING at the end of the history list.  The data field
270    is  set to NULL. */
271 void
add_history(const char * string)272 add_history (const char *string)
273 {
274   HIST_ENTRY *temp;
275   int new_length;
276 
277   if (history_stifled && (history_length == history_max_entries))
278     {
279       register int i;
280 
281       /* If the history is stifled, and history_length is zero,
282 	 and it equals history_max_entries, we don't save items. */
283       if (history_length == 0)
284 	return;
285 
286       /* If there is something in the slot, then remove it. */
287       if (the_history[0])
288 	(void) free_history_entry (the_history[0]);
289 
290       /* Copy the rest of the entries, moving down one slot.  Copy includes
291 	 trailing NULL.  */
292       memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
293 
294       new_length = history_length;
295       history_base++;
296     }
297   else
298     {
299       if (history_size == 0)
300 	{
301 	  if (history_stifled && history_max_entries > 0)
302 	    history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
303 				? MAX_HISTORY_INITIAL_SIZE
304 				: history_max_entries + 2;
305 	  else
306 	    history_size = DEFAULT_HISTORY_INITIAL_SIZE;
307 	  the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
308 	  new_length = 1;
309 	}
310       else
311 	{
312 	  if (history_length == (history_size - 1))
313 	    {
314 	      history_size += DEFAULT_HISTORY_GROW_SIZE;
315 	      the_history = (HIST_ENTRY **)
316 		xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
317 	    }
318 	  new_length = history_length + 1;
319 	}
320     }
321 
322   temp = alloc_history_entry ((char *)string, hist_inittime ());
323 
324   the_history[new_length] = (HIST_ENTRY *)NULL;
325   the_history[new_length - 1] = temp;
326   history_length = new_length;
327 }
328 
329 /* Change the time stamp of the most recent history entry to STRING. */
330 void
add_history_time(const char * string)331 add_history_time (const char *string)
332 {
333   HIST_ENTRY *hs;
334 
335   if (string == 0 || history_length < 1)
336     return;
337   hs = the_history[history_length - 1];
338   FREE (hs->timestamp);
339   hs->timestamp = savestring (string);
340 }
341 
342 /* Free HIST and return the data so the calling application can free it
343    if necessary and desired. */
344 histdata_t
free_history_entry(HIST_ENTRY * hist)345 free_history_entry (HIST_ENTRY *hist)
346 {
347   histdata_t x;
348 
349   if (hist == 0)
350     return ((histdata_t) 0);
351   FREE (hist->line);
352   FREE (hist->timestamp);
353   x = hist->data;
354   xfree (hist);
355   return (x);
356 }
357 
358 HIST_ENTRY *
copy_history_entry(HIST_ENTRY * hist)359 copy_history_entry (HIST_ENTRY *hist)
360 {
361   HIST_ENTRY *ret;
362   char *ts;
363 
364   if (hist == 0)
365     return hist;
366 
367   ret = alloc_history_entry (hist->line, (char *)NULL);
368 
369   ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
370   ret->timestamp = ts;
371 
372   ret->data = hist->data;
373 
374   return ret;
375 }
376 
377 /* Make the history entry at WHICH have LINE and DATA.  This returns
378    the old entry so you can dispose of the data.  In the case of an
379    invalid WHICH, a NULL pointer is returned. */
380 HIST_ENTRY *
replace_history_entry(int which,const char * line,histdata_t data)381 replace_history_entry (int which, const char *line, histdata_t data)
382 {
383   HIST_ENTRY *temp, *old_value;
384 
385   if (which < 0 || which >= history_length)
386     return ((HIST_ENTRY *)NULL);
387 
388   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
389   old_value = the_history[which];
390 
391   temp->line = savestring (line);
392   temp->data = data;
393   temp->timestamp = savestring (old_value->timestamp);
394   the_history[which] = temp;
395 
396   return (old_value);
397 }
398 
399 /* Append LINE to the history line at offset WHICH, adding a newline to the
400    end of the current line first.  This can be used to construct multi-line
401    history entries while reading lines from the history file. */
402 void
_hs_append_history_line(int which,const char * line)403 _hs_append_history_line (int which, const char *line)
404 {
405   HIST_ENTRY *hent;
406   size_t newlen, curlen, minlen;
407   char *newline;
408 
409   hent = the_history[which];
410   curlen = strlen (hent->line);
411   minlen = curlen + strlen (line) + 2;	/* min space needed */
412   if (curlen > 256)		/* XXX - for now */
413     {
414       newlen = 512;		/* now realloc in powers of 2 */
415       /* we recalcluate every time; the operations are cheap */
416       while (newlen < minlen)
417 	newlen <<= 1;
418     }
419   else
420     newlen = minlen;
421   /* Assume that realloc returns the same pointer and doesn't try a new
422      alloc/copy if the new size is the same as the one last passed. */
423   newline = realloc (hent->line, newlen);
424   if (newline)
425     {
426       hent->line = newline;
427       hent->line[curlen++] = '\n';
428       strcpy (hent->line + curlen, line);
429     }
430 }
431 
432 /* Replace the DATA in the specified history entries, replacing OLD with
433    NEW.  WHICH says which one(s) to replace:  WHICH == -1 means to replace
434    all of the history entries where entry->data == OLD; WHICH == -2 means
435    to replace the `newest' history entry where entry->data == OLD; and
436    WHICH >= 0 means to replace that particular history entry's data, as
437    long as it matches OLD. */
438 void
_hs_replace_history_data(int which,histdata_t * old,histdata_t * new)439 _hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
440 {
441   HIST_ENTRY *entry;
442   register int i, last;
443 
444   if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
445     return;
446 
447   if (which >= 0)
448     {
449       entry = the_history[which];
450       if (entry && entry->data == old)
451 	entry->data = new;
452       return;
453     }
454 
455   last = -1;
456   for (i = 0; i < history_length; i++)
457     {
458       entry = the_history[i];
459       if (entry == 0)
460 	continue;
461       if (entry->data == old)
462 	{
463 	  last = i;
464 	  if (which == -1)
465 	    entry->data = new;
466 	}
467     }
468   if (which == -2 && last >= 0)
469     {
470       entry = the_history[last];
471       entry->data = new;	/* XXX - we don't check entry->old */
472     }
473 }
474 
475 /* Remove history element WHICH from the history.  The removed
476    element is returned to you so you can free the line, data,
477    and containing structure. */
478 HIST_ENTRY *
remove_history(int which)479 remove_history (int which)
480 {
481   HIST_ENTRY *return_value;
482   register int i;
483 #if 1
484   int nentries;
485   HIST_ENTRY **start, **end;
486 #endif
487 
488   if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)
489     return ((HIST_ENTRY *)NULL);
490 
491   return_value = the_history[which];
492 
493 #if 1
494   /* Copy the rest of the entries, moving down one slot.  Copy includes
495      trailing NULL.  */
496   nentries = history_length - which;
497   start = the_history + which;
498   end = start + 1;
499   memmove (start, end, nentries * sizeof (HIST_ENTRY *));
500 #else
501   for (i = which; i < history_length; i++)
502     the_history[i] = the_history[i + 1];
503 #endif
504 
505   history_length--;
506 
507   return (return_value);
508 }
509 
510 HIST_ENTRY **
remove_history_range(int first,int last)511 remove_history_range (int first, int last)
512 {
513   HIST_ENTRY **return_value;
514   register int i;
515   int nentries;
516   HIST_ENTRY **start, **end;
517 
518   if (the_history == 0 || history_length == 0)
519     return ((HIST_ENTRY **)NULL);
520   if (first < 0 || first >= history_length || last < 0 || last >= history_length)
521     return ((HIST_ENTRY **)NULL);
522   if (first > last)
523     return (HIST_ENTRY **)NULL;
524 
525   nentries = last - first + 1;
526   return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
527   if (return_value == 0)
528     return return_value;
529 
530   /* Return all the deleted entries in a list */
531   for (i = first ; i <= last; i++)
532     return_value[i - first] = the_history[i];
533   return_value[i - first] = (HIST_ENTRY *)NULL;
534 
535   /* Copy the rest of the entries, moving down NENTRIES slots.  Copy includes
536      trailing NULL.  */
537   start = the_history + first;
538   end = the_history + last + 1;
539   memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
540 
541   history_length -= nentries;
542 
543   return (return_value);
544 }
545 
546 /* Stifle the history list, remembering only MAX number of lines. */
547 void
stifle_history(int max)548 stifle_history (int max)
549 {
550   register int i, j;
551 
552   if (max < 0)
553     max = 0;
554 
555   if (history_length > max)
556     {
557       /* This loses because we cannot free the data. */
558       for (i = 0, j = history_length - max; i < j; i++)
559 	free_history_entry (the_history[i]);
560 
561       history_base = i;
562       for (j = 0, i = history_length - max; j < max; i++, j++)
563 	the_history[j] = the_history[i];
564       the_history[j] = (HIST_ENTRY *)NULL;
565       history_length = j;
566     }
567 
568   history_stifled = 1;
569   max_input_history = history_max_entries = max;
570 }
571 
572 /* Stop stifling the history.  This returns the previous maximum
573    number of history entries.  The value is positive if the history
574    was stifled, negative if it wasn't. */
575 int
unstifle_history(void)576 unstifle_history (void)
577 {
578   if (history_stifled)
579     {
580       history_stifled = 0;
581       return (history_max_entries);
582     }
583   else
584     return (-history_max_entries);
585 }
586 
587 int
history_is_stifled(void)588 history_is_stifled (void)
589 {
590   return (history_stifled);
591 }
592 
593 void
clear_history(void)594 clear_history (void)
595 {
596   register int i;
597 
598   /* This loses because we cannot free the data. */
599   for (i = 0; i < history_length; i++)
600     {
601       free_history_entry (the_history[i]);
602       the_history[i] = (HIST_ENTRY *)NULL;
603     }
604 
605   history_offset = history_length = 0;
606   history_base = 1;		/* reset history base to default */
607 }
608