]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/history.c
Bash-4.4 distribution sources and documentation
[thirdparty/bash.git] / lib / readline / history.c
CommitLineData
b80f6443 1/* history.c -- standalone history library */
726f6388 2
a0c0a00f 3/* Copyright (C) 1989-2015 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
ccc6cda3
JA
60/* The number of slots to increase the_history by. */
61#define DEFAULT_HISTORY_GROW_SIZE 50
726f6388 62
b80f6443
JA
63static char *hist_inittime PARAMS((void));
64
726f6388
JA
65/* **************************************************************** */
66/* */
67/* History Functions */
68/* */
69/* **************************************************************** */
70
71/* An array of HIST_ENTRY. This is where we store the history. */
72static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
73
74/* Non-zero means that we have enforced a limit on the amount of
75 history that we save. */
ccc6cda3 76static int history_stifled;
726f6388 77
f73dda09
JA
78/* The current number of slots allocated to the input_history. */
79static int history_size;
80
726f6388
JA
81/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
82 entries to remember. */
28ef6c31
JA
83int history_max_entries;
84int max_input_history; /* backwards compatibility */
726f6388
JA
85
86/* The current location of the interactive history pointer. Just makes
87 life easier for outside callers. */
ccc6cda3 88int history_offset;
726f6388 89
ccc6cda3
JA
90/* The number of strings currently stored in the history list. */
91int history_length;
726f6388 92
726f6388
JA
93/* The logical `base' of the history array. It defaults to 1. */
94int history_base = 1;
95
96/* Return the current HISTORY_STATE of the history. */
97HISTORY_STATE *
98history_get_history_state ()
99{
100 HISTORY_STATE *state;
101
102 state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
103 state->entries = the_history;
104 state->offset = history_offset;
105 state->length = history_length;
106 state->size = history_size;
107 state->flags = 0;
108 if (history_stifled)
109 state->flags |= HS_STIFLED;
110
111 return (state);
112}
113
114/* Set the state of the current history array to STATE. */
115void
116history_set_history_state (state)
117 HISTORY_STATE *state;
118{
119 the_history = state->entries;
120 history_offset = state->offset;
121 history_length = state->length;
122 history_size = state->size;
123 if (state->flags & HS_STIFLED)
124 history_stifled = 1;
125}
126
127/* Begin a session in which the history functions might be used. This
128 initializes interactive variables. */
129void
130using_history ()
131{
132 history_offset = history_length;
133}
134
135/* Return the number of bytes that the primary history entries are using.
b80f6443
JA
136 This just adds up the lengths of the_history->lines and the associated
137 timestamps. */
726f6388
JA
138int
139history_total_bytes ()
140{
141 register int i, result;
142
28ef6c31 143 for (i = result = 0; the_history && the_history[i]; i++)
b80f6443 144 result += HISTENT_BYTES (the_history[i]);
726f6388
JA
145
146 return (result);
147}
148
ccc6cda3
JA
149/* Returns the magic number which says what history element we are
150 looking at now. In this implementation, it returns history_offset. */
151int
152where_history ()
153{
154 return (history_offset);
155}
156
157/* Make the current history item be the one at POS, an absolute index.
158 Returns zero if POS is out of range, else non-zero. */
159int
160history_set_pos (pos)
161 int pos;
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 **
173history_list ()
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 *
181current_history ()
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 *
192previous_history ()
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 *
201next_history ()
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 *
209history_get (offset)
210 int offset;
211{
212 int local_index;
213
214 local_index = offset - history_base;
95732b49 215 return (local_index >= history_length || local_index < 0 || the_history == 0)
ccc6cda3
JA
216 ? (HIST_ENTRY *)NULL
217 : the_history[local_index];
218}
219
0628567a
JA
220HIST_ENTRY *
221alloc_history_entry (string, ts)
222 char *string;
223 char *ts;
224{
225 HIST_ENTRY *temp;
226
227 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
228
229 temp->line = string ? savestring (string) : string;
230 temp->data = (char *)NULL;
231 temp->timestamp = ts;
232
233 return temp;
234}
235
b80f6443
JA
236time_t
237history_get_time (hist)
238 HIST_ENTRY *hist;
239{
240 char *ts;
241 time_t t;
242
243 if (hist == 0 || hist->timestamp == 0)
244 return 0;
245 ts = hist->timestamp;
246 if (ts[0] != history_comment_char)
247 return 0;
a0c0a00f 248 errno = 0;
ac50fbac 249 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
a0c0a00f
CR
250 if (errno == ERANGE)
251 return (time_t)0;
b80f6443
JA
252 return t;
253}
254
255static char *
256hist_inittime ()
257{
258 time_t t;
259 char ts[64], *ret;
260
261 t = (time_t) time ((time_t *)0);
262#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
263 snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
264#else
265 sprintf (ts, "X%lu", (unsigned long) t);
266#endif
267 ret = savestring (ts);
268 ret[0] = history_comment_char;
269
270 return ret;
271}
272
726f6388
JA
273/* Place STRING at the end of the history list. The data field
274 is set to NULL. */
275void
276add_history (string)
28ef6c31 277 const char *string;
726f6388
JA
278{
279 HIST_ENTRY *temp;
280
28ef6c31 281 if (history_stifled && (history_length == history_max_entries))
726f6388
JA
282 {
283 register int i;
284
285 /* If the history is stifled, and history_length is zero,
28ef6c31 286 and it equals history_max_entries, we don't save items. */
726f6388
JA
287 if (history_length == 0)
288 return;
289
290 /* If there is something in the slot, then remove it. */
291 if (the_history[0])
b80f6443 292 (void) free_history_entry (the_history[0]);
726f6388 293
a0c0a00f
CR
294 /* Copy the rest of the entries, moving down one slot. Copy includes
295 trailing NULL. */
296#if 0
726f6388
JA
297 for (i = 0; i < history_length; i++)
298 the_history[i] = the_history[i + 1];
a0c0a00f
CR
299#else
300 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
301#endif
726f6388
JA
302
303 history_base++;
726f6388
JA
304 }
305 else
306 {
ccc6cda3 307 if (history_size == 0)
726f6388 308 {
a0c0a00f
CR
309 if (history_stifled && history_max_entries > 0)
310 history_size = history_max_entries + 2;
311 else
312 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
726f6388
JA
313 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
314 history_length = 1;
726f6388
JA
315 }
316 else
317 {
318 if (history_length == (history_size - 1))
319 {
320 history_size += DEFAULT_HISTORY_GROW_SIZE;
321 the_history = (HIST_ENTRY **)
322 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
323 }
324 history_length++;
325 }
326 }
327
a0c0a00f 328 temp = alloc_history_entry ((char *)string, hist_inittime ());
b80f6443 329
726f6388
JA
330 the_history[history_length] = (HIST_ENTRY *)NULL;
331 the_history[history_length - 1] = temp;
332}
333
b80f6443
JA
334/* Change the time stamp of the most recent history entry to STRING. */
335void
336add_history_time (string)
337 const char *string;
338{
339 HIST_ENTRY *hs;
340
ac50fbac 341 if (string == 0 || history_length < 1)
3185942a 342 return;
b80f6443
JA
343 hs = the_history[history_length - 1];
344 FREE (hs->timestamp);
345 hs->timestamp = savestring (string);
346}
347
348/* Free HIST and return the data so the calling application can free it
349 if necessary and desired. */
350histdata_t
351free_history_entry (hist)
352 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;
495aee44 361 xfree (hist);
b80f6443
JA
362 return (x);
363}
0628567a
JA
364
365HIST_ENTRY *
366copy_history_entry (hist)
367 HIST_ENTRY *hist;
368{
369 HIST_ENTRY *ret;
370 char *ts;
371
372 if (hist == 0)
373 return hist;
374
375 ret = alloc_history_entry (hist->line, (char *)NULL);
376
377 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
378 ret->timestamp = ts;
379
380 ret->data = hist->data;
381
382 return ret;
383}
b80f6443 384
726f6388
JA
385/* Make the history entry at WHICH have LINE and DATA. This returns
386 the old entry so you can dispose of the data. In the case of an
387 invalid WHICH, a NULL pointer is returned. */
388HIST_ENTRY *
389replace_history_entry (which, line, data)
390 int which;
28ef6c31 391 const char *line;
b72432fd 392 histdata_t data;
726f6388 393{
28ef6c31 394 HIST_ENTRY *temp, *old_value;
726f6388 395
95732b49 396 if (which < 0 || which >= history_length)
726f6388
JA
397 return ((HIST_ENTRY *)NULL);
398
28ef6c31 399 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
726f6388
JA
400 old_value = the_history[which];
401
402 temp->line = savestring (line);
403 temp->data = data;
b80f6443 404 temp->timestamp = savestring (old_value->timestamp);
726f6388
JA
405 the_history[which] = temp;
406
407 return (old_value);
408}
409
a0c0a00f
CR
410/* Append LINE to the history line at offset WHICH, adding a newline to the
411 end of the current line first. This can be used to construct multi-line
412 history entries while reading lines from the history file. */
413void
414_hs_append_history_line (which, line)
415 int which;
416 const char *line;
417{
418 HIST_ENTRY *hent;
419 size_t newlen, curlen;
420 char *newline;
421
422 hent = the_history[which];
423 curlen = strlen (hent->line);
424 newlen = curlen + strlen (line) + 2;
425 newline = realloc (hent->line, newlen);
426 if (newline)
427 {
428 hent->line = newline;
429 hent->line[curlen++] = '\n';
430 strcpy (hent->line + curlen, line);
431 }
432}
433
0628567a
JA
434/* Replace the DATA in the specified history entries, replacing OLD with
435 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
436 all of the history entries where entry->data == OLD; WHICH == -2 means
437 to replace the `newest' history entry where entry->data == OLD; and
438 WHICH >= 0 means to replace that particular history entry's data, as
439 long as it matches OLD. */
440void
a0c0a00f 441_hs_replace_history_data (which, old, new)
0628567a
JA
442 int which;
443 histdata_t *old, *new;
444{
445 HIST_ENTRY *entry;
446 register int i, last;
447
448 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
449 return;
450
451 if (which >= 0)
452 {
453 entry = the_history[which];
454 if (entry && entry->data == old)
455 entry->data = new;
456 return;
457 }
458
459 last = -1;
460 for (i = 0; i < history_length; i++)
461 {
462 entry = the_history[i];
463 if (entry == 0)
464 continue;
465 if (entry->data == old)
466 {
467 last = i;
468 if (which == -1)
469 entry->data = new;
470 }
471 }
472 if (which == -2 && last >= 0)
473 {
474 entry = the_history[last];
475 entry->data = new; /* XXX - we don't check entry->old */
476 }
477}
478
726f6388
JA
479/* Remove history element WHICH from the history. The removed
480 element is returned to you so you can free the line, data,
481 and containing structure. */
482HIST_ENTRY *
483remove_history (which)
484 int which;
485{
486 HIST_ENTRY *return_value;
28ef6c31 487 register int i;
726f6388 488
95732b49
JA
489 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
490 return ((HIST_ENTRY *)NULL);
726f6388 491
95732b49 492 return_value = the_history[which];
726f6388 493
95732b49
JA
494 for (i = which; i < history_length; i++)
495 the_history[i] = the_history[i + 1];
496
497 history_length--;
726f6388
JA
498
499 return (return_value);
500}
501
502/* Stifle the history list, remembering only MAX number of lines. */
503void
504stifle_history (max)
505 int max;
506{
28ef6c31
JA
507 register int i, j;
508
726f6388
JA
509 if (max < 0)
510 max = 0;
511
512 if (history_length > max)
513 {
726f6388 514 /* This loses because we cannot free the data. */
ccc6cda3 515 for (i = 0, j = history_length - max; i < j; i++)
b80f6443 516 free_history_entry (the_history[i]);
726f6388
JA
517
518 history_base = i;
519 for (j = 0, i = history_length - max; j < max; i++, j++)
520 the_history[j] = the_history[i];
521 the_history[j] = (HIST_ENTRY *)NULL;
522 history_length = j;
523 }
524
525 history_stifled = 1;
28ef6c31 526 max_input_history = history_max_entries = max;
726f6388
JA
527}
528
7117c2d2
JA
529/* Stop stifling the history. This returns the previous maximum
530 number of history entries. The value is positive if the history
3185942a 531 was stifled, negative if it wasn't. */
726f6388
JA
532int
533unstifle_history ()
534{
726f6388
JA
535 if (history_stifled)
536 {
726f6388 537 history_stifled = 0;
7117c2d2 538 return (history_max_entries);
726f6388 539 }
7117c2d2
JA
540 else
541 return (-history_max_entries);
726f6388
JA
542}
543
544int
545history_is_stifled ()
546{
547 return (history_stifled);
548}
549
ccc6cda3
JA
550void
551clear_history ()
726f6388
JA
552{
553 register int i;
726f6388 554
ccc6cda3
JA
555 /* This loses because we cannot free the data. */
556 for (i = 0; i < history_length; i++)
726f6388 557 {
b80f6443 558 free_history_entry (the_history[i]);
ccc6cda3 559 the_history[i] = (HIST_ENTRY *)NULL;
726f6388
JA
560 }
561
ccc6cda3 562 history_offset = history_length = 0;
726f6388 563}