]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/history.c
Bash-5.2 patch 26: fix typo when specifying readline's custom color prefix
[thirdparty/bash.git] / lib / readline / history.c
CommitLineData
b80f6443 1/* history.c -- standalone history library */
726f6388 2
74091dd4 3/* Copyright (C) 1989-2021 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
74091dd4 65static char *hist_inittime (void);
b80f6443 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}
74091dd4
CR
168
169/* Are we currently at the end of the history list? */
170int
171_hs_at_end_of_history (void)
172{
173 return (the_history == 0 || history_offset == history_length);
174}
ccc6cda3 175
3185942a 176/* Return the current history array. The caller has to be careful, since this
ccc6cda3
JA
177 is the actual array of data, and could be bashed or made corrupt easily.
178 The array is terminated with a NULL pointer. */
179HIST_ENTRY **
d233b485 180history_list (void)
ccc6cda3
JA
181{
182 return (the_history);
183}
184
185/* Return the history entry at the current position, as determined by
186 history_offset. If there is no entry there, return a NULL pointer. */
187HIST_ENTRY *
d233b485 188current_history (void)
ccc6cda3
JA
189{
190 return ((history_offset == history_length) || the_history == 0)
191 ? (HIST_ENTRY *)NULL
192 : the_history[history_offset];
193}
194
195/* Back up history_offset to the previous history entry, and return
196 a pointer to that entry. If there is no previous entry then return
197 a NULL pointer. */
198HIST_ENTRY *
d233b485 199previous_history (void)
ccc6cda3
JA
200{
201 return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
202}
203
204/* Move history_offset forward to the next history entry, and return
205 a pointer to that entry. If there is no next entry then return a
206 NULL pointer. */
207HIST_ENTRY *
d233b485 208next_history (void)
ccc6cda3
JA
209{
210 return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
211}
212
213/* Return the history entry which is logically at OFFSET in the history array.
214 OFFSET is relative to history_base. */
215HIST_ENTRY *
d233b485 216history_get (int offset)
ccc6cda3
JA
217{
218 int local_index;
219
220 local_index = offset - history_base;
95732b49 221 return (local_index >= history_length || local_index < 0 || the_history == 0)
ccc6cda3
JA
222 ? (HIST_ENTRY *)NULL
223 : the_history[local_index];
224}
225
0628567a 226HIST_ENTRY *
d233b485 227alloc_history_entry (char *string, char *ts)
0628567a
JA
228{
229 HIST_ENTRY *temp;
230
231 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
232
233 temp->line = string ? savestring (string) : string;
234 temp->data = (char *)NULL;
235 temp->timestamp = ts;
236
237 return temp;
238}
239
b80f6443 240time_t
d233b485 241history_get_time (HIST_ENTRY *hist)
b80f6443
JA
242{
243 char *ts;
244 time_t t;
245
246 if (hist == 0 || hist->timestamp == 0)
247 return 0;
248 ts = hist->timestamp;
249 if (ts[0] != history_comment_char)
250 return 0;
a0c0a00f 251 errno = 0;
ac50fbac 252 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
a0c0a00f
CR
253 if (errno == ERANGE)
254 return (time_t)0;
b80f6443
JA
255 return t;
256}
257
258static char *
d233b485 259hist_inittime (void)
b80f6443
JA
260{
261 time_t t;
262 char ts[64], *ret;
263
264 t = (time_t) time ((time_t *)0);
265#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
266 snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
267#else
268 sprintf (ts, "X%lu", (unsigned long) t);
269#endif
270 ret = savestring (ts);
271 ret[0] = history_comment_char;
272
273 return ret;
274}
275
726f6388
JA
276/* Place STRING at the end of the history list. The data field
277 is set to NULL. */
278void
d233b485 279add_history (const char *string)
726f6388
JA
280{
281 HIST_ENTRY *temp;
e59fb114 282 int new_length;
726f6388 283
28ef6c31 284 if (history_stifled && (history_length == history_max_entries))
726f6388
JA
285 {
286 register int i;
287
288 /* If the history is stifled, and history_length is zero,
28ef6c31 289 and it equals history_max_entries, we don't save items. */
726f6388
JA
290 if (history_length == 0)
291 return;
292
293 /* If there is something in the slot, then remove it. */
294 if (the_history[0])
b80f6443 295 (void) free_history_entry (the_history[0]);
726f6388 296
a0c0a00f
CR
297 /* Copy the rest of the entries, moving down one slot. Copy includes
298 trailing NULL. */
a0c0a00f 299 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
726f6388 300
e59fb114 301 new_length = history_length;
726f6388 302 history_base++;
726f6388
JA
303 }
304 else
305 {
ccc6cda3 306 if (history_size == 0)
726f6388 307 {
a0c0a00f 308 if (history_stifled && history_max_entries > 0)
8ddc8d6e
CR
309 history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
310 ? MAX_HISTORY_INITIAL_SIZE
311 : history_max_entries + 2;
a0c0a00f
CR
312 else
313 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
726f6388 314 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
e59fb114 315 new_length = 1;
726f6388
JA
316 }
317 else
318 {
319 if (history_length == (history_size - 1))
320 {
321 history_size += DEFAULT_HISTORY_GROW_SIZE;
322 the_history = (HIST_ENTRY **)
323 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
324 }
e59fb114 325 new_length = history_length + 1;
726f6388
JA
326 }
327 }
328
a0c0a00f 329 temp = alloc_history_entry ((char *)string, hist_inittime ());
b80f6443 330
e59fb114
CR
331 the_history[new_length] = (HIST_ENTRY *)NULL;
332 the_history[new_length - 1] = temp;
333 history_length = new_length;
726f6388
JA
334}
335
b80f6443
JA
336/* Change the time stamp of the most recent history entry to STRING. */
337void
d233b485 338add_history_time (const char *string)
b80f6443
JA
339{
340 HIST_ENTRY *hs;
341
ac50fbac 342 if (string == 0 || history_length < 1)
3185942a 343 return;
b80f6443
JA
344 hs = the_history[history_length - 1];
345 FREE (hs->timestamp);
346 hs->timestamp = savestring (string);
347}
348
349/* Free HIST and return the data so the calling application can free it
350 if necessary and desired. */
351histdata_t
d233b485 352free_history_entry (HIST_ENTRY *hist)
b80f6443
JA
353{
354 histdata_t x;
355
356 if (hist == 0)
357 return ((histdata_t) 0);
358 FREE (hist->line);
359 FREE (hist->timestamp);
360 x = hist->data;
495aee44 361 xfree (hist);
b80f6443
JA
362 return (x);
363}
0628567a
JA
364
365HIST_ENTRY *
d233b485 366copy_history_entry (HIST_ENTRY *hist)
0628567a
JA
367{
368 HIST_ENTRY *ret;
369 char *ts;
370
371 if (hist == 0)
372 return hist;
373
374 ret = alloc_history_entry (hist->line, (char *)NULL);
375
376 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
377 ret->timestamp = ts;
378
379 ret->data = hist->data;
380
381 return ret;
382}
b80f6443 383
726f6388
JA
384/* Make the history entry at WHICH have LINE and DATA. This returns
385 the old entry so you can dispose of the data. In the case of an
386 invalid WHICH, a NULL pointer is returned. */
387HIST_ENTRY *
d233b485 388replace_history_entry (int which, const char *line, histdata_t data)
726f6388 389{
28ef6c31 390 HIST_ENTRY *temp, *old_value;
726f6388 391
95732b49 392 if (which < 0 || which >= history_length)
726f6388
JA
393 return ((HIST_ENTRY *)NULL);
394
28ef6c31 395 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
726f6388
JA
396 old_value = the_history[which];
397
398 temp->line = savestring (line);
399 temp->data = data;
74091dd4 400 temp->timestamp = old_value->timestamp ? savestring (old_value->timestamp) : 0;
726f6388
JA
401 the_history[which] = temp;
402
403 return (old_value);
404}
405
a0c0a00f
CR
406/* Append LINE to the history line at offset WHICH, adding a newline to the
407 end of the current line first. This can be used to construct multi-line
408 history entries while reading lines from the history file. */
409void
d233b485 410_hs_append_history_line (int which, const char *line)
a0c0a00f
CR
411{
412 HIST_ENTRY *hent;
d233b485 413 size_t newlen, curlen, minlen;
a0c0a00f
CR
414 char *newline;
415
416 hent = the_history[which];
417 curlen = strlen (hent->line);
d233b485
CR
418 minlen = curlen + strlen (line) + 2; /* min space needed */
419 if (curlen > 256) /* XXX - for now */
420 {
421 newlen = 512; /* now realloc in powers of 2 */
422 /* we recalcluate every time; the operations are cheap */
423 while (newlen < minlen)
424 newlen <<= 1;
425 }
426 else
427 newlen = minlen;
428 /* Assume that realloc returns the same pointer and doesn't try a new
429 alloc/copy if the new size is the same as the one last passed. */
a0c0a00f
CR
430 newline = realloc (hent->line, newlen);
431 if (newline)
432 {
433 hent->line = newline;
434 hent->line[curlen++] = '\n';
435 strcpy (hent->line + curlen, line);
436 }
437}
438
0628567a
JA
439/* Replace the DATA in the specified history entries, replacing OLD with
440 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
441 all of the history entries where entry->data == OLD; WHICH == -2 means
442 to replace the `newest' history entry where entry->data == OLD; and
443 WHICH >= 0 means to replace that particular history entry's data, as
444 long as it matches OLD. */
445void
d233b485 446_hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
0628567a
JA
447{
448 HIST_ENTRY *entry;
449 register int i, last;
450
451 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
452 return;
453
454 if (which >= 0)
455 {
456 entry = the_history[which];
457 if (entry && entry->data == old)
458 entry->data = new;
459 return;
460 }
461
462 last = -1;
463 for (i = 0; i < history_length; i++)
464 {
465 entry = the_history[i];
466 if (entry == 0)
467 continue;
468 if (entry->data == old)
469 {
470 last = i;
471 if (which == -1)
472 entry->data = new;
473 }
474 }
475 if (which == -2 && last >= 0)
476 {
477 entry = the_history[last];
478 entry->data = new; /* XXX - we don't check entry->old */
479 }
480}
481
726f6388
JA
482/* Remove history element WHICH from the history. The removed
483 element is returned to you so you can free the line, data,
484 and containing structure. */
485HIST_ENTRY *
d233b485 486remove_history (int which)
726f6388
JA
487{
488 HIST_ENTRY *return_value;
28ef6c31 489 register int i;
d233b485
CR
490#if 1
491 int nentries;
492 HIST_ENTRY **start, **end;
493#endif
726f6388 494
95732b49
JA
495 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
496 return ((HIST_ENTRY *)NULL);
726f6388 497
95732b49 498 return_value = the_history[which];
726f6388 499
d233b485
CR
500#if 1
501 /* Copy the rest of the entries, moving down one slot. Copy includes
502 trailing NULL. */
503 nentries = history_length - which;
504 start = the_history + which;
505 end = start + 1;
506 memmove (start, end, nentries * sizeof (HIST_ENTRY *));
507#else
95732b49
JA
508 for (i = which; i < history_length; i++)
509 the_history[i] = the_history[i + 1];
d233b485 510#endif
95732b49
JA
511
512 history_length--;
726f6388
JA
513
514 return (return_value);
515}
516
d233b485
CR
517HIST_ENTRY **
518remove_history_range (int first, int last)
519{
520 HIST_ENTRY **return_value;
521 register int i;
522 int nentries;
523 HIST_ENTRY **start, **end;
524
525 if (the_history == 0 || history_length == 0)
526 return ((HIST_ENTRY **)NULL);
527 if (first < 0 || first >= history_length || last < 0 || last >= history_length)
528 return ((HIST_ENTRY **)NULL);
529 if (first > last)
530 return (HIST_ENTRY **)NULL;
531
532 nentries = last - first + 1;
533 return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
534 if (return_value == 0)
535 return return_value;
536
537 /* Return all the deleted entries in a list */
538 for (i = first ; i <= last; i++)
539 return_value[i - first] = the_history[i];
540 return_value[i - first] = (HIST_ENTRY *)NULL;
541
542 /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
543 trailing NULL. */
544 start = the_history + first;
545 end = the_history + last + 1;
546 memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
547
548 history_length -= nentries;
549
550 return (return_value);
551}
552
726f6388
JA
553/* Stifle the history list, remembering only MAX number of lines. */
554void
d233b485 555stifle_history (int max)
726f6388 556{
28ef6c31
JA
557 register int i, j;
558
726f6388
JA
559 if (max < 0)
560 max = 0;
561
562 if (history_length > max)
563 {
726f6388 564 /* This loses because we cannot free the data. */
ccc6cda3 565 for (i = 0, j = history_length - max; i < j; i++)
b80f6443 566 free_history_entry (the_history[i]);
726f6388
JA
567
568 history_base = i;
569 for (j = 0, i = history_length - max; j < max; i++, j++)
570 the_history[j] = the_history[i];
571 the_history[j] = (HIST_ENTRY *)NULL;
572 history_length = j;
573 }
574
575 history_stifled = 1;
28ef6c31 576 max_input_history = history_max_entries = max;
726f6388
JA
577}
578
7117c2d2
JA
579/* Stop stifling the history. This returns the previous maximum
580 number of history entries. The value is positive if the history
3185942a 581 was stifled, negative if it wasn't. */
726f6388 582int
d233b485 583unstifle_history (void)
726f6388 584{
726f6388
JA
585 if (history_stifled)
586 {
726f6388 587 history_stifled = 0;
7117c2d2 588 return (history_max_entries);
726f6388 589 }
7117c2d2
JA
590 else
591 return (-history_max_entries);
726f6388
JA
592}
593
594int
d233b485 595history_is_stifled (void)
726f6388
JA
596{
597 return (history_stifled);
598}
599
ccc6cda3 600void
d233b485 601clear_history (void)
726f6388
JA
602{
603 register int i;
726f6388 604
ccc6cda3
JA
605 /* This loses because we cannot free the data. */
606 for (i = 0; i < history_length; i++)
726f6388 607 {
b80f6443 608 free_history_entry (the_history[i]);
ccc6cda3 609 the_history[i] = (HIST_ENTRY *)NULL;
726f6388
JA
610 }
611
ccc6cda3 612 history_offset = history_length = 0;
d233b485 613 history_base = 1; /* reset history base to default */
726f6388 614}