1 /* History.c -- standalone history library */
3 /* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
5 This file contains the GNU History Library (the Library), a set of
6 routines for managing the text of previously typed lines.
8 The Library 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 1, or (at your option)
13 The Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 The GNU General Public License is often shipped with GNU software, and
19 is generally kept in a file called COPYING or LICENSE. If you do not
20 have a copy of the license, write to the Free Software Foundation,
21 675 Mass Ave, Cambridge, MA 02139, USA. */
23 /* The goal is to make the implementation transparent, so that you
24 don't have to know what data types are used, just what functions
25 you can call. I think I have done that. */
26 #define READLINE_LIBRARY
28 #if defined (HAVE_CONFIG_H)
34 #if defined (HAVE_STDLIB_H)
37 # include "ansi_stdlib.h"
38 #endif /* HAVE_STDLIB_H */
40 #if defined (HAVE_UNISTD_H)
44 #if defined (HAVE_STRING_H)
48 #endif /* !HAVE_STRING_H */
53 extern char *xmalloc (), *xrealloc ();
55 /* The number of slots to increase the_history by. */
56 #define DEFAULT_HISTORY_GROW_SIZE 50
58 /* **************************************************************** */
60 /* History Functions */
62 /* **************************************************************** */
64 /* An array of HIST_ENTRY. This is where we store the history. */
65 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
67 /* Non-zero means that we have enforced a limit on the amount of
68 history that we save. */
69 static int history_stifled;
71 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
72 entries to remember. */
73 int max_input_history;
75 /* The current location of the interactive history pointer. Just makes
76 life easier for outside callers. */
79 /* The number of strings currently stored in the history list. */
82 /* The current number of slots allocated to the input_history. */
83 static int history_size;
85 /* The logical `base' of the history array. It defaults to 1. */
88 /* Return the current HISTORY_STATE of the history. */
90 history_get_history_state ()
94 state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
95 state->entries = the_history;
96 state->offset = history_offset;
97 state->length = history_length;
98 state->size = history_size;
101 state->flags |= HS_STIFLED;
106 /* Set the state of the current history array to STATE. */
108 history_set_history_state (state)
109 HISTORY_STATE *state;
111 the_history = state->entries;
112 history_offset = state->offset;
113 history_length = state->length;
114 history_size = state->size;
115 if (state->flags & HS_STIFLED)
119 /* Begin a session in which the history functions might be used. This
120 initializes interactive variables. */
124 history_offset = history_length;
127 /* Return the number of bytes that the primary history entries are using.
128 This just adds up the lengths of the_history->lines. */
130 history_total_bytes ()
132 register int i, result;
136 for (i = 0; the_history && the_history[i]; i++)
137 result += strlen (the_history[i]->line);
142 /* Returns the magic number which says what history element we are
143 looking at now. In this implementation, it returns history_offset. */
147 return (history_offset);
150 /* Make the current history item be the one at POS, an absolute index.
151 Returns zero if POS is out of range, else non-zero. */
153 history_set_pos (pos)
156 if (pos > history_length || pos < 0 || !the_history)
158 history_offset = pos;
162 /* Return the current history array. The caller has to be carefull, since this
163 is the actual array of data, and could be bashed or made corrupt easily.
164 The array is terminated with a NULL pointer. */
168 return (the_history);
171 /* Return the history entry at the current position, as determined by
172 history_offset. If there is no entry there, return a NULL pointer. */
176 return ((history_offset == history_length) || the_history == 0)
178 : the_history[history_offset];
181 /* Back up history_offset to the previous history entry, and return
182 a pointer to that entry. If there is no previous entry then return
187 return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
190 /* Move history_offset forward to the next history entry, and return
191 a pointer to that entry. If there is no next entry then return a
196 return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
199 /* Return the history entry which is logically at OFFSET in the history array.
200 OFFSET is relative to history_base. */
207 local_index = offset - history_base;
208 return (local_index >= history_length || local_index < 0 || !the_history)
210 : the_history[local_index];
213 /* Place STRING at the end of the history list. The data field
221 if (history_stifled && (history_length == max_input_history))
225 /* If the history is stifled, and history_length is zero,
226 and it equals max_input_history, we don't save items. */
227 if (history_length == 0)
230 /* If there is something in the slot, then remove it. */
233 free (the_history[0]->line);
234 free (the_history[0]);
237 /* Copy the rest of the entries, moving down one slot. */
238 for (i = 0; i < history_length; i++)
239 the_history[i] = the_history[i + 1];
245 if (history_size == 0)
247 history_size = DEFAULT_HISTORY_GROW_SIZE;
248 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
253 if (history_length == (history_size - 1))
255 history_size += DEFAULT_HISTORY_GROW_SIZE;
256 the_history = (HIST_ENTRY **)
257 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
263 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
264 temp->line = savestring (string);
265 temp->data = (char *)NULL;
267 the_history[history_length] = (HIST_ENTRY *)NULL;
268 the_history[history_length - 1] = temp;
271 /* Make the history entry at WHICH have LINE and DATA. This returns
272 the old entry so you can dispose of the data. In the case of an
273 invalid WHICH, a NULL pointer is returned. */
275 replace_history_entry (which, line, data)
280 HIST_ENTRY *temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
281 HIST_ENTRY *old_value;
283 if (which >= history_length)
284 return ((HIST_ENTRY *)NULL);
286 old_value = the_history[which];
288 temp->line = savestring (line);
290 the_history[which] = temp;
295 /* Remove history element WHICH from the history. The removed
296 element is returned to you so you can free the line, data,
297 and containing structure. */
299 remove_history (which)
302 HIST_ENTRY *return_value;
304 if (which >= history_length || !history_length)
305 return_value = (HIST_ENTRY *)NULL;
309 return_value = the_history[which];
311 for (i = which; i < history_length; i++)
312 the_history[i] = the_history[i + 1];
317 return (return_value);
320 /* Stifle the history list, remembering only MAX number of lines. */
328 if (history_length > max)
332 /* This loses because we cannot free the data. */
333 for (i = 0, j = history_length - max; i < j; i++)
335 free (the_history[i]->line);
336 free (the_history[i]);
340 for (j = 0, i = history_length - max; j < max; i++, j++)
341 the_history[j] = the_history[i];
342 the_history[j] = (HIST_ENTRY *)NULL;
347 max_input_history = max;
350 /* Stop stifling the history. This returns the previous amount the
351 history was stifled by. The value is positive if the history was
352 stifled, negative if it wasn't. */
359 return (-max_input_history);
362 return (max_input_history);
366 history_is_stifled ()
368 return (history_stifled);
376 /* This loses because we cannot free the data. */
377 for (i = 0; i < history_length; i++)
379 free (the_history[i]->line);
380 free (the_history[i]);
381 the_history[i] = (HIST_ENTRY *)NULL;
384 history_offset = history_length = 0;