eebd54953ace9ab77b46ad85f97d7e479a2a8844
[platform/upstream/bash.git] / parse.y
1 /* parse.y - Yacc grammar for bash. */
2
3 /* Copyright (C) 1989-2009 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 %{
22 #include "config.h"
23
24 #include "bashtypes.h"
25 #include "bashansi.h"
26
27 #include "filecntl.h"
28
29 #if defined (HAVE_UNISTD_H)
30 #  include <unistd.h>
31 #endif
32
33 #if defined (HAVE_LOCALE_H)
34 #  include <locale.h>
35 #endif
36
37 #include <stdio.h>
38 #include "chartypes.h"
39 #include <signal.h>
40
41 #include "memalloc.h"
42
43 #include "bashintl.h"
44
45 #define NEED_STRFTIME_DECL      /* used in externs.h */
46
47 #include "shell.h"
48 #include "trap.h"
49 #include "flags.h"
50 #include "parser.h"
51 #include "mailcheck.h"
52 #include "test.h"
53 #include "builtins.h"
54 #include "builtins/common.h"
55 #include "builtins/builtext.h"
56
57 #include "shmbutil.h"
58
59 #if defined (READLINE)
60 #  include "bashline.h"
61 #  include <readline/readline.h>
62 #endif /* READLINE */
63
64 #if defined (HISTORY)
65 #  include "bashhist.h"
66 #  include <readline/history.h>
67 #endif /* HISTORY */
68
69 #if defined (JOB_CONTROL)
70 #  include "jobs.h"
71 #endif /* JOB_CONTROL */
72
73 #if defined (ALIAS)
74 #  include "alias.h"
75 #else
76 typedef void *alias_t;
77 #endif /* ALIAS */
78
79 #if defined (PROMPT_STRING_DECODE)
80 #  ifndef _MINIX
81 #    include <sys/param.h>
82 #  endif
83 #  include <time.h>
84 #  if defined (TM_IN_SYS_TIME)
85 #    include <sys/types.h>
86 #    include <sys/time.h>
87 #  endif /* TM_IN_SYS_TIME */
88 #  include "maxpath.h"
89 #endif /* PROMPT_STRING_DECODE */
90
91 #define RE_READ_TOKEN   -99
92 #define NO_EXPANSION    -100
93
94 #ifdef DEBUG
95 #  define YYDEBUG 1
96 #else
97 #  define YYDEBUG 0
98 #endif
99
100 #if defined (HANDLE_MULTIBYTE)
101 #  define last_shell_getc_is_singlebyte \
102         ((shell_input_line_index > 1) \
103                 ? shell_input_line_property[shell_input_line_index - 1] \
104                 : 1)
105 #  define MBTEST(x)     ((x) && last_shell_getc_is_singlebyte)
106 #else
107 #  define last_shell_getc_is_singlebyte 1
108 #  define MBTEST(x)     ((x))
109 #endif
110
111 #if defined (EXTENDED_GLOB)
112 extern int extended_glob;
113 #endif
114
115 extern int eof_encountered;
116 extern int no_line_editing, running_under_emacs;
117 extern int current_command_number;
118 extern int sourcelevel, parse_and_execute_level;
119 extern int posixly_correct;
120 extern int last_command_exit_value;
121 extern char *shell_name, *current_host_name;
122 extern char *dist_version;
123 extern int patch_level;
124 extern int dump_translatable_strings, dump_po_strings;
125 extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
126 #if defined (BUFFERED_INPUT)
127 extern int bash_input_fd_changed;
128 #endif
129
130 extern int errno;
131 /* **************************************************************** */
132 /*                                                                  */
133 /*                  "Forward" declarations                          */
134 /*                                                                  */
135 /* **************************************************************** */
136
137 #ifdef DEBUG
138 static void debug_parser __P((int));
139 #endif
140
141 static int yy_getc __P((void));
142 static int yy_ungetc __P((int));
143
144 #if defined (READLINE)
145 static int yy_readline_get __P((void));
146 static int yy_readline_unget __P((int));
147 #endif
148
149 static int yy_string_get __P((void));
150 static int yy_string_unget __P((int));
151 static void rewind_input_string __P((void));
152 static int yy_stream_get __P((void));
153 static int yy_stream_unget __P((int));
154
155 static int shell_getc __P((int));
156 static void shell_ungetc __P((int));
157 static void discard_until __P((int));
158
159 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
160 static void push_string __P((char *, int, alias_t *));
161 static void pop_string __P((void));
162 static void free_string_list __P((void));
163 #endif
164
165 static char *read_a_line __P((int));
166
167 static int reserved_word_acceptable __P((int));
168 static int yylex __P((void));
169 static int alias_expand_token __P((char *));
170 static int time_command_acceptable __P((void));
171 static int special_case_tokens __P((char *));
172 static int read_token __P((int));
173 static char *parse_matched_pair __P((int, int, int, int *, int));
174 static char *parse_comsub __P((int, int, int, int *, int));
175 #if defined (ARRAY_VARS)
176 static char *parse_compound_assignment __P((int *));
177 #endif
178 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
179 static int parse_dparen __P((int));
180 static int parse_arith_cmd __P((char **, int));
181 #endif
182 #if defined (COND_COMMAND)
183 static void cond_error __P((void));
184 static COND_COM *cond_expr __P((void));
185 static COND_COM *cond_or __P((void));
186 static COND_COM *cond_and __P((void));
187 static COND_COM *cond_term __P((void));
188 static int cond_skip_newlines __P((void));
189 static COMMAND *parse_cond_command __P((void));
190 #endif
191 #if defined (ARRAY_VARS)
192 static int token_is_assignment __P((char *, int));
193 static int token_is_ident __P((char *, int));
194 #endif
195 static int read_token_word __P((int));
196 static void discard_parser_constructs __P((int));
197
198 static char *error_token_from_token __P((int));
199 static char *error_token_from_text __P((void));
200 static void print_offending_line __P((void));
201 static void report_syntax_error __P((char *));
202
203 static void handle_eof_input_unit __P((void));
204 static void prompt_again __P((void));
205 #if 0
206 static void reset_readline_prompt __P((void));
207 #endif
208 static void print_prompt __P((void));
209
210 #if defined (HANDLE_MULTIBYTE)
211 static void set_line_mbstate __P((void));
212 static char *shell_input_line_property = NULL;
213 #else
214 #  define set_line_mbstate()
215 #endif
216
217 extern int yyerror __P((const char *));
218
219 #ifdef DEBUG
220 extern int yydebug;
221 #endif
222
223 /* Default prompt strings */
224 char *primary_prompt = PPROMPT;
225 char *secondary_prompt = SPROMPT;
226
227 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
228 char *ps1_prompt, *ps2_prompt;
229
230 /* Handle on the current prompt string.  Indirectly points through
231    ps1_ or ps2_prompt. */
232 char **prompt_string_pointer = (char **)NULL;
233 char *current_prompt_string;
234
235 /* Non-zero means we expand aliases in commands. */
236 int expand_aliases = 0;
237
238 /* If non-zero, the decoded prompt string undergoes parameter and
239    variable substitution, command substitution, arithmetic substitution,
240    string expansion, process substitution, and quote removal in
241    decode_prompt_string. */
242 int promptvars = 1;
243
244 /* If non-zero, $'...' and $"..." are expanded when they appear within
245    a ${...} expansion, even when the expansion appears within double
246    quotes. */
247 int extended_quote = 1;
248
249 /* The decoded prompt string.  Used if READLINE is not defined or if
250    editing is turned off.  Analogous to current_readline_prompt. */
251 static char *current_decoded_prompt;
252
253 /* The number of lines read from input while creating the current command. */
254 int current_command_line_count;
255
256 /* The token that currently denotes the end of parse. */
257 int shell_eof_token;
258
259 /* The token currently being read. */
260 int current_token;
261
262 /* Variables to manage the task of reading here documents, because we need to
263    defer the reading until after a complete command has been collected. */
264 static REDIRECT *redir_stack[10];
265 int need_here_doc;
266
267 /* Where shell input comes from.  History expansion is performed on each
268    line when the shell is interactive. */
269 static char *shell_input_line = (char *)NULL;
270 static int shell_input_line_index;
271 static int shell_input_line_size;       /* Amount allocated for shell_input_line. */
272 static int shell_input_line_len;        /* strlen (shell_input_line) */
273
274 /* Either zero or EOF. */
275 static int shell_input_line_terminator;
276
277 /* The line number in a script on which a function definition starts. */
278 static int function_dstart;
279
280 /* The line number in a script on which a function body starts. */
281 static int function_bstart;
282
283 /* The line number in a script at which an arithmetic for command starts. */
284 static int arith_for_lineno;
285
286 /* The current parser state. */
287 static int parser_state;
288
289 /* The last read token, or NULL.  read_token () uses this for context
290    checking. */
291 static int last_read_token;
292
293 /* The token read prior to last_read_token. */
294 static int token_before_that;
295
296 /* The token read prior to token_before_that. */
297 static int two_tokens_ago;
298
299 /* The line number in a script where the word in a `case WORD', `select WORD'
300    or `for WORD' begins.  This is a nested command maximum, since the array
301    index is decremented after a case, select, or for command is parsed. */
302 #define MAX_CASE_NEST   128
303 static int word_lineno[MAX_CASE_NEST];
304 static int word_top = -1;
305
306 /* If non-zero, it is the token that we want read_token to return
307    regardless of what text is (or isn't) present to be read.  This
308    is reset by read_token.  If token_to_read == WORD or
309    ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
310 static int token_to_read;
311 static WORD_DESC *word_desc_to_read;
312
313 static REDIRECTEE redir;
314 %}
315
316 %union {
317   WORD_DESC *word;              /* the word that we read. */
318   int number;                   /* the number that we read. */
319   WORD_LIST *word_list;
320   COMMAND *command;
321   REDIRECT *redirect;
322   ELEMENT element;
323   PATTERN_LIST *pattern;
324 }
325
326 /* Reserved words.  Members of the first group are only recognized
327    in the case that they are preceded by a list_terminator.  Members
328    of the second group are for [[...]] commands.  Members of the
329    third group are recognized only under special circumstances. */
330 %token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION COPROC
331 %token COND_START COND_END COND_ERROR
332 %token IN BANG TIME TIMEOPT
333
334 /* More general tokens. yylex () knows how to make these. */
335 %token <word> WORD ASSIGNMENT_WORD
336 %token <number> NUMBER
337 %token <word_list> ARITH_CMD ARITH_FOR_EXPRS
338 %token <command> COND_CMD
339 %token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND LESS_LESS_LESS
340 %token GREATER_AND SEMI_SEMI SEMI_AND SEMI_SEMI_AND
341 %token LESS_LESS_MINUS AND_GREATER AND_GREATER_GREATER LESS_GREATER
342 %token GREATER_BAR BAR_AND
343
344 /* The types that the various syntactical units return. */
345
346 %type <command> inputunit command pipeline pipeline_command
347 %type <command> list list0 list1 compound_list simple_list simple_list1
348 %type <command> simple_command shell_command
349 %type <command> for_command select_command case_command group_command
350 %type <command> arith_command
351 %type <command> cond_command
352 %type <command> arith_for_command
353 %type <command> coproc
354 %type <command> function_def function_body if_command elif_clause subshell
355 %type <redirect> redirection redirection_list
356 %type <element> simple_command_element
357 %type <word_list> word_list pattern
358 %type <pattern> pattern_list case_clause_sequence case_clause
359 %type <number> timespec
360 %type <number> list_terminator
361
362 %start inputunit
363
364 %left '&' ';' '\n' yacc_EOF
365 %left AND_AND OR_OR
366 %right '|' BAR_AND
367 %%
368
369 inputunit:      simple_list simple_list_terminator
370                         {
371                           /* Case of regular command.  Discard the error
372                              safety net,and return the command just parsed. */
373                           global_command = $1;
374                           eof_encountered = 0;
375                           /* discard_parser_constructs (0); */
376                           if (parser_state & PST_CMDSUBST)
377                             parser_state |= PST_EOFTOKEN;
378                           YYACCEPT;
379                         }
380         |       '\n'
381                         {
382                           /* Case of regular command, but not a very
383                              interesting one.  Return a NULL command. */
384                           global_command = (COMMAND *)NULL;
385                           if (parser_state & PST_CMDSUBST)
386                             parser_state |= PST_EOFTOKEN;
387                           YYACCEPT;
388                         }
389         |       error '\n'
390                         {
391                           /* Error during parsing.  Return NULL command. */
392                           global_command = (COMMAND *)NULL;
393                           eof_encountered = 0;
394                           /* discard_parser_constructs (1); */
395                           if (interactive && parse_and_execute_level == 0)
396                             {
397                               YYACCEPT;
398                             }
399                           else
400                             {
401                               YYABORT;
402                             }
403                         }
404         |       yacc_EOF
405                         {
406                           /* Case of EOF seen by itself.  Do ignoreeof or
407                              not. */
408                           global_command = (COMMAND *)NULL;
409                           handle_eof_input_unit ();
410                           YYACCEPT;
411                         }
412         ;
413
414 word_list:      WORD
415                         { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
416         |       word_list WORD
417                         { $$ = make_word_list ($2, $1); }
418         ;
419
420 redirection:    '>' WORD
421                         {
422                           redir.filename = $2;
423                           $$ = make_redirection (1, r_output_direction, redir);
424                         }
425         |       '<' WORD
426                         {
427                           redir.filename = $2;
428                           $$ = make_redirection (0, r_input_direction, redir);
429                         }
430         |       NUMBER '>' WORD
431                         {
432                           redir.filename = $3;
433                           $$ = make_redirection ($1, r_output_direction, redir);
434                         }
435         |       NUMBER '<' WORD
436                         {
437                           redir.filename = $3;
438                           $$ = make_redirection ($1, r_input_direction, redir);
439                         }
440         |       GREATER_GREATER WORD
441                         {
442                           redir.filename = $2;
443                           $$ = make_redirection (1, r_appending_to, redir);
444                         }
445         |       NUMBER GREATER_GREATER WORD
446                         {
447                           redir.filename = $3;
448                           $$ = make_redirection ($1, r_appending_to, redir);
449                         }
450         |       LESS_LESS WORD
451                         {
452                           redir.filename = $2;
453                           $$ = make_redirection (0, r_reading_until, redir);
454                           redir_stack[need_here_doc++] = $$;
455                         }
456         |       NUMBER LESS_LESS WORD
457                         {
458                           redir.filename = $3;
459                           $$ = make_redirection ($1, r_reading_until, redir);
460                           redir_stack[need_here_doc++] = $$;
461                         }
462         |       LESS_LESS_LESS WORD
463                         {
464                           redir.filename = $2;
465                           $$ = make_redirection (0, r_reading_string, redir);
466                         }
467         |       NUMBER LESS_LESS_LESS WORD
468                         {
469                           redir.filename = $3;
470                           $$ = make_redirection ($1, r_reading_string, redir);
471                         }
472         |       LESS_AND NUMBER
473                         {
474                           redir.dest = $2;
475                           $$ = make_redirection (0, r_duplicating_input, redir);
476                         }
477         |       NUMBER LESS_AND NUMBER
478                         {
479                           redir.dest = $3;
480                           $$ = make_redirection ($1, r_duplicating_input, redir);
481                         }
482         |       GREATER_AND NUMBER
483                         {
484                           redir.dest = $2;
485                           $$ = make_redirection (1, r_duplicating_output, redir);
486                         }
487         |       NUMBER GREATER_AND NUMBER
488                         {
489                           redir.dest = $3;
490                           $$ = make_redirection ($1, r_duplicating_output, redir);
491                         }
492         |       LESS_AND WORD
493                         {
494                           redir.filename = $2;
495                           $$ = make_redirection (0, r_duplicating_input_word, redir);
496                         }
497         |       NUMBER LESS_AND WORD
498                         {
499                           redir.filename = $3;
500                           $$ = make_redirection ($1, r_duplicating_input_word, redir);
501                         }
502         |       GREATER_AND WORD
503                         {
504                           redir.filename = $2;
505                           $$ = make_redirection (1, r_duplicating_output_word, redir);
506                         }
507         |       NUMBER GREATER_AND WORD
508                         {
509                           redir.filename = $3;
510                           $$ = make_redirection ($1, r_duplicating_output_word, redir);
511                         }
512         |       LESS_LESS_MINUS WORD
513                         {
514                           redir.filename = $2;
515                           $$ = make_redirection
516                             (0, r_deblank_reading_until, redir);
517                           redir_stack[need_here_doc++] = $$;
518                         }
519         |       NUMBER LESS_LESS_MINUS WORD
520                         {
521                           redir.filename = $3;
522                           $$ = make_redirection
523                             ($1, r_deblank_reading_until, redir);
524                           redir_stack[need_here_doc++] = $$;
525                         }
526         |       GREATER_AND '-'
527                         {
528                           redir.dest = 0;
529                           $$ = make_redirection (1, r_close_this, redir);
530                         }
531         |       NUMBER GREATER_AND '-'
532                         {
533                           redir.dest = 0;
534                           $$ = make_redirection ($1, r_close_this, redir);
535                         }
536         |       LESS_AND '-'
537                         {
538                           redir.dest = 0;
539                           $$ = make_redirection (0, r_close_this, redir);
540                         }
541         |       NUMBER LESS_AND '-'
542                         {
543                           redir.dest = 0;
544                           $$ = make_redirection ($1, r_close_this, redir);
545                         }
546         |       AND_GREATER WORD
547                         {
548                           redir.filename = $2;
549                           $$ = make_redirection (1, r_err_and_out, redir);
550                         }
551         |       AND_GREATER_GREATER WORD
552                         {
553                           redir.filename = $2;
554                           $$ = make_redirection (1, r_append_err_and_out, redir);
555                         }
556         |       NUMBER LESS_GREATER WORD
557                         {
558                           redir.filename = $3;
559                           $$ = make_redirection ($1, r_input_output, redir);
560                         }
561         |       LESS_GREATER WORD
562                         {
563                           redir.filename = $2;
564                           $$ = make_redirection (0, r_input_output, redir);
565                         }
566         |       GREATER_BAR WORD
567                         {
568                           redir.filename = $2;
569                           $$ = make_redirection (1, r_output_force, redir);
570                         }
571         |       NUMBER GREATER_BAR WORD
572                         {
573                           redir.filename = $3;
574                           $$ = make_redirection ($1, r_output_force, redir);
575                         }
576         ;
577
578 simple_command_element: WORD
579                         { $$.word = $1; $$.redirect = 0; }
580         |       ASSIGNMENT_WORD
581                         { $$.word = $1; $$.redirect = 0; }
582         |       redirection
583                         { $$.redirect = $1; $$.word = 0; }
584         ;
585
586 redirection_list: redirection
587                         {
588                           $$ = $1;
589                         }
590         |       redirection_list redirection
591                         {
592                           register REDIRECT *t;
593
594                           for (t = $1; t->next; t = t->next)
595                             ;
596                           t->next = $2;
597                           $$ = $1;
598                         }
599         ;
600
601 simple_command: simple_command_element
602                         { $$ = make_simple_command ($1, (COMMAND *)NULL); }
603         |       simple_command simple_command_element
604                         { $$ = make_simple_command ($2, $1); }
605         ;
606
607 command:        simple_command
608                         { $$ = clean_simple_command ($1); }
609         |       shell_command
610                         { $$ = $1; }
611         |       shell_command redirection_list
612                         {
613                           COMMAND *tc;
614
615                           tc = $1;
616                           if (tc->redirects)
617                             {
618                               register REDIRECT *t;
619                               for (t = tc->redirects; t->next; t = t->next)
620                                 ;
621                               t->next = $2;
622                             }
623                           else
624                             tc->redirects = $2;
625                           $$ = $1;
626                         }
627         |       function_def
628                         { $$ = $1; }
629         |       coproc
630                         { $$ = $1; }
631         ;
632
633 shell_command:  for_command
634                         { $$ = $1; }
635         |       case_command
636                         { $$ = $1; }
637         |       WHILE compound_list DO compound_list DONE
638                         { $$ = make_while_command ($2, $4); }
639         |       UNTIL compound_list DO compound_list DONE
640                         { $$ = make_until_command ($2, $4); }
641         |       select_command
642                         { $$ = $1; }
643         |       if_command
644                         { $$ = $1; }
645         |       subshell
646                         { $$ = $1; }
647         |       group_command
648                         { $$ = $1; }
649         |       arith_command
650                         { $$ = $1; }
651         |       cond_command
652                         { $$ = $1; }
653         |       arith_for_command
654                         { $$ = $1; }
655         ;
656
657 for_command:    FOR WORD newline_list DO compound_list DONE
658                         {
659                           $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
660                           if (word_top > 0) word_top--;
661                         }
662         |       FOR WORD newline_list '{' compound_list '}'
663                         {
664                           $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
665                           if (word_top > 0) word_top--;
666                         }
667         |       FOR WORD ';' newline_list DO compound_list DONE
668                         {
669                           $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
670                           if (word_top > 0) word_top--;
671                         }
672         |       FOR WORD ';' newline_list '{' compound_list '}'
673                         {
674                           $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
675                           if (word_top > 0) word_top--;
676                         }
677         |       FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
678                         {
679                           $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
680                           if (word_top > 0) word_top--;
681                         }
682         |       FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
683                         {
684                           $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
685                           if (word_top > 0) word_top--;
686                         }
687         |       FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE
688                         {
689                           $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
690                           if (word_top > 0) word_top--;
691                         }
692         |       FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}'
693                         {
694                           $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
695                           if (word_top > 0) word_top--;
696                         }
697         ;
698
699 arith_for_command:      FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE
700                                 {
701                                   $$ = make_arith_for_command ($2, $6, arith_for_lineno);
702                                   if (word_top > 0) word_top--;
703                                 }
704         |               FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'
705                                 {
706                                   $$ = make_arith_for_command ($2, $6, arith_for_lineno);
707                                   if (word_top > 0) word_top--;
708                                 }
709         |               FOR ARITH_FOR_EXPRS DO compound_list DONE
710                                 {
711                                   $$ = make_arith_for_command ($2, $4, arith_for_lineno);
712                                   if (word_top > 0) word_top--;
713                                 }
714         |               FOR ARITH_FOR_EXPRS '{' compound_list '}'
715                                 {
716                                   $$ = make_arith_for_command ($2, $4, arith_for_lineno);
717                                   if (word_top > 0) word_top--;
718                                 }
719         ;
720
721 select_command: SELECT WORD newline_list DO list DONE
722                         {
723                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
724                           if (word_top > 0) word_top--;
725                         }
726         |       SELECT WORD newline_list '{' list '}'
727                         {
728                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
729                           if (word_top > 0) word_top--;
730                         }
731         |       SELECT WORD ';' newline_list DO list DONE
732                         {
733                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
734                           if (word_top > 0) word_top--;
735                         }
736         |       SELECT WORD ';' newline_list '{' list '}'
737                         {
738                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
739                           if (word_top > 0) word_top--;
740                         }
741         |       SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
742                         {
743                           $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
744                           if (word_top > 0) word_top--;
745                         }
746         |       SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
747                         {
748                           $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
749                           if (word_top > 0) word_top--;
750                         }
751         ;
752
753 case_command:   CASE WORD newline_list IN newline_list ESAC
754                         {
755                           $$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]);
756                           if (word_top > 0) word_top--;
757                         }
758         |       CASE WORD newline_list IN case_clause_sequence newline_list ESAC
759                         {
760                           $$ = make_case_command ($2, $5, word_lineno[word_top]);
761                           if (word_top > 0) word_top--;
762                         }
763         |       CASE WORD newline_list IN case_clause ESAC
764                         {
765                           $$ = make_case_command ($2, $5, word_lineno[word_top]);
766                           if (word_top > 0) word_top--;
767                         }
768         ;
769
770 function_def:   WORD '(' ')' newline_list function_body
771                         { $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
772
773         |       FUNCTION WORD '(' ')' newline_list function_body
774                         { $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
775
776         |       FUNCTION WORD newline_list function_body
777                         { $$ = make_function_def ($2, $4, function_dstart, function_bstart); }
778         ;
779
780 function_body:  shell_command
781                         { $$ = $1; }
782         |       shell_command redirection_list
783                         {
784                           COMMAND *tc;
785
786                           tc = $1;
787                           /* According to Posix.2 3.9.5, redirections
788                              specified after the body of a function should
789                              be attached to the function and performed when
790                              the function is executed, not as part of the
791                              function definition command. */
792                           /* XXX - I don't think it matters, but we might
793                              want to change this in the future to avoid
794                              problems differentiating between a function
795                              definition with a redirection and a function
796                              definition containing a single command with a
797                              redirection.  The two are semantically equivalent,
798                              though -- the only difference is in how the
799                              command printing code displays the redirections. */
800                           if (tc->redirects)
801                             {
802                               register REDIRECT *t;
803                               for (t = tc->redirects; t->next; t = t->next)
804                                 ;
805                               t->next = $2;
806                             }
807                           else
808                             tc->redirects = $2;
809                           $$ = $1;
810                         }
811         ;
812
813 subshell:       '(' compound_list ')'
814                         {
815                           $$ = make_subshell_command ($2);
816                           $$->flags |= CMD_WANT_SUBSHELL;
817                         }
818         ;
819
820 coproc:         COPROC shell_command
821                         {
822                           $$ = make_coproc_command ("COPROC", $2);
823                           $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
824                         }
825         |       COPROC shell_command redirection_list
826                         {
827                           COMMAND *tc;
828
829                           tc = $2;
830                           if (tc->redirects)
831                             {
832                               register REDIRECT *t;
833                               for (t = tc->redirects; t->next; t = t->next)
834                                 ;
835                               t->next = $3;
836                             }
837                           else
838                             tc->redirects = $3;
839                           $$ = make_coproc_command ("COPROC", $2);
840                           $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
841                         }
842         |       COPROC WORD shell_command
843                         {
844                           $$ = make_coproc_command ($2->word, $3);
845                           $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
846                         }
847         |       COPROC WORD shell_command redirection_list
848                         {
849                           COMMAND *tc;
850
851                           tc = $3;
852                           if (tc->redirects)
853                             {
854                               register REDIRECT *t;
855                               for (t = tc->redirects; t->next; t = t->next)
856                                 ;
857                               t->next = $4;
858                             }
859                           else
860                             tc->redirects = $4;
861                           $$ = make_coproc_command ($2->word, $3);
862                           $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
863                         }
864         |       COPROC simple_command
865                         {
866                           $$ = make_coproc_command ("COPROC", clean_simple_command ($2));
867                           $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
868                         }
869         ;
870
871 if_command:     IF compound_list THEN compound_list FI
872                         { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
873         |       IF compound_list THEN compound_list ELSE compound_list FI
874                         { $$ = make_if_command ($2, $4, $6); }
875         |       IF compound_list THEN compound_list elif_clause FI
876                         { $$ = make_if_command ($2, $4, $5); }
877         ;
878
879
880 group_command:  '{' compound_list '}'
881                         { $$ = make_group_command ($2); }
882         ;
883
884 arith_command:  ARITH_CMD
885                         { $$ = make_arith_command ($1); }
886         ;
887
888 cond_command:   COND_START COND_CMD COND_END
889                         { $$ = $2; }
890         ; 
891
892 elif_clause:    ELIF compound_list THEN compound_list
893                         { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
894         |       ELIF compound_list THEN compound_list ELSE compound_list
895                         { $$ = make_if_command ($2, $4, $6); }
896         |       ELIF compound_list THEN compound_list elif_clause
897                         { $$ = make_if_command ($2, $4, $5); }
898         ;
899
900 case_clause:    pattern_list
901         |       case_clause_sequence pattern_list
902                         { $2->next = $1; $$ = $2; }
903         ;
904
905 pattern_list:   newline_list pattern ')' compound_list
906                         { $$ = make_pattern_list ($2, $4); }
907         |       newline_list pattern ')' newline_list
908                         { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
909         |       newline_list '(' pattern ')' compound_list
910                         { $$ = make_pattern_list ($3, $5); }
911         |       newline_list '(' pattern ')' newline_list
912                         { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
913         ;
914
915 case_clause_sequence:  pattern_list SEMI_SEMI
916                         { $$ = $1; }
917         |       case_clause_sequence pattern_list SEMI_SEMI
918                         { $2->next = $1; $$ = $2; }
919         |       pattern_list SEMI_AND
920                         { $1->flags |= CASEPAT_FALLTHROUGH; $$ = $1; }
921         |       case_clause_sequence pattern_list SEMI_AND
922                         { $2->flags |= CASEPAT_FALLTHROUGH; $2->next = $1; $$ = $2; }
923         |       pattern_list SEMI_SEMI_AND
924                         { $1->flags |= CASEPAT_TESTNEXT; $$ = $1; }
925         |       case_clause_sequence pattern_list SEMI_SEMI_AND
926                         { $2->flags |= CASEPAT_TESTNEXT; $2->next = $1; $$ = $2; }      
927         ;
928
929 pattern:        WORD
930                         { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
931         |       pattern '|' WORD
932                         { $$ = make_word_list ($3, $1); }
933         ;
934
935 /* A list allows leading or trailing newlines and
936    newlines as operators (equivalent to semicolons).
937    It must end with a newline or semicolon.
938    Lists are used within commands such as if, for, while.  */
939
940 list:           newline_list list0
941                         {
942                           $$ = $2;
943                           if (need_here_doc)
944                             gather_here_documents ();
945                          }
946         ;
947
948 compound_list:  list
949         |       newline_list list1
950                         {
951                           $$ = $2;
952                         }
953         ;
954
955 list0:          list1 '\n' newline_list
956         |       list1 '&' newline_list
957                         {
958                           if ($1->type == cm_connection)
959                             $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
960                           else
961                             $$ = command_connect ($1, (COMMAND *)NULL, '&');
962                         }
963         |       list1 ';' newline_list
964
965         ;
966
967 list1:          list1 AND_AND newline_list list1
968                         { $$ = command_connect ($1, $4, AND_AND); }
969         |       list1 OR_OR newline_list list1
970                         { $$ = command_connect ($1, $4, OR_OR); }
971         |       list1 '&' newline_list list1
972                         {
973                           if ($1->type == cm_connection)
974                             $$ = connect_async_list ($1, $4, '&');
975                           else
976                             $$ = command_connect ($1, $4, '&');
977                         }
978         |       list1 ';' newline_list list1
979                         { $$ = command_connect ($1, $4, ';'); }
980         |       list1 '\n' newline_list list1
981                         { $$ = command_connect ($1, $4, ';'); }
982         |       pipeline_command
983                         { $$ = $1; }
984         ;
985
986 simple_list_terminator: '\n'
987         |       yacc_EOF
988         ;
989
990 list_terminator:'\n'
991                 { $$ = '\n'; }
992         |       ';'
993                 { $$ = ';'; }
994         |       yacc_EOF
995                 { $$ = yacc_EOF; }
996         ;
997
998 newline_list:
999         |       newline_list '\n'
1000         ;
1001
1002 /* A simple_list is a list that contains no significant newlines
1003    and no leading or trailing newlines.  Newlines are allowed
1004    only following operators, where they are not significant.
1005
1006    This is what an inputunit consists of.  */
1007
1008 simple_list:    simple_list1
1009                         {
1010                           $$ = $1;
1011                           if (need_here_doc)
1012                             gather_here_documents ();
1013                           if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1014                             {
1015                               global_command = $1;
1016                               eof_encountered = 0;
1017                               rewind_input_string ();
1018                               YYACCEPT;
1019                             }
1020                         }
1021         |       simple_list1 '&'
1022                         {
1023                           if ($1->type == cm_connection)
1024                             $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
1025                           else
1026                             $$ = command_connect ($1, (COMMAND *)NULL, '&');
1027                           if (need_here_doc)
1028                             gather_here_documents ();
1029                           if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1030                             {
1031                               global_command = $1;
1032                               eof_encountered = 0;
1033                               rewind_input_string ();
1034                               YYACCEPT;
1035                             }
1036                         }
1037         |       simple_list1 ';'
1038                         {
1039                           $$ = $1;
1040                           if (need_here_doc)
1041                             gather_here_documents ();
1042                           if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1043                             {
1044                               global_command = $1;
1045                               eof_encountered = 0;
1046                               rewind_input_string ();
1047                               YYACCEPT;
1048                             }
1049                         }
1050         ;
1051
1052 simple_list1:   simple_list1 AND_AND newline_list simple_list1
1053                         { $$ = command_connect ($1, $4, AND_AND); }
1054         |       simple_list1 OR_OR newline_list simple_list1
1055                         { $$ = command_connect ($1, $4, OR_OR); }
1056         |       simple_list1 '&' simple_list1
1057                         {
1058                           if ($1->type == cm_connection)
1059                             $$ = connect_async_list ($1, $3, '&');
1060                           else
1061                             $$ = command_connect ($1, $3, '&');
1062                         }
1063         |       simple_list1 ';' simple_list1
1064                         { $$ = command_connect ($1, $3, ';'); }
1065
1066         |       pipeline_command
1067                         { $$ = $1; }
1068         ;
1069
1070 pipeline_command: pipeline
1071                         { $$ = $1; }
1072         |       BANG pipeline
1073                         {
1074                           if ($2)
1075                             $2->flags |= CMD_INVERT_RETURN;
1076                           $$ = $2;
1077                         }
1078         |       timespec pipeline
1079                         {
1080                           if ($2)
1081                             $2->flags |= $1;
1082                           $$ = $2;
1083                         }
1084         |       timespec BANG pipeline
1085                         {
1086                           if ($3)
1087                             $3->flags |= $1|CMD_INVERT_RETURN;
1088                           $$ = $3;
1089                         }
1090         |       BANG timespec pipeline
1091                         {
1092                           if ($3)
1093                             $3->flags |= $2|CMD_INVERT_RETURN;
1094                           $$ = $3;
1095                         }
1096         |       timespec list_terminator
1097                         {
1098                           ELEMENT x;
1099
1100                           /* Boy, this is unclean.  `time' by itself can
1101                              time a null command.  We cheat and push a
1102                              newline back if the list_terminator was a newline
1103                              to avoid the double-newline problem (one to
1104                              terminate this, one to terminate the command) */
1105                           x.word = 0;
1106                           x.redirect = 0;
1107                           $$ = make_simple_command (x, (COMMAND *)NULL);
1108                           $$->flags |= $1;
1109                           /* XXX - let's cheat and push a newline back */
1110                           if ($2 == '\n')
1111                             token_to_read = '\n';
1112                         }
1113                         
1114         ;
1115
1116 pipeline:       pipeline '|' newline_list pipeline
1117                         { $$ = command_connect ($1, $4, '|'); }
1118         |       pipeline BAR_AND newline_list pipeline
1119                         {
1120                           /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
1121                           COMMAND *tc;
1122                           REDIRECTEE rd;
1123                           REDIRECT *r;
1124
1125                           tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
1126                           rd.dest = 1;
1127                           r = make_redirection (2, r_duplicating_output, rd);
1128                           if (tc->redirects)
1129                             {
1130                               register REDIRECT *t;
1131                               for (t = tc->redirects; t->next; t = t->next)
1132                                 ;
1133                               t->next = r;
1134                             }
1135                           else
1136                             tc->redirects = r;
1137
1138                           $$ = command_connect ($1, $4, '|');
1139                         }
1140         |       command
1141                         { $$ = $1; }
1142         ;
1143
1144 timespec:       TIME
1145                         { $$ = CMD_TIME_PIPELINE; }
1146         |       TIME TIMEOPT
1147                         { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
1148         ;
1149 %%
1150
1151 /* Initial size to allocate for tokens, and the
1152    amount to grow them by. */
1153 #define TOKEN_DEFAULT_INITIAL_SIZE 496
1154 #define TOKEN_DEFAULT_GROW_SIZE 512
1155
1156 /* Should we call prompt_again? */
1157 #define SHOULD_PROMPT() \
1158   (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
1159
1160 #if defined (ALIAS)
1161 #  define expanding_alias() (pushed_string_list && pushed_string_list->expander)
1162 #else
1163 #  define expanding_alias() 0
1164 #endif
1165
1166 /* Global var is non-zero when end of file has been reached. */
1167 int EOF_Reached = 0;
1168
1169 #ifdef DEBUG
1170 static void
1171 debug_parser (i)
1172      int i;
1173 {
1174 #if YYDEBUG != 0
1175   yydebug = i;
1176 #endif
1177 }
1178 #endif
1179
1180 /* yy_getc () returns the next available character from input or EOF.
1181    yy_ungetc (c) makes `c' the next character to read.
1182    init_yy_io (get, unget, type, location) makes the function GET the
1183    installed function for getting the next character, makes UNGET the
1184    installed function for un-getting a character, sets the type of stream
1185    (either string or file) from TYPE, and makes LOCATION point to where
1186    the input is coming from. */
1187
1188 /* Unconditionally returns end-of-file. */
1189 int
1190 return_EOF ()
1191 {
1192   return (EOF);
1193 }
1194
1195 /* Variable containing the current get and unget functions.
1196    See ./input.h for a clearer description. */
1197 BASH_INPUT bash_input;
1198
1199 /* Set all of the fields in BASH_INPUT to NULL.  Free bash_input.name if it
1200    is non-null, avoiding a memory leak. */
1201 void
1202 initialize_bash_input ()
1203 {
1204   bash_input.type = st_none;
1205   FREE (bash_input.name);
1206   bash_input.name = (char *)NULL;
1207   bash_input.location.file = (FILE *)NULL;
1208   bash_input.location.string = (char *)NULL;
1209   bash_input.getter = (sh_cget_func_t *)NULL;
1210   bash_input.ungetter = (sh_cunget_func_t *)NULL;
1211 }
1212
1213 /* Set the contents of the current bash input stream from
1214    GET, UNGET, TYPE, NAME, and LOCATION. */
1215 void
1216 init_yy_io (get, unget, type, name, location)
1217      sh_cget_func_t *get;
1218      sh_cunget_func_t *unget;
1219      enum stream_type type;
1220      const char *name;
1221      INPUT_STREAM location;
1222 {
1223   bash_input.type = type;
1224   FREE (bash_input.name);
1225   bash_input.name = name ? savestring (name) : (char *)NULL;
1226
1227   /* XXX */
1228 #if defined (CRAY)
1229   memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
1230 #else
1231   bash_input.location = location;
1232 #endif
1233   bash_input.getter = get;
1234   bash_input.ungetter = unget;
1235 }
1236
1237 char *
1238 yy_input_name ()
1239 {
1240   return (bash_input.name ? bash_input.name : "stdin");
1241 }
1242
1243 /* Call this to get the next character of input. */
1244 static int
1245 yy_getc ()
1246 {
1247   return (*(bash_input.getter)) ();
1248 }
1249
1250 /* Call this to unget C.  That is, to make C the next character
1251    to be read. */
1252 static int
1253 yy_ungetc (c)
1254      int c;
1255 {
1256   return (*(bash_input.ungetter)) (c);
1257 }
1258
1259 #if defined (BUFFERED_INPUT)
1260 #ifdef INCLUDE_UNUSED
1261 int
1262 input_file_descriptor ()
1263 {
1264   switch (bash_input.type)
1265     {
1266     case st_stream:
1267       return (fileno (bash_input.location.file));
1268     case st_bstream:
1269       return (bash_input.location.buffered_fd);
1270     case st_stdin:
1271     default:
1272       return (fileno (stdin));
1273     }
1274 }
1275 #endif
1276 #endif /* BUFFERED_INPUT */
1277
1278 /* **************************************************************** */
1279 /*                                                                  */
1280 /*                Let input be read from readline ().               */
1281 /*                                                                  */
1282 /* **************************************************************** */
1283
1284 #if defined (READLINE)
1285 char *current_readline_prompt = (char *)NULL;
1286 char *current_readline_line = (char *)NULL;
1287 int current_readline_line_index = 0;
1288
1289 static int
1290 yy_readline_get ()
1291 {
1292   SigHandler *old_sigint;
1293   int line_len;
1294   unsigned char c;
1295
1296   if (!current_readline_line)
1297     {
1298       if (!bash_readline_initialized)
1299         initialize_readline ();
1300
1301 #if defined (JOB_CONTROL)
1302       if (job_control)
1303         give_terminal_to (shell_pgrp, 0);
1304 #endif /* JOB_CONTROL */
1305
1306       old_sigint = (SigHandler *)NULL;
1307       if (signal_is_ignored (SIGINT) == 0)
1308         {
1309           old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
1310           interrupt_immediately++;
1311         }
1312       terminate_immediately = 1;
1313
1314       current_readline_line = readline (current_readline_prompt ?
1315                                           current_readline_prompt : "");
1316
1317       terminate_immediately = 0;
1318       if (signal_is_ignored (SIGINT) == 0 && old_sigint)
1319         {
1320           interrupt_immediately--;
1321           set_signal_handler (SIGINT, old_sigint);
1322         }
1323
1324 #if 0
1325       /* Reset the prompt to the decoded value of prompt_string_pointer. */
1326       reset_readline_prompt ();
1327 #endif
1328
1329       if (current_readline_line == 0)
1330         return (EOF);
1331
1332       current_readline_line_index = 0;
1333       line_len = strlen (current_readline_line);
1334
1335       current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
1336       current_readline_line[line_len++] = '\n';
1337       current_readline_line[line_len] = '\0';
1338     }
1339
1340   if (current_readline_line[current_readline_line_index] == 0)
1341     {
1342       free (current_readline_line);
1343       current_readline_line = (char *)NULL;
1344       return (yy_readline_get ());
1345     }
1346   else
1347     {
1348       c = current_readline_line[current_readline_line_index++];
1349       return (c);
1350     }
1351 }
1352
1353 static int
1354 yy_readline_unget (c)
1355      int c;
1356 {
1357   if (current_readline_line_index && current_readline_line)
1358     current_readline_line[--current_readline_line_index] = c;
1359   return (c);
1360 }
1361
1362 void
1363 with_input_from_stdin ()
1364 {
1365   INPUT_STREAM location;
1366
1367   if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
1368     {
1369       location.string = current_readline_line;
1370       init_yy_io (yy_readline_get, yy_readline_unget,
1371                   st_stdin, "readline stdin", location);
1372     }
1373 }
1374
1375 #else  /* !READLINE */
1376
1377 void
1378 with_input_from_stdin ()
1379 {
1380   with_input_from_stream (stdin, "stdin");
1381 }
1382 #endif  /* !READLINE */
1383
1384 /* **************************************************************** */
1385 /*                                                                  */
1386 /*   Let input come from STRING.  STRING is zero terminated.        */
1387 /*                                                                  */
1388 /* **************************************************************** */
1389
1390 static int
1391 yy_string_get ()
1392 {
1393   register char *string;
1394   register unsigned char c;
1395
1396   string = bash_input.location.string;
1397
1398   /* If the string doesn't exist, or is empty, EOF found. */
1399   if (string && *string)
1400     {
1401       c = *string++;
1402       bash_input.location.string = string;
1403       return (c);
1404     }
1405   else
1406     return (EOF);
1407 }
1408
1409 static int
1410 yy_string_unget (c)
1411      int c;
1412 {
1413   *(--bash_input.location.string) = c;
1414   return (c);
1415 }
1416
1417 void
1418 with_input_from_string (string, name)
1419      char *string;
1420      const char *name;
1421 {
1422   INPUT_STREAM location;
1423
1424   location.string = string;
1425   init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1426 }
1427
1428 /* Count the number of characters we've consumed from bash_input.location.string
1429    and read into shell_input_line, but have not returned from shell_getc.
1430    That is the true input location.  Rewind bash_input.location.string by
1431    that number of characters, so it points to the last character actually
1432    consumed by the parser. */
1433 static void
1434 rewind_input_string ()
1435 {
1436   int xchars;
1437
1438   /* number of unconsumed characters in the input -- XXX need to take newlines
1439      into account, e.g., $(...\n) */
1440   xchars = shell_input_line_len - shell_input_line_index;
1441   if (bash_input.location.string[-1] == '\n')
1442     xchars++;
1443
1444   /* XXX - how to reflect bash_input.location.string back to string passed to
1445      parse_and_execute or xparse_dolparen?  xparse_dolparen needs to know how
1446      far into the string we parsed.  parse_and_execute knows where bash_input.
1447      location.string is, and how far from orig_string that is -- that's the
1448      number of characters the command consumed. */
1449
1450   /* bash_input.location.string - xchars should be where we parsed to */
1451   /* need to do more validation on xchars value for sanity -- test cases. */
1452   bash_input.location.string -= xchars;
1453 }
1454
1455 /* **************************************************************** */
1456 /*                                                                  */
1457 /*                   Let input come from STREAM.                    */
1458 /*                                                                  */
1459 /* **************************************************************** */
1460
1461 /* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
1462    define, and just use getc/ungetc if it was defined, but since bash
1463    installs its signal handlers without the SA_RESTART flag, some signals
1464    (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
1465    the read to be restarted.  We need to restart it ourselves. */
1466
1467 static int
1468 yy_stream_get ()
1469 {
1470   int result;
1471
1472   result = EOF;
1473   if (bash_input.location.file)
1474     {
1475       if (interactive)
1476         {
1477           interrupt_immediately++;
1478           terminate_immediately++;
1479         }
1480       result = getc_with_restart (bash_input.location.file);
1481       if (interactive)
1482         {
1483           interrupt_immediately--;
1484           terminate_immediately--;
1485         }
1486     }
1487   return (result);
1488 }
1489
1490 static int
1491 yy_stream_unget (c)
1492      int c;
1493 {
1494   return (ungetc_with_restart (c, bash_input.location.file));
1495 }
1496
1497 void
1498 with_input_from_stream (stream, name)
1499      FILE *stream;
1500      const char *name;
1501 {
1502   INPUT_STREAM location;
1503
1504   location.file = stream;
1505   init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1506 }
1507
1508 typedef struct stream_saver {
1509   struct stream_saver *next;
1510   BASH_INPUT bash_input;
1511   int line;
1512 #if defined (BUFFERED_INPUT)
1513   BUFFERED_STREAM *bstream;
1514 #endif /* BUFFERED_INPUT */
1515 } STREAM_SAVER;
1516
1517 /* The globally known line number. */
1518 int line_number = 0;
1519
1520 #if defined (COND_COMMAND)
1521 static int cond_lineno;
1522 static int cond_token;
1523 #endif
1524
1525 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1526
1527 void
1528 push_stream (reset_lineno)
1529      int reset_lineno;
1530 {
1531   STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1532
1533   xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1534
1535 #if defined (BUFFERED_INPUT)
1536   saver->bstream = (BUFFERED_STREAM *)NULL;
1537   /* If we have a buffered stream, clear out buffers[fd]. */
1538   if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1539     saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1540                                           (BUFFERED_STREAM *)NULL);
1541 #endif /* BUFFERED_INPUT */
1542
1543   saver->line = line_number;
1544   bash_input.name = (char *)NULL;
1545   saver->next = stream_list;
1546   stream_list = saver;
1547   EOF_Reached = 0;
1548   if (reset_lineno)
1549     line_number = 0;
1550 }
1551
1552 void
1553 pop_stream ()
1554 {
1555   if (!stream_list)
1556     EOF_Reached = 1;
1557   else
1558     {
1559       STREAM_SAVER *saver = stream_list;
1560
1561       EOF_Reached = 0;
1562       stream_list = stream_list->next;
1563
1564       init_yy_io (saver->bash_input.getter,
1565                   saver->bash_input.ungetter,
1566                   saver->bash_input.type,
1567                   saver->bash_input.name,
1568                   saver->bash_input.location);
1569
1570 #if defined (BUFFERED_INPUT)
1571       /* If we have a buffered stream, restore buffers[fd]. */
1572       /* If the input file descriptor was changed while this was on the
1573          save stack, update the buffered fd to the new file descriptor and
1574          re-establish the buffer <-> bash_input fd correspondence. */
1575       if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1576         {
1577           if (bash_input_fd_changed)
1578             {
1579               bash_input_fd_changed = 0;
1580               if (default_buffered_input >= 0)
1581                 {
1582                   bash_input.location.buffered_fd = default_buffered_input;
1583                   saver->bstream->b_fd = default_buffered_input;
1584                   SET_CLOSE_ON_EXEC (default_buffered_input);
1585                 }
1586             }
1587           /* XXX could free buffered stream returned as result here. */
1588           set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
1589         }
1590 #endif /* BUFFERED_INPUT */
1591
1592       line_number = saver->line;
1593
1594       FREE (saver->bash_input.name);
1595       free (saver);
1596     }
1597 }
1598
1599 /* Return 1 if a stream of type TYPE is saved on the stack. */
1600 int
1601 stream_on_stack (type)
1602      enum stream_type type;
1603 {
1604   register STREAM_SAVER *s;
1605
1606   for (s = stream_list; s; s = s->next)
1607     if (s->bash_input.type == type)
1608       return 1;
1609   return 0;
1610 }
1611
1612 /* Save the current token state and return it in a malloced array. */
1613 int *
1614 save_token_state ()
1615 {
1616   int *ret;
1617
1618   ret = (int *)xmalloc (4 * sizeof (int));
1619   ret[0] = last_read_token;
1620   ret[1] = token_before_that;
1621   ret[2] = two_tokens_ago;
1622   ret[3] = current_token;
1623   return ret;
1624 }
1625
1626 void
1627 restore_token_state (ts)
1628      int *ts;
1629 {
1630   if (ts == 0)
1631     return;
1632   last_read_token = ts[0];
1633   token_before_that = ts[1];
1634   two_tokens_ago = ts[2];
1635   current_token = ts[3];
1636 }
1637
1638 /*
1639  * This is used to inhibit alias expansion and reserved word recognition
1640  * inside case statement pattern lists.  A `case statement pattern list' is:
1641  *
1642  *      everything between the `in' in a `case word in' and the next ')'
1643  *      or `esac'
1644  *      everything between a `;;' and the next `)' or `esac'
1645  */
1646
1647 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1648
1649 #define END_OF_ALIAS 0
1650
1651 /*
1652  * Pseudo-global variables used in implementing token-wise alias expansion.
1653  */
1654
1655 /*
1656  * Pushing and popping strings.  This works together with shell_getc to
1657  * implement alias expansion on a per-token basis.
1658  */
1659
1660 typedef struct string_saver {
1661   struct string_saver *next;
1662   int expand_alias;  /* Value to set expand_alias to when string is popped. */
1663   char *saved_line;
1664 #if defined (ALIAS)
1665   alias_t *expander;   /* alias that caused this line to be pushed. */
1666 #endif
1667   int saved_line_size, saved_line_index, saved_line_terminator;
1668 } STRING_SAVER;
1669
1670 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1671
1672 /*
1673  * Push the current shell_input_line onto a stack of such lines and make S
1674  * the current input.  Used when expanding aliases.  EXPAND is used to set
1675  * the value of expand_next_token when the string is popped, so that the
1676  * word after the alias in the original line is handled correctly when the
1677  * alias expands to multiple words.  TOKEN is the token that was expanded
1678  * into S; it is saved and used to prevent infinite recursive expansion.
1679  */
1680 static void
1681 push_string (s, expand, ap)
1682      char *s;
1683      int expand;
1684      alias_t *ap;
1685 {
1686   STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
1687
1688   temp->expand_alias = expand;
1689   temp->saved_line = shell_input_line;
1690   temp->saved_line_size = shell_input_line_size;
1691   temp->saved_line_index = shell_input_line_index;
1692   temp->saved_line_terminator = shell_input_line_terminator;
1693 #if defined (ALIAS)
1694   temp->expander = ap;
1695 #endif
1696   temp->next = pushed_string_list;
1697   pushed_string_list = temp;
1698
1699 #if defined (ALIAS)
1700   if (ap)
1701     ap->flags |= AL_BEINGEXPANDED;
1702 #endif
1703
1704   shell_input_line = s;
1705   shell_input_line_size = strlen (s);
1706   shell_input_line_index = 0;
1707   shell_input_line_terminator = '\0';
1708 #if 0
1709   parser_state &= ~PST_ALEXPNEXT;       /* XXX */
1710 #endif
1711
1712   set_line_mbstate ();
1713 }
1714
1715 /*
1716  * Make the top of the pushed_string stack be the current shell input.
1717  * Only called when there is something on the stack.  Called from shell_getc
1718  * when it thinks it has consumed the string generated by an alias expansion
1719  * and needs to return to the original input line.
1720  */
1721 static void
1722 pop_string ()
1723 {
1724   STRING_SAVER *t;
1725
1726   FREE (shell_input_line);
1727   shell_input_line = pushed_string_list->saved_line;
1728   shell_input_line_index = pushed_string_list->saved_line_index;
1729   shell_input_line_size = pushed_string_list->saved_line_size;
1730   shell_input_line_terminator = pushed_string_list->saved_line_terminator;
1731
1732   if (pushed_string_list->expand_alias)
1733     parser_state |= PST_ALEXPNEXT;
1734   else
1735     parser_state &= ~PST_ALEXPNEXT;
1736
1737   t = pushed_string_list;
1738   pushed_string_list = pushed_string_list->next;
1739
1740 #if defined (ALIAS)
1741   if (t->expander)
1742     t->expander->flags &= ~AL_BEINGEXPANDED;
1743 #endif
1744
1745   free ((char *)t);
1746
1747   set_line_mbstate ();
1748 }
1749
1750 static void
1751 free_string_list ()
1752 {
1753   register STRING_SAVER *t, *t1;
1754
1755   for (t = pushed_string_list; t; )
1756     {
1757       t1 = t->next;
1758       FREE (t->saved_line);
1759 #if defined (ALIAS)
1760       if (t->expander)
1761         t->expander->flags &= ~AL_BEINGEXPANDED;
1762 #endif
1763       free ((char *)t);
1764       t = t1;
1765     }
1766   pushed_string_list = (STRING_SAVER *)NULL;
1767 }
1768
1769 #endif /* ALIAS || DPAREN_ARITHMETIC */
1770
1771 void
1772 free_pushed_string_input ()
1773 {
1774 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1775   free_string_list ();
1776 #endif
1777 }
1778
1779 /* Return a line of text, taken from wherever yylex () reads input.
1780    If there is no more input, then we return NULL.  If REMOVE_QUOTED_NEWLINE
1781    is non-zero, we remove unquoted \<newline> pairs.  This is used by
1782    read_secondary_line to read here documents. */
1783 static char *
1784 read_a_line (remove_quoted_newline)
1785      int remove_quoted_newline;
1786 {
1787   static char *line_buffer = (char *)NULL;
1788   static int buffer_size = 0;
1789   int indx = 0, c, peekc, pass_next;
1790
1791 #if defined (READLINE)
1792   if (no_line_editing && SHOULD_PROMPT ())
1793 #else
1794   if (SHOULD_PROMPT ())
1795 #endif
1796     print_prompt ();
1797
1798   pass_next = 0;
1799   while (1)
1800     {
1801       /* Allow immediate exit if interrupted during input. */
1802       QUIT;
1803
1804       c = yy_getc ();
1805
1806       /* Ignore null bytes in input. */
1807       if (c == 0)
1808         {
1809 #if 0
1810           internal_warning ("read_a_line: ignored null byte in input");
1811 #endif
1812           continue;
1813         }
1814
1815       /* If there is no more input, then we return NULL. */
1816       if (c == EOF)
1817         {
1818           if (interactive && bash_input.type == st_stream)
1819             clearerr (stdin);
1820           if (indx == 0)
1821             return ((char *)NULL);
1822           c = '\n';
1823         }
1824
1825       /* `+2' in case the final character in the buffer is a newline. */
1826       RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
1827
1828       /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1829          here document with an unquoted delimiter.  In this case,
1830          the line will be expanded as if it were in double quotes.
1831          We allow a backslash to escape the next character, but we
1832          need to treat the backslash specially only if a backslash
1833          quoting a backslash-newline pair appears in the line. */
1834       if (pass_next)
1835         {
1836           line_buffer[indx++] = c;
1837           pass_next = 0;
1838         }
1839       else if (c == '\\' && remove_quoted_newline)
1840         {
1841           peekc = yy_getc ();
1842           if (peekc == '\n')
1843             {
1844               line_number++;
1845               continue; /* Make the unquoted \<newline> pair disappear. */
1846             }
1847           else
1848             {
1849               yy_ungetc (peekc);
1850               pass_next = 1;
1851               line_buffer[indx++] = c;          /* Preserve the backslash. */
1852             }
1853         }
1854       else
1855         line_buffer[indx++] = c;
1856
1857       if (c == '\n')
1858         {
1859           line_buffer[indx] = '\0';
1860           return (line_buffer);
1861         }
1862     }
1863 }
1864
1865 /* Return a line as in read_a_line (), but insure that the prompt is
1866    the secondary prompt.  This is used to read the lines of a here
1867    document.  REMOVE_QUOTED_NEWLINE is non-zero if we should remove
1868    newlines quoted with backslashes while reading the line.  It is
1869    non-zero unless the delimiter of the here document was quoted. */
1870 char *
1871 read_secondary_line (remove_quoted_newline)
1872      int remove_quoted_newline;
1873 {
1874   char *ret;
1875   int n, c;
1876
1877   prompt_string_pointer = &ps2_prompt;
1878   if (SHOULD_PROMPT())
1879     prompt_again ();
1880   ret = read_a_line (remove_quoted_newline);
1881 #if defined (HISTORY)
1882   if (ret && remember_on_history && (parser_state & PST_HEREDOC))
1883     {
1884       /* To make adding the the here-document body right, we need to rely
1885          on history_delimiting_chars() returning \n for the first line of
1886          the here-document body and the null string for the second and
1887          subsequent lines, so we avoid double newlines.
1888          current_command_line_count == 2 for the first line of the body. */
1889
1890       current_command_line_count++;
1891       maybe_add_history (ret);
1892     }
1893 #endif /* HISTORY */
1894   return ret;
1895 }
1896
1897 /* **************************************************************** */
1898 /*                                                                  */
1899 /*                              YYLEX ()                            */
1900 /*                                                                  */
1901 /* **************************************************************** */
1902
1903 /* Reserved words.  These are only recognized as the first word of a
1904    command. */
1905 STRING_INT_ALIST word_token_alist[] = {
1906   { "if", IF },
1907   { "then", THEN },
1908   { "else", ELSE },
1909   { "elif", ELIF },
1910   { "fi", FI },
1911   { "case", CASE },
1912   { "esac", ESAC },
1913   { "for", FOR },
1914 #if defined (SELECT_COMMAND)
1915   { "select", SELECT },
1916 #endif
1917   { "while", WHILE },
1918   { "until", UNTIL },
1919   { "do", DO },
1920   { "done", DONE },
1921   { "in", IN },
1922   { "function", FUNCTION },
1923 #if defined (COMMAND_TIMING)
1924   { "time", TIME },
1925 #endif
1926   { "{", '{' },
1927   { "}", '}' },
1928   { "!", BANG },
1929 #if defined (COND_COMMAND)
1930   { "[[", COND_START },
1931   { "]]", COND_END },
1932 #endif
1933 #if defined (COPROCESS_SUPPORT)
1934   { "coproc", COPROC },
1935 #endif
1936   { (char *)NULL, 0}
1937 };
1938
1939 /* other tokens that can be returned by read_token() */
1940 STRING_INT_ALIST other_token_alist[] = {
1941   /* Multiple-character tokens with special values */
1942   { "-p", TIMEOPT },
1943   { "&&", AND_AND },
1944   { "||", OR_OR },
1945   { ">>", GREATER_GREATER },
1946   { "<<", LESS_LESS },
1947   { "<&", LESS_AND },
1948   { ">&", GREATER_AND },
1949   { ";;", SEMI_SEMI },
1950   { ";&", SEMI_AND },
1951   { ";;&", SEMI_SEMI_AND },
1952   { "<<-", LESS_LESS_MINUS },
1953   { "<<<", LESS_LESS_LESS },
1954   { "&>", AND_GREATER },
1955   { "&>>", AND_GREATER_GREATER },
1956   { "<>", LESS_GREATER },
1957   { ">|", GREATER_BAR },
1958   { "|&", BAR_AND },
1959   { "EOF", yacc_EOF },
1960   /* Tokens whose value is the character itself */
1961   { ">", '>' },
1962   { "<", '<' },
1963   { "-", '-' },
1964   { "{", '{' },
1965   { "}", '}' },
1966   { ";", ';' },
1967   { "(", '(' },
1968   { ")", ')' },
1969   { "|", '|' },
1970   { "&", '&' },
1971   { "newline", '\n' },
1972   { (char *)NULL, 0}
1973 };
1974
1975 /* others not listed here:
1976         WORD                    look at yylval.word
1977         ASSIGNMENT_WORD         look at yylval.word
1978         NUMBER                  look at yylval.number
1979         ARITH_CMD               look at yylval.word_list
1980         ARITH_FOR_EXPRS         look at yylval.word_list
1981         COND_CMD                look at yylval.command
1982 */
1983
1984 /* These are used by read_token_word, but appear up here so that shell_getc
1985    can use them to decide when to add otherwise blank lines to the history. */
1986
1987 /* The primary delimiter stack. */
1988 struct dstack dstack = {  (char *)NULL, 0, 0 };
1989
1990 /* A temporary delimiter stack to be used when decoding prompt strings.
1991    This is needed because command substitutions in prompt strings (e.g., PS2)
1992    can screw up the parser's quoting state. */
1993 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
1994
1995 /* Macro for accessing the top delimiter on the stack.  Returns the
1996    delimiter or zero if none. */
1997 #define current_delimiter(ds) \
1998   (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
1999
2000 #define push_delimiter(ds, character) \
2001   do \
2002     { \
2003       if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2004         ds.delimiters = (char *)xrealloc \
2005           (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2006       ds.delimiters[ds.delimiter_depth] = character; \
2007       ds.delimiter_depth++; \
2008     } \
2009   while (0)
2010
2011 #define pop_delimiter(ds)       ds.delimiter_depth--
2012
2013 /* Return the next shell input character.  This always reads characters
2014    from shell_input_line; when that line is exhausted, it is time to
2015    read the next line.  This is called by read_token when the shell is
2016    processing normal command input. */
2017
2018 /* This implements one-character lookahead/lookbehind across physical input
2019    lines, to avoid something being lost because it's pushed back with
2020    shell_ungetc when we're at the start of a line. */
2021 static int eol_ungetc_lookahead = 0;
2022
2023 static int
2024 shell_getc (remove_quoted_newline)
2025      int remove_quoted_newline;
2026 {
2027   register int i;
2028   int c;
2029   unsigned char uc;
2030
2031   QUIT;
2032
2033   if (sigwinch_received)
2034     {
2035       sigwinch_received = 0;
2036       get_new_window_size (0, (int *)0, (int *)0);
2037     }
2038       
2039   if (eol_ungetc_lookahead)
2040     {
2041       c = eol_ungetc_lookahead;
2042       eol_ungetc_lookahead = 0;
2043       return (c);
2044     }
2045
2046 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2047   /* If shell_input_line[shell_input_line_index] == 0, but there is
2048      something on the pushed list of strings, then we don't want to go
2049      off and get another line.  We let the code down below handle it. */
2050
2051   if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2052                             (pushed_string_list == (STRING_SAVER *)NULL)))
2053 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2054   if (!shell_input_line || !shell_input_line[shell_input_line_index])
2055 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2056     {
2057       line_number++;
2058
2059     restart_read:
2060
2061       /* Allow immediate exit if interrupted during input. */
2062       QUIT;
2063
2064       i = 0;
2065       shell_input_line_terminator = 0;
2066
2067       /* If the shell is interatctive, but not currently printing a prompt
2068          (interactive_shell && interactive == 0), we don't want to print
2069          notifies or cleanup the jobs -- we want to defer it until we do
2070          print the next prompt. */
2071       if (interactive_shell == 0 || SHOULD_PROMPT())
2072         {
2073 #if defined (JOB_CONTROL)
2074       /* This can cause a problem when reading a command as the result
2075          of a trap, when the trap is called from flush_child.  This call
2076          had better not cause jobs to disappear from the job table in
2077          that case, or we will have big trouble. */
2078           notify_and_cleanup ();
2079 #else /* !JOB_CONTROL */
2080           cleanup_dead_jobs ();
2081 #endif /* !JOB_CONTROL */
2082         }
2083
2084 #if defined (READLINE)
2085       if (no_line_editing && SHOULD_PROMPT())
2086 #else
2087       if (SHOULD_PROMPT())
2088 #endif
2089         print_prompt ();
2090
2091       if (bash_input.type == st_stream)
2092         clearerr (stdin);
2093
2094       while (1)
2095         {
2096           c = yy_getc ();
2097
2098           /* Allow immediate exit if interrupted during input. */
2099           QUIT;
2100
2101           if (c == '\0')
2102             {
2103 #if 0
2104               internal_warning ("shell_getc: ignored null byte in input");
2105 #endif
2106               continue;
2107             }
2108
2109           RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2110
2111           if (c == EOF)
2112             {
2113               if (bash_input.type == st_stream)
2114                 clearerr (stdin);
2115
2116               if (i == 0)
2117                 shell_input_line_terminator = EOF;
2118
2119               shell_input_line[i] = '\0';
2120               break;
2121             }
2122
2123           shell_input_line[i++] = c;
2124
2125           if (c == '\n')
2126             {
2127               shell_input_line[--i] = '\0';
2128               current_command_line_count++;
2129               break;
2130             }
2131         }
2132
2133       shell_input_line_index = 0;
2134       shell_input_line_len = i;         /* == strlen (shell_input_line) */
2135
2136       set_line_mbstate ();
2137
2138 #if defined (HISTORY)
2139       if (remember_on_history && shell_input_line && shell_input_line[0])
2140         {
2141           char *expansions;
2142 #  if defined (BANG_HISTORY)
2143           int old_hist;
2144
2145           /* If the current delimiter is a single quote, we should not be
2146              performing history expansion, even if we're on a different
2147              line from the original single quote. */
2148           old_hist = history_expansion_inhibited;
2149           if (current_delimiter (dstack) == '\'')
2150             history_expansion_inhibited = 1;
2151 #  endif
2152           expansions = pre_process_line (shell_input_line, 1, 1);
2153 #  if defined (BANG_HISTORY)
2154           history_expansion_inhibited = old_hist;
2155 #  endif
2156           if (expansions != shell_input_line)
2157             {
2158               free (shell_input_line);
2159               shell_input_line = expansions;
2160               shell_input_line_len = shell_input_line ?
2161                                         strlen (shell_input_line) : 0;
2162               if (!shell_input_line_len)
2163                 current_command_line_count--;
2164
2165               /* We have to force the xrealloc below because we don't know
2166                  the true allocated size of shell_input_line anymore. */
2167               shell_input_line_size = shell_input_line_len;
2168
2169               set_line_mbstate ();
2170             }
2171         }
2172       /* Try to do something intelligent with blank lines encountered while
2173          entering multi-line commands.  XXX - this is grotesque */
2174       else if (remember_on_history && shell_input_line &&
2175                shell_input_line[0] == '\0' &&
2176                current_command_line_count > 1)
2177         {
2178           if (current_delimiter (dstack))
2179             /* We know shell_input_line[0] == 0 and we're reading some sort of
2180                quoted string.  This means we've got a line consisting of only
2181                a newline in a quoted string.  We want to make sure this line
2182                gets added to the history. */
2183             maybe_add_history (shell_input_line);
2184           else
2185             {
2186               char *hdcs;
2187               hdcs = history_delimiting_chars ();
2188               if (hdcs && hdcs[0] == ';')
2189                 maybe_add_history (shell_input_line);
2190             }
2191         }
2192
2193 #endif /* HISTORY */
2194
2195       if (shell_input_line)
2196         {
2197           /* Lines that signify the end of the shell's input should not be
2198              echoed. */
2199           if (echo_input_at_read && (shell_input_line[0] ||
2200                                      shell_input_line_terminator != EOF))
2201             fprintf (stderr, "%s\n", shell_input_line);
2202         }
2203       else
2204         {
2205           shell_input_line_size = 0;
2206           prompt_string_pointer = &current_prompt_string;
2207           if (SHOULD_PROMPT ())
2208             prompt_again ();
2209           goto restart_read;
2210         }
2211
2212       /* Add the newline to the end of this string, iff the string does
2213          not already end in an EOF character.  */
2214       if (shell_input_line_terminator != EOF)
2215         {
2216           if (shell_input_line_len + 3 > shell_input_line_size)
2217             shell_input_line = (char *)xrealloc (shell_input_line,
2218                                         1 + (shell_input_line_size += 2));
2219
2220           shell_input_line[shell_input_line_len] = '\n';
2221           shell_input_line[shell_input_line_len + 1] = '\0';
2222
2223           set_line_mbstate ();
2224         }
2225     }
2226
2227   uc = shell_input_line[shell_input_line_index];
2228
2229   if (uc)
2230     shell_input_line_index++;
2231
2232 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2233   /* If UC is NULL, we have reached the end of the current input string.  If
2234      pushed_string_list is non-empty, it's time to pop to the previous string
2235      because we have fully consumed the result of the last alias expansion.
2236      Do it transparently; just return the next character of the string popped
2237      to. */
2238   if (!uc && (pushed_string_list != (STRING_SAVER *)NULL))
2239     {
2240       pop_string ();
2241       uc = shell_input_line[shell_input_line_index];
2242       if (uc)
2243         shell_input_line_index++;
2244     }
2245 #endif /* ALIAS || DPAREN_ARITHMETIC */
2246
2247   if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
2248     {
2249         if (SHOULD_PROMPT ())
2250           prompt_again ();
2251         line_number++;
2252         goto restart_read;
2253     }
2254
2255   if (!uc && shell_input_line_terminator == EOF)
2256     return ((shell_input_line_index != 0) ? '\n' : EOF);
2257
2258   return (uc);
2259 }
2260
2261 /* Put C back into the input for the shell.  This might need changes for
2262    HANDLE_MULTIBYTE around EOLs.  Since we (currently) never push back a
2263    character different than we read, shell_input_line_property doesn't need
2264    to change when manipulating shell_input_line.  The define for
2265    last_shell_getc_is_singlebyte should take care of it, though. */
2266 static void
2267 shell_ungetc (c)
2268      int c;
2269 {
2270   if (shell_input_line && shell_input_line_index)
2271     shell_input_line[--shell_input_line_index] = c;
2272   else
2273     eol_ungetc_lookahead = c;
2274 }
2275
2276 #ifdef INCLUDE_UNUSED
2277 /* Back the input pointer up by one, effectively `ungetting' a character. */
2278 static void
2279 shell_ungetchar ()
2280 {
2281   if (shell_input_line && shell_input_line_index)
2282     shell_input_line_index--;
2283 }
2284 #endif
2285
2286 /* Discard input until CHARACTER is seen, then push that character back
2287    onto the input stream. */
2288 static void
2289 discard_until (character)
2290      int character;
2291 {
2292   int c;
2293
2294   while ((c = shell_getc (0)) != EOF && c != character)
2295     ;
2296
2297   if (c != EOF)
2298     shell_ungetc (c);
2299 }
2300
2301 void
2302 execute_variable_command (command, vname)
2303      char *command, *vname;
2304 {
2305   char *last_lastarg;
2306   sh_parser_state_t ps;
2307
2308   save_parser_state (&ps);
2309   last_lastarg = get_string_value ("_");
2310   if (last_lastarg)
2311     last_lastarg = savestring (last_lastarg);
2312
2313   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
2314
2315   restore_parser_state (&ps);
2316   bind_variable ("_", last_lastarg, 0);
2317   FREE (last_lastarg);
2318
2319   if (token_to_read == '\n')    /* reset_parser was called */
2320     token_to_read = 0;
2321 }
2322
2323 /* Place to remember the token.  We try to keep the buffer
2324    at a reasonable size, but it can grow. */
2325 static char *token = (char *)NULL;
2326
2327 /* Current size of the token buffer. */
2328 static int token_buffer_size;
2329
2330 /* Command to read_token () explaining what we want it to do. */
2331 #define READ 0
2332 #define RESET 1
2333 #define prompt_is_ps1 \
2334       (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2335
2336 /* Function for yyparse to call.  yylex keeps track of
2337    the last two tokens read, and calls read_token.  */
2338 static int
2339 yylex ()
2340 {
2341   if (interactive && (current_token == 0 || current_token == '\n'))
2342     {
2343       /* Before we print a prompt, we might have to check mailboxes.
2344          We do this only if it is time to do so. Notice that only here
2345          is the mail alarm reset; nothing takes place in check_mail ()
2346          except the checking of mail.  Please don't change this. */
2347       if (prompt_is_ps1 && time_to_check_mail ())
2348         {
2349           check_mail ();
2350           reset_mail_timer ();
2351         }
2352
2353       /* Avoid printing a prompt if we're not going to read anything, e.g.
2354          after resetting the parser with read_token (RESET). */
2355       if (token_to_read == 0 && SHOULD_PROMPT ())
2356         prompt_again ();
2357     }
2358
2359   two_tokens_ago = token_before_that;
2360   token_before_that = last_read_token;
2361   last_read_token = current_token;
2362   current_token = read_token (READ);
2363
2364   if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
2365     {
2366       current_token = yacc_EOF;
2367       if (bash_input.type == st_string)
2368         rewind_input_string ();
2369     }
2370   parser_state &= ~PST_EOFTOKEN;
2371
2372   return (current_token);
2373 }
2374
2375 /* When non-zero, we have read the required tokens
2376    which allow ESAC to be the next one read. */
2377 static int esacs_needed_count;
2378
2379 void
2380 gather_here_documents ()
2381 {
2382   int r;
2383
2384   r = 0;
2385   while (need_here_doc)
2386     {
2387       parser_state |= PST_HEREDOC;
2388       make_here_document (redir_stack[r++], line_number);
2389       parser_state &= ~PST_HEREDOC;
2390       need_here_doc--;
2391     }
2392 }
2393
2394 /* When non-zero, an open-brace used to create a group is awaiting a close
2395    brace partner. */
2396 static int open_brace_count;
2397
2398 #define command_token_position(token) \
2399   (((token) == ASSIGNMENT_WORD) || \
2400    ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
2401
2402 #define assignment_acceptable(token) \
2403   (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
2404
2405 /* Check to see if TOKEN is a reserved word and return the token
2406    value if it is. */
2407 #define CHECK_FOR_RESERVED_WORD(tok) \
2408   do { \
2409     if (!dollar_present && !quoted && \
2410         reserved_word_acceptable (last_read_token)) \
2411       { \
2412         int i; \
2413         for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2414           if (STREQ (tok, word_token_alist[i].word)) \
2415             { \
2416               if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2417                 break; \
2418               if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
2419                 break; \
2420               if (word_token_alist[i].token == ESAC) \
2421                 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2422               else if (word_token_alist[i].token == CASE) \
2423                 parser_state |= PST_CASESTMT; \
2424               else if (word_token_alist[i].token == COND_END) \
2425                 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2426               else if (word_token_alist[i].token == COND_START) \
2427                 parser_state |= PST_CONDCMD; \
2428               else if (word_token_alist[i].token == '{') \
2429                 open_brace_count++; \
2430               else if (word_token_alist[i].token == '}' && open_brace_count) \
2431                 open_brace_count--; \
2432               return (word_token_alist[i].token); \
2433             } \
2434       } \
2435   } while (0)
2436
2437 #if defined (ALIAS)
2438
2439     /* OK, we have a token.  Let's try to alias expand it, if (and only if)
2440        it's eligible.
2441
2442        It is eligible for expansion if EXPAND_ALIASES is set, and
2443        the token is unquoted and the last token read was a command
2444        separator (or expand_next_token is set), and we are currently
2445        processing an alias (pushed_string_list is non-empty) and this
2446        token is not the same as the current or any previously
2447        processed alias.
2448
2449        Special cases that disqualify:
2450          In a pattern list in a case statement (parser_state & PST_CASEPAT). */
2451
2452 static char *
2453 mk_alexpansion (s)
2454      char *s;
2455 {
2456   int l;
2457   char *r;
2458
2459   l = strlen (s);
2460   r = xmalloc (l + 2);
2461   strcpy (r, s);
2462   if (r[l -1] != ' ')
2463     r[l++] = ' ';
2464   r[l] = '\0';
2465   return r;
2466 }
2467
2468 static int
2469 alias_expand_token (tokstr)
2470      char *tokstr;
2471 {
2472   char *expanded;
2473   alias_t *ap;
2474
2475   if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2476         (parser_state & PST_CASEPAT) == 0)
2477     {
2478       ap = find_alias (tokstr);
2479
2480       /* Currently expanding this token. */
2481       if (ap && (ap->flags & AL_BEINGEXPANDED))
2482         return (NO_EXPANSION);
2483
2484       /* mk_alexpansion puts an extra space on the end of the alias expansion,
2485          so the lookahead by the parser works right.  If this gets changed,
2486          make sure the code in shell_getc that deals with reaching the end of
2487          an expanded alias is changed with it. */
2488       expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2489
2490       if (expanded)
2491         {
2492           push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2493           return (RE_READ_TOKEN);
2494         }
2495       else
2496         /* This is an eligible token that does not have an expansion. */
2497         return (NO_EXPANSION);
2498     }
2499   return (NO_EXPANSION);
2500 }
2501 #endif /* ALIAS */
2502
2503 static int
2504 time_command_acceptable ()
2505 {
2506 #if defined (COMMAND_TIMING)
2507   switch (last_read_token)
2508     {
2509     case 0:
2510     case ';':
2511     case '\n':
2512     case AND_AND:
2513     case OR_OR:
2514     case '&':
2515     case DO:
2516     case THEN:
2517     case ELSE:
2518     case '{':           /* } */
2519     case '(':           /* ) */
2520       return 1;
2521     default:
2522       return 0;
2523     }
2524 #else
2525   return 0;
2526 #endif /* COMMAND_TIMING */
2527 }
2528
2529 /* Handle special cases of token recognition:
2530         IN is recognized if the last token was WORD and the token
2531         before that was FOR or CASE or SELECT.
2532
2533         DO is recognized if the last token was WORD and the token
2534         before that was FOR or SELECT.
2535
2536         ESAC is recognized if the last token caused `esacs_needed_count'
2537         to be set
2538
2539         `{' is recognized if the last token as WORD and the token
2540         before that was FUNCTION, or if we just parsed an arithmetic
2541         `for' command.
2542
2543         `}' is recognized if there is an unclosed `{' present.
2544
2545         `-p' is returned as TIMEOPT if the last read token was TIME.
2546
2547         ']]' is returned as COND_END if the parser is currently parsing
2548         a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2549
2550         `time' is returned as TIME if and only if it is immediately
2551         preceded by one of `;', `\n', `||', `&&', or `&'.
2552 */
2553
2554 static int
2555 special_case_tokens (tokstr)
2556      char *tokstr;
2557 {
2558   if ((last_read_token == WORD) &&
2559 #if defined (SELECT_COMMAND)
2560       ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2561 #else
2562       ((token_before_that == FOR) || (token_before_that == CASE)) &&
2563 #endif
2564       (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
2565     {
2566       if (token_before_that == CASE)
2567         {
2568           parser_state |= PST_CASEPAT;
2569           esacs_needed_count++;
2570         }
2571       return (IN);
2572     }
2573
2574   if (last_read_token == WORD &&
2575 #if defined (SELECT_COMMAND)
2576       (token_before_that == FOR || token_before_that == SELECT) &&
2577 #else
2578       (token_before_that == FOR) &&
2579 #endif
2580       (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
2581     return (DO);
2582
2583   /* Ditto for ESAC in the CASE case.
2584      Specifically, this handles "case word in esac", which is a legal
2585      construct, certainly because someone will pass an empty arg to the
2586      case construct, and we don't want it to barf.  Of course, we should
2587      insist that the case construct has at least one pattern in it, but
2588      the designers disagree. */
2589   if (esacs_needed_count)
2590     {
2591       esacs_needed_count--;
2592       if (STREQ (tokstr, "esac"))
2593         {
2594           parser_state &= ~PST_CASEPAT;
2595           return (ESAC);
2596         }
2597     }
2598
2599   /* The start of a shell function definition. */
2600   if (parser_state & PST_ALLOWOPNBRC)
2601     {
2602       parser_state &= ~PST_ALLOWOPNBRC;
2603       if (tokstr[0] == '{' && tokstr[1] == '\0')                /* } */
2604         {
2605           open_brace_count++;
2606           function_bstart = line_number;
2607           return ('{');                                 /* } */
2608         }
2609     }
2610
2611   /* We allow a `do' after a for ((...)) without an intervening
2612      list_terminator */
2613   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
2614     return (DO);
2615   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0')      /* } */
2616     {
2617       open_brace_count++;
2618       return ('{');                     /* } */
2619     }
2620
2621   if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
2622     {
2623       open_brace_count--;               /* { */
2624       return ('}');
2625     }
2626
2627 #if defined (COMMAND_TIMING)
2628   /* Handle -p after `time'. */
2629   if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
2630     return (TIMEOPT);
2631 #endif
2632
2633 #if 0
2634 #if defined (COMMAND_TIMING)
2635   if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
2636     return (TIME);
2637 #endif /* COMMAND_TIMING */
2638 #endif
2639
2640 #if defined (COND_COMMAND) /* [[ */
2641   if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
2642     return (COND_END);
2643 #endif
2644
2645   return (-1);
2646 }
2647
2648 /* Called from shell.c when Control-C is typed at top level.  Or
2649    by the error rule at top level. */
2650 void
2651 reset_parser ()
2652 {
2653   dstack.delimiter_depth = 0;   /* No delimiters found so far. */
2654   open_brace_count = 0;
2655
2656   parser_state = 0;
2657
2658 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2659   if (pushed_string_list)
2660     free_string_list ();
2661 #endif /* ALIAS || DPAREN_ARITHMETIC */
2662
2663   if (shell_input_line)
2664     {
2665       free (shell_input_line);
2666       shell_input_line = (char *)NULL;
2667       shell_input_line_size = shell_input_line_index = 0;
2668     }
2669
2670   FREE (word_desc_to_read);
2671   word_desc_to_read = (WORD_DESC *)NULL;
2672
2673   current_token = '\n';         /* XXX */
2674   last_read_token = '\n';
2675   token_to_read = '\n';
2676 }
2677
2678 /* Read the next token.  Command can be READ (normal operation) or
2679    RESET (to normalize state). */
2680 static int
2681 read_token (command)
2682      int command;
2683 {
2684   int character;                /* Current character. */
2685   int peek_char;                /* Temporary look-ahead character. */
2686   int result;                   /* The thing to return. */
2687
2688   if (command == RESET)
2689     {
2690       reset_parser ();
2691       return ('\n');
2692     }
2693
2694   if (token_to_read)
2695     {
2696       result = token_to_read;
2697       if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
2698         {
2699           yylval.word = word_desc_to_read;
2700           word_desc_to_read = (WORD_DESC *)NULL;
2701         }
2702       token_to_read = 0;
2703       return (result);
2704     }
2705
2706 #if defined (COND_COMMAND)
2707   if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2708     {
2709       cond_lineno = line_number;
2710       parser_state |= PST_CONDEXPR;
2711       yylval.command = parse_cond_command ();
2712       if (cond_token != COND_END)
2713         {
2714           cond_error ();
2715           return (-1);
2716         }
2717       token_to_read = COND_END;
2718       parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2719       return (COND_CMD);
2720     }
2721 #endif
2722
2723 #if defined (ALIAS)
2724   /* This is a place to jump back to once we have successfully expanded a
2725      token with an alias and pushed the string with push_string () */
2726  re_read_token:
2727 #endif /* ALIAS */
2728
2729   /* Read a single word from input.  Start by skipping blanks. */
2730   while ((character = shell_getc (1)) != EOF && shellblank (character))
2731     ;
2732
2733   if (character == EOF)
2734     {
2735       EOF_Reached = 1;
2736       return (yacc_EOF);
2737     }
2738
2739   if MBTEST(character == '#' && (!interactive || interactive_comments))
2740     {
2741       /* A comment.  Discard until EOL or EOF, and then return a newline. */
2742       discard_until ('\n');
2743       shell_getc (0);
2744       character = '\n'; /* this will take the next if statement and return. */
2745     }
2746
2747   if (character == '\n')
2748     {
2749       /* If we're about to return an unquoted newline, we can go and collect
2750          the text of any pending here document. */
2751       if (need_here_doc)
2752         gather_here_documents ();
2753
2754 #if defined (ALIAS)
2755       parser_state &= ~PST_ALEXPNEXT;
2756 #endif /* ALIAS */
2757
2758       parser_state &= ~PST_ASSIGNOK;
2759
2760       return (character);
2761     }
2762
2763   if (parser_state & PST_REGEXP)
2764     goto tokword;
2765
2766   /* Shell meta-characters. */
2767   if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
2768     {
2769 #if defined (ALIAS)
2770       /* Turn off alias tokenization iff this character sequence would
2771          not leave us ready to read a command. */
2772       if (character == '<' || character == '>')
2773         parser_state &= ~PST_ALEXPNEXT;
2774 #endif /* ALIAS */
2775
2776       parser_state &= ~PST_ASSIGNOK;
2777
2778       peek_char = shell_getc (1);
2779       if (character == peek_char)
2780         {
2781           switch (character)
2782             {
2783             case '<':
2784               /* If '<' then we could be at "<<" or at "<<-".  We have to
2785                  look ahead one more character. */
2786               peek_char = shell_getc (1);
2787               if MBTEST(peek_char == '-')
2788                 return (LESS_LESS_MINUS);
2789               else if MBTEST(peek_char == '<')
2790                 return (LESS_LESS_LESS);
2791               else
2792                 {
2793                   shell_ungetc (peek_char);
2794                   return (LESS_LESS);
2795                 }
2796
2797             case '>':
2798               return (GREATER_GREATER);
2799
2800             case ';':
2801               parser_state |= PST_CASEPAT;
2802 #if defined (ALIAS)
2803               parser_state &= ~PST_ALEXPNEXT;
2804 #endif /* ALIAS */
2805
2806               peek_char = shell_getc (1);
2807               if MBTEST(peek_char == '&')
2808                 return (SEMI_SEMI_AND);
2809               else
2810                 {
2811                   shell_ungetc (peek_char);
2812                   return (SEMI_SEMI);
2813                 }
2814
2815             case '&':
2816               return (AND_AND);
2817
2818             case '|':
2819               return (OR_OR);
2820
2821 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
2822             case '(':           /* ) */
2823               result = parse_dparen (character);
2824               if (result == -2)
2825                 break;
2826               else
2827                 return result;
2828 #endif
2829             }
2830         }
2831       else if MBTEST(character == '<' && peek_char == '&')
2832         return (LESS_AND);
2833       else if MBTEST(character == '>' && peek_char == '&')
2834         return (GREATER_AND);
2835       else if MBTEST(character == '<' && peek_char == '>')
2836         return (LESS_GREATER);
2837       else if MBTEST(character == '>' && peek_char == '|')
2838         return (GREATER_BAR);
2839       else if MBTEST(character == '&' && peek_char == '>')
2840         {
2841           peek_char = shell_getc (1);
2842           if MBTEST(peek_char == '>')
2843             return (AND_GREATER_GREATER);
2844           else
2845             {
2846               shell_ungetc (peek_char);
2847               return (AND_GREATER);
2848             }
2849         }
2850       else if MBTEST(character == '|' && peek_char == '&')
2851         return (BAR_AND);
2852       else if MBTEST(character == ';' && peek_char == '&')
2853         {
2854           parser_state |= PST_CASEPAT;
2855 #if defined (ALIAS)
2856           parser_state &= ~PST_ALEXPNEXT;
2857 #endif /* ALIAS */
2858           return (SEMI_AND);
2859         }
2860
2861       shell_ungetc (peek_char);
2862
2863       /* If we look like we are reading the start of a function
2864          definition, then let the reader know about it so that
2865          we will do the right thing with `{'. */
2866       if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
2867         {
2868           parser_state |= PST_ALLOWOPNBRC;
2869 #if defined (ALIAS)
2870           parser_state &= ~PST_ALEXPNEXT;
2871 #endif /* ALIAS */
2872           function_dstart = line_number;
2873         }
2874
2875       /* case pattern lists may be preceded by an optional left paren.  If
2876          we're not trying to parse a case pattern list, the left paren
2877          indicates a subshell. */
2878       if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
2879         parser_state |= PST_SUBSHELL;
2880       /*(*/
2881       else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
2882         parser_state &= ~PST_CASEPAT;
2883       /*(*/
2884       else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
2885         parser_state &= ~PST_SUBSHELL;
2886
2887 #if defined (PROCESS_SUBSTITUTION)
2888       /* Check for the constructs which introduce process substitution.
2889          Shells running in `posix mode' don't do process substitution. */
2890       if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
2891 #endif /* PROCESS_SUBSTITUTION */
2892         return (character);
2893     }
2894
2895   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */
2896   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
2897     return (character);
2898
2899 tokword:
2900   /* Okay, if we got this far, we have to read a word.  Read one,
2901      and then check it against the known ones. */
2902   result = read_token_word (character);
2903 #if defined (ALIAS)
2904   if (result == RE_READ_TOKEN)
2905     goto re_read_token;
2906 #endif
2907   return result;
2908 }
2909
2910 /*
2911  * Match a $(...) or other grouping construct.  This has to handle embedded
2912  * quoted strings ('', ``, "") and nested constructs.  It also must handle
2913  * reprompting the user, if necessary, after reading a newline, and returning
2914  * correct error values if it reads EOF.
2915  */
2916 #define P_FIRSTCLOSE    0x01
2917 #define P_ALLOWESC      0x02
2918 #define P_DQUOTE        0x04
2919 #define P_COMMAND       0x08    /* parsing a command, so look for comments */
2920 #define P_BACKQUOTE     0x10    /* parsing a backquoted command substitution */
2921 #define P_ARRAYSUB      0x20    /* parsing a [...] array subscript for assignment */
2922
2923 /* Lexical state while parsing a grouping construct or $(...). */
2924 #define LEX_WASDOL      0x001
2925 #define LEX_CKCOMMENT   0x002
2926 #define LEX_INCOMMENT   0x004
2927 #define LEX_PASSNEXT    0x008
2928 #define LEX_RESWDOK     0x010
2929 #define LEX_CKCASE      0x020
2930 #define LEX_INCASE      0x040
2931 #define LEX_INHEREDOC   0x080
2932 #define LEX_HEREDELIM   0x100           /* reading here-doc delimiter */
2933 #define LEX_STRIPDOC    0x200           /* <<- strip tabs from here doc delim */
2934 #define LEX_INWORD      0x400
2935
2936 #define COMSUB_META(ch)         ((ch) == ';' || (ch) == '&' || (ch) == '|')
2937
2938 #define CHECK_NESTRET_ERROR() \
2939   do { \
2940     if (nestret == &matched_pair_error) \
2941       { \
2942         free (ret); \
2943         return &matched_pair_error; \
2944       } \
2945   } while (0)
2946
2947 #define APPEND_NESTRET() \
2948   do { \
2949     if (nestlen) \
2950       { \
2951         RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
2952         strcpy (ret + retind, nestret); \
2953         retind += nestlen; \
2954       } \
2955   } while (0)
2956
2957 static char matched_pair_error;
2958
2959 static char *
2960 parse_matched_pair (qc, open, close, lenp, flags)
2961      int qc;    /* `"' if this construct is within double quotes */
2962      int open, close;
2963      int *lenp, flags;
2964 {
2965   int count, ch, tflags;
2966   int nestlen, ttranslen, start_lineno;
2967   char *ret, *nestret, *ttrans;
2968   int retind, retsize, rflags;
2969
2970 /* itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
2971   count = 1;
2972   tflags = 0;
2973
2974   if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
2975     tflags |= LEX_CKCOMMENT;
2976
2977   /* RFLAGS is the set of flags we want to pass to recursive calls. */
2978   rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
2979
2980   ret = (char *)xmalloc (retsize = 64);
2981   retind = 0;
2982
2983   start_lineno = line_number;
2984   while (count)
2985     {
2986       ch = shell_getc (qc != '\'' && (tflags & LEX_PASSNEXT) == 0);
2987
2988       if (ch == EOF)
2989         {
2990           free (ret);
2991           parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
2992           EOF_Reached = 1;      /* XXX */
2993           return (&matched_pair_error);
2994         }
2995
2996       /* Possible reprompting. */
2997       if (ch == '\n' && SHOULD_PROMPT ())
2998         prompt_again ();
2999
3000       /* Don't bother counting parens or doing anything else if in a comment
3001          or part of a case statement */
3002       if (tflags & LEX_INCOMMENT)
3003         {
3004           /* Add this character. */
3005           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3006           ret[retind++] = ch;
3007
3008           if (ch == '\n')
3009             tflags &= ~LEX_INCOMMENT;
3010
3011           continue;
3012         }
3013
3014       /* Not exactly right yet, should handle shell metacharacters, too.  If
3015          any changes are made to this test, make analogous changes to subst.c:
3016          extract_delimited_string(). */
3017       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
3018         tflags |= LEX_INCOMMENT;
3019
3020       if (tflags & LEX_PASSNEXT)                /* last char was backslash */
3021         {
3022           tflags &= ~LEX_PASSNEXT;
3023           if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3024             {
3025               if (retind > 0)
3026                 retind--;       /* swallow previously-added backslash */
3027               continue;
3028             }
3029
3030           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3031           if MBTEST(ch == CTLESC || ch == CTLNUL)
3032             ret[retind++] = CTLESC;
3033           ret[retind++] = ch;
3034           continue;
3035         }
3036       /* If we're reparsing the input (e.g., from parse_string_to_word_list),
3037          we've already prepended CTLESC to single-quoted results of $'...'.
3038          We may want to do this for other CTLESC-quoted characters in
3039          reparse, too. */
3040       else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
3041         {
3042           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3043           ret[retind++] = ch;
3044           continue;
3045         }
3046       else if MBTEST(ch == CTLESC || ch == CTLNUL)      /* special shell escapes */
3047         {
3048           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3049           ret[retind++] = CTLESC;
3050           ret[retind++] = ch;
3051           continue;
3052         }
3053       else if MBTEST(ch == close)               /* ending delimiter */
3054         count--;
3055       /* handle nested ${...} specially. */
3056       else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
3057         count++;
3058       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open)       /* nested begin */
3059         count++;
3060
3061       /* Add this character. */
3062       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3063       ret[retind++] = ch;
3064
3065       /* If we just read the ending character, don't bother continuing. */
3066       if (count == 0)
3067         break;
3068
3069       if (open == '\'')                 /* '' inside grouping construct */
3070         {
3071           if MBTEST((flags & P_ALLOWESC) && ch == '\\')
3072             tflags |= LEX_PASSNEXT;
3073           continue;
3074         }
3075
3076       if MBTEST(ch == '\\')                     /* backslashes */
3077         tflags |= LEX_PASSNEXT;
3078
3079 #if 0
3080       /* The big hammer.  Single quotes aren't special in double quotes.  The
3081          problem is that Posix says the single quotes are semi-special:
3082          within a double-quoted ${...} construct "an even number of
3083          unescaped double-quotes or single-quotes, if any, shall occur." */
3084       if MBTEST(open == '{' && (flags & P_DQUOTE) && ch == '\'')        /* } */
3085         continue;
3086 #endif
3087
3088       /* Could also check open == '`' if we want to parse grouping constructs
3089          inside old-style command substitution. */
3090       if (open != close)                /* a grouping construct */
3091         {
3092           if MBTEST(shellquote (ch))
3093             {
3094               /* '', ``, or "" inside $(...) or other grouping construct. */
3095               push_delimiter (dstack, ch);
3096               if MBTEST((tflags & LEX_WASDOL) && ch == '\'')    /* $'...' inside group */
3097                 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3098               else
3099                 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3100               pop_delimiter (dstack);
3101               CHECK_NESTRET_ERROR ();
3102
3103               if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3104                 {
3105                   /* Translate $'...' here. */
3106                   ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3107                   xfree (nestret);
3108
3109                   if ((rflags & P_DQUOTE) == 0)
3110                     {
3111                       nestret = sh_single_quote (ttrans);
3112                       free (ttrans);
3113                       nestlen = strlen (nestret);
3114                     }
3115                   else
3116                     {
3117                       nestret = ttrans;
3118                       nestlen = ttranslen;
3119                     }
3120                   retind -= 2;          /* back up before the $' */
3121                 }
3122               else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3123                 {
3124                   /* Locale expand $"..." here. */
3125                   ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3126                   xfree (nestret);
3127
3128                   nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3129                   free (ttrans);
3130                   nestlen = ttranslen + 2;
3131                   retind -= 2;          /* back up before the $" */
3132                 }
3133
3134               APPEND_NESTRET ();
3135               FREE (nestret);
3136             }
3137           else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
3138             goto parse_dollar_word;
3139         }
3140       /* Parse an old-style command substitution within double quotes as a
3141          single word. */
3142       /* XXX - sh and ksh93 don't do this - XXX */
3143       else if MBTEST(open == '"' && ch == '`')
3144         {
3145           nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
3146
3147           CHECK_NESTRET_ERROR ();
3148           APPEND_NESTRET ();
3149
3150           FREE (nestret);
3151         }
3152       else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))     /* ) } ] */
3153         /* check for $(), $[], or ${} inside quoted string. */
3154         {
3155 parse_dollar_word:
3156           if (open == ch)       /* undo previous increment */
3157             count--;
3158           if (ch == '(')                /* ) */
3159             nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3160           else if (ch == '{')           /* } */
3161             nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
3162           else if (ch == '[')           /* ] */
3163             nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3164
3165           CHECK_NESTRET_ERROR ();
3166           APPEND_NESTRET ();
3167
3168           FREE (nestret);
3169         }
3170       if MBTEST(ch == '$')
3171         tflags |= LEX_WASDOL;
3172       else
3173         tflags &= ~LEX_WASDOL;
3174     }
3175
3176   ret[retind] = '\0';
3177   if (lenp)
3178     *lenp = retind;
3179   return ret;
3180 }
3181
3182 /* Parse a $(...) command substitution.  This is messier than I'd like, and
3183    reproduces a lot more of the token-reading code than I'd like. */
3184 static char *
3185 parse_comsub (qc, open, close, lenp, flags)
3186      int qc;    /* `"' if this construct is within double quotes */
3187      int open, close;
3188      int *lenp, flags;
3189 {
3190   int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
3191   int nestlen, ttranslen, start_lineno;
3192   char *ret, *nestret, *ttrans, *heredelim;
3193   int retind, retsize, rflags, hdlen;
3194
3195 /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
3196   count = 1;
3197   tflags = LEX_RESWDOK;
3198
3199   if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3200     tflags |= LEX_CKCASE;
3201   if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
3202     tflags |= LEX_CKCOMMENT;
3203
3204   /* RFLAGS is the set of flags we want to pass to recursive calls. */
3205   rflags = (flags & P_DQUOTE);
3206
3207   ret = (char *)xmalloc (retsize = 64);
3208   retind = 0;
3209
3210   start_lineno = line_number;
3211   lex_rwlen = lex_wlen = 0;
3212
3213   heredelim = 0;
3214   lex_firstind = -1;
3215
3216   while (count)
3217     {
3218 comsub_readchar:
3219       ch = shell_getc (qc != '\'' && (tflags & LEX_PASSNEXT) == 0);
3220
3221       if (ch == EOF)
3222         {
3223 eof_error:
3224           free (ret);
3225           FREE (heredelim);
3226           parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3227           EOF_Reached = 1;      /* XXX */
3228           return (&matched_pair_error);
3229         }
3230
3231       /* If we hit the end of a line and are reading the contents of a here
3232          document, and it's not the same line that the document starts on,
3233          check for this line being the here doc delimiter.  Otherwise, if
3234          we're in a here document, mark the next character as the beginning
3235          of a line. */
3236       if (ch == '\n')
3237         {
3238           if ((tflags & LEX_HEREDELIM) && heredelim)
3239             {
3240               tflags &= ~LEX_HEREDELIM;
3241               tflags |= LEX_INHEREDOC;
3242               lex_firstind = retind + 1;
3243             }
3244           else if (tflags & LEX_INHEREDOC)
3245             {
3246               int tind;
3247               tind = lex_firstind;
3248               while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3249                 tind++;
3250               if (STREQN (ret + tind, heredelim, hdlen))
3251                 {
3252                   tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
3253 /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
3254                   lex_firstind = -1;
3255                 }
3256               else
3257                 lex_firstind = retind + 1;
3258             }
3259         }
3260
3261       /* Possible reprompting. */
3262       if (ch == '\n' && SHOULD_PROMPT ())
3263         prompt_again ();
3264
3265       /* Don't bother counting parens or doing anything else if in a comment */
3266       if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
3267         {
3268           /* Add this character. */
3269           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3270           ret[retind++] = ch;
3271
3272           if ((tflags & LEX_INCOMMENT) && ch == '\n')
3273             tflags &= ~LEX_INCOMMENT;
3274
3275           continue;
3276         }
3277
3278       if (tflags & LEX_PASSNEXT)                /* last char was backslash */
3279         {
3280 /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3281           tflags &= ~LEX_PASSNEXT;
3282           if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3283             {
3284               if (retind > 0)
3285                 retind--;       /* swallow previously-added backslash */
3286               continue;
3287             }
3288
3289           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3290           if MBTEST(ch == CTLESC || ch == CTLNUL)
3291             ret[retind++] = CTLESC;
3292           ret[retind++] = ch;
3293           continue;
3294         }
3295
3296       /* If this is a shell break character, we are not in a word.  If not,
3297          we either start or continue a word. */
3298       if MBTEST(shellbreak (ch))
3299         {
3300           tflags &= ~LEX_INWORD;
3301 /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3302         }
3303       else
3304         {
3305           if (tflags & LEX_INWORD)
3306             {
3307               lex_wlen++;
3308 /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
3309             }         
3310           else
3311             {
3312 /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3313               tflags |= LEX_INWORD;
3314               lex_wlen = 0;
3315             }
3316         }
3317
3318       /* Skip whitespace */
3319       if MBTEST(shellblank (ch) && lex_rwlen == 0)
3320         {
3321           /* Add this character. */
3322           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3323           ret[retind++] = ch;
3324           continue;
3325         }
3326
3327       /* Either we are looking for the start of the here-doc delimiter
3328          (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
3329          If this character is a shell break character and we are reading
3330          the delimiter, save it and note that we are now reading a here
3331          document.  If we've found the start of the delimiter, note it by
3332          setting lex_firstind.  Backslashes can quote shell metacharacters
3333          in here-doc delimiters. */
3334       if (tflags & LEX_HEREDELIM)
3335         {
3336           if (lex_firstind == -1 && shellbreak (ch) == 0)
3337             lex_firstind = retind;
3338           else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
3339             {
3340               nestret = substring (ret, lex_firstind, retind);
3341               heredelim = string_quote_removal (nestret, 0);
3342               free (nestret);
3343               hdlen = STRLEN(heredelim);
3344 /*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
3345               if (ch == '\n')
3346                 {
3347                   tflags |= LEX_INHEREDOC;
3348                   tflags &= ~LEX_HEREDELIM;
3349                   lex_firstind = retind + 1;
3350                 }
3351               else
3352                 lex_firstind = -1;
3353             }
3354         }
3355
3356       /* Meta-characters that can introduce a reserved word.  Not perfect yet. */
3357       if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
3358         {
3359           /* Add this character. */
3360           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3361           ret[retind++] = ch;
3362           peekc = shell_getc (1);
3363           if (ch == peekc && (ch == '&' || ch == '|' || ch == ';'))     /* two-character tokens */
3364             {
3365               RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3366               ret[retind++] = peekc;
3367 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch); */
3368               tflags |= LEX_RESWDOK;
3369               lex_rwlen = 0;
3370               continue;
3371             }
3372           else if (ch == '\n' || COMSUB_META(ch))
3373             {
3374               shell_ungetc (peekc);
3375               tflags |= LEX_RESWDOK;
3376 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
3377               lex_rwlen = 0;
3378               continue;
3379             }
3380           else if (ch == EOF)
3381             goto eof_error;
3382           else
3383             {
3384               /* `unget' the character we just added and fall through */
3385               retind--;
3386               shell_ungetc (peekc);
3387             }
3388         }
3389
3390       /* If we can read a reserved word, try to read one. */
3391       if (tflags & LEX_RESWDOK)
3392         {
3393           if MBTEST(islower (ch))
3394             {
3395               /* Add this character. */
3396               RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3397               ret[retind++] = ch;
3398               lex_rwlen++;
3399               continue;
3400             }
3401           else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
3402             {
3403               if (STREQN (ret + retind - 4, "case", 4))
3404 {
3405                 tflags |= LEX_INCASE;
3406 /*itrace("parse_comsub:%d: found `case', lex_incase -> 1", line_number);*/
3407 }
3408               else if (STREQN (ret + retind - 4, "esac", 4))
3409 {
3410                 tflags &= ~LEX_INCASE;
3411 /*itrace("parse_comsub:%d: found `esac', lex_incase -> 0", line_number);*/
3412 }               
3413               tflags &= ~LEX_RESWDOK;
3414             }
3415           else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
3416             ;   /* don't modify LEX_RESWDOK if we're starting a comment */
3417           else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
3418             /* If we can read a reserved word and we're in case, we're at the
3419                point where we can read a new pattern list or an esac.  We
3420                handle the esac case above.  If we read a newline, we want to
3421                leave LEX_RESWDOK alone.  If we read anything else, we want to
3422                turn off LEX_RESWDOK, since we're going to read a pattern list. */
3423 {
3424             tflags &= ~LEX_RESWDOK;
3425 /*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
3426 }
3427           else if MBTEST(shellbreak (ch) == 0)
3428 {
3429             tflags &= ~LEX_RESWDOK;
3430 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
3431 }
3432         }
3433
3434       if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
3435         {
3436           /* Add this character. */
3437           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3438           ret[retind++] = ch;
3439           peekc = shell_getc (1);
3440           if (peekc == EOF)
3441             goto eof_error;
3442           if (peekc == ch)
3443             {
3444               RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3445               ret[retind++] = peekc;
3446               peekc = shell_getc (1);
3447               if (peekc == EOF)
3448                 goto eof_error;
3449               if (peekc == '-')
3450                 {
3451                   RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3452                   ret[retind++] = peekc;
3453                   tflags |= LEX_STRIPDOC;
3454                 }
3455               else
3456                 shell_ungetc (peekc);
3457               if (peekc != '<')
3458                 {
3459                   tflags |= LEX_HEREDELIM;
3460                   lex_firstind = -1;
3461                 }
3462               continue;
3463             }
3464           else
3465             ch = peekc;         /* fall through and continue XXX */
3466         }
3467       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
3468 {
3469 /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
3470         tflags |= LEX_INCOMMENT;
3471 }
3472
3473       if MBTEST(ch == CTLESC || ch == CTLNUL)   /* special shell escapes */
3474         {
3475           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3476           ret[retind++] = CTLESC;
3477           ret[retind++] = ch;
3478           continue;
3479         }
3480 #if 0
3481       else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
3482         tflags &= ~LEX_INCASE;          /* XXX */
3483 #endif
3484       else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0)         /* ending delimiter */
3485 {
3486         count--;
3487 /*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
3488 }
3489       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */
3490         count++;
3491
3492       /* Add this character. */
3493       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3494       ret[retind++] = ch;
3495
3496       /* If we just read the ending character, don't bother continuing. */
3497       if (count == 0)
3498         break;
3499
3500       if MBTEST(ch == '\\')                     /* backslashes */
3501         tflags |= LEX_PASSNEXT;
3502
3503       if MBTEST(shellquote (ch))
3504         {
3505           /* '', ``, or "" inside $(...). */
3506           push_delimiter (dstack, ch);
3507           if MBTEST((tflags & LEX_WASDOL) && ch == '\'')        /* $'...' inside group */
3508             nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3509           else
3510             nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3511           pop_delimiter (dstack);
3512           CHECK_NESTRET_ERROR ();
3513
3514           if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3515             {
3516               /* Translate $'...' here. */
3517               ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3518               xfree (nestret);
3519
3520               if ((rflags & P_DQUOTE) == 0)
3521                 {
3522                   nestret = sh_single_quote (ttrans);
3523                   free (ttrans);
3524                   nestlen = strlen (nestret);
3525                 }
3526               else
3527                 {
3528                   nestret = ttrans;
3529                   nestlen = ttranslen;
3530                 }
3531               retind -= 2;              /* back up before the $' */
3532             }
3533           else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3534             {
3535               /* Locale expand $"..." here. */
3536               ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3537               xfree (nestret);
3538
3539               nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3540               free (ttrans);
3541               nestlen = ttranslen + 2;
3542               retind -= 2;              /* back up before the $" */
3543             }
3544
3545           APPEND_NESTRET ();
3546           FREE (nestret);
3547         }
3548       else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))    /* ) } ] */
3549         /* check for $(), $[], or ${} inside command substitution. */
3550         {
3551           if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */
3552             count--;
3553           if (ch == '(')                /* ) */
3554             nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3555           else if (ch == '{')           /* } */
3556             nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
3557           else if (ch == '[')           /* ] */
3558             nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3559
3560           CHECK_NESTRET_ERROR ();
3561           APPEND_NESTRET ();
3562
3563           FREE (nestret);
3564         }
3565       if MBTEST(ch == '$')
3566         tflags |= LEX_WASDOL;
3567       else
3568         tflags &= ~LEX_WASDOL;
3569     }
3570
3571   FREE (heredelim);
3572   ret[retind] = '\0';
3573   if (lenp)
3574     *lenp = retind;
3575 /*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
3576   return ret;
3577 }
3578
3579 /* XXX - this needs to handle functionality like subst.c:no_longjmp_on_fatal_error;
3580    maybe extract_command_subst should handle it. */
3581 char *
3582 xparse_dolparen (base, string, indp, flags)
3583      char *base;
3584      char *string;
3585      int *indp;
3586      int flags;
3587 {
3588   sh_parser_state_t ps;
3589   int orig_ind, nc, sflags;
3590   char *ret, *s, *ep, *ostring;
3591
3592   /*yydebug = 1;*/
3593   orig_ind = *indp;
3594   ostring = string;
3595
3596   sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
3597   if (flags & SX_NOLONGJMP)
3598     sflags |= SEVAL_NOLONGJMP;
3599   save_parser_state (&ps);
3600
3601   /*(*/
3602   parser_state |= PST_CMDSUBST|PST_EOFTOKEN;    /* allow instant ')' */ /*(*/
3603   shell_eof_token = ')';
3604   parse_string (string, "command substitution", sflags, &ep);
3605
3606   restore_parser_state (&ps);
3607   reset_parser ();
3608   if (interactive)
3609     token_to_read = 0;
3610
3611   /* Need to find how many characters parse_and_execute consumed, update
3612      *indp, if flags != 0, copy the portion of the string parsed into RET
3613      and return it.  If flags & 1 (EX_NOALLOC) we can return NULL. */
3614
3615   /*(*/
3616   if (ep[-1] != ')')
3617     {
3618 #if DEBUG
3619       if (ep[-1] != '\n')
3620         itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
3621 #endif
3622       while (ep > ostring && ep[-1] == '\n') ep--;
3623     }
3624
3625   nc = ep - ostring;
3626   *indp = ep - base - 1;
3627
3628   /*(*/
3629 #if DEBUG
3630   if (base[*indp] != ')')
3631     itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
3632 #endif
3633
3634   if (flags & SX_NOALLOC) 
3635     return (char *)NULL;
3636
3637   if (nc == 0)
3638     {
3639       ret = xmalloc (1);
3640       ret[0] = '\0';
3641     }
3642   else
3643     ret = substring (ostring, 0, nc - 1);
3644
3645   return ret;
3646 }
3647
3648 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3649 /* Parse a double-paren construct.  It can be either an arithmetic
3650    command, an arithmetic `for' command, or a nested subshell.  Returns
3651    the parsed token, -1 on error, or -2 if we didn't do anything and
3652    should just go on. */
3653 static int
3654 parse_dparen (c)
3655      int c;
3656 {
3657   int cmdtyp, sline;
3658   char *wval;
3659   WORD_DESC *wd;
3660
3661 #if defined (ARITH_FOR_COMMAND)
3662   if (last_read_token == FOR)
3663     {
3664       arith_for_lineno = line_number;
3665       cmdtyp = parse_arith_cmd (&wval, 0);
3666       if (cmdtyp == 1)
3667         {
3668           wd = alloc_word_desc ();
3669           wd->word = wval;
3670           yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3671           return (ARITH_FOR_EXPRS);
3672         }
3673       else
3674         return -1;              /* ERROR */
3675     }
3676 #endif
3677
3678 #if defined (DPAREN_ARITHMETIC)
3679   if (reserved_word_acceptable (last_read_token))
3680     {
3681       sline = line_number;
3682
3683       cmdtyp = parse_arith_cmd (&wval, 0);
3684       if (cmdtyp == 1)  /* arithmetic command */
3685         {
3686           wd = alloc_word_desc ();
3687           wd->word = wval;
3688           wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
3689           yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3690           return (ARITH_CMD);
3691         }
3692       else if (cmdtyp == 0)     /* nested subshell */
3693         {
3694           push_string (wval, 0, (alias_t *)NULL);
3695           if ((parser_state & PST_CASEPAT) == 0)
3696             parser_state |= PST_SUBSHELL;
3697           return (c);
3698         }
3699       else                      /* ERROR */
3700         return -1;
3701     }
3702 #endif
3703
3704   return -2;                    /* XXX */
3705 }
3706
3707 /* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
3708    If not, assume it's a nested subshell for backwards compatibility and
3709    return 0.  In any case, put the characters we've consumed into a locally-
3710    allocated buffer and make *ep point to that buffer.  Return -1 on an
3711    error, for example EOF. */
3712 static int
3713 parse_arith_cmd (ep, adddq)
3714      char **ep;
3715      int adddq;
3716 {
3717   int exp_lineno, rval, c;
3718   char *ttok, *tokstr;
3719   int ttoklen;
3720
3721   exp_lineno = line_number;
3722   ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3723   rval = 1;
3724   if (ttok == &matched_pair_error)
3725     return -1;
3726   /* Check that the next character is the closing right paren.  If
3727      not, this is a syntax error. ( */
3728   c = shell_getc (0);
3729   if MBTEST(c != ')')
3730     rval = 0;
3731
3732   tokstr = (char *)xmalloc (ttoklen + 4);
3733
3734   /* if ADDDQ != 0 then (( ... )) -> "..." */
3735   if (rval == 1 && adddq)       /* arith cmd, add double quotes */
3736     {
3737       tokstr[0] = '"';
3738       strncpy (tokstr + 1, ttok, ttoklen - 1);
3739       tokstr[ttoklen] = '"';
3740       tokstr[ttoklen+1] = '\0';
3741     }
3742   else if (rval == 1)           /* arith cmd, don't add double quotes */
3743     {
3744       strncpy (tokstr, ttok, ttoklen - 1);
3745       tokstr[ttoklen-1] = '\0';
3746     }
3747   else                          /* nested subshell */
3748     {
3749       tokstr[0] = '(';
3750       strncpy (tokstr + 1, ttok, ttoklen - 1);
3751       tokstr[ttoklen] = ')';
3752       tokstr[ttoklen+1] = c;
3753       tokstr[ttoklen+2] = '\0';
3754     }
3755
3756   *ep = tokstr;
3757   FREE (ttok);
3758   return rval;
3759 }
3760 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
3761
3762 #if defined (COND_COMMAND)
3763 static void
3764 cond_error ()
3765 {
3766   char *etext;
3767
3768   if (EOF_Reached && cond_token != COND_ERROR)          /* [[ */
3769     parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
3770   else if (cond_token != COND_ERROR)
3771     {
3772       if (etext = error_token_from_token (cond_token))
3773         {
3774           parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
3775           free (etext);
3776         }
3777       else
3778         parser_error (cond_lineno, _("syntax error in conditional expression"));
3779     }
3780 }
3781
3782 static COND_COM *
3783 cond_expr ()
3784 {
3785   return (cond_or ());  
3786 }
3787
3788 static COND_COM *
3789 cond_or ()
3790 {
3791   COND_COM *l, *r;
3792
3793   l = cond_and ();
3794   if (cond_token == OR_OR)
3795     {
3796       r = cond_or ();
3797       l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3798     }
3799   return l;
3800 }
3801
3802 static COND_COM *
3803 cond_and ()
3804 {
3805   COND_COM *l, *r;
3806
3807   l = cond_term ();
3808   if (cond_token == AND_AND)
3809     {
3810       r = cond_and ();
3811       l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3812     }
3813   return l;
3814 }
3815
3816 static int
3817 cond_skip_newlines ()
3818 {
3819   while ((cond_token = read_token (READ)) == '\n')
3820     {
3821       if (SHOULD_PROMPT ())
3822         prompt_again ();
3823     }
3824   return (cond_token);
3825 }
3826
3827 #define COND_RETURN_ERROR() \
3828   do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3829
3830 static COND_COM *
3831 cond_term ()
3832 {
3833   WORD_DESC *op;
3834   COND_COM *term, *tleft, *tright;
3835   int tok, lineno;
3836   char *etext;
3837
3838   /* Read a token.  It can be a left paren, a `!', a unary operator, or a
3839      word that should be the first argument of a binary operator.  Start by
3840      skipping newlines, since this is a compound command. */
3841   tok = cond_skip_newlines ();
3842   lineno = line_number;
3843   if (tok == COND_END)
3844     {
3845       COND_RETURN_ERROR ();
3846     }
3847   else if (tok == '(')
3848     {
3849       term = cond_expr ();
3850       if (cond_token != ')')
3851         {
3852           if (term)
3853             dispose_cond_node (term);           /* ( */
3854           if (etext = error_token_from_token (cond_token))
3855             {
3856               parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
3857               free (etext);
3858             }
3859           else
3860             parser_error (lineno, _("expected `)'"));
3861           COND_RETURN_ERROR ();
3862         }
3863       term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3864       (void)cond_skip_newlines ();
3865     }
3866   else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3867     {
3868       if (tok == WORD)
3869         dispose_word (yylval.word);     /* not needed */
3870       term = cond_term ();
3871       if (term)
3872         term->flags |= CMD_INVERT_RETURN;
3873     }
3874   else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
3875     {
3876       op = yylval.word;
3877       tok = read_token (READ);
3878       if (tok == WORD)
3879         {
3880           tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3881           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3882         }
3883       else
3884         {
3885           dispose_word (op);
3886           if (etext = error_token_from_token (tok))
3887             {
3888               parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
3889               free (etext);
3890             }
3891           else
3892             parser_error (line_number, _("unexpected argument to conditional unary operator"));
3893           COND_RETURN_ERROR ();
3894         }
3895
3896       (void)cond_skip_newlines ();
3897     }
3898   else if (tok == WORD)         /* left argument to binary operator */
3899     {
3900       /* lhs */
3901       tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3902
3903       /* binop */
3904       tok = read_token (READ);
3905       if (tok == WORD && test_binop (yylval.word->word))
3906         op = yylval.word;
3907 #if defined (COND_REGEXP)
3908       else if (tok == WORD && STREQ (yylval.word->word, "=~"))
3909         {
3910           op = yylval.word;
3911           parser_state |= PST_REGEXP;
3912         }
3913 #endif
3914       else if (tok == '<' || tok == '>')
3915         op = make_word_from_token (tok);  /* ( */
3916       /* There should be a check before blindly accepting the `)' that we have
3917          seen the opening `('. */
3918       else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
3919         {
3920           /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
3921              the test command.  Similarly for [[ x && expr ]] or
3922              [[ x || expr ]] or [[ (x) ]]. */
3923           op = make_word ("-n");
3924           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3925           cond_token = tok;
3926           return (term);
3927         }
3928       else
3929         {
3930           if (etext = error_token_from_token (tok))
3931             {
3932               parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
3933               free (etext);
3934             }
3935           else
3936             parser_error (line_number, _("conditional binary operator expected"));
3937           dispose_cond_node (tleft);
3938           COND_RETURN_ERROR ();
3939         }
3940
3941       /* rhs */
3942       tok = read_token (READ);
3943       parser_state &= ~PST_REGEXP;
3944       if (tok == WORD)
3945         {
3946           tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3947           term = make_cond_node (COND_BINARY, op, tleft, tright);
3948         }
3949       else
3950         {
3951           if (etext = error_token_from_token (tok))
3952             {
3953               parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
3954               free (etext);
3955             }
3956           else
3957             parser_error (line_number, _("unexpected argument to conditional binary operator"));
3958           dispose_cond_node (tleft);
3959           dispose_word (op);
3960           COND_RETURN_ERROR ();
3961         }
3962
3963       (void)cond_skip_newlines ();
3964     }
3965   else
3966     {
3967       if (tok < 256)
3968         parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
3969       else if (etext = error_token_from_token (tok))
3970         {
3971           parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
3972           free (etext);
3973         }
3974       else
3975         parser_error (line_number, _("unexpected token %d in conditional command"), tok);
3976       COND_RETURN_ERROR ();
3977     }
3978   return (term);
3979 }      
3980
3981 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3982    here to handle the conditional statement syntax. */
3983 static COMMAND *
3984 parse_cond_command ()
3985 {
3986   COND_COM *cexp;
3987
3988   cexp = cond_expr ();
3989   return (make_cond_command (cexp));
3990 }
3991 #endif
3992
3993 #if defined (ARRAY_VARS)
3994 /* When this is called, it's guaranteed that we don't care about anything
3995    in t beyond i.  We do save and restore the chars, though. */
3996 static int
3997 token_is_assignment (t, i)
3998      char *t;
3999      int i;
4000 {
4001   unsigned char c, c1;
4002   int r;
4003
4004   c = t[i]; c1 = t[i+1];
4005   t[i] = '='; t[i+1] = '\0';
4006   r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
4007   t[i] = c; t[i+1] = c1;
4008   return r;
4009 }
4010
4011 /* XXX - possible changes here for `+=' */
4012 static int
4013 token_is_ident (t, i)
4014      char *t;
4015      int i;
4016 {
4017   unsigned char c;
4018   int r;
4019
4020   c = t[i];
4021   t[i] = '\0';
4022   r = legal_identifier (t);
4023   t[i] = c;
4024   return r;
4025 }
4026 #endif
4027
4028 static int
4029 read_token_word (character)
4030      int character;
4031 {
4032   /* The value for YYLVAL when a WORD is read. */
4033   WORD_DESC *the_word;
4034
4035   /* Index into the token that we are building. */
4036   int token_index;
4037
4038   /* ALL_DIGITS becomes zero when we see a non-digit. */
4039   int all_digit_token;
4040
4041   /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4042   int dollar_present;
4043
4044   /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4045      assignment. */
4046   int compound_assignment;
4047
4048   /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4049   int quoted;
4050
4051   /* Non-zero means to ignore the value of the next character, and just
4052      to add it no matter what. */
4053  int pass_next_character;
4054
4055   /* The current delimiting character. */
4056   int cd;
4057   int result, peek_char;
4058   char *ttok, *ttrans;
4059   int ttoklen, ttranslen;
4060   intmax_t lvalue;
4061
4062   if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
4063     token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
4064
4065   token_index = 0;
4066   all_digit_token = DIGIT (character);
4067   dollar_present = quoted = pass_next_character = compound_assignment = 0;
4068
4069   for (;;)
4070     {
4071       if (character == EOF)
4072         goto got_token;
4073
4074       if (pass_next_character)
4075         {
4076           pass_next_character = 0;
4077           goto got_escaped_character;
4078         }
4079
4080       cd = current_delimiter (dstack);
4081
4082       /* Handle backslashes.  Quote lots of things when not inside of
4083          double-quotes, quote some things inside of double-quotes. */
4084       if MBTEST(character == '\\')
4085         {
4086           peek_char = shell_getc (0);
4087
4088           /* Backslash-newline is ignored in all cases except
4089              when quoted with single quotes. */
4090           if (peek_char == '\n')
4091             {
4092               character = '\n';
4093               goto next_character;
4094             }
4095           else
4096             {
4097               shell_ungetc (peek_char);
4098
4099               /* If the next character is to be quoted, note it now. */
4100               if (cd == 0 || cd == '`' ||
4101                   (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
4102                 pass_next_character++;
4103
4104               quoted = 1;
4105               goto got_character;
4106             }
4107         }
4108
4109       /* Parse a matched pair of quote characters. */
4110       if MBTEST(shellquote (character))
4111         {
4112           push_delimiter (dstack, character);
4113           ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
4114           pop_delimiter (dstack);
4115           if (ttok == &matched_pair_error)
4116             return -1;          /* Bail immediately. */
4117           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4118                                   token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4119           token[token_index++] = character;
4120           strcpy (token + token_index, ttok);
4121           token_index += ttoklen;
4122           all_digit_token = 0;
4123           quoted = 1;
4124           dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4125           FREE (ttok);
4126           goto next_character;
4127         }
4128
4129 #ifdef COND_REGEXP
4130       /* When parsing a regexp as a single word inside a conditional command,
4131          we need to special-case characters special to both the shell and
4132          regular expressions.  Right now, that is only '(' and '|'. */ /*)*/
4133       if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|'))          /*)*/
4134         {
4135           if (character == '|')
4136             goto got_character;
4137
4138           push_delimiter (dstack, character);
4139           ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4140           pop_delimiter (dstack);
4141           if (ttok == &matched_pair_error)
4142             return -1;          /* Bail immediately. */
4143           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4144                                   token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4145           token[token_index++] = character;
4146           strcpy (token + token_index, ttok);
4147           token_index += ttoklen;
4148           FREE (ttok);
4149           dollar_present = all_digit_token = 0;
4150           goto next_character;
4151         }
4152 #endif /* COND_REGEXP */
4153
4154 #ifdef EXTENDED_GLOB
4155       /* Parse a ksh-style extended pattern matching specification. */
4156       if MBTEST(extended_glob && PATTERN_CHAR (character))
4157         {
4158           peek_char = shell_getc (1);
4159           if MBTEST(peek_char == '(')           /* ) */
4160             {
4161               push_delimiter (dstack, peek_char);
4162               ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4163               pop_delimiter (dstack);
4164               if (ttok == &matched_pair_error)
4165                 return -1;              /* Bail immediately. */
4166               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4167                                       token_buffer_size,
4168                                       TOKEN_DEFAULT_GROW_SIZE);
4169               token[token_index++] = character;
4170               token[token_index++] = peek_char;
4171               strcpy (token + token_index, ttok);
4172               token_index += ttoklen;
4173               FREE (ttok);
4174               dollar_present = all_digit_token = 0;
4175               goto next_character;
4176             }
4177           else
4178             shell_ungetc (peek_char);
4179         }
4180 #endif /* EXTENDED_GLOB */
4181
4182       /* If the delimiter character is not single quote, parse some of
4183          the shell expansions that must be read as a single word. */
4184       if (shellexp (character))
4185         {
4186           peek_char = shell_getc (1);
4187           /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4188           if MBTEST(peek_char == '(' || \
4189                 ((peek_char == '{' || peek_char == '[') && character == '$'))   /* ) ] } */
4190             {
4191               if (peek_char == '{')             /* } */
4192                 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
4193               else if (peek_char == '(')                /* ) */
4194                 {
4195                   /* XXX - push and pop the `(' as a delimiter for use by
4196                      the command-oriented-history code.  This way newlines
4197                      appearing in the $(...) string get added to the
4198                      history literally rather than causing a possibly-
4199                      incorrect `;' to be added. ) */
4200                   push_delimiter (dstack, peek_char);
4201                   ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
4202                   pop_delimiter (dstack);
4203                 }
4204               else
4205                 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4206               if (ttok == &matched_pair_error)
4207                 return -1;              /* Bail immediately. */
4208               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4209                                       token_buffer_size,
4210                                       TOKEN_DEFAULT_GROW_SIZE);
4211               token[token_index++] = character;
4212               token[token_index++] = peek_char;
4213               strcpy (token + token_index, ttok);
4214               token_index += ttoklen;
4215               FREE (ttok);
4216               dollar_present = 1;
4217               all_digit_token = 0;
4218               goto next_character;
4219             }
4220           /* This handles $'...' and $"..." new-style quoted strings. */
4221           else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
4222             {
4223               int first_line;
4224
4225               first_line = line_number;
4226               push_delimiter (dstack, peek_char);
4227               ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4228                                          &ttoklen,
4229                                          (peek_char == '\'') ? P_ALLOWESC : 0);
4230               pop_delimiter (dstack);
4231               if (ttok == &matched_pair_error)
4232                 return -1;
4233               if (peek_char == '\'')
4234                 {
4235                   ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4236                   free (ttok);
4237
4238                   /* Insert the single quotes and correctly quote any
4239                      embedded single quotes (allowed because P_ALLOWESC was
4240                      passed to parse_matched_pair). */
4241                   ttok = sh_single_quote (ttrans);
4242                   free (ttrans);
4243                   ttranslen = strlen (ttok);
4244                   ttrans = ttok;
4245                 }
4246               else
4247                 {
4248                   /* Try to locale-expand the converted string. */
4249                   ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4250                   free (ttok);
4251
4252                   /* Add the double quotes back */
4253                   ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
4254                   free (ttrans);
4255                   ttranslen += 2;
4256                   ttrans = ttok;
4257                 }
4258
4259               RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4260                                       token_buffer_size,
4261                                       TOKEN_DEFAULT_GROW_SIZE);
4262               strcpy (token + token_index, ttrans);
4263               token_index += ttranslen;
4264               FREE (ttrans);
4265               quoted = 1;
4266               all_digit_token = 0;
4267               goto next_character;
4268             }
4269           /* This could eventually be extended to recognize all of the
4270              shell's single-character parameter expansions, and set flags.*/
4271           else if MBTEST(character == '$' && peek_char == '$')
4272             {
4273               ttok = (char *)xmalloc (3);
4274               ttok[0] = ttok[1] = '$';
4275               ttok[2] = '\0';
4276               RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4277                                       token_buffer_size,
4278                                       TOKEN_DEFAULT_GROW_SIZE);
4279               strcpy (token + token_index, ttok);
4280               token_index += 2;
4281               dollar_present = 1;
4282               all_digit_token = 0;
4283               FREE (ttok);
4284               goto next_character;
4285             }
4286           else
4287             shell_ungetc (peek_char);
4288         }
4289
4290 #if defined (ARRAY_VARS)
4291       /* Identify possible array subscript assignment; match [...].  If
4292          parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
4293          `sub' as if it were enclosed in double quotes. */
4294       else if MBTEST(character == '[' &&                /* ] */
4295                      ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
4296                       (token_index == 0 && (parser_state&PST_COMPASSIGN))))
4297         {
4298           ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
4299           if (ttok == &matched_pair_error)
4300             return -1;          /* Bail immediately. */
4301           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4302                                   token_buffer_size,
4303                                   TOKEN_DEFAULT_GROW_SIZE);
4304           token[token_index++] = character;
4305           strcpy (token + token_index, ttok);
4306           token_index += ttoklen;
4307           FREE (ttok);
4308           all_digit_token = 0;
4309           goto next_character;
4310         }
4311       /* Identify possible compound array variable assignment. */
4312       else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
4313         {
4314           peek_char = shell_getc (1);
4315           if MBTEST(peek_char == '(')           /* ) */
4316             {
4317               ttok = parse_compound_assignment (&ttoklen);
4318
4319               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
4320                                       token_buffer_size,
4321                                       TOKEN_DEFAULT_GROW_SIZE);
4322
4323               token[token_index++] = '=';
4324               token[token_index++] = '(';
4325               if (ttok)
4326                 {
4327                   strcpy (token + token_index, ttok);
4328                   token_index += ttoklen;
4329                 }
4330               token[token_index++] = ')';
4331               FREE (ttok);
4332               all_digit_token = 0;
4333               compound_assignment = 1;
4334 #if 1
4335               goto next_character;
4336 #else
4337               goto got_token;           /* ksh93 seems to do this */
4338 #endif
4339             }
4340           else
4341             shell_ungetc (peek_char);
4342         }
4343 #endif
4344
4345       /* When not parsing a multi-character word construct, shell meta-
4346          characters break words. */
4347       if MBTEST(shellbreak (character))
4348         {
4349           shell_ungetc (character);
4350           goto got_token;
4351         }
4352
4353     got_character:
4354
4355       if (character == CTLESC || character == CTLNUL)
4356         token[token_index++] = CTLESC;
4357
4358     got_escaped_character:
4359
4360       all_digit_token &= DIGIT (character);
4361       dollar_present |= character == '$';
4362
4363       token[token_index++] = character;
4364
4365       RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4366                               TOKEN_DEFAULT_GROW_SIZE);
4367
4368     next_character:
4369       if (character == '\n' && SHOULD_PROMPT ())
4370         prompt_again ();
4371
4372       /* We want to remove quoted newlines (that is, a \<newline> pair)
4373          unless we are within single quotes or pass_next_character is
4374          set (the shell equivalent of literal-next). */
4375       cd = current_delimiter (dstack);
4376       character = shell_getc (cd != '\'' && pass_next_character == 0);
4377     }   /* end for (;;) */
4378
4379 got_token:
4380
4381   token[token_index] = '\0';
4382
4383   /* Check to see what thing we should return.  If the last_read_token
4384      is a `<', or a `&', or the character which ended this token is
4385      a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4386      Otherwise, it is just a word, and should be returned as such. */
4387   if MBTEST(all_digit_token && (character == '<' || character == '>' || \
4388                     last_read_token == LESS_AND || \
4389                     last_read_token == GREATER_AND))
4390       {
4391         if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
4392           yylval.number = lvalue;
4393         else
4394           yylval.number = -1;
4395         return (NUMBER);
4396       }
4397
4398   /* Check for special case tokens. */
4399   result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
4400   if (result >= 0)
4401     return result;
4402
4403 #if defined (ALIAS)
4404   /* Posix.2 does not allow reserved words to be aliased, so check for all
4405      of them, including special cases, before expanding the current token
4406      as an alias. */
4407   if MBTEST(posixly_correct)
4408     CHECK_FOR_RESERVED_WORD (token);
4409
4410   /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4411      inhibits alias expansion. */
4412   if (expand_aliases && quoted == 0)
4413     {
4414       result = alias_expand_token (token);
4415       if (result == RE_READ_TOKEN)
4416         return (RE_READ_TOKEN);
4417       else if (result == NO_EXPANSION)
4418         parser_state &= ~PST_ALEXPNEXT;
4419     }
4420
4421   /* If not in Posix.2 mode, check for reserved words after alias
4422      expansion. */
4423   if MBTEST(posixly_correct == 0)
4424 #endif
4425     CHECK_FOR_RESERVED_WORD (token);
4426
4427   the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4428   the_word->word = (char *)xmalloc (1 + token_index);
4429   the_word->flags = 0;
4430   strcpy (the_word->word, token);
4431   if (dollar_present)
4432     the_word->flags |= W_HASDOLLAR;
4433   if (quoted)
4434     the_word->flags |= W_QUOTED;                /*(*/
4435   if (compound_assignment && token[token_index-1] == ')')
4436     the_word->flags |= W_COMPASSIGN;
4437   /* A word is an assignment if it appears at the beginning of a
4438      simple command, or after another assignment word.  This is
4439      context-dependent, so it cannot be handled in the grammar. */
4440   if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
4441     {
4442       the_word->flags |= W_ASSIGNMENT;
4443       /* Don't perform word splitting on assignment statements. */
4444       if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
4445         the_word->flags |= W_NOSPLIT;
4446     }
4447
4448   if (command_token_position (last_read_token))
4449     {
4450       struct builtin *b;
4451       b = builtin_address_internal (token, 0);
4452       if (b && (b->flags & ASSIGNMENT_BUILTIN))
4453         parser_state |= PST_ASSIGNOK;
4454       else if (STREQ (token, "eval") || STREQ (token, "let"))
4455         parser_state |= PST_ASSIGNOK;
4456     }
4457
4458   yylval.word = the_word;
4459
4460   result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4461                 ? ASSIGNMENT_WORD : WORD;
4462
4463   switch (last_read_token)
4464     {
4465     case FUNCTION:
4466       parser_state |= PST_ALLOWOPNBRC;
4467       function_dstart = line_number;
4468       break;
4469     case CASE:
4470     case SELECT:
4471     case FOR:
4472       if (word_top < MAX_CASE_NEST)
4473         word_top++;
4474       word_lineno[word_top] = line_number;
4475       break;
4476     }
4477
4478   return (result);
4479 }
4480
4481 /* Return 1 if TOKSYM is a token that after being read would allow
4482    a reserved word to be seen, else 0. */
4483 static int
4484 reserved_word_acceptable (toksym)
4485      int toksym;
4486 {
4487   switch (toksym)
4488     {
4489     case '\n':
4490     case ';':
4491     case '(':
4492     case ')':
4493     case '|':
4494     case '&':
4495     case '{':
4496     case '}':           /* XXX */
4497     case AND_AND:
4498     case BANG:
4499     case BAR_AND:
4500     case DO:
4501     case DONE:
4502     case ELIF:
4503     case ELSE:
4504     case ESAC:
4505     case FI:
4506     case IF:
4507     case OR_OR:
4508     case SEMI_SEMI:
4509     case SEMI_AND:
4510     case SEMI_SEMI_AND:
4511     case THEN:
4512     case TIME:
4513     case TIMEOPT:
4514     case COPROC:
4515     case UNTIL:
4516     case WHILE:
4517     case 0:
4518       return 1;
4519     default:
4520 #if defined (COPROCESS_SUPPORT)
4521       if (last_read_token == WORD && token_before_that == COPROC)
4522         return 1;
4523 #endif
4524       return 0;
4525     }
4526 }
4527     
4528 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4529    TOKEN is not a shell reserved word. */
4530 int
4531 find_reserved_word (tokstr)
4532      char *tokstr;
4533 {
4534   int i;
4535   for (i = 0; word_token_alist[i].word; i++)
4536     if (STREQ (tokstr, word_token_alist[i].word))
4537       return i;
4538   return -1;
4539 }
4540
4541 #if 0
4542 #if defined (READLINE)
4543 /* Called after each time readline is called.  This insures that whatever
4544    the new prompt string is gets propagated to readline's local prompt
4545    variable. */
4546 static void
4547 reset_readline_prompt ()
4548 {
4549   char *temp_prompt;
4550
4551   if (prompt_string_pointer)
4552     {
4553       temp_prompt = (*prompt_string_pointer)
4554                         ? decode_prompt_string (*prompt_string_pointer)
4555                         : (char *)NULL;
4556
4557       if (temp_prompt == 0)
4558         {
4559           temp_prompt = (char *)xmalloc (1);
4560           temp_prompt[0] = '\0';
4561         }
4562
4563       FREE (current_readline_prompt);
4564       current_readline_prompt = temp_prompt;
4565     }
4566 }
4567 #endif /* READLINE */
4568 #endif /* 0 */
4569
4570 #if defined (HISTORY)
4571 /* A list of tokens which can be followed by newlines, but not by
4572    semi-colons.  When concatenating multiple lines of history, the
4573    newline separator for such tokens is replaced with a space. */
4574 static const int no_semi_successors[] = {
4575   '\n', '{', '(', ')', ';', '&', '|',
4576   CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
4577   WHILE, AND_AND, OR_OR, IN,
4578   0
4579 };
4580
4581 /* If we are not within a delimited expression, try to be smart
4582    about which separators can be semi-colons and which must be
4583    newlines.  Returns the string that should be added into the
4584    history entry. */
4585 char *
4586 history_delimiting_chars ()
4587 {
4588   register int i;
4589
4590   if (dstack.delimiter_depth != 0)
4591     return ("\n");
4592
4593   /* We look for current_command_line_count == 2 because we are looking to
4594      add the first line of the body of the here document (the second line
4595      of the command). */
4596   if (parser_state & PST_HEREDOC)
4597     return (current_command_line_count == 2 ? "\n" : "");
4598
4599   /* First, handle some special cases. */
4600   /*(*/
4601   /* If we just read `()', assume it's a function definition, and don't
4602      add a semicolon.  If the token before the `)' was not `(', and we're
4603      not in the midst of parsing a case statement, assume it's a
4604      parenthesized command and add the semicolon. */
4605   /*)(*/
4606   if (token_before_that == ')')
4607     {
4608       if (two_tokens_ago == '(')        /*)*/   /* function def */
4609         return " ";
4610       /* This does not work for subshells inside case statement
4611          command lists.  It's a suboptimal solution. */
4612       else if (parser_state & PST_CASESTMT)     /* case statement pattern */
4613         return " ";
4614       else      
4615         return "; ";                            /* (...) subshell */
4616     }
4617   else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4618     return " ";         /* function def using `function name' without `()' */
4619
4620   else if (token_before_that == WORD && two_tokens_ago == FOR)
4621     {
4622       /* Tricky.  `for i\nin ...' should not have a semicolon, but
4623          `for i\ndo ...' should.  We do what we can. */
4624       for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
4625         ;
4626       if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
4627         return " ";
4628       return ";";
4629     }
4630   else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
4631     return " ";
4632
4633   for (i = 0; no_semi_successors[i]; i++)
4634     {
4635       if (token_before_that == no_semi_successors[i])
4636         return (" ");
4637     }
4638
4639   return ("; ");
4640 }
4641 #endif /* HISTORY */
4642
4643 /* Issue a prompt, or prepare to issue a prompt when the next character
4644    is read. */
4645 static void
4646 prompt_again ()
4647 {
4648   char *temp_prompt;
4649
4650   if (interactive == 0 || expanding_alias())    /* XXX */
4651     return;
4652
4653   ps1_prompt = get_string_value ("PS1");
4654   ps2_prompt = get_string_value ("PS2");
4655
4656   if (!prompt_string_pointer)
4657     prompt_string_pointer = &ps1_prompt;
4658
4659   temp_prompt = *prompt_string_pointer
4660                         ? decode_prompt_string (*prompt_string_pointer)
4661                         : (char *)NULL;
4662
4663   if (temp_prompt == 0)
4664     {
4665       temp_prompt = (char *)xmalloc (1);
4666       temp_prompt[0] = '\0';
4667     }
4668
4669   current_prompt_string = *prompt_string_pointer;
4670   prompt_string_pointer = &ps2_prompt;
4671
4672 #if defined (READLINE)
4673   if (!no_line_editing)
4674     {
4675       FREE (current_readline_prompt);
4676       current_readline_prompt = temp_prompt;
4677     }
4678   else
4679 #endif  /* READLINE */
4680     {
4681       FREE (current_decoded_prompt);
4682       current_decoded_prompt = temp_prompt;
4683     }
4684 }
4685
4686 int
4687 get_current_prompt_level ()
4688 {
4689   return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
4690 }
4691
4692 void
4693 set_current_prompt_level (x)
4694      int x;
4695 {
4696   prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
4697   current_prompt_string = *prompt_string_pointer;
4698 }
4699       
4700 static void
4701 print_prompt ()
4702 {
4703   fprintf (stderr, "%s", current_decoded_prompt);
4704   fflush (stderr);
4705 }
4706
4707 /* Return a string which will be printed as a prompt.  The string
4708    may contain special characters which are decoded as follows:
4709
4710         \a      bell (ascii 07)
4711         \d      the date in Day Mon Date format
4712         \e      escape (ascii 033)
4713         \h      the hostname up to the first `.'
4714         \H      the hostname
4715         \j      the number of active jobs
4716         \l      the basename of the shell's tty device name
4717         \n      CRLF
4718         \r      CR
4719         \s      the name of the shell
4720         \t      the time in 24-hour hh:mm:ss format
4721         \T      the time in 12-hour hh:mm:ss format
4722         \@      the time in 12-hour hh:mm am/pm format
4723         \A      the time in 24-hour hh:mm format
4724         \D{fmt} the result of passing FMT to strftime(3)
4725         \u      your username
4726         \v      the version of bash (e.g., 2.00)
4727         \V      the release of bash, version + patchlevel (e.g., 2.00.0)
4728         \w      the current working directory
4729         \W      the last element of $PWD
4730         \!      the history number of this command
4731         \#      the command number of this command
4732         \$      a $ or a # if you are root
4733         \nnn    character code nnn in octal
4734         \\      a backslash
4735         \[      begin a sequence of non-printing chars
4736         \]      end a sequence of non-printing chars
4737 */
4738 #define PROMPT_GROWTH 48
4739 char *
4740 decode_prompt_string (string)
4741      char *string;
4742 {
4743   WORD_LIST *list;
4744   char *result, *t;
4745   struct dstack save_dstack;
4746   int last_exit_value;
4747 #if defined (PROMPT_STRING_DECODE)
4748   int result_size, result_index;
4749   int c, n, i;
4750   char *temp, octal_string[4];
4751   struct tm *tm;  
4752   time_t the_time;
4753   char timebuf[128];
4754   char *timefmt;
4755
4756   result = (char *)xmalloc (result_size = PROMPT_GROWTH);
4757   result[result_index = 0] = 0;
4758   temp = (char *)NULL;
4759
4760   while (c = *string++)
4761     {
4762       if (posixly_correct && c == '!')
4763         {
4764           if (*string == '!')
4765             {
4766               temp = savestring ("!");
4767               goto add_string;
4768             }
4769           else
4770             {
4771 #if !defined (HISTORY)
4772                 temp = savestring ("1");
4773 #else /* HISTORY */
4774                 temp = itos (history_number ());
4775 #endif /* HISTORY */
4776                 string--;       /* add_string increments string again. */
4777                 goto add_string;
4778             }
4779         }
4780       if (c == '\\')
4781         {
4782           c = *string;
4783
4784           switch (c)
4785             {
4786             case '0':
4787             case '1':
4788             case '2':
4789             case '3':
4790             case '4':
4791             case '5':
4792             case '6':
4793             case '7':
4794               strncpy (octal_string, string, 3);
4795               octal_string[3] = '\0';
4796
4797               n = read_octal (octal_string);
4798               temp = (char *)xmalloc (3);
4799
4800               if (n == CTLESC || n == CTLNUL)
4801                 {
4802                   temp[0] = CTLESC;
4803                   temp[1] = n;
4804                   temp[2] = '\0';
4805                 }
4806               else if (n == -1)
4807                 {
4808                   temp[0] = '\\';
4809                   temp[1] = '\0';
4810                 }
4811               else
4812                 {
4813                   temp[0] = n;
4814                   temp[1] = '\0';
4815                 }
4816
4817               for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
4818                 string++;
4819
4820               c = 0;            /* tested at add_string: */
4821               goto add_string;
4822
4823             case 'd':
4824             case 't':
4825             case 'T':
4826             case '@':
4827             case 'A':
4828               /* Make the current time/date into a string. */
4829               (void) time (&the_time);
4830               tm = localtime (&the_time);
4831
4832               if (c == 'd')
4833                 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
4834               else if (c == 't')
4835                 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
4836               else if (c == 'T')
4837                 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
4838               else if (c == '@')
4839                 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
4840               else if (c == 'A')
4841                 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
4842
4843               if (n == 0)
4844                 timebuf[0] = '\0';
4845               else
4846                 timebuf[sizeof(timebuf) - 1] = '\0';
4847
4848               temp = savestring (timebuf);
4849               goto add_string;
4850
4851             case 'D':           /* strftime format */
4852               if (string[1] != '{')             /* } */
4853                 goto not_escape;
4854
4855               (void) time (&the_time);
4856               tm = localtime (&the_time);
4857               string += 2;                      /* skip { */
4858               timefmt = xmalloc (strlen (string) + 3);
4859               for (t = timefmt; *string && *string != '}'; )
4860                 *t++ = *string++;
4861               *t = '\0';
4862               c = *string;      /* tested at add_string */
4863               if (timefmt[0] == '\0')
4864                 {
4865                   timefmt[0] = '%';
4866                   timefmt[1] = 'X';     /* locale-specific current time */
4867                   timefmt[2] = '\0';
4868                 }
4869               n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
4870               free (timefmt);
4871
4872               if (n == 0)
4873                 timebuf[0] = '\0';
4874               else
4875                 timebuf[sizeof(timebuf) - 1] = '\0';
4876
4877               if (promptvars || posixly_correct)
4878                 /* Make sure that expand_prompt_string is called with a
4879                    second argument of Q_DOUBLE_QUOTES if we use this
4880                    function here. */
4881                 temp = sh_backslash_quote_for_double_quotes (timebuf);
4882               else
4883                 temp = savestring (timebuf);
4884               goto add_string;
4885               
4886             case 'n':
4887               temp = (char *)xmalloc (3);
4888               temp[0] = no_line_editing ? '\n' : '\r';
4889               temp[1] = no_line_editing ? '\0' : '\n';
4890               temp[2] = '\0';
4891               goto add_string;
4892
4893             case 's':
4894               temp = base_pathname (shell_name);
4895               temp = savestring (temp);
4896               goto add_string;
4897
4898             case 'v':
4899             case 'V':
4900               temp = (char *)xmalloc (16);
4901               if (c == 'v')
4902                 strcpy (temp, dist_version);
4903               else
4904                 sprintf (temp, "%s.%d", dist_version, patch_level);
4905               goto add_string;
4906
4907             case 'w':
4908             case 'W':
4909               {
4910                 /* Use the value of PWD because it is much more efficient. */
4911                 char t_string[PATH_MAX];
4912                 int tlen;
4913
4914                 temp = get_string_value ("PWD");
4915
4916                 if (temp == 0)
4917                   {
4918                     if (getcwd (t_string, sizeof(t_string)) == 0)
4919                       {
4920                         t_string[0] = '.';
4921                         tlen = 1;
4922                       }
4923                     else
4924                       tlen = strlen (t_string);
4925                   }
4926                 else
4927                   {
4928                     tlen = sizeof (t_string) - 1;
4929                     strncpy (t_string, temp, tlen);
4930                   }
4931                 t_string[tlen] = '\0';
4932
4933 #define ROOT_PATH(x)    ((x)[0] == '/' && (x)[1] == 0)
4934 #define DOUBLE_SLASH_ROOT(x)    ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
4935                 /* Abbreviate \W as ~ if $PWD == $HOME */
4936                 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
4937                   {
4938                     if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
4939                       {
4940                         t = strrchr (t_string, '/');
4941                         if (t)
4942                           strcpy (t_string, t + 1);
4943                       }
4944                   }
4945 #undef ROOT_PATH
4946 #undef DOUBLE_SLASH_ROOT
4947                 else
4948                   /* polite_directory_format is guaranteed to return a string
4949                      no longer than PATH_MAX - 1 characters. */
4950                   strcpy (t_string, polite_directory_format (t_string));
4951
4952                 temp = trim_pathname (t_string, PATH_MAX - 1);
4953                 /* If we're going to be expanding the prompt string later,
4954                    quote the directory name. */
4955                 if (promptvars || posixly_correct)
4956                   /* Make sure that expand_prompt_string is called with a
4957                      second argument of Q_DOUBLE_QUOTES if we use this
4958                      function here. */
4959                   temp = sh_backslash_quote_for_double_quotes (t_string);
4960                 else
4961                   temp = savestring (t_string);
4962
4963                 goto add_string;
4964               }
4965
4966             case 'u':
4967               if (current_user.user_name == 0)
4968                 get_current_user_info ();
4969               temp = savestring (current_user.user_name);
4970               goto add_string;
4971
4972             case 'h':
4973             case 'H':
4974               temp = savestring (current_host_name);
4975               if (c == 'h' && (t = (char *)strchr (temp, '.')))
4976                 *t = '\0';
4977               goto add_string;
4978
4979             case '#':
4980               temp = itos (current_command_number);
4981               goto add_string;
4982
4983             case '!':
4984 #if !defined (HISTORY)
4985               temp = savestring ("1");
4986 #else /* HISTORY */
4987               temp = itos (history_number ());
4988 #endif /* HISTORY */
4989               goto add_string;
4990
4991             case '$':
4992               t = temp = (char *)xmalloc (3);
4993               if ((promptvars || posixly_correct) && (current_user.euid != 0))
4994                 *t++ = '\\';
4995               *t++ = current_user.euid == 0 ? '#' : '$';
4996               *t = '\0';
4997               goto add_string;
4998
4999             case 'j':
5000               temp = itos (count_all_jobs ());
5001               goto add_string;
5002
5003             case 'l':
5004 #if defined (HAVE_TTYNAME)
5005               temp = (char *)ttyname (fileno (stdin));
5006               t = temp ? base_pathname (temp) : "tty";
5007               temp = savestring (t);
5008 #else
5009               temp = savestring ("tty");
5010 #endif /* !HAVE_TTYNAME */
5011               goto add_string;
5012
5013 #if defined (READLINE)
5014             case '[':
5015             case ']':
5016               if (no_line_editing)
5017                 {
5018                   string++;
5019                   break;
5020                 }
5021               temp = (char *)xmalloc (3);
5022               n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
5023               i = 0;
5024               if (n == CTLESC || n == CTLNUL)
5025                 temp[i++] = CTLESC;
5026               temp[i++] = n;
5027               temp[i] = '\0';
5028               goto add_string;
5029 #endif /* READLINE */
5030
5031             case '\\':
5032             case 'a':
5033             case 'e':
5034             case 'r':
5035               temp = (char *)xmalloc (2);
5036               if (c == 'a')
5037                 temp[0] = '\07';
5038               else if (c == 'e')
5039                 temp[0] = '\033';
5040               else if (c == 'r')
5041                 temp[0] = '\r';
5042               else                      /* (c == '\\') */
5043                 temp[0] = c;
5044               temp[1] = '\0';
5045               goto add_string;
5046
5047             default:
5048 not_escape:
5049               temp = (char *)xmalloc (3);
5050               temp[0] = '\\';
5051               temp[1] = c;
5052               temp[2] = '\0';
5053
5054             add_string:
5055               if (c)
5056                 string++;
5057               result =
5058                 sub_append_string (temp, result, &result_index, &result_size);
5059               temp = (char *)NULL; /* Freed in sub_append_string (). */
5060               result[result_index] = '\0';
5061               break;
5062             }
5063         }
5064       else
5065         {
5066           RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
5067           result[result_index++] = c;
5068           result[result_index] = '\0';
5069         }
5070     }
5071 #else /* !PROMPT_STRING_DECODE */
5072   result = savestring (string);
5073 #endif /* !PROMPT_STRING_DECODE */
5074
5075   /* Save the delimiter stack and point `dstack' to temp space so any
5076      command substitutions in the prompt string won't result in screwing
5077      up the parser's quoting state. */
5078   save_dstack = dstack;
5079   dstack = temp_dstack;
5080   dstack.delimiter_depth = 0;
5081
5082   /* Perform variable and parameter expansion and command substitution on
5083      the prompt string. */
5084   if (promptvars || posixly_correct)
5085     {
5086       last_exit_value = last_command_exit_value;
5087       list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
5088       free (result);
5089       result = string_list (list);
5090       dispose_words (list);
5091       last_command_exit_value = last_exit_value;
5092     }
5093   else
5094     {
5095       t = dequote_string (result);
5096       free (result);
5097       result = t;
5098     }
5099
5100   dstack = save_dstack;
5101
5102   return (result);
5103 }
5104
5105 /************************************************
5106  *                                              *
5107  *              ERROR HANDLING                  *
5108  *                                              *
5109  ************************************************/
5110
5111 /* Report a syntax error, and restart the parser.  Call here for fatal
5112    errors. */
5113 int
5114 yyerror (msg)
5115      const char *msg;
5116 {
5117   report_syntax_error ((char *)NULL);
5118   reset_parser ();
5119   return (0);
5120 }
5121
5122 static char *
5123 error_token_from_token (tok)
5124      int tok;
5125 {
5126   char *t;
5127
5128   if (t = find_token_in_alist (tok, word_token_alist, 0))
5129     return t;
5130
5131   if (t = find_token_in_alist (tok, other_token_alist, 0))
5132     return t;
5133
5134   t = (char *)NULL;
5135   /* This stuff is dicy and needs closer inspection */
5136   switch (current_token)
5137     {
5138     case WORD:
5139     case ASSIGNMENT_WORD:
5140       if (yylval.word)
5141         t = savestring (yylval.word->word);
5142       break;
5143     case NUMBER:
5144       t = itos (yylval.number);
5145       break;
5146     case ARITH_CMD:
5147       if (yylval.word_list)
5148         t = string_list (yylval.word_list);
5149       break;
5150     case ARITH_FOR_EXPRS:
5151       if (yylval.word_list)
5152         t = string_list_internal (yylval.word_list, " ; ");
5153       break;
5154     case COND_CMD:
5155       t = (char *)NULL;         /* punt */
5156       break;
5157     }
5158
5159   return t;
5160 }
5161
5162 static char *
5163 error_token_from_text ()
5164 {
5165   char *msg, *t;
5166   int token_end, i;
5167
5168   t = shell_input_line;
5169   i = shell_input_line_index;
5170   token_end = 0;
5171   msg = (char *)NULL;
5172
5173   if (i && t[i] == '\0')
5174     i--;
5175
5176   while (i && (whitespace (t[i]) || t[i] == '\n'))
5177     i--;
5178
5179   if (i)
5180     token_end = i + 1;
5181
5182   while (i && (member (t[i], " \n\t;|&") == 0))
5183     i--;
5184
5185   while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
5186     i++;
5187
5188   /* Return our idea of the offending token. */
5189   if (token_end || (i == 0 && token_end == 0))
5190     {
5191       if (token_end)
5192         msg = substring (t, i, token_end);
5193       else      /* one-character token */
5194         {
5195           msg = (char *)xmalloc (2);
5196           msg[0] = t[i];
5197           msg[1] = '\0';
5198         }
5199     }
5200
5201   return (msg);
5202 }
5203
5204 static void
5205 print_offending_line ()
5206 {
5207   char *msg;
5208   int token_end;
5209
5210   msg = savestring (shell_input_line);
5211   token_end = strlen (msg);
5212   while (token_end && msg[token_end - 1] == '\n')
5213     msg[--token_end] = '\0';
5214
5215   parser_error (line_number, "`%s'", msg);
5216   free (msg);
5217 }
5218
5219 /* Report a syntax error with line numbers, etc.
5220    Call here for recoverable errors.  If you have a message to print,
5221    then place it in MESSAGE, otherwise pass NULL and this will figure
5222    out an appropriate message for you. */
5223 static void
5224 report_syntax_error (message)
5225      char *message;
5226 {
5227   char *msg;
5228
5229   if (message)
5230     {
5231       parser_error (line_number, "%s", message);
5232       if (interactive && EOF_Reached)
5233         EOF_Reached = 0;
5234       last_command_exit_value = EX_USAGE;
5235       return;
5236     }
5237
5238   /* If the line of input we're reading is not null, try to find the
5239      objectionable token.  First, try to figure out what token the
5240      parser's complaining about by looking at current_token. */
5241   if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
5242     {
5243       parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
5244       free (msg);
5245
5246       if (interactive == 0)
5247         print_offending_line ();
5248
5249       last_command_exit_value = EX_USAGE;
5250       return;
5251     }
5252
5253   /* If looking at the current token doesn't prove fruitful, try to find the
5254      offending token by analyzing the text of the input line near the current
5255      input line index and report what we find. */
5256   if (shell_input_line && *shell_input_line)
5257     {
5258       msg = error_token_from_text ();
5259       if (msg)
5260         {
5261           parser_error (line_number, _("syntax error near `%s'"), msg);
5262           free (msg);
5263         }
5264
5265       /* If not interactive, print the line containing the error. */
5266       if (interactive == 0)
5267         print_offending_line ();
5268     }
5269   else
5270     {
5271       msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
5272       parser_error (line_number, "%s", msg);
5273       /* When the shell is interactive, this file uses EOF_Reached
5274          only for error reporting.  Other mechanisms are used to
5275          decide whether or not to exit. */
5276       if (interactive && EOF_Reached)
5277         EOF_Reached = 0;
5278     }
5279
5280   last_command_exit_value = EX_USAGE;
5281 }
5282
5283 /* ??? Needed function. ??? We have to be able to discard the constructs
5284    created during parsing.  In the case of error, we want to return
5285    allocated objects to the memory pool.  In the case of no error, we want
5286    to throw away the information about where the allocated objects live.
5287    (dispose_command () will actually free the command.) */
5288 static void
5289 discard_parser_constructs (error_p)
5290      int error_p;
5291 {
5292 }
5293
5294 /************************************************
5295  *                                              *
5296  *              EOF HANDLING                    *
5297  *                                              *
5298  ************************************************/
5299
5300 /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
5301
5302 /* A flag denoting whether or not ignoreeof is set. */
5303 int ignoreeof = 0;
5304
5305 /* The number of times that we have encountered an EOF character without
5306    another character intervening.  When this gets above the limit, the
5307    shell terminates. */
5308 int eof_encountered = 0;
5309
5310 /* The limit for eof_encountered. */
5311 int eof_encountered_limit = 10;
5312
5313 /* If we have EOF as the only input unit, this user wants to leave
5314    the shell.  If the shell is not interactive, then just leave.
5315    Otherwise, if ignoreeof is set, and we haven't done this the
5316    required number of times in a row, print a message. */
5317 static void
5318 handle_eof_input_unit ()
5319 {
5320   if (interactive)
5321     {
5322       /* shell.c may use this to decide whether or not to write out the
5323          history, among other things.  We use it only for error reporting
5324          in this file. */
5325       if (EOF_Reached)
5326         EOF_Reached = 0;
5327
5328       /* If the user wants to "ignore" eof, then let her do so, kind of. */
5329       if (ignoreeof)
5330         {
5331           if (eof_encountered < eof_encountered_limit)
5332             {
5333               fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
5334                        login_shell ? "logout" : "exit");
5335               eof_encountered++;
5336               /* Reset the parsing state. */
5337               last_read_token = current_token = '\n';
5338               /* Reset the prompt string to be $PS1. */
5339               prompt_string_pointer = (char **)NULL;
5340               prompt_again ();
5341               return;
5342             }
5343         }
5344
5345       /* In this case EOF should exit the shell.  Do it now. */
5346       reset_parser ();
5347       exit_builtin ((WORD_LIST *)NULL);
5348     }
5349   else
5350     {
5351       /* We don't write history files, etc., for non-interactive shells. */
5352       EOF_Reached = 1;
5353     }
5354 }
5355
5356 /************************************************
5357  *                                              *
5358  *      STRING PARSING FUNCTIONS                *
5359  *                                              *
5360  ************************************************/
5361
5362 /* It's very important that these two functions treat the characters
5363    between ( and ) identically. */
5364
5365 static WORD_LIST parse_string_error;
5366
5367 /* Take a string and run it through the shell parser, returning the
5368    resultant word list.  Used by compound array assignment. */
5369 WORD_LIST *
5370 parse_string_to_word_list (s, flags, whom)
5371      char *s;
5372      int flags;
5373      const char *whom;
5374 {
5375   WORD_LIST *wl;
5376   int tok, orig_current_token, orig_line_number, orig_input_terminator;
5377   int orig_line_count;
5378   int old_echo_input, old_expand_aliases;
5379 #if defined (HISTORY)
5380   int old_remember_on_history, old_history_expansion_inhibited;
5381 #endif
5382
5383 #if defined (HISTORY)
5384   old_remember_on_history = remember_on_history;
5385 #  if defined (BANG_HISTORY)
5386   old_history_expansion_inhibited = history_expansion_inhibited;
5387 #  endif
5388   bash_history_disable ();
5389 #endif
5390
5391   orig_line_number = line_number;
5392   orig_line_count = current_command_line_count;
5393   orig_input_terminator = shell_input_line_terminator;
5394   old_echo_input = echo_input_at_read;
5395   old_expand_aliases = expand_aliases;
5396
5397   push_stream (1);
5398   last_read_token = WORD;               /* WORD to allow reserved words here */
5399   current_command_line_count = 0;
5400   echo_input_at_read = expand_aliases = 0;
5401
5402   with_input_from_string (s, whom);
5403   wl = (WORD_LIST *)NULL;
5404
5405   if (flags & 1)
5406     parser_state |= PST_COMPASSIGN|PST_REPARSE;
5407
5408   while ((tok = read_token (READ)) != yacc_EOF)
5409     {
5410       if (tok == '\n' && *bash_input.location.string == '\0')
5411         break;
5412       if (tok == '\n')          /* Allow newlines in compound assignments */
5413         continue;
5414       if (tok != WORD && tok != ASSIGNMENT_WORD)
5415         {
5416           line_number = orig_line_number + line_number - 1;
5417           orig_current_token = current_token;
5418           current_token = tok;
5419           yyerror (NULL);       /* does the right thing */
5420           current_token = orig_current_token;
5421           if (wl)
5422             dispose_words (wl);
5423           wl = &parse_string_error;
5424           break;
5425         }
5426       wl = make_word_list (yylval.word, wl);
5427     }
5428   
5429   last_read_token = '\n';
5430   pop_stream ();
5431
5432 #if defined (HISTORY)
5433   remember_on_history = old_remember_on_history;
5434 #  if defined (BANG_HISTORY)
5435   history_expansion_inhibited = old_history_expansion_inhibited;
5436 #  endif /* BANG_HISTORY */
5437 #endif /* HISTORY */
5438
5439   echo_input_at_read = old_echo_input;
5440   expand_aliases = old_expand_aliases;
5441
5442   current_command_line_count = orig_line_count;
5443   shell_input_line_terminator = orig_input_terminator;
5444
5445   if (flags & 1)
5446     parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
5447
5448   if (wl == &parse_string_error)
5449     {
5450       last_command_exit_value = EXECUTION_FAILURE;
5451       if (interactive_shell == 0 && posixly_correct)
5452         jump_to_top_level (FORCE_EOF);
5453       else
5454         jump_to_top_level (DISCARD);
5455     }
5456
5457   return (REVERSE_LIST (wl, WORD_LIST *));
5458 }
5459
5460 static char *
5461 parse_compound_assignment (retlenp)
5462      int *retlenp;
5463 {
5464   WORD_LIST *wl, *rl;
5465   int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
5466   char *saved_token, *ret;
5467
5468   saved_token = token;
5469   orig_token_size = token_buffer_size;
5470   orig_line_number = line_number;
5471   orig_last_token = last_read_token;
5472
5473   last_read_token = WORD;       /* WORD to allow reserved words here */
5474
5475   token = (char *)NULL;
5476   token_buffer_size = 0;
5477
5478   assignok = parser_state&PST_ASSIGNOK;         /* XXX */
5479
5480   wl = (WORD_LIST *)NULL;       /* ( */
5481   parser_state |= PST_COMPASSIGN;
5482
5483   while ((tok = read_token (READ)) != ')')
5484     {
5485       if (tok == '\n')                  /* Allow newlines in compound assignments */
5486         {
5487           if (SHOULD_PROMPT ())
5488             prompt_again ();
5489           continue;
5490         }
5491       if (tok != WORD && tok != ASSIGNMENT_WORD)
5492         {
5493           current_token = tok;  /* for error reporting */
5494           if (tok == yacc_EOF)  /* ( */
5495             parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
5496           else
5497             yyerror(NULL);      /* does the right thing */
5498           if (wl)
5499             dispose_words (wl);
5500           wl = &parse_string_error;
5501           break;
5502         }
5503       wl = make_word_list (yylval.word, wl);
5504     }
5505
5506   FREE (token);
5507   token = saved_token;
5508   token_buffer_size = orig_token_size;
5509
5510   parser_state &= ~PST_COMPASSIGN;
5511
5512   if (wl == &parse_string_error)
5513     {
5514       last_command_exit_value = EXECUTION_FAILURE;
5515       last_read_token = '\n';   /* XXX */
5516       if (interactive_shell == 0 && posixly_correct)
5517         jump_to_top_level (FORCE_EOF);
5518       else
5519         jump_to_top_level (DISCARD);
5520     }
5521
5522   last_read_token = orig_last_token;            /* XXX - was WORD? */
5523
5524   if (wl)
5525     {
5526       rl = REVERSE_LIST (wl, WORD_LIST *);
5527       ret = string_list (rl);
5528       dispose_words (rl);
5529     }
5530   else
5531     ret = (char *)NULL;
5532
5533   if (retlenp)
5534     *retlenp = (ret && *ret) ? strlen (ret) : 0;
5535
5536   if (assignok)
5537     parser_state |= PST_ASSIGNOK;
5538
5539   return ret;
5540 }
5541
5542 /************************************************
5543  *                                              *
5544  *   SAVING AND RESTORING PARTIAL PARSE STATE   *
5545  *                                              *
5546  ************************************************/
5547
5548 sh_parser_state_t *
5549 save_parser_state (ps)
5550      sh_parser_state_t *ps;
5551 {
5552 #if defined (ARRAY_VARS)
5553   SHELL_VAR *v;
5554 #endif
5555
5556   if (ps == 0)
5557     ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
5558   if (ps == 0)
5559     return ((sh_parser_state_t *)NULL);
5560
5561   ps->parser_state = parser_state;
5562   ps->token_state = save_token_state ();
5563
5564   ps->input_line_terminator = shell_input_line_terminator;
5565   ps->eof_encountered = eof_encountered;
5566
5567   ps->current_command_line_count = current_command_line_count;
5568
5569 #if defined (HISTORY)
5570   ps->remember_on_history = remember_on_history;
5571 #  if defined (BANG_HISTORY)
5572   ps->history_expansion_inhibited = history_expansion_inhibited;
5573 #  endif
5574 #endif
5575
5576   ps->last_command_exit_value = last_command_exit_value;
5577 #if defined (ARRAY_VARS)
5578   v = find_variable ("PIPESTATUS");
5579   if (v && array_p (v) && array_cell (v))
5580     ps->pipestatus = array_copy (array_cell (v));
5581   else
5582     ps->pipestatus = (ARRAY *)NULL;
5583 #endif
5584     
5585   ps->last_shell_builtin = last_shell_builtin;
5586   ps->this_shell_builtin = this_shell_builtin;
5587
5588   ps->expand_aliases = expand_aliases;
5589   ps->echo_input_at_read = echo_input_at_read;
5590
5591   return (ps);
5592 }
5593
5594 void
5595 restore_parser_state (ps)
5596      sh_parser_state_t *ps;
5597 {
5598 #if defined (ARRAY_VARS)
5599   SHELL_VAR *v;
5600 #endif
5601
5602   if (ps == 0)
5603     return;
5604
5605   parser_state = ps->parser_state;
5606   if (ps->token_state)
5607     {
5608       restore_token_state (ps->token_state);
5609       free (ps->token_state);
5610     }
5611
5612   shell_input_line_terminator = ps->input_line_terminator;
5613   eof_encountered = ps->eof_encountered;
5614
5615   current_command_line_count = ps->current_command_line_count;
5616
5617 #if defined (HISTORY)
5618   remember_on_history = ps->remember_on_history;
5619 #  if defined (BANG_HISTORY)
5620   history_expansion_inhibited = ps->history_expansion_inhibited;
5621 #  endif
5622 #endif
5623
5624   last_command_exit_value = ps->last_command_exit_value;
5625 #if defined (ARRAY_VARS)
5626   v = find_variable ("PIPESTATUS");
5627   if (v && array_p (v) && array_cell (v))
5628     {
5629       array_dispose (array_cell (v));
5630       var_setarray (v, ps->pipestatus);
5631     }
5632 #endif
5633
5634   last_shell_builtin = ps->last_shell_builtin;
5635   this_shell_builtin = ps->this_shell_builtin;
5636
5637   expand_aliases = ps->expand_aliases;
5638   echo_input_at_read = ps->echo_input_at_read;
5639 }
5640
5641 /************************************************
5642  *                                              *
5643  *      MULTIBYTE CHARACTER HANDLING            *
5644  *                                              *
5645  ************************************************/
5646
5647 #if defined (HANDLE_MULTIBYTE)
5648 static void
5649 set_line_mbstate ()
5650 {
5651   int i, previ, len, c;
5652   mbstate_t mbs, prevs;
5653   size_t mbclen;
5654
5655   if (shell_input_line == NULL)
5656     return;
5657   len = strlen (shell_input_line);      /* XXX - shell_input_line_len ? */
5658   FREE (shell_input_line_property);
5659   shell_input_line_property = (char *)xmalloc (len + 1);
5660
5661   memset (&prevs, '\0', sizeof (mbstate_t));
5662   for (i = previ = 0; i < len; i++)
5663     {
5664       mbs = prevs;
5665
5666       c = shell_input_line[i];
5667       if (c == EOF)
5668         {
5669           int j;
5670           for (j = i; j < len; j++)
5671             shell_input_line_property[j] = 1;
5672           break;
5673         }
5674
5675       mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
5676       if (mbclen == 1 || mbclen == (size_t)-1)
5677         {
5678           mbclen = 1;
5679           previ = i + 1;
5680         }
5681       else if (mbclen == (size_t)-2)
5682         mbclen = 0;
5683       else if (mbclen > 1)
5684         {
5685           mbclen = 0;
5686           previ = i + 1;
5687           prevs = mbs;
5688         }
5689       else
5690         {
5691           /* XXX - what to do if mbrlen returns 0? (null wide character) */
5692           int j;
5693           for (j = i; j < len; j++)
5694             shell_input_line_property[j] = 1;
5695           break;
5696         }
5697
5698       shell_input_line_property[i] = mbclen;
5699     }
5700 }
5701 #endif /* HANDLE_MULTIBYTE */