1 /* History.c -- standalone history library */
3 /* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
5 This file contains the GNU History Library (the Library), a set of
6 routines for managing the text of previously typed lines.
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)
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.
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. */
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
29 #include <sys/types.h>
33 #if defined (HAVE_STDLIB_H)
36 # include "ansi_stdlib.h"
37 #endif /* HAVE_STDLIB_H */
38 #if defined (HAVE_UNISTD_H)
41 #if defined (HAVE_STRING_H)
45 #endif /* !HAVE_STRING_H */
48 /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
56 #if defined (STATIC_MALLOC)
57 static char *xmalloc (), *xrealloc ();
59 extern char *xmalloc (), *xrealloc ();
60 #endif /* STATIC_MALLOC */
62 #define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
63 #define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
67 extern char *strcpy ();
69 #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
73 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
77 #define digit_p(c) ((c) >= '0' && (c) <= '9')
81 #define digit_value(c) ((c) - '0')
86 extern char *strchr ();
88 #define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
91 /* Possible history errors passed to hist_error. */
92 #define EVENT_NOT_FOUND 0
93 #define BAD_WORD_SPEC 1
94 #define SUBST_FAILED 2
95 #define BAD_MODIFIER 3
97 static char error_pointer;
99 static char *subst_lhs;
100 static char *subst_rhs;
101 static int subst_lhs_len = 0;
102 static int subst_rhs_len = 0;
104 static char *get_history_word_specifier ();
105 static char *history_find_word ();
108 extern char *single_quote ();
111 /* **************************************************************** */
113 /* History Functions */
115 /* **************************************************************** */
117 /* An array of HIST_ENTRY. This is where we store the history. */
118 static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
120 /* Non-zero means that we have enforced a limit on the amount of
121 history that we save. */
122 static int history_stifled = 0;
124 /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
125 entries to remember. */
126 int max_input_history;
128 /* The current location of the interactive history pointer. Just makes
129 life easier for outside callers. */
130 static int history_offset = 0;
132 /* The number of strings currently stored in the input_history list. */
133 int history_length = 0;
135 /* The current number of slots allocated to the input_history. */
136 static int history_size = 0;
138 /* The number of slots to increase the_history by. */
139 #define DEFAULT_HISTORY_GROW_SIZE 50
141 /* The character that represents the start of a history expansion
142 request. This is usually `!'. */
143 char history_expansion_char = '!';
145 /* The character that invokes word substitution if found at the start of
146 a line. This is usually `^'. */
147 char history_subst_char = '^';
149 /* During tokenization, if this character is seen as the first character
150 of a word, then it, and all subsequent characters upto a newline are
151 ignored. For a Bourne shell, this should be '#'. Bash special cases
152 the interactive comment character to not be a comment delimiter. */
153 char history_comment_char = '\0';
155 /* The list of characters which inhibit the expansion of text if found
156 immediately following history_expansion_char. */
157 char *history_no_expand_chars = " \t\n\r=";
159 /* The logical `base' of the history array. It defaults to 1. */
160 int history_base = 1;
162 /* Return the current HISTORY_STATE of the history. */
164 history_get_history_state ()
166 HISTORY_STATE *state;
168 state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
169 state->entries = the_history;
170 state->offset = history_offset;
171 state->length = history_length;
172 state->size = history_size;
175 state->flags |= HS_STIFLED;
180 /* Set the state of the current history array to STATE. */
182 history_set_history_state (state)
183 HISTORY_STATE *state;
185 the_history = state->entries;
186 history_offset = state->offset;
187 history_length = state->length;
188 history_size = state->size;
189 if (state->flags & HS_STIFLED)
193 /* Begin a session in which the history functions might be used. This
194 initializes interactive variables. */
198 history_offset = history_length;
201 /* Return the number of bytes that the primary history entries are using.
202 This just adds up the lengths of the_history->lines. */
204 history_total_bytes ()
206 register int i, result;
210 for (i = 0; the_history && the_history[i]; i++)
211 result += strlen (the_history[i]->line);
216 /* Place STRING at the end of the history list. The data field
224 if (history_stifled && (history_length == max_input_history))
228 /* If the history is stifled, and history_length is zero,
229 and it equals max_input_history, we don't save items. */
230 if (history_length == 0)
233 /* If there is something in the slot, then remove it. */
236 free (the_history[0]->line);
237 free (the_history[0]);
240 /* Copy the rest of the entries, moving down one slot. */
241 for (i = 0; i < history_length; i++)
242 the_history[i] = the_history[i + 1];
251 history_size = DEFAULT_HISTORY_GROW_SIZE;
252 the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
258 if (history_length == (history_size - 1))
260 history_size += DEFAULT_HISTORY_GROW_SIZE;
261 the_history = (HIST_ENTRY **)
262 xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
268 temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
269 temp->line = savestring (string);
270 temp->data = (char *)NULL;
272 the_history[history_length] = (HIST_ENTRY *)NULL;
273 the_history[history_length - 1] = temp;
276 /* Make the history entry at WHICH have LINE and DATA. This returns
277 the old entry so you can dispose of the data. In the case of an
278 invalid WHICH, a NULL pointer is returned. */
280 replace_history_entry (which, line, data)
285 HIST_ENTRY *temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
286 HIST_ENTRY *old_value;
288 if (which >= history_length)
289 return ((HIST_ENTRY *)NULL);
291 old_value = the_history[which];
293 temp->line = savestring (line);
295 the_history[which] = temp;
300 /* Returns the magic number which says what history element we are
301 looking at now. In this implementation, it returns history_offset. */
305 return (history_offset);
308 /* Search the history for STRING, starting at history_offset.
309 If DIRECTION < 0, then the search is through previous entries, else
310 through subsequent. If ANCHORED is non-zero, the string must
311 appear at the beginning of a history line, otherwise, the string
312 may appear anywhere in the line. If the string is found, then
313 current_history () is the history entry, and the value of this
314 function is the offset in the line of that history entry that the
315 string was found in. Otherwise, nothing is changed, and a -1 is
318 #define ANCHORED_SEARCH 1
319 #define NON_ANCHORED_SEARCH 0
322 history_search_internal (string, direction, anchored)
324 int direction, anchored;
326 register int i, reverse;
328 register int line_index;
332 reverse = (direction < 0);
334 /* Take care of trivial cases first. */
335 if (string == 0 || *string == '\0')
338 if (!history_length || ((i == history_length) && !reverse))
341 if (reverse && (i == history_length))
344 #define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
346 string_len = strlen (string);
349 /* Search each line in the history list for STRING. */
351 /* At limit for direction? */
352 if ((reverse && i < 0) || (!reverse && i == history_length))
355 line = the_history[i]->line;
356 line_index = strlen (line);
358 /* If STRING is longer than line, no match. */
359 if (string_len > line_index)
365 /* Handle anchored searches first. */
366 if (anchored == ANCHORED_SEARCH)
368 if (STREQN (string, line, string_len))
378 /* Do substring search. */
381 line_index -= string_len;
383 while (line_index >= 0)
385 if (STREQN (string, line + line_index, string_len))
395 register int limit = line_index - string_len + 1;
398 while (line_index < limit)
400 if (STREQN (string, line + line_index, string_len))
412 /* Do a non-anchored search for STRING through the history in DIRECTION. */
414 history_search (string, direction)
418 return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
421 /* Do an anchored search for string through the history in DIRECTION. */
423 history_search_prefix (string, direction)
427 return (history_search_internal (string, direction, ANCHORED_SEARCH));
430 /* Remove history element WHICH from the history. The removed
431 element is returned to you so you can free the line, data,
432 and containing structure. */
434 remove_history (which)
437 HIST_ENTRY *return_value;
439 if (which >= history_length || !history_length)
440 return_value = (HIST_ENTRY *)NULL;
444 return_value = the_history[which];
446 for (i = which; i < history_length; i++)
447 the_history[i] = the_history[i + 1];
452 return (return_value);
455 /* Stifle the history list, remembering only MAX number of lines. */
463 if (history_length > max)
467 /* This loses because we cannot free the data. */
468 for (i = 0; i < (history_length - max); i++)
470 free (the_history[i]->line);
471 free (the_history[i]);
475 for (j = 0, i = history_length - max; j < max; i++, j++)
476 the_history[j] = the_history[i];
477 the_history[j] = (HIST_ENTRY *)NULL;
482 max_input_history = max;
485 /* Stop stifling the history. This returns the previous amount the history
486 was stifled by. The value is positive if the history was stifled, negative
491 int result = max_input_history;
503 history_is_stifled ()
505 return (history_stifled);
508 /* Return the string that should be used in the place of this
509 filename. This only matters when you don't specify the
510 filename to read_history (), or write_history (). */
512 history_filename (filename)
515 char *return_val = filename ? savestring (filename) : (char *)NULL;
522 home = getenv ("HOME");
527 home_len = strlen (home);
528 /* strlen(".history") == 8 */
529 return_val = xmalloc (2 + home_len + 8);
531 strcpy (return_val, home);
532 return_val[home_len] = '/';
533 strcpy (return_val + home_len + 1, ".history");
539 /* Add the contents of FILENAME to the history list, a line at a time.
540 If FILENAME is NULL, then read from ~/.history. Returns 0 if
541 successful, or errno if not. */
543 read_history (filename)
546 return (read_history_range (filename, 0, -1));
549 /* Read a range of lines from FILENAME, adding them to the history list.
550 Start reading at the FROM'th line and end at the TO'th. If FROM
551 is zero, start at the beginning. If TO is less than FROM, read
552 until the end of the file. If FILENAME is NULL, then read from
553 ~/.history. Returns 0 if successful, or errno if not. */
555 read_history_range (filename, from, to)
559 register int line_start, line_end;
560 char *input, *buffer = (char *)NULL;
561 int file, current_line;
564 input = history_filename (filename);
565 file = open (input, O_RDONLY, 0666);
567 if ((file < 0) || (fstat (file, &finfo) == -1))
570 buffer = xmalloc ((int)finfo.st_size + 1);
572 if (read (file, buffer, finfo.st_size) != finfo.st_size)
589 /* Set TO to larger than end of file if negative. */
593 /* Start at beginning of file, work to end. */
594 line_start = line_end = current_line = 0;
596 /* Skip lines until we are at FROM. */
597 while (line_start < finfo.st_size && current_line < from)
599 for (line_end = line_start; line_end < finfo.st_size; line_end++)
600 if (buffer[line_end] == '\n')
603 line_start = line_end + 1;
604 if (current_line == from)
609 /* If there are lines left to gobble, then gobble them now. */
610 for (line_end = line_start; line_end < finfo.st_size; line_end++)
611 if (buffer[line_end] == '\n')
613 buffer[line_end] = '\0';
615 if (buffer[line_start])
616 add_history (buffer + line_start);
620 if (current_line >= to)
623 line_start = line_end + 1;
635 /* Truncate the history file FNAME, leaving only LINES trailing lines.
636 If FNAME is NULL, then use ~/.history. */
638 history_truncate_file (fname, lines)
643 int file, chars_read;
644 char *buffer = (char *)NULL, *filename;
647 filename = history_filename (fname);
648 file = open (filename, O_RDONLY, 0666);
650 if (file == -1 || fstat (file, &finfo) == -1)
653 buffer = xmalloc ((int)finfo.st_size + 1);
654 chars_read = read (file, buffer, finfo.st_size);
660 /* Count backwards from the end of buffer until we have passed
662 for (i = chars_read - 1; lines && i; i--)
664 if (buffer[i] == '\n')
668 /* If this is the first line, then the file contains exactly the
669 number of lines we want to truncate to, so we don't need to do
670 anything. It's the first line if we don't find a newline between
671 the current value of i and 0. Otherwise, write from the start of
672 this line until the end of the buffer. */
674 if (buffer[i] == '\n')
680 /* Write only if there are more lines in the file than we want to
682 if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1))
684 write (file, buffer + i, finfo.st_size - i);
696 #define HISTORY_APPEND 0
697 #define HISTORY_OVERWRITE 1
699 /* Workhorse function for writing history. Writes NELEMENT entries
700 from the history list to FILENAME. OVERWRITE is non-zero if you
701 wish to replace FILENAME with the entries. */
703 history_do_write (filename, nelements, overwrite)
705 int nelements, overwrite;
708 char *output = history_filename (filename);
711 mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND;
713 if ((file = open (output, mode, 0666)) == -1)
721 if (nelements > history_length)
722 nelements = history_length;
724 /* Build a buffer of all the lines to write, and write them in one syscall.
725 Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
731 /* Calculate the total number of bytes to write. */
732 for (i = history_length - nelements; i < history_length; i++)
733 buffer_size += 1 + strlen (the_history[i]->line);
735 /* Allocate the buffer, and fill it. */
736 buffer = xmalloc (buffer_size);
738 for (i = history_length - nelements; i < history_length; i++)
740 strcpy (buffer + j, the_history[i]->line);
741 j += strlen (the_history[i]->line);
745 write (file, buffer, buffer_size);
757 /* Append NELEMENT entries to FILENAME. The entries appended are from
758 the end of the list minus NELEMENTs up to the end of the list. */
760 append_history (nelements, filename)
764 return (history_do_write (filename, nelements, HISTORY_APPEND));
767 /* Overwrite FILENAME with the current history. If FILENAME is NULL,
768 then write the history list to ~/.history. Values returned
769 are as in read_history ().*/
771 write_history (filename)
774 return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
777 /* Return the history entry at the current position, as determined by
778 history_offset. If there is no entry there, return a NULL pointer. */
782 if ((history_offset == history_length) || !the_history)
783 return ((HIST_ENTRY *)NULL);
785 return (the_history[history_offset]);
788 /* Back up history_offset to the previous history entry, and return
789 a pointer to that entry. If there is no previous entry then return
795 return ((HIST_ENTRY *)NULL);
797 return (the_history[--history_offset]);
800 /* Move history_offset forward to the next history entry, and return
801 a pointer to that entry. If there is no next entry then return a
806 if (history_offset == history_length)
807 return ((HIST_ENTRY *)NULL);
809 return (the_history[++history_offset]);
812 /* Return the current history array. The caller has to be carefull, since this
813 is the actual array of data, and could be bashed or made corrupt easily.
814 The array is terminated with a NULL pointer. */
818 return (the_history);
821 /* Return the history entry which is logically at OFFSET in the history array.
822 OFFSET is relative to history_base. */
827 int local_index = offset - history_base;
829 if (local_index >= history_length ||
832 return ((HIST_ENTRY *)NULL);
833 return (the_history[local_index]);
836 /* Search for STRING in the history list. DIR is < 0 for searching
837 backwards. POS is an absolute index into the history list at
838 which point to begin searching. */
840 history_search_pos (string, dir, pos)
844 int ret, old = where_history ();
845 history_set_pos (pos);
846 if (history_search (string, dir) == -1)
848 history_set_pos (old);
851 ret = where_history ();
852 history_set_pos (old);
856 /* Make the current history item be the one at POS, an absolute index.
857 Returns zero if POS is out of range, else non-zero. */
859 history_set_pos (pos)
862 if (pos > history_length || pos < 0 || !the_history)
864 history_offset = pos;
869 /* **************************************************************** */
871 /* History Expansion */
873 /* **************************************************************** */
875 /* Hairy history expansion on text, not tokens. This is of general
876 use, and thus belongs in this library. */
878 /* The last string searched for in a !?string? search. */
879 static char *search_string = (char *)NULL;
881 /* The last string matched by a !?string? search. */
882 static char *search_match = (char *)NULL;
884 /* Return the event specified at TEXT + OFFSET modifying OFFSET to
885 point to after the event specifier. Just a pointer to the history
886 line is returned; NULL is returned in the event of a bad specifier.
887 You pass STRING with *INDEX equal to the history_expansion_char that
888 begins this specification.
889 DELIMITING_QUOTE is a character that is allowed to end the string
890 specification for what to search for in addition to the normal
891 characters `:', ` ', `\t', `\n', and sometimes `?'.
892 So you might call this function like:
893 line = get_history_event ("!echo:p", &index, 0); */
895 get_history_event (string, caller_index, delimiting_quote)
898 int delimiting_quote;
900 register int i = *caller_index;
904 int local_index, search_mode, substring_okay = 0;
907 /* The event can be specified in a number of ways.
909 !! the previous command
911 !-n current command-line minus N
912 !str the most recent command starting with STR
914 the most recent command containing STR
916 All values N are determined via HISTORY_BASE. */
918 if (string[i] != history_expansion_char)
919 return ((char *)NULL);
921 /* Move on to the specification. */
924 #define RETURN_ENTRY(e, w) \
925 return ((e = history_get (w)) ? e->line : (char *)NULL)
927 /* Handle !! case. */
928 if (string[i] == history_expansion_char)
931 which = history_base + (history_length - 1);
933 RETURN_ENTRY (entry, which);
936 /* Hack case of numeric line specification. */
937 if (string[i] == '-')
943 if (digit_p (string[i]))
945 /* Get the extent of the digits and compute the value. */
946 for (which = 0; digit_p (string[i]); i++)
947 which = (which * 10) + digit_value (string[i]);
952 which = (history_length + history_base) - which;
954 RETURN_ENTRY (entry, which);
957 /* This must be something to search for. If the spec begins with
958 a '?', then the string may be anywhere on the line. Otherwise,
959 the string must be found at the start of a line. */
960 if (string[i] == '?')
966 /* Only a closing `?' or a newline delimit a substring search string. */
967 for (local_index = i; c = string[i]; i++)
968 if ((!substring_okay && (whitespace (c) || c == ':' ||
970 member (c, ";&()|<>") ||
972 string[i] == delimiting_quote)) ||
974 (substring_okay && string[i] == '?'))
977 temp = xmalloc (1 + (i - local_index));
978 strncpy (temp, &string[local_index], (i - local_index));
979 temp[i - local_index] = '\0';
981 if (substring_okay && string[i] == '?')
986 #define FAIL_SEARCH() \
987 do { history_offset = history_length; free (temp) ; return (char *)NULL; } while (0)
989 search_mode = substring_okay ? NON_ANCHORED_SEARCH : ANCHORED_SEARCH;
992 local_index = history_search_internal (temp, -1, search_mode);
997 if (local_index == 0 || substring_okay)
999 entry = current_history ();
1000 history_offset = history_length;
1002 /* If this was a substring search, then remember the
1003 string that we matched for word substitution. */
1007 free (search_string);
1008 search_string = temp;
1011 free (search_match);
1012 search_match = history_find_word (entry->line, local_index);
1016 return (entry->line);
1028 /* Function for extracting single-quoted strings. Used for inhibiting
1029 history expansion within single quotes. */
1031 /* Extract the contents of STRING as if it is enclosed in single quotes.
1032 SINDEX, when passed in, is the offset of the character immediately
1033 following the opening single quote; on exit, SINDEX is left pointing
1034 to the closing single quote. */
1036 rl_string_extract_single_quoted (string, sindex)
1040 register int i = *sindex;
1042 while (string[i] && string[i] != '\'')
1052 register char *p, *r;
1056 for (p = s; p && *p; p++, len++)
1060 else if (whitespace (*p) || *p == '\n')
1064 r = ret = xmalloc (len);
1066 for (p = s; p && *p; )
1076 else if (whitespace (*p) || *p == '\n')
1092 hist_error(s, start, current, errtype)
1094 int start, current, errtype;
1099 ll = current - start;
1103 case EVENT_NOT_FOUND:
1104 emsg = "event not found";
1108 emsg = "bad word specifier";
1112 emsg = "substitution failed";
1116 emsg = "unrecognized history modifier";
1120 emsg = "unknown expansion error";
1125 temp = xmalloc (ll + elen + 3);
1126 strncpy (temp, s + start, ll);
1129 strcpy (temp + ll + 2, emsg);
1133 /* Get a history substitution string from STR starting at *IPTR
1134 and return it. The length is returned in LENPTR.
1136 A backslash can quote the delimiter. If the string is the
1137 empty string, the previous pattern is used. If there is
1138 no previous pattern for the lhs, the last history search
1141 If IS_RHS is 1, we ignore empty strings and set the pattern
1142 to "" anyway. subst_lhs is not changed if the lhs is empty;
1143 subst_rhs is allowed to be set to the empty string. */
1146 get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr)
1148 int *iptr, delimiter, is_rhs, *lenptr;
1150 register int si, i, j, k;
1151 char *s = (char *) NULL;
1155 for (si = i; str[si] && str[si] != delimiter; si++)
1156 if (str[si] == '\\' && str[si + 1] == delimiter)
1159 if (si > i || is_rhs)
1161 s = xmalloc (si - i + 1);
1162 for (j = 0, k = i; k < si; j++, k++)
1164 /* Remove a backslash quoting the search string delimiter. */
1165 if (str[k] == '\\' && str[k + 1] == delimiter)
1183 postproc_subst_rhs ()
1188 new = xmalloc (new_size = subst_rhs_len + subst_lhs_len);
1189 for (i = j = 0; i < subst_rhs_len; i++)
1191 if (subst_rhs[i] == '&')
1193 if (j + subst_lhs_len >= new_size)
1194 new = xrealloc (new, (new_size = new_size * 2 + subst_lhs_len));
1195 strcpy (new + j, subst_lhs);
1200 /* a single backslash protects the `&' from lhs interpolation */
1201 if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&')
1204 new = xrealloc (new, new_size *= 2);
1205 new[j++] = subst_rhs[i];
1214 /* Expand the bulk of a history specifier starting at STRING[START].
1215 Returns 0 if everything is OK, -1 if an error occurred, and 1
1216 if the `p' modifier was supplied and the caller should just print
1217 the returned string. Returns the new index into string in
1218 *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */
1220 history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
1222 int start, *end_index_ptr;
1224 char *current_line; /* for !# */
1226 int i, n, starting_index;
1227 int substitute_globally, want_quotes, print_only;
1228 char *event, *temp, *result, *tstr, *t, c, *word_spec;
1231 result = xmalloc (result_len = 128);
1235 /* If it is followed by something that starts a word specifier,
1236 then !! is implied as the event specifier. */
1238 if (member (string[i + 1], ":$*%^"))
1243 fake_s[0] = fake_s[1] = history_expansion_char;
1245 event = get_history_event (fake_s, &fake_i, 0);
1247 else if (string[i + 1] == '#')
1250 event = current_line;
1254 int quoted_search_delimiter = 0;
1256 /* If the character before this `!' is a double or single
1257 quote, then this expansion takes place inside of the
1258 quoted string. If we have to search for some text ("!foo"),
1259 allow the delimiter to end the search string. */
1260 if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
1261 quoted_search_delimiter = string[i - 1];
1262 event = get_history_event (string, &i, quoted_search_delimiter);
1267 *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
1272 /* If a word specifier is found, then do what that requires. */
1274 word_spec = get_history_word_specifier (string, event, &i);
1276 /* There is no such thing as a `malformed word specifier'. However,
1277 it is possible for a specifier that has no match. In that case,
1279 if (word_spec == (char *)&error_pointer)
1281 *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC);
1286 /* If no word specifier, than the thing of interest was the event. */
1288 temp = savestring (event);
1291 temp = savestring (word_spec);
1295 /* Perhaps there are other modifiers involved. Do what they say. */
1296 want_quotes = substitute_globally = print_only = 0;
1299 while (string[i] == ':')
1305 substitute_globally = 1;
1313 *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER);
1328 /* :p means make this the last executed line. So we
1329 return an error state after adding this line to the
1335 /* :t discards all but the last part of the pathname. */
1337 tstr = strrchr (temp, '/');
1341 t = savestring (tstr);
1347 /* :h discards the last part of a pathname. */
1349 tstr = strrchr (temp, '/');
1354 /* :r discards the suffix. */
1356 tstr = strrchr (temp, '.');
1361 /* :e discards everything but the suffix. */
1363 tstr = strrchr (temp, '.');
1366 t = savestring (tstr);
1372 /* :s/this/that substitutes `that' for the first
1373 occurrence of `this'. :gs/this/that substitutes `that'
1374 for each occurrence of `this'. :& repeats the last
1375 substitution. :g& repeats the last substitution
1381 char *new_event, *t;
1382 int delimiter, failed, si, l_temp;
1386 if (i + 2 < (int)strlen (string))
1387 delimiter = string[i + 2];
1389 break; /* no search delimiter */
1393 t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len);
1394 /* An empty substitution lhs with no previous substitution
1395 uses the last search string as the lhs. */
1402 else if (!subst_lhs)
1404 if (search_string && *search_string)
1406 subst_lhs = savestring (search_string);
1407 subst_lhs_len = strlen (subst_lhs);
1411 subst_lhs = (char *) NULL;
1416 /* If there is no lhs, the substitution can't succeed. */
1417 if (subst_lhs_len == 0)
1419 *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
1427 subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len);
1429 /* If `&' appears in the rhs, it's supposed to be replaced
1431 if (member ('&', subst_rhs))
1432 postproc_subst_rhs ();
1437 l_temp = strlen (temp);
1438 /* Ignore impossible cases. */
1439 if (subst_lhs_len > l_temp)
1441 *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
1447 /* Find the first occurrence of THIS in TEMP. */
1449 for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
1450 if (STREQN (temp+si, subst_lhs, subst_lhs_len))
1452 int len = subst_rhs_len - subst_lhs_len + l_temp;
1453 new_event = xmalloc (1 + len);
1454 strncpy (new_event, temp, si);
1455 strncpy (new_event + si, subst_rhs, subst_rhs_len);
1456 strncpy (new_event + si + subst_rhs_len,
1457 temp + si + subst_lhs_len,
1458 l_temp - (si + subst_lhs_len));
1459 new_event[len] = '\0';
1465 if (substitute_globally)
1467 si += subst_rhs_len;
1468 l_temp = strlen (temp);
1469 substitute_globally++;
1476 if (substitute_globally > 1)
1478 substitute_globally = 0;
1479 continue; /* don't want to increment i */
1483 continue; /* don't want to increment i */
1485 *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
1493 /* Done with modfiers. */
1494 /* Believe it or not, we have to back the pointer up by one. */
1502 if (want_quotes == 'q')
1503 x = single_quote (temp);
1504 else if (want_quotes == 'x')
1505 x = quote_breaks (temp);
1507 x = savestring (temp);
1516 result = xrealloc (result, n + 2);
1517 strcpy (result, temp);
1521 *ret_string = result;
1522 return (print_only);
1525 /* Expand the string STRING, placing the result into OUTPUT, a pointer
1526 to a string. Returns:
1528 -1) If there was an error in expansion.
1529 0) If no expansions took place (or, if the only change in
1530 the text was the de-slashifying of the history expansion
1532 1) If expansions did take place
1533 2) If the `p' modifier was given and the caller should print the result
1535 If an error ocurred in expansion, then OUTPUT contains a descriptive
1538 #define ADD_STRING(s) \
1541 int sl = strlen (s); \
1543 if (j >= result_len) \
1545 while (j >= result_len) \
1546 result_len += 128; \
1547 result = xrealloc (result, result_len); \
1549 strcpy (result + j - sl, s); \
1553 #define ADD_CHAR(c) \
1556 if (j >= result_len - 1) \
1557 result = xrealloc (result, result_len += 64); \
1564 history_expand (hstring, output)
1569 int i, r, l, passc, cc, modified, eindex, only_printing;
1572 /* The output string, and its length. */
1576 /* Used when adding the string. */
1579 /* Setting the history expansion character to 0 inhibits all
1580 history expansion. */
1581 if (history_expansion_char == 0)
1583 *output = savestring (hstring);
1587 /* Prepare the buffer for printing error messages. */
1588 result = xmalloc (result_len = 256);
1591 only_printing = modified = 0;
1592 l = strlen (hstring);
1594 /* Grovel the string. Only backslash can quote the history escape
1595 character. We also handle arg specifiers. */
1597 /* Before we grovel forever, see if the history_expansion_char appears
1598 anywhere within the text. */
1600 /* The quick substitution character is a history expansion all right. That
1601 is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact,
1602 that is the substitution that we do. */
1603 if (hstring[0] == history_subst_char)
1605 string = xmalloc (l + 5);
1607 string[0] = string[1] = history_expansion_char;
1610 strcpy (string + 4, hstring);
1616 /* If not quick substitution, still maybe have to do expansion. */
1618 /* `!' followed by one of the characters in history_no_expand_chars
1619 is NOT an expansion. */
1620 for (i = 0; string[i]; i++)
1623 if (string[i] == history_expansion_char)
1625 if (!cc || member (cc, history_no_expand_chars))
1628 /* The shell uses ! as a pattern negation character
1629 in globbing [...] expressions, so let those pass
1630 without expansion. */
1631 else if (i > 0 && (string[i - 1] == '[') &&
1632 member (']', string + i + 1))
1639 else if (string[i] == '\'')
1641 /* If this is bash, single quotes inhibit history expansion. */
1643 rl_string_extract_single_quoted (string, &i);
1645 else if (string[i] == '\\')
1647 /* If this is bash, allow backslashes to quote single
1649 the history expansion character. */
1650 if (cc == '\'' || cc == history_expansion_char)
1656 if (string[i] != history_expansion_char)
1659 *output = savestring (string);
1664 /* Extract and perform the substitution. */
1665 for (passc = i = j = 0; i < l; i++)
1667 int tchar = string[i];
1676 if (tchar == history_expansion_char)
1682 ADD_CHAR (string[i]);
1693 /* If this is bash, single quotes inhibit history expansion. */
1697 rl_string_extract_single_quoted (string, &i);
1699 slen = i - quote + 2;
1700 temp = xmalloc (slen);
1701 strncpy (temp, string + quote, slen);
1702 temp[slen - 1] = '\0';
1709 case -3: /* history_expansion_char */
1712 /* If the history_expansion_char is followed by one of the
1713 characters in history_no_expand_chars, then it is not a
1714 candidate for expansion of any kind. */
1715 if (member (cc, history_no_expand_chars))
1717 ADD_CHAR (string[i]);
1721 #if defined (NO_BANG_HASH_MODIFIERS)
1722 /* There is something that is listed as a `word specifier' in csh
1723 documentation which means `the expanded text to this point'.
1724 That is not a word specifier, it is an event specifier. If we
1725 don't want to allow modifiers with `!#', just stick the current
1726 output line in again. */
1731 temp = xmalloc (1 + strlen (result));
1732 strcpy (temp, result);
1741 r = history_expand_internal (string, i, &eindex, &temp, result);
1746 if (string != hstring)
1759 only_printing = r == 1;
1767 if (string != hstring)
1772 add_history (result);
1776 return (modified != 0);
1779 /* Return a consed string which is the word specified in SPEC, and found
1780 in FROM. NULL is returned if there is no spec. The address of
1781 ERROR_POINTER is returned if the word specified cannot be found.
1782 CALLER_INDEX is the offset in SPEC to start looking; it is updated
1783 to point to just after the last character parsed. */
1785 get_history_word_specifier (spec, from, caller_index)
1789 register int i = *caller_index;
1791 int expecting_word_spec = 0;
1794 /* The range of words to return doesn't exist yet. */
1796 result = (char *)NULL;
1798 /* If we found a colon, then this *must* be a word specification. If
1799 it isn't, then it is an error. */
1803 expecting_word_spec++;
1806 /* Handle special cases first. */
1808 /* `%' is the word last searched for. */
1811 *caller_index = i + 1;
1812 return (search_match ? savestring (search_match) : savestring (""));
1815 /* `*' matches all of the arguments, but not the command. */
1818 *caller_index = i + 1;
1819 result = history_arg_extract (1, '$', from);
1820 return (result ? result : savestring (""));
1823 /* `$' is last arg. */
1826 *caller_index = i + 1;
1827 return (history_arg_extract ('$', '$', from));
1830 /* Try to get FIRST and LAST figured out. */
1834 else if (spec[i] == '^')
1836 else if (digit_p (spec[i]) && expecting_word_spec)
1838 for (first = 0; digit_p (spec[i]); i++)
1839 first = (first * 10) + digit_value (spec[i]);
1842 return ((char *)NULL); /* no valid `first' for word specifier */
1844 if (spec[i] == '^' || spec[i] == '*')
1846 last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */
1849 else if (spec[i] != '-')
1855 if (digit_p (spec[i]))
1857 for (last = 0; digit_p (spec[i]); i++)
1858 last = (last * 10) + digit_value (spec[i]);
1860 else if (spec[i] == '$')
1865 else if (!spec[i] || spec[i] == ':') /* could be modifier separator */
1866 last = -1; /* x- abbreviates x-$ omitting word `$' */
1871 if (last >= first || last == '$' || last < 0)
1872 result = history_arg_extract (first, last, from);
1874 return (result ? result : (char *)&error_pointer);
1877 /* Extract the args specified, starting at FIRST, and ending at LAST.
1878 The args are taken from STRING. If either FIRST or LAST is < 0,
1879 then make that arg count from the right (subtract from the number of
1880 tokens, so that FIRST = -1 means the next to last token on the line).
1881 If LAST is `$' the last arg from STRING is used. */
1883 history_arg_extract (first, last, string)
1887 register int i, len;
1888 char *result = (char *)NULL;
1889 int size = 0, offset = 0;
1892 /* XXX - think about making history_tokenize return a struct array,
1893 each struct in array being a string and a length to avoid the
1894 calls to strlen below. */
1895 if ((list = history_tokenize (string)) == NULL)
1896 return ((char *)NULL);
1898 for (len = 0; list[len]; len++)
1902 last = len + last - 1;
1905 first = len + first - 1;
1915 if (first >= len || last > len || first < 0 || last < 0 || first > last)
1916 result = ((char *)NULL);
1919 for (size = 0, i = first; i < last; i++)
1920 size += strlen (list[i]) + 1;
1921 result = xmalloc (size + 1);
1924 for (i = first; i < last; i++)
1926 strcpy (result + offset, list[i]);
1927 offset += strlen (list[i]);
1930 result[offset++] = ' ';
1936 for (i = 0; i < len; i++)
1943 #define slashify_in_quotes "\\`\"$"
1945 /* Parse STRING into tokens and return an array of strings. If WIND is
1946 not -1 and INDP is not null, we also want the word surrounding index
1947 WIND. The position in the returned array of strings is returned in
1950 history_tokenize_internal (string, wind, indp)
1954 char **result = (char **)NULL;
1955 register int i, start, result_index, size;
1958 i = result_index = size = 0;
1960 /* Get a token, and stuff it into RESULT. The tokens are split
1961 exactly where the shell would split them. */
1966 /* Skip leading whitespace. */
1967 for (; string[i] && whitespace (string[i]); i++)
1969 if (!string[i] || string[i] == history_comment_char)
1974 if (member (string[i], "()\n"))
1980 if (member (string[i], "<>;&|$"))
1982 int peek = string[i + 1];
1984 if (peek == string[i] && peek != '$')
1986 if (peek == '<' && string[i + 2] == '-')
1993 if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
1994 ((peek == '>') && (string[i] == '&')) ||
1995 ((peek == '(') && (string[i] == '$')))
2001 if (string[i] != '$')
2008 /* Get word from string + i; */
2010 if (member (string[i], "\"'`"))
2011 delimiter = string[i++];
2013 for (; string[i]; i++)
2015 if (string[i] == '\\' && string[i + 1] == '\n')
2021 if (string[i] == '\\' && delimiter != '\'' &&
2022 (delimiter != '"' || member (string[i], slashify_in_quotes)))
2028 if (delimiter && string[i] == delimiter)
2034 if (!delimiter && (member (string[i], " \t\n;&()|<>")))
2037 if (!delimiter && member (string[i], "\"'`"))
2038 delimiter = string[i];
2042 /* If we are looking for the word in which the character at a
2043 particular index falls, remember it. */
2044 if (indp && wind >= 0 && wind >= start && wind < i)
2045 *indp = result_index;
2048 if (result_index + 2 >= size)
2049 result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
2050 result[result_index] = xmalloc (1 + len);
2051 strncpy (result[result_index], string + start, len);
2052 result[result_index][len] = '\0';
2053 result[++result_index] = (char *)NULL;
2059 /* Return an array of tokens, much as the shell might. The tokens are
2060 parsed out of STRING. */
2062 history_tokenize (string)
2065 return (history_tokenize_internal (string, -1, (int *)NULL));
2068 /* Find and return the word which contains the character at index IND
2069 in the history line LINE. Used to save the word matched by the
2070 last history !?string? search. */
2072 history_find_word (line, ind)
2079 words = history_tokenize_internal (line, ind, &wind);
2081 return ((char *)NULL);
2083 for (i = 0; i < wind; i++)
2085 for (i = wind + 1; words[i]; i++)
2091 #if defined (STATIC_MALLOC)
2093 /* **************************************************************** */
2095 /* xmalloc and xrealloc () */
2097 /* **************************************************************** */
2099 static void memory_error_and_abort ();
2105 char *temp = (char *)malloc (bytes);
2108 memory_error_and_abort ();
2113 xrealloc (pointer, bytes)
2120 temp = (char *)xmalloc (bytes);
2122 temp = (char *)realloc (pointer, bytes);
2125 memory_error_and_abort ();
2131 memory_error_and_abort ()
2133 fprintf (stderr, "history: Out of virtual memory!\n");
2136 #endif /* STATIC_MALLOC */
2138 /* **************************************************************** */
2142 /* **************************************************************** */
2146 char line[1024], *t;
2153 fprintf (stdout, "history%% ");
2157 strcpy (line, "quit");
2166 result = history_expand (line, &expansion);
2167 strcpy (line, expansion);
2170 fprintf (stderr, "%s\n", line);
2178 if (strcmp (line, "quit") == 0) done = 1;
2179 if (strcmp (line, "save") == 0) write_history (0);
2180 if (strcmp (line, "read") == 0) read_history (0);
2181 if (strcmp (line, "list") == 0)
2183 register HIST_ENTRY **the_list = history_list ();
2187 for (i = 0; the_list[i]; i++)
2188 fprintf (stdout, "%d: %s\n", i + history_base, the_list[i]->line);
2190 if (strncmp (line, "delete", strlen ("delete")) == 0)
2193 if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1)
2195 HIST_ENTRY *entry = remove_history (which);
2197 fprintf (stderr, "No such entry %d\n", which);
2206 fprintf (stderr, "non-numeric arg given to `delete'\n");
2216 * compile-command: "gcc -g -DTEST -o history history.c"