]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/readline/history.c
final set of ANSI C changes
[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 /* If the history is stifled, and history_length is zero,
287 and it equals history_max_entries, we don't save items. */
288 if (history_length == 0)
289 return;
290
291 /* If there is something in the slot, then remove it. */
292 if (the_history[0])
293 (void) free_history_entry (the_history[0]);
294
295 /* Copy the rest of the entries, moving down one slot. Copy includes
296 trailing NULL. */
297 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
298
299 new_length = history_length;
300 history_base++;
301 }
302 else
303 {
304 if (history_size == 0)
305 {
306 if (history_stifled && history_max_entries > 0)
307 history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
308 ? MAX_HISTORY_INITIAL_SIZE
309 : history_max_entries + 2;
310 else
311 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
312 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
313 new_length = 1;
314 }
315 else
316 {
317 if (history_length == (history_size - 1))
318 {
319 history_size += DEFAULT_HISTORY_GROW_SIZE;
320 the_history = (HIST_ENTRY **)
321 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
322 }
323 new_length = history_length + 1;
324 }
325 }
326
327 temp = alloc_history_entry ((char *)string, hist_inittime ());
328
329 the_history[new_length] = (HIST_ENTRY *)NULL;
330 the_history[new_length - 1] = temp;
331 history_length = new_length;
332 }
333
334 /* Change the time stamp of the most recent history entry to STRING. */
335 void
336 add_history_time (const char *string)
337 {
338 HIST_ENTRY *hs;
339
340 if (string == 0 || history_length < 1)
341 return;
342 hs = the_history[history_length - 1];
343 FREE (hs->timestamp);
344 hs->timestamp = savestring (string);
345 }
346
347 /* Free HIST and return the data so the calling application can free it
348 if necessary and desired. */
349 histdata_t
350 free_history_entry (HIST_ENTRY *hist)
351 {
352 histdata_t x;
353
354 if (hist == 0)
355 return ((histdata_t) 0);
356 FREE (hist->line);
357 FREE (hist->timestamp);
358 x = hist->data;
359 xfree (hist);
360 return (x);
361 }
362
363 HIST_ENTRY *
364 copy_history_entry (HIST_ENTRY *hist)
365 {
366 HIST_ENTRY *ret;
367 char *ts;
368
369 if (hist == 0)
370 return hist;
371
372 ret = alloc_history_entry (hist->line, (char *)NULL);
373
374 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
375 ret->timestamp = ts;
376
377 ret->data = hist->data;
378
379 return ret;
380 }
381
382 /* Make the history entry at WHICH have LINE and DATA. This returns
383 the old entry so you can dispose of the data. In the case of an
384 invalid WHICH, a NULL pointer is returned. */
385 HIST_ENTRY *
386 replace_history_entry (int which, const char *line, histdata_t data)
387 {
388 HIST_ENTRY *temp, *old_value;
389
390 if (which < 0 || which >= history_length)
391 return ((HIST_ENTRY *)NULL);
392
393 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
394 old_value = the_history[which];
395
396 temp->line = savestring (line);
397 temp->data = data;
398 temp->timestamp = old_value->timestamp ? savestring (old_value->timestamp) : 0;
399 the_history[which] = temp;
400
401 return (old_value);
402 }
403
404 /* Append LINE to the history line at offset WHICH, adding a newline to the
405 end of the current line first. This can be used to construct multi-line
406 history entries while reading lines from the history file. */
407 void
408 _hs_append_history_line (int which, const char *line)
409 {
410 HIST_ENTRY *hent;
411 size_t newlen, curlen, minlen;
412 char *newline;
413
414 hent = the_history[which];
415 curlen = strlen (hent->line);
416 minlen = curlen + strlen (line) + 2; /* min space needed */
417 if (curlen > 256) /* XXX - for now */
418 {
419 newlen = 512; /* now realloc in powers of 2 */
420 /* we recalcluate every time; the operations are cheap */
421 while (newlen < minlen)
422 newlen <<= 1;
423 }
424 else
425 newlen = minlen;
426 /* Assume that realloc returns the same pointer and doesn't try a new
427 alloc/copy if the new size is the same as the one last passed. */
428 newline = realloc (hent->line, newlen);
429 if (newline)
430 {
431 hent->line = newline;
432 hent->line[curlen++] = '\n';
433 strcpy (hent->line + curlen, line);
434 }
435 }
436
437 /* Replace the DATA in the specified history entries, replacing OLD with
438 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
439 all of the history entries where entry->data == OLD; WHICH == -2 means
440 to replace the `newest' history entry where entry->data == OLD; and
441 WHICH >= 0 means to replace that particular history entry's data, as
442 long as it matches OLD. */
443 void
444 _hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
445 {
446 HIST_ENTRY *entry;
447 register int i, last;
448
449 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
450 return;
451
452 if (which >= 0)
453 {
454 entry = the_history[which];
455 if (entry && entry->data == old)
456 entry->data = new;
457 return;
458 }
459
460 last = -1;
461 for (i = 0; i < history_length; i++)
462 {
463 entry = the_history[i];
464 if (entry == 0)
465 continue;
466 if (entry->data == old)
467 {
468 last = i;
469 if (which == -1)
470 entry->data = new;
471 }
472 }
473 if (which == -2 && last >= 0)
474 {
475 entry = the_history[last];
476 entry->data = new; /* XXX - we don't check entry->old */
477 }
478 }
479
480 /* Remove history element WHICH from the history. The removed
481 element is returned to you so you can free the line, data,
482 and containing structure. */
483 HIST_ENTRY *
484 remove_history (int which)
485 {
486 HIST_ENTRY *return_value;
487 register int i;
488 #if 1
489 int nentries;
490 HIST_ENTRY **start, **end;
491 #endif
492
493 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
494 return ((HIST_ENTRY *)NULL);
495
496 return_value = the_history[which];
497
498 #if 1
499 /* Copy the rest of the entries, moving down one slot. Copy includes
500 trailing NULL. */
501 nentries = history_length - which;
502 start = the_history + which;
503 end = start + 1;
504 memmove (start, end, nentries * sizeof (HIST_ENTRY *));
505 #else
506 for (i = which; i < history_length; i++)
507 the_history[i] = the_history[i + 1];
508 #endif
509
510 history_length--;
511
512 return (return_value);
513 }
514
515 HIST_ENTRY **
516 remove_history_range (int first, int last)
517 {
518 HIST_ENTRY **return_value;
519 register int i;
520 int nentries;
521 HIST_ENTRY **start, **end;
522
523 if (the_history == 0 || history_length == 0)
524 return ((HIST_ENTRY **)NULL);
525 if (first < 0 || first >= history_length || last < 0 || last >= history_length)
526 return ((HIST_ENTRY **)NULL);
527 if (first > last)
528 return (HIST_ENTRY **)NULL;
529
530 nentries = last - first + 1;
531 return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
532 if (return_value == 0)
533 return return_value;
534
535 /* Return all the deleted entries in a list */
536 for (i = first ; i <= last; i++)
537 return_value[i - first] = the_history[i];
538 return_value[i - first] = (HIST_ENTRY *)NULL;
539
540 /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
541 trailing NULL. */
542 start = the_history + first;
543 end = the_history + last + 1;
544 memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
545
546 history_length -= nentries;
547
548 return (return_value);
549 }
550
551 /* Stifle the history list, remembering only MAX number of lines. */
552 void
553 stifle_history (int max)
554 {
555 register int i, j;
556
557 if (max < 0)
558 max = 0;
559
560 if (history_length > max)
561 {
562 /* This loses because we cannot free the data. */
563 for (i = 0, j = history_length - max; i < j; i++)
564 free_history_entry (the_history[i]);
565
566 history_base = i;
567 for (j = 0, i = history_length - max; j < max; i++, j++)
568 the_history[j] = the_history[i];
569 the_history[j] = (HIST_ENTRY *)NULL;
570 history_length = j;
571 }
572
573 history_stifled = 1;
574 max_input_history = history_max_entries = max;
575 }
576
577 /* Stop stifling the history. This returns the previous maximum
578 number of history entries. The value is positive if the history
579 was stifled, negative if it wasn't. */
580 int
581 unstifle_history (void)
582 {
583 if (history_stifled)
584 {
585 history_stifled = 0;
586 return (history_max_entries);
587 }
588 else
589 return (-history_max_entries);
590 }
591
592 int
593 history_is_stifled (void)
594 {
595 return (history_stifled);
596 }
597
598 void
599 clear_history (void)
600 {
601 register int i;
602
603 /* This loses because we cannot free the data. */
604 for (i = 0; i < history_length; i++)
605 {
606 free_history_entry (the_history[i]);
607 the_history[i] = (HIST_ENTRY *)NULL;
608 }
609
610 history_offset = history_length = 0;
611 history_base = 1; /* reset history base to default */
612 }