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