xref: /openbsd/gnu/lib/libreadline/history.c (revision 898184e3)
1 /* History.c -- standalone history library */
2 
3 /* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
4 
5    This file contains the GNU History Library (the Library), a set of
6    routines for managing the text of previously typed lines.
7 
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 2, or (at your option)
11    any later version.
12 
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.
17 
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    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22 
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
27 
28 #if defined (HAVE_CONFIG_H)
29 #  include <config.h>
30 #endif
31 
32 #include <stdio.h>
33 
34 #if defined (HAVE_STDLIB_H)
35 #  include <stdlib.h>
36 #else
37 #  include "ansi_stdlib.h"
38 #endif /* HAVE_STDLIB_H */
39 
40 #if defined (HAVE_UNISTD_H)
41 #  ifdef _MINIX
42 #    include <sys/types.h>
43 #  endif
44 #  include <unistd.h>
45 #endif
46 
47 #include "history.h"
48 #include "histlib.h"
49 
50 #include "xmalloc.h"
51 
52 /* The number of slots to increase the_history by. */
53 #define DEFAULT_HISTORY_GROW_SIZE 50
54 
55 /* **************************************************************** */
56 /*								    */
57 /*			History Functions			    */
58 /*								    */
59 /* **************************************************************** */
60 
61 /* An array of HIST_ENTRY.  This is where we store the history. */
62 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
63 
64 /* Non-zero means that we have enforced a limit on the amount of
65    history that we save. */
66 static int history_stifled;
67 
68 /* The current number of slots allocated to the input_history. */
69 static int history_size;
70 
71 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
72    entries to remember. */
73 int history_max_entries;
74 int max_input_history;	/* backwards compatibility */
75 
76 /* The current location of the interactive history pointer.  Just makes
77    life easier for outside callers. */
78 int history_offset;
79 
80 /* The number of strings currently stored in the history list. */
81 int history_length;
82 
83 /* The logical `base' of the history array.  It defaults to 1. */
84 int history_base = 1;
85 
86 /* Return the current HISTORY_STATE of the history. */
87 HISTORY_STATE *
88 history_get_history_state ()
89 {
90   HISTORY_STATE *state;
91 
92   state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
93   state->entries = the_history;
94   state->offset = history_offset;
95   state->length = history_length;
96   state->size = history_size;
97   state->flags = 0;
98   if (history_stifled)
99     state->flags |= HS_STIFLED;
100 
101   return (state);
102 }
103 
104 /* Set the state of the current history array to STATE. */
105 void
106 history_set_history_state (state)
107      HISTORY_STATE *state;
108 {
109   the_history = state->entries;
110   history_offset = state->offset;
111   history_length = state->length;
112   history_size = state->size;
113   if (state->flags & HS_STIFLED)
114     history_stifled = 1;
115 }
116 
117 /* Begin a session in which the history functions might be used.  This
118    initializes interactive variables. */
119 void
120 using_history ()
121 {
122   history_offset = history_length;
123 }
124 
125 /* Return the number of bytes that the primary history entries are using.
126    This just adds up the lengths of the_history->lines. */
127 int
128 history_total_bytes ()
129 {
130   register int i, result;
131 
132   for (i = result = 0; the_history && the_history[i]; i++)
133     result += strlen (the_history[i]->line);
134 
135   return (result);
136 }
137 
138 /* Returns the magic number which says what history element we are
139    looking at now.  In this implementation, it returns history_offset. */
140 int
141 where_history ()
142 {
143   return (history_offset);
144 }
145 
146 /* Make the current history item be the one at POS, an absolute index.
147    Returns zero if POS is out of range, else non-zero. */
148 int
149 history_set_pos (pos)
150      int pos;
151 {
152   if (pos > history_length || pos < 0 || !the_history)
153     return (0);
154   history_offset = pos;
155   return (1);
156 }
157 
158 /* Return the current history array.  The caller has to be carefull, since this
159    is the actual array of data, and could be bashed or made corrupt easily.
160    The array is terminated with a NULL pointer. */
161 HIST_ENTRY **
162 history_list ()
163 {
164   return (the_history);
165 }
166 
167 /* Return the history entry at the current position, as determined by
168    history_offset.  If there is no entry there, return a NULL pointer. */
169 HIST_ENTRY *
170 current_history ()
171 {
172   return ((history_offset == history_length) || the_history == 0)
173 		? (HIST_ENTRY *)NULL
174 		: the_history[history_offset];
175 }
176 
177 /* Back up history_offset to the previous history entry, and return
178    a pointer to that entry.  If there is no previous entry then return
179    a NULL pointer. */
180 HIST_ENTRY *
181 previous_history ()
182 {
183   return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
184 }
185 
186 /* Move history_offset forward to the next history entry, and return
187    a pointer to that entry.  If there is no next entry then return a
188    NULL pointer. */
189 HIST_ENTRY *
190 next_history ()
191 {
192   return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
193 }
194 
195 /* Return the history entry which is logically at OFFSET in the history array.
196    OFFSET is relative to history_base. */
197 HIST_ENTRY *
198 history_get (offset)
199      int offset;
200 {
201   int local_index;
202 
203   local_index = offset - history_base;
204   return (local_index >= history_length || local_index < 0 || !the_history)
205 		? (HIST_ENTRY *)NULL
206 		: the_history[local_index];
207 }
208 
209 /* Place STRING at the end of the history list.  The data field
210    is  set to NULL. */
211 void
212 add_history (string)
213      const char *string;
214 {
215   HIST_ENTRY *temp;
216 
217   if (history_stifled && (history_length == history_max_entries))
218     {
219       register int i;
220 
221       /* If the history is stifled, and history_length is zero,
222 	 and it equals history_max_entries, we don't save items. */
223       if (history_length == 0)
224 	return;
225 
226       /* If there is something in the slot, then remove it. */
227       if (the_history[0])
228 	{
229 	  free (the_history[0]->line);
230 	  free (the_history[0]);
231 	}
232 
233       /* Copy the rest of the entries, moving down one slot. */
234       for (i = 0; i < history_length; i++)
235 	the_history[i] = the_history[i + 1];
236 
237       history_base++;
238     }
239   else
240     {
241       if (history_size == 0)
242 	{
243 	  history_size = DEFAULT_HISTORY_GROW_SIZE;
244 	  the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
245 	  history_length = 1;
246 	}
247       else
248 	{
249 	  if (history_length == (history_size - 1))
250 	    {
251 	      history_size += DEFAULT_HISTORY_GROW_SIZE;
252 	      the_history = (HIST_ENTRY **)
253 		xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
254 	    }
255 	  history_length++;
256 	}
257     }
258 
259   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
260   temp->line = savestring (string);
261   temp->data = (char *)NULL;
262 
263   the_history[history_length] = (HIST_ENTRY *)NULL;
264   the_history[history_length - 1] = temp;
265 }
266 
267 /* Make the history entry at WHICH have LINE and DATA.  This returns
268    the old entry so you can dispose of the data.  In the case of an
269    invalid WHICH, a NULL pointer is returned. */
270 HIST_ENTRY *
271 replace_history_entry (which, line, data)
272      int which;
273      const char *line;
274      histdata_t data;
275 {
276   HIST_ENTRY *temp, *old_value;
277 
278   if (which >= history_length)
279     return ((HIST_ENTRY *)NULL);
280 
281   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
282   old_value = the_history[which];
283 
284   temp->line = savestring (line);
285   temp->data = data;
286   the_history[which] = temp;
287 
288   return (old_value);
289 }
290 
291 /* Remove history element WHICH from the history.  The removed
292    element is returned to you so you can free the line, data,
293    and containing structure. */
294 HIST_ENTRY *
295 remove_history (which)
296      int which;
297 {
298   HIST_ENTRY *return_value;
299   register int i;
300 
301   if (which >= history_length || !history_length)
302     return_value = (HIST_ENTRY *)NULL;
303   else
304     {
305       return_value = the_history[which];
306 
307       for (i = which; i < history_length; i++)
308 	the_history[i] = the_history[i + 1];
309 
310       history_length--;
311     }
312 
313   return (return_value);
314 }
315 
316 /* Stifle the history list, remembering only MAX number of lines. */
317 void
318 stifle_history (max)
319      int max;
320 {
321   register int i, j;
322 
323   if (max < 0)
324     max = 0;
325 
326   if (history_length > max)
327     {
328       /* This loses because we cannot free the data. */
329       for (i = 0, j = history_length - max; i < j; i++)
330 	{
331 	  free (the_history[i]->line);
332 	  free (the_history[i]);
333 	}
334 
335       history_base = i;
336       for (j = 0, i = history_length - max; j < max; i++, j++)
337 	the_history[j] = the_history[i];
338       the_history[j] = (HIST_ENTRY *)NULL;
339       history_length = j;
340     }
341 
342   history_stifled = 1;
343   max_input_history = history_max_entries = max;
344 }
345 
346 /* Stop stifling the history.  This returns the previous maximum
347    number of history entries.  The value is positive if the history
348    was stifled,  negative if it wasn't. */
349 int
350 unstifle_history ()
351 {
352   if (history_stifled)
353     {
354       history_stifled = 0;
355       return (history_max_entries);
356     }
357   else
358     return (-history_max_entries);
359 }
360 
361 int
362 history_is_stifled ()
363 {
364   return (history_stifled);
365 }
366 
367 void
368 clear_history ()
369 {
370   register int i;
371 
372   /* This loses because we cannot free the data. */
373   for (i = 0; i < history_length; i++)
374     {
375       free (the_history[i]->line);
376       free (the_history[i]);
377       the_history[i] = (HIST_ENTRY *)NULL;
378     }
379 
380   history_offset = history_length = 0;
381 }
382