Automatic date update in version.in
[external/binutils.git] / readline / history.c
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 *
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
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
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
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
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
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 **
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 *
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 *
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 *
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 *
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 *
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
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 *
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
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
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
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 *
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 *
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
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
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 *
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 **
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
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
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
588 history_is_stifled (void)
589 {
590   return (history_stifled);
591 }
592
593 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 }