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