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