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