xref: /dflybsd-src/contrib/gdb-7/readline/history.c (revision 16003dcfd2baa152f5dd24794ec9f36e139eaeb8)
1*6b445a62SJohn Marino /* history.c -- standalone history library */
2*6b445a62SJohn Marino 
3*6b445a62SJohn Marino /* Copyright (C) 1989-2009 Free Software Foundation, Inc.
4*6b445a62SJohn Marino 
5*6b445a62SJohn Marino    This file contains the GNU History Library (History), a set of
6*6b445a62SJohn Marino    routines for managing the text of previously typed lines.
7*6b445a62SJohn Marino 
8*6b445a62SJohn Marino    History is free software: you can redistribute it and/or modify
9*6b445a62SJohn Marino    it under the terms of the GNU General Public License as published by
10*6b445a62SJohn Marino    the Free Software Foundation, either version 3 of the License, or
11*6b445a62SJohn Marino    (at your option) any later version.
12*6b445a62SJohn Marino 
13*6b445a62SJohn Marino    History is distributed in the hope that it will be useful,
14*6b445a62SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*6b445a62SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*6b445a62SJohn Marino    GNU General Public License for more details.
17*6b445a62SJohn Marino 
18*6b445a62SJohn Marino    You should have received a copy of the GNU General Public License
19*6b445a62SJohn Marino    along with History.  If not, see <http://www.gnu.org/licenses/>.
20*6b445a62SJohn Marino */
21*6b445a62SJohn Marino 
22*6b445a62SJohn Marino /* The goal is to make the implementation transparent, so that you
23*6b445a62SJohn Marino    don't have to know what data types are used, just what functions
24*6b445a62SJohn Marino    you can call.  I think I have done that. */
25*6b445a62SJohn Marino #define READLINE_LIBRARY
26*6b445a62SJohn Marino 
27*6b445a62SJohn Marino #if defined (HAVE_CONFIG_H)
28*6b445a62SJohn Marino #  include <config.h>
29*6b445a62SJohn Marino #endif
30*6b445a62SJohn Marino 
31*6b445a62SJohn Marino #include <stdio.h>
32*6b445a62SJohn Marino 
33*6b445a62SJohn Marino #if defined (HAVE_STDLIB_H)
34*6b445a62SJohn Marino #  include <stdlib.h>
35*6b445a62SJohn Marino #else
36*6b445a62SJohn Marino #  include "ansi_stdlib.h"
37*6b445a62SJohn Marino #endif /* HAVE_STDLIB_H */
38*6b445a62SJohn Marino 
39*6b445a62SJohn Marino #if defined (HAVE_UNISTD_H)
40*6b445a62SJohn Marino #  ifdef _MINIX
41*6b445a62SJohn Marino #    include <sys/types.h>
42*6b445a62SJohn Marino #  endif
43*6b445a62SJohn Marino #  include <unistd.h>
44*6b445a62SJohn Marino #endif
45*6b445a62SJohn Marino 
46*6b445a62SJohn Marino #include "history.h"
47*6b445a62SJohn Marino #include "histlib.h"
48*6b445a62SJohn Marino 
49*6b445a62SJohn Marino #include "xmalloc.h"
50*6b445a62SJohn Marino 
51*6b445a62SJohn Marino /* The number of slots to increase the_history by. */
52*6b445a62SJohn Marino #define DEFAULT_HISTORY_GROW_SIZE 50
53*6b445a62SJohn Marino 
54*6b445a62SJohn Marino static char *hist_inittime PARAMS((void));
55*6b445a62SJohn Marino 
56*6b445a62SJohn Marino /* **************************************************************** */
57*6b445a62SJohn Marino /*								    */
58*6b445a62SJohn Marino /*			History Functions			    */
59*6b445a62SJohn Marino /*								    */
60*6b445a62SJohn Marino /* **************************************************************** */
61*6b445a62SJohn Marino 
62*6b445a62SJohn Marino /* An array of HIST_ENTRY.  This is where we store the history. */
63*6b445a62SJohn Marino static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
64*6b445a62SJohn Marino 
65*6b445a62SJohn Marino /* Non-zero means that we have enforced a limit on the amount of
66*6b445a62SJohn Marino    history that we save. */
67*6b445a62SJohn Marino static int history_stifled;
68*6b445a62SJohn Marino 
69*6b445a62SJohn Marino /* The current number of slots allocated to the input_history. */
70*6b445a62SJohn Marino static int history_size;
71*6b445a62SJohn Marino 
72*6b445a62SJohn Marino /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
73*6b445a62SJohn Marino    entries to remember. */
74*6b445a62SJohn Marino int history_max_entries;
75*6b445a62SJohn Marino int max_input_history;	/* backwards compatibility */
76*6b445a62SJohn Marino 
77*6b445a62SJohn Marino /* The current location of the interactive history pointer.  Just makes
78*6b445a62SJohn Marino    life easier for outside callers. */
79*6b445a62SJohn Marino int history_offset;
80*6b445a62SJohn Marino 
81*6b445a62SJohn Marino /* The number of strings currently stored in the history list. */
82*6b445a62SJohn Marino int history_length;
83*6b445a62SJohn Marino 
84*6b445a62SJohn Marino /* The logical `base' of the history array.  It defaults to 1. */
85*6b445a62SJohn Marino int history_base = 1;
86*6b445a62SJohn Marino 
87*6b445a62SJohn Marino /* Return the current HISTORY_STATE of the history. */
88*6b445a62SJohn Marino HISTORY_STATE *
history_get_history_state()89*6b445a62SJohn Marino history_get_history_state ()
90*6b445a62SJohn Marino {
91*6b445a62SJohn Marino   HISTORY_STATE *state;
92*6b445a62SJohn Marino 
93*6b445a62SJohn Marino   state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
94*6b445a62SJohn Marino   state->entries = the_history;
95*6b445a62SJohn Marino   state->offset = history_offset;
96*6b445a62SJohn Marino   state->length = history_length;
97*6b445a62SJohn Marino   state->size = history_size;
98*6b445a62SJohn Marino   state->flags = 0;
99*6b445a62SJohn Marino   if (history_stifled)
100*6b445a62SJohn Marino     state->flags |= HS_STIFLED;
101*6b445a62SJohn Marino 
102*6b445a62SJohn Marino   return (state);
103*6b445a62SJohn Marino }
104*6b445a62SJohn Marino 
105*6b445a62SJohn Marino /* Set the state of the current history array to STATE. */
106*6b445a62SJohn Marino void
history_set_history_state(state)107*6b445a62SJohn Marino history_set_history_state (state)
108*6b445a62SJohn Marino      HISTORY_STATE *state;
109*6b445a62SJohn Marino {
110*6b445a62SJohn Marino   the_history = state->entries;
111*6b445a62SJohn Marino   history_offset = state->offset;
112*6b445a62SJohn Marino   history_length = state->length;
113*6b445a62SJohn Marino   history_size = state->size;
114*6b445a62SJohn Marino   if (state->flags & HS_STIFLED)
115*6b445a62SJohn Marino     history_stifled = 1;
116*6b445a62SJohn Marino }
117*6b445a62SJohn Marino 
118*6b445a62SJohn Marino /* Begin a session in which the history functions might be used.  This
119*6b445a62SJohn Marino    initializes interactive variables. */
120*6b445a62SJohn Marino void
using_history()121*6b445a62SJohn Marino using_history ()
122*6b445a62SJohn Marino {
123*6b445a62SJohn Marino   history_offset = history_length;
124*6b445a62SJohn Marino }
125*6b445a62SJohn Marino 
126*6b445a62SJohn Marino /* Return the number of bytes that the primary history entries are using.
127*6b445a62SJohn Marino    This just adds up the lengths of the_history->lines and the associated
128*6b445a62SJohn Marino    timestamps. */
129*6b445a62SJohn Marino int
history_total_bytes()130*6b445a62SJohn Marino history_total_bytes ()
131*6b445a62SJohn Marino {
132*6b445a62SJohn Marino   register int i, result;
133*6b445a62SJohn Marino 
134*6b445a62SJohn Marino   for (i = result = 0; the_history && the_history[i]; i++)
135*6b445a62SJohn Marino     result += HISTENT_BYTES (the_history[i]);
136*6b445a62SJohn Marino 
137*6b445a62SJohn Marino   return (result);
138*6b445a62SJohn Marino }
139*6b445a62SJohn Marino 
140*6b445a62SJohn Marino /* Returns the magic number which says what history element we are
141*6b445a62SJohn Marino    looking at now.  In this implementation, it returns history_offset. */
142*6b445a62SJohn Marino int
where_history()143*6b445a62SJohn Marino where_history ()
144*6b445a62SJohn Marino {
145*6b445a62SJohn Marino   return (history_offset);
146*6b445a62SJohn Marino }
147*6b445a62SJohn Marino 
148*6b445a62SJohn Marino /* Make the current history item be the one at POS, an absolute index.
149*6b445a62SJohn Marino    Returns zero if POS is out of range, else non-zero. */
150*6b445a62SJohn Marino int
history_set_pos(pos)151*6b445a62SJohn Marino history_set_pos (pos)
152*6b445a62SJohn Marino      int pos;
153*6b445a62SJohn Marino {
154*6b445a62SJohn Marino   if (pos > history_length || pos < 0 || !the_history)
155*6b445a62SJohn Marino     return (0);
156*6b445a62SJohn Marino   history_offset = pos;
157*6b445a62SJohn Marino   return (1);
158*6b445a62SJohn Marino }
159*6b445a62SJohn Marino 
160*6b445a62SJohn Marino /* Return the current history array.  The caller has to be careful, since this
161*6b445a62SJohn Marino    is the actual array of data, and could be bashed or made corrupt easily.
162*6b445a62SJohn Marino    The array is terminated with a NULL pointer. */
163*6b445a62SJohn Marino HIST_ENTRY **
history_list()164*6b445a62SJohn Marino history_list ()
165*6b445a62SJohn Marino {
166*6b445a62SJohn Marino   return (the_history);
167*6b445a62SJohn Marino }
168*6b445a62SJohn Marino 
169*6b445a62SJohn Marino /* Return the history entry at the current position, as determined by
170*6b445a62SJohn Marino    history_offset.  If there is no entry there, return a NULL pointer. */
171*6b445a62SJohn Marino HIST_ENTRY *
current_history()172*6b445a62SJohn Marino current_history ()
173*6b445a62SJohn Marino {
174*6b445a62SJohn Marino   return ((history_offset == history_length) || the_history == 0)
175*6b445a62SJohn Marino 		? (HIST_ENTRY *)NULL
176*6b445a62SJohn Marino 		: the_history[history_offset];
177*6b445a62SJohn Marino }
178*6b445a62SJohn Marino 
179*6b445a62SJohn Marino /* Back up history_offset to the previous history entry, and return
180*6b445a62SJohn Marino    a pointer to that entry.  If there is no previous entry then return
181*6b445a62SJohn Marino    a NULL pointer. */
182*6b445a62SJohn Marino HIST_ENTRY *
previous_history()183*6b445a62SJohn Marino previous_history ()
184*6b445a62SJohn Marino {
185*6b445a62SJohn Marino   return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
186*6b445a62SJohn Marino }
187*6b445a62SJohn Marino 
188*6b445a62SJohn Marino /* Move history_offset forward to the next history entry, and return
189*6b445a62SJohn Marino    a pointer to that entry.  If there is no next entry then return a
190*6b445a62SJohn Marino    NULL pointer. */
191*6b445a62SJohn Marino HIST_ENTRY *
next_history()192*6b445a62SJohn Marino next_history ()
193*6b445a62SJohn Marino {
194*6b445a62SJohn Marino   return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
195*6b445a62SJohn Marino }
196*6b445a62SJohn Marino 
197*6b445a62SJohn Marino /* Return the history entry which is logically at OFFSET in the history array.
198*6b445a62SJohn Marino    OFFSET is relative to history_base. */
199*6b445a62SJohn Marino HIST_ENTRY *
history_get(offset)200*6b445a62SJohn Marino history_get (offset)
201*6b445a62SJohn Marino      int offset;
202*6b445a62SJohn Marino {
203*6b445a62SJohn Marino   int local_index;
204*6b445a62SJohn Marino 
205*6b445a62SJohn Marino   local_index = offset - history_base;
206*6b445a62SJohn Marino   return (local_index >= history_length || local_index < 0 || the_history == 0)
207*6b445a62SJohn Marino 		? (HIST_ENTRY *)NULL
208*6b445a62SJohn Marino 		: the_history[local_index];
209*6b445a62SJohn Marino }
210*6b445a62SJohn Marino 
211*6b445a62SJohn Marino HIST_ENTRY *
alloc_history_entry(string,ts)212*6b445a62SJohn Marino alloc_history_entry (string, ts)
213*6b445a62SJohn Marino      char *string;
214*6b445a62SJohn Marino      char *ts;
215*6b445a62SJohn Marino {
216*6b445a62SJohn Marino   HIST_ENTRY *temp;
217*6b445a62SJohn Marino 
218*6b445a62SJohn Marino   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
219*6b445a62SJohn Marino 
220*6b445a62SJohn Marino   temp->line = string ? savestring (string) : string;
221*6b445a62SJohn Marino   temp->data = (char *)NULL;
222*6b445a62SJohn Marino   temp->timestamp = ts;
223*6b445a62SJohn Marino 
224*6b445a62SJohn Marino   return temp;
225*6b445a62SJohn Marino }
226*6b445a62SJohn Marino 
227*6b445a62SJohn Marino time_t
history_get_time(hist)228*6b445a62SJohn Marino history_get_time (hist)
229*6b445a62SJohn Marino      HIST_ENTRY *hist;
230*6b445a62SJohn Marino {
231*6b445a62SJohn Marino   char *ts;
232*6b445a62SJohn Marino   time_t t;
233*6b445a62SJohn Marino 
234*6b445a62SJohn Marino   if (hist == 0 || hist->timestamp == 0)
235*6b445a62SJohn Marino     return 0;
236*6b445a62SJohn Marino   ts = hist->timestamp;
237*6b445a62SJohn Marino   if (ts[0] != history_comment_char)
238*6b445a62SJohn Marino     return 0;
239*6b445a62SJohn Marino   t = (time_t) atol (ts + 1);		/* XXX - should use strtol() here */
240*6b445a62SJohn Marino   return t;
241*6b445a62SJohn Marino }
242*6b445a62SJohn Marino 
243*6b445a62SJohn Marino static char *
hist_inittime()244*6b445a62SJohn Marino hist_inittime ()
245*6b445a62SJohn Marino {
246*6b445a62SJohn Marino   time_t t;
247*6b445a62SJohn Marino   char ts[64], *ret;
248*6b445a62SJohn Marino 
249*6b445a62SJohn Marino   t = (time_t) time ((time_t *)0);
250*6b445a62SJohn Marino #if defined (HAVE_VSNPRINTF)		/* assume snprintf if vsnprintf exists */
251*6b445a62SJohn Marino   snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
252*6b445a62SJohn Marino #else
253*6b445a62SJohn Marino   sprintf (ts, "X%lu", (unsigned long) t);
254*6b445a62SJohn Marino #endif
255*6b445a62SJohn Marino   ret = savestring (ts);
256*6b445a62SJohn Marino   ret[0] = history_comment_char;
257*6b445a62SJohn Marino 
258*6b445a62SJohn Marino   return ret;
259*6b445a62SJohn Marino }
260*6b445a62SJohn Marino 
261*6b445a62SJohn Marino /* Place STRING at the end of the history list.  The data field
262*6b445a62SJohn Marino    is  set to NULL. */
263*6b445a62SJohn Marino void
add_history(string)264*6b445a62SJohn Marino add_history (string)
265*6b445a62SJohn Marino      const char *string;
266*6b445a62SJohn Marino {
267*6b445a62SJohn Marino   HIST_ENTRY *temp;
268*6b445a62SJohn Marino 
269*6b445a62SJohn Marino   if (history_stifled && (history_length == history_max_entries))
270*6b445a62SJohn Marino     {
271*6b445a62SJohn Marino       register int i;
272*6b445a62SJohn Marino 
273*6b445a62SJohn Marino       /* If the history is stifled, and history_length is zero,
274*6b445a62SJohn Marino 	 and it equals history_max_entries, we don't save items. */
275*6b445a62SJohn Marino       if (history_length == 0)
276*6b445a62SJohn Marino 	return;
277*6b445a62SJohn Marino 
278*6b445a62SJohn Marino       /* If there is something in the slot, then remove it. */
279*6b445a62SJohn Marino       if (the_history[0])
280*6b445a62SJohn Marino 	(void) free_history_entry (the_history[0]);
281*6b445a62SJohn Marino 
282*6b445a62SJohn Marino       /* Copy the rest of the entries, moving down one slot. */
283*6b445a62SJohn Marino       for (i = 0; i < history_length; i++)
284*6b445a62SJohn Marino 	the_history[i] = the_history[i + 1];
285*6b445a62SJohn Marino 
286*6b445a62SJohn Marino       history_base++;
287*6b445a62SJohn Marino     }
288*6b445a62SJohn Marino   else
289*6b445a62SJohn Marino     {
290*6b445a62SJohn Marino       if (history_size == 0)
291*6b445a62SJohn Marino 	{
292*6b445a62SJohn Marino 	  history_size = DEFAULT_HISTORY_GROW_SIZE;
293*6b445a62SJohn Marino 	  the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
294*6b445a62SJohn Marino 	  history_length = 1;
295*6b445a62SJohn Marino 	}
296*6b445a62SJohn Marino       else
297*6b445a62SJohn Marino 	{
298*6b445a62SJohn Marino 	  if (history_length == (history_size - 1))
299*6b445a62SJohn Marino 	    {
300*6b445a62SJohn Marino 	      history_size += DEFAULT_HISTORY_GROW_SIZE;
301*6b445a62SJohn Marino 	      the_history = (HIST_ENTRY **)
302*6b445a62SJohn Marino 		xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
303*6b445a62SJohn Marino 	    }
304*6b445a62SJohn Marino 	  history_length++;
305*6b445a62SJohn Marino 	}
306*6b445a62SJohn Marino     }
307*6b445a62SJohn Marino 
308*6b445a62SJohn Marino   temp = alloc_history_entry (string, hist_inittime ());
309*6b445a62SJohn Marino 
310*6b445a62SJohn Marino   the_history[history_length] = (HIST_ENTRY *)NULL;
311*6b445a62SJohn Marino   the_history[history_length - 1] = temp;
312*6b445a62SJohn Marino }
313*6b445a62SJohn Marino 
314*6b445a62SJohn Marino /* Change the time stamp of the most recent history entry to STRING. */
315*6b445a62SJohn Marino void
add_history_time(string)316*6b445a62SJohn Marino add_history_time (string)
317*6b445a62SJohn Marino      const char *string;
318*6b445a62SJohn Marino {
319*6b445a62SJohn Marino   HIST_ENTRY *hs;
320*6b445a62SJohn Marino 
321*6b445a62SJohn Marino   if (string == 0)
322*6b445a62SJohn Marino     return;
323*6b445a62SJohn Marino   hs = the_history[history_length - 1];
324*6b445a62SJohn Marino   FREE (hs->timestamp);
325*6b445a62SJohn Marino   hs->timestamp = savestring (string);
326*6b445a62SJohn Marino }
327*6b445a62SJohn Marino 
328*6b445a62SJohn Marino /* Free HIST and return the data so the calling application can free it
329*6b445a62SJohn Marino    if necessary and desired. */
330*6b445a62SJohn Marino histdata_t
free_history_entry(hist)331*6b445a62SJohn Marino free_history_entry (hist)
332*6b445a62SJohn Marino      HIST_ENTRY *hist;
333*6b445a62SJohn Marino {
334*6b445a62SJohn Marino   histdata_t x;
335*6b445a62SJohn Marino 
336*6b445a62SJohn Marino   if (hist == 0)
337*6b445a62SJohn Marino     return ((histdata_t) 0);
338*6b445a62SJohn Marino   FREE (hist->line);
339*6b445a62SJohn Marino   FREE (hist->timestamp);
340*6b445a62SJohn Marino   x = hist->data;
341*6b445a62SJohn Marino   xfree (hist);
342*6b445a62SJohn Marino   return (x);
343*6b445a62SJohn Marino }
344*6b445a62SJohn Marino 
345*6b445a62SJohn Marino HIST_ENTRY *
copy_history_entry(hist)346*6b445a62SJohn Marino copy_history_entry (hist)
347*6b445a62SJohn Marino      HIST_ENTRY *hist;
348*6b445a62SJohn Marino {
349*6b445a62SJohn Marino   HIST_ENTRY *ret;
350*6b445a62SJohn Marino   char *ts;
351*6b445a62SJohn Marino 
352*6b445a62SJohn Marino   if (hist == 0)
353*6b445a62SJohn Marino     return hist;
354*6b445a62SJohn Marino 
355*6b445a62SJohn Marino   ret = alloc_history_entry (hist->line, (char *)NULL);
356*6b445a62SJohn Marino 
357*6b445a62SJohn Marino   ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
358*6b445a62SJohn Marino   ret->timestamp = ts;
359*6b445a62SJohn Marino 
360*6b445a62SJohn Marino   ret->data = hist->data;
361*6b445a62SJohn Marino 
362*6b445a62SJohn Marino   return ret;
363*6b445a62SJohn Marino }
364*6b445a62SJohn Marino 
365*6b445a62SJohn Marino /* Make the history entry at WHICH have LINE and DATA.  This returns
366*6b445a62SJohn Marino    the old entry so you can dispose of the data.  In the case of an
367*6b445a62SJohn Marino    invalid WHICH, a NULL pointer is returned. */
368*6b445a62SJohn Marino HIST_ENTRY *
replace_history_entry(which,line,data)369*6b445a62SJohn Marino replace_history_entry (which, line, data)
370*6b445a62SJohn Marino      int which;
371*6b445a62SJohn Marino      const char *line;
372*6b445a62SJohn Marino      histdata_t data;
373*6b445a62SJohn Marino {
374*6b445a62SJohn Marino   HIST_ENTRY *temp, *old_value;
375*6b445a62SJohn Marino 
376*6b445a62SJohn Marino   if (which < 0 || which >= history_length)
377*6b445a62SJohn Marino     return ((HIST_ENTRY *)NULL);
378*6b445a62SJohn Marino 
379*6b445a62SJohn Marino   temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
380*6b445a62SJohn Marino   old_value = the_history[which];
381*6b445a62SJohn Marino 
382*6b445a62SJohn Marino   temp->line = savestring (line);
383*6b445a62SJohn Marino   temp->data = data;
384*6b445a62SJohn Marino   temp->timestamp = savestring (old_value->timestamp);
385*6b445a62SJohn Marino   the_history[which] = temp;
386*6b445a62SJohn Marino 
387*6b445a62SJohn Marino   return (old_value);
388*6b445a62SJohn Marino }
389*6b445a62SJohn Marino 
390*6b445a62SJohn Marino /* Replace the DATA in the specified history entries, replacing OLD with
391*6b445a62SJohn Marino    NEW.  WHICH says which one(s) to replace:  WHICH == -1 means to replace
392*6b445a62SJohn Marino    all of the history entries where entry->data == OLD; WHICH == -2 means
393*6b445a62SJohn Marino    to replace the `newest' history entry where entry->data == OLD; and
394*6b445a62SJohn Marino    WHICH >= 0 means to replace that particular history entry's data, as
395*6b445a62SJohn Marino    long as it matches OLD. */
396*6b445a62SJohn Marino void
replace_history_data(which,old,new)397*6b445a62SJohn Marino replace_history_data (which,old, new)
398*6b445a62SJohn Marino      int which;
399*6b445a62SJohn Marino      histdata_t *old, *new;
400*6b445a62SJohn Marino {
401*6b445a62SJohn Marino   HIST_ENTRY *entry;
402*6b445a62SJohn Marino   register int i, last;
403*6b445a62SJohn Marino 
404*6b445a62SJohn Marino   if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
405*6b445a62SJohn Marino     return;
406*6b445a62SJohn Marino 
407*6b445a62SJohn Marino   if (which >= 0)
408*6b445a62SJohn Marino     {
409*6b445a62SJohn Marino       entry = the_history[which];
410*6b445a62SJohn Marino       if (entry && entry->data == old)
411*6b445a62SJohn Marino 	entry->data = new;
412*6b445a62SJohn Marino       return;
413*6b445a62SJohn Marino     }
414*6b445a62SJohn Marino 
415*6b445a62SJohn Marino   last = -1;
416*6b445a62SJohn Marino   for (i = 0; i < history_length; i++)
417*6b445a62SJohn Marino     {
418*6b445a62SJohn Marino       entry = the_history[i];
419*6b445a62SJohn Marino       if (entry == 0)
420*6b445a62SJohn Marino 	continue;
421*6b445a62SJohn Marino       if (entry->data == old)
422*6b445a62SJohn Marino 	{
423*6b445a62SJohn Marino 	  last = i;
424*6b445a62SJohn Marino 	  if (which == -1)
425*6b445a62SJohn Marino 	    entry->data = new;
426*6b445a62SJohn Marino 	}
427*6b445a62SJohn Marino     }
428*6b445a62SJohn Marino   if (which == -2 && last >= 0)
429*6b445a62SJohn Marino     {
430*6b445a62SJohn Marino       entry = the_history[last];
431*6b445a62SJohn Marino       entry->data = new;	/* XXX - we don't check entry->old */
432*6b445a62SJohn Marino     }
433*6b445a62SJohn Marino }
434*6b445a62SJohn Marino 
435*6b445a62SJohn Marino /* Remove history element WHICH from the history.  The removed
436*6b445a62SJohn Marino    element is returned to you so you can free the line, data,
437*6b445a62SJohn Marino    and containing structure. */
438*6b445a62SJohn Marino HIST_ENTRY *
remove_history(which)439*6b445a62SJohn Marino remove_history (which)
440*6b445a62SJohn Marino      int which;
441*6b445a62SJohn Marino {
442*6b445a62SJohn Marino   HIST_ENTRY *return_value;
443*6b445a62SJohn Marino   register int i;
444*6b445a62SJohn Marino 
445*6b445a62SJohn Marino   if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)
446*6b445a62SJohn Marino     return ((HIST_ENTRY *)NULL);
447*6b445a62SJohn Marino 
448*6b445a62SJohn Marino   return_value = the_history[which];
449*6b445a62SJohn Marino 
450*6b445a62SJohn Marino   for (i = which; i < history_length; i++)
451*6b445a62SJohn Marino     the_history[i] = the_history[i + 1];
452*6b445a62SJohn Marino 
453*6b445a62SJohn Marino   history_length--;
454*6b445a62SJohn Marino 
455*6b445a62SJohn Marino   return (return_value);
456*6b445a62SJohn Marino }
457*6b445a62SJohn Marino 
458*6b445a62SJohn Marino /* Stifle the history list, remembering only MAX number of lines. */
459*6b445a62SJohn Marino void
stifle_history(max)460*6b445a62SJohn Marino stifle_history (max)
461*6b445a62SJohn Marino      int max;
462*6b445a62SJohn Marino {
463*6b445a62SJohn Marino   register int i, j;
464*6b445a62SJohn Marino 
465*6b445a62SJohn Marino   if (max < 0)
466*6b445a62SJohn Marino     max = 0;
467*6b445a62SJohn Marino 
468*6b445a62SJohn Marino   if (history_length > max)
469*6b445a62SJohn Marino     {
470*6b445a62SJohn Marino       /* This loses because we cannot free the data. */
471*6b445a62SJohn Marino       for (i = 0, j = history_length - max; i < j; i++)
472*6b445a62SJohn Marino 	free_history_entry (the_history[i]);
473*6b445a62SJohn Marino 
474*6b445a62SJohn Marino       history_base = i;
475*6b445a62SJohn Marino       for (j = 0, i = history_length - max; j < max; i++, j++)
476*6b445a62SJohn Marino 	the_history[j] = the_history[i];
477*6b445a62SJohn Marino       the_history[j] = (HIST_ENTRY *)NULL;
478*6b445a62SJohn Marino       history_length = j;
479*6b445a62SJohn Marino     }
480*6b445a62SJohn Marino 
481*6b445a62SJohn Marino   history_stifled = 1;
482*6b445a62SJohn Marino   max_input_history = history_max_entries = max;
483*6b445a62SJohn Marino }
484*6b445a62SJohn Marino 
485*6b445a62SJohn Marino /* Stop stifling the history.  This returns the previous maximum
486*6b445a62SJohn Marino    number of history entries.  The value is positive if the history
487*6b445a62SJohn Marino    was stifled, negative if it wasn't. */
488*6b445a62SJohn Marino int
unstifle_history()489*6b445a62SJohn Marino unstifle_history ()
490*6b445a62SJohn Marino {
491*6b445a62SJohn Marino   if (history_stifled)
492*6b445a62SJohn Marino     {
493*6b445a62SJohn Marino       history_stifled = 0;
494*6b445a62SJohn Marino       return (history_max_entries);
495*6b445a62SJohn Marino     }
496*6b445a62SJohn Marino   else
497*6b445a62SJohn Marino     return (-history_max_entries);
498*6b445a62SJohn Marino }
499*6b445a62SJohn Marino 
500*6b445a62SJohn Marino int
history_is_stifled()501*6b445a62SJohn Marino history_is_stifled ()
502*6b445a62SJohn Marino {
503*6b445a62SJohn Marino   return (history_stifled);
504*6b445a62SJohn Marino }
505*6b445a62SJohn Marino 
506*6b445a62SJohn Marino void
clear_history()507*6b445a62SJohn Marino clear_history ()
508*6b445a62SJohn Marino {
509*6b445a62SJohn Marino   register int i;
510*6b445a62SJohn Marino 
511*6b445a62SJohn Marino   /* This loses because we cannot free the data. */
512*6b445a62SJohn Marino   for (i = 0; i < history_length; i++)
513*6b445a62SJohn Marino     {
514*6b445a62SJohn Marino       free_history_entry (the_history[i]);
515*6b445a62SJohn Marino       the_history[i] = (HIST_ENTRY *)NULL;
516*6b445a62SJohn Marino     }
517*6b445a62SJohn Marino 
518*6b445a62SJohn Marino   history_offset = history_length = 0;
519*6b445a62SJohn Marino }
520