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