Imported from ../bash-3.1.tar.gz.
[platform/upstream/bash.git] / parse.y
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 (sigwinch_received)
1877     {
1878       sigwinch_received = 0;
1879       get_new_window_size (0, (int *)0, (int *)0);
1880     }
1881       
1882   if (eol_ungetc_lookahead)
1883     {
1884       c = eol_ungetc_lookahead;
1885       eol_ungetc_lookahead = 0;
1886       return (c);
1887     }
1888
1889 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1890   /* If shell_input_line[shell_input_line_index] == 0, but there is
1891      something on the pushed list of strings, then we don't want to go
1892      off and get another line.  We let the code down below handle it. */
1893
1894   if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
1895                             (pushed_string_list == (STRING_SAVER *)NULL)))
1896 #else /* !ALIAS && !DPAREN_ARITHMETIC */
1897   if (!shell_input_line || !shell_input_line[shell_input_line_index])
1898 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
1899     {
1900       line_number++;
1901
1902     restart_read:
1903
1904       /* Allow immediate exit if interrupted during input. */
1905       QUIT;
1906
1907       i = 0;
1908       shell_input_line_terminator = 0;
1909
1910       /* If the shell is interatctive, but not currently printing a prompt
1911          (interactive_shell && interactive == 0), we don't want to print
1912          notifies or cleanup the jobs -- we want to defer it until we do
1913          print the next prompt. */
1914       if (interactive_shell == 0 || SHOULD_PROMPT())
1915         {
1916 #if defined (JOB_CONTROL)
1917       /* This can cause a problem when reading a command as the result
1918          of a trap, when the trap is called from flush_child.  This call
1919          had better not cause jobs to disappear from the job table in
1920          that case, or we will have big trouble. */
1921           notify_and_cleanup ();
1922 #else /* !JOB_CONTROL */
1923           cleanup_dead_jobs ();
1924 #endif /* !JOB_CONTROL */
1925         }
1926
1927 #if defined (READLINE)
1928       if (no_line_editing && SHOULD_PROMPT())
1929 #else
1930       if (SHOULD_PROMPT())
1931 #endif
1932         print_prompt ();
1933
1934       if (bash_input.type == st_stream)
1935         clearerr (stdin);
1936
1937       while (1)
1938         {
1939           c = yy_getc ();
1940
1941           /* Allow immediate exit if interrupted during input. */
1942           QUIT;
1943
1944           if (c == '\0')
1945             {
1946 #if 0
1947               internal_warning ("shell_getc: ignored null byte in input");
1948 #endif
1949               continue;
1950             }
1951
1952           RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
1953
1954           if (c == EOF)
1955             {
1956               if (bash_input.type == st_stream)
1957                 clearerr (stdin);
1958
1959               if (i == 0)
1960                 shell_input_line_terminator = EOF;
1961
1962               shell_input_line[i] = '\0';
1963               break;
1964             }
1965
1966           shell_input_line[i++] = c;
1967
1968           if (c == '\n')
1969             {
1970               shell_input_line[--i] = '\0';
1971               current_command_line_count++;
1972               break;
1973             }
1974         }
1975
1976       shell_input_line_index = 0;
1977       shell_input_line_len = i;         /* == strlen (shell_input_line) */
1978
1979       set_line_mbstate ();
1980
1981 #if defined (HISTORY)
1982       if (remember_on_history && shell_input_line && shell_input_line[0])
1983         {
1984           char *expansions;
1985 #  if defined (BANG_HISTORY)
1986           int old_hist;
1987
1988           /* If the current delimiter is a single quote, we should not be
1989              performing history expansion, even if we're on a different
1990              line from the original single quote. */
1991           old_hist = history_expansion_inhibited;
1992           if (current_delimiter (dstack) == '\'')
1993             history_expansion_inhibited = 1;
1994 #  endif
1995           expansions = pre_process_line (shell_input_line, 1, 1);
1996 #  if defined (BANG_HISTORY)
1997           history_expansion_inhibited = old_hist;
1998 #  endif
1999           if (expansions != shell_input_line)
2000             {
2001               free (shell_input_line);
2002               shell_input_line = expansions;
2003               shell_input_line_len = shell_input_line ?
2004                                         strlen (shell_input_line) : 0;
2005               if (!shell_input_line_len)
2006                 current_command_line_count--;
2007
2008               /* We have to force the xrealloc below because we don't know
2009                  the true allocated size of shell_input_line anymore. */
2010               shell_input_line_size = shell_input_line_len;
2011
2012               set_line_mbstate ();
2013             }
2014         }
2015       /* Try to do something intelligent with blank lines encountered while
2016          entering multi-line commands.  XXX - this is grotesque */
2017       else if (remember_on_history && shell_input_line &&
2018                shell_input_line[0] == '\0' &&
2019                current_command_line_count > 1)
2020         {
2021           if (current_delimiter (dstack))
2022             /* We know shell_input_line[0] == 0 and we're reading some sort of
2023                quoted string.  This means we've got a line consisting of only
2024                a newline in a quoted string.  We want to make sure this line
2025                gets added to the history. */
2026             maybe_add_history (shell_input_line);
2027           else
2028             {
2029               char *hdcs;
2030               hdcs = history_delimiting_chars ();
2031               if (hdcs && hdcs[0] == ';')
2032                 maybe_add_history (shell_input_line);
2033             }
2034         }
2035
2036 #endif /* HISTORY */
2037
2038       if (shell_input_line)
2039         {
2040           /* Lines that signify the end of the shell's input should not be
2041              echoed. */
2042           if (echo_input_at_read && (shell_input_line[0] ||
2043                                      shell_input_line_terminator != EOF))
2044             fprintf (stderr, "%s\n", shell_input_line);
2045         }
2046       else
2047         {
2048           shell_input_line_size = 0;
2049           prompt_string_pointer = &current_prompt_string;
2050           if (SHOULD_PROMPT ())
2051             prompt_again ();
2052           goto restart_read;
2053         }
2054
2055       /* Add the newline to the end of this string, iff the string does
2056          not already end in an EOF character.  */
2057       if (shell_input_line_terminator != EOF)
2058         {
2059           if (shell_input_line_len + 3 > shell_input_line_size)
2060             shell_input_line = (char *)xrealloc (shell_input_line,
2061                                         1 + (shell_input_line_size += 2));
2062
2063           shell_input_line[shell_input_line_len] = '\n';
2064           shell_input_line[shell_input_line_len + 1] = '\0';
2065
2066           set_line_mbstate ();
2067         }
2068     }
2069
2070   uc = shell_input_line[shell_input_line_index];
2071
2072   if (uc)
2073     shell_input_line_index++;
2074
2075 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2076   /* If UC is NULL, we have reached the end of the current input string.  If
2077      pushed_string_list is non-empty, it's time to pop to the previous string
2078      because we have fully consumed the result of the last alias expansion.
2079      Do it transparently; just return the next character of the string popped
2080      to. */
2081   if (!uc && (pushed_string_list != (STRING_SAVER *)NULL))
2082     {
2083       pop_string ();
2084       uc = shell_input_line[shell_input_line_index];
2085       if (uc)
2086         shell_input_line_index++;
2087     }
2088 #endif /* ALIAS || DPAREN_ARITHMETIC */
2089
2090   if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
2091     {
2092         if (SHOULD_PROMPT ())
2093           prompt_again ();
2094         line_number++;
2095         goto restart_read;
2096     }
2097
2098   if (!uc && shell_input_line_terminator == EOF)
2099     return ((shell_input_line_index != 0) ? '\n' : EOF);
2100
2101   return (uc);
2102 }
2103
2104 /* Put C back into the input for the shell.  This might need changes for
2105    HANDLE_MULTIBYTE around EOLs.  Since we (currently) never push back a
2106    character different than we read, shell_input_line_property doesn't need
2107    to change when manipulating shell_input_line.  The define for
2108    last_shell_getc_is_singlebyte should take care of it, though. */
2109 static void
2110 shell_ungetc (c)
2111      int c;
2112 {
2113   if (shell_input_line && shell_input_line_index)
2114     shell_input_line[--shell_input_line_index] = c;
2115   else
2116     eol_ungetc_lookahead = c;
2117 }
2118
2119 #ifdef INCLUDE_UNUSED
2120 /* Back the input pointer up by one, effectively `ungetting' a character. */
2121 static void
2122 shell_ungetchar ()
2123 {
2124   if (shell_input_line && shell_input_line_index)
2125     shell_input_line_index--;
2126 }
2127 #endif
2128
2129 /* Discard input until CHARACTER is seen, then push that character back
2130    onto the input stream. */
2131 static void
2132 discard_until (character)
2133      int character;
2134 {
2135   int c;
2136
2137   while ((c = shell_getc (0)) != EOF && c != character)
2138     ;
2139
2140   if (c != EOF)
2141     shell_ungetc (c);
2142 }
2143
2144 void
2145 execute_prompt_command (command)
2146      char *command;
2147 {
2148   char *last_lastarg;
2149   sh_parser_state_t ps;
2150
2151   save_parser_state (&ps);
2152   last_lastarg = get_string_value ("_");
2153   if (last_lastarg)
2154     last_lastarg = savestring (last_lastarg);
2155
2156   parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
2157
2158   restore_parser_state (&ps);
2159   bind_variable ("_", last_lastarg, 0);
2160   FREE (last_lastarg);
2161
2162   if (token_to_read == '\n')    /* reset_parser was called */
2163     token_to_read = 0;
2164 }
2165
2166 /* Place to remember the token.  We try to keep the buffer
2167    at a reasonable size, but it can grow. */
2168 static char *token = (char *)NULL;
2169
2170 /* Current size of the token buffer. */
2171 static int token_buffer_size;
2172
2173 /* Command to read_token () explaining what we want it to do. */
2174 #define READ 0
2175 #define RESET 1
2176 #define prompt_is_ps1 \
2177       (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2178
2179 /* Function for yyparse to call.  yylex keeps track of
2180    the last two tokens read, and calls read_token.  */
2181 static int
2182 yylex ()
2183 {
2184   if (interactive && (current_token == 0 || current_token == '\n'))
2185     {
2186       /* Before we print a prompt, we might have to check mailboxes.
2187          We do this only if it is time to do so. Notice that only here
2188          is the mail alarm reset; nothing takes place in check_mail ()
2189          except the checking of mail.  Please don't change this. */
2190       if (prompt_is_ps1 && time_to_check_mail ())
2191         {
2192           check_mail ();
2193           reset_mail_timer ();
2194         }
2195
2196       /* Avoid printing a prompt if we're not going to read anything, e.g.
2197          after resetting the parser with read_token (RESET). */
2198       if (token_to_read == 0 && SHOULD_PROMPT ())
2199         prompt_again ();
2200     }
2201
2202   two_tokens_ago = token_before_that;
2203   token_before_that = last_read_token;
2204   last_read_token = current_token;
2205   current_token = read_token (READ);
2206   return (current_token);
2207 }
2208
2209 /* When non-zero, we have read the required tokens
2210    which allow ESAC to be the next one read. */
2211 static int esacs_needed_count;
2212
2213 void
2214 gather_here_documents ()
2215 {
2216   int r = 0;
2217   while (need_here_doc)
2218     {
2219       make_here_document (redir_stack[r++]);
2220       need_here_doc--;
2221     }
2222 }
2223
2224 /* When non-zero, an open-brace used to create a group is awaiting a close
2225    brace partner. */
2226 static int open_brace_count;
2227
2228 #define command_token_position(token) \
2229   (((token) == ASSIGNMENT_WORD) || \
2230    ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
2231
2232 #define assignment_acceptable(token) \
2233   (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
2234
2235 /* Check to see if TOKEN is a reserved word and return the token
2236    value if it is. */
2237 #define CHECK_FOR_RESERVED_WORD(tok) \
2238   do { \
2239     if (!dollar_present && !quoted && \
2240         reserved_word_acceptable (last_read_token)) \
2241       { \
2242         int i; \
2243         for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2244           if (STREQ (tok, word_token_alist[i].word)) \
2245             { \
2246               if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2247                 break; \
2248               if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
2249                 break; \
2250               if (word_token_alist[i].token == ESAC) \
2251                 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2252               else if (word_token_alist[i].token == CASE) \
2253                 parser_state |= PST_CASESTMT; \
2254               else if (word_token_alist[i].token == COND_END) \
2255                 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2256               else if (word_token_alist[i].token == COND_START) \
2257                 parser_state |= PST_CONDCMD; \
2258               else if (word_token_alist[i].token == '{') \
2259                 open_brace_count++; \
2260               else if (word_token_alist[i].token == '}' && open_brace_count) \
2261                 open_brace_count--; \
2262               return (word_token_alist[i].token); \
2263             } \
2264       } \
2265   } while (0)
2266
2267 #if defined (ALIAS)
2268
2269     /* OK, we have a token.  Let's try to alias expand it, if (and only if)
2270        it's eligible.
2271
2272        It is eligible for expansion if EXPAND_ALIASES is set, and
2273        the token is unquoted and the last token read was a command
2274        separator (or expand_next_token is set), and we are currently
2275        processing an alias (pushed_string_list is non-empty) and this
2276        token is not the same as the current or any previously
2277        processed alias.
2278
2279        Special cases that disqualify:
2280          In a pattern list in a case statement (parser_state & PST_CASEPAT). */
2281
2282 static char *
2283 mk_alexpansion (s)
2284      char *s;
2285 {
2286   int l;
2287   char *r;
2288
2289   l = strlen (s);
2290   r = xmalloc (l + 2);
2291   strcpy (r, s);
2292   if (r[l -1] != ' ')
2293     r[l++] = ' ';
2294   r[l] = '\0';
2295   return r;
2296 }
2297
2298 static int
2299 alias_expand_token (tokstr)
2300      char *tokstr;
2301 {
2302   char *expanded;
2303   alias_t *ap;
2304
2305   if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2306         (parser_state & PST_CASEPAT) == 0)
2307     {
2308       ap = find_alias (tokstr);
2309
2310       /* Currently expanding this token. */
2311       if (ap && (ap->flags & AL_BEINGEXPANDED))
2312         return (NO_EXPANSION);
2313
2314       /* mk_alexpansion puts an extra space on the end of the alias expansion,
2315          so the lookahead by the parser works right.  If this gets changed,
2316          make sure the code in shell_getc that deals with reaching the end of
2317          an expanded alias is changed with it. */
2318       expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2319
2320       if (expanded)
2321         {
2322           push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2323           return (RE_READ_TOKEN);
2324         }
2325       else
2326         /* This is an eligible token that does not have an expansion. */
2327         return (NO_EXPANSION);
2328     }
2329   return (NO_EXPANSION);
2330 }
2331 #endif /* ALIAS */
2332
2333 static int
2334 time_command_acceptable ()
2335 {
2336 #if defined (COMMAND_TIMING)
2337   switch (last_read_token)
2338     {
2339     case 0:
2340     case ';':
2341     case '\n':
2342     case AND_AND:
2343     case OR_OR:
2344     case '&':
2345     case DO:
2346     case THEN:
2347     case ELSE:
2348     case '{':           /* } */
2349     case '(':           /* ) */
2350       return 1;
2351     default:
2352       return 0;
2353     }
2354 #else
2355   return 0;
2356 #endif /* COMMAND_TIMING */
2357 }
2358
2359 /* Handle special cases of token recognition:
2360         IN is recognized if the last token was WORD and the token
2361         before that was FOR or CASE or SELECT.
2362
2363         DO is recognized if the last token was WORD and the token
2364         before that was FOR or SELECT.
2365
2366         ESAC is recognized if the last token caused `esacs_needed_count'
2367         to be set
2368
2369         `{' is recognized if the last token as WORD and the token
2370         before that was FUNCTION, or if we just parsed an arithmetic
2371         `for' command.
2372
2373         `}' is recognized if there is an unclosed `{' present.
2374
2375         `-p' is returned as TIMEOPT if the last read token was TIME.
2376
2377         ']]' is returned as COND_END if the parser is currently parsing
2378         a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2379
2380         `time' is returned as TIME if and only if it is immediately
2381         preceded by one of `;', `\n', `||', `&&', or `&'.
2382 */
2383
2384 static int
2385 special_case_tokens (tokstr)
2386      char *tokstr;
2387 {
2388   if ((last_read_token == WORD) &&
2389 #if defined (SELECT_COMMAND)
2390       ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2391 #else
2392       ((token_before_that == FOR) || (token_before_that == CASE)) &&
2393 #endif
2394       (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
2395     {
2396       if (token_before_that == CASE)
2397         {
2398           parser_state |= PST_CASEPAT;
2399           esacs_needed_count++;
2400         }
2401       return (IN);
2402     }
2403
2404   if (last_read_token == WORD &&
2405 #if defined (SELECT_COMMAND)
2406       (token_before_that == FOR || token_before_that == SELECT) &&
2407 #else
2408       (token_before_that == FOR) &&
2409 #endif
2410       (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
2411     return (DO);
2412
2413   /* Ditto for ESAC in the CASE case.
2414      Specifically, this handles "case word in esac", which is a legal
2415      construct, certainly because someone will pass an empty arg to the
2416      case construct, and we don't want it to barf.  Of course, we should
2417      insist that the case construct has at least one pattern in it, but
2418      the designers disagree. */
2419   if (esacs_needed_count)
2420     {
2421       esacs_needed_count--;
2422       if (STREQ (tokstr, "esac"))
2423         {
2424           parser_state &= ~PST_CASEPAT;
2425           return (ESAC);
2426         }
2427     }
2428
2429   /* The start of a shell function definition. */
2430   if (parser_state & PST_ALLOWOPNBRC)
2431     {
2432       parser_state &= ~PST_ALLOWOPNBRC;
2433       if (tokstr[0] == '{' && tokstr[1] == '\0')                /* } */
2434         {
2435           open_brace_count++;
2436           function_bstart = line_number;
2437           return ('{');                                 /* } */
2438         }
2439     }
2440
2441   /* We allow a `do' after a for ((...)) without an intervening
2442      list_terminator */
2443   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
2444     return (DO);
2445   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0')      /* } */
2446     {
2447       open_brace_count++;
2448       return ('{');                     /* } */
2449     }
2450
2451   if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
2452     {
2453       open_brace_count--;               /* { */
2454       return ('}');
2455     }
2456
2457 #if defined (COMMAND_TIMING)
2458   /* Handle -p after `time'. */
2459   if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
2460     return (TIMEOPT);
2461 #endif
2462
2463 #if 0
2464 #if defined (COMMAND_TIMING)
2465   if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
2466     return (TIME);
2467 #endif /* COMMAND_TIMING */
2468 #endif
2469
2470 #if defined (COND_COMMAND) /* [[ */
2471   if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
2472     return (COND_END);
2473 #endif
2474
2475   return (-1);
2476 }
2477
2478 /* Called from shell.c when Control-C is typed at top level.  Or
2479    by the error rule at top level. */
2480 void
2481 reset_parser ()
2482 {
2483   dstack.delimiter_depth = 0;   /* No delimiters found so far. */
2484   open_brace_count = 0;
2485
2486   parser_state = 0;
2487
2488 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2489   if (pushed_string_list)
2490     free_string_list ();
2491 #endif /* ALIAS || DPAREN_ARITHMETIC */
2492
2493   if (shell_input_line)
2494     {
2495       free (shell_input_line);
2496       shell_input_line = (char *)NULL;
2497       shell_input_line_size = shell_input_line_index = 0;
2498     }
2499
2500   FREE (word_desc_to_read);
2501   word_desc_to_read = (WORD_DESC *)NULL;
2502
2503   last_read_token = '\n';
2504   token_to_read = '\n';
2505 }
2506
2507 /* Read the next token.  Command can be READ (normal operation) or
2508    RESET (to normalize state). */
2509 static int
2510 read_token (command)
2511      int command;
2512 {
2513   int character;                /* Current character. */
2514   int peek_char;                /* Temporary look-ahead character. */
2515   int result;                   /* The thing to return. */
2516
2517   if (command == RESET)
2518     {
2519       reset_parser ();
2520       return ('\n');
2521     }
2522
2523   if (token_to_read)
2524     {
2525       result = token_to_read;
2526       if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
2527         {
2528           yylval.word = word_desc_to_read;
2529           word_desc_to_read = (WORD_DESC *)NULL;
2530         }
2531       token_to_read = 0;
2532       return (result);
2533     }
2534
2535 #if defined (COND_COMMAND)
2536   if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2537     {
2538       cond_lineno = line_number;
2539       parser_state |= PST_CONDEXPR;
2540       yylval.command = parse_cond_command ();
2541       if (cond_token != COND_END)
2542         {
2543           cond_error ();
2544           return (-1);
2545         }
2546       token_to_read = COND_END;
2547       parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2548       return (COND_CMD);
2549     }
2550 #endif
2551
2552 #if defined (ALIAS)
2553   /* This is a place to jump back to once we have successfully expanded a
2554      token with an alias and pushed the string with push_string () */
2555  re_read_token:
2556 #endif /* ALIAS */
2557
2558   /* Read a single word from input.  Start by skipping blanks. */
2559   while ((character = shell_getc (1)) != EOF && whitespace (character))
2560     ;
2561
2562   if (character == EOF)
2563     {
2564       EOF_Reached = 1;
2565       return (yacc_EOF);
2566     }
2567
2568   if MBTEST(character == '#' && (!interactive || interactive_comments))
2569     {
2570       /* A comment.  Discard until EOL or EOF, and then return a newline. */
2571       discard_until ('\n');
2572       shell_getc (0);
2573       character = '\n'; /* this will take the next if statement and return. */
2574     }
2575
2576   if (character == '\n')
2577     {
2578       /* If we're about to return an unquoted newline, we can go and collect
2579          the text of any pending here document. */
2580       if (need_here_doc)
2581         gather_here_documents ();
2582
2583 #if defined (ALIAS)
2584       parser_state &= ~PST_ALEXPNEXT;
2585 #endif /* ALIAS */
2586
2587       parser_state &= ~PST_ASSIGNOK;
2588
2589       return (character);
2590     }
2591
2592   /* Shell meta-characters. */
2593   if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
2594     {
2595 #if defined (ALIAS)
2596       /* Turn off alias tokenization iff this character sequence would
2597          not leave us ready to read a command. */
2598       if (character == '<' || character == '>')
2599         parser_state &= ~PST_ALEXPNEXT;
2600 #endif /* ALIAS */
2601
2602       parser_state &= ~PST_ASSIGNOK;
2603
2604       peek_char = shell_getc (1);
2605       if (character == peek_char)
2606         {
2607           switch (character)
2608             {
2609             case '<':
2610               /* If '<' then we could be at "<<" or at "<<-".  We have to
2611                  look ahead one more character. */
2612               peek_char = shell_getc (1);
2613               if (peek_char == '-')
2614                 return (LESS_LESS_MINUS);
2615               else if (peek_char == '<')
2616                 return (LESS_LESS_LESS);
2617               else
2618                 {
2619                   shell_ungetc (peek_char);
2620                   return (LESS_LESS);
2621                 }
2622
2623             case '>':
2624               return (GREATER_GREATER);
2625
2626             case ';':
2627               parser_state |= PST_CASEPAT;
2628 #if defined (ALIAS)
2629               parser_state &= ~PST_ALEXPNEXT;
2630 #endif /* ALIAS */
2631
2632               return (SEMI_SEMI);
2633
2634             case '&':
2635               return (AND_AND);
2636
2637             case '|':
2638               return (OR_OR);
2639
2640 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
2641             case '(':           /* ) */
2642               result = parse_dparen (character);
2643               if (result == -2)
2644                 break;
2645               else
2646                 return result;
2647 #endif
2648             }
2649         }
2650       else if MBTEST(character == '<' && peek_char == '&')
2651         return (LESS_AND);
2652       else if MBTEST(character == '>' && peek_char == '&')
2653         return (GREATER_AND);
2654       else if MBTEST(character == '<' && peek_char == '>')
2655         return (LESS_GREATER);
2656       else if MBTEST(character == '>' && peek_char == '|')
2657         return (GREATER_BAR);
2658       else if MBTEST(peek_char == '>' && character == '&')
2659         return (AND_GREATER);
2660
2661       shell_ungetc (peek_char);
2662
2663       /* If we look like we are reading the start of a function
2664          definition, then let the reader know about it so that
2665          we will do the right thing with `{'. */
2666       if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
2667         {
2668           parser_state |= PST_ALLOWOPNBRC;
2669 #if defined (ALIAS)
2670           parser_state &= ~PST_ALEXPNEXT;
2671 #endif /* ALIAS */
2672           function_dstart = line_number;
2673         }
2674
2675       /* case pattern lists may be preceded by an optional left paren.  If
2676          we're not trying to parse a case pattern list, the left paren
2677          indicates a subshell. */
2678       if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
2679         parser_state |= PST_SUBSHELL;
2680       /*(*/
2681       else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
2682         parser_state &= ~PST_CASEPAT;
2683       /*(*/
2684       else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
2685         parser_state &= ~PST_SUBSHELL;
2686
2687 #if defined (PROCESS_SUBSTITUTION)
2688       /* Check for the constructs which introduce process substitution.
2689          Shells running in `posix mode' don't do process substitution. */
2690       if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
2691 #endif /* PROCESS_SUBSTITUTION */
2692         return (character);
2693     }
2694
2695   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */
2696   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
2697     return (character);
2698
2699   /* Okay, if we got this far, we have to read a word.  Read one,
2700      and then check it against the known ones. */
2701   result = read_token_word (character);
2702 #if defined (ALIAS)
2703   if (result == RE_READ_TOKEN)
2704     goto re_read_token;
2705 #endif
2706   return result;
2707 }
2708
2709 /*
2710  * Match a $(...) or other grouping construct.  This has to handle embedded
2711  * quoted strings ('', ``, "") and nested constructs.  It also must handle
2712  * reprompting the user, if necessary, after reading a newline, and returning
2713  * correct error values if it reads EOF.
2714  */
2715 #define P_FIRSTCLOSE    0x01
2716 #define P_ALLOWESC      0x02
2717 #define P_DQUOTE        0x04
2718 #define P_COMMAND       0x08    /* parsing a command, so look for comments */
2719
2720 static char matched_pair_error;
2721 static char *
2722 parse_matched_pair (qc, open, close, lenp, flags)
2723      int qc;    /* `"' if this construct is within double quotes */
2724      int open, close;
2725      int *lenp, flags;
2726 {
2727   int count, ch, was_dollar, in_comment, check_comment;
2728   int pass_next_character, nestlen, ttranslen, start_lineno;
2729   char *ret, *nestret, *ttrans;
2730   int retind, retsize, rflags;
2731
2732   count = 1;
2733   pass_next_character = was_dollar = in_comment = 0;
2734   check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
2735
2736   /* RFLAGS is the set of flags we want to pass to recursive calls. */
2737   rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
2738
2739   ret = (char *)xmalloc (retsize = 64);
2740   retind = 0;
2741
2742   start_lineno = line_number;
2743   while (count)
2744     {
2745 #if 0
2746       ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
2747 #else
2748       ch = shell_getc (qc != '\'' && pass_next_character == 0);
2749 #endif
2750       if (ch == EOF)
2751         {
2752           free (ret);
2753           parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
2754           EOF_Reached = 1;      /* XXX */
2755           return (&matched_pair_error);
2756         }
2757
2758       /* Possible reprompting. */
2759       if (ch == '\n' && SHOULD_PROMPT ())
2760         prompt_again ();
2761
2762       if (in_comment)
2763         {
2764           /* Add this character. */
2765           RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2766           ret[retind++] = ch;
2767
2768           if (ch == '\n')
2769             in_comment = 0;
2770
2771           continue;
2772         }
2773       /* Not exactly right yet */
2774       else if (check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind -1])))
2775         in_comment = 1;
2776
2777       if (pass_next_character)          /* last char was backslash */
2778         {
2779           pass_next_character = 0;
2780           if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
2781             {
2782               if (retind > 0) retind--; /* swallow previously-added backslash */
2783               continue;
2784             }
2785
2786           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2787           if MBTEST(ch == CTLESC || ch == CTLNUL)
2788             ret[retind++] = CTLESC;
2789           ret[retind++] = ch;
2790           continue;
2791         }
2792       else if MBTEST(ch == CTLESC || ch == CTLNUL)      /* special shell escapes */
2793         {
2794           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2795           ret[retind++] = CTLESC;
2796           ret[retind++] = ch;
2797           continue;
2798         }
2799       else if MBTEST(ch == close)               /* ending delimiter */
2800         count--;
2801 #if 1
2802       /* handle nested ${...} specially. */
2803       else if MBTEST(open != close && was_dollar && open == '{' && ch == open) /* } */
2804         count++;
2805 #endif
2806       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open)       /* nested begin */
2807         count++;
2808
2809       /* Add this character. */
2810       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2811       ret[retind++] = ch;
2812
2813       if (open == '\'')                 /* '' inside grouping construct */
2814         {
2815           if MBTEST((flags & P_ALLOWESC) && ch == '\\')
2816             pass_next_character++;
2817           continue;
2818         }
2819
2820       if MBTEST(ch == '\\')                     /* backslashes */
2821         pass_next_character++;
2822
2823       if (open != close)                /* a grouping construct */
2824         {
2825           if MBTEST(shellquote (ch))
2826             {
2827               /* '', ``, or "" inside $(...) or other grouping construct. */
2828               push_delimiter (dstack, ch);
2829               if MBTEST(was_dollar && ch == '\'')       /* $'...' inside group */
2830                 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
2831               else
2832                 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
2833               pop_delimiter (dstack);
2834               if (nestret == &matched_pair_error)
2835                 {
2836                   free (ret);
2837                   return &matched_pair_error;
2838                 }
2839               if MBTEST(was_dollar && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
2840                 {
2841                   /* Translate $'...' here. */
2842                   ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
2843                   xfree (nestret);
2844
2845                   if ((rflags & P_DQUOTE) == 0)
2846                     {
2847                       nestret = sh_single_quote (ttrans);
2848                       free (ttrans);
2849                       nestlen = strlen (nestret);
2850                     }
2851                   else
2852                     {
2853                       nestret = ttrans;
2854                       nestlen = ttranslen;
2855                     }
2856                   retind -= 2;          /* back up before the $' */
2857                 }
2858               else if MBTEST(was_dollar && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
2859                 {
2860                   /* Locale expand $"..." here. */
2861                   ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
2862                   xfree (nestret);
2863
2864                   nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
2865                   free (ttrans);
2866                   nestlen = ttranslen + 2;
2867                   retind -= 2;          /* back up before the $" */
2868                 }
2869
2870               if (nestlen)
2871                 {
2872                   RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2873                   strcpy (ret + retind, nestret);
2874                   retind += nestlen;
2875                 }
2876               FREE (nestret);
2877             }
2878         }
2879       /* Parse an old-style command substitution within double quotes as a
2880          single word. */
2881       /* XXX - sh and ksh93 don't do this - XXX */
2882       else if MBTEST(open == '"' && ch == '`')
2883         {
2884           nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
2885 add_nestret:
2886           if (nestret == &matched_pair_error)
2887             {
2888               free (ret);
2889               return &matched_pair_error;
2890             }
2891           if (nestlen)
2892             {
2893               RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2894               strcpy (ret + retind, nestret);
2895               retind += nestlen;
2896             }
2897           FREE (nestret);
2898         }
2899       else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
2900         {
2901           nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags);
2902           goto add_nestret;
2903         }
2904       else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '['))       /* ) } ] */
2905         /* check for $(), $[], or ${} inside quoted string. */
2906         {
2907           if (open == ch)       /* undo previous increment */
2908             count--;
2909           if (ch == '(')                /* ) */
2910             nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags);
2911           else if (ch == '{')           /* } */
2912             nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
2913           else if (ch == '[')           /* ] */
2914             nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
2915
2916           goto add_nestret;
2917         }
2918       was_dollar = MBTEST(ch == '$');
2919     }
2920
2921   ret[retind] = '\0';
2922   if (lenp)
2923     *lenp = retind;
2924   return ret;
2925 }
2926
2927 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
2928 /* Parse a double-paren construct.  It can be either an arithmetic
2929    command, an arithmetic `for' command, or a nested subshell.  Returns
2930    the parsed token, -1 on error, or -2 if we didn't do anything and
2931    should just go on. */
2932 static int
2933 parse_dparen (c)
2934      int c;
2935 {
2936   int cmdtyp, len, sline;
2937   char *wval, *wv2;
2938   WORD_DESC *wd;
2939
2940 #if defined (ARITH_FOR_COMMAND)
2941   if (last_read_token == FOR)
2942     {
2943       arith_for_lineno = line_number;
2944       cmdtyp = parse_arith_cmd (&wval, 0);
2945       if (cmdtyp == 1)
2946         {
2947           wd = alloc_word_desc ();
2948           wd->word = wval;
2949           wd = make_word (wval);
2950           yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2951           return (ARITH_FOR_EXPRS);
2952         }
2953       else
2954         return -1;              /* ERROR */
2955     }
2956 #endif
2957
2958 #if defined (DPAREN_ARITHMETIC)
2959   if (reserved_word_acceptable (last_read_token))
2960     {
2961       sline = line_number;
2962
2963       cmdtyp = parse_arith_cmd (&wval, 0);
2964       if (cmdtyp == 1)  /* arithmetic command */
2965         {
2966           wd = alloc_word_desc ();
2967           wd->word = wval;
2968           wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
2969           yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2970           return (ARITH_CMD);
2971         }
2972       else if (cmdtyp == 0)     /* nested subshell */
2973         {
2974           push_string (wval, 0, (alias_t *)NULL);
2975           if ((parser_state & PST_CASEPAT) == 0)
2976             parser_state |= PST_SUBSHELL;
2977           return (c);
2978         }
2979       else                      /* ERROR */
2980         return -1;
2981     }
2982 #endif
2983
2984   return -2;                    /* XXX */
2985 }
2986
2987 /* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
2988    If not, assume it's a nested subshell for backwards compatibility and
2989    return 0.  In any case, put the characters we've consumed into a locally-
2990    allocated buffer and make *ep point to that buffer.  Return -1 on an
2991    error, for example EOF. */
2992 static int
2993 parse_arith_cmd (ep, adddq)
2994      char **ep;
2995      int adddq;
2996 {
2997   int exp_lineno, rval, c;
2998   char *ttok, *tokstr;
2999   int ttoklen;
3000
3001   exp_lineno = line_number;
3002   ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3003   rval = 1;
3004   if (ttok == &matched_pair_error)
3005     return -1;
3006   /* Check that the next character is the closing right paren.  If
3007      not, this is a syntax error. ( */
3008   c = shell_getc (0);
3009   if MBTEST(c != ')')
3010     rval = 0;
3011
3012   tokstr = (char *)xmalloc (ttoklen + 4);
3013
3014   /* if ADDDQ != 0 then (( ... )) -> "..." */
3015   if (rval == 1 && adddq)       /* arith cmd, add double quotes */
3016     {
3017       tokstr[0] = '"';
3018       strncpy (tokstr + 1, ttok, ttoklen - 1);
3019       tokstr[ttoklen] = '"';
3020       tokstr[ttoklen+1] = '\0';
3021     }
3022   else if (rval == 1)           /* arith cmd, don't add double quotes */
3023     {
3024       strncpy (tokstr, ttok, ttoklen - 1);
3025       tokstr[ttoklen-1] = '\0';
3026     }
3027   else                          /* nested subshell */
3028     {
3029       tokstr[0] = '(';
3030       strncpy (tokstr + 1, ttok, ttoklen - 1);
3031       tokstr[ttoklen] = ')';
3032       tokstr[ttoklen+1] = c;
3033       tokstr[ttoklen+2] = '\0';
3034     }
3035
3036   *ep = tokstr;
3037   FREE (ttok);
3038   return rval;
3039 }
3040 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
3041
3042 #if defined (COND_COMMAND)
3043 static void
3044 cond_error ()
3045 {
3046   char *etext;
3047
3048   if (EOF_Reached && cond_token != COND_ERROR)          /* [[ */
3049     parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
3050   else if (cond_token != COND_ERROR)
3051     {
3052       if (etext = error_token_from_token (cond_token))
3053         {
3054           parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
3055           free (etext);
3056         }
3057       else
3058         parser_error (cond_lineno, _("syntax error in conditional expression"));
3059     }
3060 }
3061
3062 static COND_COM *
3063 cond_expr ()
3064 {
3065   return (cond_or ());  
3066 }
3067
3068 static COND_COM *
3069 cond_or ()
3070 {
3071   COND_COM *l, *r;
3072
3073   l = cond_and ();
3074   if (cond_token == OR_OR)
3075     {
3076       r = cond_or ();
3077       l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3078     }
3079   return l;
3080 }
3081
3082 static COND_COM *
3083 cond_and ()
3084 {
3085   COND_COM *l, *r;
3086
3087   l = cond_term ();
3088   if (cond_token == AND_AND)
3089     {
3090       r = cond_and ();
3091       l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3092     }
3093   return l;
3094 }
3095
3096 static int
3097 cond_skip_newlines ()
3098 {
3099   while ((cond_token = read_token (READ)) == '\n')
3100     {
3101       if (SHOULD_PROMPT ())
3102         prompt_again ();
3103     }
3104   return (cond_token);
3105 }
3106
3107 #define COND_RETURN_ERROR() \
3108   do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3109
3110 static COND_COM *
3111 cond_term ()
3112 {
3113   WORD_DESC *op;
3114   COND_COM *term, *tleft, *tright;
3115   int tok, lineno;
3116   char *etext;
3117
3118   /* Read a token.  It can be a left paren, a `!', a unary operator, or a
3119      word that should be the first argument of a binary operator.  Start by
3120      skipping newlines, since this is a compound command. */
3121   tok = cond_skip_newlines ();
3122   lineno = line_number;
3123   if (tok == COND_END)
3124     {
3125       COND_RETURN_ERROR ();
3126     }
3127   else if (tok == '(')
3128     {
3129       term = cond_expr ();
3130       if (cond_token != ')')
3131         {
3132           if (term)
3133             dispose_cond_node (term);           /* ( */
3134           if (etext = error_token_from_token (cond_token))
3135             {
3136               parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
3137               free (etext);
3138             }
3139           else
3140             parser_error (lineno, _("expected `)'"));
3141           COND_RETURN_ERROR ();
3142         }
3143       term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3144       (void)cond_skip_newlines ();
3145     }
3146   else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3147     {
3148       if (tok == WORD)
3149         dispose_word (yylval.word);     /* not needed */
3150       term = cond_term ();
3151       if (term)
3152         term->flags |= CMD_INVERT_RETURN;
3153     }
3154   else if (tok == WORD && test_unop (yylval.word->word))
3155     {
3156       op = yylval.word;
3157       tok = read_token (READ);
3158       if (tok == WORD)
3159         {
3160           tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3161           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3162         }
3163       else
3164         {
3165           dispose_word (op);
3166           if (etext = error_token_from_token (tok))
3167             {
3168               parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
3169               free (etext);
3170             }
3171           else
3172             parser_error (line_number, _("unexpected argument to conditional unary operator"));
3173           COND_RETURN_ERROR ();
3174         }
3175
3176       (void)cond_skip_newlines ();
3177     }
3178   else if (tok == WORD)         /* left argument to binary operator */
3179     {
3180       /* lhs */
3181       tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3182
3183       /* binop */
3184       tok = read_token (READ);
3185       if (tok == WORD && test_binop (yylval.word->word))
3186         op = yylval.word;
3187 #if defined (COND_REGEXP)
3188       else if (tok == WORD && STREQ (yylval.word->word,"=~"))
3189         op = yylval.word;
3190 #endif
3191       else if (tok == '<' || tok == '>')
3192         op = make_word_from_token (tok);  /* ( */
3193       /* There should be a check before blindly accepting the `)' that we have
3194          seen the opening `('. */
3195       else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
3196         {
3197           /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
3198              the test command.  Similarly for [[ x && expr ]] or
3199              [[ x || expr ]] or [[ (x) ]]. */
3200           op = make_word ("-n");
3201           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3202           cond_token = tok;
3203           return (term);
3204         }
3205       else
3206         {
3207           if (etext = error_token_from_token (tok))
3208             {
3209               parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
3210               free (etext);
3211             }
3212           else
3213             parser_error (line_number, _("conditional binary operator expected"));
3214           dispose_cond_node (tleft);
3215           COND_RETURN_ERROR ();
3216         }
3217
3218       /* rhs */
3219       tok = read_token (READ);
3220       if (tok == WORD)
3221         {
3222           tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3223           term = make_cond_node (COND_BINARY, op, tleft, tright);
3224         }
3225       else
3226         {
3227           if (etext = error_token_from_token (tok))
3228             {
3229               parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
3230               free (etext);
3231             }
3232           else
3233             parser_error (line_number, _("unexpected argument to conditional binary operator"));
3234           dispose_cond_node (tleft);
3235           dispose_word (op);
3236           COND_RETURN_ERROR ();
3237         }
3238
3239       (void)cond_skip_newlines ();
3240     }
3241   else
3242     {
3243       if (tok < 256)
3244         parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
3245       else if (etext = error_token_from_token (tok))
3246         {
3247           parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
3248           free (etext);
3249         }
3250       else
3251         parser_error (line_number, _("unexpected token %d in conditional command"), tok);
3252       COND_RETURN_ERROR ();
3253     }
3254   return (term);
3255 }      
3256
3257 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3258    here to handle the conditional statement syntax. */
3259 static COMMAND *
3260 parse_cond_command ()
3261 {
3262   COND_COM *cexp;
3263
3264   cexp = cond_expr ();
3265   return (make_cond_command (cexp));
3266 }
3267 #endif
3268
3269 #if defined (ARRAY_VARS)
3270 /* When this is called, it's guaranteed that we don't care about anything
3271    in t beyond i.  We do save and restore the chars, though. */
3272 static int
3273 token_is_assignment (t, i)
3274      char *t;
3275      int i;
3276 {
3277   unsigned char c, c1;
3278   int r;
3279
3280   c = t[i]; c1 = t[i+1];
3281   t[i] = '='; t[i+1] = '\0';
3282   r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
3283   t[i] = c; t[i+1] = c1;
3284   return r;
3285 }
3286
3287 /* XXX - possible changes here for `+=' */
3288 static int
3289 token_is_ident (t, i)
3290      char *t;
3291      int i;
3292 {
3293   unsigned char c;
3294   int r;
3295
3296   c = t[i];
3297   t[i] = '\0';
3298   r = legal_identifier (t);
3299   t[i] = c;
3300   return r;
3301 }
3302 #endif
3303
3304 static int
3305 read_token_word (character)
3306      int character;
3307 {
3308   /* The value for YYLVAL when a WORD is read. */
3309   WORD_DESC *the_word;
3310
3311   /* Index into the token that we are building. */
3312   int token_index;
3313
3314   /* ALL_DIGITS becomes zero when we see a non-digit. */
3315   int all_digit_token;
3316
3317   /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3318   int dollar_present;
3319
3320   /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
3321      assignment. */
3322   int compound_assignment;
3323
3324   /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3325   int quoted;
3326
3327   /* Non-zero means to ignore the value of the next character, and just
3328      to add it no matter what. */
3329  int pass_next_character;
3330
3331   /* The current delimiting character. */
3332   int cd;
3333   int result, peek_char;
3334   char *ttok, *ttrans;
3335   int ttoklen, ttranslen;
3336   intmax_t lvalue;
3337
3338   if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3339     token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3340
3341   token_index = 0;
3342   all_digit_token = DIGIT (character);
3343   dollar_present = quoted = pass_next_character = compound_assignment = 0;
3344
3345   for (;;)
3346     {
3347       if (character == EOF)
3348         goto got_token;
3349
3350       if (pass_next_character)
3351         {
3352           pass_next_character = 0;
3353           goto got_character;
3354         }
3355
3356       cd = current_delimiter (dstack);
3357
3358       /* Handle backslashes.  Quote lots of things when not inside of
3359          double-quotes, quote some things inside of double-quotes. */
3360       if MBTEST(character == '\\')
3361         {
3362           peek_char = shell_getc (0);
3363
3364           /* Backslash-newline is ignored in all cases except
3365              when quoted with single quotes. */
3366           if (peek_char == '\n')
3367             {
3368               character = '\n';
3369               goto next_character;
3370             }
3371           else
3372             {
3373               shell_ungetc (peek_char);
3374
3375               /* If the next character is to be quoted, note it now. */
3376               if (cd == 0 || cd == '`' ||
3377                   (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
3378                 pass_next_character++;
3379
3380               quoted = 1;
3381               goto got_character;
3382             }
3383         }
3384
3385       /* Parse a matched pair of quote characters. */
3386       if MBTEST(shellquote (character))
3387         {
3388           push_delimiter (dstack, character);
3389           ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
3390           pop_delimiter (dstack);
3391           if (ttok == &matched_pair_error)
3392             return -1;          /* Bail immediately. */
3393           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3394                                   token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3395           token[token_index++] = character;
3396           strcpy (token + token_index, ttok);
3397           token_index += ttoklen;
3398           all_digit_token = 0;
3399           quoted = 1;
3400           dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3401           FREE (ttok);
3402           goto next_character;
3403         }
3404
3405 #ifdef EXTENDED_GLOB
3406       /* Parse a ksh-style extended pattern matching specification. */
3407       if (extended_glob && PATTERN_CHAR (character))
3408         {
3409           peek_char = shell_getc (1);
3410           if MBTEST(peek_char == '(')           /* ) */
3411             {
3412               push_delimiter (dstack, peek_char);
3413               ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3414               pop_delimiter (dstack);
3415               if (ttok == &matched_pair_error)
3416                 return -1;              /* Bail immediately. */
3417               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3418                                       token_buffer_size,
3419                                       TOKEN_DEFAULT_GROW_SIZE);
3420               token[token_index++] = character;
3421               token[token_index++] = peek_char;
3422               strcpy (token + token_index, ttok);
3423               token_index += ttoklen;
3424               FREE (ttok);
3425               dollar_present = all_digit_token = 0;
3426               goto next_character;
3427             }
3428           else
3429             shell_ungetc (peek_char);
3430         }
3431 #endif /* EXTENDED_GLOB */
3432
3433       /* If the delimiter character is not single quote, parse some of
3434          the shell expansions that must be read as a single word. */
3435       if (shellexp (character))
3436         {
3437           peek_char = shell_getc (1);
3438           /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3439           if MBTEST(peek_char == '(' || \
3440                 ((peek_char == '{' || peek_char == '[') && character == '$'))   /* ) ] } */
3441             {
3442               if (peek_char == '{')             /* } */
3443                 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
3444               else if (peek_char == '(')                /* ) */
3445                 {
3446                   /* XXX - push and pop the `(' as a delimiter for use by
3447                      the command-oriented-history code.  This way newlines
3448                      appearing in the $(...) string get added to the
3449                      history literally rather than causing a possibly-
3450                      incorrect `;' to be added. ) */
3451                   push_delimiter (dstack, peek_char);
3452                   ttok = parse_matched_pair (cd, '(', ')', &ttoklen, P_COMMAND);
3453                   pop_delimiter (dstack);
3454                 }
3455               else
3456                 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3457               if (ttok == &matched_pair_error)
3458                 return -1;              /* Bail immediately. */
3459               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3460                                       token_buffer_size,
3461                                       TOKEN_DEFAULT_GROW_SIZE);
3462               token[token_index++] = character;
3463               token[token_index++] = peek_char;
3464               strcpy (token + token_index, ttok);
3465               token_index += ttoklen;
3466               FREE (ttok);
3467               dollar_present = 1;
3468               all_digit_token = 0;
3469               goto next_character;
3470             }
3471           /* This handles $'...' and $"..." new-style quoted strings. */
3472           else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
3473             {
3474               int first_line;
3475
3476               first_line = line_number;
3477               push_delimiter (dstack, peek_char);
3478               ttok = parse_matched_pair (peek_char, peek_char, peek_char,
3479                                          &ttoklen,
3480                                          (peek_char == '\'') ? P_ALLOWESC : 0);
3481               pop_delimiter (dstack);
3482               if (ttok == &matched_pair_error)
3483                 return -1;
3484               if (peek_char == '\'')
3485                 {
3486                   ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3487                   free (ttok);
3488
3489                   /* Insert the single quotes and correctly quote any
3490                      embedded single quotes (allowed because P_ALLOWESC was
3491                      passed to parse_matched_pair). */
3492                   ttok = sh_single_quote (ttrans);
3493                   free (ttrans);
3494                   ttranslen = strlen (ttok);
3495                   ttrans = ttok;
3496                 }
3497               else
3498                 {
3499                   /* Try to locale)-expand the converted string. */
3500                   ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
3501                   free (ttok);
3502
3503                   /* Add the double quotes back */
3504                   ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
3505                   free (ttrans);
3506                   ttranslen += 2;
3507                   ttrans = ttok;
3508                 }
3509
3510               RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3511                                       token_buffer_size,
3512                                       TOKEN_DEFAULT_GROW_SIZE);
3513               strcpy (token + token_index, ttrans);
3514               token_index += ttranslen;
3515               FREE (ttrans);
3516               quoted = 1;
3517               all_digit_token = 0;
3518               goto next_character;
3519             }
3520           /* This could eventually be extended to recognize all of the
3521              shell's single-character parameter expansions, and set flags.*/
3522           else if MBTEST(character == '$' && peek_char == '$')
3523             {
3524               ttok = (char *)xmalloc (3);
3525               ttok[0] = ttok[1] = '$';
3526               ttok[2] = '\0';
3527               RESIZE_MALLOCED_BUFFER (token, token_index, 3,
3528                                       token_buffer_size,
3529                                       TOKEN_DEFAULT_GROW_SIZE);
3530               strcpy (token + token_index, ttok);
3531               token_index += 2;
3532               dollar_present = 1;
3533               all_digit_token = 0;
3534               FREE (ttok);
3535               goto next_character;
3536             }
3537           else
3538             shell_ungetc (peek_char);
3539         }
3540
3541 #if defined (ARRAY_VARS)
3542       /* Identify possible array subscript assignment; match [...] */
3543       else if MBTEST(character == '[' && token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index))     /* ] */
3544         {
3545           ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3546           if (ttok == &matched_pair_error)
3547             return -1;          /* Bail immediately. */
3548           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3549                                   token_buffer_size,
3550                                   TOKEN_DEFAULT_GROW_SIZE);
3551           token[token_index++] = character;
3552           strcpy (token + token_index, ttok);
3553           token_index += ttoklen;
3554           FREE (ttok);
3555           all_digit_token = 0;
3556           goto next_character;
3557         }
3558       /* Identify possible compound array variable assignment. */
3559       else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
3560         {
3561           peek_char = shell_getc (1);
3562           if MBTEST(peek_char == '(')           /* ) */
3563             {
3564               ttok = parse_compound_assignment (&ttoklen);
3565
3566               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
3567                                       token_buffer_size,
3568                                       TOKEN_DEFAULT_GROW_SIZE);
3569
3570               token[token_index++] = '=';
3571               token[token_index++] = '(';
3572               if (ttok)
3573                 {
3574                   strcpy (token + token_index, ttok);
3575                   token_index += ttoklen;
3576                 }
3577               token[token_index++] = ')';
3578               FREE (ttok);
3579               all_digit_token = 0;
3580               compound_assignment = 1;
3581 #if 0
3582               goto next_character;
3583 #else
3584               goto got_token;           /* ksh93 seems to do this */
3585 #endif
3586             }
3587           else
3588             shell_ungetc (peek_char);
3589         }
3590 #endif
3591
3592       /* When not parsing a multi-character word construct, shell meta-
3593          characters break words. */
3594       if MBTEST(shellbreak (character))
3595         {
3596           shell_ungetc (character);
3597           goto got_token;
3598         }
3599
3600     got_character:
3601
3602       all_digit_token &= DIGIT (character);
3603       dollar_present |= character == '$';
3604
3605       if (character == CTLESC || character == CTLNUL)
3606         token[token_index++] = CTLESC;
3607
3608       token[token_index++] = character;
3609
3610       RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3611                               TOKEN_DEFAULT_GROW_SIZE);
3612
3613     next_character:
3614       if (character == '\n' && SHOULD_PROMPT ())
3615         prompt_again ();
3616
3617       /* We want to remove quoted newlines (that is, a \<newline> pair)
3618          unless we are within single quotes or pass_next_character is
3619          set (the shell equivalent of literal-next). */
3620       cd = current_delimiter (dstack);
3621       character = shell_getc (cd != '\'' && pass_next_character == 0);
3622     }   /* end for (;;) */
3623
3624 got_token:
3625
3626   token[token_index] = '\0';
3627
3628   /* Check to see what thing we should return.  If the last_read_token
3629      is a `<', or a `&', or the character which ended this token is
3630      a '>' or '<', then, and ONLY then, is this input token a NUMBER.
3631      Otherwise, it is just a word, and should be returned as such. */
3632   if MBTEST(all_digit_token && (character == '<' || character == '>' || \
3633                     last_read_token == LESS_AND || \
3634                     last_read_token == GREATER_AND))
3635       {
3636         if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
3637           yylval.number = lvalue;
3638         else
3639           yylval.number = -1;
3640         return (NUMBER);
3641       }
3642
3643   /* Check for special case tokens. */
3644   result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
3645   if (result >= 0)
3646     return result;
3647
3648 #if defined (ALIAS)
3649   /* Posix.2 does not allow reserved words to be aliased, so check for all
3650      of them, including special cases, before expanding the current token
3651      as an alias. */
3652   if MBTEST(posixly_correct)
3653     CHECK_FOR_RESERVED_WORD (token);
3654
3655   /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3656      inhibits alias expansion. */
3657   if (expand_aliases && quoted == 0)
3658     {
3659       result = alias_expand_token (token);
3660       if (result == RE_READ_TOKEN)
3661         return (RE_READ_TOKEN);
3662       else if (result == NO_EXPANSION)
3663         parser_state &= ~PST_ALEXPNEXT;
3664     }
3665
3666   /* If not in Posix.2 mode, check for reserved words after alias
3667      expansion. */
3668   if MBTEST(posixly_correct == 0)
3669 #endif
3670     CHECK_FOR_RESERVED_WORD (token);
3671
3672   the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
3673   the_word->word = (char *)xmalloc (1 + token_index);
3674   the_word->flags = 0;
3675   strcpy (the_word->word, token);
3676   if (dollar_present)
3677     the_word->flags |= W_HASDOLLAR;
3678   if (quoted)
3679     the_word->flags |= W_QUOTED;
3680   if (compound_assignment)
3681     the_word->flags |= W_COMPASSIGN;
3682   /* A word is an assignment if it appears at the beginning of a
3683      simple command, or after another assignment word.  This is
3684      context-dependent, so it cannot be handled in the grammar. */
3685   if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
3686     {
3687       the_word->flags |= W_ASSIGNMENT;
3688       /* Don't perform word splitting on assignment statements. */
3689       if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
3690         the_word->flags |= W_NOSPLIT;
3691     }
3692
3693   if (command_token_position (last_read_token))
3694     {
3695       struct builtin *b;
3696       b = builtin_address_internal (token, 0);
3697       if (b && (b->flags & ASSIGNMENT_BUILTIN))
3698         parser_state |= PST_ASSIGNOK;
3699     }
3700
3701   yylval.word = the_word;
3702
3703   result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3704                 ? ASSIGNMENT_WORD : WORD;
3705
3706   switch (last_read_token)
3707     {
3708     case FUNCTION:
3709       parser_state |= PST_ALLOWOPNBRC;
3710       function_dstart = line_number;
3711       break;
3712     case CASE:
3713     case SELECT:
3714     case FOR:
3715       if (word_top < MAX_CASE_NEST)
3716         word_top++;
3717       word_lineno[word_top] = line_number;
3718       break;
3719     }
3720
3721   return (result);
3722 }
3723
3724 /* Return 1 if TOKSYM is a token that after being read would allow
3725    a reserved word to be seen, else 0. */
3726 static int
3727 reserved_word_acceptable (toksym)
3728      int toksym;
3729 {
3730   switch (toksym)
3731     {
3732     case '\n':
3733     case ';':
3734     case '(':
3735     case ')':
3736     case '|':
3737     case '&':
3738     case '{':
3739     case '}':           /* XXX */
3740     case AND_AND:
3741     case BANG:
3742     case DO:
3743     case DONE:
3744     case ELIF:
3745     case ELSE:
3746     case ESAC:
3747     case FI:
3748     case IF:
3749     case OR_OR:
3750     case SEMI_SEMI:
3751     case THEN:
3752     case TIME:
3753     case TIMEOPT:
3754     case UNTIL:
3755     case WHILE:
3756     case 0:
3757       return 1;
3758     default:
3759       return 0;
3760     }
3761 }
3762     
3763 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3764    TOKEN is not a shell reserved word. */
3765 int
3766 find_reserved_word (tokstr)
3767      char *tokstr;
3768 {
3769   int i;
3770   for (i = 0; word_token_alist[i].word; i++)
3771     if (STREQ (tokstr, word_token_alist[i].word))
3772       return i;
3773   return -1;
3774 }
3775
3776 #if 0
3777 #if defined (READLINE)
3778 /* Called after each time readline is called.  This insures that whatever
3779    the new prompt string is gets propagated to readline's local prompt
3780    variable. */
3781 static void
3782 reset_readline_prompt ()
3783 {
3784   char *temp_prompt;
3785
3786   if (prompt_string_pointer)
3787     {
3788       temp_prompt = (*prompt_string_pointer)
3789                         ? decode_prompt_string (*prompt_string_pointer)
3790                         : (char *)NULL;
3791
3792       if (temp_prompt == 0)
3793         {
3794           temp_prompt = (char *)xmalloc (1);
3795           temp_prompt[0] = '\0';
3796         }
3797
3798       FREE (current_readline_prompt);
3799       current_readline_prompt = temp_prompt;
3800     }
3801 }
3802 #endif /* READLINE */
3803 #endif /* 0 */
3804
3805 #if defined (HISTORY)
3806 /* A list of tokens which can be followed by newlines, but not by
3807    semi-colons.  When concatenating multiple lines of history, the
3808    newline separator for such tokens is replaced with a space. */
3809 static int no_semi_successors[] = {
3810   '\n', '{', '(', ')', ';', '&', '|',
3811   CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
3812   0
3813 };
3814
3815 /* If we are not within a delimited expression, try to be smart
3816    about which separators can be semi-colons and which must be
3817    newlines.  Returns the string that should be added into the
3818    history entry. */
3819 char *
3820 history_delimiting_chars ()
3821 {
3822   register int i;
3823
3824   if (dstack.delimiter_depth != 0)
3825     return ("\n");
3826     
3827   /* First, handle some special cases. */
3828   /*(*/
3829   /* If we just read `()', assume it's a function definition, and don't
3830      add a semicolon.  If the token before the `)' was not `(', and we're
3831      not in the midst of parsing a case statement, assume it's a
3832      parenthesized command and add the semicolon. */
3833   /*)(*/
3834   if (token_before_that == ')')
3835     {
3836       if (two_tokens_ago == '(')        /*)*/   /* function def */
3837         return " ";
3838       /* This does not work for subshells inside case statement
3839          command lists.  It's a suboptimal solution. */
3840       else if (parser_state & PST_CASESTMT)     /* case statement pattern */
3841         return " ";
3842       else      
3843         return "; ";                            /* (...) subshell */
3844     }
3845   else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
3846     return " ";         /* function def using `function name' without `()' */
3847
3848   else if (token_before_that == WORD && two_tokens_ago == FOR)
3849     {
3850       /* Tricky.  `for i\nin ...' should not have a semicolon, but
3851          `for i\ndo ...' should.  We do what we can. */
3852       for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
3853         ;
3854       if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
3855         return " ";
3856       return ";";
3857     }
3858   else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
3859     return " ";
3860
3861   for (i = 0; no_semi_successors[i]; i++)
3862     {
3863       if (token_before_that == no_semi_successors[i])
3864         return (" ");
3865     }
3866
3867   return ("; ");
3868 }
3869 #endif /* HISTORY */
3870
3871 /* Issue a prompt, or prepare to issue a prompt when the next character
3872    is read. */
3873 static void
3874 prompt_again ()
3875 {
3876   char *temp_prompt;
3877
3878   if (interactive == 0 || expanding_alias())    /* XXX */
3879     return;
3880
3881   ps1_prompt = get_string_value ("PS1");
3882   ps2_prompt = get_string_value ("PS2");
3883
3884   if (!prompt_string_pointer)
3885     prompt_string_pointer = &ps1_prompt;
3886
3887   temp_prompt = *prompt_string_pointer
3888                         ? decode_prompt_string (*prompt_string_pointer)
3889                         : (char *)NULL;
3890
3891   if (temp_prompt == 0)
3892     {
3893       temp_prompt = (char *)xmalloc (1);
3894       temp_prompt[0] = '\0';
3895     }
3896
3897   current_prompt_string = *prompt_string_pointer;
3898   prompt_string_pointer = &ps2_prompt;
3899
3900 #if defined (READLINE)
3901   if (!no_line_editing)
3902     {
3903       FREE (current_readline_prompt);
3904       current_readline_prompt = temp_prompt;
3905     }
3906   else
3907 #endif  /* READLINE */
3908     {
3909       FREE (current_decoded_prompt);
3910       current_decoded_prompt = temp_prompt;
3911     }
3912 }
3913
3914 int
3915 get_current_prompt_level ()
3916 {
3917   return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
3918 }
3919
3920 void
3921 set_current_prompt_level (x)
3922      int x;
3923 {
3924   prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
3925   current_prompt_string = *prompt_string_pointer;
3926 }
3927       
3928 static void
3929 print_prompt ()
3930 {
3931   fprintf (stderr, "%s", current_decoded_prompt);
3932   fflush (stderr);
3933 }
3934
3935 /* Return a string which will be printed as a prompt.  The string
3936    may contain special characters which are decoded as follows:
3937
3938         \a      bell (ascii 07)
3939         \d      the date in Day Mon Date format
3940         \e      escape (ascii 033)
3941         \h      the hostname up to the first `.'
3942         \H      the hostname
3943         \j      the number of active jobs
3944         \l      the basename of the shell's tty device name
3945         \n      CRLF
3946         \r      CR
3947         \s      the name of the shell
3948         \t      the time in 24-hour hh:mm:ss format
3949         \T      the time in 12-hour hh:mm:ss format
3950         \@      the time in 12-hour hh:mm am/pm format
3951         \A      the time in 24-hour hh:mm format
3952         \D{fmt} the result of passing FMT to strftime(3)
3953         \u      your username
3954         \v      the version of bash (e.g., 2.00)
3955         \V      the release of bash, version + patchlevel (e.g., 2.00.0)
3956         \w      the current working directory
3957         \W      the last element of $PWD
3958         \!      the history number of this command
3959         \#      the command number of this command
3960         \$      a $ or a # if you are root
3961         \nnn    character code nnn in octal
3962         \\      a backslash
3963         \[      begin a sequence of non-printing chars
3964         \]      end a sequence of non-printing chars
3965 */
3966 #define PROMPT_GROWTH 48
3967 char *
3968 decode_prompt_string (string)
3969      char *string;
3970 {
3971   WORD_LIST *list;
3972   char *result, *t;
3973   struct dstack save_dstack;
3974   int last_exit_value;
3975 #if defined (PROMPT_STRING_DECODE)
3976   int result_size, result_index;
3977   int c, n;
3978   char *temp, octal_string[4];
3979   struct tm *tm;  
3980   time_t the_time;
3981   char timebuf[128];
3982   char *timefmt;
3983
3984   result = (char *)xmalloc (result_size = PROMPT_GROWTH);
3985   result[result_index = 0] = 0;
3986   temp = (char *)NULL;
3987
3988   while (c = *string++)
3989     {
3990       if (posixly_correct && c == '!')
3991         {
3992           if (*string == '!')
3993             {
3994               temp = savestring ("!");
3995               goto add_string;
3996             }
3997           else
3998             {
3999 #if !defined (HISTORY)
4000                 temp = savestring ("1");
4001 #else /* HISTORY */
4002                 temp = itos (history_number ());
4003 #endif /* HISTORY */
4004                 string--;       /* add_string increments string again. */
4005                 goto add_string;
4006             }
4007         }
4008       if (c == '\\')
4009         {
4010           c = *string;
4011
4012           switch (c)
4013             {
4014             case '0':
4015             case '1':
4016             case '2':
4017             case '3':
4018             case '4':
4019             case '5':
4020             case '6':
4021             case '7':
4022               strncpy (octal_string, string, 3);
4023               octal_string[3] = '\0';
4024
4025               n = read_octal (octal_string);
4026               temp = (char *)xmalloc (3);
4027
4028               if (n == CTLESC || n == CTLNUL)
4029                 {
4030                   temp[0] = CTLESC;
4031                   temp[1] = n;
4032                   temp[2] = '\0';
4033                 }
4034               else if (n == -1)
4035                 {
4036                   temp[0] = '\\';
4037                   temp[1] = '\0';
4038                 }
4039               else
4040                 {
4041                   temp[0] = n;
4042                   temp[1] = '\0';
4043                 }
4044
4045               for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
4046                 string++;
4047
4048               c = 0;            /* tested at add_string: */
4049               goto add_string;
4050
4051             case 'd':
4052             case 't':
4053             case 'T':
4054             case '@':
4055             case 'A':
4056               /* Make the current time/date into a string. */
4057               (void) time (&the_time);
4058               tm = localtime (&the_time);
4059
4060               if (c == 'd')
4061                 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
4062               else if (c == 't')
4063                 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
4064               else if (c == 'T')
4065                 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
4066               else if (c == '@')
4067                 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
4068               else if (c == 'A')
4069                 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
4070
4071               if (n == 0)
4072                 timebuf[0] = '\0';
4073               else
4074                 timebuf[sizeof(timebuf) - 1] = '\0';
4075
4076               temp = savestring (timebuf);
4077               goto add_string;
4078
4079             case 'D':           /* strftime format */
4080               if (string[1] != '{')             /* } */
4081                 goto not_escape;
4082
4083               (void) time (&the_time);
4084               tm = localtime (&the_time);
4085               string += 2;                      /* skip { */
4086               timefmt = xmalloc (strlen (string) + 3);
4087               for (t = timefmt; *string && *string != '}'; )
4088                 *t++ = *string++;
4089               *t = '\0';
4090               c = *string;      /* tested at add_string */
4091               if (timefmt[0] == '\0')
4092                 {
4093                   timefmt[0] = '%';
4094                   timefmt[1] = 'X';     /* locale-specific current time */
4095                   timefmt[2] = '\0';
4096                 }
4097               n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
4098               free (timefmt);
4099
4100               if (n == 0)
4101                 timebuf[0] = '\0';
4102               else
4103                 timebuf[sizeof(timebuf) - 1] = '\0';
4104
4105               if (promptvars || posixly_correct)
4106                 /* Make sure that expand_prompt_string is called with a
4107                    second argument of Q_DOUBLE_QUOTES if we use this
4108                    function here. */
4109                 temp = sh_backslash_quote_for_double_quotes (timebuf);
4110               else
4111                 temp = savestring (timebuf);
4112               goto add_string;
4113               
4114             case 'n':
4115               temp = (char *)xmalloc (3);
4116               temp[0] = no_line_editing ? '\n' : '\r';
4117               temp[1] = no_line_editing ? '\0' : '\n';
4118               temp[2] = '\0';
4119               goto add_string;
4120
4121             case 's':
4122               temp = base_pathname (shell_name);
4123               temp = savestring (temp);
4124               goto add_string;
4125
4126             case 'v':
4127             case 'V':
4128               temp = (char *)xmalloc (16);
4129               if (c == 'v')
4130                 strcpy (temp, dist_version);
4131               else
4132                 sprintf (temp, "%s.%d", dist_version, patch_level);
4133               goto add_string;
4134
4135             case 'w':
4136             case 'W':
4137               {
4138                 /* Use the value of PWD because it is much more efficient. */
4139                 char t_string[PATH_MAX], *t;
4140                 int tlen;
4141
4142                 temp = get_string_value ("PWD");
4143
4144                 if (temp == 0)
4145                   {
4146                     if (getcwd (t_string, sizeof(t_string)) == 0)
4147                       {
4148                         t_string[0] = '.';
4149                         tlen = 1;
4150                       }
4151                     else
4152                       tlen = strlen (t_string);
4153                   }
4154                 else
4155                   {
4156                     tlen = sizeof (t_string) - 1;
4157                     strncpy (t_string, temp, tlen);
4158                   }
4159                 t_string[tlen] = '\0';
4160
4161 #define ROOT_PATH(x)    ((x)[0] == '/' && (x)[1] == 0)
4162 #define DOUBLE_SLASH_ROOT(x)    ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
4163                 /* Abbreviate \W as ~ if $PWD == $HOME */
4164                 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
4165                   {
4166                     if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
4167                       {
4168                         t = strrchr (t_string, '/');
4169                         if (t)
4170                           strcpy (t_string, t + 1);
4171                       }
4172                   }
4173 #undef ROOT_PATH
4174 #undef DOUBLE_SLASH_ROOT
4175                 else
4176                   /* polite_directory_format is guaranteed to return a string
4177                      no longer than PATH_MAX - 1 characters. */
4178                   strcpy (t_string, polite_directory_format (t_string));
4179
4180                 /* If we're going to be expanding the prompt string later,
4181                    quote the directory name. */
4182                 if (promptvars || posixly_correct)
4183                   /* Make sure that expand_prompt_string is called with a
4184                      second argument of Q_DOUBLE_QUOTES if we use this
4185                      function here. */
4186                   temp = sh_backslash_quote_for_double_quotes (t_string);
4187                 else
4188                   temp = savestring (t_string);
4189
4190                 goto add_string;
4191               }
4192
4193             case 'u':
4194               if (current_user.user_name == 0)
4195                 get_current_user_info ();
4196               temp = savestring (current_user.user_name);
4197               goto add_string;
4198
4199             case 'h':
4200             case 'H':
4201               temp = savestring (current_host_name);
4202               if (c == 'h' && (t = (char *)strchr (temp, '.')))
4203                 *t = '\0';
4204               goto add_string;
4205
4206             case '#':
4207               temp = itos (current_command_number);
4208               goto add_string;
4209
4210             case '!':
4211 #if !defined (HISTORY)
4212               temp = savestring ("1");
4213 #else /* HISTORY */
4214               temp = itos (history_number ());
4215 #endif /* HISTORY */
4216               goto add_string;
4217
4218             case '$':
4219               t = temp = (char *)xmalloc (3);
4220               if ((promptvars || posixly_correct) && (current_user.euid != 0))
4221                 *t++ = '\\';
4222               *t++ = current_user.euid == 0 ? '#' : '$';
4223               *t = '\0';
4224               goto add_string;
4225
4226             case 'j':
4227               temp = itos (count_all_jobs ());
4228               goto add_string;
4229
4230             case 'l':
4231 #if defined (HAVE_TTYNAME)
4232               temp = (char *)ttyname (fileno (stdin));
4233               t = temp ? base_pathname (temp) : "tty";
4234               temp = savestring (t);
4235 #else
4236               temp = savestring ("tty");
4237 #endif /* !HAVE_TTYNAME */
4238               goto add_string;
4239
4240 #if defined (READLINE)
4241             case '[':
4242             case ']':
4243               if (no_line_editing)
4244                 {
4245                   string++;
4246                   break;
4247                 }
4248               temp = (char *)xmalloc (3);
4249               temp[0] = '\001';
4250               temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4251               temp[2] = '\0';
4252               goto add_string;
4253 #endif /* READLINE */
4254
4255             case '\\':
4256             case 'a':
4257             case 'e':
4258             case 'r':
4259               temp = (char *)xmalloc (2);
4260               if (c == 'a')
4261                 temp[0] = '\07';
4262               else if (c == 'e')
4263                 temp[0] = '\033';
4264               else if (c == 'r')
4265                 temp[0] = '\r';
4266               else                      /* (c == '\\') */
4267                 temp[0] = c;
4268               temp[1] = '\0';
4269               goto add_string;
4270
4271             default:
4272 not_escape:
4273               temp = (char *)xmalloc (3);
4274               temp[0] = '\\';
4275               temp[1] = c;
4276               temp[2] = '\0';
4277
4278             add_string:
4279               if (c)
4280                 string++;
4281               result =
4282                 sub_append_string (temp, result, &result_index, &result_size);
4283               temp = (char *)NULL; /* Freed in sub_append_string (). */
4284               result[result_index] = '\0';
4285               break;
4286             }
4287         }
4288       else
4289         {
4290           RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4291           result[result_index++] = c;
4292           result[result_index] = '\0';
4293         }
4294     }
4295 #else /* !PROMPT_STRING_DECODE */
4296   result = savestring (string);
4297 #endif /* !PROMPT_STRING_DECODE */
4298
4299   /* Save the delimiter stack and point `dstack' to temp space so any
4300      command substitutions in the prompt string won't result in screwing
4301      up the parser's quoting state. */
4302   save_dstack = dstack;
4303   dstack = temp_dstack;
4304   dstack.delimiter_depth = 0;
4305
4306   /* Perform variable and parameter expansion and command substitution on
4307      the prompt string. */
4308   if (promptvars || posixly_correct)
4309     {
4310       last_exit_value = last_command_exit_value;
4311       list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
4312       free (result);
4313       result = string_list (list);
4314       dispose_words (list);
4315       last_command_exit_value = last_exit_value;
4316     }
4317   else
4318     {
4319       t = dequote_string (result);
4320       free (result);
4321       result = t;
4322     }
4323
4324   dstack = save_dstack;
4325
4326   return (result);
4327 }
4328
4329 /************************************************
4330  *                                              *
4331  *              ERROR HANDLING                  *
4332  *                                              *
4333  ************************************************/
4334
4335 /* Report a syntax error, and restart the parser.  Call here for fatal
4336    errors. */
4337 int
4338 yyerror (msg)
4339      const char *msg;
4340 {
4341   report_syntax_error ((char *)NULL);
4342   reset_parser ();
4343   return (0);
4344 }
4345
4346 static char *
4347 error_token_from_token (token)
4348      int token;
4349 {
4350   char *t;
4351
4352   if (t = find_token_in_alist (token, word_token_alist, 0))
4353     return t;
4354
4355   if (t = find_token_in_alist (token, other_token_alist, 0))
4356     return t;
4357
4358   t = (char *)NULL;
4359   /* This stuff is dicy and needs closer inspection */
4360   switch (current_token)
4361     {
4362     case WORD:
4363     case ASSIGNMENT_WORD:
4364       if (yylval.word)
4365         t = savestring (yylval.word->word);
4366       break;
4367     case NUMBER:
4368       t = itos (yylval.number);
4369       break;
4370     case ARITH_CMD:
4371       if (yylval.word_list)
4372         t = string_list (yylval.word_list);
4373       break;
4374     case ARITH_FOR_EXPRS:
4375       if (yylval.word_list)
4376         t = string_list_internal (yylval.word_list, " ; ");
4377       break;
4378     case COND_CMD:
4379       t = (char *)NULL;         /* punt */
4380       break;
4381     }
4382
4383   return t;
4384 }
4385
4386 static char *
4387 error_token_from_text ()
4388 {
4389   char *msg, *t;
4390   int token_end, i;
4391
4392   t = shell_input_line;
4393   i = shell_input_line_index;
4394   token_end = 0;
4395   msg = (char *)NULL;
4396
4397   if (i && t[i] == '\0')
4398     i--;
4399
4400   while (i && (whitespace (t[i]) || t[i] == '\n'))
4401     i--;
4402
4403   if (i)
4404     token_end = i + 1;
4405
4406   while (i && (member (t[i], " \n\t;|&") == 0))
4407     i--;
4408
4409   while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4410     i++;
4411
4412   /* Return our idea of the offending token. */
4413   if (token_end || (i == 0 && token_end == 0))
4414     {
4415       if (token_end)
4416         msg = substring (t, i, token_end);
4417       else      /* one-character token */
4418         {
4419           msg = (char *)xmalloc (2);
4420           msg[0] = t[i];
4421           msg[1] = '\0';
4422         }
4423     }
4424
4425   return (msg);
4426 }
4427
4428 static void
4429 print_offending_line ()
4430 {
4431   char *msg;
4432   int token_end;
4433
4434   msg = savestring (shell_input_line);
4435   token_end = strlen (msg);
4436   while (token_end && msg[token_end - 1] == '\n')
4437     msg[--token_end] = '\0';
4438
4439   parser_error (line_number, "`%s'", msg);
4440   free (msg);
4441 }
4442
4443 /* Report a syntax error with line numbers, etc.
4444    Call here for recoverable errors.  If you have a message to print,
4445    then place it in MESSAGE, otherwise pass NULL and this will figure
4446    out an appropriate message for you. */
4447 static void
4448 report_syntax_error (message)
4449      char *message;
4450 {
4451   char *msg;
4452
4453   if (message)
4454     {
4455       parser_error (line_number, "%s", message);
4456       if (interactive && EOF_Reached)
4457         EOF_Reached = 0;
4458       last_command_exit_value = EX_USAGE;
4459       return;
4460     }
4461
4462   /* If the line of input we're reading is not null, try to find the
4463      objectionable token.  First, try to figure out what token the
4464      parser's complaining about by looking at current_token. */
4465   if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
4466     {
4467       parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
4468       free (msg);
4469
4470       if (interactive == 0)
4471         print_offending_line ();
4472
4473       last_command_exit_value = EX_USAGE;
4474       return;
4475     }
4476
4477   /* If looking at the current token doesn't prove fruitful, try to find the
4478      offending token by analyzing the text of the input line near the current
4479      input line index and report what we find. */
4480   if (shell_input_line && *shell_input_line)
4481     {
4482       msg = error_token_from_text ();
4483       if (msg)
4484         {
4485           parser_error (line_number, _("syntax error near `%s'"), msg);
4486           free (msg);
4487         }
4488
4489       /* If not interactive, print the line containing the error. */
4490       if (interactive == 0)
4491         print_offending_line ();
4492     }
4493   else
4494     {
4495       msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
4496       parser_error (line_number, "%s", msg);
4497       /* When the shell is interactive, this file uses EOF_Reached
4498          only for error reporting.  Other mechanisms are used to
4499          decide whether or not to exit. */
4500       if (interactive && EOF_Reached)
4501         EOF_Reached = 0;
4502     }
4503
4504   last_command_exit_value = EX_USAGE;
4505 }
4506
4507 /* ??? Needed function. ??? We have to be able to discard the constructs
4508    created during parsing.  In the case of error, we want to return
4509    allocated objects to the memory pool.  In the case of no error, we want
4510    to throw away the information about where the allocated objects live.
4511    (dispose_command () will actually free the command.) */
4512 static void
4513 discard_parser_constructs (error_p)
4514      int error_p;
4515 {
4516 }
4517
4518 /************************************************
4519  *                                              *
4520  *              EOF HANDLING                    *
4521  *                                              *
4522  ************************************************/
4523
4524 /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
4525
4526 /* A flag denoting whether or not ignoreeof is set. */
4527 int ignoreeof = 0;
4528
4529 /* The number of times that we have encountered an EOF character without
4530    another character intervening.  When this gets above the limit, the
4531    shell terminates. */
4532 int eof_encountered = 0;
4533
4534 /* The limit for eof_encountered. */
4535 int eof_encountered_limit = 10;
4536
4537 /* If we have EOF as the only input unit, this user wants to leave
4538    the shell.  If the shell is not interactive, then just leave.
4539    Otherwise, if ignoreeof is set, and we haven't done this the
4540    required number of times in a row, print a message. */
4541 static void
4542 handle_eof_input_unit ()
4543 {
4544   if (interactive)
4545     {
4546       /* shell.c may use this to decide whether or not to write out the
4547          history, among other things.  We use it only for error reporting
4548          in this file. */
4549       if (EOF_Reached)
4550         EOF_Reached = 0;
4551
4552       /* If the user wants to "ignore" eof, then let her do so, kind of. */
4553       if (ignoreeof)
4554         {
4555           if (eof_encountered < eof_encountered_limit)
4556             {
4557               fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
4558                        login_shell ? "logout" : "exit");
4559               eof_encountered++;
4560               /* Reset the parsing state. */
4561               last_read_token = current_token = '\n';
4562               /* Reset the prompt string to be $PS1. */
4563               prompt_string_pointer = (char **)NULL;
4564               prompt_again ();
4565               return;
4566             }
4567         }
4568
4569       /* In this case EOF should exit the shell.  Do it now. */
4570       reset_parser ();
4571       exit_builtin ((WORD_LIST *)NULL);
4572     }
4573   else
4574     {
4575       /* We don't write history files, etc., for non-interactive shells. */
4576       EOF_Reached = 1;
4577     }
4578 }
4579
4580 /************************************************
4581  *                                              *
4582  *      STRING PARSING FUNCTIONS                *
4583  *                                              *
4584  ************************************************/
4585
4586 /* It's very important that these two functions treat the characters
4587    between ( and ) identically. */
4588
4589 static WORD_LIST parse_string_error;
4590
4591 /* Take a string and run it through the shell parser, returning the
4592    resultant word list.  Used by compound array assignment. */
4593 WORD_LIST *
4594 parse_string_to_word_list (s, flags, whom)
4595      char *s;
4596      int flags;
4597      const char *whom;
4598 {
4599   WORD_LIST *wl;
4600   int tok, orig_current_token, orig_line_number, orig_input_terminator;
4601   int orig_line_count;
4602   int old_echo_input, old_expand_aliases;
4603 #if defined (HISTORY)
4604   int old_remember_on_history, old_history_expansion_inhibited;
4605 #endif
4606
4607 #if defined (HISTORY)
4608   old_remember_on_history = remember_on_history;
4609 #  if defined (BANG_HISTORY)
4610   old_history_expansion_inhibited = history_expansion_inhibited;
4611 #  endif
4612   bash_history_disable ();
4613 #endif
4614
4615   orig_line_number = line_number;
4616   orig_line_count = current_command_line_count;
4617   orig_input_terminator = shell_input_line_terminator;
4618   old_echo_input = echo_input_at_read;
4619   old_expand_aliases = expand_aliases;
4620
4621   push_stream (1);
4622   last_read_token = WORD;               /* WORD to allow reserved words here */
4623   current_command_line_count = 0;
4624   echo_input_at_read = expand_aliases = 0;
4625
4626   with_input_from_string (s, whom);
4627   wl = (WORD_LIST *)NULL;
4628
4629   if (flags & 1)
4630     parser_state |= PST_COMPASSIGN;
4631
4632   while ((tok = read_token (READ)) != yacc_EOF)
4633     {
4634       if (tok == '\n' && *bash_input.location.string == '\0')
4635         break;
4636       if (tok == '\n')          /* Allow newlines in compound assignments */
4637         continue;
4638       if (tok != WORD && tok != ASSIGNMENT_WORD)
4639         {
4640           line_number = orig_line_number + line_number - 1;
4641           orig_current_token = current_token;
4642           current_token = tok;
4643           yyerror (NULL);       /* does the right thing */
4644           current_token = orig_current_token;
4645           if (wl)
4646             dispose_words (wl);
4647           wl = &parse_string_error;
4648           break;
4649         }
4650       wl = make_word_list (yylval.word, wl);
4651     }
4652   
4653   last_read_token = '\n';
4654   pop_stream ();
4655
4656 #if defined (HISTORY)
4657   remember_on_history = old_remember_on_history;
4658 #  if defined (BANG_HISTORY)
4659   history_expansion_inhibited = old_history_expansion_inhibited;
4660 #  endif /* BANG_HISTORY */
4661 #endif /* HISTORY */
4662
4663   echo_input_at_read = old_echo_input;
4664   expand_aliases = old_expand_aliases;
4665
4666   current_command_line_count = orig_line_count;
4667   shell_input_line_terminator = orig_input_terminator;
4668
4669   if (flags & 1)
4670     parser_state &= ~PST_COMPASSIGN;
4671
4672   if (wl == &parse_string_error)
4673     {
4674       last_command_exit_value = EXECUTION_FAILURE;
4675       if (interactive_shell == 0 && posixly_correct)
4676         jump_to_top_level (FORCE_EOF);
4677       else
4678         jump_to_top_level (DISCARD);
4679     }
4680
4681   return (REVERSE_LIST (wl, WORD_LIST *));
4682 }
4683
4684 static char *
4685 parse_compound_assignment (retlenp)
4686      int *retlenp;
4687 {
4688   WORD_LIST *wl, *rl;
4689   int tok, orig_line_number, orig_token_size;
4690   char *saved_token, *ret;
4691
4692   saved_token = token;
4693   orig_token_size = token_buffer_size;
4694   orig_line_number = line_number;
4695
4696   last_read_token = WORD;       /* WORD to allow reserved words here */
4697
4698   token = (char *)NULL;
4699   token_buffer_size = 0;
4700
4701   wl = (WORD_LIST *)NULL;       /* ( */
4702   parser_state |= PST_COMPASSIGN;
4703
4704   while ((tok = read_token (READ)) != ')')
4705     {
4706       if (tok == '\n')                  /* Allow newlines in compound assignments */
4707         {
4708           if (SHOULD_PROMPT ())
4709             prompt_again ();
4710           continue;
4711         }
4712       if (tok != WORD && tok != ASSIGNMENT_WORD)
4713         {
4714           current_token = tok;  /* for error reporting */
4715           if (tok == yacc_EOF)  /* ( */
4716             parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
4717           else
4718             yyerror(NULL);      /* does the right thing */
4719           if (wl)
4720             dispose_words (wl);
4721           wl = &parse_string_error;
4722           break;
4723         }
4724       wl = make_word_list (yylval.word, wl);
4725     }
4726
4727   FREE (token);
4728   token = saved_token;
4729   token_buffer_size = orig_token_size;
4730
4731   parser_state &= ~PST_COMPASSIGN;
4732
4733   if (wl == &parse_string_error)
4734     {
4735       last_command_exit_value = EXECUTION_FAILURE;
4736       last_read_token = '\n';   /* XXX */
4737       if (interactive_shell == 0 && posixly_correct)
4738         jump_to_top_level (FORCE_EOF);
4739       else
4740         jump_to_top_level (DISCARD);
4741     }
4742
4743   last_read_token = WORD;
4744   if (wl)
4745     {
4746       rl = REVERSE_LIST (wl, WORD_LIST *);
4747       ret = string_list (rl);
4748       dispose_words (rl);
4749     }
4750   else
4751     ret = (char *)NULL;
4752
4753   if (retlenp)
4754     *retlenp = (ret && *ret) ? strlen (ret) : 0;
4755   return ret;
4756 }
4757
4758 /************************************************
4759  *                                              *
4760  *   SAVING AND RESTORING PARTIAL PARSE STATE   *
4761  *                                              *
4762  ************************************************/
4763
4764 sh_parser_state_t *
4765 save_parser_state (ps)
4766      sh_parser_state_t *ps;
4767 {
4768 #if defined (ARRAY_VARS)
4769   SHELL_VAR *v;
4770 #endif
4771
4772   if (ps == 0)
4773     ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
4774   if (ps == 0)
4775     return ((sh_parser_state_t *)NULL);
4776
4777   ps->parser_state = parser_state;
4778   ps->token_state = save_token_state ();
4779
4780   ps->input_line_terminator = shell_input_line_terminator;
4781   ps->eof_encountered = eof_encountered;
4782
4783   ps->current_command_line_count = current_command_line_count;
4784
4785 #if defined (HISTORY)
4786   ps->remember_on_history = remember_on_history;
4787 #  if defined (BANG_HISTORY)
4788   ps->history_expansion_inhibited = history_expansion_inhibited;
4789 #  endif
4790 #endif
4791
4792   ps->last_command_exit_value = last_command_exit_value;
4793 #if defined (ARRAY_VARS)
4794   v = find_variable ("PIPESTATUS");
4795   if (v && array_p (v) && array_cell (v))
4796     ps->pipestatus = array_copy (array_cell (v));
4797   else
4798     ps->pipestatus = (ARRAY *)NULL;
4799 #endif
4800     
4801   ps->last_shell_builtin = last_shell_builtin;
4802   ps->this_shell_builtin = this_shell_builtin;
4803
4804   ps->expand_aliases = expand_aliases;
4805   ps->echo_input_at_read = echo_input_at_read;
4806
4807   return (ps);
4808 }
4809
4810 void
4811 restore_parser_state (ps)
4812      sh_parser_state_t *ps;
4813 {
4814 #if defined (ARRAY_VARS)
4815   SHELL_VAR *v;
4816 #endif
4817
4818   if (ps == 0)
4819     return;
4820
4821   parser_state = ps->parser_state;
4822   if (ps->token_state)
4823     {
4824       restore_token_state (ps->token_state);
4825       free (ps->token_state);
4826     }
4827
4828   shell_input_line_terminator = ps->input_line_terminator;
4829   eof_encountered = ps->eof_encountered;
4830
4831   current_command_line_count = ps->current_command_line_count;
4832
4833 #if defined (HISTORY)
4834   remember_on_history = ps->remember_on_history;
4835 #  if defined (BANG_HISTORY)
4836   history_expansion_inhibited = ps->history_expansion_inhibited;
4837 #  endif
4838 #endif
4839
4840   last_command_exit_value = ps->last_command_exit_value;
4841 #if defined (ARRAY_VARS)
4842   v = find_variable ("PIPESTATUS");
4843   if (v && array_p (v) && array_cell (v))
4844     {
4845       array_dispose (array_cell (v));
4846       var_setarray (v, ps->pipestatus);
4847     }
4848 #endif
4849
4850   last_shell_builtin = ps->last_shell_builtin;
4851   this_shell_builtin = ps->this_shell_builtin;
4852
4853   expand_aliases = ps->expand_aliases;
4854   echo_input_at_read = ps->echo_input_at_read;
4855 }
4856
4857 /************************************************
4858  *                                              *
4859  *      MULTIBYTE CHARACTER HANDLING            *
4860  *                                              *
4861  ************************************************/
4862
4863 #if defined (HANDLE_MULTIBYTE)
4864 static void
4865 set_line_mbstate ()
4866 {
4867   int i, previ, len, c;
4868   mbstate_t mbs, prevs;
4869   size_t mbclen;
4870
4871   if (shell_input_line == NULL)
4872     return;
4873   len = strlen (shell_input_line);      /* XXX - shell_input_line_len ? */
4874   FREE (shell_input_line_property);
4875   shell_input_line_property = (char *)xmalloc (len + 1);
4876
4877   memset (&prevs, '\0', sizeof (mbstate_t));
4878   for (i = previ = 0; i < len; i++)
4879     {
4880       mbs = prevs;
4881
4882       c = shell_input_line[i];
4883       if (c == EOF)
4884         {
4885           int j;
4886           for (j = i; j < len; j++)
4887             shell_input_line_property[j] = 1;
4888           break;
4889         }
4890
4891       mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
4892       if (mbclen == 1 || mbclen == (size_t)-1)
4893         {
4894           mbclen = 1;
4895           previ = i + 1;
4896         }
4897       else if (mbclen == (size_t)-2)
4898         mbclen = 0;
4899       else if (mbclen > 1)
4900         {
4901           mbclen = 0;
4902           previ = i + 1;
4903           prevs = mbs;
4904         }
4905       else
4906         {
4907           /* XXX - what to do if mbrlen returns 0? (null wide character) */
4908           int j;
4909           for (j = i; j < len; j++)
4910             shell_input_line_property[j] = 1;
4911           break;
4912         }
4913
4914       shell_input_line_property[i] = mbclen;
4915     }
4916 }
4917 #endif /* HANDLE_MULTIBYTE */