Sync readline/ to version 7.0 alpha
[external/binutils.git] / readline / histexpand.c
1 /* histexpand.c -- history expansion. */
2
3 /* Copyright (C) 1989-2012 Free Software Foundation, Inc.
4
5    This file contains the GNU History Library (History), a set of
6    routines for managing the text of previously typed lines.
7
8    History 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 3 of the License, or
11    (at your option) any later version.
12
13    History is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with History.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27
28 #include <stdio.h>
29
30 #if defined (HAVE_STDLIB_H)
31 #  include <stdlib.h>
32 #else
33 #  include "ansi_stdlib.h"
34 #endif /* HAVE_STDLIB_H */
35
36 #if defined (HAVE_UNISTD_H)
37 #  ifndef _MINIX
38 #    include <sys/types.h>
39 #  endif
40 #  include <unistd.h>
41 #endif
42
43 #include "rlmbutil.h"
44
45 #include "history.h"
46 #include "histlib.h"
47
48 #include "rlshell.h"
49 #include "xmalloc.h"
50
51 #define HISTORY_WORD_DELIMITERS         " \t\n;&()|<>"
52 #define HISTORY_QUOTE_CHARACTERS        "\"'`"
53 #define HISTORY_EVENT_DELIMITERS        "^$*%-"
54
55 #define slashify_in_quotes "\\`\"$"
56
57 typedef int _hist_search_func_t PARAMS((const char *, int));
58
59 static char error_pointer;
60
61 static char *subst_lhs;
62 static char *subst_rhs;
63 static int subst_lhs_len;
64 static int subst_rhs_len;
65
66 /* Characters that delimit history event specifications and separate event
67    specifications from word designators.  Static for now */
68 static char *history_event_delimiter_chars = HISTORY_EVENT_DELIMITERS;
69
70 static char *get_history_word_specifier PARAMS((char *, char *, int *));
71 static int history_tokenize_word PARAMS((const char *, int));
72 static char **history_tokenize_internal PARAMS((const char *, int, int *));
73 static char *history_substring PARAMS((const char *, int, int));
74 static void freewords PARAMS((char **, int));
75 static char *history_find_word PARAMS((char *, int));
76
77 static char *quote_breaks PARAMS((char *));
78
79 /* Variables exported by this file. */
80 /* The character that represents the start of a history expansion
81    request.  This is usually `!'. */
82 char history_expansion_char = '!';
83
84 /* The character that invokes word substitution if found at the start of
85    a line.  This is usually `^'. */
86 char history_subst_char = '^';
87
88 /* During tokenization, if this character is seen as the first character
89    of a word, then it, and all subsequent characters upto a newline are
90    ignored.  For a Bourne shell, this should be '#'.  Bash special cases
91    the interactive comment character to not be a comment delimiter. */
92 char history_comment_char = '\0';
93
94 /* The list of characters which inhibit the expansion of text if found
95    immediately following history_expansion_char. */
96 char *history_no_expand_chars = " \t\n\r=";
97
98 /* If set to a non-zero value, single quotes inhibit history expansion.
99    The default is 0. */
100 int history_quotes_inhibit_expansion = 0;
101
102 /* Used to split words by history_tokenize_internal. */
103 char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
104
105 /* If set, this points to a function that is called to verify that a
106    particular history expansion should be performed. */
107 rl_linebuf_func_t *history_inhibit_expansion_function;
108
109 /* **************************************************************** */
110 /*                                                                  */
111 /*                      History Expansion                           */
112 /*                                                                  */
113 /* **************************************************************** */
114
115 /* Hairy history expansion on text, not tokens.  This is of general
116    use, and thus belongs in this library. */
117
118 /* The last string searched for by a !?string? search. */
119 static char *search_string;
120 /* The last string matched by a !?string? search. */
121 static char *search_match;
122
123 /* Return the event specified at TEXT + OFFSET modifying OFFSET to
124    point to after the event specifier.  Just a pointer to the history
125    line is returned; NULL is returned in the event of a bad specifier.
126    You pass STRING with *INDEX equal to the history_expansion_char that
127    begins this specification.
128    DELIMITING_QUOTE is a character that is allowed to end the string
129    specification for what to search for in addition to the normal
130    characters `:', ` ', `\t', `\n', and sometimes `?'.
131    So you might call this function like:
132    line = get_history_event ("!echo:p", &index, 0);  */
133 char *
134 get_history_event (string, caller_index, delimiting_quote)
135      const char *string;
136      int *caller_index;
137      int delimiting_quote;
138 {
139   register int i;
140   register char c;
141   HIST_ENTRY *entry;
142   int which, sign, local_index, substring_okay;
143   _hist_search_func_t *search_func;
144   char *temp;
145
146   /* The event can be specified in a number of ways.
147
148      !!   the previous command
149      !n   command line N
150      !-n  current command-line minus N
151      !str the most recent command starting with STR
152      !?str[?]
153           the most recent command containing STR
154
155      All values N are determined via HISTORY_BASE. */
156
157   i = *caller_index;
158
159   if (string[i] != history_expansion_char)
160     return ((char *)NULL);
161
162   /* Move on to the specification. */
163   i++;
164
165   sign = 1;
166   substring_okay = 0;
167
168 #define RETURN_ENTRY(e, w) \
169         return ((e = history_get (w)) ? e->line : (char *)NULL)
170
171   /* Handle !! case. */
172   if (string[i] == history_expansion_char)
173     {
174       i++;
175       which = history_base + (history_length - 1);
176       *caller_index = i;
177       RETURN_ENTRY (entry, which);
178     }
179
180   /* Hack case of numeric line specification. */
181   if (string[i] == '-')
182     {
183       sign = -1;
184       i++;
185     }
186
187   if (_rl_digit_p (string[i]))
188     {
189       /* Get the extent of the digits and compute the value. */
190       for (which = 0; _rl_digit_p (string[i]); i++)
191         which = (which * 10) + _rl_digit_value (string[i]);
192
193       *caller_index = i;
194
195       if (sign < 0)
196         which = (history_length + history_base) - which;
197
198       RETURN_ENTRY (entry, which);
199     }
200
201   /* This must be something to search for.  If the spec begins with
202      a '?', then the string may be anywhere on the line.  Otherwise,
203      the string must be found at the start of a line. */
204   if (string[i] == '?')
205     {
206       substring_okay++;
207       i++;
208     }
209
210   /* Only a closing `?' or a newline delimit a substring search string. */
211   for (local_index = i; c = string[i]; i++)
212     {
213 #if defined (HANDLE_MULTIBYTE)
214       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
215         {
216           int v;
217           mbstate_t ps;
218
219           memset (&ps, 0, sizeof (mbstate_t));
220           /* These produce warnings because we're passing a const string to a
221              function that takes a non-const string. */
222           _rl_adjust_point ((char *)string, i, &ps);
223           if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1)
224             {
225               i += v - 1;
226               continue;
227             }
228         }
229
230 #endif /* HANDLE_MULTIBYTE */
231       if ((!substring_okay && (whitespace (c) || c == ':' ||
232           (history_event_delimiter_chars && member (c, history_event_delimiter_chars)) ||
233           (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
234           string[i] == delimiting_quote)) ||
235           string[i] == '\n' ||
236           (substring_okay && string[i] == '?'))
237         break;
238     }
239
240   which = i - local_index;
241   temp = (char *)xmalloc (1 + which);
242   if (which)
243     strncpy (temp, string + local_index, which);
244   temp[which] = '\0';
245
246   if (substring_okay && string[i] == '?')
247     i++;
248
249   *caller_index = i;
250
251 #define FAIL_SEARCH() \
252   do { \
253     history_offset = history_length; xfree (temp) ; return (char *)NULL; \
254   } while (0)
255
256   /* If there is no search string, try to use the previous search string,
257      if one exists.  If not, fail immediately. */
258   if (*temp == '\0' && substring_okay)
259     {
260       if (search_string)
261         {
262           xfree (temp);
263           temp = savestring (search_string);
264         }
265       else
266         FAIL_SEARCH ();
267     }
268
269   search_func = substring_okay ? history_search : history_search_prefix;
270   while (1)
271     {
272       local_index = (*search_func) (temp, -1);
273
274       if (local_index < 0)
275         FAIL_SEARCH ();
276
277       if (local_index == 0 || substring_okay)
278         {
279           entry = current_history ();
280           if (entry == 0)
281             FAIL_SEARCH ();
282           history_offset = history_length;
283         
284           /* If this was a substring search, then remember the
285              string that we matched for word substitution. */
286           if (substring_okay)
287             {
288               FREE (search_string);
289               search_string = temp;
290
291               FREE (search_match);
292               search_match = history_find_word (entry->line, local_index);
293             }
294           else
295             xfree (temp);
296
297           return (entry->line);
298         }
299
300       if (history_offset)
301         history_offset--;
302       else
303         FAIL_SEARCH ();
304     }
305 #undef FAIL_SEARCH
306 #undef RETURN_ENTRY
307 }
308
309 /* Function for extracting single-quoted strings.  Used for inhibiting
310    history expansion within single quotes. */
311
312 /* Extract the contents of STRING as if it is enclosed in single quotes.
313    SINDEX, when passed in, is the offset of the character immediately
314    following the opening single quote; on exit, SINDEX is left pointing
315    to the closing single quote.  FLAGS currently used to allow backslash
316    to escape a single quote (e.g., for bash $'...'). */
317 static void
318 hist_string_extract_single_quoted (string, sindex, flags)
319      char *string;
320      int *sindex, flags;
321 {
322   register int i;
323
324   for (i = *sindex; string[i] && string[i] != '\''; i++)
325     {
326       if ((flags & 1) && string[i] == '\\' && string[i+1])
327         i++;
328     }
329
330   *sindex = i;
331 }
332
333 static char *
334 quote_breaks (s)
335      char *s;
336 {
337   register char *p, *r;
338   char *ret;
339   int len = 3;
340
341   for (p = s; p && *p; p++, len++)
342     {
343       if (*p == '\'')
344         len += 3;
345       else if (whitespace (*p) || *p == '\n')
346         len += 2;
347     }
348
349   r = ret = (char *)xmalloc (len);
350   *r++ = '\'';
351   for (p = s; p && *p; )
352     {
353       if (*p == '\'')
354         {
355           *r++ = '\'';
356           *r++ = '\\';
357           *r++ = '\'';
358           *r++ = '\'';
359           p++;
360         }
361       else if (whitespace (*p) || *p == '\n')
362         {
363           *r++ = '\'';
364           *r++ = *p++;
365           *r++ = '\'';
366         }
367       else
368         *r++ = *p++;
369     }
370   *r++ = '\'';
371   *r = '\0';
372   return ret;
373 }
374
375 static char *
376 hist_error(s, start, current, errtype)
377       char *s;
378       int start, current, errtype;
379 {
380   char *temp;
381   const char *emsg;
382   int ll, elen;
383
384   ll = current - start;
385
386   switch (errtype)
387     {
388     case EVENT_NOT_FOUND:
389       emsg = "event not found";
390       elen = 15;
391       break;
392     case BAD_WORD_SPEC:
393       emsg = "bad word specifier";
394       elen = 18;
395       break;
396     case SUBST_FAILED:
397       emsg = "substitution failed";
398       elen = 19;
399       break;
400     case BAD_MODIFIER:
401       emsg = "unrecognized history modifier";
402       elen = 29;
403       break;
404     case NO_PREV_SUBST:
405       emsg = "no previous substitution";
406       elen = 24;
407       break;
408     default:
409       emsg = "unknown expansion error";
410       elen = 23;
411       break;
412     }
413
414   temp = (char *)xmalloc (ll + elen + 3);
415   strncpy (temp, s + start, ll);
416   temp[ll] = ':';
417   temp[ll + 1] = ' ';
418   strcpy (temp + ll + 2, emsg);
419   return (temp);
420 }
421
422 /* Get a history substitution string from STR starting at *IPTR
423    and return it.  The length is returned in LENPTR.
424
425    A backslash can quote the delimiter.  If the string is the
426    empty string, the previous pattern is used.  If there is
427    no previous pattern for the lhs, the last history search
428    string is used.
429
430    If IS_RHS is 1, we ignore empty strings and set the pattern
431    to "" anyway.  subst_lhs is not changed if the lhs is empty;
432    subst_rhs is allowed to be set to the empty string. */
433
434 static char *
435 get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr)
436      char *str;
437      int *iptr, delimiter, is_rhs, *lenptr;
438 {
439   register int si, i, j, k;
440   char *s;
441 #if defined (HANDLE_MULTIBYTE)
442   mbstate_t ps;
443 #endif
444
445   s = (char *)NULL;
446   i = *iptr;
447
448 #if defined (HANDLE_MULTIBYTE)
449   memset (&ps, 0, sizeof (mbstate_t));
450   _rl_adjust_point (str, i, &ps);
451 #endif
452
453   for (si = i; str[si] && str[si] != delimiter; si++)
454 #if defined (HANDLE_MULTIBYTE)
455     if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
456       {
457         int v;
458         if ((v = _rl_get_char_len (str + si, &ps)) > 1)
459           si += v - 1;
460         else if (str[si] == '\\' && str[si + 1] == delimiter)
461           si++;
462       }
463     else
464 #endif /* HANDLE_MULTIBYTE */
465       if (str[si] == '\\' && str[si + 1] == delimiter)
466         si++;
467
468   if (si > i || is_rhs)
469     {
470       s = (char *)xmalloc (si - i + 1);
471       for (j = 0, k = i; k < si; j++, k++)
472         {
473           /* Remove a backslash quoting the search string delimiter. */
474           if (str[k] == '\\' && str[k + 1] == delimiter)
475             k++;
476           s[j] = str[k];
477         }
478       s[j] = '\0';
479       if (lenptr)
480         *lenptr = j;
481     }
482
483   i = si;
484   if (str[i])
485     i++;
486   *iptr = i;
487
488   return s;
489 }
490
491 static void
492 postproc_subst_rhs ()
493 {
494   char *new;
495   int i, j, new_size;
496
497   new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len);
498   for (i = j = 0; i < subst_rhs_len; i++)
499     {
500       if (subst_rhs[i] == '&')
501         {
502           if (j + subst_lhs_len >= new_size)
503             new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len));
504           strcpy (new + j, subst_lhs);
505           j += subst_lhs_len;
506         }
507       else
508         {
509           /* a single backslash protects the `&' from lhs interpolation */
510           if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&')
511             i++;
512           if (j >= new_size)
513             new = (char *)xrealloc (new, new_size *= 2);
514           new[j++] = subst_rhs[i];
515         }
516     }
517   new[j] = '\0';
518   xfree (subst_rhs);
519   subst_rhs = new;
520   subst_rhs_len = j;
521 }
522
523 /* Expand the bulk of a history specifier starting at STRING[START].
524    Returns 0 if everything is OK, -1 if an error occurred, and 1
525    if the `p' modifier was supplied and the caller should just print
526    the returned string.  Returns the new index into string in
527    *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */
528 static int
529 history_expand_internal (string, start, qc, end_index_ptr, ret_string, current_line)
530      char *string;
531      int start, qc, *end_index_ptr;
532      char **ret_string;
533      char *current_line;        /* for !# */
534 {
535   int i, n, starting_index;
536   int substitute_globally, subst_bywords, want_quotes, print_only;
537   char *event, *temp, *result, *tstr, *t, c, *word_spec;
538   int result_len;
539 #if defined (HANDLE_MULTIBYTE)
540   mbstate_t ps;
541
542   memset (&ps, 0, sizeof (mbstate_t));
543 #endif
544
545   result = (char *)xmalloc (result_len = 128);
546
547   i = start;
548
549   /* If it is followed by something that starts a word specifier,
550      then !! is implied as the event specifier. */
551
552   if (member (string[i + 1], ":$*%^"))
553     {
554       char fake_s[3];
555       int fake_i = 0;
556       i++;
557       fake_s[0] = fake_s[1] = history_expansion_char;
558       fake_s[2] = '\0';
559       event = get_history_event (fake_s, &fake_i, 0);
560     }
561   else if (string[i + 1] == '#')
562     {
563       i += 2;
564       event = current_line;
565     }
566   else
567     event = get_history_event (string, &i, qc);
568           
569   if (event == 0)
570     {
571       *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
572       xfree (result);
573       return (-1);
574     }
575
576   /* If a word specifier is found, then do what that requires. */
577   starting_index = i;
578   word_spec = get_history_word_specifier (string, event, &i);
579
580   /* There is no such thing as a `malformed word specifier'.  However,
581      it is possible for a specifier that has no match.  In that case,
582      we complain. */
583   if (word_spec == (char *)&error_pointer)
584     {
585       *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC);
586       xfree (result);
587       return (-1);
588     }
589
590   /* If no word specifier, than the thing of interest was the event. */
591   temp = word_spec ? savestring (word_spec) : savestring (event);
592   FREE (word_spec);
593
594   /* Perhaps there are other modifiers involved.  Do what they say. */
595   want_quotes = substitute_globally = subst_bywords = print_only = 0;
596   starting_index = i;
597
598   while (string[i] == ':')
599     {
600       c = string[i + 1];
601
602       if (c == 'g' || c == 'a')
603         {
604           substitute_globally = 1;
605           i++;
606           c = string[i + 1];
607         }
608       else if (c == 'G')
609         {
610           subst_bywords = 1;
611           i++;
612           c = string[i + 1];
613         }
614
615       switch (c)
616         {
617         default:
618           *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER);
619           xfree (result);
620           xfree (temp);
621           return -1;
622
623         case 'q':
624           want_quotes = 'q';
625           break;
626
627         case 'x':
628           want_quotes = 'x';
629           break;
630
631           /* :p means make this the last executed line.  So we
632              return an error state after adding this line to the
633              history. */
634         case 'p':
635           print_only++;
636           break;
637
638           /* :t discards all but the last part of the pathname. */
639         case 't':
640           tstr = strrchr (temp, '/');
641           if (tstr)
642             {
643               tstr++;
644               t = savestring (tstr);
645               xfree (temp);
646               temp = t;
647             }
648           break;
649
650           /* :h discards the last part of a pathname. */
651         case 'h':
652           tstr = strrchr (temp, '/');
653           if (tstr)
654             *tstr = '\0';
655           break;
656
657           /* :r discards the suffix. */
658         case 'r':
659           tstr = strrchr (temp, '.');
660           if (tstr)
661             *tstr = '\0';
662           break;
663
664           /* :e discards everything but the suffix. */
665         case 'e':
666           tstr = strrchr (temp, '.');
667           if (tstr)
668             {
669               t = savestring (tstr);
670               xfree (temp);
671               temp = t;
672             }
673           break;
674
675         /* :s/this/that substitutes `that' for the first
676            occurrence of `this'.  :gs/this/that substitutes `that'
677            for each occurrence of `this'.  :& repeats the last
678            substitution.  :g& repeats the last substitution
679            globally. */
680
681         case '&':
682         case 's':
683           {
684             char *new_event;
685             int delimiter, failed, si, l_temp, ws, we;
686
687             if (c == 's')
688               {
689                 if (i + 2 < (int)strlen (string))
690                   {
691 #if defined (HANDLE_MULTIBYTE)
692                     if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
693                       {
694                         _rl_adjust_point (string, i + 2, &ps);
695                         if (_rl_get_char_len (string + i + 2, &ps) > 1)
696                           delimiter = 0;
697                         else
698                           delimiter = string[i + 2];
699                       }
700                     else
701 #endif /* HANDLE_MULTIBYTE */
702                       delimiter = string[i + 2];
703                   }
704                 else
705                   break;        /* no search delimiter */
706
707                 i += 3;
708
709                 t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len);
710                 /* An empty substitution lhs with no previous substitution
711                    uses the last search string as the lhs. */
712                 if (t)
713                   {
714                     FREE (subst_lhs);
715                     subst_lhs = t;
716                   }
717                 else if (!subst_lhs)
718                   {
719                     if (search_string && *search_string)
720                       {
721                         subst_lhs = savestring (search_string);
722                         subst_lhs_len = strlen (subst_lhs);
723                       }
724                     else
725                       {
726                         subst_lhs = (char *) NULL;
727                         subst_lhs_len = 0;
728                       }
729                   }
730
731                 FREE (subst_rhs);
732                 subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len);
733
734                 /* If `&' appears in the rhs, it's supposed to be replaced
735                    with the lhs. */
736                 if (member ('&', subst_rhs))
737                   postproc_subst_rhs ();
738               }
739             else
740               i += 2;
741
742             /* If there is no lhs, the substitution can't succeed. */
743             if (subst_lhs_len == 0)
744               {
745                 *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST);
746                 xfree (result);
747                 xfree (temp);
748                 return -1;
749               }
750
751             l_temp = strlen (temp);
752             /* Ignore impossible cases. */
753             if (subst_lhs_len > l_temp)
754               {
755                 *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
756                 xfree (result);
757                 xfree (temp);
758                 return (-1);
759               }
760
761             /* Find the first occurrence of THIS in TEMP. */
762             /* Substitute SUBST_RHS for SUBST_LHS in TEMP.  There are three
763                cases to consider:
764
765                  1.  substitute_globally == subst_bywords == 0
766                  2.  substitute_globally == 1 && subst_bywords == 0
767                  3.  substitute_globally == 0 && subst_bywords == 1
768
769                In the first case, we substitute for the first occurrence only.
770                In the second case, we substitute for every occurrence.
771                In the third case, we tokenize into words and substitute the
772                first occurrence of each word. */
773
774             si = we = 0;
775             for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
776               {
777                 /* First skip whitespace and find word boundaries if
778                    we're past the end of the word boundary we found
779                    the last time. */
780                 if (subst_bywords && si > we)
781                   {
782                     for (; temp[si] && whitespace (temp[si]); si++)
783                       ;
784                     ws = si;
785                     we = history_tokenize_word (temp, si);
786                   }
787
788                 if (STREQN (temp+si, subst_lhs, subst_lhs_len))
789                   {
790                     int len = subst_rhs_len - subst_lhs_len + l_temp;
791                     new_event = (char *)xmalloc (1 + len);
792                     strncpy (new_event, temp, si);
793                     strncpy (new_event + si, subst_rhs, subst_rhs_len);
794                     strncpy (new_event + si + subst_rhs_len,
795                              temp + si + subst_lhs_len,
796                              l_temp - (si + subst_lhs_len));
797                     new_event[len] = '\0';
798                     xfree (temp);
799                     temp = new_event;
800
801                     failed = 0;
802
803                     if (substitute_globally)
804                       {
805                         /* Reported to fix a bug that causes it to skip every
806                            other match when matching a single character.  Was
807                            si += subst_rhs_len previously. */
808                         si += subst_rhs_len - 1;
809                         l_temp = strlen (temp);
810                         substitute_globally++;
811                         continue;
812                       }
813                     else if (subst_bywords)
814                       {
815                         si = we;
816                         l_temp = strlen (temp);
817                         continue;
818                       }
819                     else
820                       break;
821                   }
822               }
823
824             if (substitute_globally > 1)
825               {
826                 substitute_globally = 0;
827                 continue;       /* don't want to increment i */
828               }
829
830             if (failed == 0)
831               continue;         /* don't want to increment i */
832
833             *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
834             xfree (result);
835             xfree (temp);
836             return (-1);
837           }
838         }
839       i += 2;
840     }
841   /* Done with modifiers. */
842   /* Believe it or not, we have to back the pointer up by one. */
843   --i;
844
845   if (want_quotes)
846     {
847       char *x;
848
849       if (want_quotes == 'q')
850         x = sh_single_quote (temp);
851       else if (want_quotes == 'x')
852         x = quote_breaks (temp);
853       else
854         x = savestring (temp);
855
856       xfree (temp);
857       temp = x;
858     }
859
860   n = strlen (temp);
861   if (n >= result_len)
862     result = (char *)xrealloc (result, n + 2);
863   strcpy (result, temp);
864   xfree (temp);
865
866   *end_index_ptr = i;
867   *ret_string = result;
868   return (print_only);
869 }
870
871 /* Expand the string STRING, placing the result into OUTPUT, a pointer
872    to a string.  Returns:
873
874   -1) If there was an error in expansion.
875    0) If no expansions took place (or, if the only change in
876       the text was the de-slashifying of the history expansion
877       character)
878    1) If expansions did take place
879    2) If the `p' modifier was given and the caller should print the result
880
881   If an error occurred in expansion, then OUTPUT contains a descriptive
882   error message. */
883
884 #define ADD_STRING(s) \
885         do \
886           { \
887             int sl = strlen (s); \
888             j += sl; \
889             if (j >= result_len) \
890               { \
891                 while (j >= result_len) \
892                   result_len += 128; \
893                 result = (char *)xrealloc (result, result_len); \
894               } \
895             strcpy (result + j - sl, s); \
896           } \
897         while (0)
898
899 #define ADD_CHAR(c) \
900         do \
901           { \
902             if (j >= result_len - 1) \
903               result = (char *)xrealloc (result, result_len += 64); \
904             result[j++] = c; \
905             result[j] = '\0'; \
906           } \
907         while (0)
908
909 int
910 history_expand (hstring, output)
911      char *hstring;
912      char **output;
913 {
914   register int j;
915   int i, r, l, passc, cc, modified, eindex, only_printing, dquote, squote, flag;
916   char *string;
917
918   /* The output string, and its length. */
919   int result_len;
920   char *result;
921
922 #if defined (HANDLE_MULTIBYTE)
923   char mb[MB_LEN_MAX];
924   mbstate_t ps;
925 #endif
926
927   /* Used when adding the string. */
928   char *temp;
929
930   if (output == 0)
931     return 0;
932
933   /* Setting the history expansion character to 0 inhibits all
934      history expansion. */
935   if (history_expansion_char == 0)
936     {
937       *output = savestring (hstring);
938       return (0);
939     }
940     
941   /* Prepare the buffer for printing error messages. */
942   result = (char *)xmalloc (result_len = 256);
943   result[0] = '\0';
944
945   only_printing = modified = 0;
946   l = strlen (hstring);
947
948   /* Grovel the string.  Only backslash and single quotes can quote the
949      history escape character.  We also handle arg specifiers. */
950
951   /* Before we grovel forever, see if the history_expansion_char appears
952      anywhere within the text. */
953
954   /* The quick substitution character is a history expansion all right.  That
955      is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact,
956      that is the substitution that we do. */
957   if (hstring[0] == history_subst_char)
958     {
959       string = (char *)xmalloc (l + 5);
960
961       string[0] = string[1] = history_expansion_char;
962       string[2] = ':';
963       string[3] = 's';
964       strcpy (string + 4, hstring);
965       l += 4;
966     }
967   else
968     {
969 #if defined (HANDLE_MULTIBYTE)
970       memset (&ps, 0, sizeof (mbstate_t));
971 #endif
972
973       string = hstring;
974       /* If not quick substitution, still maybe have to do expansion. */
975
976       /* `!' followed by one of the characters in history_no_expand_chars
977          is NOT an expansion. */
978       for (i = dquote = squote = 0; string[i]; i++)
979         {
980 #if defined (HANDLE_MULTIBYTE)
981           if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
982             {
983               int v;
984               v = _rl_get_char_len (string + i, &ps);
985               if (v > 1)
986                 {
987                   i += v - 1;
988                   continue;
989                 }
990             }
991 #endif /* HANDLE_MULTIBYTE */
992
993           cc = string[i + 1];
994           /* The history_comment_char, if set, appearing at the beginning
995              of a word signifies that the rest of the line should not have
996              history expansion performed on it.
997              Skip the rest of the line and break out of the loop. */
998           if (history_comment_char && string[i] == history_comment_char &&
999               dquote == 0 &&
1000               (i == 0 || member (string[i - 1], history_word_delimiters)))
1001             {
1002               while (string[i])
1003                 i++;
1004               break;
1005             }
1006           else if (string[i] == history_expansion_char)
1007             {
1008               if (cc == 0 || member (cc, history_no_expand_chars))
1009                 continue;
1010               /* DQUOTE won't be set unless history_quotes_inhibit_expansion
1011                  is set.  The idea here is to treat double-quoted strings the
1012                  same as the word outside double quotes; in effect making the
1013                  double quote part of history_no_expand_chars when DQUOTE is
1014                  set. */
1015               else if (dquote && cc == '"')
1016                 continue;
1017               /* If the calling application has set
1018                  history_inhibit_expansion_function to a function that checks
1019                  for special cases that should not be history expanded,
1020                  call the function and skip the expansion if it returns a
1021                  non-zero value. */
1022               else if (history_inhibit_expansion_function &&
1023                         (*history_inhibit_expansion_function) (string, i))
1024                 continue;
1025               else
1026                 break;
1027             }
1028           /* Shell-like quoting: allow backslashes to quote double quotes
1029              inside a double-quoted string. */
1030           else if (dquote && string[i] == '\\' && cc == '"')
1031             i++;
1032           /* More shell-like quoting:  if we're paying attention to single
1033              quotes and letting them quote the history expansion character,
1034              then we need to pay attention to double quotes, because single
1035              quotes are not special inside double-quoted strings. */
1036           else if (history_quotes_inhibit_expansion && string[i] == '"')
1037             {
1038               dquote = 1 - dquote;
1039             }
1040           else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'')
1041             {
1042               /* If this is bash, single quotes inhibit history expansion. */
1043               flag = (i > 0 && string[i - 1] == '$');
1044               i++;
1045               hist_string_extract_single_quoted (string, &i, flag);
1046             }
1047           else if (history_quotes_inhibit_expansion && string[i] == '\\')
1048             {
1049               /* If this is bash, allow backslashes to quote single
1050                  quotes and the history expansion character. */
1051               if (cc == '\'' || cc == history_expansion_char)
1052                 i++;
1053             }
1054           
1055         }
1056           
1057       if (string[i] != history_expansion_char)
1058         {
1059           xfree (result);
1060           *output = savestring (string);
1061           return (0);
1062         }
1063     }
1064
1065   /* Extract and perform the substitution. */
1066   for (passc = dquote = squote = i = j = 0; i < l; i++)
1067     {
1068       int qc, tchar = string[i];
1069
1070       if (passc)
1071         {
1072           passc = 0;
1073           ADD_CHAR (tchar);
1074           continue;
1075         }
1076
1077 #if defined (HANDLE_MULTIBYTE)
1078       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1079         {
1080           int k, c;
1081
1082           c = tchar;
1083           memset (mb, 0, sizeof (mb));
1084           for (k = 0; k < MB_LEN_MAX; k++)
1085             {
1086               mb[k] = (char)c;
1087               memset (&ps, 0, sizeof (mbstate_t));
1088               if (_rl_get_char_len (mb, &ps) == -2)
1089                 c = string[++i];
1090               else
1091                 break;
1092             }
1093           if (strlen (mb) > 1)
1094             {
1095               ADD_STRING (mb);
1096               continue;
1097             }
1098         }
1099 #endif /* HANDLE_MULTIBYTE */
1100
1101       if (tchar == history_expansion_char)
1102         tchar = -3;
1103       else if (tchar == history_comment_char)
1104         tchar = -2;
1105
1106       switch (tchar)
1107         {
1108         default:
1109           ADD_CHAR (string[i]);
1110           break;
1111
1112         case '\\':
1113           passc++;
1114           ADD_CHAR (tchar);
1115           break;
1116
1117         case '"':
1118           dquote = 1 - dquote;
1119           ADD_CHAR (tchar);
1120           break;
1121           
1122         case '\'':
1123           {
1124             /* If history_quotes_inhibit_expansion is set, single quotes
1125                inhibit history expansion, otherwise they are treated like
1126                double quotes. */
1127             if (squote)
1128               {
1129                 squote = 0;
1130                 ADD_CHAR (tchar);
1131               }
1132             else if (dquote == 0 && history_quotes_inhibit_expansion)
1133               {
1134                 int quote, slen;
1135
1136                 flag = (i > 0 && string[i - 1] == '$');
1137                 quote = i++;
1138                 hist_string_extract_single_quoted (string, &i, flag);
1139
1140                 slen = i - quote + 2;
1141                 temp = (char *)xmalloc (slen);
1142                 strncpy (temp, string + quote, slen);
1143                 temp[slen - 1] = '\0';
1144                 ADD_STRING (temp);
1145                 xfree (temp);
1146               }
1147             else if (dquote == 0 && squote == 0 && history_quotes_inhibit_expansion == 0)
1148               {
1149                 squote = 1;
1150                 ADD_CHAR (string[i]);
1151               }
1152             else
1153               ADD_CHAR (string[i]);
1154             break;
1155           }
1156
1157         case -2:                /* history_comment_char */
1158           if ((dquote == 0 || history_quotes_inhibit_expansion == 0) &&
1159               (i == 0 || member (string[i - 1], history_word_delimiters)))
1160             {
1161               temp = (char *)xmalloc (l - i + 1);
1162               strcpy (temp, string + i);
1163               ADD_STRING (temp);
1164               xfree (temp);
1165               i = l;
1166             }
1167           else
1168             ADD_CHAR (string[i]);
1169           break;
1170
1171         case -3:                /* history_expansion_char */
1172           cc = string[i + 1];
1173
1174           /* If the history_expansion_char is followed by one of the
1175              characters in history_no_expand_chars, then it is not a
1176              candidate for expansion of any kind. */
1177           if (cc == 0 || member (cc, history_no_expand_chars) ||
1178                          (dquote && cc == '"') ||
1179                          (history_inhibit_expansion_function && (*history_inhibit_expansion_function) (string, i)))
1180             {
1181               ADD_CHAR (string[i]);
1182               break;
1183             }
1184
1185 #if defined (NO_BANG_HASH_MODIFIERS)
1186           /* There is something that is listed as a `word specifier' in csh
1187              documentation which means `the expanded text to this point'.
1188              That is not a word specifier, it is an event specifier.  If we
1189              don't want to allow modifiers with `!#', just stick the current
1190              output line in again. */
1191           if (cc == '#')
1192             {
1193               if (result)
1194                 {
1195                   temp = (char *)xmalloc (1 + strlen (result));
1196                   strcpy (temp, result);
1197                   ADD_STRING (temp);
1198                   xfree (temp);
1199                 }
1200               i++;
1201               break;
1202             }
1203 #endif
1204           qc = squote ? '\'' : (dquote ? '"' : 0);
1205           r = history_expand_internal (string, i, qc, &eindex, &temp, result);
1206           if (r < 0)
1207             {
1208               *output = temp;
1209               xfree (result);
1210               if (string != hstring)
1211                 xfree (string);
1212               return -1;
1213             }
1214           else
1215             {
1216               if (temp)
1217                 {
1218                   modified++;
1219                   if (*temp)
1220                     ADD_STRING (temp);
1221                   xfree (temp);
1222                 }
1223               only_printing = r == 1;
1224               i = eindex;
1225             }
1226           break;
1227         }
1228     }
1229
1230   *output = result;
1231   if (string != hstring)
1232     xfree (string);
1233
1234   if (only_printing)
1235     {
1236 #if 0
1237       add_history (result);
1238 #endif
1239       return (2);
1240     }
1241
1242   return (modified != 0);
1243 }
1244
1245 /* Return a consed string which is the word specified in SPEC, and found
1246    in FROM.  NULL is returned if there is no spec.  The address of
1247    ERROR_POINTER is returned if the word specified cannot be found.
1248    CALLER_INDEX is the offset in SPEC to start looking; it is updated
1249    to point to just after the last character parsed. */
1250 static char *
1251 get_history_word_specifier (spec, from, caller_index)
1252      char *spec, *from;
1253      int *caller_index;
1254 {
1255   register int i = *caller_index;
1256   int first, last;
1257   int expecting_word_spec = 0;
1258   char *result;
1259
1260   /* The range of words to return doesn't exist yet. */
1261   first = last = 0;
1262   result = (char *)NULL;
1263
1264   /* If we found a colon, then this *must* be a word specification.  If
1265      it isn't, then it is an error. */
1266   if (spec[i] == ':')
1267     {
1268       i++;
1269       expecting_word_spec++;
1270     }
1271
1272   /* Handle special cases first. */
1273
1274   /* `%' is the word last searched for. */
1275   if (spec[i] == '%')
1276     {
1277       *caller_index = i + 1;
1278       return (search_match ? savestring (search_match) : savestring (""));
1279     }
1280
1281   /* `*' matches all of the arguments, but not the command. */
1282   if (spec[i] == '*')
1283     {
1284       *caller_index = i + 1;
1285       result = history_arg_extract (1, '$', from);
1286       return (result ? result : savestring (""));
1287     }
1288
1289   /* `$' is last arg. */
1290   if (spec[i] == '$')
1291     {
1292       *caller_index = i + 1;
1293       return (history_arg_extract ('$', '$', from));
1294     }
1295
1296   /* Try to get FIRST and LAST figured out. */
1297
1298   if (spec[i] == '-')
1299     first = 0;
1300   else if (spec[i] == '^')
1301     {
1302       first = 1;
1303       i++;
1304     }
1305   else if (_rl_digit_p (spec[i]) && expecting_word_spec)
1306     {
1307       for (first = 0; _rl_digit_p (spec[i]); i++)
1308         first = (first * 10) + _rl_digit_value (spec[i]);
1309     }
1310   else
1311     return ((char *)NULL);      /* no valid `first' for word specifier */
1312
1313   if (spec[i] == '^' || spec[i] == '*')
1314     {
1315       last = (spec[i] == '^') ? 1 : '$';        /* x* abbreviates x-$ */
1316       i++;
1317     }
1318   else if (spec[i] != '-')
1319     last = first;
1320   else
1321     {
1322       i++;
1323
1324       if (_rl_digit_p (spec[i]))
1325         {
1326           for (last = 0; _rl_digit_p (spec[i]); i++)
1327             last = (last * 10) + _rl_digit_value (spec[i]);
1328         }
1329       else if (spec[i] == '$')
1330         {
1331           i++;
1332           last = '$';
1333         }
1334 #if 0
1335       else if (!spec[i] || spec[i] == ':')
1336         /* check against `:' because there could be a modifier separator */
1337 #else
1338       else
1339         /* csh seems to allow anything to terminate the word spec here,
1340            leaving it as an abbreviation. */
1341 #endif
1342         last = -1;              /* x- abbreviates x-$ omitting word `$' */
1343     }
1344
1345   *caller_index = i;
1346
1347   if (last >= first || last == '$' || last < 0)
1348     result = history_arg_extract (first, last, from);
1349
1350   return (result ? result : (char *)&error_pointer);
1351 }
1352
1353 /* Extract the args specified, starting at FIRST, and ending at LAST.
1354    The args are taken from STRING.  If either FIRST or LAST is < 0,
1355    then make that arg count from the right (subtract from the number of
1356    tokens, so that FIRST = -1 means the next to last token on the line).
1357    If LAST is `$' the last arg from STRING is used. */
1358 char *
1359 history_arg_extract (first, last, string)
1360      int first, last;
1361      const char *string;
1362 {
1363   register int i, len;
1364   char *result;
1365   int size, offset;
1366   char **list;
1367
1368   /* XXX - think about making history_tokenize return a struct array,
1369      each struct in array being a string and a length to avoid the
1370      calls to strlen below. */
1371   if ((list = history_tokenize (string)) == NULL)
1372     return ((char *)NULL);
1373
1374   for (len = 0; list[len]; len++)
1375     ;
1376
1377   if (last < 0)
1378     last = len + last - 1;
1379
1380   if (first < 0)
1381     first = len + first - 1;
1382
1383   if (last == '$')
1384     last = len - 1;
1385
1386   if (first == '$')
1387     first = len - 1;
1388
1389   last++;
1390
1391   if (first >= len || last > len || first < 0 || last < 0 || first > last)
1392     result = ((char *)NULL);
1393   else
1394     {
1395       for (size = 0, i = first; i < last; i++)
1396         size += strlen (list[i]) + 1;
1397       result = (char *)xmalloc (size + 1);
1398       result[0] = '\0';
1399
1400       for (i = first, offset = 0; i < last; i++)
1401         {
1402           strcpy (result + offset, list[i]);
1403           offset += strlen (list[i]);
1404           if (i + 1 < last)
1405             {
1406               result[offset++] = ' ';
1407               result[offset] = 0;
1408             }
1409         }
1410     }
1411
1412   for (i = 0; i < len; i++)
1413     xfree (list[i]);
1414   xfree (list);
1415
1416   return (result);
1417 }
1418
1419 static int
1420 history_tokenize_word (string, ind)
1421      const char *string;
1422      int ind;
1423 {
1424   register int i;
1425   int delimiter, nestdelim, delimopen;
1426
1427   i = ind;
1428   delimiter = nestdelim = 0;
1429
1430   if (member (string[i], "()\n"))
1431     {
1432       i++;
1433       return i;
1434     }
1435
1436   if (member (string[i], "<>;&|$"))
1437     {
1438       int peek = string[i + 1];
1439
1440       if (peek == string[i] && peek != '$')
1441         {
1442           if (peek == '<' && string[i + 2] == '-')
1443             i++;
1444           else if (peek == '<' && string[i + 2] == '<')
1445             i++;
1446           i += 2;
1447           return i;
1448         }
1449       else if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
1450                 (peek == '>' && string[i] == '&'))
1451         {
1452           i += 2;
1453           return i;
1454         }
1455       /* XXX - separated out for later -- bash-4.2 */
1456       else if ((peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
1457                (peek == '(' && string[i] == '$')) /*)*/
1458         {
1459           i += 2;
1460           delimopen = '(';
1461           delimiter = ')';
1462           nestdelim = 1;
1463           goto get_word;
1464         }
1465 #if 0
1466       else if (peek == '\'' && string[i] == '$')
1467         {
1468           i += 2;       /* XXX */
1469           return i;
1470         }
1471 #endif
1472
1473       if (string[i] != '$')
1474         {
1475           i++;
1476           return i;
1477         }
1478     }
1479
1480   /* same code also used for $(...)/<(...)/>(...) above */
1481   if (member (string[i], "!@?+*"))
1482     {
1483       int peek = string[i + 1];
1484
1485       if (peek == '(')          /*)*/
1486         {
1487           /* Shell extended globbing patterns */
1488           i += 2;
1489           delimopen = '(';
1490           delimiter = ')';      /* XXX - not perfect */
1491           nestdelim = 1;
1492         }
1493     }
1494
1495 get_word:
1496   /* Get word from string + i; */
1497
1498   if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS))
1499     delimiter = string[i++];
1500
1501   for (; string[i]; i++)
1502     {
1503       if (string[i] == '\\' && string[i + 1] == '\n')
1504         {
1505           i++;
1506           continue;
1507         }
1508
1509       if (string[i] == '\\' && delimiter != '\'' &&
1510           (delimiter != '"' || member (string[i], slashify_in_quotes)))
1511         {
1512           i++;
1513           continue;
1514         }
1515
1516       /* delimiter must be set and set to something other than a quote if
1517          nestdelim is set, so these tests are safe. */
1518       if (nestdelim && string[i] == delimopen)
1519         {
1520           nestdelim++;
1521           continue;
1522         }
1523       if (nestdelim && string[i] == delimiter)
1524         {
1525           nestdelim--;
1526           if (nestdelim == 0)
1527             delimiter = 0;
1528           continue;
1529         }
1530       
1531       if (delimiter && string[i] == delimiter)
1532         {
1533           delimiter = 0;
1534           continue;
1535         }
1536
1537       if (delimiter == 0 && (member (string[i], history_word_delimiters)))
1538         break;
1539
1540       if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS))
1541         delimiter = string[i];
1542     }
1543
1544   return i;
1545 }
1546
1547 static char *
1548 history_substring (string, start, end)
1549      const char *string;
1550      int start, end;
1551 {
1552   register int len;
1553   register char *result;
1554
1555   len = end - start;
1556   result = (char *)xmalloc (len + 1);
1557   strncpy (result, string + start, len);
1558   result[len] = '\0';
1559   return result;
1560 }
1561
1562 /* Parse STRING into tokens and return an array of strings.  If WIND is
1563    not -1 and INDP is not null, we also want the word surrounding index
1564    WIND.  The position in the returned array of strings is returned in
1565    *INDP. */
1566 static char **
1567 history_tokenize_internal (string, wind, indp)
1568      const char *string;
1569      int wind, *indp;
1570 {
1571   char **result;
1572   register int i, start, result_index, size;
1573
1574   /* If we're searching for a string that's not part of a word (e.g., " "),
1575      make sure we set *INDP to a reasonable value. */
1576   if (indp && wind != -1)
1577     *indp = -1;
1578
1579   /* Get a token, and stuff it into RESULT.  The tokens are split
1580      exactly where the shell would split them. */
1581   for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
1582     {
1583       /* Skip leading whitespace. */
1584       for (; string[i] && whitespace (string[i]); i++)
1585         ;
1586       if (string[i] == 0 || string[i] == history_comment_char)
1587         return (result);
1588
1589       start = i;
1590
1591       i = history_tokenize_word (string, start);
1592
1593       /* If we have a non-whitespace delimiter character (which would not be
1594          skipped by the loop above), use it and any adjacent delimiters to
1595          make a separate field.  Any adjacent white space will be skipped the
1596          next time through the loop. */
1597       if (i == start && history_word_delimiters)
1598         {
1599           i++;
1600           while (string[i] && member (string[i], history_word_delimiters))
1601             i++;
1602         }
1603
1604       /* If we are looking for the word in which the character at a
1605          particular index falls, remember it. */
1606       if (indp && wind != -1 && wind >= start && wind < i)
1607         *indp = result_index;
1608
1609       if (result_index + 2 >= size)
1610         result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
1611
1612       result[result_index++] = history_substring (string, start, i);
1613       result[result_index] = (char *)NULL;
1614     }
1615
1616   return (result);
1617 }
1618
1619 /* Return an array of tokens, much as the shell might.  The tokens are
1620    parsed out of STRING. */
1621 char **
1622 history_tokenize (string)
1623      const char *string;
1624 {
1625   return (history_tokenize_internal (string, -1, (int *)NULL));
1626 }
1627
1628 /* Free members of WORDS from START to an empty string */
1629 static void
1630 freewords (words, start)
1631      char **words;
1632      int start;
1633 {
1634   register int i;
1635
1636   for (i = start; words[i]; i++)
1637     xfree (words[i]);
1638 }
1639
1640 /* Find and return the word which contains the character at index IND
1641    in the history line LINE.  Used to save the word matched by the
1642    last history !?string? search. */
1643 static char *
1644 history_find_word (line, ind)
1645      char *line;
1646      int ind;
1647 {
1648   char **words, *s;
1649   int i, wind;
1650
1651   words = history_tokenize_internal (line, ind, &wind);
1652   if (wind == -1 || words == 0)
1653     {
1654       if (words)
1655         freewords (words, 0);
1656       FREE (words);
1657       return ((char *)NULL);
1658     }
1659   s = words[wind];
1660   for (i = 0; i < wind; i++)
1661     xfree (words[i]);
1662   freewords (words, wind + 1);
1663   xfree (words);
1664   return s;
1665 }