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