1 /* history.c -- standalone history library */
3 /* Copyright (C) 1989-2017 Free Software Foundation, Inc.
5 This file contains the GNU History Library (History), a set of
6 routines for managing the text of previously typed lines.
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.
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.
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/>.
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
27 #if defined (HAVE_CONFIG_H)
33 #if defined (HAVE_STDLIB_H)
36 # include "ansi_stdlib.h"
37 #endif /* HAVE_STDLIB_H */
39 #if defined (HAVE_UNISTD_H)
41 # include <sys/types.h>
57 /* How big to make the_history when we first allocate it. */
58 #define DEFAULT_HISTORY_INITIAL_SIZE 502
60 #define MAX_HISTORY_INITIAL_SIZE 8192
62 /* The number of slots to increase the_history by. */
63 #define DEFAULT_HISTORY_GROW_SIZE 50
65 static char *hist_inittime PARAMS((void));
67 /* **************************************************************** */
69 /* History Functions */
71 /* **************************************************************** */
73 /* An array of HIST_ENTRY. This is where we store the history. */
74 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
76 /* Non-zero means that we have enforced a limit on the amount of
77 history that we save. */
78 static int history_stifled;
80 /* The current number of slots allocated to the input_history. */
81 static int history_size;
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 */
88 /* The current location of the interactive history pointer. Just makes
89 life easier for outside callers. */
92 /* The number of strings currently stored in the history list. */
95 /* The logical `base' of the history array. It defaults to 1. */
98 /* Return the current HISTORY_STATE of the history. */
100 history_get_history_state (void)
102 HISTORY_STATE *state;
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;
111 state->flags |= HS_STIFLED;
116 /* Set the state of the current history array to STATE. */
118 history_set_history_state (HISTORY_STATE *state)
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)
128 /* Begin a session in which the history functions might be used. This
129 initializes interactive variables. */
133 history_offset = history_length;
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
140 history_total_bytes (void)
142 register int i, result;
144 for (i = result = 0; the_history && the_history[i]; i++)
145 result += HISTENT_BYTES (the_history[i]);
150 /* Returns the magic number which says what history element we are
151 looking at now. In this implementation, it returns history_offset. */
155 return (history_offset);
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. */
161 history_set_pos (int pos)
163 if (pos > history_length || pos < 0 || !the_history)
165 history_offset = pos;
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. */
175 return (the_history);
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. */
181 current_history (void)
183 return ((history_offset == history_length) || the_history == 0)
185 : the_history[history_offset];
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
192 previous_history (void)
194 return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
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
203 return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
206 /* Return the history entry which is logically at OFFSET in the history array.
207 OFFSET is relative to history_base. */
209 history_get (int offset)
213 local_index = offset - history_base;
214 return (local_index >= history_length || local_index < 0 || the_history == 0)
216 : the_history[local_index];
220 alloc_history_entry (char *string, char *ts)
224 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
226 temp->line = string ? savestring (string) : string;
227 temp->data = (char *)NULL;
228 temp->timestamp = ts;
234 history_get_time (HIST_ENTRY *hist)
239 if (hist == 0 || hist->timestamp == 0)
241 ts = hist->timestamp;
242 if (ts[0] != history_comment_char)
245 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
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);
261 sprintf (ts, "X%lu", (unsigned long) t);
263 ret = savestring (ts);
264 ret[0] = history_comment_char;
269 /* Place STRING at the end of the history list. The data field
272 add_history (const char *string)
277 if (history_stifled && (history_length == history_max_entries))
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)
286 /* If there is something in the slot, then remove it. */
288 (void) free_history_entry (the_history[0]);
290 /* Copy the rest of the entries, moving down one slot. Copy includes
292 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
294 new_length = history_length;
299 if (history_size == 0)
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;
306 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
307 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
312 if (history_length == (history_size - 1))
314 history_size += DEFAULT_HISTORY_GROW_SIZE;
315 the_history = (HIST_ENTRY **)
316 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
318 new_length = history_length + 1;
322 temp = alloc_history_entry ((char *)string, hist_inittime ());
324 the_history[new_length] = (HIST_ENTRY *)NULL;
325 the_history[new_length - 1] = temp;
326 history_length = new_length;
329 /* Change the time stamp of the most recent history entry to STRING. */
331 add_history_time (const char *string)
335 if (string == 0 || history_length < 1)
337 hs = the_history[history_length - 1];
338 FREE (hs->timestamp);
339 hs->timestamp = savestring (string);
342 /* Free HIST and return the data so the calling application can free it
343 if necessary and desired. */
345 free_history_entry (HIST_ENTRY *hist)
350 return ((histdata_t) 0);
352 FREE (hist->timestamp);
359 copy_history_entry (HIST_ENTRY *hist)
367 ret = alloc_history_entry (hist->line, (char *)NULL);
369 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
372 ret->data = hist->data;
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. */
381 replace_history_entry (int which, const char *line, histdata_t data)
383 HIST_ENTRY *temp, *old_value;
385 if (which < 0 || which >= history_length)
386 return ((HIST_ENTRY *)NULL);
388 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
389 old_value = the_history[which];
391 temp->line = savestring (line);
393 temp->timestamp = savestring (old_value->timestamp);
394 the_history[which] = temp;
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. */
403 _hs_append_history_line (int which, const char *line)
406 size_t newlen, curlen, minlen;
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 */
414 newlen = 512; /* now realloc in powers of 2 */
415 /* we recalcluate every time; the operations are cheap */
416 while (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);
426 hent->line = newline;
427 hent->line[curlen++] = '\n';
428 strcpy (hent->line + curlen, line);
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. */
439 _hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
442 register int i, last;
444 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
449 entry = the_history[which];
450 if (entry && entry->data == old)
456 for (i = 0; i < history_length; i++)
458 entry = the_history[i];
461 if (entry->data == old)
468 if (which == -2 && last >= 0)
470 entry = the_history[last];
471 entry->data = new; /* XXX - we don't check entry->old */
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. */
479 remove_history (int which)
481 HIST_ENTRY *return_value;
485 HIST_ENTRY **start, **end;
488 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
489 return ((HIST_ENTRY *)NULL);
491 return_value = the_history[which];
494 /* Copy the rest of the entries, moving down one slot. Copy includes
496 nentries = history_length - which;
497 start = the_history + which;
499 memmove (start, end, nentries * sizeof (HIST_ENTRY *));
501 for (i = which; i < history_length; i++)
502 the_history[i] = the_history[i + 1];
507 return (return_value);
511 remove_history_range (int first, int last)
513 HIST_ENTRY **return_value;
516 HIST_ENTRY **start, **end;
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);
523 return (HIST_ENTRY **)NULL;
525 nentries = last - first + 1;
526 return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
527 if (return_value == 0)
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;
535 /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
537 start = the_history + first;
538 end = the_history + last + 1;
539 memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
541 history_length -= nentries;
543 return (return_value);
546 /* Stifle the history list, remembering only MAX number of lines. */
548 stifle_history (int max)
555 if (history_length > max)
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]);
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;
569 max_input_history = history_max_entries = max;
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. */
576 unstifle_history (void)
581 return (history_max_entries);
584 return (-history_max_entries);
588 history_is_stifled (void)
590 return (history_stifled);
598 /* This loses because we cannot free the data. */
599 for (i = 0; i < history_length; i++)
601 free_history_entry (the_history[i]);
602 the_history[i] = (HIST_ENTRY *)NULL;
605 history_offset = history_length = 0;
606 history_base = 1; /* reset history base to default */