Imported from ../bash-4.0-rc1.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 || 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 (member (cc, history_no_expand_chars))
1168             {
1169               ADD_CHAR (string[i]);
1170               break;
1171             }
1172
1173 #if defined (NO_BANG_HASH_MODIFIERS)
1174           /* There is something that is listed as a `word specifier' in csh
1175              documentation which means `the expanded text to this point'.
1176              That is not a word specifier, it is an event specifier.  If we
1177              don't want to allow modifiers with `!#', just stick the current
1178              output line in again. */
1179           if (cc == '#')
1180             {
1181               if (result)
1182                 {
1183                   temp = (char *)xmalloc (1 + strlen (result));
1184                   strcpy (temp, result);
1185                   ADD_STRING (temp);
1186                   free (temp);
1187                 }
1188               i++;
1189               break;
1190             }
1191 #endif
1192
1193           r = history_expand_internal (string, i, &eindex, &temp, result);
1194           if (r < 0)
1195             {
1196               *output = temp;
1197               free (result);
1198               if (string != hstring)
1199                 free (string);
1200               return -1;
1201             }
1202           else
1203             {
1204               if (temp)
1205                 {
1206                   modified++;
1207                   if (*temp)
1208                     ADD_STRING (temp);
1209                   free (temp);
1210                 }
1211               only_printing = r == 1;
1212               i = eindex;
1213             }
1214           break;
1215         }
1216     }
1217
1218   *output = result;
1219   if (string != hstring)
1220     free (string);
1221
1222   if (only_printing)
1223     {
1224 #if 0
1225       add_history (result);
1226 #endif
1227       return (2);
1228     }
1229
1230   return (modified != 0);
1231 }
1232
1233 /* Return a consed string which is the word specified in SPEC, and found
1234    in FROM.  NULL is returned if there is no spec.  The address of
1235    ERROR_POINTER is returned if the word specified cannot be found.
1236    CALLER_INDEX is the offset in SPEC to start looking; it is updated
1237    to point to just after the last character parsed. */
1238 static char *
1239 get_history_word_specifier (spec, from, caller_index)
1240      char *spec, *from;
1241      int *caller_index;
1242 {
1243   register int i = *caller_index;
1244   int first, last;
1245   int expecting_word_spec = 0;
1246   char *result;
1247
1248   /* The range of words to return doesn't exist yet. */
1249   first = last = 0;
1250   result = (char *)NULL;
1251
1252   /* If we found a colon, then this *must* be a word specification.  If
1253      it isn't, then it is an error. */
1254   if (spec[i] == ':')
1255     {
1256       i++;
1257       expecting_word_spec++;
1258     }
1259
1260   /* Handle special cases first. */
1261
1262   /* `%' is the word last searched for. */
1263   if (spec[i] == '%')
1264     {
1265       *caller_index = i + 1;
1266       return (search_match ? savestring (search_match) : savestring (""));
1267     }
1268
1269   /* `*' matches all of the arguments, but not the command. */
1270   if (spec[i] == '*')
1271     {
1272       *caller_index = i + 1;
1273       result = history_arg_extract (1, '$', from);
1274       return (result ? result : savestring (""));
1275     }
1276
1277   /* `$' is last arg. */
1278   if (spec[i] == '$')
1279     {
1280       *caller_index = i + 1;
1281       return (history_arg_extract ('$', '$', from));
1282     }
1283
1284   /* Try to get FIRST and LAST figured out. */
1285
1286   if (spec[i] == '-')
1287     first = 0;
1288   else if (spec[i] == '^')
1289     {
1290       first = 1;
1291       i++;
1292     }
1293   else if (_rl_digit_p (spec[i]) && expecting_word_spec)
1294     {
1295       for (first = 0; _rl_digit_p (spec[i]); i++)
1296         first = (first * 10) + _rl_digit_value (spec[i]);
1297     }
1298   else
1299     return ((char *)NULL);      /* no valid `first' for word specifier */
1300
1301   if (spec[i] == '^' || spec[i] == '*')
1302     {
1303       last = (spec[i] == '^') ? 1 : '$';        /* x* abbreviates x-$ */
1304       i++;
1305     }
1306   else if (spec[i] != '-')
1307     last = first;
1308   else
1309     {
1310       i++;
1311
1312       if (_rl_digit_p (spec[i]))
1313         {
1314           for (last = 0; _rl_digit_p (spec[i]); i++)
1315             last = (last * 10) + _rl_digit_value (spec[i]);
1316         }
1317       else if (spec[i] == '$')
1318         {
1319           i++;
1320           last = '$';
1321         }
1322 #if 0
1323       else if (!spec[i] || spec[i] == ':')
1324         /* check against `:' because there could be a modifier separator */
1325 #else
1326       else
1327         /* csh seems to allow anything to terminate the word spec here,
1328            leaving it as an abbreviation. */
1329 #endif
1330         last = -1;              /* x- abbreviates x-$ omitting word `$' */
1331     }
1332
1333   *caller_index = i;
1334
1335   if (last >= first || last == '$' || last < 0)
1336     result = history_arg_extract (first, last, from);
1337
1338   return (result ? result : (char *)&error_pointer);
1339 }
1340
1341 /* Extract the args specified, starting at FIRST, and ending at LAST.
1342    The args are taken from STRING.  If either FIRST or LAST is < 0,
1343    then make that arg count from the right (subtract from the number of
1344    tokens, so that FIRST = -1 means the next to last token on the line).
1345    If LAST is `$' the last arg from STRING is used. */
1346 char *
1347 history_arg_extract (first, last, string)
1348      int first, last;
1349      const char *string;
1350 {
1351   register int i, len;
1352   char *result;
1353   int size, offset;
1354   char **list;
1355
1356   /* XXX - think about making history_tokenize return a struct array,
1357      each struct in array being a string and a length to avoid the
1358      calls to strlen below. */
1359   if ((list = history_tokenize (string)) == NULL)
1360     return ((char *)NULL);
1361
1362   for (len = 0; list[len]; len++)
1363     ;
1364
1365   if (last < 0)
1366     last = len + last - 1;
1367
1368   if (first < 0)
1369     first = len + first - 1;
1370
1371   if (last == '$')
1372     last = len - 1;
1373
1374   if (first == '$')
1375     first = len - 1;
1376
1377   last++;
1378
1379   if (first >= len || last > len || first < 0 || last < 0 || first > last)
1380     result = ((char *)NULL);
1381   else
1382     {
1383       for (size = 0, i = first; i < last; i++)
1384         size += strlen (list[i]) + 1;
1385       result = (char *)xmalloc (size + 1);
1386       result[0] = '\0';
1387
1388       for (i = first, offset = 0; i < last; i++)
1389         {
1390           strcpy (result + offset, list[i]);
1391           offset += strlen (list[i]);
1392           if (i + 1 < last)
1393             {
1394               result[offset++] = ' ';
1395               result[offset] = 0;
1396             }
1397         }
1398     }
1399
1400   for (i = 0; i < len; i++)
1401     free (list[i]);
1402   free (list);
1403
1404   return (result);
1405 }
1406
1407 static int
1408 history_tokenize_word (string, ind)
1409      const char *string;
1410      int ind;
1411 {
1412   register int i;
1413   int delimiter;
1414
1415   i = ind;
1416   delimiter = 0;
1417
1418   if (member (string[i], "()\n"))
1419     {
1420       i++;
1421       return i;
1422     }
1423
1424   if (member (string[i], "<>;&|$"))
1425     {
1426       int peek = string[i + 1];
1427
1428       if (peek == string[i] && peek != '$')
1429         {
1430           if (peek == '<' && string[i + 2] == '-')
1431             i++;
1432           else if (peek == '<' && string[i + 2] == '<')
1433             i++;
1434           i += 2;
1435           return i;
1436         }
1437       else
1438         {
1439           if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
1440               (peek == '>' && string[i] == '&') ||
1441               (peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
1442               (peek == '(' && string[i] == '$')) /* ) */
1443             {
1444               i += 2;
1445               return i;
1446             }
1447         }
1448
1449       if (string[i] != '$')
1450         {
1451           i++;
1452           return i;
1453         }
1454     }
1455
1456   /* Get word from string + i; */
1457
1458   if (member (string[i], HISTORY_QUOTE_CHARACTERS))
1459     delimiter = string[i++];
1460
1461   for (; string[i]; i++)
1462     {
1463       if (string[i] == '\\' && string[i + 1] == '\n')
1464         {
1465           i++;
1466           continue;
1467         }
1468
1469       if (string[i] == '\\' && delimiter != '\'' &&
1470           (delimiter != '"' || member (string[i], slashify_in_quotes)))
1471         {
1472           i++;
1473           continue;
1474         }
1475
1476       if (delimiter && string[i] == delimiter)
1477         {
1478           delimiter = 0;
1479           continue;
1480         }
1481
1482       if (!delimiter && (member (string[i], history_word_delimiters)))
1483         break;
1484
1485       if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
1486         delimiter = string[i];
1487     }
1488
1489   return i;
1490 }
1491
1492 static char *
1493 history_substring (string, start, end)
1494      const char *string;
1495      int start, end;
1496 {
1497   register int len;
1498   register char *result;
1499
1500   len = end - start;
1501   result = (char *)xmalloc (len + 1);
1502   strncpy (result, string + start, len);
1503   result[len] = '\0';
1504   return result;
1505 }
1506
1507 /* Parse STRING into tokens and return an array of strings.  If WIND is
1508    not -1 and INDP is not null, we also want the word surrounding index
1509    WIND.  The position in the returned array of strings is returned in
1510    *INDP. */
1511 static char **
1512 history_tokenize_internal (string, wind, indp)
1513      const char *string;
1514      int wind, *indp;
1515 {
1516   char **result;
1517   register int i, start, result_index, size;
1518
1519   /* If we're searching for a string that's not part of a word (e.g., " "),
1520      make sure we set *INDP to a reasonable value. */
1521   if (indp && wind != -1)
1522     *indp = -1;
1523
1524   /* Get a token, and stuff it into RESULT.  The tokens are split
1525      exactly where the shell would split them. */
1526   for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
1527     {
1528       /* Skip leading whitespace. */
1529       for (; string[i] && whitespace (string[i]); i++)
1530         ;
1531       if (string[i] == 0 || string[i] == history_comment_char)
1532         return (result);
1533
1534       start = i;
1535
1536       i = history_tokenize_word (string, start);
1537
1538       /* If we have a non-whitespace delimiter character (which would not be
1539          skipped by the loop above), use it and any adjacent delimiters to
1540          make a separate field.  Any adjacent white space will be skipped the
1541          next time through the loop. */
1542       if (i == start && history_word_delimiters)
1543         {
1544           i++;
1545           while (string[i] && member (string[i], history_word_delimiters))
1546             i++;
1547         }
1548
1549       /* If we are looking for the word in which the character at a
1550          particular index falls, remember it. */
1551       if (indp && wind != -1 && wind >= start && wind < i)
1552         *indp = result_index;
1553
1554       if (result_index + 2 >= size)
1555         result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
1556
1557       result[result_index++] = history_substring (string, start, i);
1558       result[result_index] = (char *)NULL;
1559     }
1560
1561   return (result);
1562 }
1563
1564 /* Return an array of tokens, much as the shell might.  The tokens are
1565    parsed out of STRING. */
1566 char **
1567 history_tokenize (string)
1568      const char *string;
1569 {
1570   return (history_tokenize_internal (string, -1, (int *)NULL));
1571 }
1572
1573 /* Free members of WORDS from START to an empty string */
1574 static void
1575 freewords (words, start)
1576      char **words;
1577      int start;
1578 {
1579   register int i;
1580
1581   for (i = start; words[i]; i++)
1582     free (words[i]);
1583 }
1584
1585 /* Find and return the word which contains the character at index IND
1586    in the history line LINE.  Used to save the word matched by the
1587    last history !?string? search. */
1588 static char *
1589 history_find_word (line, ind)
1590      char *line;
1591      int ind;
1592 {
1593   char **words, *s;
1594   int i, wind;
1595
1596   words = history_tokenize_internal (line, ind, &wind);
1597   if (wind == -1 || words == 0)
1598     {
1599       if (words)
1600         freewords (words, 0);
1601       FREE (words);
1602       return ((char *)NULL);
1603     }
1604   s = words[wind];
1605   for (i = 0; i < wind; i++)
1606     free (words[i]);
1607   freewords (words, wind + 1);
1608   free (words);
1609   return s;
1610 }