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