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