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