]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/history.c
bash-4.3-beta overlay
[thirdparty/bash.git] / lib / readline / history.c
CommitLineData
d3a24ed2 1/* history.c -- standalone history library */
726f6388 2
ba4ab055 3/* Copyright (C) 1989-2011 Free Software Foundation, Inc.
726f6388 4
2e4498b3 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
2e4498b3 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
2e4498b3
CR
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*/
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
726f6388 46#include "history.h"
ccc6cda3 47#include "histlib.h"
726f6388 48
bb70624e 49#include "xmalloc.h"
726f6388 50
ccc6cda3
JA
51/* The number of slots to increase the_history by. */
52#define DEFAULT_HISTORY_GROW_SIZE 50
726f6388 53
d3a24ed2
CR
54static char *hist_inittime PARAMS((void));
55
726f6388
JA
56/* **************************************************************** */
57/* */
58/* History Functions */
59/* */
60/* **************************************************************** */
61
62/* An array of HIST_ENTRY. This is where we store the history. */
63static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
64
65/* Non-zero means that we have enforced a limit on the amount of
66 history that we save. */
ccc6cda3 67static int history_stifled;
726f6388 68
f73dda09
JA
69/* The current number of slots allocated to the input_history. */
70static int history_size;
71
726f6388
JA
72/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
73 entries to remember. */
28ef6c31
JA
74int history_max_entries;
75int max_input_history; /* backwards compatibility */
726f6388
JA
76
77/* The current location of the interactive history pointer. Just makes
78 life easier for outside callers. */
ccc6cda3 79int history_offset;
726f6388 80
ccc6cda3
JA
81/* The number of strings currently stored in the history list. */
82int history_length;
726f6388 83
726f6388
JA
84/* The logical `base' of the history array. It defaults to 1. */
85int history_base = 1;
86
87/* Return the current HISTORY_STATE of the history. */
88HISTORY_STATE *
89history_get_history_state ()
90{
91 HISTORY_STATE *state;
92
93 state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
94 state->entries = the_history;
95 state->offset = history_offset;
96 state->length = history_length;
97 state->size = history_size;
98 state->flags = 0;
99 if (history_stifled)
100 state->flags |= HS_STIFLED;
101
102 return (state);
103}
104
105/* Set the state of the current history array to STATE. */
106void
107history_set_history_state (state)
108 HISTORY_STATE *state;
109{
110 the_history = state->entries;
111 history_offset = state->offset;
112 history_length = state->length;
113 history_size = state->size;
114 if (state->flags & HS_STIFLED)
115 history_stifled = 1;
116}
117
118/* Begin a session in which the history functions might be used. This
119 initializes interactive variables. */
120void
121using_history ()
122{
123 history_offset = history_length;
124}
125
126/* Return the number of bytes that the primary history entries are using.
d3a24ed2
CR
127 This just adds up the lengths of the_history->lines and the associated
128 timestamps. */
726f6388
JA
129int
130history_total_bytes ()
131{
132 register int i, result;
133
28ef6c31 134 for (i = result = 0; the_history && the_history[i]; i++)
d3a24ed2 135 result += HISTENT_BYTES (the_history[i]);
726f6388
JA
136
137 return (result);
138}
139
ccc6cda3
JA
140/* Returns the magic number which says what history element we are
141 looking at now. In this implementation, it returns history_offset. */
142int
143where_history ()
144{
145 return (history_offset);
146}
147
148/* Make the current history item be the one at POS, an absolute index.
149 Returns zero if POS is out of range, else non-zero. */
150int
151history_set_pos (pos)
152 int pos;
153{
154 if (pos > history_length || pos < 0 || !the_history)
155 return (0);
156 history_offset = pos;
157 return (1);
158}
159
d3ad40de 160/* Return the current history array. The caller has to be careful, since this
ccc6cda3
JA
161 is the actual array of data, and could be bashed or made corrupt easily.
162 The array is terminated with a NULL pointer. */
163HIST_ENTRY **
164history_list ()
165{
166 return (the_history);
167}
168
169/* Return the history entry at the current position, as determined by
170 history_offset. If there is no entry there, return a NULL pointer. */
171HIST_ENTRY *
172current_history ()
173{
174 return ((history_offset == history_length) || the_history == 0)
175 ? (HIST_ENTRY *)NULL
176 : the_history[history_offset];
177}
178
179/* Back up history_offset to the previous history entry, and return
180 a pointer to that entry. If there is no previous entry then return
181 a NULL pointer. */
182HIST_ENTRY *
183previous_history ()
184{
185 return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
186}
187
188/* Move history_offset forward to the next history entry, and return
189 a pointer to that entry. If there is no next entry then return a
190 NULL pointer. */
191HIST_ENTRY *
192next_history ()
193{
194 return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
195}
196
197/* Return the history entry which is logically at OFFSET in the history array.
198 OFFSET is relative to history_base. */
199HIST_ENTRY *
200history_get (offset)
201 int offset;
202{
203 int local_index;
204
205 local_index = offset - history_base;
ff247e74 206 return (local_index >= history_length || local_index < 0 || the_history == 0)
ccc6cda3
JA
207 ? (HIST_ENTRY *)NULL
208 : the_history[local_index];
209}
210
d3ad40de
CR
211HIST_ENTRY *
212alloc_history_entry (string, ts)
213 char *string;
214 char *ts;
215{
216 HIST_ENTRY *temp;
217
218 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
219
220 temp->line = string ? savestring (string) : string;
221 temp->data = (char *)NULL;
222 temp->timestamp = ts;
223
224 return temp;
225}
226
d3a24ed2
CR
227time_t
228history_get_time (hist)
229 HIST_ENTRY *hist;
230{
231 char *ts;
232 time_t t;
233
234 if (hist == 0 || hist->timestamp == 0)
235 return 0;
236 ts = hist->timestamp;
237 if (ts[0] != history_comment_char)
238 return 0;
ba4ab055 239 t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
d3a24ed2
CR
240 return t;
241}
242
243static char *
244hist_inittime ()
245{
246 time_t t;
247 char ts[64], *ret;
248
249 t = (time_t) time ((time_t *)0);
250#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
251 snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
252#else
253 sprintf (ts, "X%lu", (unsigned long) t);
254#endif
255 ret = savestring (ts);
256 ret[0] = history_comment_char;
257
258 return ret;
259}
260
726f6388
JA
261/* Place STRING at the end of the history list. The data field
262 is set to NULL. */
263void
264add_history (string)
28ef6c31 265 const char *string;
726f6388
JA
266{
267 HIST_ENTRY *temp;
268
28ef6c31 269 if (history_stifled && (history_length == history_max_entries))
726f6388
JA
270 {
271 register int i;
272
273 /* If the history is stifled, and history_length is zero,
28ef6c31 274 and it equals history_max_entries, we don't save items. */
726f6388
JA
275 if (history_length == 0)
276 return;
277
278 /* If there is something in the slot, then remove it. */
279 if (the_history[0])
d3a24ed2 280 (void) free_history_entry (the_history[0]);
726f6388
JA
281
282 /* Copy the rest of the entries, moving down one slot. */
283 for (i = 0; i < history_length; i++)
284 the_history[i] = the_history[i + 1];
285
286 history_base++;
726f6388
JA
287 }
288 else
289 {
ccc6cda3 290 if (history_size == 0)
726f6388
JA
291 {
292 history_size = DEFAULT_HISTORY_GROW_SIZE;
293 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
294 history_length = 1;
726f6388
JA
295 }
296 else
297 {
298 if (history_length == (history_size - 1))
299 {
300 history_size += DEFAULT_HISTORY_GROW_SIZE;
301 the_history = (HIST_ENTRY **)
302 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
303 }
304 history_length++;
305 }
306 }
307
d3ad40de 308 temp = alloc_history_entry (string, hist_inittime ());
d3a24ed2 309
726f6388
JA
310 the_history[history_length] = (HIST_ENTRY *)NULL;
311 the_history[history_length - 1] = temp;
312}
313
d3a24ed2
CR
314/* Change the time stamp of the most recent history entry to STRING. */
315void
316add_history_time (string)
317 const char *string;
318{
319 HIST_ENTRY *hs;
320
1442f67c 321 if (string == 0 || history_length < 1)
e77a3058 322 return;
d3a24ed2
CR
323 hs = the_history[history_length - 1];
324 FREE (hs->timestamp);
325 hs->timestamp = savestring (string);
326}
327
328/* Free HIST and return the data so the calling application can free it
329 if necessary and desired. */
330histdata_t
331free_history_entry (hist)
332 HIST_ENTRY *hist;
333{
334 histdata_t x;
335
336 if (hist == 0)
337 return ((histdata_t) 0);
338 FREE (hist->line);
339 FREE (hist->timestamp);
340 x = hist->data;
9ec5ed66 341 xfree (hist);
d3a24ed2
CR
342 return (x);
343}
d3ad40de
CR
344
345HIST_ENTRY *
346copy_history_entry (hist)
347 HIST_ENTRY *hist;
348{
349 HIST_ENTRY *ret;
350 char *ts;
351
352 if (hist == 0)
353 return hist;
354
355 ret = alloc_history_entry (hist->line, (char *)NULL);
356
357 ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
358 ret->timestamp = ts;
359
360 ret->data = hist->data;
361
362 return ret;
363}
d3a24ed2 364
726f6388
JA
365/* Make the history entry at WHICH have LINE and DATA. This returns
366 the old entry so you can dispose of the data. In the case of an
367 invalid WHICH, a NULL pointer is returned. */
368HIST_ENTRY *
369replace_history_entry (which, line, data)
370 int which;
28ef6c31 371 const char *line;
b72432fd 372 histdata_t data;
726f6388 373{
28ef6c31 374 HIST_ENTRY *temp, *old_value;
726f6388 375
10590446 376 if (which < 0 || which >= history_length)
726f6388
JA
377 return ((HIST_ENTRY *)NULL);
378
28ef6c31 379 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
726f6388
JA
380 old_value = the_history[which];
381
382 temp->line = savestring (line);
383 temp->data = data;
d3a24ed2 384 temp->timestamp = savestring (old_value->timestamp);
726f6388
JA
385 the_history[which] = temp;
386
387 return (old_value);
388}
389
d3ad40de
CR
390/* Replace the DATA in the specified history entries, replacing OLD with
391 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
392 all of the history entries where entry->data == OLD; WHICH == -2 means
393 to replace the `newest' history entry where entry->data == OLD; and
394 WHICH >= 0 means to replace that particular history entry's data, as
395 long as it matches OLD. */
396void
abe2eb5b 397replace_history_data (which, old, new)
d3ad40de
CR
398 int which;
399 histdata_t *old, *new;
400{
401 HIST_ENTRY *entry;
402 register int i, last;
403
404 if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
405 return;
406
407 if (which >= 0)
408 {
409 entry = the_history[which];
410 if (entry && entry->data == old)
411 entry->data = new;
412 return;
413 }
414
415 last = -1;
416 for (i = 0; i < history_length; i++)
417 {
418 entry = the_history[i];
419 if (entry == 0)
420 continue;
421 if (entry->data == old)
422 {
423 last = i;
424 if (which == -1)
425 entry->data = new;
426 }
427 }
428 if (which == -2 && last >= 0)
429 {
430 entry = the_history[last];
431 entry->data = new; /* XXX - we don't check entry->old */
432 }
433}
434
726f6388
JA
435/* Remove history element WHICH from the history. The removed
436 element is returned to you so you can free the line, data,
437 and containing structure. */
438HIST_ENTRY *
439remove_history (which)
440 int which;
441{
442 HIST_ENTRY *return_value;
28ef6c31 443 register int i;
726f6388 444
ff247e74 445 if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
10590446 446 return ((HIST_ENTRY *)NULL);
726f6388 447
10590446 448 return_value = the_history[which];
227f982e 449
10590446
CR
450 for (i = which; i < history_length; i++)
451 the_history[i] = the_history[i + 1];
452
453 history_length--;
726f6388
JA
454
455 return (return_value);
456}
457
458/* Stifle the history list, remembering only MAX number of lines. */
459void
460stifle_history (max)
461 int max;
462{
28ef6c31
JA
463 register int i, j;
464
726f6388
JA
465 if (max < 0)
466 max = 0;
467
468 if (history_length > max)
469 {
726f6388 470 /* This loses because we cannot free the data. */
ccc6cda3 471 for (i = 0, j = history_length - max; i < j; i++)
d3a24ed2 472 free_history_entry (the_history[i]);
726f6388
JA
473
474 history_base = i;
475 for (j = 0, i = history_length - max; j < max; i++, j++)
476 the_history[j] = the_history[i];
477 the_history[j] = (HIST_ENTRY *)NULL;
478 history_length = j;
479 }
480
481 history_stifled = 1;
28ef6c31 482 max_input_history = history_max_entries = max;
726f6388
JA
483}
484
7117c2d2
JA
485/* Stop stifling the history. This returns the previous maximum
486 number of history entries. The value is positive if the history
f13513ff 487 was stifled, negative if it wasn't. */
726f6388
JA
488int
489unstifle_history ()
490{
726f6388
JA
491 if (history_stifled)
492 {
726f6388 493 history_stifled = 0;
7117c2d2 494 return (history_max_entries);
726f6388 495 }
7117c2d2
JA
496 else
497 return (-history_max_entries);
726f6388
JA
498}
499
500int
501history_is_stifled ()
502{
503 return (history_stifled);
504}
505
ccc6cda3
JA
506void
507clear_history ()
726f6388
JA
508{
509 register int i;
726f6388 510
ccc6cda3
JA
511 /* This loses because we cannot free the data. */
512 for (i = 0; i < history_length; i++)
726f6388 513 {
d3a24ed2 514 free_history_entry (the_history[i]);
ccc6cda3 515 the_history[i] = (HIST_ENTRY *)NULL;
726f6388
JA
516 }
517
ccc6cda3 518 history_offset = history_length = 0;
726f6388 519}