Automatic date update in version.in
[deliverable/binutils-gdb.git] / readline / history.c
CommitLineData
5bdf8622 1/* history.c -- standalone history library */
d60d9f65 2
cb41b9e7 3/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
d60d9f65 4
cc88a640 5 This file contains the GNU History Library (History), a set of
d60d9f65
SS
6 routines for managing the text of previously typed lines.
7
cc88a640 8 History is free software: you can redistribute it and/or modify
d60d9f65 9 it under the terms of the GNU General Public License as published by
cc88a640
JK
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
d60d9f65 12
cc88a640
JK
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.
d60d9f65 17
cc88a640
JK
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*/
d60d9f65
SS
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
775e241e
TT
46#include <errno.h>
47
d60d9f65
SS
48#include "history.h"
49#include "histlib.h"
50
1b17e766 51#include "xmalloc.h"
d60d9f65 52
775e241e
TT
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
60#define MAX_HISTORY_INITIAL_SIZE 8192
61
d60d9f65
SS
62/* The number of slots to increase the_history by. */
63#define DEFAULT_HISTORY_GROW_SIZE 50
64
5bdf8622
DJ
65static char *hist_inittime PARAMS((void));
66
d60d9f65
SS
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. */
78static int history_stifled;
79
9255ee31
EZ
80/* The current number of slots allocated to the input_history. */
81static int history_size;
82
d60d9f65
SS
83/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
84 entries to remember. */
9255ee31
EZ
85int history_max_entries;
86int max_input_history; /* backwards compatibility */
d60d9f65
SS
87
88/* The current location of the interactive history pointer. Just makes
89 life easier for outside callers. */
90int history_offset;
91
92/* The number of strings currently stored in the history list. */
93int history_length;
94
d60d9f65
SS
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 *
cb41b9e7 100history_get_history_state (void)
d60d9f65
SS
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
cb41b9e7 118history_set_history_state (HISTORY_STATE *state)
d60d9f65
SS
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
cb41b9e7 131using_history (void)
d60d9f65
SS
132{
133 history_offset = history_length;
134}
135
136/* Return the number of bytes that the primary history entries are using.
5bdf8622
DJ
137 This just adds up the lengths of the_history->lines and the associated
138 timestamps. */
d60d9f65 139int
cb41b9e7 140history_total_bytes (void)
d60d9f65
SS
141{
142 register int i, result;
143
9255ee31 144 for (i = result = 0; the_history && the_history[i]; i++)
5bdf8622 145 result += HISTENT_BYTES (the_history[i]);
d60d9f65
SS
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. */
152int
cb41b9e7 153where_history (void)
d60d9f65
SS
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
cb41b9e7 161history_set_pos (int pos)
d60d9f65
SS
162{
163 if (pos > history_length || pos < 0 || !the_history)
164 return (0);
165 history_offset = pos;
166 return (1);
167}
168
cc88a640 169/* Return the current history array. The caller has to be careful, since this
d60d9f65
SS
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 **
cb41b9e7 173history_list (void)
d60d9f65
SS
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 *
cb41b9e7 181current_history (void)
d60d9f65
SS
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 *
cb41b9e7 192previous_history (void)
d60d9f65
SS
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 *
cb41b9e7 201next_history (void)
d60d9f65
SS
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 *
cb41b9e7 209history_get (int offset)
d60d9f65
SS
210{
211 int local_index;
212
213 local_index = offset - history_base;
5bdf8622 214 return (local_index >= history_length || local_index < 0 || the_history == 0)
d60d9f65
SS
215 ? (HIST_ENTRY *)NULL
216 : the_history[local_index];
217}
218
cc88a640 219HIST_ENTRY *
cb41b9e7 220alloc_history_entry (char *string, char *ts)
cc88a640
JK
221{
222 HIST_ENTRY *temp;
223
224 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
225
226 temp->line = string ? savestring (string) : string;
227 temp->data = (char *)NULL;
228 temp->timestamp = ts;
229
230 return temp;
231}
232
5bdf8622 233time_t
cb41b9e7 234history_get_time (HIST_ENTRY *hist)
5bdf8622
DJ
235{
236 char *ts;
237 time_t t;
238
239 if (hist == 0 || hist->timestamp == 0)
240 return 0;
241 ts = hist->timestamp;
242 if (ts[0] != history_comment_char)
243 return 0;
775e241e
TT
244 errno = 0;
245 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
246 if (errno == ERANGE)
247 return (time_t)0;
5bdf8622
DJ
248 return t;
249}
250
251static char *
cb41b9e7 252hist_inittime (void)
5bdf8622
DJ
253{
254 time_t t;
255 char ts[64], *ret;
256
257 t = (time_t) time ((time_t *)0);
258#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
259 snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
260#else
261 sprintf (ts, "X%lu", (unsigned long) t);
262#endif
263 ret = savestring (ts);
264 ret[0] = history_comment_char;
265
266 return ret;
267}
268
d60d9f65
SS
269/* Place STRING at the end of the history list. The data field
270 is set to NULL. */
271void
cb41b9e7 272add_history (const char *string)
d60d9f65
SS
273{
274 HIST_ENTRY *temp;
775e241e 275 int new_length;
d60d9f65 276
9255ee31 277 if (history_stifled && (history_length == history_max_entries))
d60d9f65
SS
278 {
279 register int i;
280
281 /* If the history is stifled, and history_length is zero,
9255ee31 282 and it equals history_max_entries, we don't save items. */
d60d9f65
SS
283 if (history_length == 0)
284 return;
285
286 /* If there is something in the slot, then remove it. */
287 if (the_history[0])
5bdf8622 288 (void) free_history_entry (the_history[0]);
d60d9f65 289
775e241e
TT
290 /* Copy the rest of the entries, moving down one slot. Copy includes
291 trailing NULL. */
292 memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
d60d9f65 293
775e241e 294 new_length = history_length;
d60d9f65
SS
295 history_base++;
296 }
297 else
298 {
299 if (history_size == 0)
300 {
775e241e
TT
301 if (history_stifled && history_max_entries > 0)
302 history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
303 ? MAX_HISTORY_INITIAL_SIZE
304 : history_max_entries + 2;
305 else
306 history_size = DEFAULT_HISTORY_INITIAL_SIZE;
d60d9f65 307 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
775e241e 308 new_length = 1;
d60d9f65
SS
309 }
310 else
311 {
312 if (history_length == (history_size - 1))
313 {
314 history_size += DEFAULT_HISTORY_GROW_SIZE;
315 the_history = (HIST_ENTRY **)
316 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
317 }
775e241e 318 new_length = history_length + 1;
d60d9f65
SS
319 }
320 }
321
775e241e 322 temp = alloc_history_entry ((char *)string, hist_inittime ());
5bdf8622 323
775e241e
TT
324 the_history[new_length] = (HIST_ENTRY *)NULL;
325 the_history[new_length - 1] = temp;
326 history_length = new_length;
d60d9f65
SS
327}
328
5bdf8622
DJ
329/* Change the time stamp of the most recent history entry to STRING. */
330void
cb41b9e7 331add_history_time (const char *string)
5bdf8622
DJ
332{
333 HIST_ENTRY *hs;
334
775e241e 335 if (string == 0 || history_length < 1)
cc88a640 336 return;
5bdf8622
DJ
337 hs = the_history[history_length - 1];
338 FREE (hs->timestamp);
339 hs->timestamp = savestring (string);
340}
341
342/* Free HIST and return the data so the calling application can free it
343 if necessary and desired. */
344histdata_t
cb41b9e7 345free_history_entry (HIST_ENTRY *hist)
5bdf8622
DJ
346{
347 histdata_t x;
348
349 if (hist == 0)
350 return ((histdata_t) 0);
351 FREE (hist->line);
352 FREE (hist->timestamp);
353 x = hist->data;
cc88a640 354 xfree (hist);
5bdf8622
DJ
355 return (x);
356}
cc88a640
JK
357
358HIST_ENTRY *
cb41b9e7 359copy_history_entry (HIST_ENTRY *hist)
cc88a640
JK
360{
361 HIST_ENTRY *ret;
362 char *ts;
363
364 if (hist == 0)
365 return hist;
366
367 ret = alloc_history_entry (hist->line, (char *)NULL);
368
369 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
370 ret->timestamp = ts;
371
372 ret->data = hist->data;
373
374 return ret;
375}
5bdf8622 376
d60d9f65
SS
377/* Make the history entry at WHICH have LINE and DATA. This returns
378 the old entry so you can dispose of the data. In the case of an
379 invalid WHICH, a NULL pointer is returned. */
380HIST_ENTRY *
cb41b9e7 381replace_history_entry (int which, const char *line, histdata_t data)
d60d9f65 382{
9255ee31 383 HIST_ENTRY *temp, *old_value;
d60d9f65 384
5bdf8622 385 if (which < 0 || which >= history_length)
d60d9f65
SS
386 return ((HIST_ENTRY *)NULL);
387
9255ee31 388 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
d60d9f65
SS
389 old_value = the_history[which];
390
391 temp->line = savestring (line);
392 temp->data = data;
5bdf8622 393 temp->timestamp = savestring (old_value->timestamp);
d60d9f65
SS
394 the_history[which] = temp;
395
396 return (old_value);
397}
398
775e241e
TT
399/* Append LINE to the history line at offset WHICH, adding a newline to the
400 end of the current line first. This can be used to construct multi-line
401 history entries while reading lines from the history file. */
402void
cb41b9e7 403_hs_append_history_line (int which, const char *line)
775e241e
TT
404{
405 HIST_ENTRY *hent;
cb41b9e7 406 size_t newlen, curlen, minlen;
775e241e
TT
407 char *newline;
408
409 hent = the_history[which];
410 curlen = strlen (hent->line);
cb41b9e7
TT
411 minlen = curlen + strlen (line) + 2; /* min space needed */
412 if (curlen > 256) /* XXX - for now */
413 {
414 newlen = 512; /* now realloc in powers of 2 */
415 /* we recalcluate every time; the operations are cheap */
416 while (newlen < minlen)
417 newlen <<= 1;
418 }
419 else
420 newlen = minlen;
421 /* Assume that realloc returns the same pointer and doesn't try a new
422 alloc/copy if the new size is the same as the one last passed. */
775e241e
TT
423 newline = realloc (hent->line, newlen);
424 if (newline)
425 {
426 hent->line = newline;
427 hent->line[curlen++] = '\n';
428 strcpy (hent->line + curlen, line);
429 }
430}
431
cc88a640
JK
432/* Replace the DATA in the specified history entries, replacing OLD with
433 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
434 all of the history entries where entry->data == OLD; WHICH == -2 means
435 to replace the `newest' history entry where entry->data == OLD; and
436 WHICH >= 0 means to replace that particular history entry's data, as
437 long as it matches OLD. */
438void
cb41b9e7 439_hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
cc88a640
JK
440{
441 HIST_ENTRY *entry;
442 register int i, last;
443
444 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
445 return;
446
447 if (which >= 0)
448 {
449 entry = the_history[which];
450 if (entry && entry->data == old)
451 entry->data = new;
452 return;
453 }
454
455 last = -1;
456 for (i = 0; i < history_length; i++)
457 {
458 entry = the_history[i];
459 if (entry == 0)
460 continue;
461 if (entry->data == old)
462 {
463 last = i;
464 if (which == -1)
465 entry->data = new;
466 }
467 }
468 if (which == -2 && last >= 0)
469 {
470 entry = the_history[last];
471 entry->data = new; /* XXX - we don't check entry->old */
472 }
473}
474
d60d9f65
SS
475/* Remove history element WHICH from the history. The removed
476 element is returned to you so you can free the line, data,
477 and containing structure. */
478HIST_ENTRY *
cb41b9e7 479remove_history (int which)
d60d9f65
SS
480{
481 HIST_ENTRY *return_value;
9255ee31 482 register int i;
cb41b9e7
TT
483#if 1
484 int nentries;
485 HIST_ENTRY **start, **end;
486#endif
d60d9f65 487
5bdf8622
DJ
488 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
489 return ((HIST_ENTRY *)NULL);
d60d9f65 490
5bdf8622 491 return_value = the_history[which];
d60d9f65 492
cb41b9e7
TT
493#if 1
494 /* Copy the rest of the entries, moving down one slot. Copy includes
495 trailing NULL. */
496 nentries = history_length - which;
497 start = the_history + which;
498 end = start + 1;
499 memmove (start, end, nentries * sizeof (HIST_ENTRY *));
500#else
5bdf8622
DJ
501 for (i = which; i < history_length; i++)
502 the_history[i] = the_history[i + 1];
cb41b9e7 503#endif
5bdf8622
DJ
504
505 history_length--;
d60d9f65
SS
506
507 return (return_value);
508}
509
cb41b9e7
TT
510HIST_ENTRY **
511remove_history_range (int first, int last)
512{
513 HIST_ENTRY **return_value;
514 register int i;
515 int nentries;
516 HIST_ENTRY **start, **end;
517
518 if (the_history == 0 || history_length == 0)
519 return ((HIST_ENTRY **)NULL);
520 if (first < 0 || first >= history_length || last < 0 || last >= history_length)
521 return ((HIST_ENTRY **)NULL);
522 if (first > last)
523 return (HIST_ENTRY **)NULL;
524
525 nentries = last - first + 1;
526 return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
527 if (return_value == 0)
528 return return_value;
529
530 /* Return all the deleted entries in a list */
531 for (i = first ; i <= last; i++)
532 return_value[i - first] = the_history[i];
533 return_value[i - first] = (HIST_ENTRY *)NULL;
534
535 /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
536 trailing NULL. */
537 start = the_history + first;
538 end = the_history + last + 1;
539 memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
540
541 history_length -= nentries;
542
543 return (return_value);
544}
545
d60d9f65
SS
546/* Stifle the history list, remembering only MAX number of lines. */
547void
cb41b9e7 548stifle_history (int max)
d60d9f65 549{
9255ee31
EZ
550 register int i, j;
551
d60d9f65
SS
552 if (max < 0)
553 max = 0;
554
555 if (history_length > max)
556 {
d60d9f65
SS
557 /* This loses because we cannot free the data. */
558 for (i = 0, j = history_length - max; i < j; i++)
5bdf8622 559 free_history_entry (the_history[i]);
d60d9f65
SS
560
561 history_base = i;
562 for (j = 0, i = history_length - max; j < max; i++, j++)
563 the_history[j] = the_history[i];
564 the_history[j] = (HIST_ENTRY *)NULL;
565 history_length = j;
566 }
567
568 history_stifled = 1;
9255ee31 569 max_input_history = history_max_entries = max;
d60d9f65
SS
570}
571
9255ee31
EZ
572/* Stop stifling the history. This returns the previous maximum
573 number of history entries. The value is positive if the history
cc88a640 574 was stifled, negative if it wasn't. */
d60d9f65 575int
cb41b9e7 576unstifle_history (void)
d60d9f65
SS
577{
578 if (history_stifled)
579 {
580 history_stifled = 0;
9255ee31 581 return (history_max_entries);
d60d9f65 582 }
9255ee31
EZ
583 else
584 return (-history_max_entries);
d60d9f65
SS
585}
586
587int
cb41b9e7 588history_is_stifled (void)
d60d9f65
SS
589{
590 return (history_stifled);
591}
592
593void
cb41b9e7 594clear_history (void)
d60d9f65
SS
595{
596 register int i;
597
598 /* This loses because we cannot free the data. */
599 for (i = 0; i < history_length; i++)
600 {
5bdf8622 601 free_history_entry (the_history[i]);
d60d9f65
SS
602 the_history[i] = (HIST_ENTRY *)NULL;
603 }
604
605 history_offset = history_length = 0;
cb41b9e7 606 history_base = 1; /* reset history base to default */
d60d9f65 607}
This page took 1.141022 seconds and 4 git commands to generate.