1 /* history.c -- standalone history library */
3 /* Copyright (C) 1989-2025 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>
45 #include "posixtime.h"
58 /* How big to make the_history when we first allocate it. */
59 #define DEFAULT_HISTORY_INITIAL_SIZE 502
61 #define MAX_HISTORY_INITIAL_SIZE 8192
63 /* The number of slots to increase the_history by. */
64 #define DEFAULT_HISTORY_GROW_SIZE 256
66 static char *hist_inittime (void);
68 static int history_list_grow_size (void);
69 static void history_list_resize (int); /* XXX - size_t? */
70 static void advance_history (void);
72 /* **************************************************************** */
74 /* History Functions */
76 /* **************************************************************** */
78 /* An array of HIST_ENTRY. This is where we store the history. the_history is
79 a roving pointer somewhere into this, so the user-visible history list is
80 a window into real_history starting at the_history and extending
81 history_length entries. */
82 static HIST_ENTRY
**real_history
= (HIST_ENTRY
**)NULL
;
84 /* The current number of slots allocated to the input_history. */
85 static int real_history_size
= 0;
87 /* A pointer to somewhere in real_history, where the user-visible history
89 static HIST_ENTRY
**the_history
= (HIST_ENTRY
**)NULL
;
91 /* Non-zero means that we have enforced a limit on the amount of
92 history that we save. */
93 static int history_stifled
;
95 /* The number of history entries available for user use, starting at the_history.
96 real_history_size - history_size == the_history - real_history */
97 static int history_size
;
99 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
100 entries to remember. */
101 int history_max_entries
;
102 int max_input_history
; /* backwards compatibility */
104 /* The current location of the interactive history pointer. Just makes
105 life easier for outside callers. */
108 /* The number of strings currently stored in the history list. This is
109 always <= real_history_length */
112 /* The logical `base' of the history array. It defaults to 1. */
113 int history_base
= 1;
115 /* Compute the number of bits required to store a given nonnegative integer.
117 NOTE: _bit_length(0) == 0 */
118 static inline unsigned
119 _bit_length(unsigned n
)
121 /* This implementation is for simplicity, not for performance, but it is
122 fast enough for our purposes here. */
132 /* Compute a grow size that adjusts to the size of the history.
134 We aim to grow by roughly sqrt(history_size) in order to amortize the cost of
135 realloc() and memmove(). This reduces the total cost of the memmoves from
136 O(N^2) to O(N*sqrt(N)). */
138 history_list_grow_size (void)
141 /* Handle small positive values and guard against history_length accidentally
143 const int MIN_BITS
= 10;
144 if (history_length
< (1 << MIN_BITS
))
145 return DEFAULT_HISTORY_GROW_SIZE
;
147 /* For other values, we just want something easy to compute that grows roughly
148 as sqrt(N), where N=history_length. We use approximately 2^((k+1)/2),
149 where k is the bit length of N. This bounds the value between sqrt(2N) and
151 width
= MIN_BITS
+ _bit_length(history_length
>> MIN_BITS
);
153 /* If width is odd then this is 2^((width+1)/2). An even width gives a value
154 of 3*2^((width-2)/2) ~ 1.06*2^((width+1)/2). */
155 r
= (1 << (width
/ 2)) + (1 << ((width
- 1) / 2));
157 /* Make sure we always expand the list by at least DEFAULT_HISTORY_GROW_SIZE */
158 return ((r
< DEFAULT_HISTORY_GROW_SIZE
) ? DEFAULT_HISTORY_GROW_SIZE
: r
);
161 /* Return the current HISTORY_STATE of the history. */
163 history_get_history_state (void)
165 HISTORY_STATE
*state
;
167 state
= (HISTORY_STATE
*)xmalloc (sizeof (HISTORY_STATE
));
168 state
->entries
= the_history
;
169 state
->offset
= history_offset
;
170 state
->length
= history_length
;
171 state
->size
= history_size
;
174 state
->flags
|= HS_STIFLED
;
179 /* Set the state of the current history array to STATE. */
181 history_set_history_state (HISTORY_STATE
*state
)
183 the_history
= state
->entries
;
184 history_offset
= state
->offset
;
185 history_length
= state
->length
;
186 history_size
= state
->size
;
187 if (state
->flags
& HS_STIFLED
)
191 /* Begin a session in which the history functions might be used. This
192 initializes interactive variables. */
196 history_offset
= history_length
;
199 /* Return the number of bytes that the primary history entries are using.
200 This just adds up the lengths of the_history->lines and the associated
203 history_total_bytes (void)
207 for (i
= result
= 0; the_history
&& the_history
[i
]; i
++)
208 result
+= HISTENT_BYTES (the_history
[i
]);
213 /* Returns the magic number which says what history element we are
214 looking at now. In this implementation, it returns history_offset. */
218 return (history_offset
);
221 /* Make the current history item be the one at POS, an absolute index.
222 Returns zero if POS is out of range, else non-zero. */
224 history_set_pos (int pos
)
226 if (pos
> history_length
|| pos
< 0 || !the_history
)
228 history_offset
= pos
;
232 /* Are we currently at the end of the history list? */
234 _hs_at_end_of_history (void)
236 return (the_history
== 0 || history_offset
== history_length
);
239 /* Return the current history array. The caller has to be careful, since this
240 is the actual array of data, and could be bashed or made corrupt easily.
241 The array is terminated with a NULL pointer. */
245 return (the_history
);
248 /* Return the history entry at the current position, as determined by
249 history_offset. If there is no entry there, return a NULL pointer. */
251 current_history (void)
253 return ((history_offset
== history_length
) || the_history
== 0)
255 : the_history
[history_offset
];
258 /* Back up history_offset to the previous history entry, and return
259 a pointer to that entry. If there is no previous entry then return
262 previous_history (void)
264 return history_offset
? the_history
[--history_offset
] : (HIST_ENTRY
*)NULL
;
267 /* Move history_offset forward to the next history entry, and return
268 a pointer to that entry. If there is no next entry then return a
273 return (history_offset
== history_length
) ? (HIST_ENTRY
*)NULL
: the_history
[++history_offset
];
276 /* Return the history entry which is logically at OFFSET in the history array.
277 OFFSET is relative to history_base. */
279 history_get (int offset
)
283 local_index
= offset
- history_base
;
284 return (local_index
>= history_length
|| local_index
< 0 || the_history
== 0)
286 : the_history
[local_index
];
290 alloc_history_entry (char *string
, char *ts
)
294 temp
= (HIST_ENTRY
*)xmalloc (sizeof (HIST_ENTRY
));
296 temp
->line
= string
? savestring (string
) : string
;
297 temp
->data
= (char *)NULL
;
298 temp
->timestamp
= ts
;
304 history_get_time (HIST_ENTRY
*hist
)
309 if (hist
== 0 || hist
->timestamp
== 0)
311 ts
= hist
->timestamp
;
312 if (ts
[0] != history_comment_char
)
315 t
= (time_t) strtol (ts
+ 1, (char **)NULL
, 10); /* XXX - should use strtol() here */
328 #if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
329 snprintf (ts
, sizeof (ts
) - 1, "X%lu", (unsigned long) t
);
331 sprintf (ts
, "X%lu", (unsigned long) t
);
333 ret
= savestring (ts
);
334 ret
[0] = history_comment_char
;
339 /* Ensure space for new history entries by resetting the start pointer
340 (the_history) and resizing real_history if necessary. */
342 history_list_resize (int new_size
)
344 /* Do nothing there is already enough user space. history_length is always <=
346 if (new_size
< history_length
)
349 /* If we need to, reset the_history to the start of real_history and
351 if (the_history
!= real_history
)
352 memmove (real_history
, the_history
, history_length
* sizeof (HIST_ENTRY
*));
354 /* Don't bother if real_history_size is already big enough, since at this
355 point the_history == real_history and we will set history_size to
356 real_history_size. We don't shrink the history list. */
357 if (new_size
> real_history_size
)
359 real_history
= (HIST_ENTRY
**) xrealloc (real_history
, new_size
* sizeof (HIST_ENTRY
*));
360 real_history_size
= new_size
;
362 the_history
= real_history
;
363 history_size
= real_history_size
;
365 if (history_size
> history_length
)
366 memset (real_history
+ history_length
, 0, (history_size
- history_length
) * sizeof (HIST_ENTRY
*));
370 advance_history (void)
372 /* Advance 'the_history' pointer to simulate dropping the first entry. */
376 /* If full, move all the entries (and trailing NULL) to the beginning. */
377 if (history_length
== history_size
)
378 history_list_resize (history_length
+ history_list_grow_size ());
381 /* Place STRING at the end of the history list. The data field
384 add_history (const char *string
)
389 if (history_stifled
&& (history_length
== history_max_entries
))
391 /* If the history is stifled, and history_length is zero,
392 and it equals history_max_entries, we don't save items. */
393 if (history_length
== 0)
396 /* If there is something in the slot, then remove it. */
398 (void) free_history_entry (the_history
[0]);
400 /* Advance the pointer into real_history, resizing if necessary. */
403 new_length
= history_length
;
408 if (history_size
== 0)
411 if (history_stifled
&& history_max_entries
> 0)
412 initial_size
= (history_max_entries
> MAX_HISTORY_INITIAL_SIZE
)
413 ? MAX_HISTORY_INITIAL_SIZE
414 : history_max_entries
+ 2;
416 initial_size
= DEFAULT_HISTORY_INITIAL_SIZE
;
417 history_list_resize (initial_size
);
422 if (history_length
== (history_size
- 1))
423 history_list_resize (real_history_size
+ history_list_grow_size ());
424 new_length
= history_length
+ 1;
428 temp
= alloc_history_entry ((char *)string
, hist_inittime ());
430 the_history
[new_length
] = (HIST_ENTRY
*)NULL
;
431 the_history
[new_length
- 1] = temp
;
432 history_length
= new_length
;
435 /* Change the time stamp of the most recent history entry to STRING. */
437 add_history_time (const char *string
)
441 if (string
== 0 || history_length
< 1)
443 hs
= the_history
[history_length
- 1];
444 FREE (hs
->timestamp
);
445 hs
->timestamp
= savestring (string
);
448 /* Free HIST and return the data so the calling application can free it
449 if necessary and desired. */
451 free_history_entry (HIST_ENTRY
*hist
)
456 return ((histdata_t
) 0);
458 FREE (hist
->timestamp
);
465 copy_history_entry (HIST_ENTRY
*hist
)
473 ret
= alloc_history_entry (hist
->line
, (char *)NULL
);
475 ts
= hist
->timestamp
? savestring (hist
->timestamp
) : hist
->timestamp
;
478 ret
->data
= hist
->data
;
483 /* Make the history entry at WHICH have LINE and DATA. This returns
484 the old entry so you can dispose of the data. In the case of an
485 invalid WHICH, a NULL pointer is returned. */
487 replace_history_entry (int which
, const char *line
, histdata_t data
)
489 HIST_ENTRY
*temp
, *old_value
;
491 if (which
< 0 || which
>= history_length
)
492 return ((HIST_ENTRY
*)NULL
);
494 temp
= (HIST_ENTRY
*)xmalloc (sizeof (HIST_ENTRY
));
495 old_value
= the_history
[which
];
497 temp
->line
= savestring (line
);
499 temp
->timestamp
= old_value
->timestamp
? savestring (old_value
->timestamp
) : 0;
500 the_history
[which
] = temp
;
505 /* Append LINE to the history line at offset WHICH, adding a newline to the
506 end of the current line first. This can be used to construct multi-line
507 history entries while reading lines from the history file. */
509 _hs_append_history_line (int which
, const char *line
)
512 size_t newlen
, curlen
, minlen
;
515 hent
= the_history
[which
];
516 curlen
= strlen (hent
->line
);
517 minlen
= curlen
+ strlen (line
) + 2; /* min space needed */
518 if (curlen
> 256) /* XXX - for now */
520 newlen
= 512; /* now realloc in powers of 2 */
521 /* we recalcluate every time; the operations are cheap */
522 while (newlen
< minlen
)
527 /* Assume that realloc returns the same pointer and doesn't try a new
528 alloc/copy if the new size is the same as the one last passed. */
529 newline
= realloc (hent
->line
, newlen
);
532 hent
->line
= newline
;
533 hent
->line
[curlen
++] = '\n';
534 strcpy (hent
->line
+ curlen
, line
);
538 /* Replace the DATA in the specified history entries, replacing OLD with
539 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
540 all of the history entries where entry->data == OLD; WHICH == -2 means
541 to replace the `newest' history entry where entry->data == OLD; and
542 WHICH >= 0 means to replace that particular history entry's data, as
543 long as it matches OLD. */
545 _hs_replace_history_data (int which
, histdata_t
*old
, histdata_t
*new)
550 if (which
< -2 || which
>= history_length
|| history_length
== 0 || the_history
== 0)
555 entry
= the_history
[which
];
556 if (entry
&& entry
->data
== old
)
562 for (i
= history_length
- 1; i
>= 0; i
--)
564 entry
= the_history
[i
];
567 if (entry
->data
== old
)
574 if (which
== -2 && last
>= 0)
576 entry
= the_history
[last
];
577 entry
->data
= new; /* XXX - we don't check entry->old */
582 _hs_search_history_data (histdata_t
*needle
)
587 if (history_length
== 0 || the_history
== 0)
590 for (i
= history_length
- 1; i
>= 0; i
--)
592 entry
= the_history
[i
];
595 if (entry
->data
== needle
)
601 /* Remove history element WHICH from the history. The removed
602 element is returned to you so you can free the line, data,
603 and containing structure. */
605 remove_history (int which
)
607 HIST_ENTRY
*return_value
;
610 HIST_ENTRY
**start
, **end
;
615 if (which
< 0 || which
>= history_length
|| history_length
== 0 || the_history
== 0)
616 return ((HIST_ENTRY
*)NULL
);
618 return_value
= the_history
[which
];
621 /* Copy the rest of the entries, moving down one slot. Copy includes
623 nentries
= history_length
- which
;
624 start
= the_history
+ which
;
626 memmove (start
, end
, nentries
* sizeof (HIST_ENTRY
*));
628 for (i
= which
; i
< history_length
; i
++)
629 the_history
[i
] = the_history
[i
+ 1];
634 return (return_value
);
638 remove_history_range (int first
, int last
)
640 HIST_ENTRY
**return_value
;
643 HIST_ENTRY
**start
, **end
;
645 if (the_history
== 0 || history_length
== 0)
646 return ((HIST_ENTRY
**)NULL
);
647 if (first
< 0 || first
>= history_length
|| last
< 0 || last
>= history_length
)
648 return ((HIST_ENTRY
**)NULL
);
650 return (HIST_ENTRY
**)NULL
;
652 nentries
= last
- first
+ 1;
653 return_value
= (HIST_ENTRY
**)malloc ((nentries
+ 1) * sizeof (HIST_ENTRY
*));
654 if (return_value
== 0)
657 /* Return all the deleted entries in a list */
658 for (i
= first
; i
<= last
; i
++)
659 return_value
[i
- first
] = the_history
[i
];
660 return_value
[i
- first
] = (HIST_ENTRY
*)NULL
;
662 /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
664 start
= the_history
+ first
;
665 end
= the_history
+ last
+ 1;
666 memmove (start
, end
, (history_length
- last
) * sizeof (HIST_ENTRY
*));
668 history_length
-= nentries
;
670 return (return_value
);
673 /* Stifle the history list, remembering only MAX number of lines. */
675 stifle_history (int max
)
682 if (history_length
> max
)
684 /* This loses because we cannot free the data. */
685 for (i
= 0, j
= history_length
- max
; i
< j
; i
++)
686 free_history_entry (the_history
[i
]);
689 for (j
= 0, i
= history_length
- max
; j
< max
; i
++, j
++)
690 the_history
[j
] = the_history
[i
];
691 the_history
[j
] = (HIST_ENTRY
*)NULL
;
696 max_input_history
= history_max_entries
= max
;
699 /* Stop stifling the history. This returns the previous maximum
700 number of history entries. The value is positive if the history
701 was stifled, negative if it wasn't. */
703 unstifle_history (void)
708 return (history_max_entries
);
711 return (-history_max_entries
);
715 history_is_stifled (void)
717 return (history_stifled
);
725 /* This loses because we cannot free the data. */
726 for (i
= 0; i
< history_length
; i
++)
728 free_history_entry (the_history
[i
]);
729 the_history
[i
] = (HIST_ENTRY
*)NULL
;
732 history_offset
= history_length
= 0;
733 history_base
= 1; /* reset history base to default */