1 |
106 |
markom |
@ignore
|
2 |
|
|
This file documents the user interface to the GNU History library.
|
3 |
|
|
|
4 |
|
|
Copyright (C) 1988, 1991, 1994, 1996 Free Software Foundation, Inc.
|
5 |
|
|
Authored by Brian Fox and Chet Ramey.
|
6 |
|
|
|
7 |
|
|
Permission is granted to make and distribute verbatim copies of this manual
|
8 |
|
|
provided the copyright notice and this permission notice are preserved on
|
9 |
|
|
all copies.
|
10 |
|
|
|
11 |
|
|
Permission is granted to process this file through Tex and print the
|
12 |
|
|
results, provided the printed document carries copying permission notice
|
13 |
|
|
identical to this one except for the removal of this paragraph (this
|
14 |
|
|
paragraph not being relevant to the printed manual).
|
15 |
|
|
|
16 |
|
|
Permission is granted to copy and distribute modified versions of this
|
17 |
|
|
manual under the conditions for verbatim copying, provided also that the
|
18 |
|
|
GNU Copyright statement is available to the distributee, and provided that
|
19 |
|
|
the entire resulting derived work is distributed under the terms of a
|
20 |
|
|
permission notice identical to this one.
|
21 |
|
|
|
22 |
|
|
Permission is granted to copy and distribute translations of this manual
|
23 |
|
|
into another language, under the above conditions for modified versions.
|
24 |
|
|
@end ignore
|
25 |
|
|
|
26 |
|
|
@node Programming with GNU History
|
27 |
|
|
@chapter Programming with GNU History
|
28 |
|
|
|
29 |
|
|
This chapter describes how to interface programs that you write
|
30 |
|
|
with the GNU History Library.
|
31 |
|
|
It should be considered a technical guide.
|
32 |
|
|
For information on the interactive use of GNU History, @pxref{Using
|
33 |
|
|
History Interactively}.
|
34 |
|
|
|
35 |
|
|
@menu
|
36 |
|
|
* Introduction to History:: What is the GNU History library for?
|
37 |
|
|
* History Storage:: How information is stored.
|
38 |
|
|
* History Functions:: Functions that you can use.
|
39 |
|
|
* History Variables:: Variables that control behaviour.
|
40 |
|
|
* History Programming Example:: Example of using the GNU History Library.
|
41 |
|
|
@end menu
|
42 |
|
|
|
43 |
|
|
@node Introduction to History
|
44 |
|
|
@section Introduction to History
|
45 |
|
|
|
46 |
|
|
Many programs read input from the user a line at a time. The GNU History
|
47 |
|
|
library is able to keep track of those lines, associate arbitrary data with
|
48 |
|
|
each line, and utilize information from previous lines in composing new
|
49 |
|
|
ones.
|
50 |
|
|
|
51 |
|
|
The programmer using the History library has available functions
|
52 |
|
|
for remembering lines on a history list, associating arbitrary data
|
53 |
|
|
with a line, removing lines from the list, searching through the list
|
54 |
|
|
for a line containing an arbitrary text string, and referencing any line
|
55 |
|
|
in the list directly. In addition, a history @dfn{expansion} function
|
56 |
|
|
is available which provides for a consistent user interface across
|
57 |
|
|
different programs.
|
58 |
|
|
|
59 |
|
|
The user using programs written with the History library has the
|
60 |
|
|
benefit of a consistent user interface with a set of well-known
|
61 |
|
|
commands for manipulating the text of previous lines and using that text
|
62 |
|
|
in new commands. The basic history manipulation commands are similar to
|
63 |
|
|
the history substitution provided by @code{csh}.
|
64 |
|
|
|
65 |
|
|
If the programmer desires, he can use the Readline library, which
|
66 |
|
|
includes some history manipulation by default, and has the added
|
67 |
|
|
advantage of command line editing.
|
68 |
|
|
|
69 |
|
|
@node History Storage
|
70 |
|
|
@section History Storage
|
71 |
|
|
|
72 |
|
|
The history list is an array of history entries. A history entry is
|
73 |
|
|
declared as follows:
|
74 |
|
|
|
75 |
|
|
@example
|
76 |
|
|
typedef struct _hist_entry @{
|
77 |
|
|
char *line;
|
78 |
|
|
char *data;
|
79 |
|
|
@} HIST_ENTRY;
|
80 |
|
|
@end example
|
81 |
|
|
|
82 |
|
|
The history list itself might therefore be declared as
|
83 |
|
|
|
84 |
|
|
@example
|
85 |
|
|
HIST_ENTRY **the_history_list;
|
86 |
|
|
@end example
|
87 |
|
|
|
88 |
|
|
The state of the History library is encapsulated into a single structure:
|
89 |
|
|
|
90 |
|
|
@example
|
91 |
|
|
/* A structure used to pass the current state of the history stuff around. */
|
92 |
|
|
typedef struct _hist_state @{
|
93 |
|
|
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
|
94 |
|
|
int offset; /* The location pointer within this array. */
|
95 |
|
|
int length; /* Number of elements within this array. */
|
96 |
|
|
int size; /* Number of slots allocated to this array. */
|
97 |
|
|
int flags;
|
98 |
|
|
@} HISTORY_STATE;
|
99 |
|
|
@end example
|
100 |
|
|
|
101 |
|
|
If the flags member includes @code{HS_STIFLED}, the history has been
|
102 |
|
|
stifled.
|
103 |
|
|
|
104 |
|
|
@node History Functions
|
105 |
|
|
@section History Functions
|
106 |
|
|
|
107 |
|
|
This section describes the calling sequence for the various functions
|
108 |
|
|
present in GNU History.
|
109 |
|
|
|
110 |
|
|
@menu
|
111 |
|
|
* Initializing History and State Management:: Functions to call when you
|
112 |
|
|
want to use history in a
|
113 |
|
|
program.
|
114 |
|
|
* History List Management:: Functions used to manage the list
|
115 |
|
|
of history entries.
|
116 |
|
|
* Information About the History List:: Functions returning information about
|
117 |
|
|
the history list.
|
118 |
|
|
* Moving Around the History List:: Functions used to change the position
|
119 |
|
|
in the history list.
|
120 |
|
|
* Searching the History List:: Functions to search the history list
|
121 |
|
|
for entries containing a string.
|
122 |
|
|
* Managing the History File:: Functions that read and write a file
|
123 |
|
|
containing the history list.
|
124 |
|
|
* History Expansion:: Functions to perform csh-like history
|
125 |
|
|
expansion.
|
126 |
|
|
@end menu
|
127 |
|
|
|
128 |
|
|
@node Initializing History and State Management
|
129 |
|
|
@subsection Initializing History and State Management
|
130 |
|
|
|
131 |
|
|
This section describes functions used to initialize and manage
|
132 |
|
|
the state of the History library when you want to use the history
|
133 |
|
|
functions in your program.
|
134 |
|
|
|
135 |
|
|
@deftypefun void using_history ()
|
136 |
|
|
Begin a session in which the history functions might be used. This
|
137 |
|
|
initializes the interactive variables.
|
138 |
|
|
@end deftypefun
|
139 |
|
|
|
140 |
|
|
@deftypefun {HISTORY_STATE *} history_get_history_state ()
|
141 |
|
|
Return a structure describing the current state of the input history.
|
142 |
|
|
@end deftypefun
|
143 |
|
|
|
144 |
|
|
@deftypefun void history_set_history_state (HISTORY_STATE *state)
|
145 |
|
|
Set the state of the history list according to @var{state}.
|
146 |
|
|
@end deftypefun
|
147 |
|
|
|
148 |
|
|
@node History List Management
|
149 |
|
|
@subsection History List Management
|
150 |
|
|
|
151 |
|
|
These functions manage individual entries on the history list, or set
|
152 |
|
|
parameters managing the list itself.
|
153 |
|
|
|
154 |
|
|
@deftypefun void add_history (char *string)
|
155 |
|
|
Place @var{string} at the end of the history list. The associated data
|
156 |
|
|
field (if any) is set to @code{NULL}.
|
157 |
|
|
@end deftypefun
|
158 |
|
|
|
159 |
|
|
@deftypefun {HIST_ENTRY *} remove_history (int which)
|
160 |
|
|
Remove history entry at offset @var{which} from the history. The
|
161 |
|
|
removed element is returned so you can free the line, data,
|
162 |
|
|
and containing structure.
|
163 |
|
|
@end deftypefun
|
164 |
|
|
|
165 |
|
|
@deftypefun {HIST_ENTRY *} replace_history_entry (int which, char *line, char *data)
|
166 |
|
|
Make the history entry at offset @var{which} have @var{line} and @var{data}.
|
167 |
|
|
This returns the old entry so you can dispose of the data. In the case
|
168 |
|
|
of an invalid @var{which}, a @code{NULL} pointer is returned.
|
169 |
|
|
@end deftypefun
|
170 |
|
|
|
171 |
|
|
@deftypefun void clear_history ()
|
172 |
|
|
Clear the history list by deleting all the entries.
|
173 |
|
|
@end deftypefun
|
174 |
|
|
|
175 |
|
|
@deftypefun void stifle_history (int max)
|
176 |
|
|
Stifle the history list, remembering only the last @var{max} entries.
|
177 |
|
|
@end deftypefun
|
178 |
|
|
|
179 |
|
|
@deftypefun int unstifle_history ()
|
180 |
|
|
Stop stifling the history. This returns the previous amount the
|
181 |
|
|
history was stifled. The value is positive if the history was
|
182 |
|
|
stifled, negative if it wasn't.
|
183 |
|
|
@end deftypefun
|
184 |
|
|
|
185 |
|
|
@deftypefun int history_is_stifled ()
|
186 |
|
|
Returns non-zero if the history is stifled, zero if it is not.
|
187 |
|
|
@end deftypefun
|
188 |
|
|
|
189 |
|
|
@node Information About the History List
|
190 |
|
|
@subsection Information About the History List
|
191 |
|
|
|
192 |
|
|
These functions return information about the entire history list or
|
193 |
|
|
individual list entries.
|
194 |
|
|
|
195 |
|
|
@deftypefun {HIST_ENTRY **} history_list ()
|
196 |
|
|
Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the
|
197 |
|
|
current input history. Element 0 of this list is the beginning of time.
|
198 |
|
|
If there is no history, return @code{NULL}.
|
199 |
|
|
@end deftypefun
|
200 |
|
|
|
201 |
|
|
@deftypefun int where_history ()
|
202 |
|
|
Returns the offset of the current history element.
|
203 |
|
|
@end deftypefun
|
204 |
|
|
|
205 |
|
|
@deftypefun {HIST_ENTRY *} current_history ()
|
206 |
|
|
Return the history entry at the current position, as determined by
|
207 |
|
|
@code{where_history ()}. If there is no entry there, return a @code{NULL}
|
208 |
|
|
pointer.
|
209 |
|
|
@end deftypefun
|
210 |
|
|
|
211 |
|
|
@deftypefun {HIST_ENTRY *} history_get (int offset)
|
212 |
|
|
Return the history entry at position @var{offset}, starting from
|
213 |
|
|
@code{history_base}. If there is no entry there, or if @var{offset}
|
214 |
|
|
is greater than the history length, return a @code{NULL} pointer.
|
215 |
|
|
@end deftypefun
|
216 |
|
|
|
217 |
|
|
@deftypefun int history_total_bytes ()
|
218 |
|
|
Return the number of bytes that the primary history entries are using.
|
219 |
|
|
This function returns the sum of the lengths of all the lines in the
|
220 |
|
|
history.
|
221 |
|
|
@end deftypefun
|
222 |
|
|
|
223 |
|
|
@node Moving Around the History List
|
224 |
|
|
@subsection Moving Around the History List
|
225 |
|
|
|
226 |
|
|
These functions allow the current index into the history list to be
|
227 |
|
|
set or changed.
|
228 |
|
|
|
229 |
|
|
@deftypefun int history_set_pos (int pos)
|
230 |
|
|
Set the position in the history list to @var{pos}, an absolute index
|
231 |
|
|
into the list.
|
232 |
|
|
@end deftypefun
|
233 |
|
|
|
234 |
|
|
@deftypefun {HIST_ENTRY *} previous_history ()
|
235 |
|
|
Back up the current history offset to the previous history entry, and
|
236 |
|
|
return a pointer to that entry. If there is no previous entry, return
|
237 |
|
|
a @code{NULL} pointer.
|
238 |
|
|
@end deftypefun
|
239 |
|
|
|
240 |
|
|
@deftypefun {HIST_ENTRY *} next_history ()
|
241 |
|
|
Move the current history offset forward to the next history entry, and
|
242 |
|
|
return the a pointer to that entry. If there is no next entry, return
|
243 |
|
|
a @code{NULL} pointer.
|
244 |
|
|
@end deftypefun
|
245 |
|
|
|
246 |
|
|
@node Searching the History List
|
247 |
|
|
@subsection Searching the History List
|
248 |
|
|
@cindex History Searching
|
249 |
|
|
|
250 |
|
|
These functions allow searching of the history list for entries containing
|
251 |
|
|
a specific string. Searching may be performed both forward and backward
|
252 |
|
|
from the current history position. The search may be @dfn{anchored},
|
253 |
|
|
meaning that the string must match at the beginning of the history entry.
|
254 |
|
|
@cindex anchored search
|
255 |
|
|
|
256 |
|
|
@deftypefun int history_search (char *string, int direction)
|
257 |
|
|
Search the history for @var{string}, starting at the current history
|
258 |
|
|
offset. If @var{direction} < 0, then the search is through previous entries,
|
259 |
|
|
else through subsequent. If @var{string} is found, then
|
260 |
|
|
the current history index is set to that history entry, and the value
|
261 |
|
|
returned is the offset in the line of the entry where
|
262 |
|
|
@var{string} was found. Otherwise, nothing is changed, and a -1 is
|
263 |
|
|
returned.
|
264 |
|
|
@end deftypefun
|
265 |
|
|
|
266 |
|
|
@deftypefun int history_search_prefix (char *string, int direction)
|
267 |
|
|
Search the history for @var{string}, starting at the current history
|
268 |
|
|
offset. The search is anchored: matching lines must begin with
|
269 |
|
|
@var{string}. If @var{direction} < 0, then the search is through previous
|
270 |
|
|
entries, else through subsequent. If @var{string} is found, then the
|
271 |
|
|
current history index is set to that entry, and the return value is 0.
|
272 |
|
|
Otherwise, nothing is changed, and a -1 is returned.
|
273 |
|
|
@end deftypefun
|
274 |
|
|
|
275 |
|
|
@deftypefun int history_search_pos (char *string, int direction, int pos)
|
276 |
|
|
Search for @var{string} in the history list, starting at @var{pos}, an
|
277 |
|
|
absolute index into the list. If @var{direction} is negative, the search
|
278 |
|
|
proceeds backward from @var{pos}, otherwise forward. Returns the absolute
|
279 |
|
|
index of the history element where @var{string} was found, or -1 otherwise.
|
280 |
|
|
@end deftypefun
|
281 |
|
|
|
282 |
|
|
@node Managing the History File
|
283 |
|
|
@subsection Managing the History File
|
284 |
|
|
|
285 |
|
|
The History library can read the history from and write it to a file.
|
286 |
|
|
This section documents the functions for managing a history file.
|
287 |
|
|
|
288 |
|
|
@deftypefun int read_history (char *filename)
|
289 |
|
|
Add the contents of @var{filename} to the history list, a line at a
|
290 |
|
|
time. If @var{filename} is @code{NULL}, then read from
|
291 |
|
|
@file{~/.history}. Returns 0 if successful, or errno if not.
|
292 |
|
|
@end deftypefun
|
293 |
|
|
|
294 |
|
|
@deftypefun int read_history_range (char *filename, int from, int to)
|
295 |
|
|
Read a range of lines from @var{filename}, adding them to the history list.
|
296 |
|
|
Start reading at line @var{from} and end at @var{to}. If
|
297 |
|
|
@var{from} is zero, start at the beginning. If @var{to} is less than
|
298 |
|
|
@var{from}, then read until the end of the file. If @var{filename} is
|
299 |
|
|
@code{NULL}, then read from @file{~/.history}. Returns 0 if successful,
|
300 |
|
|
or @code{errno} if not.
|
301 |
|
|
@end deftypefun
|
302 |
|
|
|
303 |
|
|
@deftypefun int write_history (char *filename)
|
304 |
|
|
Write the current history to @var{filename}, overwriting @var{filename}
|
305 |
|
|
if necessary. If @var{filename} is
|
306 |
|
|
@code{NULL}, then write the history list to @file{~/.history}. Values
|
307 |
|
|
returned are as in @code{read_history ()}.
|
308 |
|
|
@end deftypefun
|
309 |
|
|
|
310 |
|
|
@deftypefun int append_history (int nelements, char *filename)
|
311 |
|
|
Append the last @var{nelements} of the history list to @var{filename}.
|
312 |
|
|
@end deftypefun
|
313 |
|
|
|
314 |
|
|
@deftypefun int history_truncate_file (char *filename, int nlines)
|
315 |
|
|
Truncate the history file @var{filename}, leaving only the last
|
316 |
|
|
@var{nlines} lines.
|
317 |
|
|
@end deftypefun
|
318 |
|
|
|
319 |
|
|
@node History Expansion
|
320 |
|
|
@subsection History Expansion
|
321 |
|
|
|
322 |
|
|
These functions implement @code{csh}-like history expansion.
|
323 |
|
|
|
324 |
|
|
@deftypefun int history_expand (char *string, char **output)
|
325 |
|
|
Expand @var{string}, placing the result into @var{output}, a pointer
|
326 |
|
|
to a string (@pxref{History Interaction}). Returns:
|
327 |
|
|
@table @code
|
328 |
|
|
@item 0
|
329 |
|
|
If no expansions took place (or, if the only change in
|
330 |
|
|
the text was the de-slashifying of the history expansion
|
331 |
|
|
character);
|
332 |
|
|
@item 1
|
333 |
|
|
if expansions did take place;
|
334 |
|
|
@item -1
|
335 |
|
|
if there was an error in expansion;
|
336 |
|
|
@item 2
|
337 |
|
|
if the returned line should only be displayed, but not executed,
|
338 |
|
|
as with the @code{:p} modifier (@pxref{Modifiers}).
|
339 |
|
|
@end table
|
340 |
|
|
|
341 |
|
|
If an error ocurred in expansion, then @var{output} contains a descriptive
|
342 |
|
|
error message.
|
343 |
|
|
@end deftypefun
|
344 |
|
|
|
345 |
|
|
@deftypefun {char *} history_arg_extract (int first, int last, char *string)
|
346 |
|
|
Extract a string segment consisting of the @var{first} through @var{last}
|
347 |
|
|
arguments present in @var{string}. Arguments are broken up as in Bash.
|
348 |
|
|
@end deftypefun
|
349 |
|
|
|
350 |
|
|
@deftypefun {char *} get_history_event (char *string, int *cindex, int qchar)
|
351 |
|
|
Returns the text of the history event beginning at @var{string} +
|
352 |
|
|
@var{*cindex}. @var{*cindex} is modified to point to after the event
|
353 |
|
|
specifier. At function entry, @var{cindex} points to the index into
|
354 |
|
|
@var{string} where the history event specification begins. @var{qchar}
|
355 |
|
|
is a character that is allowed to end the event specification in addition
|
356 |
|
|
to the ``normal'' terminating characters.
|
357 |
|
|
@end deftypefun
|
358 |
|
|
|
359 |
|
|
@deftypefun {char **} history_tokenize (char *string)
|
360 |
|
|
Return an array of tokens parsed out of @var{string}, much as the
|
361 |
|
|
shell might. The tokens are split on white space and on the
|
362 |
|
|
characters @code{()<>;&|$}, and shell quoting conventions are
|
363 |
|
|
obeyed.
|
364 |
|
|
@end deftypefun
|
365 |
|
|
|
366 |
|
|
@node History Variables
|
367 |
|
|
@section History Variables
|
368 |
|
|
|
369 |
|
|
This section describes the externally visible variables exported by
|
370 |
|
|
the GNU History Library.
|
371 |
|
|
|
372 |
|
|
@deftypevar int history_base
|
373 |
|
|
The logical offset of the first entry in the history list.
|
374 |
|
|
@end deftypevar
|
375 |
|
|
|
376 |
|
|
@deftypevar int history_length
|
377 |
|
|
The number of entries currently stored in the history list.
|
378 |
|
|
@end deftypevar
|
379 |
|
|
|
380 |
|
|
@deftypevar int max_input_history
|
381 |
|
|
The maximum number of history entries. This must be changed using
|
382 |
|
|
@code{stifle_history ()}.
|
383 |
|
|
@end deftypevar
|
384 |
|
|
|
385 |
|
|
@deftypevar char history_expansion_char
|
386 |
|
|
The character that starts a history event. The default is @samp{!}.
|
387 |
|
|
@end deftypevar
|
388 |
|
|
|
389 |
|
|
@deftypevar char history_subst_char
|
390 |
|
|
The character that invokes word substitution if found at the start of
|
391 |
|
|
a line. The default is @samp{^}.
|
392 |
|
|
@end deftypevar
|
393 |
|
|
|
394 |
|
|
@deftypevar char history_comment_char
|
395 |
|
|
During tokenization, if this character is seen as the first character
|
396 |
|
|
of a word, then it and all subsequent characters up to a newline are
|
397 |
|
|
ignored, suppressing history expansion for the remainder of the line.
|
398 |
|
|
This is disabled by default.
|
399 |
|
|
@end deftypevar
|
400 |
|
|
|
401 |
|
|
@deftypevar {char *} history_no_expand_chars
|
402 |
|
|
The list of characters which inhibit history expansion if found immediately
|
403 |
|
|
following @var{history_expansion_char}. The default is whitespace and
|
404 |
|
|
@samp{=}.
|
405 |
|
|
@end deftypevar
|
406 |
|
|
|
407 |
|
|
@deftypevar {char *} history_search_delimiter_chars
|
408 |
|
|
The list of additional characters which can delimit a history search
|
409 |
|
|
string, in addition to whitespace, @samp{:} and @samp{?} in the case of
|
410 |
|
|
a substring search. The default is empty.
|
411 |
|
|
@end deftypevar
|
412 |
|
|
|
413 |
|
|
@deftypevar int history_quotes_inhibit_expansion
|
414 |
|
|
If non-zero, single-quoted words are not scanned for the history expansion
|
415 |
|
|
character. The default value is 0.
|
416 |
|
|
@end deftypevar
|
417 |
|
|
|
418 |
|
|
@deftypevar {Function *} history_inhibit_expansion_function
|
419 |
|
|
This should be set to the address of a function that takes two arguments:
|
420 |
|
|
a @code{char *} (@var{string}) and an integer index into that string (@var{i}).
|
421 |
|
|
It should return a non-zero value if the history expansion starting at
|
422 |
|
|
@var{string[i]} should not be performed; zero if the expansion should
|
423 |
|
|
be done.
|
424 |
|
|
It is intended for use by applications like Bash that use the history
|
425 |
|
|
expansion character for additional purposes.
|
426 |
|
|
By default, this variable is set to NULL.
|
427 |
|
|
@end deftypevar
|
428 |
|
|
|
429 |
|
|
@node History Programming Example
|
430 |
|
|
@section History Programming Example
|
431 |
|
|
|
432 |
|
|
The following program demonstrates simple use of the GNU History Library.
|
433 |
|
|
|
434 |
|
|
@smallexample
|
435 |
|
|
main ()
|
436 |
|
|
@{
|
437 |
|
|
char line[1024], *t;
|
438 |
|
|
int len, done = 0;
|
439 |
|
|
|
440 |
|
|
line[0] = 0;
|
441 |
|
|
|
442 |
|
|
using_history ();
|
443 |
|
|
while (!done)
|
444 |
|
|
@{
|
445 |
|
|
printf ("history$ ");
|
446 |
|
|
fflush (stdout);
|
447 |
|
|
t = fgets (line, sizeof (line) - 1, stdin);
|
448 |
|
|
if (t && *t)
|
449 |
|
|
@{
|
450 |
|
|
len = strlen (t);
|
451 |
|
|
if (t[len - 1] == '\n')
|
452 |
|
|
t[len - 1] = '\0';
|
453 |
|
|
@}
|
454 |
|
|
|
455 |
|
|
if (!t)
|
456 |
|
|
strcpy (line, "quit");
|
457 |
|
|
|
458 |
|
|
if (line[0])
|
459 |
|
|
@{
|
460 |
|
|
char *expansion;
|
461 |
|
|
int result;
|
462 |
|
|
|
463 |
|
|
result = history_expand (line, &expansion);
|
464 |
|
|
if (result)
|
465 |
|
|
fprintf (stderr, "%s\n", expansion);
|
466 |
|
|
|
467 |
|
|
if (result < 0 || result == 2)
|
468 |
|
|
@{
|
469 |
|
|
free (expansion);
|
470 |
|
|
continue;
|
471 |
|
|
@}
|
472 |
|
|
|
473 |
|
|
add_history (expansion);
|
474 |
|
|
strncpy (line, expansion, sizeof (line) - 1);
|
475 |
|
|
free (expansion);
|
476 |
|
|
@}
|
477 |
|
|
|
478 |
|
|
if (strcmp (line, "quit") == 0)
|
479 |
|
|
done = 1;
|
480 |
|
|
else if (strcmp (line, "save") == 0)
|
481 |
|
|
write_history ("history_file");
|
482 |
|
|
else if (strcmp (line, "read") == 0)
|
483 |
|
|
read_history ("history_file");
|
484 |
|
|
else if (strcmp (line, "list") == 0)
|
485 |
|
|
@{
|
486 |
|
|
register HIST_ENTRY **the_list;
|
487 |
|
|
register int i;
|
488 |
|
|
|
489 |
|
|
the_list = history_list ();
|
490 |
|
|
if (the_list)
|
491 |
|
|
for (i = 0; the_list[i]; i++)
|
492 |
|
|
printf ("%d: %s\n", i + history_base, the_list[i]->line);
|
493 |
|
|
@}
|
494 |
|
|
else if (strncmp (line, "delete", 6) == 0)
|
495 |
|
|
@{
|
496 |
|
|
int which;
|
497 |
|
|
if ((sscanf (line + 6, "%d", &which)) == 1)
|
498 |
|
|
@{
|
499 |
|
|
HIST_ENTRY *entry = remove_history (which);
|
500 |
|
|
if (!entry)
|
501 |
|
|
fprintf (stderr, "No such entry %d\n", which);
|
502 |
|
|
else
|
503 |
|
|
@{
|
504 |
|
|
free (entry->line);
|
505 |
|
|
free (entry);
|
506 |
|
|
@}
|
507 |
|
|
@}
|
508 |
|
|
else
|
509 |
|
|
@{
|
510 |
|
|
fprintf (stderr, "non-numeric arg given to `delete'\n");
|
511 |
|
|
@}
|
512 |
|
|
@}
|
513 |
|
|
@}
|
514 |
|
|
@}
|
515 |
|
|
@end smallexample
|