Imported from ../bash-2.0.tar.gz.
[platform/upstream/bash.git] / lib / readline / history.c
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 1, 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    675 Mass Ave, Cambridge, MA 02139, 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 #  include <unistd.h>
42 #endif
43
44 #if defined (HAVE_STRING_H)
45 #  include <string.h>
46 #else
47 #  include <strings.h>
48 #endif /* !HAVE_STRING_H */
49
50 #include "history.h"
51 #include "histlib.h"
52
53 extern char *xmalloc (), *xrealloc ();
54
55 /* The number of slots to increase the_history by. */
56 #define DEFAULT_HISTORY_GROW_SIZE 50
57
58 /* **************************************************************** */
59 /*                                                                  */
60 /*                      History Functions                           */
61 /*                                                                  */
62 /* **************************************************************** */
63
64 /* An array of HIST_ENTRY.  This is where we store the history. */
65 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
66
67 /* Non-zero means that we have enforced a limit on the amount of
68    history that we save. */
69 static int history_stifled;
70
71 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
72    entries to remember. */
73 int max_input_history;
74
75 /* The current location of the interactive history pointer.  Just makes
76    life easier for outside callers. */
77 int history_offset;
78
79 /* The number of strings currently stored in the history list. */
80 int history_length;
81
82 /* The current number of slots allocated to the input_history. */
83 static int history_size;
84
85 /* The logical `base' of the history array.  It defaults to 1. */
86 int history_base = 1;
87
88 /* Return the current HISTORY_STATE of the history. */
89 HISTORY_STATE *
90 history_get_history_state ()
91 {
92   HISTORY_STATE *state;
93
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;
99   state->flags = 0;
100   if (history_stifled)
101     state->flags |= HS_STIFLED;
102
103   return (state);
104 }
105
106 /* Set the state of the current history array to STATE. */
107 void
108 history_set_history_state (state)
109      HISTORY_STATE *state;
110 {
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)
116     history_stifled = 1;
117 }
118
119 /* Begin a session in which the history functions might be used.  This
120    initializes interactive variables. */
121 void
122 using_history ()
123 {
124   history_offset = history_length;
125 }
126
127 /* Return the number of bytes that the primary history entries are using.
128    This just adds up the lengths of the_history->lines. */
129 int
130 history_total_bytes ()
131 {
132   register int i, result;
133
134   result = 0;
135
136   for (i = 0; the_history && the_history[i]; i++)
137     result += strlen (the_history[i]->line);
138
139   return (result);
140 }
141
142 /* Returns the magic number which says what history element we are
143    looking at now.  In this implementation, it returns history_offset. */
144 int
145 where_history ()
146 {
147   return (history_offset);
148 }
149
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. */
152 int
153 history_set_pos (pos)
154      int pos;
155 {
156   if (pos > history_length || pos < 0 || !the_history)
157     return (0);
158   history_offset = pos;
159   return (1);
160 }
161  
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. */
165 HIST_ENTRY **
166 history_list ()
167 {
168   return (the_history);
169 }
170
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. */
173 HIST_ENTRY *
174 current_history ()
175 {
176   return ((history_offset == history_length) || the_history == 0)
177                 ? (HIST_ENTRY *)NULL
178                 : the_history[history_offset];
179 }
180
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
183    a NULL pointer. */
184 HIST_ENTRY *
185 previous_history ()
186 {
187   return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
188 }
189
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
192    NULL pointer. */
193 HIST_ENTRY *
194 next_history ()
195 {
196   return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
197 }
198
199 /* Return the history entry which is logically at OFFSET in the history array.
200    OFFSET is relative to history_base. */
201 HIST_ENTRY *
202 history_get (offset)
203      int offset;
204 {
205   int local_index;
206
207   local_index = offset - history_base;
208   return (local_index >= history_length || local_index < 0 || !the_history)
209                 ? (HIST_ENTRY *)NULL
210                 : the_history[local_index];
211 }
212
213 /* Place STRING at the end of the history list.  The data field
214    is  set to NULL. */
215 void
216 add_history (string)
217      char *string;
218 {
219   HIST_ENTRY *temp;
220
221   if (history_stifled && (history_length == max_input_history))
222     {
223       register int i;
224
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)
228         return;
229
230       /* If there is something in the slot, then remove it. */
231       if (the_history[0])
232         {
233           free (the_history[0]->line);
234           free (the_history[0]);
235         }
236
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];
240
241       history_base++;
242     }
243   else
244     {
245       if (history_size == 0)
246         {
247           history_size = DEFAULT_HISTORY_GROW_SIZE;
248           the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
249           history_length = 1;
250         }
251       else
252         {
253           if (history_length == (history_size - 1))
254             {
255               history_size += DEFAULT_HISTORY_GROW_SIZE;
256               the_history = (HIST_ENTRY **)
257                 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
258             }
259           history_length++;
260         }
261     }
262
263   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
264   temp->line = savestring (string);
265   temp->data = (char *)NULL;
266
267   the_history[history_length] = (HIST_ENTRY *)NULL;
268   the_history[history_length - 1] = temp;
269 }
270
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. */
274 HIST_ENTRY *
275 replace_history_entry (which, line, data)
276      int which;
277      char *line;
278      char *data;
279 {
280   HIST_ENTRY *temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
281   HIST_ENTRY *old_value;
282
283   if (which >= history_length)
284     return ((HIST_ENTRY *)NULL);
285
286   old_value = the_history[which];
287
288   temp->line = savestring (line);
289   temp->data = data;
290   the_history[which] = temp;
291
292   return (old_value);
293 }
294
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. */
298 HIST_ENTRY *
299 remove_history (which)
300      int which;
301 {
302   HIST_ENTRY *return_value;
303
304   if (which >= history_length || !history_length)
305     return_value = (HIST_ENTRY *)NULL;
306   else
307     {
308       register int i;
309       return_value = the_history[which];
310
311       for (i = which; i < history_length; i++)
312         the_history[i] = the_history[i + 1];
313
314       history_length--;
315     }
316
317   return (return_value);
318 }
319
320 /* Stifle the history list, remembering only MAX number of lines. */
321 void
322 stifle_history (max)
323      int max;
324 {
325   if (max < 0)
326     max = 0;
327
328   if (history_length > max)
329     {
330       register int i, j;
331
332       /* This loses because we cannot free the data. */
333       for (i = 0, j = history_length - max; i < j; i++)
334         {
335           free (the_history[i]->line);
336           free (the_history[i]);
337         }
338
339       history_base = 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;
343       history_length = j;
344     }
345
346   history_stifled = 1;
347   max_input_history = max;
348 }
349
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. */
353 int
354 unstifle_history ()
355 {
356   if (history_stifled)
357     {
358       history_stifled = 0;
359       return (-max_input_history);
360     }
361
362   return (max_input_history);
363 }
364
365 int
366 history_is_stifled ()
367 {
368   return (history_stifled);
369 }
370
371 void
372 clear_history ()
373 {
374   register int i;
375
376   /* This loses because we cannot free the data. */
377   for (i = 0; i < history_length; i++)
378     {
379       free (the_history[i]->line);
380       free (the_history[i]);
381       the_history[i] = (HIST_ENTRY *)NULL;
382     }
383
384   history_offset = history_length = 0;
385 }