]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/history.c
bash-5.0 distribution sources and documentation
[thirdparty/bash.git] / lib / readline / history.c
CommitLineData
b80f6443 1/* history.c -- standalone history library */
726f6388 2
d233b485 3/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
726f6388 4
3185942a 5 This file contains the GNU History Library (History), a set of
726f6388
JA
6 routines for managing the text of previously typed lines.
7
3185942a 8 History is free software: you can redistribute it and/or modify
726f6388 9 it under the terms of the GNU General Public License as published by
3185942a
JA
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
726f6388 12
3185942a
JA
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.
726f6388 17
3185942a
JA
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*/
726f6388
JA
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
ccc6cda3
JA
27#if defined (HAVE_CONFIG_H)
28# include <config.h>
29#endif
30
726f6388 31#include <stdio.h>
ccc6cda3 32
726f6388
JA
33#if defined (HAVE_STDLIB_H)
34# include <stdlib.h>
35#else
36# include "ansi_stdlib.h"
37#endif /* HAVE_STDLIB_H */
ccc6cda3 38
726f6388 39#if defined (HAVE_UNISTD_H)
cce855bc
JA
40# ifdef _MINIX
41# include <sys/types.h>
42# endif
726f6388
JA
43# include <unistd.h>
44#endif
ccc6cda3 45
a0c0a00f
CR
46#include <errno.h>
47
726f6388 48#include "history.h"
ccc6cda3 49#include "histlib.h"
726f6388 50
bb70624e 51#include "xmalloc.h"
726f6388 52
a0c0a00f
CR
53#if !defined (errno)
54extern 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
8ddc8d6e
CR
60#define MAX_HISTORY_INITIAL_SIZE 8192
61
ccc6cda3
JA
62/* The number of slots to increase the_history by. */
63#define DEFAULT_HISTORY_GROW_SIZE 50
726f6388 64
b80f6443
JA
65static char *hist_inittime PARAMS((void));
66
726f6388
JA
67/* **************************************************************** */
68/* */
69/* History Functions */
70/* */
71/* **************************************************************** */
72
73/* An array of HIST_ENTRY. This is where we store the history. */
74static 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. */
ccc6cda3 78static int history_stifled;
726f6388 79
f73dda09
JA
80/* The current number of slots allocated to the input_history. */
81static int history_size;
82
726f6388
JA
83/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
84 entries to remember. */
28ef6c31
JA
85int history_max_entries;
86int max_input_history; /* backwards compatibility */
726f6388
JA
87
88/* The current location of the interactive history pointer. Just makes
89 life easier for outside callers. */
ccc6cda3 90int history_offset;
726f6388 91
ccc6cda3
JA
92/* The number of strings currently stored in the history list. */
93int history_length;
726f6388 94
726f6388
JA
95/* The logical `base' of the history array. It defaults to 1. */
96int history_base = 1;
97
98/* Return the current HISTORY_STATE of the history. */
99HISTORY_STATE *
d233b485 100history_get_history_state (void)
726f6388
JA
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. */
117void
d233b485 118history_set_history_state (HISTORY_STATE *state)
726f6388
JA
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. */
130void
d233b485 131using_history (void)
726f6388
JA
132{
133 history_offset = history_length;
134}
135
136/* Return the number of bytes that the primary history entries are using.
b80f6443
JA
137 This just adds up the lengths of the_history->lines and the associated
138 timestamps. */
726f6388 139int
d233b485 140history_total_bytes (void)
726f6388
JA
141{
142 register int i, result;
143
28ef6c31 144 for (i = result = 0; the_history && the_history[i]; i++)
b80f6443 145 result += HISTENT_BYTES (the_history[i]);
726f6388
JA
146
147 return (result);
148}
149
ccc6cda3
JA
150/* Returns the magic number which says what history element we are
151 looking at now. In this implementation, it returns history_offset. */
152int
d233b485 153where_history (void)
ccc6cda3
JA
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. */
160int
d233b485 161history_set_pos (int pos)
ccc6cda3
JA
162{
163 if (pos > history_length || pos < 0 || !the_history)
164 return (0);
165 history_offset = pos;
166 return (1);
167}
168
3185942a 169/* Return the current history array. The caller has to be careful, since this
ccc6cda3
JA
170 is the actual array of data, and could be bashed or made corrupt easily.
171 The array is terminated with a NULL pointer. */
172HIST_ENTRY **
d233b485 173history_list (void)
ccc6cda3
JA
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. */
180HIST_ENTRY *
d233b485 181current_history (void)
ccc6cda3
JA
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. */
191HIST_ENTRY *
d233b485 192previous_history (void)
ccc6cda3
JA
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. */
200HIST_ENTRY *
d233b485 201next_history (void)
ccc6cda3
JA
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. */
208HIST_ENTRY *
d233b485 209history_get (int offset)
ccc6cda3
JA
210{
211 int local_index;
212
213 local_index = offset - history_base;
95732b49 214 return (local_index >= history_length || local_index < 0 || the_history == 0)
ccc6cda3
JA
215 ? (HIST_ENTRY *)NULL
216 : the_history[local_index];
217}
218
0628567a 219HIST_ENTRY *
d233b485 220alloc_history_entry (char *string, char *ts)
0628567a
JA
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
b80f6443 233time_t
d233b485 234history_get_time (HIST_ENTRY *hist)
b80f6443
JA
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;
a0c0a00f 244 errno = 0;
ac50fbac 245 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
a0c0a00f
CR
246 if (errno == ERANGE)
247 return (time_t)0;
b80f6443
JA
248 return t;
249}
250
251static char *
d233b485 252hist_inittime (void)
b80f6443
JA
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
726f6388
JA
269/* Place STRING at the end of the history list. The data field
270 is set to NULL. */
271void
d233b485 272add_history (const char *string)
726f6388
JA
273{
274 HIST_ENTRY *temp;
e59fb114 275 int new_length;
726f6388 276
28ef6c31 277 if (history_stifled && (history_length == history_max_entries))
726f6388
JA
278 {
279 register int i;
280
281 /* If the history is stifled, and history_length is zero,
28ef6c31 282 and it equals history_max_entries, we don't save items. */
726f6388
JA
283 if (history_length == 0)
284 return;
285
286 /* If there is something in the slot, then remove it. */
287 if (the_history[0])
b80f6443 288 (void) free_history_entry (the_history[0]);
726f6388 289
a0c0a00f
CR
290 /* Copy the rest of the entries, moving down one slot. Copy includes
291 trailing NULL. */
a0c0a00f 292 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
726f6388 293
e59fb114 294 new_length = history_length;
726f6388 295 history_base++;
726f6388
JA
296 }
297 else
298 {
ccc6cda3 299 if (history_size == 0)
726f6388 300 {
a0c0a00f 301 if (history_stifled && history_max_entries > 0)
8ddc8d6e
CR
302 history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
303 ? MAX_HISTORY_INITIAL_SIZE
304 : history_max_entries + 2;
a0c0a00f
CR
305 else
306 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
726f6388 307 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
e59fb114 308 new_length = 1;
726f6388
JA
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 }
e59fb114 318 new_length = history_length + 1;
726f6388
JA
319 }
320 }
321
a0c0a00f 322 temp = alloc_history_entry ((char *)string, hist_inittime ());
b80f6443 323
e59fb114
CR
324 the_history[new_length] = (HIST_ENTRY *)NULL;
325 the_history[new_length - 1] = temp;
326 history_length = new_length;
726f6388
JA
327}
328
b80f6443
JA
329/* Change the time stamp of the most recent history entry to STRING. */
330void
d233b485 331add_history_time (const char *string)
b80f6443
JA
332{
333 HIST_ENTRY *hs;
334
ac50fbac 335 if (string == 0 || history_length < 1)
3185942a 336 return;
b80f6443
JA
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. */
344histdata_t
d233b485 345free_history_entry (HIST_ENTRY *hist)
b80f6443
JA
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;
495aee44 354 xfree (hist);
b80f6443
JA
355 return (x);
356}
0628567a
JA
357
358HIST_ENTRY *
d233b485 359copy_history_entry (HIST_ENTRY *hist)
0628567a
JA
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}
b80f6443 376
726f6388
JA
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. */
380HIST_ENTRY *
d233b485 381replace_history_entry (int which, const char *line, histdata_t data)
726f6388 382{
28ef6c31 383 HIST_ENTRY *temp, *old_value;
726f6388 384
95732b49 385 if (which < 0 || which >= history_length)
726f6388
JA
386 return ((HIST_ENTRY *)NULL);
387
28ef6c31 388 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
726f6388
JA
389 old_value = the_history[which];
390
391 temp->line = savestring (line);
392 temp->data = data;
b80f6443 393 temp->timestamp = savestring (old_value->timestamp);
726f6388
JA
394 the_history[which] = temp;
395
396 return (old_value);
397}
398
a0c0a00f
CR
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. */
402void
d233b485 403_hs_append_history_line (int which, const char *line)
a0c0a00f
CR
404{
405 HIST_ENTRY *hent;
d233b485 406 size_t newlen, curlen, minlen;
a0c0a00f
CR
407 char *newline;
408
409 hent = the_history[which];
410 curlen = strlen (hent->line);
d233b485
CR
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. */
a0c0a00f
CR
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
0628567a
JA
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. */
438void
d233b485 439_hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
0628567a
JA
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
726f6388
JA
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. */
478HIST_ENTRY *
d233b485 479remove_history (int which)
726f6388
JA
480{
481 HIST_ENTRY *return_value;
28ef6c31 482 register int i;
d233b485
CR
483#if 1
484 int nentries;
485 HIST_ENTRY **start, **end;
486#endif
726f6388 487
95732b49
JA
488 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
489 return ((HIST_ENTRY *)NULL);
726f6388 490
95732b49 491 return_value = the_history[which];
726f6388 492
d233b485
CR
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
95732b49
JA
501 for (i = which; i < history_length; i++)
502 the_history[i] = the_history[i + 1];
d233b485 503#endif
95732b49
JA
504
505 history_length--;
726f6388
JA
506
507 return (return_value);
508}
509
d233b485
CR
510HIST_ENTRY **
511remove_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
726f6388
JA
546/* Stifle the history list, remembering only MAX number of lines. */
547void
d233b485 548stifle_history (int max)
726f6388 549{
28ef6c31
JA
550 register int i, j;
551
726f6388
JA
552 if (max < 0)
553 max = 0;
554
555 if (history_length > max)
556 {
726f6388 557 /* This loses because we cannot free the data. */
ccc6cda3 558 for (i = 0, j = history_length - max; i < j; i++)
b80f6443 559 free_history_entry (the_history[i]);
726f6388
JA
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;
28ef6c31 569 max_input_history = history_max_entries = max;
726f6388
JA
570}
571
7117c2d2
JA
572/* Stop stifling the history. This returns the previous maximum
573 number of history entries. The value is positive if the history
3185942a 574 was stifled, negative if it wasn't. */
726f6388 575int
d233b485 576unstifle_history (void)
726f6388 577{
726f6388
JA
578 if (history_stifled)
579 {
726f6388 580 history_stifled = 0;
7117c2d2 581 return (history_max_entries);
726f6388 582 }
7117c2d2
JA
583 else
584 return (-history_max_entries);
726f6388
JA
585}
586
587int
d233b485 588history_is_stifled (void)
726f6388
JA
589{
590 return (history_stifled);
591}
592
ccc6cda3 593void
d233b485 594clear_history (void)
726f6388
JA
595{
596 register int i;
726f6388 597
ccc6cda3
JA
598 /* This loses because we cannot free the data. */
599 for (i = 0; i < history_length; i++)
726f6388 600 {
b80f6443 601 free_history_entry (the_history[i]);
ccc6cda3 602 the_history[i] = (HIST_ENTRY *)NULL;
726f6388
JA
603 }
604
ccc6cda3 605 history_offset = history_length = 0;
d233b485 606 history_base = 1; /* reset history base to default */
726f6388 607}