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