]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/readline/history.c
bash-5.2 distribution sources and documentation
[thirdparty/bash.git] / lib / readline / history.c
1 /* history.c -- standalone history library */
2
3 /* Copyright (C) 1989-2021 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 (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 /* Are we currently at the end of the history list? */
170 int
171 _hs_at_end_of_history (void)
172 {
173 return (the_history == 0 || history_offset == history_length);
174 }
175
176 /* Return the current history array. The caller has to be careful, since this
177 is the actual array of data, and could be bashed or made corrupt easily.
178 The array is terminated with a NULL pointer. */
179 HIST_ENTRY **
180 history_list (void)
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. */
187 HIST_ENTRY *
188 current_history (void)
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. */
198 HIST_ENTRY *
199 previous_history (void)
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. */
207 HIST_ENTRY *
208 next_history (void)
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. */
215 HIST_ENTRY *
216 history_get (int offset)
217 {
218 int local_index;
219
220 local_index = offset - history_base;
221 return (local_index >= history_length || local_index < 0 || the_history == 0)
222 ? (HIST_ENTRY *)NULL
223 : the_history[local_index];
224 }
225
226 HIST_ENTRY *
227 alloc_history_entry (char *string, char *ts)
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
240 time_t
241 history_get_time (HIST_ENTRY *hist)
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;
251 errno = 0;
252 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
253 if (errno == ERANGE)
254 return (time_t)0;
255 return t;
256 }
257
258 static char *
259 hist_inittime (void)
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
276 /* Place STRING at the end of the history list. The data field
277 is set to NULL. */
278 void
279 add_history (const char *string)
280 {
281 HIST_ENTRY *temp;
282 int new_length;
283
284 if (history_stifled && (history_length == history_max_entries))
285 {
286 register int i;
287
288 /* If the history is stifled, and history_length is zero,
289 and it equals history_max_entries, we don't save items. */
290 if (history_length == 0)
291 return;
292
293 /* If there is something in the slot, then remove it. */
294 if (the_history[0])
295 (void) free_history_entry (the_history[0]);
296
297 /* Copy the rest of the entries, moving down one slot. Copy includes
298 trailing NULL. */
299 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
300
301 new_length = history_length;
302 history_base++;
303 }
304 else
305 {
306 if (history_size == 0)
307 {
308 if (history_stifled && history_max_entries > 0)
309 history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
310 ? MAX_HISTORY_INITIAL_SIZE
311 : history_max_entries + 2;
312 else
313 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
314 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
315 new_length = 1;
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 }
325 new_length = history_length + 1;
326 }
327 }
328
329 temp = alloc_history_entry ((char *)string, hist_inittime ());
330
331 the_history[new_length] = (HIST_ENTRY *)NULL;
332 the_history[new_length - 1] = temp;
333 history_length = new_length;
334 }
335
336 /* Change the time stamp of the most recent history entry to STRING. */
337 void
338 add_history_time (const char *string)
339 {
340 HIST_ENTRY *hs;
341
342 if (string == 0 || history_length < 1)
343 return;
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. */
351 histdata_t
352 free_history_entry (HIST_ENTRY *hist)
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;
361 xfree (hist);
362 return (x);
363 }
364
365 HIST_ENTRY *
366 copy_history_entry (HIST_ENTRY *hist)
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 }
383
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. */
387 HIST_ENTRY *
388 replace_history_entry (int which, const char *line, histdata_t data)
389 {
390 HIST_ENTRY *temp, *old_value;
391
392 if (which < 0 || which >= history_length)
393 return ((HIST_ENTRY *)NULL);
394
395 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
396 old_value = the_history[which];
397
398 temp->line = savestring (line);
399 temp->data = data;
400 temp->timestamp = old_value->timestamp ? savestring (old_value->timestamp) : 0;
401 the_history[which] = temp;
402
403 return (old_value);
404 }
405
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. */
409 void
410 _hs_append_history_line (int which, const char *line)
411 {
412 HIST_ENTRY *hent;
413 size_t newlen, curlen, minlen;
414 char *newline;
415
416 hent = the_history[which];
417 curlen = strlen (hent->line);
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. */
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
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. */
445 void
446 _hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
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
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. */
485 HIST_ENTRY *
486 remove_history (int which)
487 {
488 HIST_ENTRY *return_value;
489 register int i;
490 #if 1
491 int nentries;
492 HIST_ENTRY **start, **end;
493 #endif
494
495 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
496 return ((HIST_ENTRY *)NULL);
497
498 return_value = the_history[which];
499
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
508 for (i = which; i < history_length; i++)
509 the_history[i] = the_history[i + 1];
510 #endif
511
512 history_length--;
513
514 return (return_value);
515 }
516
517 HIST_ENTRY **
518 remove_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
553 /* Stifle the history list, remembering only MAX number of lines. */
554 void
555 stifle_history (int max)
556 {
557 register int i, j;
558
559 if (max < 0)
560 max = 0;
561
562 if (history_length > max)
563 {
564 /* This loses because we cannot free the data. */
565 for (i = 0, j = history_length - max; i < j; i++)
566 free_history_entry (the_history[i]);
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;
576 max_input_history = history_max_entries = max;
577 }
578
579 /* Stop stifling the history. This returns the previous maximum
580 number of history entries. The value is positive if the history
581 was stifled, negative if it wasn't. */
582 int
583 unstifle_history (void)
584 {
585 if (history_stifled)
586 {
587 history_stifled = 0;
588 return (history_max_entries);
589 }
590 else
591 return (-history_max_entries);
592 }
593
594 int
595 history_is_stifled (void)
596 {
597 return (history_stifled);
598 }
599
600 void
601 clear_history (void)
602 {
603 register int i;
604
605 /* This loses because we cannot free the data. */
606 for (i = 0; i < history_length; i++)
607 {
608 free_history_entry (the_history[i]);
609 the_history[i] = (HIST_ENTRY *)NULL;
610 }
611
612 history_offset = history_length = 0;
613 history_base = 1; /* reset history base to default */
614 }