("" < 3.4) always evaluates to true, which unconditionally
[dragonfly.git] / contrib / libreadline / history.c
blob400f18bc6027050758612c850627e4c02bb4251a
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 2, or (at your option)
11 any later version.
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 59 Temple Place, Suite 330, Boston, MA 02111 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)
29 # include <config.h>
30 #endif
32 #include <stdio.h>
34 #if defined (HAVE_STDLIB_H)
35 # include <stdlib.h>
36 #else
37 # include "ansi_stdlib.h"
38 #endif /* HAVE_STDLIB_H */
40 #if defined (HAVE_UNISTD_H)
41 # ifdef _MINIX
42 # include <sys/types.h>
43 # endif
44 # include <unistd.h>
45 #endif
47 #if defined (HAVE_STRING_H)
48 # include <string.h>
49 #else
50 # include <strings.h>
51 #endif /* !HAVE_STRING_H */
53 #include "history.h"
54 #include "histlib.h"
56 #include "xmalloc.h"
58 /* The number of slots to increase the_history by. */
59 #define DEFAULT_HISTORY_GROW_SIZE 50
61 /* **************************************************************** */
62 /* */
63 /* History Functions */
64 /* */
65 /* **************************************************************** */
67 /* An array of HIST_ENTRY. This is where we store the history. */
68 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
70 /* Non-zero means that we have enforced a limit on the amount of
71 history that we save. */
72 static int history_stifled;
74 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
75 entries to remember. */
76 int max_input_history;
78 /* The current location of the interactive history pointer. Just makes
79 life easier for outside callers. */
80 int history_offset;
82 /* The number of strings currently stored in the history list. */
83 int history_length;
85 /* The current number of slots allocated to the input_history. */
86 static int history_size;
88 /* The logical `base' of the history array. It defaults to 1. */
89 int history_base = 1;
91 /* Return the current HISTORY_STATE of the history. */
92 HISTORY_STATE *
93 history_get_history_state ()
95 HISTORY_STATE *state;
97 state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
98 state->entries = the_history;
99 state->offset = history_offset;
100 state->length = history_length;
101 state->size = history_size;
102 state->flags = 0;
103 if (history_stifled)
104 state->flags |= HS_STIFLED;
106 return (state);
109 /* Set the state of the current history array to STATE. */
110 void
111 history_set_history_state (state)
112 HISTORY_STATE *state;
114 the_history = state->entries;
115 history_offset = state->offset;
116 history_length = state->length;
117 history_size = state->size;
118 if (state->flags & HS_STIFLED)
119 history_stifled = 1;
122 /* Begin a session in which the history functions might be used. This
123 initializes interactive variables. */
124 void
125 using_history ()
127 history_offset = history_length;
130 /* Return the number of bytes that the primary history entries are using.
131 This just adds up the lengths of the_history->lines. */
133 history_total_bytes ()
135 register int i, result;
137 result = 0;
139 for (i = 0; the_history && the_history[i]; i++)
140 result += strlen (the_history[i]->line);
142 return (result);
145 /* Returns the magic number which says what history element we are
146 looking at now. In this implementation, it returns history_offset. */
148 where_history ()
150 return (history_offset);
153 /* Make the current history item be the one at POS, an absolute index.
154 Returns zero if POS is out of range, else non-zero. */
156 history_set_pos (pos)
157 int pos;
159 if (pos > history_length || pos < 0 || !the_history)
160 return (0);
161 history_offset = pos;
162 return (1);
165 /* Return the current history array. The caller has to be carefull, since this
166 is the actual array of data, and could be bashed or made corrupt easily.
167 The array is terminated with a NULL pointer. */
168 HIST_ENTRY **
169 history_list ()
171 return (the_history);
174 /* Return the history entry at the current position, as determined by
175 history_offset. If there is no entry there, return a NULL pointer. */
176 HIST_ENTRY *
177 current_history ()
179 return ((history_offset == history_length) || the_history == 0)
180 ? (HIST_ENTRY *)NULL
181 : the_history[history_offset];
184 /* Back up history_offset to the previous history entry, and return
185 a pointer to that entry. If there is no previous entry then return
186 a NULL pointer. */
187 HIST_ENTRY *
188 previous_history ()
190 return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
193 /* Move history_offset forward to the next history entry, and return
194 a pointer to that entry. If there is no next entry then return a
195 NULL pointer. */
196 HIST_ENTRY *
197 next_history ()
199 return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
202 /* Return the history entry which is logically at OFFSET in the history array.
203 OFFSET is relative to history_base. */
204 HIST_ENTRY *
205 history_get (offset)
206 int offset;
208 int local_index;
210 local_index = offset - history_base;
211 return (local_index >= history_length || local_index < 0 || !the_history)
212 ? (HIST_ENTRY *)NULL
213 : the_history[local_index];
216 /* Place STRING at the end of the history list. The data field
217 is set to NULL. */
218 void
219 add_history (string)
220 char *string;
222 HIST_ENTRY *temp;
224 if (history_stifled && (history_length == max_input_history))
226 register int i;
228 /* If the history is stifled, and history_length is zero,
229 and it equals max_input_history, we don't save items. */
230 if (history_length == 0)
231 return;
233 /* If there is something in the slot, then remove it. */
234 if (the_history[0])
236 free (the_history[0]->line);
237 free (the_history[0]);
240 /* Copy the rest of the entries, moving down one slot. */
241 for (i = 0; i < history_length; i++)
242 the_history[i] = the_history[i + 1];
244 history_base++;
246 else
248 if (history_size == 0)
250 history_size = DEFAULT_HISTORY_GROW_SIZE;
251 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
252 history_length = 1;
254 else
256 if (history_length == (history_size - 1))
258 history_size += DEFAULT_HISTORY_GROW_SIZE;
259 the_history = (HIST_ENTRY **)
260 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
262 history_length++;
266 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
267 temp->line = savestring (string);
268 temp->data = (char *)NULL;
270 the_history[history_length] = (HIST_ENTRY *)NULL;
271 the_history[history_length - 1] = temp;
274 /* Make the history entry at WHICH have LINE and DATA. This returns
275 the old entry so you can dispose of the data. In the case of an
276 invalid WHICH, a NULL pointer is returned. */
277 HIST_ENTRY *
278 replace_history_entry (which, line, data)
279 int which;
280 char *line;
281 histdata_t data;
283 HIST_ENTRY *temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
284 HIST_ENTRY *old_value;
286 if (which >= history_length)
287 return ((HIST_ENTRY *)NULL);
289 old_value = the_history[which];
291 temp->line = savestring (line);
292 temp->data = data;
293 the_history[which] = temp;
295 return (old_value);
298 /* Remove history element WHICH from the history. The removed
299 element is returned to you so you can free the line, data,
300 and containing structure. */
301 HIST_ENTRY *
302 remove_history (which)
303 int which;
305 HIST_ENTRY *return_value;
307 if (which >= history_length || !history_length)
308 return_value = (HIST_ENTRY *)NULL;
309 else
311 register int i;
312 return_value = the_history[which];
314 for (i = which; i < history_length; i++)
315 the_history[i] = the_history[i + 1];
317 history_length--;
320 return (return_value);
323 /* Stifle the history list, remembering only MAX number of lines. */
324 void
325 stifle_history (max)
326 int max;
328 if (max < 0)
329 max = 0;
331 if (history_length > max)
333 register int i, j;
335 /* This loses because we cannot free the data. */
336 for (i = 0, j = history_length - max; i < j; i++)
338 free (the_history[i]->line);
339 free (the_history[i]);
342 history_base = i;
343 for (j = 0, i = history_length - max; j < max; i++, j++)
344 the_history[j] = the_history[i];
345 the_history[j] = (HIST_ENTRY *)NULL;
346 history_length = j;
349 history_stifled = 1;
350 max_input_history = max;
353 /* Stop stifling the history. This returns the previous amount the
354 history was stifled by. The value is positive if the history was
355 stifled, negative if it wasn't. */
357 unstifle_history ()
359 if (history_stifled)
361 history_stifled = 0;
362 return (-max_input_history);
365 return (max_input_history);
369 history_is_stifled ()
371 return (history_stifled);
374 void
375 clear_history ()
377 register int i;
379 /* This loses because we cannot free the data. */
380 for (i = 0; i < history_length; i++)
382 free (the_history[i]->line);
383 free (the_history[i]);
384 the_history[i] = (HIST_ENTRY *)NULL;
387 history_offset = history_length = 0;