Bash-4.2 patch 34
[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 (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
2397           {
2398             uc = 0;
2399             goto pop_alias;
2400           }
2401         else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0')
2402           {
2403             shell_input_line_index++;   /* skip newline */
2404             goto next_alias_char;       /* and get next character */
2405           }
2406         else        
2407           goto restart_read;
2408     }
2409
2410   if (uc == 0 && shell_input_line_terminator == EOF)
2411     return ((shell_input_line_index != 0) ? '\n' : EOF);
2412
2413   return (uc);
2414 }
2415
2416 /* Put C back into the input for the shell.  This might need changes for
2417    HANDLE_MULTIBYTE around EOLs.  Since we (currently) never push back a
2418    character different than we read, shell_input_line_property doesn't need
2419    to change when manipulating shell_input_line.  The define for
2420    last_shell_getc_is_singlebyte should take care of it, though. */
2421 static void
2422 shell_ungetc (c)
2423      int c;
2424 {
2425   if (shell_input_line && shell_input_line_index)
2426     shell_input_line[--shell_input_line_index] = c;
2427   else
2428     eol_ungetc_lookahead = c;
2429 }
2430
2431 #ifdef INCLUDE_UNUSED
2432 /* Back the input pointer up by one, effectively `ungetting' a character. */
2433 static void
2434 shell_ungetchar ()
2435 {
2436   if (shell_input_line && shell_input_line_index)
2437     shell_input_line_index--;
2438 }
2439 #endif
2440
2441 /* Discard input until CHARACTER is seen, then push that character back
2442    onto the input stream. */
2443 static void
2444 discard_until (character)
2445      int character;
2446 {
2447   int c;
2448
2449   while ((c = shell_getc (0)) != EOF && c != character)
2450     ;
2451
2452   if (c != EOF)
2453     shell_ungetc (c);
2454 }
2455
2456 void
2457 execute_variable_command (command, vname)
2458      char *command, *vname;
2459 {
2460   char *last_lastarg;
2461   sh_parser_state_t ps;
2462
2463   save_parser_state (&ps);
2464   last_lastarg = get_string_value ("_");
2465   if (last_lastarg)
2466     last_lastarg = savestring (last_lastarg);
2467
2468   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
2469
2470   restore_parser_state (&ps);
2471   bind_variable ("_", last_lastarg, 0);
2472   FREE (last_lastarg);
2473
2474   if (token_to_read == '\n')    /* reset_parser was called */
2475     token_to_read = 0;
2476 }
2477
2478 /* Place to remember the token.  We try to keep the buffer
2479    at a reasonable size, but it can grow. */
2480 static char *token = (char *)NULL;
2481
2482 /* Current size of the token buffer. */
2483 static int token_buffer_size;
2484
2485 /* Command to read_token () explaining what we want it to do. */
2486 #define READ 0
2487 #define RESET 1
2488 #define prompt_is_ps1 \
2489       (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2490
2491 /* Function for yyparse to call.  yylex keeps track of
2492    the last two tokens read, and calls read_token.  */
2493 static int
2494 yylex ()
2495 {
2496   if (interactive && (current_token == 0 || current_token == '\n'))
2497     {
2498       /* Before we print a prompt, we might have to check mailboxes.
2499          We do this only if it is time to do so. Notice that only here
2500          is the mail alarm reset; nothing takes place in check_mail ()
2501          except the checking of mail.  Please don't change this. */
2502       if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
2503         {
2504           check_mail ();
2505           reset_mail_timer ();
2506         }
2507
2508       /* Avoid printing a prompt if we're not going to read anything, e.g.
2509          after resetting the parser with read_token (RESET). */
2510       if (token_to_read == 0 && SHOULD_PROMPT ())
2511         prompt_again ();
2512     }
2513
2514   two_tokens_ago = token_before_that;
2515   token_before_that = last_read_token;
2516   last_read_token = current_token;
2517   current_token = read_token (READ);
2518
2519   if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
2520     {
2521       current_token = yacc_EOF;
2522       if (bash_input.type == st_string)
2523         rewind_input_string ();
2524     }
2525   parser_state &= ~PST_EOFTOKEN;
2526
2527   return (current_token);
2528 }
2529
2530 /* When non-zero, we have read the required tokens
2531    which allow ESAC to be the next one read. */
2532 static int esacs_needed_count;
2533
2534 void
2535 gather_here_documents ()
2536 {
2537   int r;
2538
2539   r = 0;
2540   while (need_here_doc)
2541     {
2542       parser_state |= PST_HEREDOC;
2543       make_here_document (redir_stack[r++], line_number);
2544       parser_state &= ~PST_HEREDOC;
2545       need_here_doc--;
2546     }
2547 }
2548
2549 /* When non-zero, an open-brace used to create a group is awaiting a close
2550    brace partner. */
2551 static int open_brace_count;
2552
2553 #define command_token_position(token) \
2554   (((token) == ASSIGNMENT_WORD) || (parser_state&PST_REDIRLIST) || \
2555    ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
2556
2557 #define assignment_acceptable(token) \
2558   (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
2559
2560 /* Check to see if TOKEN is a reserved word and return the token
2561    value if it is. */
2562 #define CHECK_FOR_RESERVED_WORD(tok) \
2563   do { \
2564     if (!dollar_present && !quoted && \
2565         reserved_word_acceptable (last_read_token)) \
2566       { \
2567         int i; \
2568         for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2569           if (STREQ (tok, word_token_alist[i].word)) \
2570             { \
2571               if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2572                 break; \
2573               if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
2574                 break; \
2575               if (word_token_alist[i].token == ESAC) \
2576                 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2577               else if (word_token_alist[i].token == CASE) \
2578                 parser_state |= PST_CASESTMT; \
2579               else if (word_token_alist[i].token == COND_END) \
2580                 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2581               else if (word_token_alist[i].token == COND_START) \
2582                 parser_state |= PST_CONDCMD; \
2583               else if (word_token_alist[i].token == '{') \
2584                 open_brace_count++; \
2585               else if (word_token_alist[i].token == '}' && open_brace_count) \
2586                 open_brace_count--; \
2587               return (word_token_alist[i].token); \
2588             } \
2589       } \
2590   } while (0)
2591
2592 #if defined (ALIAS)
2593
2594     /* OK, we have a token.  Let's try to alias expand it, if (and only if)
2595        it's eligible.
2596
2597        It is eligible for expansion if EXPAND_ALIASES is set, and
2598        the token is unquoted and the last token read was a command
2599        separator (or expand_next_token is set), and we are currently
2600        processing an alias (pushed_string_list is non-empty) and this
2601        token is not the same as the current or any previously
2602        processed alias.
2603
2604        Special cases that disqualify:
2605          In a pattern list in a case statement (parser_state & PST_CASEPAT). */
2606
2607 static char *
2608 mk_alexpansion (s)
2609      char *s;
2610 {
2611   int l;
2612   char *r;
2613
2614   l = strlen (s);
2615   r = xmalloc (l + 2);
2616   strcpy (r, s);
2617   /* If the last character in the alias is a newline, don't add a trailing
2618      space to the expansion.  Works with shell_getc above. */
2619   if (r[l - 1] != ' ' && r[l - 1] != '\n')
2620     r[l++] = ' ';
2621   r[l] = '\0';
2622   return r;
2623 }
2624
2625 static int
2626 alias_expand_token (tokstr)
2627      char *tokstr;
2628 {
2629   char *expanded;
2630   alias_t *ap;
2631
2632   if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2633         (parser_state & PST_CASEPAT) == 0)
2634     {
2635       ap = find_alias (tokstr);
2636
2637       /* Currently expanding this token. */
2638       if (ap && (ap->flags & AL_BEINGEXPANDED))
2639         return (NO_EXPANSION);
2640
2641       /* mk_alexpansion puts an extra space on the end of the alias expansion,
2642          so the lookahead by the parser works right.  If this gets changed,
2643          make sure the code in shell_getc that deals with reaching the end of
2644          an expanded alias is changed with it. */
2645       expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2646
2647       if (expanded)
2648         {
2649           push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2650           return (RE_READ_TOKEN);
2651         }
2652       else
2653         /* This is an eligible token that does not have an expansion. */
2654         return (NO_EXPANSION);
2655     }
2656   return (NO_EXPANSION);
2657 }
2658 #endif /* ALIAS */
2659
2660 static int
2661 time_command_acceptable ()
2662 {
2663 #if defined (COMMAND_TIMING)
2664   int i;
2665
2666   if (posixly_correct && shell_compatibility_level > 41)
2667     {
2668       /* Quick check of the rest of the line to find the next token.  If it
2669          begins with a `-', Posix says to not return `time' as the token.
2670          This was interp 267. */
2671       i = shell_input_line_index;
2672       while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
2673         i++;
2674       if (shell_input_line[i] == '-')
2675         return 0;
2676     }
2677
2678   switch (last_read_token)
2679     {
2680     case 0:
2681     case ';':
2682     case '\n':
2683     case AND_AND:
2684     case OR_OR:
2685     case '&':
2686     case DO:
2687     case THEN:
2688     case ELSE:
2689     case '{':           /* } */
2690     case '(':           /* ) */
2691     case BANG:          /* ! time pipeline */
2692     case TIME:          /* time time pipeline */
2693     case TIMEOPT:       /* time -p time pipeline */
2694     case TIMEIGN:       /* time -p -- ... */
2695       return 1;
2696     default:
2697       return 0;
2698     }
2699 #else
2700   return 0;
2701 #endif /* COMMAND_TIMING */
2702 }
2703
2704 /* Handle special cases of token recognition:
2705         IN is recognized if the last token was WORD and the token
2706         before that was FOR or CASE or SELECT.
2707
2708         DO is recognized if the last token was WORD and the token
2709         before that was FOR or SELECT.
2710
2711         ESAC is recognized if the last token caused `esacs_needed_count'
2712         to be set
2713
2714         `{' is recognized if the last token as WORD and the token
2715         before that was FUNCTION, or if we just parsed an arithmetic
2716         `for' command.
2717
2718         `}' is recognized if there is an unclosed `{' present.
2719
2720         `-p' is returned as TIMEOPT if the last read token was TIME.
2721         `--' is returned as TIMEIGN if the last read token was TIMEOPT.
2722
2723         ']]' is returned as COND_END if the parser is currently parsing
2724         a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2725
2726         `time' is returned as TIME if and only if it is immediately
2727         preceded by one of `;', `\n', `||', `&&', or `&'.
2728 */
2729
2730 static int
2731 special_case_tokens (tokstr)
2732      char *tokstr;
2733 {
2734   if ((last_read_token == WORD) &&
2735 #if defined (SELECT_COMMAND)
2736       ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2737 #else
2738       ((token_before_that == FOR) || (token_before_that == CASE)) &&
2739 #endif
2740       (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
2741     {
2742       if (token_before_that == CASE)
2743         {
2744           parser_state |= PST_CASEPAT;
2745           esacs_needed_count++;
2746         }
2747       return (IN);
2748     }
2749
2750   if (last_read_token == WORD &&
2751 #if defined (SELECT_COMMAND)
2752       (token_before_that == FOR || token_before_that == SELECT) &&
2753 #else
2754       (token_before_that == FOR) &&
2755 #endif
2756       (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
2757     return (DO);
2758
2759   /* Ditto for ESAC in the CASE case.
2760      Specifically, this handles "case word in esac", which is a legal
2761      construct, certainly because someone will pass an empty arg to the
2762      case construct, and we don't want it to barf.  Of course, we should
2763      insist that the case construct has at least one pattern in it, but
2764      the designers disagree. */
2765   if (esacs_needed_count)
2766     {
2767       esacs_needed_count--;
2768       if (STREQ (tokstr, "esac"))
2769         {
2770           parser_state &= ~PST_CASEPAT;
2771           return (ESAC);
2772         }
2773     }
2774
2775   /* The start of a shell function definition. */
2776   if (parser_state & PST_ALLOWOPNBRC)
2777     {
2778       parser_state &= ~PST_ALLOWOPNBRC;
2779       if (tokstr[0] == '{' && tokstr[1] == '\0')                /* } */
2780         {
2781           open_brace_count++;
2782           function_bstart = line_number;
2783           return ('{');                                 /* } */
2784         }
2785     }
2786
2787   /* We allow a `do' after a for ((...)) without an intervening
2788      list_terminator */
2789   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
2790     return (DO);
2791   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0')      /* } */
2792     {
2793       open_brace_count++;
2794       return ('{');                     /* } */
2795     }
2796
2797   if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
2798     {
2799       open_brace_count--;               /* { */
2800       return ('}');
2801     }
2802
2803 #if defined (COMMAND_TIMING)
2804   /* Handle -p after `time'. */
2805   if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
2806     return (TIMEOPT);
2807   /* Handle -- after `time -p'. */
2808   if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
2809     return (TIMEIGN);
2810 #endif
2811
2812 #if defined (COND_COMMAND) /* [[ */
2813   if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
2814     return (COND_END);
2815 #endif
2816
2817   return (-1);
2818 }
2819
2820 /* Called from shell.c when Control-C is typed at top level.  Or
2821    by the error rule at top level. */
2822 void
2823 reset_parser ()
2824 {
2825   dstack.delimiter_depth = 0;   /* No delimiters found so far. */
2826   open_brace_count = 0;
2827
2828 #if defined (EXTENDED_GLOB)
2829   /* Reset to global value of extended glob */
2830   if (parser_state & PST_EXTPAT)
2831     extended_glob = global_extglob;
2832 #endif
2833
2834   parser_state = 0;
2835
2836 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2837   if (pushed_string_list)
2838     free_string_list ();
2839 #endif /* ALIAS || DPAREN_ARITHMETIC */
2840
2841   if (shell_input_line)
2842     {
2843       free (shell_input_line);
2844       shell_input_line = (char *)NULL;
2845       shell_input_line_size = shell_input_line_index = 0;
2846     }
2847
2848   FREE (word_desc_to_read);
2849   word_desc_to_read = (WORD_DESC *)NULL;
2850
2851   current_token = '\n';         /* XXX */
2852   last_read_token = '\n';
2853   token_to_read = '\n';
2854 }
2855
2856 /* Read the next token.  Command can be READ (normal operation) or
2857    RESET (to normalize state). */
2858 static int
2859 read_token (command)
2860      int command;
2861 {
2862   int character;                /* Current character. */
2863   int peek_char;                /* Temporary look-ahead character. */
2864   int result;                   /* The thing to return. */
2865
2866   if (command == RESET)
2867     {
2868       reset_parser ();
2869       return ('\n');
2870     }
2871
2872   if (token_to_read)
2873     {
2874       result = token_to_read;
2875       if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
2876         {
2877           yylval.word = word_desc_to_read;
2878           word_desc_to_read = (WORD_DESC *)NULL;
2879         }
2880       token_to_read = 0;
2881       return (result);
2882     }
2883
2884 #if defined (COND_COMMAND)
2885   if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2886     {
2887       cond_lineno = line_number;
2888       parser_state |= PST_CONDEXPR;
2889       yylval.command = parse_cond_command ();
2890       if (cond_token != COND_END)
2891         {
2892           cond_error ();
2893           return (-1);
2894         }
2895       token_to_read = COND_END;
2896       parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2897       return (COND_CMD);
2898     }
2899 #endif
2900
2901 #if defined (ALIAS)
2902   /* This is a place to jump back to once we have successfully expanded a
2903      token with an alias and pushed the string with push_string () */
2904  re_read_token:
2905 #endif /* ALIAS */
2906
2907   /* Read a single word from input.  Start by skipping blanks. */
2908   while ((character = shell_getc (1)) != EOF && shellblank (character))
2909     ;
2910
2911   if (character == EOF)
2912     {
2913       EOF_Reached = 1;
2914       return (yacc_EOF);
2915     }
2916
2917   if MBTEST(character == '#' && (!interactive || interactive_comments))
2918     {
2919       /* A comment.  Discard until EOL or EOF, and then return a newline. */
2920       discard_until ('\n');
2921       shell_getc (0);
2922       character = '\n'; /* this will take the next if statement and return. */
2923     }
2924
2925   if (character == '\n')
2926     {
2927       /* If we're about to return an unquoted newline, we can go and collect
2928          the text of any pending here document. */
2929       if (need_here_doc)
2930         gather_here_documents ();
2931
2932 #if defined (ALIAS)
2933       parser_state &= ~PST_ALEXPNEXT;
2934 #endif /* ALIAS */
2935
2936       parser_state &= ~PST_ASSIGNOK;
2937
2938       return (character);
2939     }
2940
2941   if (parser_state & PST_REGEXP)
2942     goto tokword;
2943
2944   /* Shell meta-characters. */
2945   if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
2946     {
2947 #if defined (ALIAS)
2948       /* Turn off alias tokenization iff this character sequence would
2949          not leave us ready to read a command. */
2950       if (character == '<' || character == '>')
2951         parser_state &= ~PST_ALEXPNEXT;
2952 #endif /* ALIAS */
2953
2954       parser_state &= ~PST_ASSIGNOK;
2955
2956       peek_char = shell_getc (1);
2957       if (character == peek_char)
2958         {
2959           switch (character)
2960             {
2961             case '<':
2962               /* If '<' then we could be at "<<" or at "<<-".  We have to
2963                  look ahead one more character. */
2964               peek_char = shell_getc (1);
2965               if MBTEST(peek_char == '-')
2966                 return (LESS_LESS_MINUS);
2967               else if MBTEST(peek_char == '<')
2968                 return (LESS_LESS_LESS);
2969               else
2970                 {
2971                   shell_ungetc (peek_char);
2972                   return (LESS_LESS);
2973                 }
2974
2975             case '>':
2976               return (GREATER_GREATER);
2977
2978             case ';':
2979               parser_state |= PST_CASEPAT;
2980 #if defined (ALIAS)
2981               parser_state &= ~PST_ALEXPNEXT;
2982 #endif /* ALIAS */
2983
2984               peek_char = shell_getc (1);
2985               if MBTEST(peek_char == '&')
2986                 return (SEMI_SEMI_AND);
2987               else
2988                 {
2989                   shell_ungetc (peek_char);
2990                   return (SEMI_SEMI);
2991                 }
2992
2993             case '&':
2994               return (AND_AND);
2995
2996             case '|':
2997               return (OR_OR);
2998
2999 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3000             case '(':           /* ) */
3001               result = parse_dparen (character);
3002               if (result == -2)
3003                 break;
3004               else
3005                 return result;
3006 #endif
3007             }
3008         }
3009       else if MBTEST(character == '<' && peek_char == '&')
3010         return (LESS_AND);
3011       else if MBTEST(character == '>' && peek_char == '&')
3012         return (GREATER_AND);
3013       else if MBTEST(character == '<' && peek_char == '>')
3014         return (LESS_GREATER);
3015       else if MBTEST(character == '>' && peek_char == '|')
3016         return (GREATER_BAR);
3017       else if MBTEST(character == '&' && peek_char == '>')
3018         {
3019           peek_char = shell_getc (1);
3020           if MBTEST(peek_char == '>')
3021             return (AND_GREATER_GREATER);
3022           else
3023             {
3024               shell_ungetc (peek_char);
3025               return (AND_GREATER);
3026             }
3027         }
3028       else if MBTEST(character == '|' && peek_char == '&')
3029         return (BAR_AND);
3030       else if MBTEST(character == ';' && peek_char == '&')
3031         {
3032           parser_state |= PST_CASEPAT;
3033 #if defined (ALIAS)
3034           parser_state &= ~PST_ALEXPNEXT;
3035 #endif /* ALIAS */
3036           return (SEMI_AND);
3037         }
3038
3039       shell_ungetc (peek_char);
3040
3041       /* If we look like we are reading the start of a function
3042          definition, then let the reader know about it so that
3043          we will do the right thing with `{'. */
3044       if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
3045         {
3046           parser_state |= PST_ALLOWOPNBRC;
3047 #if defined (ALIAS)
3048           parser_state &= ~PST_ALEXPNEXT;
3049 #endif /* ALIAS */
3050           function_dstart = line_number;
3051         }
3052
3053       /* case pattern lists may be preceded by an optional left paren.  If
3054          we're not trying to parse a case pattern list, the left paren
3055          indicates a subshell. */
3056       if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3057         parser_state |= PST_SUBSHELL;
3058       /*(*/
3059       else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
3060         parser_state &= ~PST_CASEPAT;
3061       /*(*/
3062       else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
3063         parser_state &= ~PST_SUBSHELL;
3064
3065 #if defined (PROCESS_SUBSTITUTION)
3066       /* Check for the constructs which introduce process substitution.
3067          Shells running in `posix mode' don't do process substitution. */
3068       if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
3069 #endif /* PROCESS_SUBSTITUTION */
3070         return (character);
3071     }
3072
3073   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */
3074   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3075     return (character);
3076
3077 tokword:
3078   /* Okay, if we got this far, we have to read a word.  Read one,
3079      and then check it against the known ones. */
3080   result = read_token_word (character);
3081 #if defined (ALIAS)
3082   if (result == RE_READ_TOKEN)
3083     goto re_read_token;
3084 #endif
3085   return result;
3086 }
3087
3088 /*
3089  * Match a $(...) or other grouping construct.  This has to handle embedded
3090  * quoted strings ('', ``, "") and nested constructs.  It also must handle
3091  * reprompting the user, if necessary, after reading a newline, and returning
3092  * correct error values if it reads EOF.
3093  */
3094 #define P_FIRSTCLOSE    0x0001
3095 #define P_ALLOWESC      0x0002
3096 #define P_DQUOTE        0x0004
3097 #define P_COMMAND       0x0008  /* parsing a command, so look for comments */
3098 #define P_BACKQUOTE     0x0010  /* parsing a backquoted command substitution */
3099 #define P_ARRAYSUB      0x0020  /* parsing a [...] array subscript for assignment */
3100 #define P_DOLBRACE      0x0040  /* parsing a ${...} construct */
3101
3102 /* Lexical state while parsing a grouping construct or $(...). */
3103 #define LEX_WASDOL      0x001
3104 #define LEX_CKCOMMENT   0x002
3105 #define LEX_INCOMMENT   0x004
3106 #define LEX_PASSNEXT    0x008
3107 #define LEX_RESWDOK     0x010
3108 #define LEX_CKCASE      0x020
3109 #define LEX_INCASE      0x040
3110 #define LEX_INHEREDOC   0x080
3111 #define LEX_HEREDELIM   0x100           /* reading here-doc delimiter */
3112 #define LEX_STRIPDOC    0x200           /* <<- strip tabs from here doc delim */
3113 #define LEX_INWORD      0x400
3114
3115 #define COMSUB_META(ch)         ((ch) == ';' || (ch) == '&' || (ch) == '|')
3116
3117 #define CHECK_NESTRET_ERROR() \
3118   do { \
3119     if (nestret == &matched_pair_error) \
3120       { \
3121         free (ret); \
3122         return &matched_pair_error; \
3123       } \
3124   } while (0)
3125
3126 #define APPEND_NESTRET() \
3127   do { \
3128     if (nestlen) \
3129       { \
3130         RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
3131         strcpy (ret + retind, nestret); \
3132         retind += nestlen; \
3133       } \
3134   } while (0)
3135
3136 static char matched_pair_error;
3137
3138 static char *
3139 parse_matched_pair (qc, open, close, lenp, flags)
3140      int qc;    /* `"' if this construct is within double quotes */
3141      int open, close;
3142      int *lenp, flags;
3143 {
3144   int count, ch, tflags;
3145   int nestlen, ttranslen, start_lineno;
3146   char *ret, *nestret, *ttrans;
3147   int retind, retsize, rflags;
3148   int dolbrace_state;
3149
3150   dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
3151
3152 /*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
3153   count = 1;
3154   tflags = 0;
3155
3156   if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3157     tflags |= LEX_CKCOMMENT;
3158
3159   /* RFLAGS is the set of flags we want to pass to recursive calls. */
3160   rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
3161
3162   ret = (char *)xmalloc (retsize = 64);
3163   retind = 0;
3164
3165   start_lineno = line_number;
3166   while (count)
3167     {
3168       ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
3169
3170       if (ch == EOF)
3171         {
3172           free (ret);
3173           parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3174           EOF_Reached = 1;      /* XXX */
3175           return (&matched_pair_error);
3176         }
3177
3178       /* Possible reprompting. */
3179       if (ch == '\n' && SHOULD_PROMPT ())
3180         prompt_again ();
3181
3182       /* Don't bother counting parens or doing anything else if in a comment
3183          or part of a case statement */
3184       if (tflags & LEX_INCOMMENT)
3185         {
3186           /* Add this character. */
3187           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3188           ret[retind++] = ch;
3189
3190           if (ch == '\n')
3191             tflags &= ~LEX_INCOMMENT;
3192
3193           continue;
3194         }
3195
3196       /* Not exactly right yet, should handle shell metacharacters, too.  If
3197          any changes are made to this test, make analogous changes to subst.c:
3198          extract_delimited_string(). */
3199       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
3200         tflags |= LEX_INCOMMENT;
3201
3202       if (tflags & LEX_PASSNEXT)                /* last char was backslash */
3203         {
3204           tflags &= ~LEX_PASSNEXT;
3205           if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3206             {
3207               if (retind > 0)
3208                 retind--;       /* swallow previously-added backslash */
3209               continue;
3210             }
3211
3212           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3213           if MBTEST(ch == CTLESC || ch == CTLNUL)
3214             ret[retind++] = CTLESC;
3215           ret[retind++] = ch;
3216           continue;
3217         }
3218       /* If we're reparsing the input (e.g., from parse_string_to_word_list),
3219          we've already prepended CTLESC to single-quoted results of $'...'.
3220          We may want to do this for other CTLESC-quoted characters in
3221          reparse, too. */
3222       else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
3223         {
3224           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3225           ret[retind++] = ch;
3226           continue;
3227         }
3228       else if MBTEST(ch == CTLESC || ch == CTLNUL)      /* special shell escapes */
3229         {
3230           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3231           ret[retind++] = CTLESC;
3232           ret[retind++] = ch;
3233           continue;
3234         }
3235       else if MBTEST(ch == close)               /* ending delimiter */
3236         count--;
3237       /* handle nested ${...} specially. */
3238       else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
3239         count++;
3240       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open)       /* nested begin */
3241         count++;
3242
3243       /* Add this character. */
3244       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3245       ret[retind++] = ch;
3246
3247       /* If we just read the ending character, don't bother continuing. */
3248       if (count == 0)
3249         break;
3250
3251       if (open == '\'')                 /* '' inside grouping construct */
3252         {
3253           if MBTEST((flags & P_ALLOWESC) && ch == '\\')
3254             tflags |= LEX_PASSNEXT;
3255           continue;
3256         }
3257
3258       if MBTEST(ch == '\\')                     /* backslashes */
3259         tflags |= LEX_PASSNEXT;
3260
3261       /* Based on which dolstate is currently in (param, op, or word),
3262          decide what the op is.  We're really only concerned if it's % or
3263          #, so we can turn on a flag that says whether or not we should
3264          treat single quotes as special when inside a double-quoted
3265          ${...}. This logic must agree with subst.c:extract_dollar_brace_string
3266          since they share the same defines. */
3267       if (flags & P_DOLBRACE)
3268         {
3269           /* ${param%[%]word} */
3270           if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
3271             dolbrace_state = DOLBRACE_QUOTE;
3272           /* ${param#[#]word} */
3273           else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
3274             dolbrace_state = DOLBRACE_QUOTE;
3275           /* ${param/[/]pat/rep} */
3276           else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1)
3277             dolbrace_state = DOLBRACE_QUOTE;
3278           /* ${param^[^]pat} */
3279           else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1)
3280             dolbrace_state = DOLBRACE_QUOTE;
3281           /* ${param,[,]pat} */
3282           else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
3283             dolbrace_state = DOLBRACE_QUOTE;
3284           else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
3285             dolbrace_state = DOLBRACE_OP;
3286           else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
3287             dolbrace_state = DOLBRACE_WORD;
3288         }
3289
3290       /* The big hammer.  Single quotes aren't special in double quotes.  The
3291          problem is that Posix used to say the single quotes are semi-special:
3292          within a double-quoted ${...} construct "an even number of
3293          unescaped double-quotes or single-quotes, if any, shall occur." */
3294       /* This was changed in Austin Group Interp 221 */
3295       if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
3296         continue;
3297
3298       /* Could also check open == '`' if we want to parse grouping constructs
3299          inside old-style command substitution. */
3300       if (open != close)                /* a grouping construct */
3301         {
3302           if MBTEST(shellquote (ch))
3303             {
3304               /* '', ``, or "" inside $(...) or other grouping construct. */
3305               push_delimiter (dstack, ch);
3306               if MBTEST((tflags & LEX_WASDOL) && ch == '\'')    /* $'...' inside group */
3307                 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3308               else
3309                 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3310               pop_delimiter (dstack);
3311               CHECK_NESTRET_ERROR ();
3312
3313               if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3314                 {
3315                   /* Translate $'...' here. */
3316                   ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3317                   xfree (nestret);
3318
3319                   if ((rflags & P_DQUOTE) == 0)
3320                     {
3321                       nestret = sh_single_quote (ttrans);
3322                       free (ttrans);
3323                       nestlen = strlen (nestret);
3324                     }
3325                   else
3326                     {
3327                       nestret = ttrans;
3328                       nestlen = ttranslen;
3329                     }
3330                   retind -= 2;          /* back up before the $' */
3331                 }
3332               else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3333                 {
3334                   /* Locale expand $"..." here. */
3335                   ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3336                   xfree (nestret);
3337
3338                   nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3339                   free (ttrans);
3340                   nestlen = ttranslen + 2;
3341                   retind -= 2;          /* back up before the $" */
3342                 }
3343
3344               APPEND_NESTRET ();
3345               FREE (nestret);
3346             }
3347           else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
3348             goto parse_dollar_word;
3349         }
3350       /* Parse an old-style command substitution within double quotes as a
3351          single word. */
3352       /* XXX - sh and ksh93 don't do this - XXX */
3353       else if MBTEST(open == '"' && ch == '`')
3354         {
3355           nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
3356
3357           CHECK_NESTRET_ERROR ();
3358           APPEND_NESTRET ();
3359
3360           FREE (nestret);
3361         }
3362       else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))     /* ) } ] */
3363         /* check for $(), $[], or ${} inside quoted string. */
3364         {
3365 parse_dollar_word:
3366           if (open == ch)       /* undo previous increment */
3367             count--;
3368           if (ch == '(')                /* ) */
3369             nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3370           else if (ch == '{')           /* } */
3371             nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3372           else if (ch == '[')           /* ] */
3373             nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3374
3375           CHECK_NESTRET_ERROR ();
3376           APPEND_NESTRET ();
3377
3378           FREE (nestret);
3379         }
3380       if MBTEST(ch == '$')
3381         tflags |= LEX_WASDOL;
3382       else
3383         tflags &= ~LEX_WASDOL;
3384     }
3385
3386   ret[retind] = '\0';
3387   if (lenp)
3388     *lenp = retind;
3389 /*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
3390   return ret;
3391 }
3392
3393 /* Parse a $(...) command substitution.  This is messier than I'd like, and
3394    reproduces a lot more of the token-reading code than I'd like. */
3395 static char *
3396 parse_comsub (qc, open, close, lenp, flags)
3397      int qc;    /* `"' if this construct is within double quotes */
3398      int open, close;
3399      int *lenp, flags;
3400 {
3401   int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
3402   int nestlen, ttranslen, start_lineno;
3403   char *ret, *nestret, *ttrans, *heredelim;
3404   int retind, retsize, rflags, hdlen;
3405
3406   /* Posix interp 217 says arithmetic expressions have precedence, so
3407      assume $(( introduces arithmetic expansion and parse accordingly. */
3408   peekc = shell_getc (0);
3409   shell_ungetc (peekc);
3410   if (peekc == '(')
3411     return (parse_matched_pair (qc, open, close, lenp, 0));
3412
3413 /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
3414   count = 1;
3415   tflags = LEX_RESWDOK;
3416
3417   if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3418     tflags |= LEX_CKCASE;
3419   if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
3420     tflags |= LEX_CKCOMMENT;
3421
3422   /* RFLAGS is the set of flags we want to pass to recursive calls. */
3423   rflags = (flags & P_DQUOTE);
3424
3425   ret = (char *)xmalloc (retsize = 64);
3426   retind = 0;
3427
3428   start_lineno = line_number;
3429   lex_rwlen = lex_wlen = 0;
3430
3431   heredelim = 0;
3432   lex_firstind = -1;
3433
3434   while (count)
3435     {
3436 comsub_readchar:
3437       ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0);
3438
3439       if (ch == EOF)
3440         {
3441 eof_error:
3442           free (ret);
3443           FREE (heredelim);
3444           parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3445           EOF_Reached = 1;      /* XXX */
3446           return (&matched_pair_error);
3447         }
3448
3449       /* If we hit the end of a line and are reading the contents of a here
3450          document, and it's not the same line that the document starts on,
3451          check for this line being the here doc delimiter.  Otherwise, if
3452          we're in a here document, mark the next character as the beginning
3453          of a line. */
3454       if (ch == '\n')
3455         {
3456           if ((tflags & LEX_HEREDELIM) && heredelim)
3457             {
3458               tflags &= ~LEX_HEREDELIM;
3459               tflags |= LEX_INHEREDOC;
3460               lex_firstind = retind + 1;
3461             }
3462           else if (tflags & LEX_INHEREDOC)
3463             {
3464               int tind;
3465               tind = lex_firstind;
3466               while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3467                 tind++;
3468               if (STREQN (ret + tind, heredelim, hdlen))
3469                 {
3470                   tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
3471 /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
3472                   free (heredelim);
3473                   heredelim = 0;
3474                   lex_firstind = -1;
3475                 }
3476               else
3477                 lex_firstind = retind + 1;
3478             }
3479         }
3480
3481       /* Possible reprompting. */
3482       if (ch == '\n' && SHOULD_PROMPT ())
3483         prompt_again ();
3484
3485       /* XXX -- possibly allow here doc to be delimited by ending right
3486          paren. */
3487       if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
3488         {
3489           int tind;
3490 /*itrace("parse_comsub: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", retind-lex_firstind, hdlen, retind);*/
3491           tind = lex_firstind;
3492           while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3493             tind++;
3494           if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
3495             {
3496               tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
3497 /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
3498               free (heredelim);
3499               heredelim = 0;
3500               lex_firstind = -1;
3501             }
3502         }
3503
3504       /* Don't bother counting parens or doing anything else if in a comment */
3505       if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
3506         {
3507           /* Add this character. */
3508           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3509           ret[retind++] = ch;
3510
3511           if ((tflags & LEX_INCOMMENT) && ch == '\n')
3512 {
3513 /*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/
3514             tflags &= ~LEX_INCOMMENT;
3515 }
3516
3517           continue;
3518         }
3519
3520       if (tflags & LEX_PASSNEXT)                /* last char was backslash */
3521         {
3522 /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3523           tflags &= ~LEX_PASSNEXT;
3524           if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3525             {
3526               if (retind > 0)
3527                 retind--;       /* swallow previously-added backslash */
3528               continue;
3529             }
3530
3531           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3532           if MBTEST(ch == CTLESC || ch == CTLNUL)
3533             ret[retind++] = CTLESC;
3534           ret[retind++] = ch;
3535           continue;
3536         }
3537
3538       /* If this is a shell break character, we are not in a word.  If not,
3539          we either start or continue a word. */
3540       if MBTEST(shellbreak (ch))
3541         {
3542           tflags &= ~LEX_INWORD;
3543 /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3544         }
3545       else
3546         {
3547           if (tflags & LEX_INWORD)
3548             {
3549               lex_wlen++;
3550 /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
3551             }         
3552           else
3553             {
3554 /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3555               tflags |= LEX_INWORD;
3556               lex_wlen = 0;
3557             }
3558         }
3559
3560       /* Skip whitespace */
3561       if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0)
3562         {
3563           /* Add this character. */
3564           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3565           ret[retind++] = ch;
3566           continue;
3567         }
3568
3569       /* Either we are looking for the start of the here-doc delimiter
3570          (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
3571          If this character is a shell break character and we are reading
3572          the delimiter, save it and note that we are now reading a here
3573          document.  If we've found the start of the delimiter, note it by
3574          setting lex_firstind.  Backslashes can quote shell metacharacters
3575          in here-doc delimiters. */
3576       if (tflags & LEX_HEREDELIM)
3577         {
3578           if (lex_firstind == -1 && shellbreak (ch) == 0)
3579             lex_firstind = retind;
3580 #if 0
3581           else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n')
3582             {
3583               tflags |= LEX_INHEREDOC;
3584               tflags &= ~LEX_HEREDELIM;
3585               lex_firstind = retind + 1;
3586             }
3587 #endif
3588           else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
3589             {
3590               if (heredelim == 0)
3591                 {
3592                   nestret = substring (ret, lex_firstind, retind);
3593                   heredelim = string_quote_removal (nestret, 0);
3594                   free (nestret);
3595                   hdlen = STRLEN(heredelim);
3596 /*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
3597                 }
3598               if (ch == '\n')
3599                 {
3600                   tflags |= LEX_INHEREDOC;
3601                   tflags &= ~LEX_HEREDELIM;
3602                   lex_firstind = retind + 1;
3603                 }
3604               else
3605                 lex_firstind = -1;
3606             }
3607         }
3608
3609       /* Meta-characters that can introduce a reserved word.  Not perfect yet. */
3610       if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
3611         {
3612           /* Add this character. */
3613           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3614           ret[retind++] = ch;
3615           peekc = shell_getc (1);
3616           if (ch == peekc && (ch == '&' || ch == '|' || ch == ';'))     /* two-character tokens */
3617             {
3618               RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3619               ret[retind++] = peekc;
3620 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
3621               tflags |= LEX_RESWDOK;
3622               lex_rwlen = 0;
3623               continue;
3624             }
3625           else if (ch == '\n' || COMSUB_META(ch))
3626             {
3627               shell_ungetc (peekc);
3628 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
3629               tflags |= LEX_RESWDOK;
3630               lex_rwlen = 0;
3631               continue;
3632             }
3633           else if (ch == EOF)
3634             goto eof_error;
3635           else
3636             {
3637               /* `unget' the character we just added and fall through */
3638               retind--;
3639               shell_ungetc (peekc);
3640             }
3641         }
3642
3643       /* If we can read a reserved word, try to read one. */
3644       if (tflags & LEX_RESWDOK)
3645         {
3646           if MBTEST(islower (ch))
3647             {
3648               /* Add this character. */
3649               RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3650               ret[retind++] = ch;
3651               lex_rwlen++;
3652               continue;
3653             }
3654           else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
3655             {
3656               if (STREQN (ret + retind - 4, "case", 4))
3657 {
3658                 tflags |= LEX_INCASE;
3659 /*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
3660 }
3661               else if (STREQN (ret + retind - 4, "esac", 4))
3662 {
3663                 tflags &= ~LEX_INCASE;
3664 /*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 0", line_number);*/
3665 }               
3666               tflags &= ~LEX_RESWDOK;
3667             }
3668           else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
3669             ;   /* don't modify LEX_RESWDOK if we're starting a comment */
3670           else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
3671             /* If we can read a reserved word and we're in case, we're at the
3672                point where we can read a new pattern list or an esac.  We
3673                handle the esac case above.  If we read a newline, we want to
3674                leave LEX_RESWDOK alone.  If we read anything else, we want to
3675                turn off LEX_RESWDOK, since we're going to read a pattern list. */
3676 {
3677             tflags &= ~LEX_RESWDOK;
3678 /*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
3679 }
3680           else if MBTEST(shellbreak (ch) == 0)
3681 {
3682             tflags &= ~LEX_RESWDOK;
3683 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
3684 }
3685         }
3686
3687       /* Might be the start of a here-doc delimiter */
3688       if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
3689         {
3690           /* Add this character. */
3691           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3692           ret[retind++] = ch;
3693           peekc = shell_getc (1);
3694           if (peekc == EOF)
3695             goto eof_error;
3696           if (peekc == ch)
3697             {
3698               RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3699               ret[retind++] = peekc;
3700               peekc = shell_getc (1);
3701               if (peekc == EOF)
3702                 goto eof_error;
3703               if (peekc == '-')
3704                 {
3705                   RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3706                   ret[retind++] = peekc;
3707                   tflags |= LEX_STRIPDOC;
3708                 }
3709               else
3710                 shell_ungetc (peekc);
3711               if (peekc != '<')
3712                 {
3713                   tflags |= LEX_HEREDELIM;
3714                   lex_firstind = -1;
3715                 }
3716               continue;
3717             }
3718           else
3719             ch = peekc;         /* fall through and continue XXX */
3720         }
3721       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
3722 {
3723 /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
3724         tflags |= LEX_INCOMMENT;
3725 }
3726
3727       if MBTEST(ch == CTLESC || ch == CTLNUL)   /* special shell escapes */
3728         {
3729           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3730           ret[retind++] = CTLESC;
3731           ret[retind++] = ch;
3732           continue;
3733         }
3734 #if 0
3735       else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
3736         tflags &= ~LEX_INCASE;          /* XXX */
3737 #endif
3738       else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0)         /* ending delimiter */
3739 {
3740         count--;
3741 /*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
3742 }
3743       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */
3744 {
3745         count++;
3746 /*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
3747 }
3748
3749       /* Add this character. */
3750       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3751       ret[retind++] = ch;
3752
3753       /* If we just read the ending character, don't bother continuing. */
3754       if (count == 0)
3755         break;
3756
3757       if MBTEST(ch == '\\')                     /* backslashes */
3758         tflags |= LEX_PASSNEXT;
3759
3760       if MBTEST(shellquote (ch))
3761         {
3762           /* '', ``, or "" inside $(...). */
3763           push_delimiter (dstack, ch);
3764           if MBTEST((tflags & LEX_WASDOL) && ch == '\'')        /* $'...' inside group */
3765             nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3766           else
3767             nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3768           pop_delimiter (dstack);
3769           CHECK_NESTRET_ERROR ();
3770
3771           if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3772             {
3773               /* Translate $'...' here. */
3774               ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3775               xfree (nestret);
3776
3777               if ((rflags & P_DQUOTE) == 0)
3778                 {
3779                   nestret = sh_single_quote (ttrans);
3780                   free (ttrans);
3781                   nestlen = strlen (nestret);
3782                 }
3783               else
3784                 {
3785                   nestret = ttrans;
3786                   nestlen = ttranslen;
3787                 }
3788               retind -= 2;              /* back up before the $' */
3789             }
3790           else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3791             {
3792               /* Locale expand $"..." here. */
3793               ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3794               xfree (nestret);
3795
3796               nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3797               free (ttrans);
3798               nestlen = ttranslen + 2;
3799               retind -= 2;              /* back up before the $" */
3800             }
3801
3802           APPEND_NESTRET ();
3803           FREE (nestret);
3804         }
3805       else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))    /* ) } ] */
3806         /* check for $(), $[], or ${} inside command substitution. */
3807         {
3808           if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */
3809             count--;
3810           if (ch == '(')                /* ) */
3811             nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3812           else if (ch == '{')           /* } */
3813             nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3814           else if (ch == '[')           /* ] */
3815             nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3816
3817           CHECK_NESTRET_ERROR ();
3818           APPEND_NESTRET ();
3819
3820           FREE (nestret);
3821         }
3822       if MBTEST(ch == '$')
3823         tflags |= LEX_WASDOL;
3824       else
3825         tflags &= ~LEX_WASDOL;
3826     }
3827
3828   FREE (heredelim);
3829   ret[retind] = '\0';
3830   if (lenp)
3831     *lenp = retind;
3832 /*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
3833   return ret;
3834 }
3835
3836 /* Recursively call the parser to parse a $(...) command substitution. */
3837 char *
3838 xparse_dolparen (base, string, indp, flags)
3839      char *base;
3840      char *string;
3841      int *indp;
3842      int flags;
3843 {
3844   sh_parser_state_t ps;
3845   sh_input_line_state_t ls;
3846   int orig_ind, nc, sflags;
3847   char *ret, *s, *ep, *ostring;
3848
3849   /*yydebug = 1;*/
3850   orig_ind = *indp;
3851   ostring = string;
3852
3853 /*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
3854   sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
3855   if (flags & SX_NOLONGJMP)
3856     sflags |= SEVAL_NOLONGJMP;
3857   save_parser_state (&ps);
3858   save_input_line_state (&ls);
3859
3860   /*(*/
3861   parser_state |= PST_CMDSUBST|PST_EOFTOKEN;    /* allow instant ')' */ /*(*/
3862   shell_eof_token = ')';
3863   parse_string (string, "command substitution", sflags, &ep);
3864
3865   restore_parser_state (&ps);
3866   reset_parser ();
3867   /* reset_parser clears shell_input_line and associated variables */
3868   restore_input_line_state (&ls);
3869   if (interactive)
3870     token_to_read = 0;
3871
3872   /* Need to find how many characters parse_and_execute consumed, update
3873      *indp, if flags != 0, copy the portion of the string parsed into RET
3874      and return it.  If flags & 1 (EX_NOALLOC) we can return NULL. */
3875
3876   /*(*/
3877   if (ep[-1] != ')')
3878     {
3879 #if DEBUG
3880       if (ep[-1] != '\n')
3881         itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
3882 #endif
3883       while (ep > ostring && ep[-1] == '\n') ep--;
3884     }
3885
3886   nc = ep - ostring;
3887   *indp = ep - base - 1;
3888
3889   /*(*/
3890 #if DEBUG
3891   if (base[*indp] != ')')
3892     itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
3893 #endif
3894
3895   if (flags & SX_NOALLOC) 
3896     return (char *)NULL;
3897
3898   if (nc == 0)
3899     {
3900       ret = xmalloc (1);
3901       ret[0] = '\0';
3902     }
3903   else
3904     ret = substring (ostring, 0, nc - 1);
3905
3906   return ret;
3907 }
3908
3909 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3910 /* Parse a double-paren construct.  It can be either an arithmetic
3911    command, an arithmetic `for' command, or a nested subshell.  Returns
3912    the parsed token, -1 on error, or -2 if we didn't do anything and
3913    should just go on. */
3914 static int
3915 parse_dparen (c)
3916      int c;
3917 {
3918   int cmdtyp, sline;
3919   char *wval;
3920   WORD_DESC *wd;
3921
3922 #if defined (ARITH_FOR_COMMAND)
3923   if (last_read_token == FOR)
3924     {
3925       arith_for_lineno = line_number;
3926       cmdtyp = parse_arith_cmd (&wval, 0);
3927       if (cmdtyp == 1)
3928         {
3929           wd = alloc_word_desc ();
3930           wd->word = wval;
3931           yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3932           return (ARITH_FOR_EXPRS);
3933         }
3934       else
3935         return -1;              /* ERROR */
3936     }
3937 #endif
3938
3939 #if defined (DPAREN_ARITHMETIC)
3940   if (reserved_word_acceptable (last_read_token))
3941     {
3942       sline = line_number;
3943
3944       cmdtyp = parse_arith_cmd (&wval, 0);
3945       if (cmdtyp == 1)  /* arithmetic command */
3946         {
3947           wd = alloc_word_desc ();
3948           wd->word = wval;
3949           wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
3950           yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3951           return (ARITH_CMD);
3952         }
3953       else if (cmdtyp == 0)     /* nested subshell */
3954         {
3955           push_string (wval, 0, (alias_t *)NULL);
3956           if ((parser_state & PST_CASEPAT) == 0)
3957             parser_state |= PST_SUBSHELL;
3958           return (c);
3959         }
3960       else                      /* ERROR */
3961         return -1;
3962     }
3963 #endif
3964
3965   return -2;                    /* XXX */
3966 }
3967
3968 /* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
3969    If not, assume it's a nested subshell for backwards compatibility and
3970    return 0.  In any case, put the characters we've consumed into a locally-
3971    allocated buffer and make *ep point to that buffer.  Return -1 on an
3972    error, for example EOF. */
3973 static int
3974 parse_arith_cmd (ep, adddq)
3975      char **ep;
3976      int adddq;
3977 {
3978   int exp_lineno, rval, c;
3979   char *ttok, *tokstr;
3980   int ttoklen;
3981
3982   exp_lineno = line_number;
3983   ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3984   rval = 1;
3985   if (ttok == &matched_pair_error)
3986     return -1;
3987   /* Check that the next character is the closing right paren.  If
3988      not, this is a syntax error. ( */
3989   c = shell_getc (0);
3990   if MBTEST(c != ')')
3991     rval = 0;
3992
3993   tokstr = (char *)xmalloc (ttoklen + 4);
3994
3995   /* if ADDDQ != 0 then (( ... )) -> "..." */
3996   if (rval == 1 && adddq)       /* arith cmd, add double quotes */
3997     {
3998       tokstr[0] = '"';
3999       strncpy (tokstr + 1, ttok, ttoklen - 1);
4000       tokstr[ttoklen] = '"';
4001       tokstr[ttoklen+1] = '\0';
4002     }
4003   else if (rval == 1)           /* arith cmd, don't add double quotes */
4004     {
4005       strncpy (tokstr, ttok, ttoklen - 1);
4006       tokstr[ttoklen-1] = '\0';
4007     }
4008   else                          /* nested subshell */
4009     {
4010       tokstr[0] = '(';
4011       strncpy (tokstr + 1, ttok, ttoklen - 1);
4012       tokstr[ttoklen] = ')';
4013       tokstr[ttoklen+1] = c;
4014       tokstr[ttoklen+2] = '\0';
4015     }
4016
4017   *ep = tokstr;
4018   FREE (ttok);
4019   return rval;
4020 }
4021 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
4022
4023 #if defined (COND_COMMAND)
4024 static void
4025 cond_error ()
4026 {
4027   char *etext;
4028
4029   if (EOF_Reached && cond_token != COND_ERROR)          /* [[ */
4030     parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
4031   else if (cond_token != COND_ERROR)
4032     {
4033       if (etext = error_token_from_token (cond_token))
4034         {
4035           parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
4036           free (etext);
4037         }
4038       else
4039         parser_error (cond_lineno, _("syntax error in conditional expression"));
4040     }
4041 }
4042
4043 static COND_COM *
4044 cond_expr ()
4045 {
4046   return (cond_or ());  
4047 }
4048
4049 static COND_COM *
4050 cond_or ()
4051 {
4052   COND_COM *l, *r;
4053
4054   l = cond_and ();
4055   if (cond_token == OR_OR)
4056     {
4057       r = cond_or ();
4058       l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
4059     }
4060   return l;
4061 }
4062
4063 static COND_COM *
4064 cond_and ()
4065 {
4066   COND_COM *l, *r;
4067
4068   l = cond_term ();
4069   if (cond_token == AND_AND)
4070     {
4071       r = cond_and ();
4072       l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
4073     }
4074   return l;
4075 }
4076
4077 static int
4078 cond_skip_newlines ()
4079 {
4080   while ((cond_token = read_token (READ)) == '\n')
4081     {
4082       if (SHOULD_PROMPT ())
4083         prompt_again ();
4084     }
4085   return (cond_token);
4086 }
4087
4088 #define COND_RETURN_ERROR() \
4089   do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
4090
4091 static COND_COM *
4092 cond_term ()
4093 {
4094   WORD_DESC *op;
4095   COND_COM *term, *tleft, *tright;
4096   int tok, lineno;
4097   char *etext;
4098
4099   /* Read a token.  It can be a left paren, a `!', a unary operator, or a
4100      word that should be the first argument of a binary operator.  Start by
4101      skipping newlines, since this is a compound command. */
4102   tok = cond_skip_newlines ();
4103   lineno = line_number;
4104   if (tok == COND_END)
4105     {
4106       COND_RETURN_ERROR ();
4107     }
4108   else if (tok == '(')
4109     {
4110       term = cond_expr ();
4111       if (cond_token != ')')
4112         {
4113           if (term)
4114             dispose_cond_node (term);           /* ( */
4115           if (etext = error_token_from_token (cond_token))
4116             {
4117               parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
4118               free (etext);
4119             }
4120           else
4121             parser_error (lineno, _("expected `)'"));
4122           COND_RETURN_ERROR ();
4123         }
4124       term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
4125       (void)cond_skip_newlines ();
4126     }
4127   else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
4128     {
4129       if (tok == WORD)
4130         dispose_word (yylval.word);     /* not needed */
4131       term = cond_term ();
4132       if (term)
4133         term->flags |= CMD_INVERT_RETURN;
4134     }
4135   else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
4136     {
4137       op = yylval.word;
4138       tok = read_token (READ);
4139       if (tok == WORD)
4140         {
4141           tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4142           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4143         }
4144       else
4145         {
4146           dispose_word (op);
4147           if (etext = error_token_from_token (tok))
4148             {
4149               parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
4150               free (etext);
4151             }
4152           else
4153             parser_error (line_number, _("unexpected argument to conditional unary operator"));
4154           COND_RETURN_ERROR ();
4155         }
4156
4157       (void)cond_skip_newlines ();
4158     }
4159   else if (tok == WORD)         /* left argument to binary operator */
4160     {
4161       /* lhs */
4162       tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4163
4164       /* binop */
4165       tok = read_token (READ);
4166       if (tok == WORD && test_binop (yylval.word->word))
4167         {
4168           op = yylval.word;
4169           if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
4170             parser_state |= PST_EXTPAT;
4171           else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
4172             parser_state |= PST_EXTPAT;
4173         }
4174 #if defined (COND_REGEXP)
4175       else if (tok == WORD && STREQ (yylval.word->word, "=~"))
4176         {
4177           op = yylval.word;
4178           parser_state |= PST_REGEXP;
4179         }
4180 #endif
4181       else if (tok == '<' || tok == '>')
4182         op = make_word_from_token (tok);  /* ( */
4183       /* There should be a check before blindly accepting the `)' that we have
4184          seen the opening `('. */
4185       else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
4186         {
4187           /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
4188              the test command.  Similarly for [[ x && expr ]] or
4189              [[ x || expr ]] or [[ (x) ]]. */
4190           op = make_word ("-n");
4191           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4192           cond_token = tok;
4193           return (term);
4194         }
4195       else
4196         {
4197           if (etext = error_token_from_token (tok))
4198             {
4199               parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
4200               free (etext);
4201             }
4202           else
4203             parser_error (line_number, _("conditional binary operator expected"));
4204           dispose_cond_node (tleft);
4205           COND_RETURN_ERROR ();
4206         }
4207
4208       /* rhs */
4209       if (parser_state & PST_EXTPAT)
4210         extended_glob = 1;
4211       tok = read_token (READ);
4212       if (parser_state & PST_EXTPAT)
4213         extended_glob = global_extglob;
4214       parser_state &= ~(PST_REGEXP|PST_EXTPAT);
4215
4216       if (tok == WORD)
4217         {
4218           tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4219           term = make_cond_node (COND_BINARY, op, tleft, tright);
4220         }
4221       else
4222         {
4223           if (etext = error_token_from_token (tok))
4224             {
4225               parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
4226               free (etext);
4227             }
4228           else
4229             parser_error (line_number, _("unexpected argument to conditional binary operator"));
4230           dispose_cond_node (tleft);
4231           dispose_word (op);
4232           COND_RETURN_ERROR ();
4233         }
4234
4235       (void)cond_skip_newlines ();
4236     }
4237   else
4238     {
4239       if (tok < 256)
4240         parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
4241       else if (etext = error_token_from_token (tok))
4242         {
4243           parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
4244           free (etext);
4245         }
4246       else
4247         parser_error (line_number, _("unexpected token %d in conditional command"), tok);
4248       COND_RETURN_ERROR ();
4249     }
4250   return (term);
4251 }      
4252
4253 /* This is kind of bogus -- we slip a mini recursive-descent parser in
4254    here to handle the conditional statement syntax. */
4255 static COMMAND *
4256 parse_cond_command ()
4257 {
4258   COND_COM *cexp;
4259
4260   global_extglob = extended_glob;
4261   cexp = cond_expr ();
4262   return (make_cond_command (cexp));
4263 }
4264 #endif
4265
4266 #if defined (ARRAY_VARS)
4267 /* When this is called, it's guaranteed that we don't care about anything
4268    in t beyond i.  We do save and restore the chars, though. */
4269 static int
4270 token_is_assignment (t, i)
4271      char *t;
4272      int i;
4273 {
4274   unsigned char c, c1;
4275   int r;
4276
4277   c = t[i]; c1 = t[i+1];
4278   t[i] = '='; t[i+1] = '\0';
4279   r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
4280   t[i] = c; t[i+1] = c1;
4281   return r;
4282 }
4283
4284 /* XXX - possible changes here for `+=' */
4285 static int
4286 token_is_ident (t, i)
4287      char *t;
4288      int i;
4289 {
4290   unsigned char c;
4291   int r;
4292
4293   c = t[i];
4294   t[i] = '\0';
4295   r = legal_identifier (t);
4296   t[i] = c;
4297   return r;
4298 }
4299 #endif
4300
4301 static int
4302 read_token_word (character)
4303      int character;
4304 {
4305   /* The value for YYLVAL when a WORD is read. */
4306   WORD_DESC *the_word;
4307
4308   /* Index into the token that we are building. */
4309   int token_index;
4310
4311   /* ALL_DIGITS becomes zero when we see a non-digit. */
4312   int all_digit_token;
4313
4314   /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4315   int dollar_present;
4316
4317   /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4318      assignment. */
4319   int compound_assignment;
4320
4321   /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4322   int quoted;
4323
4324   /* Non-zero means to ignore the value of the next character, and just
4325      to add it no matter what. */
4326  int pass_next_character;
4327
4328   /* The current delimiting character. */
4329   int cd;
4330   int result, peek_char;
4331   char *ttok, *ttrans;
4332   int ttoklen, ttranslen;
4333   intmax_t lvalue;
4334
4335   if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
4336     token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
4337
4338   token_index = 0;
4339   all_digit_token = DIGIT (character);
4340   dollar_present = quoted = pass_next_character = compound_assignment = 0;
4341
4342   for (;;)
4343     {
4344       if (character == EOF)
4345         goto got_token;
4346
4347       if (pass_next_character)
4348         {
4349           pass_next_character = 0;
4350           goto got_escaped_character;
4351         }
4352
4353       cd = current_delimiter (dstack);
4354
4355       /* Handle backslashes.  Quote lots of things when not inside of
4356          double-quotes, quote some things inside of double-quotes. */
4357       if MBTEST(character == '\\')
4358         {
4359           peek_char = shell_getc (0);
4360
4361           /* Backslash-newline is ignored in all cases except
4362              when quoted with single quotes. */
4363           if (peek_char == '\n')
4364             {
4365               character = '\n';
4366               goto next_character;
4367             }
4368           else
4369             {
4370               shell_ungetc (peek_char);
4371
4372               /* If the next character is to be quoted, note it now. */
4373               if (cd == 0 || cd == '`' ||
4374                   (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
4375                 pass_next_character++;
4376
4377               quoted = 1;
4378               goto got_character;
4379             }
4380         }
4381
4382       /* Parse a matched pair of quote characters. */
4383       if MBTEST(shellquote (character))
4384         {
4385           push_delimiter (dstack, character);
4386           ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
4387           pop_delimiter (dstack);
4388           if (ttok == &matched_pair_error)
4389             return -1;          /* Bail immediately. */
4390           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4391                                   token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4392           token[token_index++] = character;
4393           strcpy (token + token_index, ttok);
4394           token_index += ttoklen;
4395           all_digit_token = 0;
4396           quoted = 1;
4397           dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4398           FREE (ttok);
4399           goto next_character;
4400         }
4401
4402 #ifdef COND_REGEXP
4403       /* When parsing a regexp as a single word inside a conditional command,
4404          we need to special-case characters special to both the shell and
4405          regular expressions.  Right now, that is only '(' and '|'. */ /*)*/
4406       if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|'))          /*)*/
4407         {
4408           if (character == '|')
4409             goto got_character;
4410
4411           push_delimiter (dstack, character);
4412           ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4413           pop_delimiter (dstack);
4414           if (ttok == &matched_pair_error)
4415             return -1;          /* Bail immediately. */
4416           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4417                                   token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4418           token[token_index++] = character;
4419           strcpy (token + token_index, ttok);
4420           token_index += ttoklen;
4421           FREE (ttok);
4422           dollar_present = all_digit_token = 0;
4423           goto next_character;
4424         }
4425 #endif /* COND_REGEXP */
4426
4427 #ifdef EXTENDED_GLOB
4428       /* Parse a ksh-style extended pattern matching specification. */
4429       if MBTEST(extended_glob && PATTERN_CHAR (character))
4430         {
4431           peek_char = shell_getc (1);
4432           if MBTEST(peek_char == '(')           /* ) */
4433             {
4434               push_delimiter (dstack, peek_char);
4435               ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4436               pop_delimiter (dstack);
4437               if (ttok == &matched_pair_error)
4438                 return -1;              /* Bail immediately. */
4439               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4440                                       token_buffer_size,
4441                                       TOKEN_DEFAULT_GROW_SIZE);
4442               token[token_index++] = character;
4443               token[token_index++] = peek_char;
4444               strcpy (token + token_index, ttok);
4445               token_index += ttoklen;
4446               FREE (ttok);
4447               dollar_present = all_digit_token = 0;
4448               goto next_character;
4449             }
4450           else
4451             shell_ungetc (peek_char);
4452         }
4453 #endif /* EXTENDED_GLOB */
4454
4455       /* If the delimiter character is not single quote, parse some of
4456          the shell expansions that must be read as a single word. */
4457       if (shellexp (character))
4458         {
4459           peek_char = shell_getc (1);
4460           /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4461           if MBTEST(peek_char == '(' || \
4462                 ((peek_char == '{' || peek_char == '[') && character == '$'))   /* ) ] } */
4463             {
4464               if (peek_char == '{')             /* } */
4465                 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
4466               else if (peek_char == '(')                /* ) */
4467                 {
4468                   /* XXX - push and pop the `(' as a delimiter for use by
4469                      the command-oriented-history code.  This way newlines
4470                      appearing in the $(...) string get added to the
4471                      history literally rather than causing a possibly-
4472                      incorrect `;' to be added. ) */
4473                   push_delimiter (dstack, peek_char);
4474                   ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
4475                   pop_delimiter (dstack);
4476                 }
4477               else
4478                 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4479               if (ttok == &matched_pair_error)
4480                 return -1;              /* Bail immediately. */
4481               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4482                                       token_buffer_size,
4483                                       TOKEN_DEFAULT_GROW_SIZE);
4484               token[token_index++] = character;
4485               token[token_index++] = peek_char;
4486               strcpy (token + token_index, ttok);
4487               token_index += ttoklen;
4488               FREE (ttok);
4489               dollar_present = 1;
4490               all_digit_token = 0;
4491               goto next_character;
4492             }
4493           /* This handles $'...' and $"..." new-style quoted strings. */
4494           else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
4495             {
4496               int first_line;
4497
4498               first_line = line_number;
4499               push_delimiter (dstack, peek_char);
4500               ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4501                                          &ttoklen,
4502                                          (peek_char == '\'') ? P_ALLOWESC : 0);
4503               pop_delimiter (dstack);
4504               if (ttok == &matched_pair_error)
4505                 return -1;
4506               if (peek_char == '\'')
4507                 {
4508                   ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4509                   free (ttok);
4510
4511                   /* Insert the single quotes and correctly quote any
4512                      embedded single quotes (allowed because P_ALLOWESC was
4513                      passed to parse_matched_pair). */
4514                   ttok = sh_single_quote (ttrans);
4515                   free (ttrans);
4516                   ttranslen = strlen (ttok);
4517                   ttrans = ttok;
4518                 }
4519               else
4520                 {
4521                   /* Try to locale-expand the converted string. */
4522                   ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4523                   free (ttok);
4524
4525                   /* Add the double quotes back */
4526                   ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
4527                   free (ttrans);
4528                   ttranslen += 2;
4529                   ttrans = ttok;
4530                 }
4531
4532               RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4533                                       token_buffer_size,
4534                                       TOKEN_DEFAULT_GROW_SIZE);
4535               strcpy (token + token_index, ttrans);
4536               token_index += ttranslen;
4537               FREE (ttrans);
4538               quoted = 1;
4539               all_digit_token = 0;
4540               goto next_character;
4541             }
4542           /* This could eventually be extended to recognize all of the
4543              shell's single-character parameter expansions, and set flags.*/
4544           else if MBTEST(character == '$' && peek_char == '$')
4545             {
4546               ttok = (char *)xmalloc (3);
4547               ttok[0] = ttok[1] = '$';
4548               ttok[2] = '\0';
4549               RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4550                                       token_buffer_size,
4551                                       TOKEN_DEFAULT_GROW_SIZE);
4552               strcpy (token + token_index, ttok);
4553               token_index += 2;
4554               dollar_present = 1;
4555               all_digit_token = 0;
4556               FREE (ttok);
4557               goto next_character;
4558             }
4559           else
4560             shell_ungetc (peek_char);
4561         }
4562
4563 #if defined (ARRAY_VARS)
4564       /* Identify possible array subscript assignment; match [...].  If
4565          parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
4566          `sub' as if it were enclosed in double quotes. */
4567       else if MBTEST(character == '[' &&                /* ] */
4568                      ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
4569                       (token_index == 0 && (parser_state&PST_COMPASSIGN))))
4570         {
4571           ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
4572           if (ttok == &matched_pair_error)
4573             return -1;          /* Bail immediately. */
4574           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4575                                   token_buffer_size,
4576                                   TOKEN_DEFAULT_GROW_SIZE);
4577           token[token_index++] = character;
4578           strcpy (token + token_index, ttok);
4579           token_index += ttoklen;
4580           FREE (ttok);
4581           all_digit_token = 0;
4582           goto next_character;
4583         }
4584       /* Identify possible compound array variable assignment. */
4585       else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
4586         {
4587           peek_char = shell_getc (1);
4588           if MBTEST(peek_char == '(')           /* ) */
4589             {
4590               ttok = parse_compound_assignment (&ttoklen);
4591
4592               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
4593                                       token_buffer_size,
4594                                       TOKEN_DEFAULT_GROW_SIZE);
4595
4596               token[token_index++] = '=';
4597               token[token_index++] = '(';
4598               if (ttok)
4599                 {
4600                   strcpy (token + token_index, ttok);
4601                   token_index += ttoklen;
4602                 }
4603               token[token_index++] = ')';
4604               FREE (ttok);
4605               all_digit_token = 0;
4606               compound_assignment = 1;
4607 #if 1
4608               goto next_character;
4609 #else
4610               goto got_token;           /* ksh93 seems to do this */
4611 #endif
4612             }
4613           else
4614             shell_ungetc (peek_char);
4615         }
4616 #endif
4617
4618       /* When not parsing a multi-character word construct, shell meta-
4619          characters break words. */
4620       if MBTEST(shellbreak (character))
4621         {
4622           shell_ungetc (character);
4623           goto got_token;
4624         }
4625
4626     got_character:
4627
4628       if (character == CTLESC || character == CTLNUL)
4629         token[token_index++] = CTLESC;
4630
4631     got_escaped_character:
4632
4633       all_digit_token &= DIGIT (character);
4634       dollar_present |= character == '$';
4635
4636       token[token_index++] = character;
4637
4638       RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4639                               TOKEN_DEFAULT_GROW_SIZE);
4640
4641     next_character:
4642       if (character == '\n' && SHOULD_PROMPT ())
4643         prompt_again ();
4644
4645       /* We want to remove quoted newlines (that is, a \<newline> pair)
4646          unless we are within single quotes or pass_next_character is
4647          set (the shell equivalent of literal-next). */
4648       cd = current_delimiter (dstack);
4649       character = shell_getc (cd != '\'' && pass_next_character == 0);
4650     }   /* end for (;;) */
4651
4652 got_token:
4653
4654   token[token_index] = '\0';
4655
4656   /* Check to see what thing we should return.  If the last_read_token
4657      is a `<', or a `&', or the character which ended this token is
4658      a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4659      Otherwise, it is just a word, and should be returned as such. */
4660   if MBTEST(all_digit_token && (character == '<' || character == '>' || \
4661                     last_read_token == LESS_AND || \
4662                     last_read_token == GREATER_AND))
4663       {
4664         if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
4665           yylval.number = lvalue;
4666         else
4667           yylval.number = -1;
4668         return (NUMBER);
4669       }
4670
4671   /* Check for special case tokens. */
4672   result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
4673   if (result >= 0)
4674     return result;
4675
4676 #if defined (ALIAS)
4677   /* Posix.2 does not allow reserved words to be aliased, so check for all
4678      of them, including special cases, before expanding the current token
4679      as an alias. */
4680   if MBTEST(posixly_correct)
4681     CHECK_FOR_RESERVED_WORD (token);
4682
4683   /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4684      inhibits alias expansion. */
4685   if (expand_aliases && quoted == 0)
4686     {
4687       result = alias_expand_token (token);
4688       if (result == RE_READ_TOKEN)
4689         return (RE_READ_TOKEN);
4690       else if (result == NO_EXPANSION)
4691         parser_state &= ~PST_ALEXPNEXT;
4692     }
4693
4694   /* If not in Posix.2 mode, check for reserved words after alias
4695      expansion. */
4696   if MBTEST(posixly_correct == 0)
4697 #endif
4698     CHECK_FOR_RESERVED_WORD (token);
4699
4700   the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4701   the_word->word = (char *)xmalloc (1 + token_index);
4702   the_word->flags = 0;
4703   strcpy (the_word->word, token);
4704   if (dollar_present)
4705     the_word->flags |= W_HASDOLLAR;
4706   if (quoted)
4707     the_word->flags |= W_QUOTED;                /*(*/
4708   if (compound_assignment && token[token_index-1] == ')')
4709     the_word->flags |= W_COMPASSIGN;
4710   /* A word is an assignment if it appears at the beginning of a
4711      simple command, or after another assignment word.  This is
4712      context-dependent, so it cannot be handled in the grammar. */
4713   if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
4714     {
4715       the_word->flags |= W_ASSIGNMENT;
4716       /* Don't perform word splitting on assignment statements. */
4717       if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
4718         the_word->flags |= W_NOSPLIT;
4719     }
4720
4721   if (command_token_position (last_read_token))
4722     {
4723       struct builtin *b;
4724       b = builtin_address_internal (token, 0);
4725       if (b && (b->flags & ASSIGNMENT_BUILTIN))
4726         parser_state |= PST_ASSIGNOK;
4727       else if (STREQ (token, "eval") || STREQ (token, "let"))
4728         parser_state |= PST_ASSIGNOK;
4729     }
4730
4731   yylval.word = the_word;
4732
4733   if (token[0] == '{' && token[token_index-1] == '}' &&
4734       (character == '<' || character == '>'))
4735     {
4736       /* can use token; already copied to the_word */
4737       token[token_index-1] = '\0';
4738       if (legal_identifier (token+1))
4739         {
4740           strcpy (the_word->word, token+1);
4741 /*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
4742           return (REDIR_WORD);
4743         }
4744     }
4745
4746   result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4747                 ? ASSIGNMENT_WORD : WORD;
4748
4749   switch (last_read_token)
4750     {
4751     case FUNCTION:
4752       parser_state |= PST_ALLOWOPNBRC;
4753       function_dstart = line_number;
4754       break;
4755     case CASE:
4756     case SELECT:
4757     case FOR:
4758       if (word_top < MAX_CASE_NEST)
4759         word_top++;
4760       word_lineno[word_top] = line_number;
4761       break;
4762     }
4763
4764   return (result);
4765 }
4766
4767 /* Return 1 if TOKSYM is a token that after being read would allow
4768    a reserved word to be seen, else 0. */
4769 static int
4770 reserved_word_acceptable (toksym)
4771      int toksym;
4772 {
4773   switch (toksym)
4774     {
4775     case '\n':
4776     case ';':
4777     case '(':
4778     case ')':
4779     case '|':
4780     case '&':
4781     case '{':
4782     case '}':           /* XXX */
4783     case AND_AND:
4784     case BANG:
4785     case BAR_AND:
4786     case DO:
4787     case DONE:
4788     case ELIF:
4789     case ELSE:
4790     case ESAC:
4791     case FI:
4792     case IF:
4793     case OR_OR:
4794     case SEMI_SEMI:
4795     case SEMI_AND:
4796     case SEMI_SEMI_AND:
4797     case THEN:
4798     case TIME:
4799     case TIMEOPT:
4800     case TIMEIGN:
4801     case COPROC:
4802     case UNTIL:
4803     case WHILE:
4804     case 0:
4805       return 1;
4806     default:
4807 #if defined (COPROCESS_SUPPORT)
4808       if (last_read_token == WORD && token_before_that == COPROC)
4809         return 1;
4810 #endif
4811       if (last_read_token == WORD && token_before_that == FUNCTION)
4812         return 1;
4813       return 0;
4814     }
4815 }
4816     
4817 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4818    TOKEN is not a shell reserved word. */
4819 int
4820 find_reserved_word (tokstr)
4821      char *tokstr;
4822 {
4823   int i;
4824   for (i = 0; word_token_alist[i].word; i++)
4825     if (STREQ (tokstr, word_token_alist[i].word))
4826       return i;
4827   return -1;
4828 }
4829
4830 #if 0
4831 #if defined (READLINE)
4832 /* Called after each time readline is called.  This insures that whatever
4833    the new prompt string is gets propagated to readline's local prompt
4834    variable. */
4835 static void
4836 reset_readline_prompt ()
4837 {
4838   char *temp_prompt;
4839
4840   if (prompt_string_pointer)
4841     {
4842       temp_prompt = (*prompt_string_pointer)
4843                         ? decode_prompt_string (*prompt_string_pointer)
4844                         : (char *)NULL;
4845
4846       if (temp_prompt == 0)
4847         {
4848           temp_prompt = (char *)xmalloc (1);
4849           temp_prompt[0] = '\0';
4850         }
4851
4852       FREE (current_readline_prompt);
4853       current_readline_prompt = temp_prompt;
4854     }
4855 }
4856 #endif /* READLINE */
4857 #endif /* 0 */
4858
4859 #if defined (HISTORY)
4860 /* A list of tokens which can be followed by newlines, but not by
4861    semi-colons.  When concatenating multiple lines of history, the
4862    newline separator for such tokens is replaced with a space. */
4863 static const int no_semi_successors[] = {
4864   '\n', '{', '(', ')', ';', '&', '|',
4865   CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
4866   WHILE, AND_AND, OR_OR, IN,
4867   0
4868 };
4869
4870 /* If we are not within a delimited expression, try to be smart
4871    about which separators can be semi-colons and which must be
4872    newlines.  Returns the string that should be added into the
4873    history entry.  LINE is the line we're about to add; it helps
4874    make some more intelligent decisions in certain cases. */
4875 char *
4876 history_delimiting_chars (line)
4877      const char *line;
4878 {
4879   static int last_was_heredoc = 0;      /* was the last entry the start of a here document? */
4880   register int i;
4881
4882   if ((parser_state & PST_HEREDOC) == 0)
4883     last_was_heredoc = 0;
4884
4885   if (dstack.delimiter_depth != 0)
4886     return ("\n");
4887
4888   /* We look for current_command_line_count == 2 because we are looking to
4889      add the first line of the body of the here document (the second line
4890      of the command).  We also keep LAST_WAS_HEREDOC as a private sentinel
4891      variable to note when we think we added the first line of a here doc
4892      (the one with a "<<" somewhere in it) */
4893   if (parser_state & PST_HEREDOC)
4894     {
4895       if (last_was_heredoc)
4896         {
4897           last_was_heredoc = 0;
4898           return "\n";
4899         }
4900       return (current_command_line_count == 2 ? "\n" : "");
4901     }
4902
4903   if (parser_state & PST_COMPASSIGN)
4904     return (" ");
4905
4906   /* First, handle some special cases. */
4907   /*(*/
4908   /* If we just read `()', assume it's a function definition, and don't
4909      add a semicolon.  If the token before the `)' was not `(', and we're
4910      not in the midst of parsing a case statement, assume it's a
4911      parenthesized command and add the semicolon. */
4912   /*)(*/
4913   if (token_before_that == ')')
4914     {
4915       if (two_tokens_ago == '(')        /*)*/   /* function def */
4916         return " ";
4917       /* This does not work for subshells inside case statement
4918          command lists.  It's a suboptimal solution. */
4919       else if (parser_state & PST_CASESTMT)     /* case statement pattern */
4920         return " ";
4921       else      
4922         return "; ";                            /* (...) subshell */
4923     }
4924   else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4925     return " ";         /* function def using `function name' without `()' */
4926
4927   /* If we're not in a here document, but we think we're about to parse one,
4928      and we would otherwise return a `;', return a newline to delimit the
4929      line with the here-doc delimiter */
4930   else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
4931     {
4932       last_was_heredoc = 1;
4933       return "\n";
4934     }
4935
4936   else if (token_before_that == WORD && two_tokens_ago == FOR)
4937     {
4938       /* Tricky.  `for i\nin ...' should not have a semicolon, but
4939          `for i\ndo ...' should.  We do what we can. */
4940       for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
4941         ;
4942       if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
4943         return " ";
4944       return ";";
4945     }
4946   else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
4947     return " ";
4948
4949   for (i = 0; no_semi_successors[i]; i++)
4950     {
4951       if (token_before_that == no_semi_successors[i])
4952         return (" ");
4953     }
4954
4955   return ("; ");
4956 }
4957 #endif /* HISTORY */
4958
4959 /* Issue a prompt, or prepare to issue a prompt when the next character
4960    is read. */
4961 static void
4962 prompt_again ()
4963 {
4964   char *temp_prompt;
4965
4966   if (interactive == 0 || expanding_alias ())   /* XXX */
4967     return;
4968
4969   ps1_prompt = get_string_value ("PS1");
4970   ps2_prompt = get_string_value ("PS2");
4971
4972   if (!prompt_string_pointer)
4973     prompt_string_pointer = &ps1_prompt;
4974
4975   temp_prompt = *prompt_string_pointer
4976                         ? decode_prompt_string (*prompt_string_pointer)
4977                         : (char *)NULL;
4978
4979   if (temp_prompt == 0)
4980     {
4981       temp_prompt = (char *)xmalloc (1);
4982       temp_prompt[0] = '\0';
4983     }
4984
4985   current_prompt_string = *prompt_string_pointer;
4986   prompt_string_pointer = &ps2_prompt;
4987
4988 #if defined (READLINE)
4989   if (!no_line_editing)
4990     {
4991       FREE (current_readline_prompt);
4992       current_readline_prompt = temp_prompt;
4993     }
4994   else
4995 #endif  /* READLINE */
4996     {
4997       FREE (current_decoded_prompt);
4998       current_decoded_prompt = temp_prompt;
4999     }
5000 }
5001
5002 int
5003 get_current_prompt_level ()
5004 {
5005   return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
5006 }
5007
5008 void
5009 set_current_prompt_level (x)
5010      int x;
5011 {
5012   prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
5013   current_prompt_string = *prompt_string_pointer;
5014 }
5015       
5016 static void
5017 print_prompt ()
5018 {
5019   fprintf (stderr, "%s", current_decoded_prompt);
5020   fflush (stderr);
5021 }
5022
5023 /* Return a string which will be printed as a prompt.  The string
5024    may contain special characters which are decoded as follows:
5025
5026         \a      bell (ascii 07)
5027         \d      the date in Day Mon Date format
5028         \e      escape (ascii 033)
5029         \h      the hostname up to the first `.'
5030         \H      the hostname
5031         \j      the number of active jobs
5032         \l      the basename of the shell's tty device name
5033         \n      CRLF
5034         \r      CR
5035         \s      the name of the shell
5036         \t      the time in 24-hour hh:mm:ss format
5037         \T      the time in 12-hour hh:mm:ss format
5038         \@      the time in 12-hour hh:mm am/pm format
5039         \A      the time in 24-hour hh:mm format
5040         \D{fmt} the result of passing FMT to strftime(3)
5041         \u      your username
5042         \v      the version of bash (e.g., 2.00)
5043         \V      the release of bash, version + patchlevel (e.g., 2.00.0)
5044         \w      the current working directory
5045         \W      the last element of $PWD
5046         \!      the history number of this command
5047         \#      the command number of this command
5048         \$      a $ or a # if you are root
5049         \nnn    character code nnn in octal
5050         \\      a backslash
5051         \[      begin a sequence of non-printing chars
5052         \]      end a sequence of non-printing chars
5053 */
5054 #define PROMPT_GROWTH 48
5055 char *
5056 decode_prompt_string (string)
5057      char *string;
5058 {
5059   WORD_LIST *list;
5060   char *result, *t;
5061   struct dstack save_dstack;
5062   int last_exit_value, last_comsub_pid;
5063 #if defined (PROMPT_STRING_DECODE)
5064   int result_size, result_index;
5065   int c, n, i;
5066   char *temp, octal_string[4];
5067   struct tm *tm;  
5068   time_t the_time;
5069   char timebuf[128];
5070   char *timefmt;
5071
5072   result = (char *)xmalloc (result_size = PROMPT_GROWTH);
5073   result[result_index = 0] = 0;
5074   temp = (char *)NULL;
5075
5076   while (c = *string++)
5077     {
5078       if (posixly_correct && c == '!')
5079         {
5080           if (*string == '!')
5081             {
5082               temp = savestring ("!");
5083               goto add_string;
5084             }
5085           else
5086             {
5087 #if !defined (HISTORY)
5088                 temp = savestring ("1");
5089 #else /* HISTORY */
5090                 temp = itos (history_number ());
5091 #endif /* HISTORY */
5092                 string--;       /* add_string increments string again. */
5093                 goto add_string;
5094             }
5095         }
5096       if (c == '\\')
5097         {
5098           c = *string;
5099
5100           switch (c)
5101             {
5102             case '0':
5103             case '1':
5104             case '2':
5105             case '3':
5106             case '4':
5107             case '5':
5108             case '6':
5109             case '7':
5110               strncpy (octal_string, string, 3);
5111               octal_string[3] = '\0';
5112
5113               n = read_octal (octal_string);
5114               temp = (char *)xmalloc (3);
5115
5116               if (n == CTLESC || n == CTLNUL)
5117                 {
5118                   temp[0] = CTLESC;
5119                   temp[1] = n;
5120                   temp[2] = '\0';
5121                 }
5122               else if (n == -1)
5123                 {
5124                   temp[0] = '\\';
5125                   temp[1] = '\0';
5126                 }
5127               else
5128                 {
5129                   temp[0] = n;
5130                   temp[1] = '\0';
5131                 }
5132
5133               for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
5134                 string++;
5135
5136               c = 0;            /* tested at add_string: */
5137               goto add_string;
5138
5139             case 'd':
5140             case 't':
5141             case 'T':
5142             case '@':
5143             case 'A':
5144               /* Make the current time/date into a string. */
5145               (void) time (&the_time);
5146 #if defined (HAVE_TZSET)
5147               sv_tz ("TZ");             /* XXX -- just make sure */
5148 #endif
5149               tm = localtime (&the_time);
5150
5151               if (c == 'd')
5152                 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
5153               else if (c == 't')
5154                 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
5155               else if (c == 'T')
5156                 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
5157               else if (c == '@')
5158                 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
5159               else if (c == 'A')
5160                 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
5161
5162               if (n == 0)
5163                 timebuf[0] = '\0';
5164               else
5165                 timebuf[sizeof(timebuf) - 1] = '\0';
5166
5167               temp = savestring (timebuf);
5168               goto add_string;
5169
5170             case 'D':           /* strftime format */
5171               if (string[1] != '{')             /* } */
5172                 goto not_escape;
5173
5174               (void) time (&the_time);
5175               tm = localtime (&the_time);
5176               string += 2;                      /* skip { */
5177               timefmt = xmalloc (strlen (string) + 3);
5178               for (t = timefmt; *string && *string != '}'; )
5179                 *t++ = *string++;
5180               *t = '\0';
5181               c = *string;      /* tested at add_string */
5182               if (timefmt[0] == '\0')
5183                 {
5184                   timefmt[0] = '%';
5185                   timefmt[1] = 'X';     /* locale-specific current time */
5186                   timefmt[2] = '\0';
5187                 }
5188               n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
5189               free (timefmt);
5190
5191               if (n == 0)
5192                 timebuf[0] = '\0';
5193               else
5194                 timebuf[sizeof(timebuf) - 1] = '\0';
5195
5196               if (promptvars || posixly_correct)
5197                 /* Make sure that expand_prompt_string is called with a
5198                    second argument of Q_DOUBLE_QUOTES if we use this
5199                    function here. */
5200                 temp = sh_backslash_quote_for_double_quotes (timebuf);
5201               else
5202                 temp = savestring (timebuf);
5203               goto add_string;
5204               
5205             case 'n':
5206               temp = (char *)xmalloc (3);
5207               temp[0] = no_line_editing ? '\n' : '\r';
5208               temp[1] = no_line_editing ? '\0' : '\n';
5209               temp[2] = '\0';
5210               goto add_string;
5211
5212             case 's':
5213               temp = base_pathname (shell_name);
5214               temp = savestring (temp);
5215               goto add_string;
5216
5217             case 'v':
5218             case 'V':
5219               temp = (char *)xmalloc (16);
5220               if (c == 'v')
5221                 strcpy (temp, dist_version);
5222               else
5223                 sprintf (temp, "%s.%d", dist_version, patch_level);
5224               goto add_string;
5225
5226             case 'w':
5227             case 'W':
5228               {
5229                 /* Use the value of PWD because it is much more efficient. */
5230                 char t_string[PATH_MAX];
5231                 int tlen;
5232
5233                 temp = get_string_value ("PWD");
5234
5235                 if (temp == 0)
5236                   {
5237                     if (getcwd (t_string, sizeof(t_string)) == 0)
5238                       {
5239                         t_string[0] = '.';
5240                         tlen = 1;
5241                       }
5242                     else
5243                       tlen = strlen (t_string);
5244                   }
5245                 else
5246                   {
5247                     tlen = sizeof (t_string) - 1;
5248                     strncpy (t_string, temp, tlen);
5249                   }
5250                 t_string[tlen] = '\0';
5251
5252 #if defined (MACOSX)
5253                 /* Convert from "fs" format to "input" format */
5254                 temp = fnx_fromfs (t_string, strlen (t_string));
5255                 if (temp != t_string)
5256                   strcpy (t_string, temp);
5257 #endif
5258
5259 #define ROOT_PATH(x)    ((x)[0] == '/' && (x)[1] == 0)
5260 #define DOUBLE_SLASH_ROOT(x)    ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
5261                 /* Abbreviate \W as ~ if $PWD == $HOME */
5262                 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
5263                   {
5264                     if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
5265                       {
5266                         t = strrchr (t_string, '/');
5267                         if (t)
5268                           memmove (t_string, t + 1, strlen (t));        /* strlen(t) to copy NULL */
5269                       }
5270                   }
5271 #undef ROOT_PATH
5272 #undef DOUBLE_SLASH_ROOT
5273                 else
5274                   /* polite_directory_format is guaranteed to return a string
5275                      no longer than PATH_MAX - 1 characters. */
5276                   strcpy (t_string, polite_directory_format (t_string));
5277
5278                 temp = trim_pathname (t_string, PATH_MAX - 1);
5279                 /* If we're going to be expanding the prompt string later,
5280                    quote the directory name. */
5281                 if (promptvars || posixly_correct)
5282                   /* Make sure that expand_prompt_string is called with a
5283                      second argument of Q_DOUBLE_QUOTES if we use this
5284                      function here. */
5285                   temp = sh_backslash_quote_for_double_quotes (t_string);
5286                 else
5287                   temp = savestring (t_string);
5288
5289                 goto add_string;
5290               }
5291
5292             case 'u':
5293               if (current_user.user_name == 0)
5294                 get_current_user_info ();
5295               temp = savestring (current_user.user_name);
5296               goto add_string;
5297
5298             case 'h':
5299             case 'H':
5300               temp = savestring (current_host_name);
5301               if (c == 'h' && (t = (char *)strchr (temp, '.')))
5302                 *t = '\0';
5303               goto add_string;
5304
5305             case '#':
5306               temp = itos (current_command_number);
5307               goto add_string;
5308
5309             case '!':
5310 #if !defined (HISTORY)
5311               temp = savestring ("1");
5312 #else /* HISTORY */
5313               temp = itos (history_number ());
5314 #endif /* HISTORY */
5315               goto add_string;
5316
5317             case '$':
5318               t = temp = (char *)xmalloc (3);
5319               if ((promptvars || posixly_correct) && (current_user.euid != 0))
5320                 *t++ = '\\';
5321               *t++ = current_user.euid == 0 ? '#' : '$';
5322               *t = '\0';
5323               goto add_string;
5324
5325             case 'j':
5326               temp = itos (count_all_jobs ());
5327               goto add_string;
5328
5329             case 'l':
5330 #if defined (HAVE_TTYNAME)
5331               temp = (char *)ttyname (fileno (stdin));
5332               t = temp ? base_pathname (temp) : "tty";
5333               temp = savestring (t);
5334 #else
5335               temp = savestring ("tty");
5336 #endif /* !HAVE_TTYNAME */
5337               goto add_string;
5338
5339 #if defined (READLINE)
5340             case '[':
5341             case ']':
5342               if (no_line_editing)
5343                 {
5344                   string++;
5345                   break;
5346                 }
5347               temp = (char *)xmalloc (3);
5348               n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
5349               i = 0;
5350               if (n == CTLESC || n == CTLNUL)
5351                 temp[i++] = CTLESC;
5352               temp[i++] = n;
5353               temp[i] = '\0';
5354               goto add_string;
5355 #endif /* READLINE */
5356
5357             case '\\':
5358             case 'a':
5359             case 'e':
5360             case 'r':
5361               temp = (char *)xmalloc (2);
5362               if (c == 'a')
5363                 temp[0] = '\07';
5364               else if (c == 'e')
5365                 temp[0] = '\033';
5366               else if (c == 'r')
5367                 temp[0] = '\r';
5368               else                      /* (c == '\\') */
5369                 temp[0] = c;
5370               temp[1] = '\0';
5371               goto add_string;
5372
5373             default:
5374 not_escape:
5375               temp = (char *)xmalloc (3);
5376               temp[0] = '\\';
5377               temp[1] = c;
5378               temp[2] = '\0';
5379
5380             add_string:
5381               if (c)
5382                 string++;
5383               result =
5384                 sub_append_string (temp, result, &result_index, &result_size);
5385               temp = (char *)NULL; /* Freed in sub_append_string (). */
5386               result[result_index] = '\0';
5387               break;
5388             }
5389         }
5390       else
5391         {
5392           RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
5393           result[result_index++] = c;
5394           result[result_index] = '\0';
5395         }
5396     }
5397 #else /* !PROMPT_STRING_DECODE */
5398   result = savestring (string);
5399 #endif /* !PROMPT_STRING_DECODE */
5400
5401   /* Save the delimiter stack and point `dstack' to temp space so any
5402      command substitutions in the prompt string won't result in screwing
5403      up the parser's quoting state. */
5404   save_dstack = dstack;
5405   dstack = temp_dstack;
5406   dstack.delimiter_depth = 0;
5407
5408   /* Perform variable and parameter expansion and command substitution on
5409      the prompt string. */
5410   if (promptvars || posixly_correct)
5411     {
5412       last_exit_value = last_command_exit_value;
5413       last_comsub_pid = last_command_subst_pid;
5414       list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
5415       free (result);
5416       result = string_list (list);
5417       dispose_words (list);
5418       last_command_exit_value = last_exit_value;
5419       last_command_subst_pid = last_comsub_pid;
5420     }
5421   else
5422     {
5423       t = dequote_string (result);
5424       free (result);
5425       result = t;
5426     }
5427
5428   dstack = save_dstack;
5429
5430   return (result);
5431 }
5432
5433 /************************************************
5434  *                                              *
5435  *              ERROR HANDLING                  *
5436  *                                              *
5437  ************************************************/
5438
5439 /* Report a syntax error, and restart the parser.  Call here for fatal
5440    errors. */
5441 int
5442 yyerror (msg)
5443      const char *msg;
5444 {
5445   report_syntax_error ((char *)NULL);
5446   reset_parser ();
5447   return (0);
5448 }
5449
5450 static char *
5451 error_token_from_token (tok)
5452      int tok;
5453 {
5454   char *t;
5455
5456   if (t = find_token_in_alist (tok, word_token_alist, 0))
5457     return t;
5458
5459   if (t = find_token_in_alist (tok, other_token_alist, 0))
5460     return t;
5461
5462   t = (char *)NULL;
5463   /* This stuff is dicy and needs closer inspection */
5464   switch (current_token)
5465     {
5466     case WORD:
5467     case ASSIGNMENT_WORD:
5468       if (yylval.word)
5469         t = savestring (yylval.word->word);
5470       break;
5471     case NUMBER:
5472       t = itos (yylval.number);
5473       break;
5474     case ARITH_CMD:
5475       if (yylval.word_list)
5476         t = string_list (yylval.word_list);
5477       break;
5478     case ARITH_FOR_EXPRS:
5479       if (yylval.word_list)
5480         t = string_list_internal (yylval.word_list, " ; ");
5481       break;
5482     case COND_CMD:
5483       t = (char *)NULL;         /* punt */
5484       break;
5485     }
5486
5487   return t;
5488 }
5489
5490 static char *
5491 error_token_from_text ()
5492 {
5493   char *msg, *t;
5494   int token_end, i;
5495
5496   t = shell_input_line;
5497   i = shell_input_line_index;
5498   token_end = 0;
5499   msg = (char *)NULL;
5500
5501   if (i && t[i] == '\0')
5502     i--;
5503
5504   while (i && (whitespace (t[i]) || t[i] == '\n'))
5505     i--;
5506
5507   if (i)
5508     token_end = i + 1;
5509
5510   while (i && (member (t[i], " \n\t;|&") == 0))
5511     i--;
5512
5513   while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
5514     i++;
5515
5516   /* Return our idea of the offending token. */
5517   if (token_end || (i == 0 && token_end == 0))
5518     {
5519       if (token_end)
5520         msg = substring (t, i, token_end);
5521       else      /* one-character token */
5522         {
5523           msg = (char *)xmalloc (2);
5524           msg[0] = t[i];
5525           msg[1] = '\0';
5526         }
5527     }
5528
5529   return (msg);
5530 }
5531
5532 static void
5533 print_offending_line ()
5534 {
5535   char *msg;
5536   int token_end;
5537
5538   msg = savestring (shell_input_line);
5539   token_end = strlen (msg);
5540   while (token_end && msg[token_end - 1] == '\n')
5541     msg[--token_end] = '\0';
5542
5543   parser_error (line_number, "`%s'", msg);
5544   free (msg);
5545 }
5546
5547 /* Report a syntax error with line numbers, etc.
5548    Call here for recoverable errors.  If you have a message to print,
5549    then place it in MESSAGE, otherwise pass NULL and this will figure
5550    out an appropriate message for you. */
5551 static void
5552 report_syntax_error (message)
5553      char *message;
5554 {
5555   char *msg, *p;
5556
5557   if (message)
5558     {
5559       parser_error (line_number, "%s", message);
5560       if (interactive && EOF_Reached)
5561         EOF_Reached = 0;
5562       last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
5563       return;
5564     }
5565
5566   /* If the line of input we're reading is not null, try to find the
5567      objectionable token.  First, try to figure out what token the
5568      parser's complaining about by looking at current_token. */
5569   if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
5570     {
5571       if (ansic_shouldquote (msg))
5572         {
5573           p = ansic_quote (msg, 0, NULL);
5574           free (msg);
5575           msg = p;
5576         }
5577       parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
5578       free (msg);
5579
5580       if (interactive == 0)
5581         print_offending_line ();
5582
5583       last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
5584       return;
5585     }
5586
5587   /* If looking at the current token doesn't prove fruitful, try to find the
5588      offending token by analyzing the text of the input line near the current
5589      input line index and report what we find. */
5590   if (shell_input_line && *shell_input_line)
5591     {
5592       msg = error_token_from_text ();
5593       if (msg)
5594         {
5595           parser_error (line_number, _("syntax error near `%s'"), msg);
5596           free (msg);
5597         }
5598
5599       /* If not interactive, print the line containing the error. */
5600       if (interactive == 0)
5601         print_offending_line ();
5602     }
5603   else
5604     {
5605       msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
5606       parser_error (line_number, "%s", msg);
5607       /* When the shell is interactive, this file uses EOF_Reached
5608          only for error reporting.  Other mechanisms are used to
5609          decide whether or not to exit. */
5610       if (interactive && EOF_Reached)
5611         EOF_Reached = 0;
5612     }
5613
5614   last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
5615 }
5616
5617 /* ??? Needed function. ??? We have to be able to discard the constructs
5618    created during parsing.  In the case of error, we want to return
5619    allocated objects to the memory pool.  In the case of no error, we want
5620    to throw away the information about where the allocated objects live.
5621    (dispose_command () will actually free the command.) */
5622 static void
5623 discard_parser_constructs (error_p)
5624      int error_p;
5625 {
5626 }
5627
5628 /************************************************
5629  *                                              *
5630  *              EOF HANDLING                    *
5631  *                                              *
5632  ************************************************/
5633
5634 /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
5635
5636 /* A flag denoting whether or not ignoreeof is set. */
5637 int ignoreeof = 0;
5638
5639 /* The number of times that we have encountered an EOF character without
5640    another character intervening.  When this gets above the limit, the
5641    shell terminates. */
5642 int eof_encountered = 0;
5643
5644 /* The limit for eof_encountered. */
5645 int eof_encountered_limit = 10;
5646
5647 /* If we have EOF as the only input unit, this user wants to leave
5648    the shell.  If the shell is not interactive, then just leave.
5649    Otherwise, if ignoreeof is set, and we haven't done this the
5650    required number of times in a row, print a message. */
5651 static void
5652 handle_eof_input_unit ()
5653 {
5654   if (interactive)
5655     {
5656       /* shell.c may use this to decide whether or not to write out the
5657          history, among other things.  We use it only for error reporting
5658          in this file. */
5659       if (EOF_Reached)
5660         EOF_Reached = 0;
5661
5662       /* If the user wants to "ignore" eof, then let her do so, kind of. */
5663       if (ignoreeof)
5664         {
5665           if (eof_encountered < eof_encountered_limit)
5666             {
5667               fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
5668                        login_shell ? "logout" : "exit");
5669               eof_encountered++;
5670               /* Reset the parsing state. */
5671               last_read_token = current_token = '\n';
5672               /* Reset the prompt string to be $PS1. */
5673               prompt_string_pointer = (char **)NULL;
5674               prompt_again ();
5675               return;
5676             }
5677         }
5678
5679       /* In this case EOF should exit the shell.  Do it now. */
5680       reset_parser ();
5681       exit_builtin ((WORD_LIST *)NULL);
5682     }
5683   else
5684     {
5685       /* We don't write history files, etc., for non-interactive shells. */
5686       EOF_Reached = 1;
5687     }
5688 }
5689
5690 /************************************************
5691  *                                              *
5692  *      STRING PARSING FUNCTIONS                *
5693  *                                              *
5694  ************************************************/
5695
5696 /* It's very important that these two functions treat the characters
5697    between ( and ) identically. */
5698
5699 static WORD_LIST parse_string_error;
5700
5701 /* Take a string and run it through the shell parser, returning the
5702    resultant word list.  Used by compound array assignment. */
5703 WORD_LIST *
5704 parse_string_to_word_list (s, flags, whom)
5705      char *s;
5706      int flags;
5707      const char *whom;
5708 {
5709   WORD_LIST *wl;
5710   int tok, orig_current_token, orig_line_number, orig_input_terminator;
5711   int orig_line_count;
5712   int old_echo_input, old_expand_aliases;
5713 #if defined (HISTORY)
5714   int old_remember_on_history, old_history_expansion_inhibited;
5715 #endif
5716
5717 #if defined (HISTORY)
5718   old_remember_on_history = remember_on_history;
5719 #  if defined (BANG_HISTORY)
5720   old_history_expansion_inhibited = history_expansion_inhibited;
5721 #  endif
5722   bash_history_disable ();
5723 #endif
5724
5725   orig_line_number = line_number;
5726   orig_line_count = current_command_line_count;
5727   orig_input_terminator = shell_input_line_terminator;
5728   old_echo_input = echo_input_at_read;
5729   old_expand_aliases = expand_aliases;
5730
5731   push_stream (1);
5732   last_read_token = WORD;               /* WORD to allow reserved words here */
5733   current_command_line_count = 0;
5734   echo_input_at_read = expand_aliases = 0;
5735
5736   with_input_from_string (s, whom);
5737   wl = (WORD_LIST *)NULL;
5738
5739   if (flags & 1)
5740     parser_state |= PST_COMPASSIGN|PST_REPARSE;
5741
5742   while ((tok = read_token (READ)) != yacc_EOF)
5743     {
5744       if (tok == '\n' && *bash_input.location.string == '\0')
5745         break;
5746       if (tok == '\n')          /* Allow newlines in compound assignments */
5747         continue;
5748       if (tok != WORD && tok != ASSIGNMENT_WORD)
5749         {
5750           line_number = orig_line_number + line_number - 1;
5751           orig_current_token = current_token;
5752           current_token = tok;
5753           yyerror (NULL);       /* does the right thing */
5754           current_token = orig_current_token;
5755           if (wl)
5756             dispose_words (wl);
5757           wl = &parse_string_error;
5758           break;
5759         }
5760       wl = make_word_list (yylval.word, wl);
5761     }
5762   
5763   last_read_token = '\n';
5764   pop_stream ();
5765
5766 #if defined (HISTORY)
5767   remember_on_history = old_remember_on_history;
5768 #  if defined (BANG_HISTORY)
5769   history_expansion_inhibited = old_history_expansion_inhibited;
5770 #  endif /* BANG_HISTORY */
5771 #endif /* HISTORY */
5772
5773   echo_input_at_read = old_echo_input;
5774   expand_aliases = old_expand_aliases;
5775
5776   current_command_line_count = orig_line_count;
5777   shell_input_line_terminator = orig_input_terminator;
5778
5779   if (flags & 1)
5780     parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
5781
5782   if (wl == &parse_string_error)
5783     {
5784       last_command_exit_value = EXECUTION_FAILURE;
5785       if (interactive_shell == 0 && posixly_correct)
5786         jump_to_top_level (FORCE_EOF);
5787       else
5788         jump_to_top_level (DISCARD);
5789     }
5790
5791   return (REVERSE_LIST (wl, WORD_LIST *));
5792 }
5793
5794 static char *
5795 parse_compound_assignment (retlenp)
5796      int *retlenp;
5797 {
5798   WORD_LIST *wl, *rl;
5799   int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
5800   char *saved_token, *ret;
5801
5802   saved_token = token;
5803   orig_token_size = token_buffer_size;
5804   orig_line_number = line_number;
5805   orig_last_token = last_read_token;
5806
5807   last_read_token = WORD;       /* WORD to allow reserved words here */
5808
5809   token = (char *)NULL;
5810   token_buffer_size = 0;
5811
5812   assignok = parser_state&PST_ASSIGNOK;         /* XXX */
5813
5814   wl = (WORD_LIST *)NULL;       /* ( */
5815   parser_state |= PST_COMPASSIGN;
5816
5817   while ((tok = read_token (READ)) != ')')
5818     {
5819       if (tok == '\n')                  /* Allow newlines in compound assignments */
5820         {
5821           if (SHOULD_PROMPT ())
5822             prompt_again ();
5823           continue;
5824         }
5825       if (tok != WORD && tok != ASSIGNMENT_WORD)
5826         {
5827           current_token = tok;  /* for error reporting */
5828           if (tok == yacc_EOF)  /* ( */
5829             parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
5830           else
5831             yyerror(NULL);      /* does the right thing */
5832           if (wl)
5833             dispose_words (wl);
5834           wl = &parse_string_error;
5835           break;
5836         }
5837       wl = make_word_list (yylval.word, wl);
5838     }
5839
5840   FREE (token);
5841   token = saved_token;
5842   token_buffer_size = orig_token_size;
5843
5844   parser_state &= ~PST_COMPASSIGN;
5845
5846   if (wl == &parse_string_error)
5847     {
5848       last_command_exit_value = EXECUTION_FAILURE;
5849       last_read_token = '\n';   /* XXX */
5850       if (interactive_shell == 0 && posixly_correct)
5851         jump_to_top_level (FORCE_EOF);
5852       else
5853         jump_to_top_level (DISCARD);
5854     }
5855
5856   last_read_token = orig_last_token;            /* XXX - was WORD? */
5857
5858   if (wl)
5859     {
5860       rl = REVERSE_LIST (wl, WORD_LIST *);
5861       ret = string_list (rl);
5862       dispose_words (rl);
5863     }
5864   else
5865     ret = (char *)NULL;
5866
5867   if (retlenp)
5868     *retlenp = (ret && *ret) ? strlen (ret) : 0;
5869
5870   if (assignok)
5871     parser_state |= PST_ASSIGNOK;
5872
5873   return ret;
5874 }
5875
5876 /************************************************
5877  *                                              *
5878  *   SAVING AND RESTORING PARTIAL PARSE STATE   *
5879  *                                              *
5880  ************************************************/
5881
5882 sh_parser_state_t *
5883 save_parser_state (ps)
5884      sh_parser_state_t *ps;
5885 {
5886   if (ps == 0)
5887     ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
5888   if (ps == 0)
5889     return ((sh_parser_state_t *)NULL);
5890
5891   ps->parser_state = parser_state;
5892   ps->token_state = save_token_state ();
5893
5894   ps->input_line_terminator = shell_input_line_terminator;
5895   ps->eof_encountered = eof_encountered;
5896
5897   ps->prompt_string_pointer = prompt_string_pointer;
5898
5899   ps->current_command_line_count = current_command_line_count;
5900
5901 #if defined (HISTORY)
5902   ps->remember_on_history = remember_on_history;
5903 #  if defined (BANG_HISTORY)
5904   ps->history_expansion_inhibited = history_expansion_inhibited;
5905 #  endif
5906 #endif
5907
5908   ps->last_command_exit_value = last_command_exit_value;
5909 #if defined (ARRAY_VARS)
5910   ps->pipestatus = save_pipestatus_array ();
5911 #endif
5912     
5913   ps->last_shell_builtin = last_shell_builtin;
5914   ps->this_shell_builtin = this_shell_builtin;
5915
5916   ps->expand_aliases = expand_aliases;
5917   ps->echo_input_at_read = echo_input_at_read;
5918
5919   ps->token = token;
5920   ps->token_buffer_size = token_buffer_size;
5921   /* Force reallocation on next call to read_token_word */
5922   token = 0;
5923   token_buffer_size = 0;
5924
5925   return (ps);
5926 }
5927
5928 void
5929 restore_parser_state (ps)
5930      sh_parser_state_t *ps;
5931 {
5932   if (ps == 0)
5933     return;
5934
5935   parser_state = ps->parser_state;
5936   if (ps->token_state)
5937     {
5938       restore_token_state (ps->token_state);
5939       free (ps->token_state);
5940     }
5941
5942   shell_input_line_terminator = ps->input_line_terminator;
5943   eof_encountered = ps->eof_encountered;
5944
5945   prompt_string_pointer = ps->prompt_string_pointer;
5946
5947   current_command_line_count = ps->current_command_line_count;
5948
5949 #if defined (HISTORY)
5950   remember_on_history = ps->remember_on_history;
5951 #  if defined (BANG_HISTORY)
5952   history_expansion_inhibited = ps->history_expansion_inhibited;
5953 #  endif
5954 #endif
5955
5956   last_command_exit_value = ps->last_command_exit_value;
5957 #if defined (ARRAY_VARS)
5958   restore_pipestatus_array (ps->pipestatus);
5959 #endif
5960
5961   last_shell_builtin = ps->last_shell_builtin;
5962   this_shell_builtin = ps->this_shell_builtin;
5963
5964   expand_aliases = ps->expand_aliases;
5965   echo_input_at_read = ps->echo_input_at_read;
5966
5967   FREE (token);
5968   token = ps->token;
5969   token_buffer_size = ps->token_buffer_size;
5970 }
5971
5972 sh_input_line_state_t *
5973 save_input_line_state (ls)
5974      sh_input_line_state_t *ls;
5975 {
5976   if (ls == 0)
5977     ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
5978   if (ls == 0)
5979     return ((sh_input_line_state_t *)NULL);
5980
5981   ls->input_line = shell_input_line;
5982   ls->input_line_size = shell_input_line_size;
5983   ls->input_line_len = shell_input_line_len;
5984   ls->input_line_index = shell_input_line_index;
5985
5986   /* force reallocation */
5987   shell_input_line = 0;
5988   shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
5989 }
5990
5991 void
5992 restore_input_line_state (ls)
5993      sh_input_line_state_t *ls;
5994 {
5995   FREE (shell_input_line);
5996   shell_input_line = ls->input_line;
5997   shell_input_line_size = ls->input_line_size;
5998   shell_input_line_len = ls->input_line_len;
5999   shell_input_line_index = ls->input_line_index;
6000
6001   set_line_mbstate ();
6002 }
6003
6004 /************************************************
6005  *                                              *
6006  *      MULTIBYTE CHARACTER HANDLING            *
6007  *                                              *
6008  ************************************************/
6009
6010 #if defined (HANDLE_MULTIBYTE)
6011 static void
6012 set_line_mbstate ()
6013 {
6014   int i, previ, len, c;
6015   mbstate_t mbs, prevs;
6016   size_t mbclen;
6017
6018   if (shell_input_line == NULL)
6019     return;
6020   len = strlen (shell_input_line);      /* XXX - shell_input_line_len ? */
6021   FREE (shell_input_line_property);
6022   shell_input_line_property = (char *)xmalloc (len + 1);
6023
6024   memset (&prevs, '\0', sizeof (mbstate_t));
6025   for (i = previ = 0; i < len; i++)
6026     {
6027       mbs = prevs;
6028
6029       c = shell_input_line[i];
6030       if (c == EOF)
6031         {
6032           int j;
6033           for (j = i; j < len; j++)
6034             shell_input_line_property[j] = 1;
6035           break;
6036         }
6037
6038       mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
6039       if (mbclen == 1 || mbclen == (size_t)-1)
6040         {
6041           mbclen = 1;
6042           previ = i + 1;
6043         }
6044       else if (mbclen == (size_t)-2)
6045         mbclen = 0;
6046       else if (mbclen > 1)
6047         {
6048           mbclen = 0;
6049           previ = i + 1;
6050           prevs = mbs;
6051         }
6052       else
6053         {
6054           /* XXX - what to do if mbrlen returns 0? (null wide character) */
6055           int j;
6056           for (j = i; j < len; j++)
6057             shell_input_line_property[j] = 1;
6058           break;
6059         }
6060
6061       shell_input_line_property[i] = mbclen;
6062     }
6063 }
6064 #endif /* HANDLE_MULTIBYTE */