1 /* history.c -- standalone history library */
3 /* Copyright (C) 1989-2011 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>
51 /* How big to make the_history when we first allocate it. */
52 #define DEFAULT_HISTORY_INITIAL_SIZE 502
54 /* The number of slots to increase the_history by. */
55 #define DEFAULT_HISTORY_GROW_SIZE 50
57 static char *hist_inittime
PARAMS((void));
59 /* **************************************************************** */
61 /* History Functions */
63 /* **************************************************************** */
65 /* An array of HIST_ENTRY. This is where we store the history. */
66 static HIST_ENTRY
**the_history
= (HIST_ENTRY
**)NULL
;
68 /* Non-zero means that we have enforced a limit on the amount of
69 history that we save. */
70 static int history_stifled
;
72 /* The current number of slots allocated to the input_history. */
73 static int history_size
;
75 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
76 entries to remember. */
77 int history_max_entries
;
78 int max_input_history
; /* backwards compatibility */
80 /* The current location of the interactive history pointer. Just makes
81 life easier for outside callers. */
84 /* The number of strings currently stored in the history list. */
87 /* The logical `base' of the history array. It defaults to 1. */
90 /* Return the current HISTORY_STATE of the history. */
92 history_get_history_state ()
96 state
= (HISTORY_STATE
*)xmalloc (sizeof (HISTORY_STATE
));
97 state
->entries
= the_history
;
98 state
->offset
= history_offset
;
99 state
->length
= history_length
;
100 state
->size
= history_size
;
103 state
->flags
|= HS_STIFLED
;
108 /* Set the state of the current history array to STATE. */
110 history_set_history_state (state
)
111 HISTORY_STATE
*state
;
113 the_history
= state
->entries
;
114 history_offset
= state
->offset
;
115 history_length
= state
->length
;
116 history_size
= state
->size
;
117 if (state
->flags
& HS_STIFLED
)
121 /* Begin a session in which the history functions might be used. This
122 initializes interactive variables. */
126 history_offset
= history_length
;
129 /* Return the number of bytes that the primary history entries are using.
130 This just adds up the lengths of the_history->lines and the associated
133 history_total_bytes ()
135 register int i
, result
;
137 for (i
= result
= 0; the_history
&& the_history
[i
]; i
++)
138 result
+= HISTENT_BYTES (the_history
[i
]);
143 /* Returns the magic number which says what history element we are
144 looking at now. In this implementation, it returns history_offset. */
148 return (history_offset
);
151 /* Make the current history item be the one at POS, an absolute index.
152 Returns zero if POS is out of range, else non-zero. */
154 history_set_pos (pos
)
157 if (pos
> history_length
|| pos
< 0 || !the_history
)
159 history_offset
= pos
;
163 /* Return the current history array. The caller has to be careful, since this
164 is the actual array of data, and could be bashed or made corrupt easily.
165 The array is terminated with a NULL pointer. */
169 return (the_history
);
172 /* Return the history entry at the current position, as determined by
173 history_offset. If there is no entry there, return a NULL pointer. */
177 return ((history_offset
== history_length
) || the_history
== 0)
179 : the_history
[history_offset
];
182 /* Back up history_offset to the previous history entry, and return
183 a pointer to that entry. If there is no previous entry then return
188 return history_offset
? the_history
[--history_offset
] : (HIST_ENTRY
*)NULL
;
191 /* Move history_offset forward to the next history entry, and return
192 a pointer to that entry. If there is no next entry then return a
197 return (history_offset
== history_length
) ? (HIST_ENTRY
*)NULL
: the_history
[++history_offset
];
200 /* Return the history entry which is logically at OFFSET in the history array.
201 OFFSET is relative to history_base. */
208 local_index
= offset
- history_base
;
209 return (local_index
>= history_length
|| local_index
< 0 || the_history
== 0)
211 : the_history
[local_index
];
215 alloc_history_entry (string
, ts
)
221 temp
= (HIST_ENTRY
*)xmalloc (sizeof (HIST_ENTRY
));
223 temp
->line
= string
? savestring (string
) : string
;
224 temp
->data
= (char *)NULL
;
225 temp
->timestamp
= ts
;
231 history_get_time (hist
)
237 if (hist
== 0 || hist
->timestamp
== 0)
239 ts
= hist
->timestamp
;
240 if (ts
[0] != history_comment_char
)
242 t
= (time_t) strtol (ts
+ 1, (char **)NULL
, 10); /* XXX - should use strtol() here */
252 t
= (time_t) time ((time_t *)0);
253 #if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
254 snprintf (ts
, sizeof (ts
) - 1, "X%lu", (unsigned long) t
);
256 sprintf (ts
, "X%lu", (unsigned long) t
);
258 ret
= savestring (ts
);
259 ret
[0] = history_comment_char
;
264 /* Place STRING at the end of the history list. The data field
272 if (history_stifled
&& (history_length
== history_max_entries
))
276 /* If the history is stifled, and history_length is zero,
277 and it equals history_max_entries, we don't save items. */
278 if (history_length
== 0)
281 /* If there is something in the slot, then remove it. */
283 (void) free_history_entry (the_history
[0]);
285 /* Copy the rest of the entries, moving down one slot. Copy includes
288 for (i
= 0; i
< history_length
; i
++)
289 the_history
[i
] = the_history
[i
+ 1];
291 memmove (the_history
, the_history
+ 1, history_length
* sizeof (HIST_ENTRY
*));
298 if (history_size
== 0)
300 if (history_stifled
&& history_max_entries
> 0)
301 history_size
= history_max_entries
+ 2;
303 history_size
= DEFAULT_HISTORY_INITIAL_SIZE
;
304 the_history
= (HIST_ENTRY
**)xmalloc (history_size
* sizeof (HIST_ENTRY
*));
309 if (history_length
== (history_size
- 1))
311 history_size
+= DEFAULT_HISTORY_GROW_SIZE
;
312 the_history
= (HIST_ENTRY
**)
313 xrealloc (the_history
, history_size
* sizeof (HIST_ENTRY
*));
319 temp
= alloc_history_entry (string
, hist_inittime ());
321 the_history
[history_length
] = (HIST_ENTRY
*)NULL
;
322 the_history
[history_length
- 1] = temp
;
325 /* Change the time stamp of the most recent history entry to STRING. */
327 add_history_time (string
)
332 if (string
== 0 || history_length
< 1)
334 hs
= the_history
[history_length
- 1];
335 FREE (hs
->timestamp
);
336 hs
->timestamp
= savestring (string
);
339 /* Free HIST and return the data so the calling application can free it
340 if necessary and desired. */
342 free_history_entry (hist
)
348 return ((histdata_t
) 0);
350 FREE (hist
->timestamp
);
357 copy_history_entry (hist
)
366 ret
= alloc_history_entry (hist
->line
, (char *)NULL
);
368 ts
= hist
->timestamp
? savestring (hist
->timestamp
) : hist
->timestamp
;
371 ret
->data
= hist
->data
;
376 /* Make the history entry at WHICH have LINE and DATA. This returns
377 the old entry so you can dispose of the data. In the case of an
378 invalid WHICH, a NULL pointer is returned. */
380 replace_history_entry (which
, line
, data
)
385 HIST_ENTRY
*temp
, *old_value
;
387 if (which
< 0 || which
>= history_length
)
388 return ((HIST_ENTRY
*)NULL
);
390 temp
= (HIST_ENTRY
*)xmalloc (sizeof (HIST_ENTRY
));
391 old_value
= the_history
[which
];
393 temp
->line
= savestring (line
);
395 temp
->timestamp
= savestring (old_value
->timestamp
);
396 the_history
[which
] = temp
;
401 /* Replace the DATA in the specified history entries, replacing OLD with
402 NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
403 all of the history entries where entry->data == OLD; WHICH == -2 means
404 to replace the `newest' history entry where entry->data == OLD; and
405 WHICH >= 0 means to replace that particular history entry's data, as
406 long as it matches OLD. */
408 replace_history_data (which
, old
, new)
410 histdata_t
*old
, *new;
413 register int i
, last
;
415 if (which
< -2 || which
>= history_length
|| history_length
== 0 || the_history
== 0)
420 entry
= the_history
[which
];
421 if (entry
&& entry
->data
== old
)
427 for (i
= 0; i
< history_length
; i
++)
429 entry
= the_history
[i
];
432 if (entry
->data
== old
)
439 if (which
== -2 && last
>= 0)
441 entry
= the_history
[last
];
442 entry
->data
= new; /* XXX - we don't check entry->old */
446 /* Remove history element WHICH from the history. The removed
447 element is returned to you so you can free the line, data,
448 and containing structure. */
450 remove_history (which
)
453 HIST_ENTRY
*return_value
;
456 if (which
< 0 || which
>= history_length
|| history_length
== 0 || the_history
== 0)
457 return ((HIST_ENTRY
*)NULL
);
459 return_value
= the_history
[which
];
461 for (i
= which
; i
< history_length
; i
++)
462 the_history
[i
] = the_history
[i
+ 1];
466 return (return_value
);
469 /* Stifle the history list, remembering only MAX number of lines. */
479 if (history_length
> max
)
481 /* This loses because we cannot free the data. */
482 for (i
= 0, j
= history_length
- max
; i
< j
; i
++)
483 free_history_entry (the_history
[i
]);
486 for (j
= 0, i
= history_length
- max
; j
< max
; i
++, j
++)
487 the_history
[j
] = the_history
[i
];
488 the_history
[j
] = (HIST_ENTRY
*)NULL
;
493 max_input_history
= history_max_entries
= max
;
496 /* Stop stifling the history. This returns the previous maximum
497 number of history entries. The value is positive if the history
498 was stifled, negative if it wasn't. */
505 return (history_max_entries
);
508 return (-history_max_entries
);
512 history_is_stifled ()
514 return (history_stifled
);
522 /* This loses because we cannot free the data. */
523 for (i
= 0; i
< history_length
; i
++)
525 free_history_entry (the_history
[i
]);
526 the_history
[i
] = (HIST_ENTRY
*)NULL
;
529 history_offset
= history_length
= 0;