| 1 | @ignore |
| 2 | This file documents the user interface to the GNU History library. |
| 3 | |
| 4 | Copyright (C) 1988-2016 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 @sc{gnu} History Library. |
| 31 | It should be considered a technical guide. |
| 32 | For information on the interactive use of @sc{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 @sc{gnu} |
| 47 | History library is able to keep track of those lines, associate arbitrary |
| 48 | data with each line, and utilize information from previous lines in |
| 49 | composing new 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 | Before declaring any functions using any functionality the History |
| 70 | library provides in other code, an application writer should include |
| 71 | the file @code{<readline/history.h>} in any file that uses the |
| 72 | History library's features. It supplies extern declarations for all |
| 73 | of the library's public functions and variables, and declares all of |
| 74 | the public data structures. |
| 75 | |
| 76 | @node History Storage |
| 77 | @section History Storage |
| 78 | |
| 79 | The history list is an array of history entries. A history entry is |
| 80 | declared as follows: |
| 81 | |
| 82 | @example |
| 83 | typedef void *histdata_t; |
| 84 | |
| 85 | typedef struct _hist_entry @{ |
| 86 | char *line; |
| 87 | char *timestamp; |
| 88 | histdata_t data; |
| 89 | @} HIST_ENTRY; |
| 90 | @end example |
| 91 | |
| 92 | The history list itself might therefore be declared as |
| 93 | |
| 94 | @example |
| 95 | HIST_ENTRY **the_history_list; |
| 96 | @end example |
| 97 | |
| 98 | The state of the History library is encapsulated into a single structure: |
| 99 | |
| 100 | @example |
| 101 | /* |
| 102 | * A structure used to pass around the current state of the history. |
| 103 | */ |
| 104 | typedef struct _hist_state @{ |
| 105 | HIST_ENTRY **entries; /* Pointer to the entries themselves. */ |
| 106 | int offset; /* The location pointer within this array. */ |
| 107 | int length; /* Number of elements within this array. */ |
| 108 | int size; /* Number of slots allocated to this array. */ |
| 109 | int flags; |
| 110 | @} HISTORY_STATE; |
| 111 | @end example |
| 112 | |
| 113 | If the flags member includes @code{HS_STIFLED}, the history has been |
| 114 | stifled. |
| 115 | |
| 116 | @node History Functions |
| 117 | @section History Functions |
| 118 | |
| 119 | This section describes the calling sequence for the various functions |
| 120 | exported by the @sc{gnu} History library. |
| 121 | |
| 122 | @menu |
| 123 | * Initializing History and State Management:: Functions to call when you |
| 124 | want to use history in a |
| 125 | program. |
| 126 | * History List Management:: Functions used to manage the list |
| 127 | of history entries. |
| 128 | * Information About the History List:: Functions returning information about |
| 129 | the history list. |
| 130 | * Moving Around the History List:: Functions used to change the position |
| 131 | in the history list. |
| 132 | * Searching the History List:: Functions to search the history list |
| 133 | for entries containing a string. |
| 134 | * Managing the History File:: Functions that read and write a file |
| 135 | containing the history list. |
| 136 | * History Expansion:: Functions to perform csh-like history |
| 137 | expansion. |
| 138 | @end menu |
| 139 | |
| 140 | @node Initializing History and State Management |
| 141 | @subsection Initializing History and State Management |
| 142 | |
| 143 | This section describes functions used to initialize and manage |
| 144 | the state of the History library when you want to use the history |
| 145 | functions in your program. |
| 146 | |
| 147 | @deftypefun void using_history (void) |
| 148 | Begin a session in which the history functions might be used. This |
| 149 | initializes the interactive variables. |
| 150 | @end deftypefun |
| 151 | |
| 152 | @deftypefun {HISTORY_STATE *} history_get_history_state (void) |
| 153 | Return a structure describing the current state of the input history. |
| 154 | @end deftypefun |
| 155 | |
| 156 | @deftypefun void history_set_history_state (HISTORY_STATE *state) |
| 157 | Set the state of the history list according to @var{state}. |
| 158 | @end deftypefun |
| 159 | |
| 160 | @node History List Management |
| 161 | @subsection History List Management |
| 162 | |
| 163 | These functions manage individual entries on the history list, or set |
| 164 | parameters managing the list itself. |
| 165 | |
| 166 | @deftypefun void add_history (const char *string) |
| 167 | Place @var{string} at the end of the history list. The associated data |
| 168 | field (if any) is set to @code{NULL}. |
| 169 | @end deftypefun |
| 170 | |
| 171 | @deftypefun void add_history_time (const char *string) |
| 172 | Change the time stamp associated with the most recent history entry to |
| 173 | @var{string}. |
| 174 | @end deftypefun |
| 175 | |
| 176 | @deftypefun {HIST_ENTRY *} remove_history (int which) |
| 177 | Remove history entry at offset @var{which} from the history. The |
| 178 | removed element is returned so you can free the line, data, |
| 179 | and containing structure. |
| 180 | @end deftypefun |
| 181 | |
| 182 | @deftypefun {histdata_t} free_history_entry (HIST_ENTRY *histent) |
| 183 | Free the history entry @var{histent} and any history library private |
| 184 | data associated with it. Returns the application-specific data |
| 185 | so the caller can dispose of it. |
| 186 | @end deftypefun |
| 187 | |
| 188 | @deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data) |
| 189 | Make the history entry at offset @var{which} have @var{line} and @var{data}. |
| 190 | This returns the old entry so the caller can dispose of any |
| 191 | application-specific data. In the case |
| 192 | of an invalid @var{which}, a @code{NULL} pointer is returned. |
| 193 | @end deftypefun |
| 194 | |
| 195 | @deftypefun void clear_history (void) |
| 196 | Clear the history list by deleting all the entries. |
| 197 | @end deftypefun |
| 198 | |
| 199 | @deftypefun void stifle_history (int max) |
| 200 | Stifle the history list, remembering only the last @var{max} entries. |
| 201 | @end deftypefun |
| 202 | |
| 203 | @deftypefun int unstifle_history (void) |
| 204 | Stop stifling the history. This returns the previously-set |
| 205 | maximum number of history entries (as set by @code{stifle_history()}). |
| 206 | The value is positive if the history was |
| 207 | stifled, negative if it wasn't. |
| 208 | @end deftypefun |
| 209 | |
| 210 | @deftypefun int history_is_stifled (void) |
| 211 | Returns non-zero if the history is stifled, zero if it is not. |
| 212 | @end deftypefun |
| 213 | |
| 214 | @node Information About the History List |
| 215 | @subsection Information About the History List |
| 216 | |
| 217 | These functions return information about the entire history list or |
| 218 | individual list entries. |
| 219 | |
| 220 | @deftypefun {HIST_ENTRY **} history_list (void) |
| 221 | Return a @code{NULL} terminated array of @code{HIST_ENTRY *} which is the |
| 222 | current input history. Element 0 of this list is the beginning of time. |
| 223 | If there is no history, return @code{NULL}. |
| 224 | @end deftypefun |
| 225 | |
| 226 | @deftypefun int where_history (void) |
| 227 | Returns the offset of the current history element. |
| 228 | @end deftypefun |
| 229 | |
| 230 | @deftypefun {HIST_ENTRY *} current_history (void) |
| 231 | Return the history entry at the current position, as determined by |
| 232 | @code{where_history()}. If there is no entry there, return a @code{NULL} |
| 233 | pointer. |
| 234 | @end deftypefun |
| 235 | |
| 236 | @deftypefun {HIST_ENTRY *} history_get (int offset) |
| 237 | Return the history entry at position @var{offset}, starting from |
| 238 | @code{history_base} (@pxref{History Variables}). |
| 239 | If there is no entry there, or if @var{offset} |
| 240 | is greater than the history length, return a @code{NULL} pointer. |
| 241 | @end deftypefun |
| 242 | |
| 243 | @deftypefun time_t history_get_time (HIST_ENTRY *entry) |
| 244 | Return the time stamp associated with the history entry @var{entry}. |
| 245 | If the timestamp is missing or invalid, return 0. |
| 246 | @end deftypefun |
| 247 | |
| 248 | @deftypefun int history_total_bytes (void) |
| 249 | Return the number of bytes that the primary history entries are using. |
| 250 | This function returns the sum of the lengths of all the lines in the |
| 251 | history. |
| 252 | @end deftypefun |
| 253 | |
| 254 | @node Moving Around the History List |
| 255 | @subsection Moving Around the History List |
| 256 | |
| 257 | These functions allow the current index into the history list to be |
| 258 | set or changed. |
| 259 | |
| 260 | @deftypefun int history_set_pos (int pos) |
| 261 | Set the current history offset to @var{pos}, an absolute index |
| 262 | into the list. |
| 263 | Returns 1 on success, 0 if @var{pos} is less than zero or greater |
| 264 | than the number of history entries. |
| 265 | @end deftypefun |
| 266 | |
| 267 | @deftypefun {HIST_ENTRY *} previous_history (void) |
| 268 | Back up the current history offset to the previous history entry, and |
| 269 | return a pointer to that entry. If there is no previous entry, return |
| 270 | a @code{NULL} pointer. |
| 271 | @end deftypefun |
| 272 | |
| 273 | @deftypefun {HIST_ENTRY *} next_history (void) |
| 274 | If the current history offset refers to a valid history entry, |
| 275 | increment the current history offset. |
| 276 | If the possibly-incremented history offset refers to a valid history |
| 277 | entry, return a pointer to that entry; |
| 278 | otherwise, return a @code{BNULL} pointer. |
| 279 | @end deftypefun |
| 280 | |
| 281 | @node Searching the History List |
| 282 | @subsection Searching the History List |
| 283 | @cindex History Searching |
| 284 | |
| 285 | These functions allow searching of the history list for entries containing |
| 286 | a specific string. Searching may be performed both forward and backward |
| 287 | from the current history position. The search may be @dfn{anchored}, |
| 288 | meaning that the string must match at the beginning of the history entry. |
| 289 | @cindex anchored search |
| 290 | |
| 291 | @deftypefun int history_search (const char *string, int direction) |
| 292 | Search the history for @var{string}, starting at the current history offset. |
| 293 | If @var{direction} is less than 0, then the search is through |
| 294 | previous entries, otherwise through subsequent entries. |
| 295 | If @var{string} is found, then |
| 296 | the current history index is set to that history entry, and the value |
| 297 | returned is the offset in the line of the entry where |
| 298 | @var{string} was found. Otherwise, nothing is changed, and a -1 is |
| 299 | returned. |
| 300 | @end deftypefun |
| 301 | |
| 302 | @deftypefun int history_search_prefix (const char *string, int direction) |
| 303 | Search the history for @var{string}, starting at the current history |
| 304 | offset. The search is anchored: matching lines must begin with |
| 305 | @var{string}. If @var{direction} is less than 0, then the search is |
| 306 | through previous entries, otherwise through subsequent entries. |
| 307 | If @var{string} is found, then the |
| 308 | current history index is set to that entry, and the return value is 0. |
| 309 | Otherwise, nothing is changed, and a -1 is returned. |
| 310 | @end deftypefun |
| 311 | |
| 312 | @deftypefun int history_search_pos (const char *string, int direction, int pos) |
| 313 | Search for @var{string} in the history list, starting at @var{pos}, an |
| 314 | absolute index into the list. If @var{direction} is negative, the search |
| 315 | proceeds backward from @var{pos}, otherwise forward. Returns the absolute |
| 316 | index of the history element where @var{string} was found, or -1 otherwise. |
| 317 | @end deftypefun |
| 318 | |
| 319 | @node Managing the History File |
| 320 | @subsection Managing the History File |
| 321 | |
| 322 | The History library can read the history from and write it to a file. |
| 323 | This section documents the functions for managing a history file. |
| 324 | |
| 325 | @deftypefun int read_history (const char *filename) |
| 326 | Add the contents of @var{filename} to the history list, a line at a time. |
| 327 | If @var{filename} is @code{NULL}, then read from @file{~/.history}. |
| 328 | Returns 0 if successful, or @code{errno} if not. |
| 329 | @end deftypefun |
| 330 | |
| 331 | @deftypefun int read_history_range (const char *filename, int from, int to) |
| 332 | Read a range of lines from @var{filename}, adding them to the history list. |
| 333 | Start reading at line @var{from} and end at @var{to}. |
| 334 | If @var{from} is zero, start at the beginning. If @var{to} is less than |
| 335 | @var{from}, then read until the end of the file. If @var{filename} is |
| 336 | @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, |
| 337 | or @code{errno} if not. |
| 338 | @end deftypefun |
| 339 | |
| 340 | @deftypefun int write_history (const char *filename) |
| 341 | Write the current history to @var{filename}, overwriting @var{filename} |
| 342 | if necessary. |
| 343 | If @var{filename} is @code{NULL}, then write the history list to |
| 344 | @file{~/.history}. |
| 345 | Returns 0 on success, or @code{errno} on a read or write error. |
| 346 | @end deftypefun |
| 347 | |
| 348 | @deftypefun int append_history (int nelements, const char *filename) |
| 349 | Append the last @var{nelements} of the history list to @var{filename}. |
| 350 | If @var{filename} is @code{NULL}, then append to @file{~/.history}. |
| 351 | Returns 0 on success, or @code{errno} on a read or write error. |
| 352 | @end deftypefun |
| 353 | |
| 354 | @deftypefun int history_truncate_file (const char *filename, int nlines) |
| 355 | Truncate the history file @var{filename}, leaving only the last |
| 356 | @var{nlines} lines. |
| 357 | If @var{filename} is @code{NULL}, then @file{~/.history} is truncated. |
| 358 | Returns 0 on success, or @code{errno} on failure. |
| 359 | @end deftypefun |
| 360 | |
| 361 | @node History Expansion |
| 362 | @subsection History Expansion |
| 363 | |
| 364 | These functions implement history expansion. |
| 365 | |
| 366 | @deftypefun int history_expand (char *string, char **output) |
| 367 | Expand @var{string}, placing the result into @var{output}, a pointer |
| 368 | to a string (@pxref{History Interaction}). Returns: |
| 369 | @table @code |
| 370 | @item 0 |
| 371 | If no expansions took place (or, if the only change in |
| 372 | the text was the removal of escape characters preceding the history expansion |
| 373 | character); |
| 374 | @item 1 |
| 375 | if expansions did take place; |
| 376 | @item -1 |
| 377 | if there was an error in expansion; |
| 378 | @item 2 |
| 379 | if the returned line should be displayed, but not executed, |
| 380 | as with the @code{:p} modifier (@pxref{Modifiers}). |
| 381 | @end table |
| 382 | |
| 383 | If an error occurred in expansion, then @var{output} contains a descriptive |
| 384 | error message. |
| 385 | @end deftypefun |
| 386 | |
| 387 | @deftypefun {char *} get_history_event (const char *string, int *cindex, int qchar) |
| 388 | Returns the text of the history event beginning at @var{string} + |
| 389 | @var{*cindex}. @var{*cindex} is modified to point to after the event |
| 390 | specifier. At function entry, @var{cindex} points to the index into |
| 391 | @var{string} where the history event specification begins. @var{qchar} |
| 392 | is a character that is allowed to end the event specification in addition |
| 393 | to the ``normal'' terminating characters. |
| 394 | @end deftypefun |
| 395 | |
| 396 | @deftypefun {char **} history_tokenize (const char *string) |
| 397 | Return an array of tokens parsed out of @var{string}, much as the |
| 398 | shell might. The tokens are split on the characters in the |
| 399 | @var{history_word_delimiters} variable, |
| 400 | and shell quoting conventions are obeyed. |
| 401 | @end deftypefun |
| 402 | |
| 403 | @deftypefun {char *} history_arg_extract (int first, int last, const char *string) |
| 404 | Extract a string segment consisting of the @var{first} through @var{last} |
| 405 | arguments present in @var{string}. Arguments are split using |
| 406 | @code{history_tokenize}. |
| 407 | @end deftypefun |
| 408 | |
| 409 | @node History Variables |
| 410 | @section History Variables |
| 411 | |
| 412 | This section describes the externally-visible variables exported by |
| 413 | the @sc{gnu} History Library. |
| 414 | |
| 415 | @deftypevar int history_base |
| 416 | The logical offset of the first entry in the history list. |
| 417 | @end deftypevar |
| 418 | |
| 419 | @deftypevar int history_length |
| 420 | The number of entries currently stored in the history list. |
| 421 | @end deftypevar |
| 422 | |
| 423 | @deftypevar int history_max_entries |
| 424 | The maximum number of history entries. This must be changed using |
| 425 | @code{stifle_history()}. |
| 426 | @end deftypevar |
| 427 | |
| 428 | @deftypevar int history_write_timestamps |
| 429 | If non-zero, timestamps are written to the history file, so they can be |
| 430 | preserved between sessions. The default value is 0, meaning that |
| 431 | timestamps are not saved. |
| 432 | |
| 433 | The current timestamp format uses the value of @var{history_comment_char} |
| 434 | to delimit timestamp entries in the history file. If that variable does |
| 435 | not have a value (the default), timestamps will not be written. |
| 436 | @end deftypevar |
| 437 | |
| 438 | @deftypevar char history_expansion_char |
| 439 | The character that introduces a history event. The default is @samp{!}. |
| 440 | Setting this to 0 inhibits history expansion. |
| 441 | @end deftypevar |
| 442 | |
| 443 | @deftypevar char history_subst_char |
| 444 | The character that invokes word substitution if found at the start of |
| 445 | a line. The default is @samp{^}. |
| 446 | @end deftypevar |
| 447 | |
| 448 | @deftypevar char history_comment_char |
| 449 | During tokenization, if this character is seen as the first character |
| 450 | of a word, then it and all subsequent characters up to a newline are |
| 451 | ignored, suppressing history expansion for the remainder of the line. |
| 452 | This is disabled by default. |
| 453 | @end deftypevar |
| 454 | |
| 455 | @deftypevar {char *} history_word_delimiters |
| 456 | The characters that separate tokens for @code{history_tokenize()}. |
| 457 | The default value is @code{" \t\n()<>;&|"}. |
| 458 | @end deftypevar |
| 459 | |
| 460 | @deftypevar {char *} history_search_delimiter_chars |
| 461 | The list of additional characters which can delimit a history search |
| 462 | string, in addition to space, TAB, @samp{:} and @samp{?} in the case of |
| 463 | a substring search. The default is empty. |
| 464 | @end deftypevar |
| 465 | |
| 466 | @deftypevar {char *} history_no_expand_chars |
| 467 | The list of characters which inhibit history expansion if found immediately |
| 468 | following @var{history_expansion_char}. The default is space, tab, newline, |
| 469 | carriage return, and @samp{=}. |
| 470 | @end deftypevar |
| 471 | |
| 472 | @deftypevar int history_quotes_inhibit_expansion |
| 473 | If non-zero, double-quoted words are not scanned for the history expansion |
| 474 | character or the history comment character. The default value is 0. |
| 475 | @end deftypevar |
| 476 | |
| 477 | @deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function |
| 478 | This should be set to the address of a function that takes two arguments: |
| 479 | a @code{char *} (@var{string}) |
| 480 | and an @code{int} index into that string (@var{i}). |
| 481 | It should return a non-zero value if the history expansion starting at |
| 482 | @var{string[i]} should not be performed; zero if the expansion should |
| 483 | be done. |
| 484 | It is intended for use by applications like Bash that use the history |
| 485 | expansion character for additional purposes. |
| 486 | By default, this variable is set to @code{NULL}. |
| 487 | @end deftypevar |
| 488 | |
| 489 | @node History Programming Example |
| 490 | @section History Programming Example |
| 491 | |
| 492 | The following program demonstrates simple use of the @sc{gnu} History Library. |
| 493 | |
| 494 | @smallexample |
| 495 | #include <stdio.h> |
| 496 | #include <readline/history.h> |
| 497 | |
| 498 | main (argc, argv) |
| 499 | int argc; |
| 500 | char **argv; |
| 501 | @{ |
| 502 | char line[1024], *t; |
| 503 | int len, done = 0; |
| 504 | |
| 505 | line[0] = 0; |
| 506 | |
| 507 | using_history (); |
| 508 | while (!done) |
| 509 | @{ |
| 510 | printf ("history$ "); |
| 511 | fflush (stdout); |
| 512 | t = fgets (line, sizeof (line) - 1, stdin); |
| 513 | if (t && *t) |
| 514 | @{ |
| 515 | len = strlen (t); |
| 516 | if (t[len - 1] == '\n') |
| 517 | t[len - 1] = '\0'; |
| 518 | @} |
| 519 | |
| 520 | if (!t) |
| 521 | strcpy (line, "quit"); |
| 522 | |
| 523 | if (line[0]) |
| 524 | @{ |
| 525 | char *expansion; |
| 526 | int result; |
| 527 | |
| 528 | result = history_expand (line, &expansion); |
| 529 | if (result) |
| 530 | fprintf (stderr, "%s\n", expansion); |
| 531 | |
| 532 | if (result < 0 || result == 2) |
| 533 | @{ |
| 534 | free (expansion); |
| 535 | continue; |
| 536 | @} |
| 537 | |
| 538 | add_history (expansion); |
| 539 | strncpy (line, expansion, sizeof (line) - 1); |
| 540 | free (expansion); |
| 541 | @} |
| 542 | |
| 543 | if (strcmp (line, "quit") == 0) |
| 544 | done = 1; |
| 545 | else if (strcmp (line, "save") == 0) |
| 546 | write_history ("history_file"); |
| 547 | else if (strcmp (line, "read") == 0) |
| 548 | read_history ("history_file"); |
| 549 | else if (strcmp (line, "list") == 0) |
| 550 | @{ |
| 551 | register HIST_ENTRY **the_list; |
| 552 | register int i; |
| 553 | |
| 554 | the_list = history_list (); |
| 555 | if (the_list) |
| 556 | for (i = 0; the_list[i]; i++) |
| 557 | printf ("%d: %s\n", i + history_base, the_list[i]->line); |
| 558 | @} |
| 559 | else if (strncmp (line, "delete", 6) == 0) |
| 560 | @{ |
| 561 | int which; |
| 562 | if ((sscanf (line + 6, "%d", &which)) == 1) |
| 563 | @{ |
| 564 | HIST_ENTRY *entry = remove_history (which); |
| 565 | if (!entry) |
| 566 | fprintf (stderr, "No such entry %d\n", which); |
| 567 | else |
| 568 | @{ |
| 569 | free (entry->line); |
| 570 | free (entry); |
| 571 | @} |
| 572 | @} |
| 573 | else |
| 574 | @{ |
| 575 | fprintf (stderr, "non-numeric arg given to `delete'\n"); |
| 576 | @} |
| 577 | @} |
| 578 | @} |
| 579 | @} |
| 580 | @end smallexample |