Imported from ../bash-2.03.tar.gz.
[platform/upstream/bash.git] / parse.y
1 /* Yacc grammar for bash. */
2
3 /* Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 %{
22 #include "config.h"
23
24 #include "bashtypes.h"
25 #include "bashansi.h"
26
27 #if defined (HAVE_UNISTD_H)
28 #  include <unistd.h>
29 #endif
30
31 #if defined (HAVE_LOCALE_H)
32 #  include <locale.h>
33 #endif
34
35 #include <stdio.h>
36 #include <signal.h>
37
38 #include "memalloc.h"
39
40 #include "shell.h"
41 #include "trap.h"
42 #include "flags.h"
43 #include "parser.h"
44 #include "mailcheck.h"
45 #include "builtins/common.h"
46 #include "builtins/builtext.h"
47
48 #if defined (READLINE)
49 #  include "bashline.h"
50 #  include <readline/readline.h>
51 #endif /* READLINE */
52
53 #if defined (HISTORY)
54 #  include "bashhist.h"
55 #  include <readline/history.h>
56 #endif /* HISTORY */
57
58 #if defined (JOB_CONTROL)
59 #  include "jobs.h"
60 #endif /* JOB_CONTROL */
61
62 #if defined (ALIAS)
63 #  include "alias.h"
64 #endif /* ALIAS */
65
66 #if defined (PROMPT_STRING_DECODE)
67 #  ifndef _MINIX
68 #    include <sys/param.h>
69 #  endif
70 #  include <time.h>
71 #  include "maxpath.h"
72 #endif /* PROMPT_STRING_DECODE */
73
74 #define RE_READ_TOKEN   -99
75 #define NO_EXPANSION    -100
76
77 #define YYDEBUG 0
78
79 #if defined (EXTENDED_GLOB)
80 #define PATTERN_CHAR(c) \
81         ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!')
82
83 extern int extended_glob;
84 #endif
85
86 extern int eof_encountered;
87 extern int no_line_editing, running_under_emacs;
88 extern int current_command_number;
89 extern int interactive, interactive_shell, login_shell;
90 extern int sourcelevel;
91 extern int posixly_correct;
92 extern int last_command_exit_value;
93 extern int interrupt_immediately;
94 extern char *shell_name, *current_host_name;
95 extern char *dist_version;
96 extern int patch_level;
97 extern int dump_translatable_strings, dump_po_strings;
98 extern Function *last_shell_builtin, *this_shell_builtin;
99 #if defined (BUFFERED_INPUT)
100 extern int bash_input_fd_changed;
101 #endif
102
103 /* **************************************************************** */
104 /*                                                                  */
105 /*                  "Forward" declarations                          */
106 /*                                                                  */
107 /* **************************************************************** */
108
109 static char *ansiexpand ();
110 static char *localeexpand ();
111 static int reserved_word_acceptable ();
112 static int read_token ();
113 static int yylex ();
114 static int parse_arith_cmd ();
115 #if defined (COND_COMMAND)
116 static COMMAND *parse_cond_command ();
117 #endif
118 static int read_token_word ();
119 static void discard_parser_constructs ();
120
121 static void report_syntax_error ();
122 static void handle_eof_input_unit ();
123 static void prompt_again ();
124 #if 0
125 static void reset_readline_prompt ();
126 #endif
127 static void print_prompt ();
128
129 extern int yyerror ();
130
131 /* Default prompt strings */
132 char *primary_prompt = PPROMPT;
133 char *secondary_prompt = SPROMPT;
134
135 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
136 char *ps1_prompt, *ps2_prompt;
137
138 /* Handle on the current prompt string.  Indirectly points through
139    ps1_ or ps2_prompt. */
140 char **prompt_string_pointer = (char **)NULL;
141 char *current_prompt_string;
142
143 /* Non-zero means we expand aliases in commands. */
144 int expand_aliases = 0;
145
146 /* If non-zero, the decoded prompt string undergoes parameter and
147    variable substitution, command substitution, arithmetic substitution,
148    string expansion, process substitution, and quote removal in
149    decode_prompt_string. */
150 int promptvars = 1;
151
152 /* The decoded prompt string.  Used if READLINE is not defined or if
153    editing is turned off.  Analogous to current_readline_prompt. */
154 static char *current_decoded_prompt;
155
156 /* The number of lines read from input while creating the current command. */
157 int current_command_line_count;
158
159 /* Variables to manage the task of reading here documents, because we need to
160    defer the reading until after a complete command has been collected. */
161 static REDIRECT *redir_stack[10];
162 int need_here_doc;
163
164 /* Where shell input comes from.  History expansion is performed on each
165    line when the shell is interactive. */
166 static char *shell_input_line = (char *)NULL;
167 static int shell_input_line_index;
168 static int shell_input_line_size;       /* Amount allocated for shell_input_line. */
169 static int shell_input_line_len;        /* strlen (shell_input_line) */
170
171 /* Either zero or EOF. */
172 static int shell_input_line_terminator;
173
174 /* The line number in a script on which a function definition starts. */
175 static int function_dstart;
176
177 /* The line number in a script on which a function body starts. */
178 static int function_bstart;
179
180 static REDIRECTEE redir;
181 %}
182
183 %union {
184   WORD_DESC *word;              /* the word that we read. */
185   int number;                   /* the number that we read. */
186   WORD_LIST *word_list;
187   COMMAND *command;
188   REDIRECT *redirect;
189   ELEMENT element;
190   PATTERN_LIST *pattern;
191 }
192
193 /* Reserved words.  Members of the first group are only recognized
194    in the case that they are preceded by a list_terminator.  Members
195    of the second group are for [[...]] commands.  Members of the
196    third group are recognized only under special circumstances. */
197 %token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION
198 %token COND_START COND_END COND_ERROR
199 %token IN BANG TIME TIMEOPT 
200
201 /* More general tokens. yylex () knows how to make these. */
202 %token <word> WORD ASSIGNMENT_WORD
203 %token <number> NUMBER
204 %token <word_list> ARITH_CMD
205 %token <command> COND_CMD
206 %token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND
207 %token GREATER_AND SEMI_SEMI LESS_LESS_MINUS AND_GREATER LESS_GREATER
208 %token GREATER_BAR
209
210 /* The types that the various syntactical units return. */
211
212 %type <command> inputunit command pipeline pipeline_command
213 %type <command> list list0 list1 compound_list simple_list simple_list1
214 %type <command> simple_command shell_command
215 %type <command> for_command select_command case_command group_command
216 %type <command> arith_command
217 %type <command> cond_command
218 %type <command> function_def if_command elif_clause subshell
219 %type <redirect> redirection redirection_list
220 %type <element> simple_command_element
221 %type <word_list> word_list pattern
222 %type <pattern> pattern_list case_clause_sequence case_clause
223 %type <number> timespec
224
225 %start inputunit
226
227 %left '&' ';' '\n' yacc_EOF
228 %left AND_AND OR_OR
229 %right '|'
230 %%
231
232 inputunit:      simple_list '\n'
233                         {
234                           /* Case of regular command.  Discard the error
235                              safety net,and return the command just parsed. */
236                           global_command = $1;
237                           eof_encountered = 0;
238                           discard_parser_constructs (0);
239                           YYACCEPT;
240                         }
241         |       '\n'
242                         {
243                           /* Case of regular command, but not a very
244                              interesting one.  Return a NULL command. */
245                           global_command = (COMMAND *)NULL;
246                           YYACCEPT;
247                         }
248         |       error '\n'
249                         {
250                           /* Error during parsing.  Return NULL command. */
251                           global_command = (COMMAND *)NULL;
252                           eof_encountered = 0;
253                           discard_parser_constructs (1);
254                           if (interactive)
255                             {
256                               YYACCEPT;
257                             }
258                           else
259                             {
260                               YYABORT;
261                             }
262                         }
263         |       yacc_EOF
264                         {
265                           /* Case of EOF seen by itself.  Do ignoreeof or
266                              not. */
267                           global_command = (COMMAND *)NULL;
268                           handle_eof_input_unit ();
269                           YYACCEPT;
270                         }
271         ;
272
273 word_list:      WORD
274                         { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
275         |       word_list WORD
276                         { $$ = make_word_list ($2, $1); }
277         ;
278
279 redirection:    '>' WORD
280                         {
281                           redir.filename = $2;
282                           $$ = make_redirection (1, r_output_direction, redir);
283                         }
284         |       '<' WORD
285                         {
286                           redir.filename = $2;
287                           $$ = make_redirection (0, r_input_direction, redir);
288                         }
289         |       NUMBER '>' WORD
290                         {
291                           redir.filename = $3;
292                           $$ = make_redirection ($1, r_output_direction, redir);
293                         }
294         |       NUMBER '<' WORD
295                         {
296                           redir.filename = $3;
297                           $$ = make_redirection ($1, r_input_direction, redir);
298                         }
299         |       GREATER_GREATER WORD
300                         {
301                           redir.filename = $2;
302                           $$ = make_redirection (1, r_appending_to, redir);
303                         }
304         |       NUMBER GREATER_GREATER WORD
305                         {
306                           redir.filename = $3;
307                           $$ = make_redirection ($1, r_appending_to, redir);
308                         }
309         |       LESS_LESS WORD
310                         {
311                           redir.filename = $2;
312                           $$ = make_redirection (0, r_reading_until, redir);
313                           redir_stack[need_here_doc++] = $$;
314                         }
315         |       NUMBER LESS_LESS WORD
316                         {
317                           redir.filename = $3;
318                           $$ = make_redirection ($1, r_reading_until, redir);
319                           redir_stack[need_here_doc++] = $$;
320                         }
321         |       LESS_AND NUMBER
322                         {
323                           redir.dest = $2;
324                           $$ = make_redirection (0, r_duplicating_input, redir);
325                         }
326         |       NUMBER LESS_AND NUMBER
327                         {
328                           redir.dest = $3;
329                           $$ = make_redirection ($1, r_duplicating_input, redir);
330                         }
331         |       GREATER_AND NUMBER
332                         {
333                           redir.dest = $2;
334                           $$ = make_redirection (1, r_duplicating_output, redir);
335                         }
336         |       NUMBER GREATER_AND NUMBER
337                         {
338                           redir.dest = $3;
339                           $$ = make_redirection ($1, r_duplicating_output, redir);
340                         }
341         |       LESS_AND WORD
342                         {
343                           redir.filename = $2;
344                           $$ = make_redirection (0, r_duplicating_input_word, redir);
345                         }
346         |       NUMBER LESS_AND WORD
347                         {
348                           redir.filename = $3;
349                           $$ = make_redirection ($1, r_duplicating_input_word, redir);
350                         }
351         |       GREATER_AND WORD
352                         {
353                           redir.filename = $2;
354                           $$ = make_redirection (1, r_duplicating_output_word, redir);
355                         }
356         |       NUMBER GREATER_AND WORD
357                         {
358                           redir.filename = $3;
359                           $$ = make_redirection ($1, r_duplicating_output_word, redir);
360                         }
361         |       LESS_LESS_MINUS WORD
362                         {
363                           redir.filename = $2;
364                           $$ = make_redirection
365                             (0, r_deblank_reading_until, redir);
366                           redir_stack[need_here_doc++] = $$;
367                         }
368         |       NUMBER LESS_LESS_MINUS WORD
369                         {
370                           redir.filename = $3;
371                           $$ = make_redirection
372                             ($1, r_deblank_reading_until, redir);
373                           redir_stack[need_here_doc++] = $$;
374                         }
375         |       GREATER_AND '-'
376                         {
377                           redir.dest = 0L;
378                           $$ = make_redirection (1, r_close_this, redir);
379                         }
380         |       NUMBER GREATER_AND '-'
381                         {
382                           redir.dest = 0L;
383                           $$ = make_redirection ($1, r_close_this, redir);
384                         }
385         |       LESS_AND '-'
386                         {
387                           redir.dest = 0L;
388                           $$ = make_redirection (0, r_close_this, redir);
389                         }
390         |       NUMBER LESS_AND '-'
391                         {
392                           redir.dest = 0L;
393                           $$ = make_redirection ($1, r_close_this, redir);
394                         }
395         |       AND_GREATER WORD
396                         {
397                           redir.filename = $2;
398                           $$ = make_redirection (1, r_err_and_out, redir);
399                         }
400         |       NUMBER LESS_GREATER WORD
401                         {
402                           redir.filename = $3;
403                           $$ = make_redirection ($1, r_input_output, redir);
404                         }
405         |       LESS_GREATER WORD
406                         {
407                           redir.filename = $2;
408                           $$ = make_redirection (0, r_input_output, redir);
409                         }
410         |       GREATER_BAR WORD
411                         {
412                           redir.filename = $2;
413                           $$ = make_redirection (1, r_output_force, redir);
414                         }
415         |       NUMBER GREATER_BAR WORD
416                         {
417                           redir.filename = $3;
418                           $$ = make_redirection ($1, r_output_force, redir);
419                         }
420         ;
421
422 simple_command_element: WORD
423                         { $$.word = $1; $$.redirect = 0; }
424         |       ASSIGNMENT_WORD
425                         { $$.word = $1; $$.redirect = 0; }
426         |       redirection
427                         { $$.redirect = $1; $$.word = 0; }
428         ;
429
430 redirection_list: redirection
431                         {
432                           $$ = $1;
433                         }
434         |       redirection_list redirection
435                         {
436                           register REDIRECT *t;
437
438                           for (t = $1; t->next; t = t->next)
439                             ;
440                           t->next = $2;
441                           $$ = $1;
442                         }
443         ;
444
445 simple_command: simple_command_element
446                         { $$ = make_simple_command ($1, (COMMAND *)NULL); }
447         |       simple_command simple_command_element
448                         { $$ = make_simple_command ($2, $1); }
449         ;
450
451 command:        simple_command
452                         { $$ = clean_simple_command ($1); }
453         |       shell_command
454                         { $$ = $1; }
455         |       shell_command redirection_list
456                         {
457                           COMMAND *tc;
458
459                           tc = $1;
460                           /* According to Posix.2 3.9.5, redirections
461                              specified after the body of a function should
462                              be attached to the function and performed when
463                              the function is executed, not as part of the
464                              function definition command. */
465                           if (tc->type == cm_function_def)
466                             {
467                               tc = tc->value.Function_def->command;
468                               if (tc->type == cm_group)
469                                 tc = tc->value.Group->command;
470                             }
471                           if (tc->redirects)
472                             {
473                               register REDIRECT *t;
474                               for (t = tc->redirects; t->next; t = t->next)
475                                 ;
476                               t->next = $2;
477                             }
478                           else
479                             tc->redirects = $2;
480                           $$ = $1;
481                         }
482         ;
483
484 shell_command:  for_command
485                         { $$ = $1; }
486         |       case_command
487                         { $$ = $1; }
488         |       WHILE compound_list DO compound_list DONE
489                         { $$ = make_while_command ($2, $4); }
490         |       UNTIL compound_list DO compound_list DONE
491                         { $$ = make_until_command ($2, $4); }
492         |       select_command
493                         { $$ = $1; }
494         |       if_command
495                         { $$ = $1; }
496         |       subshell
497                         { $$ = $1; }
498         |       group_command
499                         { $$ = $1; }
500         |       arith_command
501                         { $$ = $1; }
502         |       cond_command
503                         { $$ = $1; }
504         |       function_def
505                         { $$ = $1; }
506         ;
507
508 for_command:    FOR WORD newline_list DO compound_list DONE
509                         { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5); }
510         |       FOR WORD newline_list '{' compound_list '}'
511                         { $$ = make_for_command ($2, add_string_to_list ("$@", (WORD_LIST *)NULL), $5); }
512         |       FOR WORD ';' newline_list DO compound_list DONE
513                         { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6); }
514         |       FOR WORD ';' newline_list '{' compound_list '}'
515                         { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6); }
516         |       FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
517                         { $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9); }
518         |       FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
519                         { $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9); }
520         ;
521
522 select_command: SELECT WORD newline_list DO list DONE
523                         {
524                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5);
525                         }
526         |       SELECT WORD newline_list '{' list '}'
527                         {
528                           $$ = make_select_command ($2, add_string_to_list ("$@", (WORD_LIST *)NULL), $5);
529                         }
530         |       SELECT WORD ';' newline_list DO list DONE
531                         {
532                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6);
533                         }
534         |       SELECT WORD ';' newline_list '{' list '}'
535                         {
536                           $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6);
537                         }
538         |       SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
539                         {
540                           $$ = make_select_command ($2, (WORD_LIST *)reverse_list ($5), $9);
541                         }
542         |       SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
543                         {
544                           $$ = make_select_command ($2, (WORD_LIST *)reverse_list ($5), $9);
545                         }
546         ;
547
548 case_command:   CASE WORD newline_list IN newline_list ESAC
549                         { $$ = make_case_command ($2, (PATTERN_LIST *)NULL); }
550         |       CASE WORD newline_list IN case_clause_sequence newline_list ESAC
551                         { $$ = make_case_command ($2, $5); }
552         |       CASE WORD newline_list IN case_clause ESAC
553                         { $$ = make_case_command ($2, $5); }
554         ;
555
556 function_def:   WORD '(' ')' newline_list group_command
557                         { $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
558
559
560         |       FUNCTION WORD '(' ')' newline_list group_command
561                         { $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
562
563         |       FUNCTION WORD newline_list group_command
564                         { $$ = make_function_def ($2, $4, function_dstart, function_bstart); }
565         ;
566
567 subshell:       '(' compound_list ')'
568                         { $2->flags |= CMD_WANT_SUBSHELL; $$ = $2; }
569         ;
570
571 if_command:     IF compound_list THEN compound_list FI
572                         { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
573         |       IF compound_list THEN compound_list ELSE compound_list FI
574                         { $$ = make_if_command ($2, $4, $6); }
575         |       IF compound_list THEN compound_list elif_clause FI
576                         { $$ = make_if_command ($2, $4, $5); }
577         ;
578
579
580 group_command:  '{' list '}'
581                         { $$ = make_group_command ($2); }
582         ;
583
584 arith_command:  ARITH_CMD
585                         { $$ = make_arith_command ($1); }
586         ;
587
588 cond_command:   COND_START COND_CMD COND_END
589                         { $$ = $2; }
590         ; 
591
592 elif_clause:    ELIF compound_list THEN compound_list
593                         { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
594         |       ELIF compound_list THEN compound_list ELSE compound_list
595                         { $$ = make_if_command ($2, $4, $6); }
596         |       ELIF compound_list THEN compound_list elif_clause
597                         { $$ = make_if_command ($2, $4, $5); }
598         ;
599
600 case_clause:    pattern_list
601         |       case_clause_sequence pattern_list
602                         { $2->next = $1; $$ = $2; }
603         ;
604
605 pattern_list:   newline_list pattern ')' compound_list
606                         { $$ = make_pattern_list ($2, $4); }
607         |       newline_list pattern ')' newline_list
608                         { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
609         |       newline_list '(' pattern ')' compound_list
610                         { $$ = make_pattern_list ($3, $5); }
611         |       newline_list '(' pattern ')' newline_list
612                         { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
613         ;
614
615 case_clause_sequence:  pattern_list SEMI_SEMI
616         |       case_clause_sequence pattern_list SEMI_SEMI
617                         { $2->next = $1; $$ = $2; }
618         ;
619
620 pattern:        WORD
621                         { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
622         |       pattern '|' WORD
623                         { $$ = make_word_list ($3, $1); }
624         ;
625
626 /* A list allows leading or trailing newlines and
627    newlines as operators (equivalent to semicolons).
628    It must end with a newline or semicolon.
629    Lists are used within commands such as if, for, while.  */
630
631 list:           newline_list list0
632                         {
633                           $$ = $2;
634                           if (need_here_doc)
635                             gather_here_documents ();
636                          }
637         ;
638
639 compound_list:  list
640         |       newline_list list1
641                         {
642                           $$ = $2;
643                         }
644         ;
645
646 list0:          list1 '\n' newline_list
647         |       list1 '&' newline_list
648                         {
649                           if ($1->type == cm_connection)
650                             $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
651                           else
652                             $$ = command_connect ($1, (COMMAND *)NULL, '&');
653                         }
654         |       list1 ';' newline_list
655
656         ;
657
658 list1:          list1 AND_AND newline_list list1
659                         { $$ = command_connect ($1, $4, AND_AND); }
660         |       list1 OR_OR newline_list list1
661                         { $$ = command_connect ($1, $4, OR_OR); }
662         |       list1 '&' newline_list list1
663                         {
664                           if ($1->type == cm_connection)
665                             $$ = connect_async_list ($1, $4, '&');
666                           else
667                             $$ = command_connect ($1, $4, '&');
668                         }
669         |       list1 ';' newline_list list1
670                         { $$ = command_connect ($1, $4, ';'); }
671         |       list1 '\n' newline_list list1
672                         { $$ = command_connect ($1, $4, ';'); }
673         |       pipeline_command
674                         { $$ = $1; }
675         ;
676
677 list_terminator:'\n'
678         |       ';'
679         |       yacc_EOF
680         ;
681
682 newline_list:
683         |       newline_list '\n'
684         ;
685
686 /* A simple_list is a list that contains no significant newlines
687    and no leading or trailing newlines.  Newlines are allowed
688    only following operators, where they are not significant.
689
690    This is what an inputunit consists of.  */
691
692 simple_list:    simple_list1
693                         {
694                           $$ = $1;
695                           if (need_here_doc)
696                             gather_here_documents ();
697                         }
698         |       simple_list1 '&'
699                         {
700                           if ($1->type == cm_connection)
701                             $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
702                           else
703                             $$ = command_connect ($1, (COMMAND *)NULL, '&');
704                           if (need_here_doc)
705                             gather_here_documents ();
706                         }
707         |       simple_list1 ';'
708                         {
709                           $$ = $1;
710                           if (need_here_doc)
711                             gather_here_documents ();
712                         }
713         ;
714
715 simple_list1:   simple_list1 AND_AND newline_list simple_list1
716                         { $$ = command_connect ($1, $4, AND_AND); }
717         |       simple_list1 OR_OR newline_list simple_list1
718                         { $$ = command_connect ($1, $4, OR_OR); }
719         |       simple_list1 '&' simple_list1
720                         {
721                           if ($1->type == cm_connection)
722                             $$ = connect_async_list ($1, $3, '&');
723                           else
724                             $$ = command_connect ($1, $3, '&');
725                         }
726         |       simple_list1 ';' simple_list1
727                         { $$ = command_connect ($1, $3, ';'); }
728
729         |       pipeline_command
730                         { $$ = $1; }
731         ;
732
733 pipeline_command: pipeline
734                         { $$ = $1; }
735         |       BANG pipeline
736                         {
737                           $2->flags |= CMD_INVERT_RETURN;
738                           $$ = $2;
739                         }
740         |       timespec pipeline
741                         {
742                           $2->flags |= $1;
743                           $$ = $2;
744                         }
745         |       timespec BANG pipeline
746                         {
747                           $3->flags |= $1;
748                           $$ = $3;
749                         }
750         |       BANG timespec pipeline
751                         {
752                           $3->flags |= $2|CMD_INVERT_RETURN;
753                           $$ = $3;
754                         }
755         ;
756
757 pipeline:
758                 pipeline '|' newline_list pipeline
759                         { $$ = command_connect ($1, $4, '|'); }
760         |       command
761                         { $$ = $1; }
762         ;
763
764 timespec:       TIME
765                         { $$ = CMD_TIME_PIPELINE; }
766         |       TIME TIMEOPT
767                         { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
768         ;
769 %%
770
771 /* Possible states for the parser that require it to do special things. */
772 #define PST_CASEPAT     0x001           /* in a case pattern list */
773 #define PST_ALEXPNEXT   0x002           /* expand next word for aliases */
774 #define PST_ALLOWOPNBRC 0x004           /* allow open brace for function def */
775 #define PST_NEEDCLOSBRC 0x008           /* need close brace */
776 #define PST_DBLPAREN    0x010           /* double-paren parsing */
777 #define PST_SUBSHELL    0x020           /* ( ... ) subshell */
778 #define PST_CMDSUBST    0x040           /* $( ... ) command substitution */
779 #define PST_CASESTMT    0x080           /* parsing a case statement */
780 #define PST_CONDCMD     0x100           /* parsing a [[...]] command */
781 #define PST_CONDEXPR    0x200           /* parsing the guts of [[...]] */
782
783 /* Initial size to allocate for tokens, and the
784    amount to grow them by. */
785 #define TOKEN_DEFAULT_INITIAL_SIZE 496
786 #define TOKEN_DEFAULT_GROW_SIZE 512
787
788 /* Shell meta-characters that, when unquoted, separate words. */
789 #define shellmeta(c)    (strchr (shell_meta_chars, (c)) != 0)
790 #define shellbreak(c)   (strchr (shell_break_chars, (c)) != 0)
791 #define shellquote(c)   ((c) == '"' || (c) == '`' || (c) == '\'')
792 #define shellexp(c)     ((c) == '$' || (c) == '<' || (c) == '>')
793
794 char *shell_meta_chars = "()<>;&|";
795 char *shell_break_chars = "()<>;&| \t\n";
796
797 /* The token currently being read. */
798 static int current_token;
799
800 /* The last read token, or NULL.  read_token () uses this for context
801    checking. */
802 static int last_read_token;
803
804 /* The token read prior to last_read_token. */
805 static int token_before_that;
806
807 /* The token read prior to token_before_that. */
808 static int two_tokens_ago;
809
810 /* If non-zero, it is the token that we want read_token to return
811    regardless of what text is (or isn't) present to be read.  This
812    is reset by read_token.  If token_to_read == WORD or
813    ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
814 static int token_to_read;
815 static WORD_DESC *word_desc_to_read;
816
817 /* The current parser state. */
818 static int parser_state;
819
820 /* Global var is non-zero when end of file has been reached. */
821 int EOF_Reached = 0;
822
823 void
824 debug_parser (i)
825      int i;
826 {
827 #if YYDEBUG != 0
828   yydebug = i;
829 #endif
830 }
831
832 /* yy_getc () returns the next available character from input or EOF.
833    yy_ungetc (c) makes `c' the next character to read.
834    init_yy_io (get, unget, type, location) makes the function GET the
835    installed function for getting the next character, makes UNGET the
836    installed function for un-getting a character, sets the type of stream
837    (either string or file) from TYPE, and makes LOCATION point to where
838    the input is coming from. */
839
840 /* Unconditionally returns end-of-file. */
841 int
842 return_EOF ()
843 {
844   return (EOF);
845 }
846
847 /* Variable containing the current get and unget functions.
848    See ./input.h for a clearer description. */
849 BASH_INPUT bash_input;
850
851 /* Set all of the fields in BASH_INPUT to NULL.  Free bash_input.name if it
852    is non-null, avoiding a memory leak. */
853 void
854 initialize_bash_input ()
855 {
856   bash_input.type = st_none;
857   FREE (bash_input.name);
858   bash_input.name = (char *)NULL;
859   bash_input.location.file = (FILE *)NULL;
860   bash_input.location.string = (char *)NULL;
861   bash_input.getter = (Function *)NULL;
862   bash_input.ungetter = (Function *)NULL;
863 }
864
865 /* Set the contents of the current bash input stream from
866    GET, UNGET, TYPE, NAME, and LOCATION. */
867 void
868 init_yy_io (get, unget, type, name, location)
869      Function *get, *unget;
870      enum stream_type type;
871      char *name;
872      INPUT_STREAM location;
873 {
874   bash_input.type = type;
875   FREE (bash_input.name);
876   bash_input.name = name ? savestring (name) : (char *)NULL;
877
878   /* XXX */
879 #if defined (CRAY)
880   memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
881 #else
882   bash_input.location = location;
883 #endif
884   bash_input.getter = get;
885   bash_input.ungetter = unget;
886 }
887
888 /* Call this to get the next character of input. */
889 int
890 yy_getc ()
891 {
892   return (*(bash_input.getter)) ();
893 }
894
895 /* Call this to unget C.  That is, to make C the next character
896    to be read. */
897 int
898 yy_ungetc (c)
899      int c;
900 {
901   return (*(bash_input.ungetter)) (c);
902 }
903
904 #if defined (BUFFERED_INPUT)
905 int
906 input_file_descriptor ()
907 {
908   switch (bash_input.type)
909     {
910     case st_stream:
911       return (fileno (bash_input.location.file));
912     case st_bstream:
913       return (bash_input.location.buffered_fd);
914     case st_stdin:
915     default:
916       return (fileno (stdin));
917     }
918 }
919 #endif /* BUFFERED_INPUT */
920
921 /* **************************************************************** */
922 /*                                                                  */
923 /*                Let input be read from readline ().               */
924 /*                                                                  */
925 /* **************************************************************** */
926
927 #if defined (READLINE)
928 char *current_readline_prompt = (char *)NULL;
929 char *current_readline_line = (char *)NULL;
930 int current_readline_line_index = 0;
931
932 static int
933 yy_readline_get ()
934 {
935   SigHandler *old_sigint;
936   int line_len, c;
937
938   if (!current_readline_line)
939     {
940       if (!bash_readline_initialized)
941         initialize_readline ();
942
943 #if defined (JOB_CONTROL)
944       if (job_control)
945         give_terminal_to (shell_pgrp);
946 #endif /* JOB_CONTROL */
947
948       if (signal_is_ignored (SIGINT) == 0)
949         {
950           old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
951           interrupt_immediately++;
952         }
953
954       current_readline_line = readline (current_readline_prompt ?
955                                           current_readline_prompt : "");
956
957       if (signal_is_ignored (SIGINT) == 0)
958         {
959           interrupt_immediately--;
960           set_signal_handler (SIGINT, old_sigint);
961         }
962
963 #if 0
964       /* Reset the prompt to the decoded value of prompt_string_pointer. */
965       reset_readline_prompt ();
966 #endif
967
968       if (current_readline_line == 0)
969         return (EOF);
970
971       current_readline_line_index = 0;
972       line_len = strlen (current_readline_line);
973
974       current_readline_line = xrealloc (current_readline_line, 2 + line_len);
975       current_readline_line[line_len++] = '\n';
976       current_readline_line[line_len] = '\0';
977     }
978
979   if (current_readline_line[current_readline_line_index] == 0)
980     {
981       free (current_readline_line);
982       current_readline_line = (char *)NULL;
983       return (yy_readline_get ());
984     }
985   else
986     {
987       c = (unsigned char)current_readline_line[current_readline_line_index++];
988       return (c);
989     }
990 }
991
992 static int
993 yy_readline_unget (c)
994      int c;
995 {
996   if (current_readline_line_index && current_readline_line)
997     current_readline_line[--current_readline_line_index] = c;
998   return (c);
999 }
1000
1001 void
1002 with_input_from_stdin ()
1003 {
1004   INPUT_STREAM location;
1005
1006   if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
1007     {
1008       location.string = current_readline_line;
1009       init_yy_io (yy_readline_get, yy_readline_unget,
1010                   st_stdin, "readline stdin", location);
1011     }
1012 }
1013
1014 #else  /* !READLINE */
1015
1016 void
1017 with_input_from_stdin ()
1018 {
1019   with_input_from_stream (stdin, "stdin");
1020 }
1021 #endif  /* !READLINE */
1022
1023 /* **************************************************************** */
1024 /*                                                                  */
1025 /*   Let input come from STRING.  STRING is zero terminated.        */
1026 /*                                                                  */
1027 /* **************************************************************** */
1028
1029 static int
1030 yy_string_get ()
1031 {
1032   register char *string;
1033   register int c;
1034
1035   string = bash_input.location.string;
1036   c = EOF;
1037
1038   /* If the string doesn't exist, or is empty, EOF found. */
1039   if (string && *string)
1040     {
1041       c = *(unsigned char *)string++;
1042       bash_input.location.string = string;
1043     }
1044   return (c);
1045 }
1046
1047 static int
1048 yy_string_unget (c)
1049      int c;
1050 {
1051   *(--bash_input.location.string) = c;
1052   return (c);
1053 }
1054
1055 void
1056 with_input_from_string (string, name)
1057      char *string, *name;
1058 {
1059   INPUT_STREAM location;
1060
1061   location.string = string;
1062   init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1063 }
1064
1065 /* **************************************************************** */
1066 /*                                                                  */
1067 /*                   Let input come from STREAM.                    */
1068 /*                                                                  */
1069 /* **************************************************************** */
1070
1071 static int
1072 yy_stream_get ()
1073 {
1074   int result = EOF;
1075
1076   if (bash_input.location.file)
1077     {
1078 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
1079       result = getc_with_restart (bash_input.location.file);
1080 #else /* HAVE_RESTARTABLE_SYSCALLS */
1081       result = getc (bash_input.location.file);
1082       result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
1083 #endif /* HAVE_RESTARTABLE_SYSCALLS */
1084     }
1085   return (result);
1086 }
1087
1088 static int
1089 yy_stream_unget (c)
1090      int c;
1091 {
1092 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
1093   return (ungetc_with_restart (c, bash_input.location.file));
1094 #else /* HAVE_RESTARTABLE_SYSCALLS */
1095   return (ungetc (c, bash_input.location.file));
1096 #endif /* HAVE_RESTARTABLE_SYSCALLS */
1097 }
1098
1099 void
1100 with_input_from_stream (stream, name)
1101      FILE *stream;
1102      char *name;
1103 {
1104   INPUT_STREAM location;
1105
1106   location.file = stream;
1107   init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1108 }
1109
1110 typedef struct stream_saver {
1111   struct stream_saver *next;
1112   BASH_INPUT bash_input;
1113   int line;
1114 #if defined (BUFFERED_INPUT)
1115   BUFFERED_STREAM *bstream;
1116 #endif /* BUFFERED_INPUT */
1117 } STREAM_SAVER;
1118
1119 /* The globally known line number. */
1120 int line_number = 0;
1121
1122 #if defined (COND_COMMAND)
1123 static int cond_lineno;
1124 static int cond_token;
1125 #endif
1126
1127 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1128
1129 void
1130 push_stream (reset_lineno)
1131      int reset_lineno;
1132 {
1133   STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1134
1135   xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1136
1137 #if defined (BUFFERED_INPUT)
1138   saver->bstream = (BUFFERED_STREAM *)NULL;
1139   /* If we have a buffered stream, clear out buffers[fd]. */
1140   if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1141     saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1142                                           (BUFFERED_STREAM *)NULL);
1143 #endif /* BUFFERED_INPUT */
1144
1145   saver->line = line_number;
1146   bash_input.name = (char *)NULL;
1147   saver->next = stream_list;
1148   stream_list = saver;
1149   EOF_Reached = 0;
1150   if (reset_lineno)
1151     line_number = 0;
1152 }
1153
1154 void
1155 pop_stream ()
1156 {
1157   if (!stream_list)
1158     EOF_Reached = 1;
1159   else
1160     {
1161       STREAM_SAVER *saver = stream_list;
1162
1163       EOF_Reached = 0;
1164       stream_list = stream_list->next;
1165
1166       init_yy_io (saver->bash_input.getter,
1167                   saver->bash_input.ungetter,
1168                   saver->bash_input.type,
1169                   saver->bash_input.name,
1170                   saver->bash_input.location);
1171
1172 #if defined (BUFFERED_INPUT)
1173       /* If we have a buffered stream, restore buffers[fd]. */
1174       /* If the input file descriptor was changed while this was on the
1175          save stack, update the buffered fd to the new file descriptor and
1176          re-establish the buffer <-> bash_input fd correspondence. */
1177       if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1178         {
1179           if (bash_input_fd_changed)
1180             {
1181               bash_input_fd_changed = 0;
1182               if (default_buffered_input >= 0)
1183                 {
1184                   bash_input.location.buffered_fd = default_buffered_input;
1185                   saver->bstream->b_fd = default_buffered_input;
1186                 }
1187             }
1188           set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
1189         }
1190 #endif /* BUFFERED_INPUT */
1191
1192       line_number = saver->line;
1193
1194       FREE (saver->bash_input.name);
1195       free (saver);
1196     }
1197 }
1198
1199 /* Return 1 if a stream of type TYPE is saved on the stack. */
1200 int
1201 stream_on_stack (type)
1202      enum stream_type type;
1203 {
1204   register STREAM_SAVER *s;
1205
1206   for (s = stream_list; s; s = s->next)
1207     if (s->bash_input.type == type)
1208       return 1;
1209   return 0;
1210 }
1211
1212 /*
1213  * This is used to inhibit alias expansion and reserved word recognition
1214  * inside case statement pattern lists.  A `case statement pattern list' is:
1215  *
1216  *      everything between the `in' in a `case word in' and the next ')'
1217  *      or `esac'
1218  *      everything between a `;;' and the next `)' or `esac'
1219  */
1220
1221 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1222
1223 #if !defined (ALIAS)
1224 typedef void *alias_t;
1225 #endif
1226
1227 #define END_OF_ALIAS 0
1228
1229 /*
1230  * Pseudo-global variables used in implementing token-wise alias expansion.
1231  */
1232
1233 /*
1234  * Pushing and popping strings.  This works together with shell_getc to
1235  * implement alias expansion on a per-token basis.
1236  */
1237
1238 typedef struct string_saver {
1239   struct string_saver *next;
1240   int expand_alias;  /* Value to set expand_alias to when string is popped. */
1241   char *saved_line;
1242 #if defined (ALIAS)
1243   alias_t *expander;   /* alias that caused this line to be pushed. */
1244 #endif
1245   int saved_line_size, saved_line_index, saved_line_terminator;
1246 } STRING_SAVER;
1247
1248 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1249
1250 /*
1251  * Push the current shell_input_line onto a stack of such lines and make S
1252  * the current input.  Used when expanding aliases.  EXPAND is used to set
1253  * the value of expand_next_token when the string is popped, so that the
1254  * word after the alias in the original line is handled correctly when the
1255  * alias expands to multiple words.  TOKEN is the token that was expanded
1256  * into S; it is saved and used to prevent infinite recursive expansion.
1257  */
1258 static void
1259 push_string (s, expand, ap)
1260      char *s;
1261      int expand;
1262      alias_t *ap;
1263 {
1264   STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
1265
1266   temp->expand_alias = expand;
1267   temp->saved_line = shell_input_line;
1268   temp->saved_line_size = shell_input_line_size;
1269   temp->saved_line_index = shell_input_line_index;
1270   temp->saved_line_terminator = shell_input_line_terminator;
1271 #if defined (ALIAS)
1272   temp->expander = ap;
1273 #endif
1274   temp->next = pushed_string_list;
1275   pushed_string_list = temp;
1276
1277 #if defined (ALIAS)
1278   if (ap)
1279     ap->flags |= AL_BEINGEXPANDED;
1280 #endif
1281
1282   shell_input_line = s;
1283   shell_input_line_size = strlen (s);
1284   shell_input_line_index = 0;
1285   shell_input_line_terminator = '\0';
1286   parser_state &= ~PST_ALEXPNEXT;
1287 }
1288
1289 /*
1290  * Make the top of the pushed_string stack be the current shell input.
1291  * Only called when there is something on the stack.  Called from shell_getc
1292  * when it thinks it has consumed the string generated by an alias expansion
1293  * and needs to return to the original input line.
1294  */
1295 static void
1296 pop_string ()
1297 {
1298   STRING_SAVER *t;
1299
1300   FREE (shell_input_line);
1301   shell_input_line = pushed_string_list->saved_line;
1302   shell_input_line_index = pushed_string_list->saved_line_index;
1303   shell_input_line_size = pushed_string_list->saved_line_size;
1304   shell_input_line_terminator = pushed_string_list->saved_line_terminator;
1305
1306   if (pushed_string_list->expand_alias)
1307     parser_state |= PST_ALEXPNEXT;
1308   else
1309     parser_state &= ~PST_ALEXPNEXT;
1310
1311   t = pushed_string_list;
1312   pushed_string_list = pushed_string_list->next;
1313
1314 #if defined (ALIAS)
1315   if (t->expander)
1316     t->expander->flags &= ~AL_BEINGEXPANDED;
1317 #endif
1318
1319   free ((char *)t);
1320 }
1321
1322 static void
1323 free_string_list ()
1324 {
1325   register STRING_SAVER *t, *t1;
1326
1327   for (t = pushed_string_list; t; )
1328     {
1329       t1 = t->next;
1330       FREE (t->saved_line);
1331 #if defined (ALIAS)
1332       if (t->expander)
1333         t->expander->flags &= ~AL_BEINGEXPANDED;
1334 #endif
1335       free ((char *)t);
1336       t = t1;
1337     }
1338   pushed_string_list = (STRING_SAVER *)NULL;
1339 }
1340
1341 #endif /* ALIAS || DPAREN_ARITHMETIC */
1342
1343 /* Return a line of text, taken from wherever yylex () reads input.
1344    If there is no more input, then we return NULL.  If REMOVE_QUOTED_NEWLINE
1345    is non-zero, we remove unquoted \<newline> pairs.  This is used by
1346    read_secondary_line to read here documents. */
1347 static char *
1348 read_a_line (remove_quoted_newline)
1349      int remove_quoted_newline;
1350 {
1351   static char *line_buffer = (char *)NULL;
1352   static int buffer_size = 0;
1353   int indx = 0, c, peekc, pass_next;
1354
1355 #if defined (READLINE)
1356   if (interactive && bash_input.type != st_string && no_line_editing)
1357 #else
1358   if (interactive && bash_input.type != st_string)
1359 #endif
1360     print_prompt ();
1361
1362   pass_next = 0;
1363   while (1)
1364     {
1365       c = yy_getc ();
1366
1367       /* Allow immediate exit if interrupted during input. */
1368       QUIT;
1369
1370       if (c == 0)
1371         continue;
1372
1373       /* If there is no more input, then we return NULL. */
1374       if (c == EOF)
1375         {
1376           if (interactive && bash_input.type == st_stream)
1377             clearerr (stdin);
1378           if (indx == 0)
1379             return ((char *)NULL);
1380           c = '\n';
1381         }
1382
1383       /* `+2' in case the final character in the buffer is a newline. */
1384       RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
1385
1386       /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1387          here document with an unquoted delimiter.  In this case,
1388          the line will be expanded as if it were in double quotes.
1389          We allow a backslash to escape the next character, but we
1390          need to treat the backslash specially only if a backslash
1391          quoting a backslash-newline pair appears in the line. */
1392       if (pass_next)
1393         {
1394           line_buffer[indx++] = c;
1395           pass_next = 0;
1396         }
1397       else if (c == '\\' && remove_quoted_newline)
1398         {
1399           peekc = yy_getc ();
1400           if (peekc == '\n')
1401             continue;   /* Make the unquoted \<newline> pair disappear. */
1402           else
1403             {
1404               yy_ungetc (peekc);
1405               pass_next = 1;
1406               line_buffer[indx++] = c;          /* Preserve the backslash. */
1407             }
1408         }
1409       else
1410         line_buffer[indx++] = c;
1411
1412       if (c == '\n')
1413         {
1414           line_buffer[indx] = '\0';
1415           return (line_buffer);
1416         }
1417     }
1418 }
1419
1420 /* Return a line as in read_a_line (), but insure that the prompt is
1421    the secondary prompt.  This is used to read the lines of a here
1422    document.  REMOVE_QUOTED_NEWLINE is non-zero if we should remove
1423    newlines quoted with backslashes while reading the line.  It is
1424    non-zero unless the delimiter of the here document was quoted. */
1425 char *
1426 read_secondary_line (remove_quoted_newline)
1427      int remove_quoted_newline;
1428 {
1429   prompt_string_pointer = &ps2_prompt;
1430   prompt_again ();
1431   return (read_a_line (remove_quoted_newline));
1432 }
1433
1434 /* **************************************************************** */
1435 /*                                                                  */
1436 /*                              YYLEX ()                            */
1437 /*                                                                  */
1438 /* **************************************************************** */
1439
1440 /* Reserved words.  These are only recognized as the first word of a
1441    command. */
1442 STRING_INT_ALIST word_token_alist[] = {
1443   { "if", IF },
1444   { "then", THEN },
1445   { "else", ELSE },
1446   { "elif", ELIF },
1447   { "fi", FI },
1448   { "case", CASE },
1449   { "esac", ESAC },
1450   { "for", FOR },
1451 #if defined (SELECT_COMMAND)
1452   { "select", SELECT },
1453 #endif
1454   { "while", WHILE },
1455   { "until", UNTIL },
1456   { "do", DO },
1457   { "done", DONE },
1458   { "in", IN },
1459   { "function", FUNCTION },
1460 #if defined (COMMAND_TIMING)
1461   { "time", TIME },
1462 #endif
1463   { "{", '{' },
1464   { "}", '}' },
1465   { "!", BANG },
1466 #if defined (COND_COMMAND)
1467   { "[[", COND_START },
1468   { "]]", COND_END },
1469 #endif
1470   { (char *)NULL, 0}
1471 };
1472
1473 /* XXX - we should also have an alist with strings for other tokens, so we
1474          can give more descriptive error messages.  Look at y.tab.h for the
1475          other tokens. */
1476
1477 /* These are used by read_token_word, but appear up here so that shell_getc
1478    can use them to decide when to add otherwise blank lines to the history. */
1479
1480 /* The primary delimiter stack. */
1481 struct dstack dstack = {  (char *)NULL, 0, 0 };
1482
1483 /* A temporary delimiter stack to be used when decoding prompt strings.
1484    This is needed because command substitutions in prompt strings (e.g., PS2)
1485    can screw up the parser's quoting state. */
1486 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
1487
1488 /* Macro for accessing the top delimiter on the stack.  Returns the
1489    delimiter or zero if none. */
1490 #define current_delimiter(ds) \
1491   (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
1492
1493 #define push_delimiter(ds, character) \
1494   do \
1495     { \
1496       if (ds.delimiter_depth + 2 > ds.delimiter_space) \
1497         ds.delimiters = xrealloc \
1498           (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
1499       ds.delimiters[ds.delimiter_depth] = character; \
1500       ds.delimiter_depth++; \
1501     } \
1502   while (0)
1503
1504 #define pop_delimiter(ds)       ds.delimiter_depth--
1505
1506 /* Return the next shell input character.  This always reads characters
1507    from shell_input_line; when that line is exhausted, it is time to
1508    read the next line.  This is called by read_token when the shell is
1509    processing normal command input. */
1510
1511 static int
1512 shell_getc (remove_quoted_newline)
1513      int remove_quoted_newline;
1514 {
1515   register int i;
1516   int c;
1517   static int mustpop = 0;
1518
1519   QUIT;
1520
1521 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1522   /* If shell_input_line[shell_input_line_index] == 0, but there is
1523      something on the pushed list of strings, then we don't want to go
1524      off and get another line.  We let the code down below handle it. */
1525
1526   if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
1527                             (pushed_string_list == (STRING_SAVER *)NULL)))
1528 #else /* !ALIAS && !DPAREN_ARITHMETIC */
1529   if (!shell_input_line || !shell_input_line[shell_input_line_index])
1530 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
1531     {
1532       line_number++;
1533
1534     restart_read:
1535
1536       /* Allow immediate exit if interrupted during input. */
1537       QUIT;
1538
1539       i = 0;
1540       shell_input_line_terminator = 0;
1541
1542 #if defined (JOB_CONTROL)
1543       /* This can cause a problem when reading a command as the result
1544          of a trap, when the trap is called from flush_child.  This call
1545          had better not cause jobs to disappear from the job table in
1546          that case, or we will have big trouble. */
1547       notify_and_cleanup ();
1548 #else /* !JOB_CONTROL */
1549       cleanup_dead_jobs ();
1550 #endif /* !JOB_CONTROL */
1551
1552 #if defined (READLINE)
1553       if (interactive && bash_input.type != st_string && no_line_editing)
1554 #else
1555       if (interactive && bash_input.type != st_string)
1556 #endif
1557         print_prompt ();
1558
1559       if (bash_input.type == st_stream)
1560         clearerr (stdin);
1561
1562       while (c = yy_getc ())
1563         {
1564           /* Allow immediate exit if interrupted during input. */
1565           QUIT;
1566
1567           RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
1568
1569           if (c == EOF)
1570             {
1571               if (bash_input.type == st_stream)
1572                 clearerr (stdin);
1573
1574               if (i == 0)
1575                 shell_input_line_terminator = EOF;
1576
1577               shell_input_line[i] = '\0';
1578               break;
1579             }
1580
1581           shell_input_line[i++] = c;
1582
1583           if (c == '\n')
1584             {
1585               shell_input_line[--i] = '\0';
1586               current_command_line_count++;
1587               break;
1588             }
1589         }
1590       shell_input_line_index = 0;
1591       shell_input_line_len = i;         /* == strlen (shell_input_line) */
1592
1593 #if defined (HISTORY)
1594       if (remember_on_history && shell_input_line && shell_input_line[0])
1595         {
1596           char *expansions;
1597 #  if defined (BANG_HISTORY)
1598           int old_hist;
1599
1600           /* If the current delimiter is a single quote, we should not be
1601              performing history expansion, even if we're on a different
1602              line from the original single quote. */
1603           old_hist = history_expansion_inhibited;
1604           if (current_delimiter (dstack) == '\'')
1605             history_expansion_inhibited = 1;
1606 #  endif
1607           expansions = pre_process_line (shell_input_line, 1, 1);
1608 #  if defined (BANG_HISTORY)
1609           history_expansion_inhibited = old_hist;
1610 #  endif
1611           if (expansions != shell_input_line)
1612             {
1613               free (shell_input_line);
1614               shell_input_line = expansions;
1615               shell_input_line_len = shell_input_line ?
1616                                         strlen (shell_input_line) : 0;
1617               if (!shell_input_line_len)
1618                 current_command_line_count--;
1619
1620               /* We have to force the xrealloc below because we don't know
1621                  the true allocated size of shell_input_line anymore. */
1622               shell_input_line_size = shell_input_line_len;
1623             }
1624         }
1625       /* XXX - this is grotesque */
1626       else if (remember_on_history && shell_input_line &&
1627                shell_input_line[0] == '\0' &&
1628                current_command_line_count > 1 && current_delimiter (dstack))
1629         {
1630           /* We know shell_input_line[0] == 0 and we're reading some sort of
1631              quoted string.  This means we've got a line consisting of only
1632              a newline in a quoted string.  We want to make sure this line
1633              gets added to the history. */
1634           maybe_add_history (shell_input_line);
1635         }
1636
1637 #endif /* HISTORY */
1638
1639       if (shell_input_line)
1640         {
1641           /* Lines that signify the end of the shell's input should not be
1642              echoed. */
1643           if (echo_input_at_read && (shell_input_line[0] ||
1644                                      shell_input_line_terminator != EOF))
1645             fprintf (stderr, "%s\n", shell_input_line);
1646         }
1647       else
1648         {
1649           shell_input_line_size = 0;
1650           prompt_string_pointer = &current_prompt_string;
1651           prompt_again ();
1652           goto restart_read;
1653         }
1654
1655       /* Add the newline to the end of this string, iff the string does
1656          not already end in an EOF character.  */
1657       if (shell_input_line_terminator != EOF)
1658         {
1659           if (shell_input_line_len + 3 > shell_input_line_size)
1660             shell_input_line = xrealloc (shell_input_line,
1661                                         1 + (shell_input_line_size += 2));
1662
1663           shell_input_line[shell_input_line_len] = '\n';
1664           shell_input_line[shell_input_line_len + 1] = '\0';
1665         }
1666     }
1667
1668   c = shell_input_line[shell_input_line_index];
1669
1670   if (c)
1671     shell_input_line_index++;
1672
1673   if (c == '\\' && remove_quoted_newline &&
1674       shell_input_line[shell_input_line_index] == '\n')
1675     {
1676         prompt_again ();
1677         line_number++;
1678         goto restart_read;
1679     }
1680
1681 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1682   /* If C is NULL, we have reached the end of the current input string.  If
1683      pushed_string_list is non-empty, it's time to pop to the previous string
1684      because we have fully consumed the result of the last alias expansion.
1685      Do it transparently; just return the next character of the string popped
1686      to. */
1687   if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
1688     {
1689       if (mustpop)
1690         {
1691           pop_string ();
1692           c = shell_input_line[shell_input_line_index];
1693           if (c)
1694             shell_input_line_index++;
1695           mustpop--;
1696         }
1697       else
1698         {
1699           mustpop++;
1700           c = ' ';
1701         }
1702     }
1703 #endif /* ALIAS || DPAREN_ARITHMETIC */
1704
1705   if (!c && shell_input_line_terminator == EOF)
1706     return ((shell_input_line_index != 0) ? '\n' : EOF);
1707
1708   return ((unsigned char)c);
1709 }
1710
1711 /* Put C back into the input for the shell. */
1712 static void
1713 shell_ungetc (c)
1714      int c;
1715 {
1716   if (shell_input_line && shell_input_line_index)
1717     shell_input_line[--shell_input_line_index] = c;
1718 }
1719
1720 static void
1721 shell_ungetchar ()
1722 {
1723   if (shell_input_line && shell_input_line_index)
1724     shell_input_line_index--;
1725 }
1726
1727 /* Discard input until CHARACTER is seen, then push that character back
1728    onto the input stream. */
1729 static void
1730 discard_until (character)
1731      int character;
1732 {
1733   int c;
1734
1735   while ((c = shell_getc (0)) != EOF && c != character)
1736     ;
1737
1738   if (c != EOF)
1739     shell_ungetc (c);
1740 }
1741
1742 void
1743 execute_prompt_command (command)
1744      char *command;
1745 {
1746   Function *temp_last, *temp_this;
1747   char *last_lastarg;
1748   int temp_exit_value, temp_eof_encountered;
1749
1750   temp_last = last_shell_builtin;
1751   temp_this = this_shell_builtin;
1752   temp_exit_value = last_command_exit_value;
1753   temp_eof_encountered = eof_encountered;
1754   last_lastarg = get_string_value ("_");
1755   if (last_lastarg)
1756     last_lastarg = savestring (last_lastarg);
1757
1758   parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
1759
1760   last_shell_builtin = temp_last;
1761   this_shell_builtin = temp_this;
1762   last_command_exit_value = temp_exit_value;
1763   eof_encountered = temp_eof_encountered;
1764
1765   bind_variable ("_", last_lastarg);
1766   FREE (last_lastarg);
1767
1768   if (token_to_read == '\n')    /* reset_parser was called */
1769     token_to_read = 0;
1770 }
1771
1772 /* Place to remember the token.  We try to keep the buffer
1773    at a reasonable size, but it can grow. */
1774 static char *token = (char *)NULL;
1775
1776 /* Current size of the token buffer. */
1777 static int token_buffer_size;
1778
1779 /* Command to read_token () explaining what we want it to do. */
1780 #define READ 0
1781 #define RESET 1
1782 #define prompt_is_ps1 \
1783       (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
1784
1785 /* Function for yyparse to call.  yylex keeps track of
1786    the last two tokens read, and calls read_token.  */
1787 static int
1788 yylex ()
1789 {
1790   if (interactive && (current_token == 0 || current_token == '\n'))
1791     {
1792       /* Before we print a prompt, we might have to check mailboxes.
1793          We do this only if it is time to do so. Notice that only here
1794          is the mail alarm reset; nothing takes place in check_mail ()
1795          except the checking of mail.  Please don't change this. */
1796       if (prompt_is_ps1 && time_to_check_mail ())
1797         {
1798           check_mail ();
1799           reset_mail_timer ();
1800         }
1801
1802       /* Avoid printing a prompt if we're not going to read anything, e.g.
1803          after resetting the parser with read_token (RESET). */
1804       if (token_to_read == 0 && interactive)
1805         prompt_again ();
1806     }
1807
1808   two_tokens_ago = token_before_that;
1809   token_before_that = last_read_token;
1810   last_read_token = current_token;
1811   current_token = read_token (READ);
1812   return (current_token);
1813 }
1814
1815 /* When non-zero, we have read the required tokens
1816    which allow ESAC to be the next one read. */
1817 static int esacs_needed_count;
1818
1819 void
1820 gather_here_documents ()
1821 {
1822   int r = 0;
1823   while (need_here_doc)
1824     {
1825       make_here_document (redir_stack[r++]);
1826       need_here_doc--;
1827     }
1828 }
1829
1830 /* When non-zero, an open-brace used to create a group is awaiting a close
1831    brace partner. */
1832 static int open_brace_count;
1833
1834 #define command_token_position(token) \
1835   (((token) == ASSIGNMENT_WORD) || \
1836    ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
1837
1838 #define assignment_acceptable(token) command_token_position(token) && \
1839                                         ((parser_state & PST_CASEPAT) == 0)
1840
1841 /* Check to see if TOKEN is a reserved word and return the token
1842    value if it is. */
1843 #define CHECK_FOR_RESERVED_WORD(tok) \
1844   do { \
1845     if (!dollar_present && !quoted && \
1846         reserved_word_acceptable (last_read_token)) \
1847       { \
1848         int i; \
1849         for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
1850           if (STREQ (tok, word_token_alist[i].word)) \
1851             { \
1852               if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
1853                 break; \
1854               if (word_token_alist[i].token == TIME) \
1855                 break; \
1856               if (word_token_alist[i].token == ESAC) \
1857                 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
1858               else if (word_token_alist[i].token == CASE) \
1859                 parser_state |= PST_CASESTMT; \
1860               else if (word_token_alist[i].token == COND_END) \
1861                 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
1862               else if (word_token_alist[i].token == COND_START) \
1863                 parser_state |= PST_CONDCMD; \
1864               else if (word_token_alist[i].token == '{') \
1865                 open_brace_count++; \
1866               else if (word_token_alist[i].token == '}' && open_brace_count) \
1867                 open_brace_count--; \
1868               return (word_token_alist[i].token); \
1869             } \
1870       } \
1871   } while (0)
1872
1873 #if defined (ALIAS)
1874
1875     /* OK, we have a token.  Let's try to alias expand it, if (and only if)
1876        it's eligible.
1877
1878        It is eligible for expansion if the shell is in interactive mode, and
1879        the token is unquoted and the last token read was a command
1880        separator (or expand_next_token is set), and we are currently
1881        processing an alias (pushed_string_list is non-empty) and this
1882        token is not the same as the current or any previously
1883        processed alias.
1884
1885        Special cases that disqualify:
1886          In a pattern list in a case statement (parser_state & PST_CASEPAT). */
1887 static int
1888 alias_expand_token (token)
1889      char *token;
1890 {
1891   char *expanded;
1892   alias_t *ap;
1893
1894   if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
1895         (parser_state & PST_CASEPAT) == 0)
1896     {
1897       ap = find_alias (token);
1898
1899       /* Currently expanding this token. */
1900       if (ap && (ap->flags & AL_BEINGEXPANDED))
1901         return (NO_EXPANSION);
1902
1903       expanded = ap ? savestring (ap->value) : (char *)NULL;
1904       if (expanded)
1905         {
1906           push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
1907           return (RE_READ_TOKEN);
1908         }
1909       else
1910         /* This is an eligible token that does not have an expansion. */
1911         return (NO_EXPANSION);
1912     }
1913   return (NO_EXPANSION);
1914 }
1915 #endif /* ALIAS */
1916
1917 static int
1918 time_command_acceptable ()
1919 {
1920 #if defined (COMMAND_TIMING)
1921   switch (last_read_token)
1922     {
1923     case 0:
1924     case ';':
1925     case '\n':
1926     case AND_AND:
1927     case OR_OR:
1928     case '&':
1929     case DO:
1930     case THEN:
1931     case ELSE:
1932     case '{':
1933     case '(':
1934       return 1;
1935     default:
1936       return 0;
1937     }
1938 #else
1939   return 0;
1940 #endif /* COMMAND_TIMING */
1941 }
1942
1943 /* Handle special cases of token recognition:
1944         IN is recognized if the last token was WORD and the token
1945         before that was FOR or CASE or SELECT.
1946
1947         DO is recognized if the last token was WORD and the token
1948         before that was FOR or SELECT.
1949
1950         ESAC is recognized if the last token caused `esacs_needed_count'
1951         to be set
1952
1953         `{' is recognized if the last token as WORD and the token
1954         before that was FUNCTION.
1955
1956         `}' is recognized if there is an unclosed `{' prsent.
1957
1958         `-p' is returned as TIMEOPT if the last read token was TIME.
1959
1960         ']]' is returned as COND_END if the parser is currently parsing
1961         a conditional expression ((parser_state & PST_CONDEXPR) != 0)
1962
1963         `time' is returned as TIME if and only if it is immediately
1964         preceded by one of `;', `\n', `||', `&&', or `&'.
1965 */
1966
1967 static int
1968 special_case_tokens (token)
1969      char *token;
1970 {
1971   if ((last_read_token == WORD) &&
1972 #if defined (SELECT_COMMAND)
1973       ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
1974 #else
1975       ((token_before_that == FOR) || (token_before_that == CASE)) &&
1976 #endif
1977       (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
1978     {
1979       if (token_before_that == CASE)
1980         {
1981           parser_state |= PST_CASEPAT;
1982           esacs_needed_count++;
1983         }
1984       return (IN);
1985     }
1986
1987   if (last_read_token == WORD &&
1988 #if defined (SELECT_COMMAND)
1989       (token_before_that == FOR || token_before_that == SELECT) &&
1990 #else
1991       (token_before_that == FOR) &&
1992 #endif
1993       (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
1994     return (DO);
1995
1996   /* Ditto for ESAC in the CASE case.
1997      Specifically, this handles "case word in esac", which is a legal
1998      construct, certainly because someone will pass an empty arg to the
1999      case construct, and we don't want it to barf.  Of course, we should
2000      insist that the case construct has at least one pattern in it, but
2001      the designers disagree. */
2002   if (esacs_needed_count)
2003     {
2004       esacs_needed_count--;
2005       if (STREQ (token, "esac"))
2006         {
2007           parser_state &= ~PST_CASEPAT;
2008           return (ESAC);
2009         }
2010     }
2011
2012   /* The start of a shell function definition. */
2013   if (parser_state & PST_ALLOWOPNBRC)
2014     {
2015       parser_state &= ~PST_ALLOWOPNBRC;
2016       if (token[0] == '{' && token[1] == '\0')          /* } */
2017         {
2018           open_brace_count++;
2019           function_bstart = line_number;
2020           return ('{');                                 /* } */
2021         }
2022     }
2023
2024   if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
2025     {
2026       open_brace_count--;               /* { */
2027       return ('}');
2028     }
2029
2030 #if defined (COMMAND_TIMING)
2031   /* Handle -p after `time'. */
2032   if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
2033     return (TIMEOPT);
2034 #endif
2035
2036 #if defined (COMMAND_TIMING)
2037   if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
2038     return (TIME);
2039 #endif /* COMMAND_TIMING */
2040
2041 #if defined (COND_COMMAND) /* [[ */
2042   if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
2043     return (COND_END);
2044 #endif
2045
2046   return (-1);
2047 }
2048
2049 /* Called from shell.c when Control-C is typed at top level.  Or
2050    by the error rule at top level. */
2051 void
2052 reset_parser ()
2053 {
2054   dstack.delimiter_depth = 0;   /* No delimiters found so far. */
2055   open_brace_count = 0;
2056
2057   parser_state = 0;
2058
2059 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2060   if (pushed_string_list)
2061     free_string_list ();
2062 #endif /* ALIAS || DPAREN_ARITHMETIC */
2063
2064   if (shell_input_line)
2065     {
2066       free (shell_input_line);
2067       shell_input_line = (char *)NULL;
2068       shell_input_line_size = shell_input_line_index = 0;
2069     }
2070
2071   FREE (word_desc_to_read);
2072   word_desc_to_read = (WORD_DESC *)NULL;
2073
2074   last_read_token = '\n';
2075   token_to_read = '\n';
2076 }
2077
2078 /* Read the next token.  Command can be READ (normal operation) or
2079    RESET (to normalize state). */
2080 static int
2081 read_token (command)
2082      int command;
2083 {
2084   int character;                /* Current character. */
2085   int peek_char;                /* Temporary look-ahead character. */
2086   int result;                   /* The thing to return. */
2087
2088   if (command == RESET)
2089     {
2090       reset_parser ();
2091       return ('\n');
2092     }
2093
2094   if (token_to_read)
2095     {
2096       result = token_to_read;
2097       if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
2098         {
2099           yylval.word = word_desc_to_read;
2100           word_desc_to_read = (WORD_DESC *)NULL;
2101         }
2102       token_to_read = 0;
2103       return (result);
2104     }
2105
2106 #if defined (COND_COMMAND)
2107   if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2108     {
2109       cond_lineno = line_number;
2110       parser_state |= PST_CONDEXPR;
2111       yylval.command = parse_cond_command ();
2112       if (cond_token != COND_END)
2113         {
2114           if (EOF_Reached && cond_token != COND_ERROR)          /* [[ */
2115             parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
2116           else if (cond_token != COND_ERROR)
2117             parser_error (cond_lineno, "syntax error in conditional expression");
2118           return (-1);
2119         }
2120       token_to_read = COND_END;
2121       parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2122       return (COND_CMD);
2123     }
2124 #endif
2125
2126 #if defined (ALIAS)
2127   /* This is a place to jump back to once we have successfully expanded a
2128      token with an alias and pushed the string with push_string () */
2129  re_read_token:
2130 #endif /* ALIAS */
2131
2132   /* Read a single word from input.  Start by skipping blanks. */
2133   while ((character = shell_getc (1)) != EOF && whitespace (character))
2134     ;
2135
2136   if (character == EOF)
2137     {
2138       EOF_Reached = 1;
2139       return (yacc_EOF);
2140     }
2141
2142   if (character == '#' && (!interactive || interactive_comments))
2143     {
2144       /* A comment.  Discard until EOL or EOF, and then return a newline. */
2145       discard_until ('\n');
2146       shell_getc (0);
2147       character = '\n'; /* this will take the next if statement and return. */
2148     }
2149
2150   if (character == '\n')
2151     {
2152       /* If we're about to return an unquoted newline, we can go and collect
2153          the text of any pending here document. */
2154       if (need_here_doc)
2155         gather_here_documents ();
2156
2157 #if defined (ALIAS)
2158       parser_state &= ~PST_ALEXPNEXT;
2159 #endif /* ALIAS */
2160
2161       return (character);
2162     }
2163
2164   /* Shell meta-characters. */
2165   if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
2166     {
2167 #if defined (ALIAS)
2168       /* Turn off alias tokenization iff this character sequence would
2169          not leave us ready to read a command. */
2170       if (character == '<' || character == '>')
2171         parser_state &= ~PST_ALEXPNEXT;
2172 #endif /* ALIAS */
2173
2174       peek_char = shell_getc (1);
2175       if (character == peek_char)
2176         {
2177           switch (character)
2178             {
2179             case '<':
2180               /* If '<' then we could be at "<<" or at "<<-".  We have to
2181                  look ahead one more character. */
2182               peek_char = shell_getc (1);
2183               if (peek_char == '-')
2184                 return (LESS_LESS_MINUS);
2185               else
2186                 {
2187                   shell_ungetc (peek_char);
2188                   return (LESS_LESS);
2189                 }
2190
2191             case '>':
2192               return (GREATER_GREATER);
2193
2194             case ';':
2195               parser_state |= PST_CASEPAT;
2196 #if defined (ALIAS)
2197               parser_state &= ~PST_ALEXPNEXT;
2198 #endif /* ALIAS */
2199               return (SEMI_SEMI);
2200
2201             case '&':
2202               return (AND_AND);
2203
2204             case '|':
2205               return (OR_OR);
2206
2207 #if defined (DPAREN_ARITHMETIC)
2208             case '(':           /* ) */
2209               if (reserved_word_acceptable (last_read_token))
2210                 {
2211                   int cmdtyp, sline;
2212                   char *wval;
2213                   WORD_DESC *wd;
2214
2215                   sline = line_number;
2216                   cmdtyp = parse_arith_cmd (&wval);
2217                   if (cmdtyp == 1)      /* arithmetic command */
2218                     {
2219                       wd = make_word (wval);
2220                       wd->flags = W_QUOTED;
2221                       yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2222                       free (wval);      /* make_word copies it */
2223                       return (ARITH_CMD);
2224                     }
2225                   else if (cmdtyp == 0) /* nested subshell */
2226                     {
2227                       push_string (wval, 0, (alias_t *)NULL);
2228                       if ((parser_state & PST_CASEPAT) == 0)
2229                         parser_state |= PST_SUBSHELL;
2230                       return (character);
2231                     }
2232                   else                  /* ERROR */
2233                     return -1;
2234                 }
2235               break;
2236 #endif
2237             }
2238         }
2239       else if (character == '<' && peek_char == '&')
2240         return (LESS_AND);
2241       else if (character == '>' && peek_char == '&')
2242         return (GREATER_AND);
2243       else if (character == '<' && peek_char == '>')
2244         return (LESS_GREATER);
2245       else if (character == '>' && peek_char == '|')
2246         return (GREATER_BAR);
2247       else if (peek_char == '>' && character == '&')
2248         return (AND_GREATER);
2249
2250       shell_ungetc (peek_char);
2251
2252       /* If we look like we are reading the start of a function
2253          definition, then let the reader know about it so that
2254          we will do the right thing with `{'. */
2255       if (character == ')' && last_read_token == '(' && token_before_that == WORD)
2256         {
2257           parser_state |= PST_ALLOWOPNBRC;
2258 #if defined (ALIAS)
2259           parser_state &= ~PST_ALEXPNEXT;
2260 #endif /* ALIAS */
2261           function_dstart = line_number;
2262         }
2263
2264       /* case pattern lists may be preceded by an optional left paren.  If
2265          we're not trying to parse a case pattern list, the left paren
2266          indicates a subshell. */
2267       if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
2268         parser_state |= PST_SUBSHELL;
2269       /*(*/
2270       else if ((parser_state & PST_CASEPAT) && character == ')')
2271         parser_state &= ~PST_CASEPAT;
2272       /*(*/
2273       else if ((parser_state & PST_SUBSHELL) && character == ')')
2274         parser_state &= ~PST_SUBSHELL;
2275
2276 #if defined (PROCESS_SUBSTITUTION)
2277       /* Check for the constructs which introduce process substitution.
2278          Shells running in `posix mode' don't do process substitution. */
2279       if (posixly_correct ||
2280           ((character != '>' && character != '<') || peek_char != '('))
2281 #endif /* PROCESS_SUBSTITUTION */
2282         return (character);
2283     }
2284
2285   /* Hack <&- (close stdin) case. */
2286   if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
2287     return (character);
2288
2289   /* Okay, if we got this far, we have to read a word.  Read one,
2290      and then check it against the known ones. */
2291   result = read_token_word (character);
2292 #if defined (ALIAS)
2293   if (result == RE_READ_TOKEN)
2294     goto re_read_token;
2295 #endif
2296   return result;
2297 }
2298
2299 /* Match a $(...) or other grouping construct.  This has to handle embedded
2300    quoted strings ('', ``, "") and nested constructs.  It also must handle
2301    reprompting the user, if necessary, after reading a newline, and returning
2302    correct error values if it reads EOF. */
2303
2304 #define P_FIRSTCLOSE    0x01
2305
2306 static char matched_pair_error;
2307 static char *
2308 parse_matched_pair (qc, open, close, lenp, flags)
2309      int qc;    /* `"' if this construct is within double quotes */
2310      int open, close;
2311      int *lenp, flags;
2312 {
2313   int count, ch, was_dollar;
2314   int pass_next_character, nestlen, start_lineno;
2315   char *ret, *nestret;
2316   int retind, retsize;
2317
2318   count = 1;
2319   pass_next_character = was_dollar = 0;
2320
2321   ret = xmalloc (retsize = 64);
2322   retind = 0;
2323
2324   start_lineno = line_number;
2325   while (count)
2326     {
2327       ch = shell_getc (qc != '\'' && pass_next_character == 0);
2328       if (ch == EOF)
2329         {
2330           free (ret);
2331           parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
2332           EOF_Reached = 1;      /* XXX */
2333           return (&matched_pair_error);
2334         }
2335
2336       /* Possible reprompting. */
2337       if (ch == '\n' && interactive &&
2338             (bash_input.type == st_stdin || bash_input.type == st_stream))
2339         prompt_again ();
2340
2341       if (pass_next_character)          /* last char was backslash */
2342         {
2343           pass_next_character = 0;
2344           if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
2345             {
2346               if (retind > 0) retind--; /* swallow previously-added backslash */
2347               continue;
2348             }
2349
2350           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2351           if (ch == CTLESC || ch == CTLNUL)
2352             ret[retind++] = CTLESC;
2353           ret[retind++] = ch;
2354           continue;
2355         }
2356       else if (ch == CTLESC || ch == CTLNUL)    /* special shell escapes */
2357         {
2358           RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2359           ret[retind++] = CTLESC;
2360           ret[retind++] = ch;
2361           continue;
2362         }
2363       else if (ch == close)             /* ending delimiter */
2364         count--;
2365       else if (((flags & P_FIRSTCLOSE) == 0) && ch == open)             /* nested begin */
2366         count++;
2367
2368       /* Add this character. */
2369       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2370       ret[retind++] = ch;
2371
2372       if (open == '\'')                 /* '' inside grouping construct */
2373         continue;
2374
2375       if (ch == '\\')                   /* backslashes */
2376         pass_next_character++;
2377
2378       if (open != close)                /* a grouping construct */
2379         {
2380           if (shellquote (ch))
2381             {
2382               /* '', ``, or "" inside $(...) or other grouping construct. */
2383               push_delimiter (dstack, ch);
2384               nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
2385               pop_delimiter (dstack);
2386               if (nestret == &matched_pair_error)
2387                 {
2388                   free (ret);
2389                   return &matched_pair_error;
2390                 }
2391               if (nestlen)
2392                 {
2393                   RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2394                   strcpy (ret + retind, nestret);
2395                   retind += nestlen;
2396                 }
2397               FREE (nestret);
2398             }
2399         }
2400       /* Parse an old-style command substitution within double quotes as a
2401          single word. */
2402       /* XXX - sh and ksh93 don't do this - XXX */
2403       else if (open == '"' && ch == '`')
2404         {
2405           nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
2406           if (nestret == &matched_pair_error)
2407             {
2408               free (ret);
2409               return &matched_pair_error;
2410             }
2411           if (nestlen)
2412             {
2413               RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2414               strcpy (ret + retind, nestret);
2415               retind += nestlen;
2416             }
2417           FREE (nestret);
2418         }
2419       else if (was_dollar && (ch == '(' || ch == '{' || ch == '['))     /* ) } ] */
2420         /* check for $(), $[], or ${} inside quoted string. */
2421         {
2422           if (open == ch)       /* undo previous increment */
2423             count--;
2424           if (ch == '(')                /* ) */
2425             nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
2426           else if (ch == '{')           /* } */
2427             nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE);
2428           else if (ch == '[')           /* ] */
2429             nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
2430           if (nestret == &matched_pair_error)
2431             {
2432               free (ret);
2433               return &matched_pair_error;
2434             }
2435           if (nestlen)
2436             {
2437               RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2438               strcpy (ret + retind, nestret);
2439               retind += nestlen;
2440             }
2441           FREE (nestret);
2442         }
2443       was_dollar = (ch == '$');
2444     }
2445
2446   ret[retind] = '\0';
2447   if (lenp)
2448     *lenp = retind;
2449   return ret;
2450 }
2451
2452 #if defined (DPAREN_ARITHMETIC)
2453 /* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
2454    If not, assume it's a nested subshell for backwards compatibility and
2455    return 0.  In any case, put the characters we've consumed into a locally-
2456    allocated buffer and make *ep point to that buffer.  Return -1 on an
2457    error, for example EOF. */
2458 static int
2459 parse_arith_cmd (ep)
2460      char **ep;
2461 {
2462   int exp_lineno, rval, c;
2463   char *ttok, *token;
2464   int ttoklen;
2465
2466   exp_lineno = line_number;
2467   ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
2468   rval = 1;
2469   if (ttok == &matched_pair_error)
2470     return -1;
2471   /* Check that the next character is the closing right paren.  If
2472      not, this is a syntax error. ( */
2473   if ((c = shell_getc (0)) != ')')
2474     rval = 0;
2475
2476   token = xmalloc(ttoklen + 4);
2477
2478   /* (( ... )) -> "..." */
2479   token[0] = (rval == 1) ? '"' : '(';
2480   strncpy (token + 1, ttok, ttoklen - 1);       /* don't copy the final `)' */
2481   if (rval == 1)
2482     {
2483       token[ttoklen] = '"';
2484       token[ttoklen+1] = '\0';
2485     }
2486   else
2487     {
2488       token[ttoklen] = ')';
2489       token[ttoklen+1] = c;
2490       token[ttoklen+2] = '\0';
2491     }
2492   *ep = token;
2493   FREE (ttok);
2494   return rval;
2495 }
2496 #endif /* DPAREN_ARITHMETIC */
2497
2498 #if defined (COND_COMMAND)
2499 static COND_COM *cond_term ();
2500 static COND_COM *cond_and ();
2501 static COND_COM *cond_or ();
2502 static COND_COM *cond_expr ();
2503
2504 static COND_COM *
2505 cond_expr ()
2506 {
2507   return (cond_or ());  
2508 }
2509
2510 static COND_COM *
2511 cond_or ()
2512 {
2513   COND_COM *l, *r;
2514
2515   l = cond_and ();
2516   if (cond_token == OR_OR)
2517     {
2518       r = cond_or ();
2519       l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
2520     }
2521   return l;
2522 }
2523
2524 static COND_COM *
2525 cond_and ()
2526 {
2527   COND_COM *l, *r;
2528
2529   l = cond_term ();
2530   if (cond_token == AND_AND)
2531     {
2532       r = cond_and ();
2533       l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
2534     }
2535   return l;
2536 }
2537
2538 static int
2539 cond_skip_newlines ()
2540 {
2541   while ((cond_token = read_token (READ)) == '\n')
2542     {
2543       if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
2544         prompt_again ();
2545     }
2546   return (cond_token);
2547 }
2548
2549 #define COND_RETURN_ERROR() \
2550   do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
2551
2552 static COND_COM *
2553 cond_term ()
2554 {
2555   WORD_DESC *op;
2556   COND_COM *term, *tleft, *tright;
2557   int tok, lineno;
2558
2559   /* Read a token.  It can be a left paren, a `!', a unary operator, or a
2560      word that should be the first argument of a binary operator.  Start by
2561      skipping newlines, since this is a compound command. */
2562   tok = cond_skip_newlines ();
2563   lineno = line_number;
2564   if (tok == COND_END)
2565     {
2566       COND_RETURN_ERROR ();
2567     }
2568   else if (tok == '(')
2569     {
2570       term = cond_expr ();
2571       if (cond_token != ')')
2572         {
2573           if (term)
2574             dispose_cond_node (term);           /* ( */
2575           parser_error (lineno, "expected `)'");
2576           COND_RETURN_ERROR ();
2577         }
2578       term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
2579       (void)cond_skip_newlines ();
2580     }
2581   else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
2582     {
2583       if (tok == WORD)
2584         dispose_word (yylval.word);     /* not needed */
2585       term = cond_term ();
2586       if (term)
2587         term->flags |= CMD_INVERT_RETURN;
2588     }
2589   else if (tok == WORD && test_unop (yylval.word->word))
2590     {
2591       op = yylval.word;
2592       tok = read_token (READ);
2593       if (tok == WORD)
2594         {
2595           tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
2596           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
2597         }
2598       else
2599         {
2600           dispose_word (op);
2601           parser_error (line_number, "unexpected argument to conditional unary operator");
2602           COND_RETURN_ERROR ();
2603         }
2604
2605       (void)cond_skip_newlines ();
2606     }
2607   else          /* left argument to binary operator */
2608     {
2609       /* lhs */
2610       tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
2611
2612       /* binop */
2613       tok = read_token (READ);
2614       if (tok == WORD && test_binop (yylval.word->word))
2615         op = yylval.word;
2616       else if (tok == '<' || tok == '>')
2617         op = make_word_from_token (tok);
2618       else if (tok == COND_END || tok == AND_AND || tok == OR_OR)
2619         {
2620           /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
2621              the test command.  Similarly for [[ x && expr ]] or
2622              [[ x || expr ]] */
2623           op = make_word ("-n");
2624           term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
2625           cond_token = tok;
2626           return (term);
2627         }
2628       else
2629         {
2630           parser_error (line_number, "conditional binary operator expected");
2631           dispose_cond_node (tleft);
2632           COND_RETURN_ERROR ();
2633         }
2634
2635       /* rhs */
2636       tok = read_token (READ);
2637       if (tok == WORD)
2638         {
2639           tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
2640           term = make_cond_node (COND_BINARY, op, tleft, tright);
2641         }
2642       else
2643         {
2644           parser_error (line_number, "unexpected argument to conditional binary operator");
2645           dispose_cond_node (tleft);
2646           dispose_word (op);
2647           COND_RETURN_ERROR ();
2648         }
2649
2650       (void)cond_skip_newlines ();
2651     }
2652   return (term);
2653 }      
2654
2655 /* This is kind of bogus -- we slip a mini recursive-descent parser in
2656    here to handle the conditional statement syntax. */
2657 static COMMAND *
2658 parse_cond_command ()
2659 {
2660   COND_COM *cexp;
2661
2662   cexp = cond_expr ();
2663   return (make_cond_command (cexp));
2664 }
2665 #endif
2666
2667 static int
2668 read_token_word (character)
2669      int character;
2670 {
2671   /* The value for YYLVAL when a WORD is read. */
2672   WORD_DESC *the_word;
2673
2674   /* Index into the token that we are building. */
2675   int token_index;
2676
2677   /* ALL_DIGITS becomes zero when we see a non-digit. */
2678   int all_digits;
2679
2680   /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
2681   int dollar_present;
2682
2683   /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
2684   int quoted;
2685
2686   /* Non-zero means to ignore the value of the next character, and just
2687      to add it no matter what. */
2688  int pass_next_character;
2689
2690   /* The current delimiting character. */
2691   int cd;
2692   int result, peek_char;
2693   char *ttok, *ttrans;
2694   int ttoklen, ttranslen;
2695
2696   if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
2697     token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
2698
2699   token_index = 0;
2700   all_digits = digit (character);
2701   dollar_present = quoted = pass_next_character = 0;
2702
2703   for (;;)
2704     {
2705       if (character == EOF)
2706         goto got_token;
2707
2708       if (pass_next_character)
2709         {
2710           pass_next_character = 0;
2711           goto got_character;
2712         }
2713
2714       cd = current_delimiter (dstack);
2715
2716       /* Handle backslashes.  Quote lots of things when not inside of
2717          double-quotes, quote some things inside of double-quotes. */
2718       if (character == '\\')
2719         {
2720           peek_char = shell_getc (0);
2721
2722           /* Backslash-newline is ignored in all cases except
2723              when quoted with single quotes. */
2724           if (peek_char == '\n')
2725             {
2726               character = '\n';
2727               goto next_character;
2728             }
2729           else
2730             {
2731               shell_ungetc (peek_char);
2732
2733               /* If the next character is to be quoted, note it now. */
2734               if (cd == 0 || cd == '`' ||
2735                   (cd == '"' && member (peek_char, slashify_in_quotes)))
2736                 pass_next_character++;
2737
2738               quoted = 1;
2739               goto got_character;
2740             }
2741         }
2742
2743       /* Parse a matched pair of quote characters. */
2744       if (shellquote (character))
2745         {
2746           push_delimiter (dstack, character);
2747           ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
2748           pop_delimiter (dstack);
2749           if (ttok == &matched_pair_error)
2750             return -1;          /* Bail immediately. */
2751           RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2752                                   token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
2753           token[token_index++] = character;
2754           strcpy (token + token_index, ttok);
2755           token_index += ttoklen;
2756           all_digits = 0;
2757           quoted = 1;
2758           dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
2759           FREE (ttok);
2760           goto next_character;
2761         }
2762
2763 #ifdef EXTENDED_GLOB
2764       /* Parse a ksh-style extended pattern matching specification. */
2765       if (extended_glob && PATTERN_CHAR(character))
2766         {
2767           peek_char = shell_getc (1);
2768           if (peek_char == '(')         /* ) */
2769             {
2770               push_delimiter (dstack, peek_char);
2771               ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
2772               pop_delimiter (dstack);
2773               if (ttok == &matched_pair_error)
2774                 return -1;              /* Bail immediately. */
2775               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2776                                       token_buffer_size,
2777                                       TOKEN_DEFAULT_GROW_SIZE);
2778               token[token_index++] = character;
2779               token[token_index++] = peek_char;
2780               strcpy (token + token_index, ttok);
2781               token_index += ttoklen;
2782               FREE (ttok);
2783               dollar_present = all_digits = 0;
2784               goto next_character;
2785             }
2786           else
2787             shell_ungetc (peek_char);
2788         }
2789 #endif /* EXTENDED_GLOB */
2790
2791       /* If the delimiter character is not single quote, parse some of
2792          the shell expansions that must be read as a single word. */
2793 #if defined (PROCESS_SUBSTITUTION)
2794       if (character == '$' || character == '<' || character == '>')
2795 #else
2796       if (character == '$')
2797 #endif /* !PROCESS_SUBSTITUTION */
2798         {
2799           peek_char = shell_getc (1);
2800           /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
2801           if (peek_char == '(' ||
2802                 ((peek_char == '{' || peek_char == '[') && character == '$'))   /* ) ] } */
2803             {
2804               if (peek_char == '{')             /* } */
2805                 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
2806               else if (peek_char == '(')                /* ) */
2807                 {
2808                   /* XXX - push and pop the `(' as a delimiter for use by
2809                      the command-oriented-history code.  This way newlines
2810                      appearing in the $(...) string get added to the
2811                      history literally rather than causing a possibly-
2812                      incorrect `;' to be added. */
2813                   push_delimiter (dstack, peek_char);
2814                   ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
2815                   pop_delimiter (dstack);
2816                 }
2817               else
2818                 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
2819               if (ttok == &matched_pair_error)
2820                 return -1;              /* Bail immediately. */
2821               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2822                                       token_buffer_size,
2823                                       TOKEN_DEFAULT_GROW_SIZE);
2824               token[token_index++] = character;
2825               token[token_index++] = peek_char;
2826               strcpy (token + token_index, ttok);
2827               token_index += ttoklen;
2828               FREE (ttok);
2829               dollar_present = 1;
2830               all_digits = 0;
2831               goto next_character;
2832             }
2833           /* This handles $'...' and $"..." new-style quoted strings. */
2834           else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
2835             {
2836               int first_line;
2837
2838               first_line = line_number;
2839               ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
2840               if (ttok == &matched_pair_error)
2841                 return -1;
2842               if (peek_char == '\'')
2843                 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
2844               else
2845                 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
2846               free (ttok);
2847               RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
2848                                       token_buffer_size,
2849                                       TOKEN_DEFAULT_GROW_SIZE);
2850               token[token_index++] = peek_char;
2851               strcpy (token + token_index, ttrans);
2852               token_index += ttranslen;
2853               token[token_index++] = peek_char;
2854               FREE (ttrans);
2855               quoted = 1;
2856               all_digits = 0;
2857               goto next_character;
2858             }
2859           /* This could eventually be extended to recognize all of the
2860              shell's single-character parameter expansions, and set flags.*/
2861           else if (character == '$' && peek_char == '$')
2862             {
2863               ttok = xmalloc (3);
2864               ttok[0] = ttok[1] = '$';
2865               ttok[2] = '\0';
2866               RESIZE_MALLOCED_BUFFER (token, token_index, 3,
2867                                       token_buffer_size,
2868                                       TOKEN_DEFAULT_GROW_SIZE);
2869               strcpy (token + token_index, ttok);
2870               token_index += 2;
2871               dollar_present = 1;
2872               all_digits = 0;
2873               FREE (ttok);
2874               goto next_character;
2875             }
2876           else
2877             shell_ungetc (peek_char);
2878         }
2879
2880 #if defined (ARRAY_VARS)
2881       /* Identify possible compound array variable assignment. */
2882       else if (character == '=' && token_index > 0)
2883         {
2884           peek_char = shell_getc (1);
2885           if (peek_char == '(')         /* ) */
2886             {
2887               ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
2888               if (ttok == &matched_pair_error)
2889                 return -1;              /* Bail immediately. */
2890               if (ttok[0] == '(')       /* ) */
2891                 {
2892                   FREE (ttok);
2893                   return -1;
2894                 }
2895               RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2896                                       token_buffer_size,
2897                                       TOKEN_DEFAULT_GROW_SIZE);
2898               token[token_index++] = character;
2899               token[token_index++] = peek_char;
2900               strcpy (token + token_index, ttok);
2901               token_index += ttoklen;
2902               FREE (ttok);
2903               all_digits = 0;
2904               goto next_character;
2905             }
2906           else
2907             shell_ungetc (peek_char);
2908         }
2909 #endif
2910
2911       /* When not parsing a multi-character word construct, shell meta-
2912          characters break words. */
2913       if (shellbreak (character))
2914         {
2915           shell_ungetc (character);
2916           goto got_token;
2917         }
2918
2919     got_character:
2920
2921       all_digits &= digit (character);
2922       dollar_present |= character == '$';
2923
2924       if (character == CTLESC || character == CTLNUL)
2925         token[token_index++] = CTLESC;
2926
2927       token[token_index++] = character;
2928
2929       RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
2930                               TOKEN_DEFAULT_GROW_SIZE);
2931
2932     next_character:
2933       if (character == '\n' && interactive &&
2934         (bash_input.type == st_stdin || bash_input.type == st_stream))
2935         prompt_again ();
2936
2937       /* We want to remove quoted newlines (that is, a \<newline> pair)
2938          unless we are within single quotes or pass_next_character is
2939          set (the shell equivalent of literal-next). */
2940       cd = current_delimiter (dstack);
2941       character = shell_getc (cd != '\'' && pass_next_character == 0);
2942     }   /* end for (;;) */
2943
2944 got_token:
2945
2946   token[token_index] = '\0';
2947
2948   /* Check to see what thing we should return.  If the last_read_token
2949      is a `<', or a `&', or the character which ended this token is
2950      a '>' or '<', then, and ONLY then, is this input token a NUMBER.
2951      Otherwise, it is just a word, and should be returned as such. */
2952   if (all_digits && (character == '<' || character == '>' ||
2953                     last_read_token == LESS_AND ||
2954                     last_read_token == GREATER_AND))
2955       {
2956         yylval.number = atoi (token);
2957         return (NUMBER);
2958       }
2959
2960   /* Check for special case tokens. */
2961   result = special_case_tokens (token);
2962   if (result >= 0)
2963     return result;
2964
2965 #if defined (ALIAS)
2966   /* Posix.2 does not allow reserved words to be aliased, so check for all
2967      of them, including special cases, before expanding the current token
2968      as an alias. */
2969   if (posixly_correct)
2970     CHECK_FOR_RESERVED_WORD (token);
2971
2972   /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
2973      inhibits alias expansion. */
2974   if (expand_aliases && quoted == 0)
2975     {
2976       result = alias_expand_token (token);
2977       if (result == RE_READ_TOKEN)
2978         return (RE_READ_TOKEN);
2979       else if (result == NO_EXPANSION)
2980         parser_state &= ~PST_ALEXPNEXT;
2981     }
2982
2983   /* If not in Posix.2 mode, check for reserved words after alias
2984      expansion. */
2985   if (posixly_correct == 0)
2986 #endif
2987     CHECK_FOR_RESERVED_WORD (token);
2988
2989   the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
2990   the_word->word = xmalloc (1 + token_index);
2991   the_word->flags = 0;
2992   strcpy (the_word->word, token);
2993   if (dollar_present)
2994     the_word->flags |= W_HASDOLLAR;
2995   if (quoted)
2996     the_word->flags |= W_QUOTED;
2997   /* A word is an assignment if it appears at the beginning of a
2998      simple command, or after another assignment word.  This is
2999      context-dependent, so it cannot be handled in the grammar. */
3000   if (assignment (token))
3001     {
3002       the_word->flags |= W_ASSIGNMENT;
3003       /* Don't perform word splitting on assignment statements. */
3004       if (assignment_acceptable (last_read_token))
3005         the_word->flags |= W_NOSPLIT;
3006     }
3007
3008   yylval.word = the_word;
3009
3010   result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3011                 ? ASSIGNMENT_WORD : WORD;
3012
3013   if (last_read_token == FUNCTION)
3014     {
3015       parser_state |= PST_ALLOWOPNBRC;
3016       function_dstart = line_number;
3017     }
3018
3019   return (result);
3020 }
3021
3022 /* $'...' ANSI-C expand the portion of STRING between START and END and
3023    return the result.  The result cannot be longer than the input string. */
3024 static char *
3025 ansiexpand (string, start, end, lenp)
3026      char *string;
3027      int start, end, *lenp;
3028 {
3029   char *temp, *t;
3030   int len, tlen;
3031
3032   temp = xmalloc (end - start + 1);
3033   for (tlen = 0, len = start; len < end; )
3034     temp[tlen++] = string[len++];
3035   temp[tlen] = '\0';
3036
3037   if (*temp)
3038     {
3039       t = ansicstr (temp, tlen, (int *)NULL, lenp);
3040       free (temp);
3041       return (t);
3042     }
3043   else
3044     {
3045       if (lenp)
3046         *lenp = 0;
3047       return (temp);
3048     }
3049 }
3050
3051 /* $"..." -- Translate the portion of STRING between START and END
3052    according to current locale using gettext (if available) and return
3053    the result.  The caller will take care of leaving the quotes intact.
3054    The string will be left without the leading `$' by the caller.
3055    If translation is performed, the translated string will be double-quoted
3056    by the caller.  The length of the translated string is returned in LENP,
3057    if non-null. */
3058 static char *
3059 localeexpand (string, start, end, lineno, lenp)
3060      char *string;
3061      int start, end, lineno, *lenp;
3062 {
3063   int len, tlen;
3064   char *temp, *t;
3065
3066   temp = xmalloc (end - start + 1);
3067   for (tlen = 0, len = start; len < end; )
3068     temp[tlen++] = string[len++];
3069   temp[tlen] = '\0';
3070
3071   /* If we're just dumping translatable strings, don't do anything. */
3072   if (dump_translatable_strings)
3073     {
3074       if (dump_po_strings)
3075         printf ("#: %s:%d\nmsgid \"%s\"\nmsgstr \"\"\n",
3076                 (bash_input.name ? bash_input.name : "stdin"), lineno, temp);
3077       else
3078         printf ("\"%s\"\n", temp);
3079       if (lenp)
3080         *lenp = tlen;
3081       return (temp);
3082     }
3083   else if (*temp)
3084     {
3085       t = localetrans (temp, tlen, &len);
3086       free (temp);
3087       if (lenp)
3088         *lenp = len;
3089       return (t);
3090     }
3091   else
3092     {
3093       if (lenp)
3094         *lenp = 0;
3095       return (temp);
3096     }
3097 }
3098
3099 /* Return 1 if TOKEN is a token that after being read would allow
3100    a reserved word to be seen, else 0. */
3101 static int
3102 reserved_word_acceptable (token)
3103      int token;
3104 {
3105   if (token == '\n' || token == ';' || token == '(' || token == ')' ||
3106       token == '|' || token == '&' || token == '{' ||
3107       token == '}' ||                   /* XXX */
3108       token == AND_AND ||
3109       token == BANG ||
3110       token == TIME || token == TIMEOPT ||
3111       token == DO ||
3112       token == ELIF ||
3113       token == ELSE ||
3114       token == FI ||
3115       token == IF ||
3116       token == OR_OR ||
3117       token == SEMI_SEMI ||
3118       token == THEN ||
3119       token == UNTIL ||
3120       token == WHILE ||
3121       token == DONE ||          /* XXX these two are experimental */
3122       token == ESAC ||
3123       token == 0)
3124     return (1);
3125   else
3126     return (0);
3127 }
3128
3129 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3130    TOKEN is not a shell reserved word. */
3131 int
3132 find_reserved_word (token)
3133      char *token;
3134 {
3135   int i;
3136   for (i = 0; word_token_alist[i].word; i++)
3137     if (STREQ (token, word_token_alist[i].word))
3138       return i;
3139   return -1;
3140 }
3141
3142 #if 0
3143 #if defined (READLINE)
3144 /* Called after each time readline is called.  This insures that whatever
3145    the new prompt string is gets propagated to readline's local prompt
3146    variable. */
3147 static void
3148 reset_readline_prompt ()
3149 {
3150   char *temp_prompt;
3151
3152   if (prompt_string_pointer)
3153     {
3154       temp_prompt = (*prompt_string_pointer)
3155                         ? decode_prompt_string (*prompt_string_pointer)
3156                         : (char *)NULL;
3157
3158       if (temp_prompt == 0)
3159         {
3160           temp_prompt = xmalloc (1);
3161           temp_prompt[0] = '\0';
3162         }
3163
3164       FREE (current_readline_prompt);
3165       current_readline_prompt = temp_prompt;
3166     }
3167 }
3168 #endif /* READLINE */
3169 #endif /* 0 */
3170
3171 #if defined (HISTORY)
3172 /* A list of tokens which can be followed by newlines, but not by
3173    semi-colons.  When concatenating multiple lines of history, the
3174    newline separator for such tokens is replaced with a space. */
3175 static int no_semi_successors[] = {
3176   '\n', '{', '(', ')', ';', '&', '|',
3177   CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
3178   0
3179 };
3180
3181 /* If we are not within a delimited expression, try to be smart
3182    about which separators can be semi-colons and which must be
3183    newlines.  Returns the string that should be added into the
3184    history entry. */
3185 char *
3186 history_delimiting_chars ()
3187 {
3188   register int i;
3189
3190   if (dstack.delimiter_depth != 0)
3191     return ("\n");
3192     
3193   /* First, handle some special cases. */
3194   /*(*/
3195   /* If we just read `()', assume it's a function definition, and don't
3196      add a semicolon.  If the token before the `)' was not `(', and we're
3197      not in the midst of parsing a case statement, assume it's a
3198      parenthesized command and add the semicolon. */
3199   /*)(*/
3200   if (token_before_that == ')')
3201     {
3202       if (two_tokens_ago == '(')        /*)*/   /* function def */
3203         return " ";
3204       /* This does not work for subshells inside case statement
3205          command lists.  It's a suboptimal solution. */
3206       else if (parser_state & PST_CASESTMT)     /* case statement pattern */
3207         return " ";
3208       else      
3209         return "; ";                            /* (...) subshell */
3210     }
3211   else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
3212     return " ";         /* function def using `function name' without `()' */
3213
3214   for (i = 0; no_semi_successors[i]; i++)
3215     {
3216       if (token_before_that == no_semi_successors[i])
3217         return (" ");
3218     }
3219
3220   return ("; ");
3221 }
3222 #endif /* HISTORY */
3223
3224 /* Issue a prompt, or prepare to issue a prompt when the next character
3225    is read. */
3226 static void
3227 prompt_again ()
3228 {
3229   char *temp_prompt;
3230
3231   if (!interactive)     /* XXX */
3232     return;
3233
3234   ps1_prompt = get_string_value ("PS1");
3235   ps2_prompt = get_string_value ("PS2");
3236
3237   if (!prompt_string_pointer)
3238     prompt_string_pointer = &ps1_prompt;
3239
3240   temp_prompt = *prompt_string_pointer
3241                         ? decode_prompt_string (*prompt_string_pointer)
3242                         : (char *)NULL;
3243
3244   if (temp_prompt == 0)
3245     {
3246       temp_prompt = xmalloc (1);
3247       temp_prompt[0] = '\0';
3248     }
3249
3250   current_prompt_string = *prompt_string_pointer;
3251   prompt_string_pointer = &ps2_prompt;
3252
3253 #if defined (READLINE)
3254   if (!no_line_editing)
3255     {
3256       FREE (current_readline_prompt);
3257       current_readline_prompt = temp_prompt;
3258     }
3259   else
3260 #endif  /* READLINE */
3261     {
3262       FREE (current_decoded_prompt);
3263       current_decoded_prompt = temp_prompt;
3264     }
3265 }
3266
3267 static void
3268 print_prompt ()
3269 {
3270   fprintf (stderr, "%s", current_decoded_prompt);
3271   fflush (stderr);
3272 }
3273
3274 /* Return a string which will be printed as a prompt.  The string
3275    may contain special characters which are decoded as follows:
3276
3277         \a      bell (ascii 07)
3278         \e      escape (ascii 033)
3279         \d      the date in Day Mon Date format
3280         \h      the hostname up to the first `.'
3281         \H      the hostname
3282         \n      CRLF
3283         \s      the name of the shell
3284         \t      the time in 24-hour hh:mm:ss format
3285         \T      the time in 12-hour hh:mm:ss format
3286         \@      the time in 12-hour am/pm format
3287         \v      the version of bash (e.g., 2.00)
3288         \V      the release of bash, version + patchlevel (e.g., 2.00.0)
3289         \w      the current working directory
3290         \W      the last element of $PWD
3291         \u      your username
3292         \#      the command number of this command
3293         \!      the history number of this command
3294         \$      a $ or a # if you are root
3295         \nnn    character code nnn in octal
3296         \\      a backslash
3297         \[      begin a sequence of non-printing chars
3298         \]      end a sequence of non-printing chars
3299 */
3300 #define PROMPT_GROWTH 48
3301 char *
3302 decode_prompt_string (string)
3303      char *string;
3304 {
3305   WORD_LIST *list;
3306   char *result, *t;
3307   struct dstack save_dstack;
3308 #if defined (PROMPT_STRING_DECODE)
3309   int result_size, result_index;
3310   int c, n;
3311   char *temp, octal_string[4];
3312   time_t the_time;
3313
3314   result = xmalloc (result_size = PROMPT_GROWTH);
3315   result[result_index = 0] = 0;
3316   temp = (char *)NULL;
3317
3318   while (c = *string++)
3319     {
3320       if (posixly_correct && c == '!')
3321         {
3322           if (*string == '!')
3323             {
3324               temp = savestring ("!");
3325               goto add_string;
3326             }
3327           else
3328             {
3329 #if !defined (HISTORY)
3330                 temp = savestring ("1");
3331 #else /* HISTORY */
3332                 temp = itos (history_number ());
3333 #endif /* HISTORY */
3334                 string--;       /* add_string increments string again. */
3335                 goto add_string;
3336             }
3337         }
3338       if (c == '\\')
3339         {
3340           c = *string;
3341
3342           switch (c)
3343             {
3344             case '0':
3345             case '1':
3346             case '2':
3347             case '3':
3348             case '4':
3349             case '5':
3350             case '6':
3351             case '7':
3352               strncpy (octal_string, string, 3);
3353               octal_string[3] = '\0';
3354
3355               n = read_octal (octal_string);
3356               temp = xmalloc (3);
3357
3358               if (n == CTLESC || n == CTLNUL)
3359                 {
3360                   string += 3;
3361                   temp[0] = CTLESC;
3362                   temp[1] = n;
3363                   temp[2] = '\0';
3364                 }
3365               else if (n == -1)
3366                 {
3367                   temp[0] = '\\';
3368                   temp[1] = '\0';
3369                 }
3370               else
3371                 {
3372                   string += 3;
3373                   temp[0] = n;
3374                   temp[1] = '\0';
3375                 }
3376
3377               c = 0;
3378               goto add_string;
3379
3380             case 't':
3381             case 'd':
3382             case 'T':
3383             case '@':
3384               /* Make the current time/date into a string. */
3385               the_time = time (0);
3386               temp = ctime (&the_time);
3387
3388               temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
3389               temp[(c != 'd') ? 8 : 10] = '\0';
3390
3391               /* quick and dirty conversion to 12-hour time */
3392               if (c == 'T' || c == '@')
3393                 {
3394                   if (c == '@')
3395                     {
3396                       temp[5] = 'a';    /* am/pm format */
3397                       temp[6] = 'm';
3398                       temp[7] = '\0';
3399                     }
3400                   c = temp[2];
3401                   temp[2] = '\0';
3402                   n = atoi (temp);
3403                   temp[2] = c;
3404                   n -= 12;
3405                   if (n > 0)
3406                     {
3407                       temp[0] = (n / 10) + '0';
3408                       temp[1] = (n % 10) + '0';
3409                     }
3410                   if (n >= 0 && temp[5] == 'a')
3411                     temp[5] = 'p';
3412                 }
3413               goto add_string;
3414
3415             case 'r':
3416               temp = xmalloc (2);
3417               temp[0] = '\r';
3418               temp[1] = '\0';
3419               goto add_string;
3420
3421             case 'n':
3422               temp = xmalloc (3);
3423               temp[0] = no_line_editing ? '\n' : '\r';
3424               temp[1] = no_line_editing ? '\0' : '\n';
3425               temp[2] = '\0';
3426               goto add_string;
3427
3428             case 's':
3429               temp = base_pathname (shell_name);
3430               temp = savestring (temp);
3431               goto add_string;
3432
3433             case 'v':
3434             case 'V':
3435               temp = xmalloc (8);
3436               if (c == 'v')
3437                 strcpy (temp, dist_version);
3438               else
3439                 sprintf (temp, "%s.%d", dist_version, patch_level);
3440               goto add_string;
3441
3442             case 'w':
3443             case 'W':
3444               {
3445                 /* Use the value of PWD because it is much more efficient. */
3446                 char t_string[PATH_MAX];
3447                 int tlen;
3448
3449                 temp = get_string_value ("PWD");
3450
3451                 if (temp == 0)
3452                   {
3453                     if (getcwd (t_string, sizeof(t_string)) == 0)
3454                       {
3455                         t_string[0] = '.';
3456                         tlen = 1;
3457                       }
3458                     else
3459                       tlen = strlen (t_string);
3460                   }
3461                 else
3462                   {
3463                     tlen = sizeof (t_string) - 1;
3464                     strncpy (t_string, temp, tlen);
3465                   }
3466                 t_string[tlen] = '\0';
3467
3468                 if (c == 'W')
3469                   {
3470                     t = strrchr (t_string, '/');
3471                     if (t && t != t_string)
3472                       strcpy (t_string, t + 1);
3473                   }
3474                 else
3475                   /* polite_directory_format is guaranteed to return a string
3476                      no longer than PATH_MAX - 1 characters. */
3477                   strcpy (t_string, polite_directory_format (t_string));
3478
3479                 /* If we're going to be expanding the prompt string later,
3480                    quote the directory name. */
3481                 if (promptvars || posixly_correct)
3482                   temp = backslash_quote (t_string);
3483                 else
3484                   temp = savestring (t_string);
3485
3486                 goto add_string;
3487               }
3488
3489             case 'u':
3490               temp = savestring (current_user.user_name);
3491               goto add_string;
3492
3493             case 'h':
3494             case 'H':
3495               temp = savestring (current_host_name);
3496               if (c == 'h' && (t = (char *)strchr (temp, '.')))
3497                 *t = '\0';
3498               goto add_string;
3499
3500             case '#':
3501               temp = itos (current_command_number);
3502               goto add_string;
3503
3504             case '!':
3505 #if !defined (HISTORY)
3506               temp = savestring ("1");
3507 #else /* HISTORY */
3508               temp = itos (history_number ());
3509 #endif /* HISTORY */
3510               goto add_string;
3511
3512             case '$':
3513               t = temp = xmalloc (3);
3514               if ((promptvars || posixly_correct) && (current_user.euid != 0))
3515                 *t++ = '\\';
3516               *t++ = current_user.euid == 0 ? '#' : '$';
3517               *t = '\0';
3518               goto add_string;
3519
3520 #if defined (READLINE)
3521             case '[':
3522             case ']':
3523               temp = xmalloc (3);
3524               temp[0] = '\001';
3525               temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
3526               temp[2] = '\0';
3527               goto add_string;
3528 #endif /* READLINE */
3529
3530             case '\\':
3531               temp = xmalloc (2);
3532               temp[0] = c;
3533               temp[1] = '\0';
3534               goto add_string;
3535
3536             case 'a':
3537             case 'e':
3538               temp = xmalloc (2);
3539               temp[0] = (c == 'a') ? '\07' : '\033';
3540               temp[1] = '\0';
3541               goto add_string;
3542
3543             default:
3544               temp = xmalloc (3);
3545               temp[0] = '\\';
3546               temp[1] = c;
3547               temp[2] = '\0';
3548
3549             add_string:
3550               if (c)
3551                 string++;
3552               result =
3553                 sub_append_string (temp, result, &result_index, &result_size);
3554               temp = (char *)NULL; /* Freed in sub_append_string (). */
3555               result[result_index] = '\0';
3556               break;
3557             }
3558         }
3559       else
3560         {
3561           RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
3562           result[result_index++] = c;
3563           result[result_index] = '\0';
3564         }
3565     }
3566 #else /* !PROMPT_STRING_DECODE */
3567   result = savestring (string);
3568 #endif /* !PROMPT_STRING_DECODE */
3569
3570   /* Save the delimiter stack and point `dstack' to temp space so any
3571      command substitutions in the prompt string won't result in screwing
3572      up the parser's quoting state. */
3573   save_dstack = dstack;
3574   dstack = temp_dstack;
3575   dstack.delimiter_depth = 0;
3576
3577   /* Perform variable and parameter expansion and command substitution on
3578      the prompt string. */
3579   if (promptvars || posixly_correct)
3580     {
3581       list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
3582       free (result);
3583       result = string_list (list);
3584       dispose_words (list);
3585     }
3586   else
3587     {
3588       t = dequote_string (result);
3589       free (result);
3590       result = t;
3591     }
3592
3593   dstack = save_dstack;
3594
3595   return (result);
3596 }
3597
3598 /* Report a syntax error, and restart the parser.  Call here for fatal
3599    errors. */
3600 int
3601 yyerror ()
3602 {
3603   report_syntax_error ((char *)NULL);
3604   reset_parser ();
3605   return (0);
3606 }
3607
3608 /* Report a syntax error with line numbers, etc.
3609    Call here for recoverable errors.  If you have a message to print,
3610    then place it in MESSAGE, otherwise pass NULL and this will figure
3611    out an appropriate message for you. */
3612 static void
3613 report_syntax_error (message)
3614      char *message;
3615 {
3616   char *msg, *t;
3617   int token_end, i;
3618   char msg2[2];
3619
3620   if (message)
3621     {
3622       parser_error (line_number, "%s", message);
3623       if (interactive && EOF_Reached)
3624         EOF_Reached = 0;
3625       last_command_exit_value = EX_USAGE;
3626       return;
3627     }
3628
3629   /* If the line of input we're reading is not null, try to find the
3630      objectionable token. */
3631   if (shell_input_line && *shell_input_line)
3632     {
3633       t = shell_input_line;
3634       i = shell_input_line_index;
3635       token_end = 0;
3636
3637       if (i && t[i] == '\0')
3638         i--;
3639
3640       while (i && (whitespace (t[i]) || t[i] == '\n'))
3641         i--;
3642
3643       if (i)
3644         token_end = i + 1;
3645
3646       while (i && (member (t[i], " \n\t;|&") == 0))
3647         i--;
3648
3649       while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
3650         i++;
3651
3652       /* Print the offending token. */
3653       if (token_end || (i == 0 && token_end == 0))
3654         {
3655           if (token_end)
3656             {
3657               msg = xmalloc (1 + (token_end - i));
3658               strncpy (msg, t + i, token_end - i);
3659               msg[token_end - i] = '\0';
3660             }
3661           else  /* one-character token */
3662             {
3663               msg2[0] = t[i];
3664               msg2[1] = '\0';
3665               msg = msg2;
3666             }
3667
3668           parser_error (line_number, "syntax error near unexpected token `%s'", msg);
3669
3670           if (msg != msg2)
3671             free (msg);
3672         }
3673
3674       /* If not interactive, print the line containing the error. */
3675       if (interactive == 0)
3676         {
3677           msg = savestring (shell_input_line);
3678           token_end = strlen (msg);
3679           while (token_end && msg[token_end - 1] == '\n')
3680             msg[--token_end] = '\0';
3681
3682           parser_error (line_number, "`%s'", msg);
3683           free (msg);
3684         }
3685     }
3686   else
3687     {
3688       msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
3689       parser_error (line_number, "%s", msg);
3690       /* When the shell is interactive, this file uses EOF_Reached
3691          only for error reporting.  Other mechanisms are used to
3692          decide whether or not to exit. */
3693       if (interactive && EOF_Reached)
3694         EOF_Reached = 0;
3695     }
3696   last_command_exit_value = EX_USAGE;
3697 }
3698
3699 /* ??? Needed function. ??? We have to be able to discard the constructs
3700    created during parsing.  In the case of error, we want to return
3701    allocated objects to the memory pool.  In the case of no error, we want
3702    to throw away the information about where the allocated objects live.
3703    (dispose_command () will actually free the command. */
3704 static void
3705 discard_parser_constructs (error_p)
3706      int error_p;
3707 {
3708 }
3709
3710 /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
3711
3712 /* A flag denoting whether or not ignoreeof is set. */
3713 int ignoreeof = 0;
3714
3715 /* The number of times that we have encountered an EOF character without
3716    another character intervening.  When this gets above the limit, the
3717    shell terminates. */
3718 int eof_encountered = 0;
3719
3720 /* The limit for eof_encountered. */
3721 int eof_encountered_limit = 10;
3722
3723 /* If we have EOF as the only input unit, this user wants to leave
3724    the shell.  If the shell is not interactive, then just leave.
3725    Otherwise, if ignoreeof is set, and we haven't done this the
3726    required number of times in a row, print a message. */
3727 static void
3728 handle_eof_input_unit ()
3729 {
3730   if (interactive)
3731     {
3732       /* shell.c may use this to decide whether or not to write out the
3733          history, among other things.  We use it only for error reporting
3734          in this file. */
3735       if (EOF_Reached)
3736         EOF_Reached = 0;
3737
3738       /* If the user wants to "ignore" eof, then let her do so, kind of. */
3739       if (ignoreeof)
3740         {
3741           if (eof_encountered < eof_encountered_limit)
3742             {
3743               fprintf (stderr, "Use \"%s\" to leave the shell.\n",
3744                        login_shell ? "logout" : "exit");
3745               eof_encountered++;
3746               /* Reset the prompt string to be $PS1. */
3747               prompt_string_pointer = (char **)NULL;
3748               prompt_again ();
3749               last_read_token = current_token = '\n';
3750               return;
3751             }
3752         }
3753
3754       /* In this case EOF should exit the shell.  Do it now. */
3755       reset_parser ();
3756       exit_builtin ((WORD_LIST *)NULL);
3757     }
3758   else
3759     {
3760       /* We don't write history files, etc., for non-interactive shells. */
3761       EOF_Reached = 1;
3762     }
3763 }