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