1 /* parse.y - Yacc grammar for bash. */
2 
3 /* Copyright (C) 1989-2020 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 "execute_cmd.h"
49 #include "typemax.h"		/* SIZE_MAX if needed */
50 #include "trap.h"
51 #include "flags.h"
52 #include "parser.h"
53 #include "mailcheck.h"
54 #include "test.h"
55 #include "builtins.h"
56 #include "builtins/common.h"
57 #include "builtins/builtext.h"
58 
59 #include "shmbutil.h"
60 
61 #if defined (READLINE)
62 #  include "bashline.h"
63 #  include <readline/readline.h>
64 #endif /* READLINE */
65 
66 #if defined (HISTORY)
67 #  include "bashhist.h"
68 #  include <readline/history.h>
69 #endif /* HISTORY */
70 
71 #if defined (JOB_CONTROL)
72 #  include "jobs.h"
73 #else
74 extern int cleanup_dead_jobs PARAMS((void));
75 #endif /* JOB_CONTROL */
76 
77 #if defined (ALIAS)
78 #  include "alias.h"
79 #else
80 typedef void *alias_t;
81 #endif /* ALIAS */
82 
83 #if defined (PROMPT_STRING_DECODE)
84 #  ifndef _MINIX
85 #    include <sys/param.h>
86 #  endif
87 #  include <time.h>
88 #  if defined (TM_IN_SYS_TIME)
89 #    include <sys/types.h>
90 #    include <sys/time.h>
91 #  endif /* TM_IN_SYS_TIME */
92 #  include "maxpath.h"
93 #endif /* PROMPT_STRING_DECODE */
94 
95 #define RE_READ_TOKEN	-99
96 #define NO_EXPANSION	-100
97 
98 #define END_ALIAS	-2
99 
100 #ifdef DEBUG
101 #  define YYDEBUG 1
102 #else
103 #  define YYDEBUG 0
104 #endif
105 
106 #if defined (HANDLE_MULTIBYTE)
107 #  define last_shell_getc_is_singlebyte \
108 	((shell_input_line_index > 1) \
109 		? shell_input_line_property[shell_input_line_index - 1] \
110 		: 1)
111 #  define MBTEST(x)	((x) && last_shell_getc_is_singlebyte)
112 #else
113 #  define last_shell_getc_is_singlebyte	1
114 #  define MBTEST(x)	((x))
115 #endif
116 
117 #if defined (EXTENDED_GLOB)
118 extern int extended_glob;
119 #endif
120 
121 extern int dump_translatable_strings, dump_po_strings;
122 
123 #if !defined (errno)
124 extern int errno;
125 #endif
126 
127 /* **************************************************************** */
128 /*								    */
129 /*		    "Forward" declarations			    */
130 /*								    */
131 /* **************************************************************** */
132 
133 #ifdef DEBUG
134 static void debug_parser PARAMS((int));
135 #endif
136 
137 static int yy_getc PARAMS((void));
138 static int yy_ungetc PARAMS((int));
139 
140 #if defined (READLINE)
141 static int yy_readline_get PARAMS((void));
142 static int yy_readline_unget PARAMS((int));
143 #endif
144 
145 static int yy_string_get PARAMS((void));
146 static int yy_string_unget PARAMS((int));
147 static void rewind_input_string PARAMS((void));
148 static int yy_stream_get PARAMS((void));
149 static int yy_stream_unget PARAMS((int));
150 
151 static int shell_getc PARAMS((int));
152 static void shell_ungetc PARAMS((int));
153 static void discard_until PARAMS((int));
154 
155 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
156 static void push_string PARAMS((char *, int, alias_t *));
157 static void pop_string PARAMS((void));
158 static void free_string_list PARAMS((void));
159 #endif
160 
161 static char *read_a_line PARAMS((int));
162 
163 static int reserved_word_acceptable PARAMS((int));
164 static int yylex PARAMS((void));
165 
166 static void push_heredoc PARAMS((REDIRECT *));
167 static char *mk_alexpansion PARAMS((char *));
168 static int alias_expand_token PARAMS((char *));
169 static int time_command_acceptable PARAMS((void));
170 static int special_case_tokens PARAMS((char *));
171 static int read_token PARAMS((int));
172 static char *parse_matched_pair PARAMS((int, int, int, int *, int));
173 static char *parse_comsub PARAMS((int, int, int, int *, int));
174 #if defined (ARRAY_VARS)
175 static char *parse_compound_assignment PARAMS((int *));
176 #endif
177 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
178 static int parse_dparen PARAMS((int));
179 static int parse_arith_cmd PARAMS((char **, int));
180 #endif
181 #if defined (COND_COMMAND)
182 static void cond_error PARAMS((void));
183 static COND_COM *cond_expr PARAMS((void));
184 static COND_COM *cond_or PARAMS((void));
185 static COND_COM *cond_and PARAMS((void));
186 static COND_COM *cond_term PARAMS((void));
187 static int cond_skip_newlines PARAMS((void));
188 static COMMAND *parse_cond_command PARAMS((void));
189 #endif
190 #if defined (ARRAY_VARS)
191 static int token_is_assignment PARAMS((char *, int));
192 static int token_is_ident PARAMS((char *, int));
193 #endif
194 static int read_token_word PARAMS((int));
195 static void discard_parser_constructs PARAMS((int));
196 
197 static char *error_token_from_token PARAMS((int));
198 static char *error_token_from_text PARAMS((void));
199 static void print_offending_line PARAMS((void));
200 static void report_syntax_error PARAMS((char *));
201 
202 static void handle_eof_input_unit PARAMS((void));
203 static void prompt_again PARAMS((void));
204 #if 0
205 static void reset_readline_prompt PARAMS((void));
206 #endif
207 static void print_prompt PARAMS((void));
208 
209 #if defined (HANDLE_MULTIBYTE)
210 static void set_line_mbstate PARAMS((void));
211 static char *shell_input_line_property = NULL;
212 static size_t shell_input_line_propsize = 0;
213 #else
214 #  define set_line_mbstate()
215 #endif
216 
217 extern int yyerror PARAMS((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 /* Displayed after reading a command but before executing it in an interactive shell */
231 char *ps0_prompt;
232 
233 /* Handle on the current prompt string.  Indirectly points through
234    ps1_ or ps2_prompt. */
235 char **prompt_string_pointer = (char **)NULL;
236 char *current_prompt_string;
237 
238 /* Non-zero means we expand aliases in commands. */
239 int expand_aliases = 0;
240 
241 /* If non-zero, the decoded prompt string undergoes parameter and
242    variable substitution, command substitution, arithmetic substitution,
243    string expansion, process substitution, and quote removal in
244    decode_prompt_string. */
245 int promptvars = 1;
246 
247 /* If non-zero, $'...' and $"..." are expanded when they appear within
248    a ${...} expansion, even when the expansion appears within double
249    quotes. */
250 int extended_quote = 1;
251 
252 /* The number of lines read from input while creating the current command. */
253 int current_command_line_count;
254 
255 /* The number of lines in a command saved while we run parse_and_execute */
256 int saved_command_line_count;
257 
258 /* The token that currently denotes the end of parse. */
259 int shell_eof_token;
260 
261 /* The token currently being read. */
262 int current_token;
263 
264 /* The current parser state. */
265 int parser_state;
266 
267 /* Variables to manage the task of reading here documents, because we need to
268    defer the reading until after a complete command has been collected. */
269 static REDIRECT *redir_stack[HEREDOC_MAX];
270 int need_here_doc;
271 
272 /* Where shell input comes from.  History expansion is performed on each
273    line when the shell is interactive. */
274 static char *shell_input_line = (char *)NULL;
275 static size_t shell_input_line_index;
276 static size_t shell_input_line_size;	/* Amount allocated for shell_input_line. */
277 static size_t shell_input_line_len;	/* strlen (shell_input_line) */
278 
279 /* Either zero or EOF. */
280 static int shell_input_line_terminator;
281 
282 /* The line number in a script on which a function definition starts. */
283 static int function_dstart;
284 
285 /* The line number in a script on which a function body starts. */
286 static int function_bstart;
287 
288 /* The line number in a script at which an arithmetic for command starts. */
289 static int arith_for_lineno;
290 
291 /* The decoded prompt string.  Used if READLINE is not defined or if
292    editing is turned off.  Analogous to current_readline_prompt. */
293 static char *current_decoded_prompt;
294 
295 /* The last read token, or NULL.  read_token () uses this for context
296    checking. */
297 static int last_read_token;
298 
299 /* The token read prior to last_read_token. */
300 static int token_before_that;
301 
302 /* The token read prior to token_before_that. */
303 static int two_tokens_ago;
304 
305 static int global_extglob;
306 
307 /* The line number in a script where the word in a `case WORD', `select WORD'
308    or `for WORD' begins.  This is a nested command maximum, since the array
309    index is decremented after a case, select, or for command is parsed. */
310 #define MAX_CASE_NEST	128
311 static int word_lineno[MAX_CASE_NEST+1];
312 static int word_top = -1;
313 
314 /* If non-zero, it is the token that we want read_token to return
315    regardless of what text is (or isn't) present to be read.  This
316    is reset by read_token.  If token_to_read == WORD or
317    ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
318 static int token_to_read;
319 static WORD_DESC *word_desc_to_read;
320 
321 static REDIRECTEE source;
322 static REDIRECTEE redir;
323 
324 static FILE *yyoutstream;
325 static FILE *yyerrstream;
326 %}
327 
328 %union {
329   WORD_DESC *word;		/* the word that we read. */
330   int number;			/* the number that we read. */
331   WORD_LIST *word_list;
332   COMMAND *command;
333   REDIRECT *redirect;
334   ELEMENT element;
335   PATTERN_LIST *pattern;
336 }
337 
338 /* Reserved words.  Members of the first group are only recognized
339    in the case that they are preceded by a list_terminator.  Members
340    of the second group are for [[...]] commands.  Members of the
341    third group are recognized only under special circumstances. */
342 %token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION COPROC
343 %token COND_START COND_END COND_ERROR
344 %token IN BANG TIME TIMEOPT TIMEIGN
345 
346 /* More general tokens. yylex () knows how to make these. */
347 %token <word> WORD ASSIGNMENT_WORD REDIR_WORD
348 %token <number> NUMBER
349 %token <word_list> ARITH_CMD ARITH_FOR_EXPRS
350 %token <command> COND_CMD
351 %token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND LESS_LESS_LESS
352 %token GREATER_AND SEMI_SEMI SEMI_AND SEMI_SEMI_AND
353 %token LESS_LESS_MINUS AND_GREATER AND_GREATER_GREATER LESS_GREATER
354 %token GREATER_BAR BAR_AND
355 
356 /* The types that the various syntactical units return. */
357 
358 %type <command> inputunit command pipeline pipeline_command
359 %type <command> list list0 list1 compound_list simple_list simple_list1
360 %type <command> simple_command shell_command
361 %type <command> for_command select_command case_command group_command
362 %type <command> arith_command
363 %type <command> cond_command
364 %type <command> arith_for_command
365 %type <command> coproc
366 %type <command> function_def function_body if_command elif_clause subshell
367 %type <redirect> redirection redirection_list
368 %type <element> simple_command_element
369 %type <word_list> word_list pattern
370 %type <pattern> pattern_list case_clause_sequence case_clause
371 %type <number> timespec
372 %type <number> list_terminator
373 
374 %start inputunit
375 
376 %left '&' ';' '\n' yacc_EOF
377 %left AND_AND OR_OR
378 %right '|' BAR_AND
379 %%
380 
381 inputunit:	simple_list simple_list_terminator
382 			{
383 			  /* Case of regular command.  Discard the error
384 			     safety net,and return the command just parsed. */
385 			  global_command = $1;
386 			  eof_encountered = 0;
387 			  /* discard_parser_constructs (0); */
388 			  if (parser_state & PST_CMDSUBST)
389 			    parser_state |= PST_EOFTOKEN;
390 			  YYACCEPT;
391 			}
392 	|	'\n'
393 			{
394 			  /* Case of regular command, but not a very
395 			     interesting one.  Return a NULL command. */
396 			  global_command = (COMMAND *)NULL;
397 			  if (parser_state & PST_CMDSUBST)
398 			    parser_state |= PST_EOFTOKEN;
399 			  YYACCEPT;
400 			}
401 	|	error '\n'
402 			{
403 			  /* Error during parsing.  Return NULL command. */
404 			  global_command = (COMMAND *)NULL;
405 			  eof_encountered = 0;
406 			  /* discard_parser_constructs (1); */
407 			  if (interactive && parse_and_execute_level == 0)
408 			    {
409 			      YYACCEPT;
410 			    }
411 			  else
412 			    {
413 			      YYABORT;
414 			    }
415 			}
416 	|	error yacc_EOF
417 			{
418 			  /* EOF after an error.  Do ignoreeof or not.  Really
419 			     only interesting in non-interactive shells */
420 			  global_command = (COMMAND *)NULL;
421 			  if (last_command_exit_value == 0)
422 			    last_command_exit_value = EX_BADUSAGE;	/* force error return */
423 			  if (interactive && parse_and_execute_level == 0)
424 			    {
425 			      handle_eof_input_unit ();
426 			      YYACCEPT;
427 			    }
428 			  else
429 			    {
430 			      YYABORT;
431 			    }
432 			}
433 	|	yacc_EOF
434 			{
435 			  /* Case of EOF seen by itself.  Do ignoreeof or
436 			     not. */
437 			  global_command = (COMMAND *)NULL;
438 			  handle_eof_input_unit ();
439 			  YYACCEPT;
440 			}
441 	;
442 
443 word_list:	WORD
444 			{ $$ = make_word_list ($1, (WORD_LIST *)NULL); }
445 	|	word_list WORD
446 			{ $$ = make_word_list ($2, $1); }
447 	;
448 
449 redirection:	'>' WORD
450 			{
451 			  source.dest = 1;
452 			  redir.filename = $2;
453 			  $$ = make_redirection (source, r_output_direction, redir, 0);
454 			}
455 	|	'<' WORD
456 			{
457 			  source.dest = 0;
458 			  redir.filename = $2;
459 			  $$ = make_redirection (source, r_input_direction, redir, 0);
460 			}
461 	|	NUMBER '>' WORD
462 			{
463 			  source.dest = $1;
464 			  redir.filename = $3;
465 			  $$ = make_redirection (source, r_output_direction, redir, 0);
466 			}
467 	|	NUMBER '<' WORD
468 			{
469 			  source.dest = $1;
470 			  redir.filename = $3;
471 			  $$ = make_redirection (source, r_input_direction, redir, 0);
472 			}
473 	|	REDIR_WORD '>' WORD
474 			{
475 			  source.filename = $1;
476 			  redir.filename = $3;
477 			  $$ = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN);
478 			}
479 	|	REDIR_WORD '<' WORD
480 			{
481 			  source.filename = $1;
482 			  redir.filename = $3;
483 			  $$ = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN);
484 			}
485 	|	GREATER_GREATER WORD
486 			{
487 			  source.dest = 1;
488 			  redir.filename = $2;
489 			  $$ = make_redirection (source, r_appending_to, redir, 0);
490 			}
491 	|	NUMBER GREATER_GREATER WORD
492 			{
493 			  source.dest = $1;
494 			  redir.filename = $3;
495 			  $$ = make_redirection (source, r_appending_to, redir, 0);
496 			}
497 	|	REDIR_WORD GREATER_GREATER WORD
498 			{
499 			  source.filename = $1;
500 			  redir.filename = $3;
501 			  $$ = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN);
502 			}
503 	|	GREATER_BAR WORD
504 			{
505 			  source.dest = 1;
506 			  redir.filename = $2;
507 			  $$ = make_redirection (source, r_output_force, redir, 0);
508 			}
509 	|	NUMBER GREATER_BAR WORD
510 			{
511 			  source.dest = $1;
512 			  redir.filename = $3;
513 			  $$ = make_redirection (source, r_output_force, redir, 0);
514 			}
515 	|	REDIR_WORD GREATER_BAR WORD
516 			{
517 			  source.filename = $1;
518 			  redir.filename = $3;
519 			  $$ = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN);
520 			}
521 	|	LESS_GREATER WORD
522 			{
523 			  source.dest = 0;
524 			  redir.filename = $2;
525 			  $$ = make_redirection (source, r_input_output, redir, 0);
526 			}
527 	|	NUMBER LESS_GREATER WORD
528 			{
529 			  source.dest = $1;
530 			  redir.filename = $3;
531 			  $$ = make_redirection (source, r_input_output, redir, 0);
532 			}
533 	|	REDIR_WORD LESS_GREATER WORD
534 			{
535 			  source.filename = $1;
536 			  redir.filename = $3;
537 			  $$ = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN);
538 			}
539 	|	LESS_LESS WORD
540 			{
541 			  source.dest = 0;
542 			  redir.filename = $2;
543 			  $$ = make_redirection (source, r_reading_until, redir, 0);
544 			  push_heredoc ($$);
545 			}
546 	|	NUMBER LESS_LESS WORD
547 			{
548 			  source.dest = $1;
549 			  redir.filename = $3;
550 			  $$ = make_redirection (source, r_reading_until, redir, 0);
551 			  push_heredoc ($$);
552 			}
553 	|	REDIR_WORD LESS_LESS WORD
554 			{
555 			  source.filename = $1;
556 			  redir.filename = $3;
557 			  $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN);
558 			  push_heredoc ($$);
559 			}
560 	|	LESS_LESS_MINUS WORD
561 			{
562 			  source.dest = 0;
563 			  redir.filename = $2;
564 			  $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
565 			  push_heredoc ($$);
566 			}
567 	|	NUMBER LESS_LESS_MINUS WORD
568 			{
569 			  source.dest = $1;
570 			  redir.filename = $3;
571 			  $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
572 			  push_heredoc ($$);
573 			}
574 	|	REDIR_WORD  LESS_LESS_MINUS WORD
575 			{
576 			  source.filename = $1;
577 			  redir.filename = $3;
578 			  $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN);
579 			  push_heredoc ($$);
580 			}
581 	|	LESS_LESS_LESS WORD
582 			{
583 			  source.dest = 0;
584 			  redir.filename = $2;
585 			  $$ = make_redirection (source, r_reading_string, redir, 0);
586 			}
587 	|	NUMBER LESS_LESS_LESS WORD
588 			{
589 			  source.dest = $1;
590 			  redir.filename = $3;
591 			  $$ = make_redirection (source, r_reading_string, redir, 0);
592 			}
593 	|	REDIR_WORD LESS_LESS_LESS WORD
594 			{
595 			  source.filename = $1;
596 			  redir.filename = $3;
597 			  $$ = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN);
598 			}
599 	|	LESS_AND NUMBER
600 			{
601 			  source.dest = 0;
602 			  redir.dest = $2;
603 			  $$ = make_redirection (source, r_duplicating_input, redir, 0);
604 			}
605 	|	NUMBER LESS_AND NUMBER
606 			{
607 			  source.dest = $1;
608 			  redir.dest = $3;
609 			  $$ = make_redirection (source, r_duplicating_input, redir, 0);
610 			}
611 	|	REDIR_WORD LESS_AND NUMBER
612 			{
613 			  source.filename = $1;
614 			  redir.dest = $3;
615 			  $$ = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN);
616 			}
617 	|	GREATER_AND NUMBER
618 			{
619 			  source.dest = 1;
620 			  redir.dest = $2;
621 			  $$ = make_redirection (source, r_duplicating_output, redir, 0);
622 			}
623 	|	NUMBER GREATER_AND NUMBER
624 			{
625 			  source.dest = $1;
626 			  redir.dest = $3;
627 			  $$ = make_redirection (source, r_duplicating_output, redir, 0);
628 			}
629 	|	REDIR_WORD GREATER_AND NUMBER
630 			{
631 			  source.filename = $1;
632 			  redir.dest = $3;
633 			  $$ = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN);
634 			}
635 	|	LESS_AND WORD
636 			{
637 			  source.dest = 0;
638 			  redir.filename = $2;
639 			  $$ = make_redirection (source, r_duplicating_input_word, redir, 0);
640 			}
641 	|	NUMBER LESS_AND WORD
642 			{
643 			  source.dest = $1;
644 			  redir.filename = $3;
645 			  $$ = make_redirection (source, r_duplicating_input_word, redir, 0);
646 			}
647 	|	REDIR_WORD LESS_AND WORD
648 			{
649 			  source.filename = $1;
650 			  redir.filename = $3;
651 			  $$ = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN);
652 			}
653 	|	GREATER_AND WORD
654 			{
655 			  source.dest = 1;
656 			  redir.filename = $2;
657 			  $$ = make_redirection (source, r_duplicating_output_word, redir, 0);
658 			}
659 	|	NUMBER GREATER_AND WORD
660 			{
661 			  source.dest = $1;
662 			  redir.filename = $3;
663 			  $$ = make_redirection (source, r_duplicating_output_word, redir, 0);
664 			}
665 	|	REDIR_WORD GREATER_AND WORD
666 			{
667 			  source.filename = $1;
668 			  redir.filename = $3;
669 			  $$ = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN);
670 			}
671 	|	GREATER_AND '-'
672 			{
673 			  source.dest = 1;
674 			  redir.dest = 0;
675 			  $$ = make_redirection (source, r_close_this, redir, 0);
676 			}
677 	|	NUMBER GREATER_AND '-'
678 			{
679 			  source.dest = $1;
680 			  redir.dest = 0;
681 			  $$ = make_redirection (source, r_close_this, redir, 0);
682 			}
683 	|	REDIR_WORD GREATER_AND '-'
684 			{
685 			  source.filename = $1;
686 			  redir.dest = 0;
687 			  $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
688 			}
689 	|	LESS_AND '-'
690 			{
691 			  source.dest = 0;
692 			  redir.dest = 0;
693 			  $$ = make_redirection (source, r_close_this, redir, 0);
694 			}
695 	|	NUMBER LESS_AND '-'
696 			{
697 			  source.dest = $1;
698 			  redir.dest = 0;
699 			  $$ = make_redirection (source, r_close_this, redir, 0);
700 			}
701 	|	REDIR_WORD LESS_AND '-'
702 			{
703 			  source.filename = $1;
704 			  redir.dest = 0;
705 			  $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
706 			}
707 	|	AND_GREATER WORD
708 			{
709 			  source.dest = 1;
710 			  redir.filename = $2;
711 			  $$ = make_redirection (source, r_err_and_out, redir, 0);
712 			}
713 	|	AND_GREATER_GREATER WORD
714 			{
715 			  source.dest = 1;
716 			  redir.filename = $2;
717 			  $$ = make_redirection (source, r_append_err_and_out, redir, 0);
718 			}
719 	;
720 
721 simple_command_element: WORD
722 			{ $$.word = $1; $$.redirect = 0; }
723 	|	ASSIGNMENT_WORD
724 			{ $$.word = $1; $$.redirect = 0; }
725 	|	redirection
726 			{ $$.redirect = $1; $$.word = 0; }
727 	;
728 
729 redirection_list: redirection
730 			{
731 			  $$ = $1;
732 			}
733 	|	redirection_list redirection
734 			{
735 			  register REDIRECT *t;
736 
737 			  for (t = $1; t->next; t = t->next)
738 			    ;
739 			  t->next = $2;
740 			  $$ = $1;
741 			}
742 	;
743 
744 simple_command:	simple_command_element
745 			{ $$ = make_simple_command ($1, (COMMAND *)NULL); }
746 	|	simple_command simple_command_element
747 			{ $$ = make_simple_command ($2, $1); }
748 	;
749 
750 command:	simple_command
751 			{ $$ = clean_simple_command ($1); }
752 	|	shell_command
753 			{ $$ = $1; }
754 	|	shell_command redirection_list
755 			{
756 			  COMMAND *tc;
757 
758 			  tc = $1;
759 			  if (tc && tc->redirects)
760 			    {
761 			      register REDIRECT *t;
762 			      for (t = tc->redirects; t->next; t = t->next)
763 				;
764 			      t->next = $2;
765 			    }
766 			  else if (tc)
767 			    tc->redirects = $2;
768 			  $$ = $1;
769 			}
770 	|	function_def
771 			{ $$ = $1; }
772 	|	coproc
773 			{ $$ = $1; }
774 	;
775 
776 shell_command:	for_command
777 			{ $$ = $1; }
778 	|	case_command
779 			{ $$ = $1; }
780  	|	WHILE compound_list DO compound_list DONE
781 			{ $$ = make_while_command ($2, $4); }
782 	|	UNTIL compound_list DO compound_list DONE
783 			{ $$ = make_until_command ($2, $4); }
784 	|	select_command
785 			{ $$ = $1; }
786 	|	if_command
787 			{ $$ = $1; }
788 	|	subshell
789 			{ $$ = $1; }
790 	|	group_command
791 			{ $$ = $1; }
792 	|	arith_command
793 			{ $$ = $1; }
794 	|	cond_command
795 			{ $$ = $1; }
796 	|	arith_for_command
797 			{ $$ = $1; }
798 	;
799 
800 for_command:	FOR WORD newline_list DO compound_list DONE
801 			{
802 			  $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
803 			  if (word_top > 0) word_top--;
804 			}
805 	|	FOR WORD newline_list '{' compound_list '}'
806 			{
807 			  $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
808 			  if (word_top > 0) word_top--;
809 			}
810 	|	FOR WORD ';' newline_list DO compound_list DONE
811 			{
812 			  $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
813 			  if (word_top > 0) word_top--;
814 			}
815 	|	FOR WORD ';' newline_list '{' compound_list '}'
816 			{
817 			  $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
818 			  if (word_top > 0) word_top--;
819 			}
820 	|	FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
821 			{
822 			  $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
823 			  if (word_top > 0) word_top--;
824 			}
825 	|	FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
826 			{
827 			  $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
828 			  if (word_top > 0) word_top--;
829 			}
830 	|	FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE
831 			{
832 			  $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
833 			  if (word_top > 0) word_top--;
834 			}
835 	|	FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}'
836 			{
837 			  $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
838 			  if (word_top > 0) word_top--;
839 			}
840 	;
841 
842 arith_for_command:	FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE
843 				{
844 				  $$ = make_arith_for_command ($2, $6, arith_for_lineno);
845 				  if ($$ == 0) YYERROR;
846 				  if (word_top > 0) word_top--;
847 				}
848 	|		FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'
849 				{
850 				  $$ = make_arith_for_command ($2, $6, arith_for_lineno);
851 				  if ($$ == 0) YYERROR;
852 				  if (word_top > 0) word_top--;
853 				}
854 	|		FOR ARITH_FOR_EXPRS DO compound_list DONE
855 				{
856 				  $$ = make_arith_for_command ($2, $4, arith_for_lineno);
857 				  if ($$ == 0) YYERROR;
858 				  if (word_top > 0) word_top--;
859 				}
860 	|		FOR ARITH_FOR_EXPRS '{' compound_list '}'
861 				{
862 				  $$ = make_arith_for_command ($2, $4, arith_for_lineno);
863 				  if ($$ == 0) YYERROR;
864 				  if (word_top > 0) word_top--;
865 				}
866 	;
867 
868 select_command:	SELECT WORD newline_list DO list DONE
869 			{
870 			  $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
871 			  if (word_top > 0) word_top--;
872 			}
873 	|	SELECT WORD newline_list '{' list '}'
874 			{
875 			  $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
876 			  if (word_top > 0) word_top--;
877 			}
878 	|	SELECT WORD ';' newline_list DO list DONE
879 			{
880 			  $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
881 			  if (word_top > 0) word_top--;
882 			}
883 	|	SELECT WORD ';' newline_list '{' list '}'
884 			{
885 			  $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
886 			  if (word_top > 0) word_top--;
887 			}
888 	|	SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
889 			{
890 			  $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
891 			  if (word_top > 0) word_top--;
892 			}
893 	|	SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
894 			{
895 			  $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
896 			  if (word_top > 0) word_top--;
897 			}
898 	|	SELECT WORD newline_list IN list_terminator newline_list DO compound_list DONE
899 			{
900 			  $$ = make_select_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
901 			  if (word_top > 0) word_top--;
902 			}
903 	|	SELECT WORD newline_list IN list_terminator newline_list '{' compound_list '}'
904 			{
905 			  $$ = make_select_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
906 			  if (word_top > 0) word_top--;
907 			}
908 	;
909 
910 case_command:	CASE WORD newline_list IN newline_list ESAC
911 			{
912 			  $$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]);
913 			  if (word_top > 0) word_top--;
914 			}
915 	|	CASE WORD newline_list IN case_clause_sequence newline_list ESAC
916 			{
917 			  $$ = make_case_command ($2, $5, word_lineno[word_top]);
918 			  if (word_top > 0) word_top--;
919 			}
920 	|	CASE WORD newline_list IN case_clause ESAC
921 			{
922 			  $$ = make_case_command ($2, $5, word_lineno[word_top]);
923 			  if (word_top > 0) word_top--;
924 			}
925 	;
926 
927 function_def:	WORD '(' ')' newline_list function_body
928 			{ $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
929 	|	FUNCTION WORD '(' ')' newline_list function_body
930 			{ $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
931 	|	FUNCTION WORD function_body
932 			{ $$ = make_function_def ($2, $3, function_dstart, function_bstart); }
933 	|	FUNCTION WORD '\n' newline_list function_body
934 			{ $$ = make_function_def ($2, $5, function_dstart, function_bstart); }
935 	;
936 
937 function_body:	shell_command
938 			{ $$ = $1; }
939 	|	shell_command redirection_list
940 			{
941 			  COMMAND *tc;
942 
943 			  tc = $1;
944 			  /* According to Posix.2 3.9.5, redirections
945 			     specified after the body of a function should
946 			     be attached to the function and performed when
947 			     the function is executed, not as part of the
948 			     function definition command. */
949 			  /* XXX - I don't think it matters, but we might
950 			     want to change this in the future to avoid
951 			     problems differentiating between a function
952 			     definition with a redirection and a function
953 			     definition containing a single command with a
954 			     redirection.  The two are semantically equivalent,
955 			     though -- the only difference is in how the
956 			     command printing code displays the redirections. */
957 			  if (tc && tc->redirects)
958 			    {
959 			      register REDIRECT *t;
960 			      for (t = tc->redirects; t->next; t = t->next)
961 				;
962 			      t->next = $2;
963 			    }
964 			  else if (tc)
965 			    tc->redirects = $2;
966 			  $$ = $1;
967 			}
968 	;
969 
970 subshell:	'(' compound_list ')'
971 			{
972 			  $$ = make_subshell_command ($2);
973 			  $$->flags |= CMD_WANT_SUBSHELL;
974 			}
975 	;
976 
977 coproc:		COPROC shell_command
978 			{
979 			  $$ = make_coproc_command ("COPROC", $2);
980 			  $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
981 			}
982 	|	COPROC shell_command redirection_list
983 			{
984 			  COMMAND *tc;
985 
986 			  tc = $2;
987 			  if (tc && tc->redirects)
988 			    {
989 			      register REDIRECT *t;
990 			      for (t = tc->redirects; t->next; t = t->next)
991 				;
992 			      t->next = $3;
993 			    }
994 			  else if (tc)
995 			    tc->redirects = $3;
996 			  $$ = make_coproc_command ("COPROC", $2);
997 			  $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
998 			}
999 	|	COPROC WORD shell_command
1000 			{
1001 			  $$ = make_coproc_command ($2->word, $3);
1002 			  $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
1003 			}
1004 	|	COPROC WORD shell_command redirection_list
1005 			{
1006 			  COMMAND *tc;
1007 
1008 			  tc = $3;
1009 			  if (tc && tc->redirects)
1010 			    {
1011 			      register REDIRECT *t;
1012 			      for (t = tc->redirects; t->next; t = t->next)
1013 				;
1014 			      t->next = $4;
1015 			    }
1016 			  else if (tc)
1017 			    tc->redirects = $4;
1018 			  $$ = make_coproc_command ($2->word, $3);
1019 			  $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
1020 			}
1021 	|	COPROC simple_command
1022 			{
1023 			  $$ = make_coproc_command ("COPROC", clean_simple_command ($2));
1024 			  $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
1025 			}
1026 	;
1027 
1028 if_command:	IF compound_list THEN compound_list FI
1029 			{ $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
1030 	|	IF compound_list THEN compound_list ELSE compound_list FI
1031 			{ $$ = make_if_command ($2, $4, $6); }
1032 	|	IF compound_list THEN compound_list elif_clause FI
1033 			{ $$ = make_if_command ($2, $4, $5); }
1034 	;
1035 
1036 
1037 group_command:	'{' compound_list '}'
1038 			{ $$ = make_group_command ($2); }
1039 	;
1040 
1041 arith_command:	ARITH_CMD
1042 			{ $$ = make_arith_command ($1); }
1043 	;
1044 
1045 cond_command:	COND_START COND_CMD COND_END
1046 			{ $$ = $2; }
1047 	;
1048 
1049 elif_clause:	ELIF compound_list THEN compound_list
1050 			{ $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
1051 	|	ELIF compound_list THEN compound_list ELSE compound_list
1052 			{ $$ = make_if_command ($2, $4, $6); }
1053 	|	ELIF compound_list THEN compound_list elif_clause
1054 			{ $$ = make_if_command ($2, $4, $5); }
1055 	;
1056 
1057 case_clause:	pattern_list
1058 	|	case_clause_sequence pattern_list
1059 			{ $2->next = $1; $$ = $2; }
1060 	;
1061 
1062 pattern_list:	newline_list pattern ')' compound_list
1063 			{ $$ = make_pattern_list ($2, $4); }
1064 	|	newline_list pattern ')' newline_list
1065 			{ $$ = make_pattern_list ($2, (COMMAND *)NULL); }
1066 	|	newline_list '(' pattern ')' compound_list
1067 			{ $$ = make_pattern_list ($3, $5); }
1068 	|	newline_list '(' pattern ')' newline_list
1069 			{ $$ = make_pattern_list ($3, (COMMAND *)NULL); }
1070 	;
1071 
1072 case_clause_sequence:  pattern_list SEMI_SEMI
1073 			{ $$ = $1; }
1074 	|	case_clause_sequence pattern_list SEMI_SEMI
1075 			{ $2->next = $1; $$ = $2; }
1076 	|	pattern_list SEMI_AND
1077 			{ $1->flags |= CASEPAT_FALLTHROUGH; $$ = $1; }
1078 	|	case_clause_sequence pattern_list SEMI_AND
1079 			{ $2->flags |= CASEPAT_FALLTHROUGH; $2->next = $1; $$ = $2; }
1080 	|	pattern_list SEMI_SEMI_AND
1081 			{ $1->flags |= CASEPAT_TESTNEXT; $$ = $1; }
1082 	|	case_clause_sequence pattern_list SEMI_SEMI_AND
1083 			{ $2->flags |= CASEPAT_TESTNEXT; $2->next = $1; $$ = $2; }
1084 	;
1085 
1086 pattern:	WORD
1087 			{ $$ = make_word_list ($1, (WORD_LIST *)NULL); }
1088 	|	pattern '|' WORD
1089 			{ $$ = make_word_list ($3, $1); }
1090 	;
1091 
1092 /* A list allows leading or trailing newlines and
1093    newlines as operators (equivalent to semicolons).
1094    It must end with a newline or semicolon.
1095    Lists are used within commands such as if, for, while.  */
1096 
1097 list:		newline_list list0
1098 			{
1099 			  $$ = $2;
1100 			  if (need_here_doc)
1101 			    gather_here_documents ();
1102 			 }
1103 	;
1104 
1105 compound_list:	list
1106 	|	newline_list list1
1107 			{
1108 			  $$ = $2;
1109 			}
1110 	;
1111 
1112 list0:  	list1 '\n' newline_list
1113 	|	list1 '&' newline_list
1114 			{
1115 			  if ($1->type == cm_connection)
1116 			    $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
1117 			  else
1118 			    $$ = command_connect ($1, (COMMAND *)NULL, '&');
1119 			}
1120 	|	list1 ';' newline_list
1121 
1122 	;
1123 
1124 list1:		list1 AND_AND newline_list list1
1125 			{ $$ = command_connect ($1, $4, AND_AND); }
1126 	|	list1 OR_OR newline_list list1
1127 			{ $$ = command_connect ($1, $4, OR_OR); }
1128 	|	list1 '&' newline_list list1
1129 			{
1130 			  if ($1->type == cm_connection)
1131 			    $$ = connect_async_list ($1, $4, '&');
1132 			  else
1133 			    $$ = command_connect ($1, $4, '&');
1134 			}
1135 	|	list1 ';' newline_list list1
1136 			{ $$ = command_connect ($1, $4, ';'); }
1137 	|	list1 '\n' newline_list list1
1138 			{ $$ = command_connect ($1, $4, ';'); }
1139 	|	pipeline_command
1140 			{ $$ = $1; }
1141 	;
1142 
1143 simple_list_terminator:	'\n'
1144 	|	yacc_EOF
1145 	;
1146 
1147 list_terminator:'\n'
1148 		{ $$ = '\n'; }
1149 	|	';'
1150 		{ $$ = ';'; }
1151 	|	yacc_EOF
1152 		{ $$ = yacc_EOF; }
1153 	;
1154 
1155 newline_list:
1156 	|	newline_list '\n'
1157 	;
1158 
1159 /* A simple_list is a list that contains no significant newlines
1160    and no leading or trailing newlines.  Newlines are allowed
1161    only following operators, where they are not significant.
1162 
1163    This is what an inputunit consists of.  */
1164 
1165 simple_list:	simple_list1
1166 			{
1167 			  $$ = $1;
1168 			  if (need_here_doc)
1169 			    gather_here_documents ();
1170 			  if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1171 			    {
1172 			      global_command = $1;
1173 			      eof_encountered = 0;
1174 			      rewind_input_string ();
1175 			      YYACCEPT;
1176 			    }
1177 			}
1178 	|	simple_list1 '&'
1179 			{
1180 			  if ($1->type == cm_connection)
1181 			    $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
1182 			  else
1183 			    $$ = command_connect ($1, (COMMAND *)NULL, '&');
1184 			  if (need_here_doc)
1185 			    gather_here_documents ();
1186 			  if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1187 			    {
1188 			      global_command = $1;
1189 			      eof_encountered = 0;
1190 			      rewind_input_string ();
1191 			      YYACCEPT;
1192 			    }
1193 			}
1194 	|	simple_list1 ';'
1195 			{
1196 			  $$ = $1;
1197 			  if (need_here_doc)
1198 			    gather_here_documents ();
1199 			  if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1200 			    {
1201 			      global_command = $1;
1202 			      eof_encountered = 0;
1203 			      rewind_input_string ();
1204 			      YYACCEPT;
1205 			    }
1206 			}
1207 	;
1208 
1209 simple_list1:	simple_list1 AND_AND newline_list simple_list1
1210 			{ $$ = command_connect ($1, $4, AND_AND); }
1211 	|	simple_list1 OR_OR newline_list simple_list1
1212 			{ $$ = command_connect ($1, $4, OR_OR); }
1213 	|	simple_list1 '&' simple_list1
1214 			{
1215 			  if ($1->type == cm_connection)
1216 			    $$ = connect_async_list ($1, $3, '&');
1217 			  else
1218 			    $$ = command_connect ($1, $3, '&');
1219 			}
1220 	|	simple_list1 ';' simple_list1
1221 			{ $$ = command_connect ($1, $3, ';'); }
1222 
1223 	|	pipeline_command
1224 			{ $$ = $1; }
1225 	;
1226 
1227 pipeline_command: pipeline
1228 			{ $$ = $1; }
1229 	|	BANG pipeline_command
1230 			{
1231 			  if ($2)
1232 			    $2->flags ^= CMD_INVERT_RETURN;	/* toggle */
1233 			  $$ = $2;
1234 			}
1235 	|	timespec pipeline_command
1236 			{
1237 			  if ($2)
1238 			    $2->flags |= $1;
1239 			  $$ = $2;
1240 			}
1241 	|	timespec list_terminator
1242 			{
1243 			  ELEMENT x;
1244 
1245 			  /* Boy, this is unclean.  `time' by itself can
1246 			     time a null command.  We cheat and push a
1247 			     newline back if the list_terminator was a newline
1248 			     to avoid the double-newline problem (one to
1249 			     terminate this, one to terminate the command) */
1250 			  x.word = 0;
1251 			  x.redirect = 0;
1252 			  $$ = make_simple_command (x, (COMMAND *)NULL);
1253 			  $$->flags |= $1;
1254 			  /* XXX - let's cheat and push a newline back */
1255 			  if ($2 == '\n')
1256 			    token_to_read = '\n';
1257 			  else if ($2 == ';')
1258 			    token_to_read = ';';
1259 			  parser_state &= ~PST_REDIRLIST;	/* make_simple_command sets this */
1260 			}
1261 	|	BANG list_terminator
1262 			{
1263 			  ELEMENT x;
1264 
1265 			  /* This is just as unclean.  Posix says that `!'
1266 			     by itself should be equivalent to `false'.
1267 			     We cheat and push a
1268 			     newline back if the list_terminator was a newline
1269 			     to avoid the double-newline problem (one to
1270 			     terminate this, one to terminate the command) */
1271 			  x.word = 0;
1272 			  x.redirect = 0;
1273 			  $$ = make_simple_command (x, (COMMAND *)NULL);
1274 			  $$->flags |= CMD_INVERT_RETURN;
1275 			  /* XXX - let's cheat and push a newline back */
1276 			  if ($2 == '\n')
1277 			    token_to_read = '\n';
1278 			  if ($2 == ';')
1279 			    token_to_read = ';';
1280 			  parser_state &= ~PST_REDIRLIST;	/* make_simple_command sets this */
1281 			}
1282 	;
1283 
1284 pipeline:	pipeline '|' newline_list pipeline
1285 			{ $$ = command_connect ($1, $4, '|'); }
1286 	|	pipeline BAR_AND newline_list pipeline
1287 			{
1288 			  /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
1289 			  COMMAND *tc;
1290 			  REDIRECTEE rd, sd;
1291 			  REDIRECT *r;
1292 
1293 			  tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
1294 			  sd.dest = 2;
1295 			  rd.dest = 1;
1296 			  r = make_redirection (sd, r_duplicating_output, rd, 0);
1297 			  if (tc->redirects)
1298 			    {
1299 			      register REDIRECT *t;
1300 			      for (t = tc->redirects; t->next; t = t->next)
1301 				;
1302 			      t->next = r;
1303 			    }
1304 			  else
1305 			    tc->redirects = r;
1306 
1307 			  $$ = command_connect ($1, $4, '|');
1308 			}
1309 	|	command
1310 			{ $$ = $1; }
1311 	;
1312 
1313 timespec:	TIME
1314 			{ $$ = CMD_TIME_PIPELINE; }
1315 	|	TIME TIMEOPT
1316 			{ $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
1317 	|	TIME TIMEIGN
1318 			{ $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
1319 	|	TIME TIMEOPT TIMEIGN
1320 			{ $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
1321 	;
1322 %%
1323 
1324 /* Initial size to allocate for tokens, and the
1325    amount to grow them by. */
1326 #define TOKEN_DEFAULT_INITIAL_SIZE 496
1327 #define TOKEN_DEFAULT_GROW_SIZE 512
1328 
1329 /* Should we call prompt_again? */
1330 #define SHOULD_PROMPT() \
1331   (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
1332 
1333 #if defined (ALIAS)
1334 #  define expanding_alias() (pushed_string_list && pushed_string_list->expander)
1335 #else
1336 #  define expanding_alias() 0
1337 #endif
1338 
1339 /* Global var is non-zero when end of file has been reached. */
1340 int EOF_Reached = 0;
1341 
1342 #ifdef DEBUG
1343 static void
debug_parser(i)1344 debug_parser (i)
1345      int i;
1346 {
1347 #if YYDEBUG != 0
1348   yydebug = i;
1349   yyoutstream = stdout;
1350   yyerrstream = stderr;
1351 #endif
1352 }
1353 #endif
1354 
1355 /* yy_getc () returns the next available character from input or EOF.
1356    yy_ungetc (c) makes `c' the next character to read.
1357    init_yy_io (get, unget, type, location) makes the function GET the
1358    installed function for getting the next character, makes UNGET the
1359    installed function for un-getting a character, sets the type of stream
1360    (either string or file) from TYPE, and makes LOCATION point to where
1361    the input is coming from. */
1362 
1363 /* Unconditionally returns end-of-file. */
1364 int
return_EOF()1365 return_EOF ()
1366 {
1367   return (EOF);
1368 }
1369 
1370 /* Variable containing the current get and unget functions.
1371    See ./input.h for a clearer description. */
1372 BASH_INPUT bash_input;
1373 
1374 /* Set all of the fields in BASH_INPUT to NULL.  Free bash_input.name if it
1375    is non-null, avoiding a memory leak. */
1376 void
initialize_bash_input()1377 initialize_bash_input ()
1378 {
1379   bash_input.type = st_none;
1380   FREE (bash_input.name);
1381   bash_input.name = (char *)NULL;
1382   bash_input.location.file = (FILE *)NULL;
1383   bash_input.location.string = (char *)NULL;
1384   bash_input.getter = (sh_cget_func_t *)NULL;
1385   bash_input.ungetter = (sh_cunget_func_t *)NULL;
1386 }
1387 
1388 /* Set the contents of the current bash input stream from
1389    GET, UNGET, TYPE, NAME, and LOCATION. */
1390 void
init_yy_io(get,unget,type,name,location)1391 init_yy_io (get, unget, type, name, location)
1392      sh_cget_func_t *get;
1393      sh_cunget_func_t *unget;
1394      enum stream_type type;
1395      const char *name;
1396      INPUT_STREAM location;
1397 {
1398   bash_input.type = type;
1399   FREE (bash_input.name);
1400   bash_input.name = name ? savestring (name) : (char *)NULL;
1401 
1402   /* XXX */
1403 #if defined (CRAY)
1404   memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
1405 #else
1406   bash_input.location = location;
1407 #endif
1408   bash_input.getter = get;
1409   bash_input.ungetter = unget;
1410 }
1411 
1412 char *
yy_input_name()1413 yy_input_name ()
1414 {
1415   return (bash_input.name ? bash_input.name : "stdin");
1416 }
1417 
1418 /* Call this to get the next character of input. */
1419 static int
yy_getc()1420 yy_getc ()
1421 {
1422   return (*(bash_input.getter)) ();
1423 }
1424 
1425 /* Call this to unget C.  That is, to make C the next character
1426    to be read. */
1427 static int
yy_ungetc(c)1428 yy_ungetc (c)
1429      int c;
1430 {
1431   return (*(bash_input.ungetter)) (c);
1432 }
1433 
1434 #if defined (BUFFERED_INPUT)
1435 #ifdef INCLUDE_UNUSED
1436 int
input_file_descriptor()1437 input_file_descriptor ()
1438 {
1439   switch (bash_input.type)
1440     {
1441     case st_stream:
1442       return (fileno (bash_input.location.file));
1443     case st_bstream:
1444       return (bash_input.location.buffered_fd);
1445     case st_stdin:
1446     default:
1447       return (fileno (stdin));
1448     }
1449 }
1450 #endif
1451 #endif /* BUFFERED_INPUT */
1452 
1453 /* **************************************************************** */
1454 /*								    */
1455 /*		  Let input be read from readline ().		    */
1456 /*								    */
1457 /* **************************************************************** */
1458 
1459 #if defined (READLINE)
1460 char *current_readline_prompt = (char *)NULL;
1461 char *current_readline_line = (char *)NULL;
1462 int current_readline_line_index = 0;
1463 
1464 static int
yy_readline_get()1465 yy_readline_get ()
1466 {
1467   SigHandler *old_sigint;
1468   int line_len;
1469   unsigned char c;
1470 
1471   if (current_readline_line == 0)
1472     {
1473       if (bash_readline_initialized == 0)
1474 	initialize_readline ();
1475 
1476 #if defined (JOB_CONTROL)
1477       if (job_control)
1478 	give_terminal_to (shell_pgrp, 0);
1479 #endif /* JOB_CONTROL */
1480 
1481       old_sigint = IMPOSSIBLE_TRAP_HANDLER;
1482       if (signal_is_ignored (SIGINT) == 0)
1483 	{
1484 	  old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
1485 	}
1486 
1487       sh_unset_nodelay_mode (fileno (rl_instream));	/* just in case */
1488       current_readline_line = readline (current_readline_prompt ?
1489       					  current_readline_prompt : "");
1490 
1491       CHECK_TERMSIG;
1492       if (signal_is_ignored (SIGINT) == 0)
1493 	{
1494 	  if (old_sigint != IMPOSSIBLE_TRAP_HANDLER)
1495 	    set_signal_handler (SIGINT, old_sigint);
1496 	}
1497 
1498 #if 0
1499       /* Reset the prompt to the decoded value of prompt_string_pointer. */
1500       reset_readline_prompt ();
1501 #endif
1502 
1503       if (current_readline_line == 0)
1504 	return (EOF);
1505 
1506       current_readline_line_index = 0;
1507       line_len = strlen (current_readline_line);
1508 
1509       current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
1510       current_readline_line[line_len++] = '\n';
1511       current_readline_line[line_len] = '\0';
1512     }
1513 
1514   if (current_readline_line[current_readline_line_index] == 0)
1515     {
1516       free (current_readline_line);
1517       current_readline_line = (char *)NULL;
1518       return (yy_readline_get ());
1519     }
1520   else
1521     {
1522       c = current_readline_line[current_readline_line_index++];
1523       return (c);
1524     }
1525 }
1526 
1527 static int
yy_readline_unget(c)1528 yy_readline_unget (c)
1529      int c;
1530 {
1531   if (current_readline_line_index && current_readline_line)
1532     current_readline_line[--current_readline_line_index] = c;
1533   return (c);
1534 }
1535 
1536 void
with_input_from_stdin()1537 with_input_from_stdin ()
1538 {
1539   INPUT_STREAM location;
1540 
1541   if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
1542     {
1543       location.string = current_readline_line;
1544       init_yy_io (yy_readline_get, yy_readline_unget,
1545 		  st_stdin, "readline stdin", location);
1546     }
1547 }
1548 
1549 /* Will we be collecting another input line and printing a prompt? This uses
1550    different conditions than SHOULD_PROMPT(), since readline allows a user to
1551    embed a newline in the middle of the line it collects, which the parser
1552    will interpret as a line break and command delimiter. */
1553 int
parser_will_prompt()1554 parser_will_prompt ()
1555 {
1556   return (current_readline_line == 0 || current_readline_line[current_readline_line_index] == 0);
1557 }
1558 
1559 #else  /* !READLINE */
1560 
1561 void
with_input_from_stdin()1562 with_input_from_stdin ()
1563 {
1564   with_input_from_stream (stdin, "stdin");
1565 }
1566 #endif	/* !READLINE */
1567 
1568 /* **************************************************************** */
1569 /*								    */
1570 /*   Let input come from STRING.  STRING is zero terminated.	    */
1571 /*								    */
1572 /* **************************************************************** */
1573 
1574 static int
yy_string_get()1575 yy_string_get ()
1576 {
1577   register char *string;
1578   register unsigned char c;
1579 
1580   string = bash_input.location.string;
1581 
1582   /* If the string doesn't exist, or is empty, EOF found. */
1583   if (string && *string)
1584     {
1585       c = *string++;
1586       bash_input.location.string = string;
1587       return (c);
1588     }
1589   else
1590     return (EOF);
1591 }
1592 
1593 static int
yy_string_unget(c)1594 yy_string_unget (c)
1595      int c;
1596 {
1597   *(--bash_input.location.string) = c;
1598   return (c);
1599 }
1600 
1601 void
with_input_from_string(string,name)1602 with_input_from_string (string, name)
1603      char *string;
1604      const char *name;
1605 {
1606   INPUT_STREAM location;
1607 
1608   location.string = string;
1609   init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1610 }
1611 
1612 /* Count the number of characters we've consumed from bash_input.location.string
1613    and read into shell_input_line, but have not returned from shell_getc.
1614    That is the true input location.  Rewind bash_input.location.string by
1615    that number of characters, so it points to the last character actually
1616    consumed by the parser. */
1617 static void
rewind_input_string()1618 rewind_input_string ()
1619 {
1620   int xchars;
1621 
1622   /* number of unconsumed characters in the input -- XXX need to take newlines
1623      into account, e.g., $(...\n) */
1624   xchars = shell_input_line_len - shell_input_line_index;
1625   if (bash_input.location.string[-1] == '\n')
1626     xchars++;
1627 
1628   /* XXX - how to reflect bash_input.location.string back to string passed to
1629      parse_and_execute or xparse_dolparen?  xparse_dolparen needs to know how
1630      far into the string we parsed.  parse_and_execute knows where bash_input.
1631      location.string is, and how far from orig_string that is -- that's the
1632      number of characters the command consumed. */
1633 
1634   /* bash_input.location.string - xchars should be where we parsed to */
1635   /* need to do more validation on xchars value for sanity -- test cases. */
1636   bash_input.location.string -= xchars;
1637 }
1638 
1639 /* **************************************************************** */
1640 /*								    */
1641 /*		     Let input come from STREAM.		    */
1642 /*								    */
1643 /* **************************************************************** */
1644 
1645 /* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
1646    define, and just use getc/ungetc if it was defined, but since bash
1647    installs most of its signal handlers without the SA_RESTART flag, some
1648    signals received during a read(2) will not cause the read to be restarted.
1649    We will need to restart it ourselves. */
1650 
1651 static int
yy_stream_get()1652 yy_stream_get ()
1653 {
1654   int result;
1655 
1656   result = EOF;
1657   if (bash_input.location.file)
1658     {
1659       /* XXX - don't need terminate_immediately; getc_with_restart checks
1660 	 for terminating signals itself if read returns < 0 */
1661       result = getc_with_restart (bash_input.location.file);
1662     }
1663   return (result);
1664 }
1665 
1666 static int
yy_stream_unget(c)1667 yy_stream_unget (c)
1668      int c;
1669 {
1670   return (ungetc_with_restart (c, bash_input.location.file));
1671 }
1672 
1673 void
with_input_from_stream(stream,name)1674 with_input_from_stream (stream, name)
1675      FILE *stream;
1676      const char *name;
1677 {
1678   INPUT_STREAM location;
1679 
1680   location.file = stream;
1681   init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1682 }
1683 
1684 typedef struct stream_saver {
1685   struct stream_saver *next;
1686   BASH_INPUT bash_input;
1687   int line;
1688 #if defined (BUFFERED_INPUT)
1689   BUFFERED_STREAM *bstream;
1690 #endif /* BUFFERED_INPUT */
1691 } STREAM_SAVER;
1692 
1693 /* The globally known line number. */
1694 int line_number = 0;
1695 
1696 /* The line number offset set by assigning to LINENO.  Not currently used. */
1697 int line_number_base = 0;
1698 
1699 #if defined (COND_COMMAND)
1700 static int cond_lineno;
1701 static int cond_token;
1702 #endif
1703 
1704 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1705 
1706 void
push_stream(reset_lineno)1707 push_stream (reset_lineno)
1708      int reset_lineno;
1709 {
1710   STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1711 
1712   xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1713 
1714 #if defined (BUFFERED_INPUT)
1715   saver->bstream = (BUFFERED_STREAM *)NULL;
1716   /* If we have a buffered stream, clear out buffers[fd]. */
1717   if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1718     saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1719     					  (BUFFERED_STREAM *)NULL);
1720 #endif /* BUFFERED_INPUT */
1721 
1722   saver->line = line_number;
1723   bash_input.name = (char *)NULL;
1724   saver->next = stream_list;
1725   stream_list = saver;
1726   EOF_Reached = 0;
1727   if (reset_lineno)
1728     line_number = 0;
1729 }
1730 
1731 void
pop_stream()1732 pop_stream ()
1733 {
1734   if (!stream_list)
1735     EOF_Reached = 1;
1736   else
1737     {
1738       STREAM_SAVER *saver = stream_list;
1739 
1740       EOF_Reached = 0;
1741       stream_list = stream_list->next;
1742 
1743       init_yy_io (saver->bash_input.getter,
1744 		  saver->bash_input.ungetter,
1745 		  saver->bash_input.type,
1746 		  saver->bash_input.name,
1747 		  saver->bash_input.location);
1748 
1749 #if defined (BUFFERED_INPUT)
1750       /* If we have a buffered stream, restore buffers[fd]. */
1751       /* If the input file descriptor was changed while this was on the
1752 	 save stack, update the buffered fd to the new file descriptor and
1753 	 re-establish the buffer <-> bash_input fd correspondence. */
1754       if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1755 	{
1756 	  if (bash_input_fd_changed)
1757 	    {
1758 	      bash_input_fd_changed = 0;
1759 	      if (default_buffered_input >= 0)
1760 		{
1761 		  bash_input.location.buffered_fd = default_buffered_input;
1762 		  saver->bstream->b_fd = default_buffered_input;
1763 		  SET_CLOSE_ON_EXEC (default_buffered_input);
1764 		}
1765 	    }
1766 	  /* XXX could free buffered stream returned as result here. */
1767 	  set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
1768 	}
1769 #endif /* BUFFERED_INPUT */
1770 
1771       line_number = saver->line;
1772 
1773       FREE (saver->bash_input.name);
1774       free (saver);
1775     }
1776 }
1777 
1778 /* Return 1 if a stream of type TYPE is saved on the stack. */
1779 int
stream_on_stack(type)1780 stream_on_stack (type)
1781      enum stream_type type;
1782 {
1783   register STREAM_SAVER *s;
1784 
1785   for (s = stream_list; s; s = s->next)
1786     if (s->bash_input.type == type)
1787       return 1;
1788   return 0;
1789 }
1790 
1791 /* Save the current token state and return it in a malloced array. */
1792 int *
save_token_state()1793 save_token_state ()
1794 {
1795   int *ret;
1796 
1797   ret = (int *)xmalloc (4 * sizeof (int));
1798   ret[0] = last_read_token;
1799   ret[1] = token_before_that;
1800   ret[2] = two_tokens_ago;
1801   ret[3] = current_token;
1802   return ret;
1803 }
1804 
1805 void
restore_token_state(ts)1806 restore_token_state (ts)
1807      int *ts;
1808 {
1809   if (ts == 0)
1810     return;
1811   last_read_token = ts[0];
1812   token_before_that = ts[1];
1813   two_tokens_ago = ts[2];
1814   current_token = ts[3];
1815 }
1816 
1817 /*
1818  * This is used to inhibit alias expansion and reserved word recognition
1819  * inside case statement pattern lists.  A `case statement pattern list' is:
1820  *
1821  *	everything between the `in' in a `case word in' and the next ')'
1822  *	or `esac'
1823  *	everything between a `;;' and the next `)' or `esac'
1824  */
1825 
1826 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1827 
1828 #define END_OF_ALIAS 0
1829 
1830 /*
1831  * Pseudo-global variables used in implementing token-wise alias expansion.
1832  */
1833 
1834 /*
1835  * Pushing and popping strings.  This works together with shell_getc to
1836  * implement alias expansion on a per-token basis.
1837  */
1838 
1839 #define PSH_ALIAS	0x01
1840 #define PSH_DPAREN	0x02
1841 #define PSH_SOURCE	0x04
1842 #define PSH_ARRAY	0x08
1843 
1844 typedef struct string_saver {
1845   struct string_saver *next;
1846   int expand_alias;  /* Value to set expand_alias to when string is popped. */
1847   char *saved_line;
1848 #if defined (ALIAS)
1849   alias_t *expander;   /* alias that caused this line to be pushed. */
1850 #endif
1851   size_t saved_line_size, saved_line_index;
1852   int saved_line_terminator;
1853   int flags;
1854 } STRING_SAVER;
1855 
1856 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1857 
1858 /*
1859  * Push the current shell_input_line onto a stack of such lines and make S
1860  * the current input.  Used when expanding aliases.  EXPAND is used to set
1861  * the value of expand_next_token when the string is popped, so that the
1862  * word after the alias in the original line is handled correctly when the
1863  * alias expands to multiple words.  TOKEN is the token that was expanded
1864  * into S; it is saved and used to prevent infinite recursive expansion.
1865  */
1866 static void
push_string(s,expand,ap)1867 push_string (s, expand, ap)
1868      char *s;
1869      int expand;
1870      alias_t *ap;
1871 {
1872   STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
1873 
1874   temp->expand_alias = expand;
1875   temp->saved_line = shell_input_line;
1876   temp->saved_line_size = shell_input_line_size;
1877   temp->saved_line_index = shell_input_line_index;
1878   temp->saved_line_terminator = shell_input_line_terminator;
1879   temp->flags = 0;
1880 #if defined (ALIAS)
1881   temp->expander = ap;
1882   if (ap)
1883     temp->flags = PSH_ALIAS;
1884 #endif
1885   temp->next = pushed_string_list;
1886   pushed_string_list = temp;
1887 
1888 #if defined (ALIAS)
1889   if (ap)
1890     ap->flags |= AL_BEINGEXPANDED;
1891 #endif
1892 
1893   shell_input_line = s;
1894   shell_input_line_size = STRLEN (s);
1895   shell_input_line_index = 0;
1896   shell_input_line_terminator = '\0';
1897 #if 0
1898   parser_state &= ~PST_ALEXPNEXT;	/* XXX */
1899 #endif
1900 
1901   set_line_mbstate ();
1902 }
1903 
1904 /*
1905  * Make the top of the pushed_string stack be the current shell input.
1906  * Only called when there is something on the stack.  Called from shell_getc
1907  * when it thinks it has consumed the string generated by an alias expansion
1908  * and needs to return to the original input line.
1909  */
1910 static void
pop_string()1911 pop_string ()
1912 {
1913   STRING_SAVER *t;
1914 
1915   FREE (shell_input_line);
1916   shell_input_line = pushed_string_list->saved_line;
1917   shell_input_line_index = pushed_string_list->saved_line_index;
1918   shell_input_line_size = pushed_string_list->saved_line_size;
1919   shell_input_line_terminator = pushed_string_list->saved_line_terminator;
1920 
1921   if (pushed_string_list->expand_alias)
1922     parser_state |= PST_ALEXPNEXT;
1923   else
1924     parser_state &= ~PST_ALEXPNEXT;
1925 
1926   t = pushed_string_list;
1927   pushed_string_list = pushed_string_list->next;
1928 
1929 #if defined (ALIAS)
1930   if (t->expander)
1931     t->expander->flags &= ~AL_BEINGEXPANDED;
1932 #endif
1933 
1934   free ((char *)t);
1935 
1936   set_line_mbstate ();
1937 }
1938 
1939 static void
free_string_list()1940 free_string_list ()
1941 {
1942   register STRING_SAVER *t, *t1;
1943 
1944   for (t = pushed_string_list; t; )
1945     {
1946       t1 = t->next;
1947       FREE (t->saved_line);
1948 #if defined (ALIAS)
1949       if (t->expander)
1950 	t->expander->flags &= ~AL_BEINGEXPANDED;
1951 #endif
1952       free ((char *)t);
1953       t = t1;
1954     }
1955   pushed_string_list = (STRING_SAVER *)NULL;
1956 }
1957 
1958 #endif /* ALIAS || DPAREN_ARITHMETIC */
1959 
1960 void
free_pushed_string_input()1961 free_pushed_string_input ()
1962 {
1963 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1964   free_string_list ();
1965 #endif
1966 }
1967 
1968 int
parser_expanding_alias()1969 parser_expanding_alias ()
1970 {
1971   return (expanding_alias ());
1972 }
1973 
1974 void
parser_save_alias()1975 parser_save_alias ()
1976 {
1977 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1978   push_string ((char *)NULL, 0, (alias_t *)NULL);
1979   pushed_string_list->flags = PSH_SOURCE;	/* XXX - for now */
1980 #else
1981   ;
1982 #endif
1983 }
1984 
1985 void
parser_restore_alias()1986 parser_restore_alias ()
1987 {
1988 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1989   if (pushed_string_list)
1990     pop_string ();
1991 #else
1992   ;
1993 #endif
1994 }
1995 
1996 #if defined (ALIAS)
1997 /* Before freeing AP, make sure that there aren't any cases of pointer
1998    aliasing that could cause us to reference freed memory later on. */
1999 void
clear_string_list_expander(ap)2000 clear_string_list_expander (ap)
2001      alias_t *ap;
2002 {
2003   register STRING_SAVER *t;
2004 
2005   for (t = pushed_string_list; t; t = t->next)
2006     {
2007       if (t->expander && t->expander == ap)
2008 	t->expander = 0;
2009     }
2010 }
2011 #endif
2012 
2013 void
clear_shell_input_line()2014 clear_shell_input_line ()
2015 {
2016   if (shell_input_line)
2017     shell_input_line[shell_input_line_index = 0] = '\0';
2018 }
2019 
2020 /* Return a line of text, taken from wherever yylex () reads input.
2021    If there is no more input, then we return NULL.  If REMOVE_QUOTED_NEWLINE
2022    is non-zero, we remove unquoted \<newline> pairs.  This is used by
2023    read_secondary_line to read here documents. */
2024 static char *
read_a_line(remove_quoted_newline)2025 read_a_line (remove_quoted_newline)
2026      int remove_quoted_newline;
2027 {
2028   static char *line_buffer = (char *)NULL;
2029   static int buffer_size = 0;
2030   int indx, c, peekc, pass_next;
2031 
2032 #if defined (READLINE)
2033   if (no_line_editing && SHOULD_PROMPT ())
2034 #else
2035   if (SHOULD_PROMPT ())
2036 #endif
2037     print_prompt ();
2038 
2039   pass_next = indx = 0;
2040   while (1)
2041     {
2042       /* Allow immediate exit if interrupted during input. */
2043       QUIT;
2044 
2045       c = yy_getc ();
2046 
2047       /* Ignore null bytes in input. */
2048       if (c == 0)
2049 	{
2050 #if 0
2051 	  internal_warning ("read_a_line: ignored null byte in input");
2052 #endif
2053 	  continue;
2054 	}
2055 
2056       /* If there is no more input, then we return NULL. */
2057       if (c == EOF)
2058 	{
2059 	  if (interactive && bash_input.type == st_stream)
2060 	    clearerr (stdin);
2061 	  if (indx == 0)
2062 	    return ((char *)NULL);
2063 	  c = '\n';
2064 	}
2065 
2066       /* `+2' in case the final character in the buffer is a newline or we
2067 	 have to handle CTLESC or CTLNUL. */
2068       RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2069 
2070       /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2071 	 here document with an unquoted delimiter.  In this case,
2072 	 the line will be expanded as if it were in double quotes.
2073 	 We allow a backslash to escape the next character, but we
2074 	 need to treat the backslash specially only if a backslash
2075 	 quoting a backslash-newline pair appears in the line. */
2076       if (pass_next)
2077 	{
2078 	  line_buffer[indx++] = c;
2079 	  pass_next = 0;
2080 	}
2081       else if (c == '\\' && remove_quoted_newline)
2082 	{
2083 	  QUIT;
2084 	  peekc = yy_getc ();
2085 	  if (peekc == '\n')
2086 	    {
2087 	      line_number++;
2088 	      continue;	/* Make the unquoted \<newline> pair disappear. */
2089 	    }
2090 	  else
2091 	    {
2092 	      yy_ungetc (peekc);
2093 	      pass_next = 1;
2094 	      line_buffer[indx++] = c;		/* Preserve the backslash. */
2095 	    }
2096 	}
2097       else
2098 	{
2099 	  /* remove_quoted_newline is non-zero if the here-document delimiter
2100 	     is unquoted. In this case, we will be expanding the lines and
2101 	     need to make sure CTLESC and CTLNUL in the input are quoted. */
2102 	  if (remove_quoted_newline && (c == CTLESC || c == CTLNUL))
2103 	    line_buffer[indx++] = CTLESC;
2104 	  line_buffer[indx++] = c;
2105 	}
2106 
2107       if (c == '\n')
2108 	{
2109 	  line_buffer[indx] = '\0';
2110 	  return (line_buffer);
2111 	}
2112     }
2113 }
2114 
2115 /* Return a line as in read_a_line (), but insure that the prompt is
2116    the secondary prompt.  This is used to read the lines of a here
2117    document.  REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2118    newlines quoted with backslashes while reading the line.  It is
2119    non-zero unless the delimiter of the here document was quoted. */
2120 char *
read_secondary_line(remove_quoted_newline)2121 read_secondary_line (remove_quoted_newline)
2122      int remove_quoted_newline;
2123 {
2124   char *ret;
2125   int n, c;
2126 
2127   prompt_string_pointer = &ps2_prompt;
2128   if (SHOULD_PROMPT())
2129     prompt_again ();
2130   ret = read_a_line (remove_quoted_newline);
2131 #if defined (HISTORY)
2132   if (ret && remember_on_history && (parser_state & PST_HEREDOC))
2133     {
2134       /* To make adding the here-document body right, we need to rely on
2135 	 history_delimiting_chars() returning \n for the first line of the
2136 	 here-document body and the null string for the second and subsequent
2137 	 lines, so we avoid double newlines.
2138 	 current_command_line_count == 2 for the first line of the body. */
2139 
2140       current_command_line_count++;
2141       maybe_add_history (ret);
2142     }
2143 #endif /* HISTORY */
2144   return ret;
2145 }
2146 
2147 /* **************************************************************** */
2148 /*								    */
2149 /*				YYLEX ()			    */
2150 /*								    */
2151 /* **************************************************************** */
2152 
2153 /* Reserved words.  These are only recognized as the first word of a
2154    command. */
2155 STRING_INT_ALIST word_token_alist[] = {
2156   { "if", IF },
2157   { "then", THEN },
2158   { "else", ELSE },
2159   { "elif", ELIF },
2160   { "fi", FI },
2161   { "case", CASE },
2162   { "esac", ESAC },
2163   { "for", FOR },
2164 #if defined (SELECT_COMMAND)
2165   { "select", SELECT },
2166 #endif
2167   { "while", WHILE },
2168   { "until", UNTIL },
2169   { "do", DO },
2170   { "done", DONE },
2171   { "in", IN },
2172   { "function", FUNCTION },
2173 #if defined (COMMAND_TIMING)
2174   { "time", TIME },
2175 #endif
2176   { "{", '{' },
2177   { "}", '}' },
2178   { "!", BANG },
2179 #if defined (COND_COMMAND)
2180   { "[[", COND_START },
2181   { "]]", COND_END },
2182 #endif
2183 #if defined (COPROCESS_SUPPORT)
2184   { "coproc", COPROC },
2185 #endif
2186   { (char *)NULL, 0}
2187 };
2188 
2189 /* other tokens that can be returned by read_token() */
2190 STRING_INT_ALIST other_token_alist[] = {
2191   /* Multiple-character tokens with special values */
2192   { "--", TIMEIGN },
2193   { "-p", TIMEOPT },
2194   { "&&", AND_AND },
2195   { "||", OR_OR },
2196   { ">>", GREATER_GREATER },
2197   { "<<", LESS_LESS },
2198   { "<&", LESS_AND },
2199   { ">&", GREATER_AND },
2200   { ";;", SEMI_SEMI },
2201   { ";&", SEMI_AND },
2202   { ";;&", SEMI_SEMI_AND },
2203   { "<<-", LESS_LESS_MINUS },
2204   { "<<<", LESS_LESS_LESS },
2205   { "&>", AND_GREATER },
2206   { "&>>", AND_GREATER_GREATER },
2207   { "<>", LESS_GREATER },
2208   { ">|", GREATER_BAR },
2209   { "|&", BAR_AND },
2210   { "EOF", yacc_EOF },
2211   /* Tokens whose value is the character itself */
2212   { ">", '>' },
2213   { "<", '<' },
2214   { "-", '-' },
2215   { "{", '{' },
2216   { "}", '}' },
2217   { ";", ';' },
2218   { "(", '(' },
2219   { ")", ')' },
2220   { "|", '|' },
2221   { "&", '&' },
2222   { "newline", '\n' },
2223   { (char *)NULL, 0}
2224 };
2225 
2226 /* others not listed here:
2227 	WORD			look at yylval.word
2228 	ASSIGNMENT_WORD		look at yylval.word
2229 	NUMBER			look at yylval.number
2230 	ARITH_CMD		look at yylval.word_list
2231 	ARITH_FOR_EXPRS		look at yylval.word_list
2232 	COND_CMD		look at yylval.command
2233 */
2234 
2235 /* These are used by read_token_word, but appear up here so that shell_getc
2236    can use them to decide when to add otherwise blank lines to the history. */
2237 
2238 /* The primary delimiter stack. */
2239 struct dstack dstack = {  (char *)NULL, 0, 0 };
2240 
2241 /* A temporary delimiter stack to be used when decoding prompt strings.
2242    This is needed because command substitutions in prompt strings (e.g., PS2)
2243    can screw up the parser's quoting state. */
2244 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2245 
2246 /* Macro for accessing the top delimiter on the stack.  Returns the
2247    delimiter or zero if none. */
2248 #define current_delimiter(ds) \
2249   (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2250 
2251 #define push_delimiter(ds, character) \
2252   do \
2253     { \
2254       if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2255 	ds.delimiters = (char *)xrealloc \
2256 	  (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2257       ds.delimiters[ds.delimiter_depth] = character; \
2258       ds.delimiter_depth++; \
2259     } \
2260   while (0)
2261 
2262 #define pop_delimiter(ds)	ds.delimiter_depth--
2263 
2264 /* Return the next shell input character.  This always reads characters
2265    from shell_input_line; when that line is exhausted, it is time to
2266    read the next line.  This is called by read_token when the shell is
2267    processing normal command input. */
2268 
2269 /* This implements one-character lookahead/lookbehind across physical input
2270    lines, to avoid something being lost because it's pushed back with
2271    shell_ungetc when we're at the start of a line. */
2272 static int eol_ungetc_lookahead = 0;
2273 
2274 static int unquoted_backslash = 0;
2275 
2276 static int
shell_getc(remove_quoted_newline)2277 shell_getc (remove_quoted_newline)
2278      int remove_quoted_newline;
2279 {
2280   register int i;
2281   int c, truncating, last_was_backslash;
2282   unsigned char uc;
2283 
2284   QUIT;
2285 
2286   last_was_backslash = 0;
2287   if (sigwinch_received)
2288     {
2289       sigwinch_received = 0;
2290       get_new_window_size (0, (int *)0, (int *)0);
2291     }
2292 
2293   if (eol_ungetc_lookahead)
2294     {
2295       c = eol_ungetc_lookahead;
2296       eol_ungetc_lookahead = 0;
2297       return (c);
2298     }
2299 
2300 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2301   /* If shell_input_line[shell_input_line_index] == 0, but there is
2302      something on the pushed list of strings, then we don't want to go
2303      off and get another line.  We let the code down below handle it. */
2304 
2305   if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2306 			    (pushed_string_list == (STRING_SAVER *)NULL)))
2307 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2308   if (!shell_input_line || !shell_input_line[shell_input_line_index])
2309 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2310     {
2311       line_number++;
2312 
2313       /* Let's not let one really really long line blow up memory allocation */
2314       if (shell_input_line && shell_input_line_size >= 32768)
2315 	{
2316 	  free (shell_input_line);
2317 	  shell_input_line = 0;
2318 	  shell_input_line_size = 0;
2319 	}
2320 
2321     restart_read:
2322 
2323       /* Allow immediate exit if interrupted during input. */
2324       QUIT;
2325 
2326       i = truncating = 0;
2327       shell_input_line_terminator = 0;
2328 
2329       /* If the shell is interactive, but not currently printing a prompt
2330          (interactive_shell && interactive == 0), we don't want to print
2331          notifies or cleanup the jobs -- we want to defer it until we do
2332          print the next prompt. */
2333       if (interactive_shell == 0 || SHOULD_PROMPT())
2334 	{
2335 #if defined (JOB_CONTROL)
2336       /* This can cause a problem when reading a command as the result
2337 	 of a trap, when the trap is called from flush_child.  This call
2338 	 had better not cause jobs to disappear from the job table in
2339 	 that case, or we will have big trouble. */
2340 	  notify_and_cleanup ();
2341 #else /* !JOB_CONTROL */
2342 	  cleanup_dead_jobs ();
2343 #endif /* !JOB_CONTROL */
2344 	}
2345 
2346 #if defined (READLINE)
2347       if (no_line_editing && SHOULD_PROMPT())
2348 #else
2349       if (SHOULD_PROMPT())
2350 #endif
2351 	print_prompt ();
2352 
2353       if (bash_input.type == st_stream)
2354 	clearerr (stdin);
2355 
2356       while (1)
2357 	{
2358 	  c = yy_getc ();
2359 
2360 	  /* Allow immediate exit if interrupted during input. */
2361 	  QUIT;
2362 
2363 	  if (c == '\0')
2364 	    {
2365 #if 0
2366 	      internal_warning ("shell_getc: ignored null byte in input");
2367 #endif
2368 	      /* If we get EOS while parsing a string, treat it as EOF so we
2369 		 don't just keep looping. Happens very rarely */
2370 	      if (bash_input.type == st_string)
2371 		{
2372 		  if (i == 0)
2373 		    shell_input_line_terminator = EOF;
2374 		  shell_input_line[i] = '\0';
2375 		  c = EOF;
2376 		  break;
2377 		}
2378 	      continue;
2379 	    }
2380 
2381 	  /* Theoretical overflow */
2382 	  /* If we can't put 256 bytes more into the buffer, allocate
2383 	     everything we can and fill it as full as we can. */
2384 	  /* XXX - we ignore rest of line using `truncating' flag */
2385 	  if (shell_input_line_size > (SIZE_MAX - 256))
2386 	    {
2387 	      size_t n;
2388 
2389 	      n = SIZE_MAX - i;	/* how much more can we put into the buffer? */
2390 	      if (n <= 2)	/* we have to save 1 for the newline added below */
2391 		{
2392 		  if (truncating == 0)
2393 		    internal_warning(_("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%lu): line truncated"), shell_input_line_size, (unsigned long)SIZE_MAX);
2394 		  shell_input_line[i] = '\0';
2395 		  truncating = 1;
2396 		}
2397 	      if (shell_input_line_size < SIZE_MAX)
2398 		{
2399 		  shell_input_line_size = SIZE_MAX;
2400 		  shell_input_line = xrealloc (shell_input_line, shell_input_line_size);
2401 		}
2402 	    }
2403 	  else
2404 	    RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2405 
2406 	  if (c == EOF)
2407 	    {
2408 	      if (bash_input.type == st_stream)
2409 		clearerr (stdin);
2410 
2411 	      if (i == 0)
2412 		shell_input_line_terminator = EOF;
2413 
2414 	      shell_input_line[i] = '\0';
2415 	      break;
2416 	    }
2417 
2418 	  if (truncating == 0 || c == '\n')
2419 	    shell_input_line[i++] = c;
2420 
2421 	  if (c == '\n')
2422 	    {
2423 	      shell_input_line[--i] = '\0';
2424 	      current_command_line_count++;
2425 	      break;
2426 	    }
2427 
2428 	  last_was_backslash = last_was_backslash == 0 && c == '\\';
2429 	}
2430 
2431       shell_input_line_index = 0;
2432       shell_input_line_len = i;		/* == strlen (shell_input_line) */
2433 
2434       set_line_mbstate ();
2435 
2436 #if defined (HISTORY)
2437       if (remember_on_history && shell_input_line && shell_input_line[0])
2438 	{
2439 	  char *expansions;
2440 #  if defined (BANG_HISTORY)
2441 	  /* If the current delimiter is a single quote, we should not be
2442 	     performing history expansion, even if we're on a different
2443 	     line from the original single quote. */
2444 	  if (current_delimiter (dstack) == '\'')
2445 	    history_quoting_state = '\'';
2446 	  else if (current_delimiter (dstack) == '"')
2447 	    history_quoting_state = '"';
2448 	  else
2449 	    history_quoting_state = 0;
2450 #  endif
2451 	  /* Calling with a third argument of 1 allows remember_on_history to
2452 	     determine whether or not the line is saved to the history list */
2453 	  expansions = pre_process_line (shell_input_line, 1, 1);
2454 #  if defined (BANG_HISTORY)
2455 	  history_quoting_state = 0;
2456 #  endif
2457 	  if (expansions != shell_input_line)
2458 	    {
2459 	      free (shell_input_line);
2460 	      shell_input_line = expansions;
2461 	      shell_input_line_len = shell_input_line ?
2462 					strlen (shell_input_line) : 0;
2463 	      if (shell_input_line_len == 0)
2464 		current_command_line_count--;
2465 
2466 	      /* We have to force the xrealloc below because we don't know
2467 		 the true allocated size of shell_input_line anymore. */
2468 	      shell_input_line_size = shell_input_line_len;
2469 
2470 	      set_line_mbstate ();
2471 	    }
2472 	}
2473       /* Try to do something intelligent with blank lines encountered while
2474 	 entering multi-line commands.  XXX - this is grotesque */
2475       else if (remember_on_history && shell_input_line &&
2476 	       shell_input_line[0] == '\0' &&
2477 	       current_command_line_count > 1)
2478 	{
2479 	  if (current_delimiter (dstack))
2480 	    /* We know shell_input_line[0] == 0 and we're reading some sort of
2481 	       quoted string.  This means we've got a line consisting of only
2482 	       a newline in a quoted string.  We want to make sure this line
2483 	       gets added to the history. */
2484 	    maybe_add_history (shell_input_line);
2485 	  else
2486 	    {
2487 	      char *hdcs;
2488 	      hdcs = history_delimiting_chars (shell_input_line);
2489 	      if (hdcs && hdcs[0] == ';')
2490 		maybe_add_history (shell_input_line);
2491 	    }
2492 	}
2493 
2494 #endif /* HISTORY */
2495 
2496       if (shell_input_line)
2497 	{
2498 	  /* Lines that signify the end of the shell's input should not be
2499 	     echoed.  We should not echo lines while parsing command
2500 	     substitutions with recursive calls into the parsing engine; those
2501 	     should only be echoed once when we read the word.  That is the
2502 	     reason for the test against shell_eof_token, which is set to a
2503 	     right paren when parsing the contents of command substitutions. */
2504 	  if (echo_input_at_read && (shell_input_line[0] ||
2505 				       shell_input_line_terminator != EOF) &&
2506 				     shell_eof_token == 0)
2507 	    fprintf (stderr, "%s\n", shell_input_line);
2508 	}
2509       else
2510 	{
2511 	  shell_input_line_size = 0;
2512 	  prompt_string_pointer = &current_prompt_string;
2513 	  if (SHOULD_PROMPT ())
2514 	    prompt_again ();
2515 	  goto restart_read;
2516 	}
2517 
2518       /* Add the newline to the end of this string, iff the string does
2519 	 not already end in an EOF character.  */
2520       if (shell_input_line_terminator != EOF)
2521 	{
2522 	  if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size))
2523 	    shell_input_line = (char *)xrealloc (shell_input_line,
2524 					1 + (shell_input_line_size += 2));
2525 
2526 	  /* Don't add a newline to a string that ends with a backslash if we're
2527 	     going to be removing quoted newlines, since that will eat the
2528 	     backslash.  Add another backslash instead (will be removed by
2529 	     word expansion). */
2530 	  if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
2531 	    shell_input_line[shell_input_line_len] = '\\';
2532 	  else
2533 	    shell_input_line[shell_input_line_len] = '\n';
2534 	  shell_input_line[shell_input_line_len + 1] = '\0';
2535 
2536 #if 0
2537 	  set_line_mbstate ();		/* XXX - this is wasteful */
2538 #else
2539 #  if defined (HANDLE_MULTIBYTE)
2540 	  /* This is kind of an abstraction violation, but there's no need to
2541 	     go through the entire shell_input_line again with a call to
2542 	     set_line_mbstate(). */
2543 	  if (shell_input_line_len + 2 > shell_input_line_propsize)
2544 	    {
2545 	      shell_input_line_propsize = shell_input_line_len + 2;
2546 	      shell_input_line_property = (char *)xrealloc (shell_input_line_property,
2547 							    shell_input_line_propsize);
2548 	    }
2549 	  shell_input_line_property[shell_input_line_len] = 1;
2550 #  endif
2551 #endif
2552 	}
2553     }
2554 
2555 next_alias_char:
2556   if (shell_input_line_index == 0)
2557     unquoted_backslash = 0;
2558 
2559   uc = shell_input_line[shell_input_line_index];
2560 
2561   if (uc)
2562     {
2563       unquoted_backslash = unquoted_backslash == 0 && uc == '\\';
2564       shell_input_line_index++;
2565     }
2566 
2567 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2568   /* If UC is NULL, we have reached the end of the current input string.  If
2569      pushed_string_list is non-empty, it's time to pop to the previous string
2570      because we have fully consumed the result of the last alias expansion.
2571      Do it transparently; just return the next character of the string popped
2572      to. */
2573   /* If pushed_string_list != 0 but pushed_string_list->expander == 0 (not
2574      currently tested) and the flags value is not PSH_SOURCE, we are not
2575      parsing an alias, we have just saved one (push_string, when called by
2576      the parse_dparen code) In this case, just go on as well.  The PSH_SOURCE
2577      case is handled below. */
2578 
2579   /* If we're at the end of an alias expansion add a space to make sure that
2580      the alias remains marked as being in use while we expand its last word.
2581      This makes sure that pop_string doesn't mark the alias as not in use
2582      before the string resulting from the alias expansion is tokenized and
2583      checked for alias expansion, preventing recursion.  At this point, the
2584      last character in shell_input_line is the last character of the alias
2585      expansion.  We test that last character to determine whether or not to
2586      return the space that will delimit the token and postpone the pop_string.
2587      This set of conditions duplicates what used to be in mk_alexpansion ()
2588      below, with the addition that we don't add a space if we're currently
2589      reading a quoted string or in a shell comment. */
2590 #ifndef OLD_ALIAS_HACK
2591   if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE &&
2592       pushed_string_list->flags != PSH_DPAREN &&
2593       (parser_state & PST_COMMENT) == 0 &&
2594       (parser_state & PST_ENDALIAS) == 0 &&	/* only once */
2595       shell_input_line_index > 0 &&
2596       shellblank (shell_input_line[shell_input_line_index-1]) == 0 &&
2597       shell_input_line[shell_input_line_index-1] != '\n' &&
2598       unquoted_backslash == 0 &&
2599       shellmeta (shell_input_line[shell_input_line_index-1]) == 0 &&
2600       (current_delimiter (dstack) != '\'' && current_delimiter (dstack) != '"'))
2601     {
2602       parser_state |= PST_ENDALIAS;
2603       return ' ';	/* END_ALIAS */
2604     }
2605 #endif
2606 
2607 pop_alias:
2608   /* This case works for PSH_DPAREN as well */
2609   if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE)
2610     {
2611       parser_state &= ~PST_ENDALIAS;
2612       pop_string ();
2613       uc = shell_input_line[shell_input_line_index];
2614       if (uc)
2615 	shell_input_line_index++;
2616     }
2617 #endif /* ALIAS || DPAREN_ARITHMETIC */
2618 
2619   if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
2620     {
2621 	if (SHOULD_PROMPT ())
2622 	  prompt_again ();
2623 	line_number++;
2624 
2625 	/* What do we do here if we're expanding an alias whose definition
2626 	   includes an escaped newline?  If that's the last character in the
2627 	   alias expansion, we just pop the pushed string list (recall that
2628 	   we inhibit the appending of a space if newline is the last
2629 	   character).  If it's not the last character, we need to consume the
2630 	   quoted newline and move to the next character in the expansion. */
2631 #if defined (ALIAS)
2632 	if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
2633 	  {
2634 	    uc = 0;
2635 	    goto pop_alias;
2636 	  }
2637 	else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0')
2638 	  {
2639 	    shell_input_line_index++;	/* skip newline */
2640 	    goto next_alias_char;	/* and get next character */
2641 	  }
2642 	else
2643 #endif
2644 	  goto restart_read;
2645     }
2646 
2647   if (uc == 0 && shell_input_line_terminator == EOF)
2648     return ((shell_input_line_index != 0) ? '\n' : EOF);
2649 
2650 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2651   /* We already know that we are not parsing an alias expansion because of the
2652      check for expanding_alias() above.  This knows how parse_and_execute
2653      handles switching to st_string input while an alias is being expanded,
2654      hence the check for pushed_string_list without pushed_string_list->expander
2655      and the check for PSH_SOURCE as pushed_string_list->flags.
2656      parse_and_execute and parse_string both change the input type to st_string
2657      and place the string to be parsed and executed into location.string, so
2658      we should not stop reading that until the pointer is '\0'.
2659      The check for shell_input_line_terminator may be superfluous.
2660 
2661      This solves the problem of `.' inside a multi-line alias with embedded
2662      newlines executing things out of order. */
2663   if (uc == 0 && bash_input.type == st_string && *bash_input.location.string &&
2664       pushed_string_list && pushed_string_list->flags == PSH_SOURCE &&
2665       shell_input_line_terminator == 0)
2666     {
2667       shell_input_line_index = 0;
2668       goto restart_read;
2669     }
2670 #endif
2671 
2672   return (uc);
2673 }
2674 
2675 /* Put C back into the input for the shell.  This might need changes for
2676    HANDLE_MULTIBYTE around EOLs.  Since we (currently) never push back a
2677    character different than we read, shell_input_line_property doesn't need
2678    to change when manipulating shell_input_line.  The define for
2679    last_shell_getc_is_singlebyte should take care of it, though. */
2680 static void
shell_ungetc(c)2681 shell_ungetc (c)
2682      int c;
2683 {
2684   if (shell_input_line && shell_input_line_index)
2685     shell_input_line[--shell_input_line_index] = c;
2686   else
2687     eol_ungetc_lookahead = c;
2688 }
2689 
2690 char *
parser_remaining_input()2691 parser_remaining_input ()
2692 {
2693   if (shell_input_line == 0)
2694     return 0;
2695   if ((int)shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len)
2696     return "";	/* XXX */
2697   return (shell_input_line + shell_input_line_index);
2698 }
2699 
2700 #ifdef INCLUDE_UNUSED
2701 /* Back the input pointer up by one, effectively `ungetting' a character. */
2702 static void
shell_ungetchar()2703 shell_ungetchar ()
2704 {
2705   if (shell_input_line && shell_input_line_index)
2706     shell_input_line_index--;
2707 }
2708 #endif
2709 
2710 /* Discard input until CHARACTER is seen, then push that character back
2711    onto the input stream. */
2712 static void
discard_until(character)2713 discard_until (character)
2714      int character;
2715 {
2716   int c;
2717 
2718   while ((c = shell_getc (0)) != EOF && c != character)
2719     ;
2720 
2721   if (c != EOF)
2722     shell_ungetc (c);
2723 }
2724 
2725 void
execute_variable_command(command,vname)2726 execute_variable_command (command, vname)
2727      char *command, *vname;
2728 {
2729   char *last_lastarg;
2730   sh_parser_state_t ps;
2731 
2732   save_parser_state (&ps);
2733   last_lastarg = get_string_value ("_");
2734   if (last_lastarg)
2735     last_lastarg = savestring (last_lastarg);
2736 
2737   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
2738 
2739   restore_parser_state (&ps);
2740   bind_variable ("_", last_lastarg, 0);
2741   FREE (last_lastarg);
2742 
2743   if (token_to_read == '\n')	/* reset_parser was called */
2744     token_to_read = 0;
2745 }
2746 
2747 void
push_token(x)2748 push_token (x)
2749      int x;
2750 {
2751   two_tokens_ago = token_before_that;
2752   token_before_that = last_read_token;
2753   last_read_token = current_token;
2754 
2755   current_token = x;
2756 }
2757 
2758 /* Place to remember the token.  We try to keep the buffer
2759    at a reasonable size, but it can grow. */
2760 static char *token = (char *)NULL;
2761 
2762 /* Current size of the token buffer. */
2763 static int token_buffer_size;
2764 
2765 /* Command to read_token () explaining what we want it to do. */
2766 #define READ 0
2767 #define RESET 1
2768 #define prompt_is_ps1 \
2769       (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2770 
2771 /* Function for yyparse to call.  yylex keeps track of
2772    the last two tokens read, and calls read_token.  */
2773 static int
yylex()2774 yylex ()
2775 {
2776   if (interactive && (current_token == 0 || current_token == '\n'))
2777     {
2778       /* Before we print a prompt, we might have to check mailboxes.
2779 	 We do this only if it is time to do so. Notice that only here
2780 	 is the mail alarm reset; nothing takes place in check_mail ()
2781 	 except the checking of mail.  Please don't change this. */
2782       if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
2783 	{
2784 	  check_mail ();
2785 	  reset_mail_timer ();
2786 	}
2787 
2788       /* Avoid printing a prompt if we're not going to read anything, e.g.
2789 	 after resetting the parser with read_token (RESET). */
2790       if (token_to_read == 0 && SHOULD_PROMPT ())
2791 	prompt_again ();
2792     }
2793 
2794   two_tokens_ago = token_before_that;
2795   token_before_that = last_read_token;
2796   last_read_token = current_token;
2797   current_token = read_token (READ);
2798 
2799   if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
2800     {
2801       current_token = yacc_EOF;
2802       if (bash_input.type == st_string)
2803 	rewind_input_string ();
2804     }
2805   parser_state &= ~PST_EOFTOKEN;	/* ??? */
2806 
2807   return (current_token);
2808 }
2809 
2810 /* When non-zero, we have read the required tokens
2811    which allow ESAC to be the next one read. */
2812 static int esacs_needed_count;
2813 
2814 /* When non-zero, we can read IN as an acceptable token, regardless of how
2815    many newlines we read. */
2816 static int expecting_in_token;
2817 
2818 static void
push_heredoc(r)2819 push_heredoc (r)
2820      REDIRECT *r;
2821 {
2822   if (need_here_doc >= HEREDOC_MAX)
2823     {
2824       last_command_exit_value = EX_BADUSAGE;
2825       need_here_doc = 0;
2826       report_syntax_error (_("maximum here-document count exceeded"));
2827       reset_parser ();
2828       exit_shell (last_command_exit_value);
2829     }
2830   redir_stack[need_here_doc++] = r;
2831 }
2832 
2833 void
gather_here_documents()2834 gather_here_documents ()
2835 {
2836   int r;
2837 
2838   r = 0;
2839   here_doc_first_line = 1;
2840   while (need_here_doc > 0)
2841     {
2842       parser_state |= PST_HEREDOC;
2843       make_here_document (redir_stack[r++], line_number);
2844       parser_state &= ~PST_HEREDOC;
2845       need_here_doc--;
2846       redir_stack[r - 1] = 0;		/* XXX */
2847     }
2848   here_doc_first_line = 0;		/* just in case */
2849 }
2850 
2851 /* When non-zero, an open-brace used to create a group is awaiting a close
2852    brace partner. */
2853 static int open_brace_count;
2854 
2855 /* In the following three macros, `token' is always last_read_token */
2856 
2857 /* Are we in the middle of parsing a redirection where we are about to read
2858    a word?  This is used to make sure alias expansion doesn't happen in the
2859    middle of a redirection, even though we're parsing a simple command. */
2860 #define parsing_redirection(token) \
2861   (token == '<' || token == '>' || \
2862    token == GREATER_GREATER || token == GREATER_BAR || \
2863    token == LESS_GREATER || token == LESS_LESS_MINUS || \
2864    token == LESS_LESS || token == LESS_LESS_LESS || \
2865    token == LESS_AND || token == GREATER_AND || token == AND_GREATER)
2866 
2867 /* Is `token' one that will allow a WORD to be read in a command position?
2868    We can read a simple command name on which we should attempt alias expansion
2869    or we can read an assignment statement. */
2870 #define command_token_position(token) \
2871   (((token) == ASSIGNMENT_WORD) || \
2872    ((parser_state&PST_REDIRLIST) && parsing_redirection(token) == 0) || \
2873    ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
2874 
2875 /* Are we in a position where we can read an assignment statement? */
2876 #define assignment_acceptable(token) \
2877   (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
2878 
2879 /* Check to see if TOKEN is a reserved word and return the token
2880    value if it is. */
2881 #define CHECK_FOR_RESERVED_WORD(tok) \
2882   do { \
2883     if (!dollar_present && !quoted && \
2884 	reserved_word_acceptable (last_read_token)) \
2885       { \
2886 	int i; \
2887 	for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2888 	  if (STREQ (tok, word_token_alist[i].word)) \
2889 	    { \
2890 	      if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2891 		break; \
2892 	      if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
2893 		break; \
2894 	      if ((parser_state & PST_CASEPAT) && last_read_token == '|' && word_token_alist[i].token == ESAC) \
2895 		break; /* Posix grammar rule 4 */ \
2896 	      if (word_token_alist[i].token == ESAC) \
2897 		parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2898 	      else if (word_token_alist[i].token == CASE) \
2899 		parser_state |= PST_CASESTMT; \
2900 	      else if (word_token_alist[i].token == COND_END) \
2901 		parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2902 	      else if (word_token_alist[i].token == COND_START) \
2903 		parser_state |= PST_CONDCMD; \
2904 	      else if (word_token_alist[i].token == '{') \
2905 		open_brace_count++; \
2906 	      else if (word_token_alist[i].token == '}' && open_brace_count) \
2907 		open_brace_count--; \
2908 	      return (word_token_alist[i].token); \
2909 	    } \
2910       } \
2911   } while (0)
2912 
2913 #if defined (ALIAS)
2914 
2915     /* OK, we have a token.  Let's try to alias expand it, if (and only if)
2916        it's eligible.
2917 
2918        It is eligible for expansion if EXPAND_ALIASES is set, and
2919        the token is unquoted and the last token read was a command
2920        separator (or expand_next_token is set), and we are currently
2921        processing an alias (pushed_string_list is non-empty) and this
2922        token is not the same as the current or any previously
2923        processed alias.
2924 
2925        Special cases that disqualify:
2926 	 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
2927 
2928 static char *
mk_alexpansion(s)2929 mk_alexpansion (s)
2930      char *s;
2931 {
2932   int l;
2933   char *r;
2934 
2935   l = strlen (s);
2936   r = xmalloc (l + 2);
2937   strcpy (r, s);
2938 #ifdef OLD_ALIAS_HACK
2939   /* If the last character in the alias is a newline, don't add a trailing
2940      space to the expansion.  Works with shell_getc above. */
2941   /* Need to do something about the case where the alias expansion contains
2942      an unmatched quoted string, since appending this space affects the
2943      subsequent output. */
2944   if (l > 0 && r[l - 1] != ' ' && r[l - 1] != '\n' && shellmeta(r[l - 1]) == 0)
2945     r[l++] = ' ';
2946 #endif
2947   r[l] = '\0';
2948   return r;
2949 }
2950 
2951 static int
alias_expand_token(tokstr)2952 alias_expand_token (tokstr)
2953      char *tokstr;
2954 {
2955   char *expanded;
2956   alias_t *ap;
2957 
2958   if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2959 	(parser_state & PST_CASEPAT) == 0)
2960     {
2961       ap = find_alias (tokstr);
2962 
2963       /* Currently expanding this token. */
2964       if (ap && (ap->flags & AL_BEINGEXPANDED))
2965 	return (NO_EXPANSION);
2966 
2967 #ifdef OLD_ALIAS_HACK
2968       /* mk_alexpansion puts an extra space on the end of the alias expansion,
2969 	 so the lookahead by the parser works right (the alias needs to remain
2970 	 `in use' while parsing its last word to avoid alias recursion for
2971 	 something like "alias echo=echo").  If this gets changed, make sure
2972 	 the code in shell_getc that deals with reaching the end of an
2973 	 expanded alias is changed with it. */
2974 #endif
2975       expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2976 
2977       if (expanded)
2978 	{
2979 	  push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2980 	  return (RE_READ_TOKEN);
2981 	}
2982       else
2983 	/* This is an eligible token that does not have an expansion. */
2984 	return (NO_EXPANSION);
2985     }
2986   return (NO_EXPANSION);
2987 }
2988 #endif /* ALIAS */
2989 
2990 static int
time_command_acceptable()2991 time_command_acceptable ()
2992 {
2993 #if defined (COMMAND_TIMING)
2994   int i;
2995 
2996   if (posixly_correct && shell_compatibility_level > 41)
2997     {
2998       /* Quick check of the rest of the line to find the next token.  If it
2999 	 begins with a `-', Posix says to not return `time' as the token.
3000 	 This was interp 267. */
3001       i = shell_input_line_index;
3002       while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
3003         i++;
3004       if (shell_input_line[i] == '-')
3005 	return 0;
3006     }
3007 
3008   switch (last_read_token)
3009     {
3010     case 0:
3011     case ';':
3012     case '\n':
3013       if (token_before_that == '|')
3014 	return (0);
3015       /* FALLTHROUGH */
3016     case AND_AND:
3017     case OR_OR:
3018     case '&':
3019     case WHILE:
3020     case DO:
3021     case UNTIL:
3022     case IF:
3023     case THEN:
3024     case ELIF:
3025     case ELSE:
3026     case '{':		/* } */
3027     case '(':		/* )( */
3028     case ')':		/* only valid in case statement */
3029     case BANG:		/* ! time pipeline */
3030     case TIME:		/* time time pipeline */
3031     case TIMEOPT:	/* time -p time pipeline */
3032     case TIMEIGN:	/* time -p -- ... */
3033       return 1;
3034     default:
3035       return 0;
3036     }
3037 #else
3038   return 0;
3039 #endif /* COMMAND_TIMING */
3040 }
3041 
3042 /* Handle special cases of token recognition:
3043 	IN is recognized if the last token was WORD and the token
3044 	before that was FOR or CASE or SELECT.
3045 
3046 	DO is recognized if the last token was WORD and the token
3047 	before that was FOR or SELECT.
3048 
3049 	ESAC is recognized if the last token caused `esacs_needed_count'
3050 	to be set
3051 
3052 	`{' is recognized if the last token as WORD and the token
3053 	before that was FUNCTION, or if we just parsed an arithmetic
3054 	`for' command.
3055 
3056 	`}' is recognized if there is an unclosed `{' present.
3057 
3058 	`-p' is returned as TIMEOPT if the last read token was TIME.
3059 	`--' is returned as TIMEIGN if the last read token was TIME or TIMEOPT.
3060 
3061 	']]' is returned as COND_END if the parser is currently parsing
3062 	a conditional expression ((parser_state & PST_CONDEXPR) != 0)
3063 
3064 	`time' is returned as TIME if and only if it is immediately
3065 	preceded by one of `;', `\n', `||', `&&', or `&'.
3066 */
3067 
3068 static int
special_case_tokens(tokstr)3069 special_case_tokens (tokstr)
3070      char *tokstr;
3071 {
3072   /* Posix grammar rule 6 */
3073   if ((last_read_token == WORD) &&
3074 #if defined (SELECT_COMMAND)
3075       ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3076 #else
3077       ((token_before_that == FOR) || (token_before_that == CASE)) &&
3078 #endif
3079       (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
3080     {
3081       if (token_before_that == CASE)
3082 	{
3083 	  parser_state |= PST_CASEPAT;
3084 	  esacs_needed_count++;
3085 	}
3086       if (expecting_in_token)
3087 	expecting_in_token--;
3088       return (IN);
3089     }
3090 
3091   /* XXX - leaving above code intact for now, but it should eventually be
3092      removed in favor of this clause. */
3093   /* Posix grammar rule 6 */
3094   if (expecting_in_token && (last_read_token == WORD || last_read_token == '\n') &&
3095       (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
3096     {
3097       if (parser_state & PST_CASESTMT)
3098 	{
3099 	  parser_state |= PST_CASEPAT;
3100 	  esacs_needed_count++;
3101 	}
3102       expecting_in_token--;
3103       return (IN);
3104     }
3105   /* Posix grammar rule 6, third word in FOR: for i; do command-list; done */
3106   else if (expecting_in_token && (last_read_token == '\n' || last_read_token == ';') &&
3107     (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
3108     {
3109       expecting_in_token--;
3110       return (DO);
3111     }
3112 
3113   /* for i do; command-list; done */
3114   if (last_read_token == WORD &&
3115 #if defined (SELECT_COMMAND)
3116       (token_before_that == FOR || token_before_that == SELECT) &&
3117 #else
3118       (token_before_that == FOR) &&
3119 #endif
3120       (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
3121     {
3122       if (expecting_in_token)
3123 	expecting_in_token--;
3124       return (DO);
3125     }
3126 
3127   /* Ditto for ESAC in the CASE case.
3128      Specifically, this handles "case word in esac", which is a legal
3129      construct, certainly because someone will pass an empty arg to the
3130      case construct, and we don't want it to barf.  Of course, we should
3131      insist that the case construct has at least one pattern in it, but
3132      the designers disagree. */
3133   if (esacs_needed_count)
3134     {
3135       if (last_read_token == IN && STREQ (tokstr, "esac"))
3136 	{
3137 	  esacs_needed_count--;
3138 	  parser_state &= ~PST_CASEPAT;
3139 	  return (ESAC);
3140 	}
3141     }
3142 
3143   /* The start of a shell function definition. */
3144   if (parser_state & PST_ALLOWOPNBRC)
3145     {
3146       parser_state &= ~PST_ALLOWOPNBRC;
3147       if (tokstr[0] == '{' && tokstr[1] == '\0')		/* } */
3148 	{
3149 	  open_brace_count++;
3150 	  function_bstart = line_number;
3151 	  return ('{');					/* } */
3152 	}
3153     }
3154 
3155   /* We allow a `do' after a for ((...)) without an intervening
3156      list_terminator */
3157   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
3158     return (DO);
3159   if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0')	/* } */
3160     {
3161       open_brace_count++;
3162       return ('{');			/* } */
3163     }
3164 
3165   if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
3166     {
3167       open_brace_count--;		/* { */
3168       return ('}');
3169     }
3170 
3171 #if defined (COMMAND_TIMING)
3172   /* Handle -p after `time'. */
3173   if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
3174     return (TIMEOPT);
3175   /* Handle -- after `time'. */
3176   if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
3177     return (TIMEIGN);
3178   /* Handle -- after `time -p'. */
3179   if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
3180     return (TIMEIGN);
3181 #endif
3182 
3183 #if defined (COND_COMMAND) /* [[ */
3184   if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
3185     return (COND_END);
3186 #endif
3187 
3188   return (-1);
3189 }
3190 
3191 /* Called from shell.c when Control-C is typed at top level.  Or
3192    by the error rule at top level. */
3193 void
reset_parser()3194 reset_parser ()
3195 {
3196   dstack.delimiter_depth = 0;	/* No delimiters found so far. */
3197   open_brace_count = 0;
3198 
3199 #if defined (EXTENDED_GLOB)
3200   /* Reset to global value of extended glob */
3201   if (parser_state & PST_EXTPAT)
3202     extended_glob = global_extglob;
3203 #endif
3204 
3205   parser_state = 0;
3206   here_doc_first_line = 0;
3207 
3208 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3209   if (pushed_string_list)
3210     free_string_list ();
3211 #endif /* ALIAS || DPAREN_ARITHMETIC */
3212 
3213   /* This is where we resynchronize to the next newline on error/reset */
3214   if (shell_input_line)
3215     {
3216       free (shell_input_line);
3217       shell_input_line = (char *)NULL;
3218       shell_input_line_size = shell_input_line_index = 0;
3219     }
3220 
3221   FREE (word_desc_to_read);
3222   word_desc_to_read = (WORD_DESC *)NULL;
3223 
3224   eol_ungetc_lookahead = 0;
3225 
3226   current_token = '\n';		/* XXX */
3227   last_read_token = '\n';
3228   token_to_read = '\n';
3229 }
3230 
3231 void
reset_readahead_token()3232 reset_readahead_token ()
3233 {
3234   if (token_to_read == '\n')
3235     token_to_read = 0;
3236 }
3237 
3238 /* Read the next token.  Command can be READ (normal operation) or
3239    RESET (to normalize state). */
3240 static int
read_token(command)3241 read_token (command)
3242      int command;
3243 {
3244   int character;		/* Current character. */
3245   int peek_char;		/* Temporary look-ahead character. */
3246   int result;			/* The thing to return. */
3247 
3248   if (command == RESET)
3249     {
3250       reset_parser ();
3251       return ('\n');
3252     }
3253 
3254   if (token_to_read)
3255     {
3256       result = token_to_read;
3257       if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3258 	{
3259 	  yylval.word = word_desc_to_read;
3260 	  word_desc_to_read = (WORD_DESC *)NULL;
3261 	}
3262       token_to_read = 0;
3263       return (result);
3264     }
3265 
3266 #if defined (COND_COMMAND)
3267   if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3268     {
3269       cond_lineno = line_number;
3270       parser_state |= PST_CONDEXPR;
3271       yylval.command = parse_cond_command ();
3272       if (cond_token != COND_END)
3273 	{
3274 	  cond_error ();
3275 	  return (-1);
3276 	}
3277       token_to_read = COND_END;
3278       parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3279       return (COND_CMD);
3280     }
3281 #endif
3282 
3283 #if defined (ALIAS)
3284   /* This is a place to jump back to once we have successfully expanded a
3285      token with an alias and pushed the string with push_string () */
3286  re_read_token:
3287 #endif /* ALIAS */
3288 
3289   /* Read a single word from input.  Start by skipping blanks. */
3290   while ((character = shell_getc (1)) != EOF && shellblank (character))
3291     ;
3292 
3293   if (character == EOF)
3294     {
3295       EOF_Reached = 1;
3296       return (yacc_EOF);
3297     }
3298 
3299   /* If we hit the end of the string and we're not expanding an alias (e.g.,
3300      we are eval'ing a string that is an incomplete command), return EOF */
3301   if (character == '\0' && bash_input.type == st_string && expanding_alias() == 0)
3302     {
3303 #if defined (DEBUG)
3304 itrace("shell_getc: bash_input.location.string = `%s'", bash_input.location.string);
3305 #endif
3306       EOF_Reached = 1;
3307       return (yacc_EOF);
3308     }
3309 
3310   if MBTEST(character == '#' && (!interactive || interactive_comments))
3311     {
3312       /* A comment.  Discard until EOL or EOF, and then return a newline. */
3313       parser_state |= PST_COMMENT;
3314       discard_until ('\n');
3315       shell_getc (0);
3316       parser_state &= ~PST_COMMENT;
3317       character = '\n';	/* this will take the next if statement and return. */
3318     }
3319 
3320   if (character == '\n')
3321     {
3322       /* If we're about to return an unquoted newline, we can go and collect
3323 	 the text of any pending here document. */
3324       if (need_here_doc)
3325 	gather_here_documents ();
3326 
3327 #if defined (ALIAS)
3328       parser_state &= ~PST_ALEXPNEXT;
3329 #endif /* ALIAS */
3330 
3331       parser_state &= ~PST_ASSIGNOK;
3332 
3333       return (character);
3334     }
3335 
3336   if (parser_state & PST_REGEXP)
3337     goto tokword;
3338 
3339   /* Shell meta-characters. */
3340   if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3341     {
3342 #if defined (ALIAS)
3343       /* Turn off alias tokenization iff this character sequence would
3344 	 not leave us ready to read a command. */
3345       if (character == '<' || character == '>')
3346 	parser_state &= ~PST_ALEXPNEXT;
3347 #endif /* ALIAS */
3348 
3349       parser_state &= ~PST_ASSIGNOK;
3350 
3351       /* If we are parsing a command substitution and we have read a character
3352 	 that marks the end of it, don't bother to skip over quoted newlines
3353 	 when we read the next token. We're just interested in a character
3354 	 that will turn this into a two-character token, so we let the higher
3355 	 layers deal with quoted newlines following the command substitution. */
3356       if ((parser_state & PST_CMDSUBST) && character == shell_eof_token)
3357 	peek_char = shell_getc (0);
3358       else
3359 	peek_char = shell_getc (1);
3360 
3361       if (character == peek_char)
3362 	{
3363 	  switch (character)
3364 	    {
3365 	    case '<':
3366 	      /* If '<' then we could be at "<<" or at "<<-".  We have to
3367 		 look ahead one more character. */
3368 	      peek_char = shell_getc (1);
3369 	      if MBTEST(peek_char == '-')
3370 		return (LESS_LESS_MINUS);
3371 	      else if MBTEST(peek_char == '<')
3372 		return (LESS_LESS_LESS);
3373 	      else
3374 		{
3375 		  shell_ungetc (peek_char);
3376 		  return (LESS_LESS);
3377 		}
3378 
3379 	    case '>':
3380 	      return (GREATER_GREATER);
3381 
3382 	    case ';':
3383 	      parser_state |= PST_CASEPAT;
3384 #if defined (ALIAS)
3385 	      parser_state &= ~PST_ALEXPNEXT;
3386 #endif /* ALIAS */
3387 
3388 	      peek_char = shell_getc (1);
3389 	      if MBTEST(peek_char == '&')
3390 		return (SEMI_SEMI_AND);
3391 	      else
3392 		{
3393 		  shell_ungetc (peek_char);
3394 		  return (SEMI_SEMI);
3395 		}
3396 
3397 	    case '&':
3398 	      return (AND_AND);
3399 
3400 	    case '|':
3401 	      return (OR_OR);
3402 
3403 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3404 	    case '(':		/* ) */
3405 	      result = parse_dparen (character);
3406 	      if (result == -2)
3407 	        break;
3408 	      else
3409 	        return result;
3410 #endif
3411 	    }
3412 	}
3413       else if MBTEST(character == '<' && peek_char == '&')
3414 	return (LESS_AND);
3415       else if MBTEST(character == '>' && peek_char == '&')
3416 	return (GREATER_AND);
3417       else if MBTEST(character == '<' && peek_char == '>')
3418 	return (LESS_GREATER);
3419       else if MBTEST(character == '>' && peek_char == '|')
3420 	return (GREATER_BAR);
3421       else if MBTEST(character == '&' && peek_char == '>')
3422 	{
3423 	  peek_char = shell_getc (1);
3424 	  if MBTEST(peek_char == '>')
3425 	    return (AND_GREATER_GREATER);
3426 	  else
3427 	    {
3428 	      shell_ungetc (peek_char);
3429 	      return (AND_GREATER);
3430 	    }
3431 	}
3432       else if MBTEST(character == '|' && peek_char == '&')
3433 	return (BAR_AND);
3434       else if MBTEST(character == ';' && peek_char == '&')
3435 	{
3436 	  parser_state |= PST_CASEPAT;
3437 #if defined (ALIAS)
3438 	  parser_state &= ~PST_ALEXPNEXT;
3439 #endif /* ALIAS */
3440 	  return (SEMI_AND);
3441 	}
3442 
3443       shell_ungetc (peek_char);
3444 
3445       /* If we look like we are reading the start of a function
3446 	 definition, then let the reader know about it so that
3447 	 we will do the right thing with `{'. */
3448       if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
3449 	{
3450 	  parser_state |= PST_ALLOWOPNBRC;
3451 #if defined (ALIAS)
3452 	  parser_state &= ~PST_ALEXPNEXT;
3453 #endif /* ALIAS */
3454 	  function_dstart = line_number;
3455 	}
3456 
3457       /* case pattern lists may be preceded by an optional left paren.  If
3458 	 we're not trying to parse a case pattern list, the left paren
3459 	 indicates a subshell. */
3460       if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3461 	parser_state |= PST_SUBSHELL;
3462       /*(*/
3463       else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
3464 	parser_state &= ~PST_CASEPAT;
3465       /*(*/
3466       else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
3467 	parser_state &= ~PST_SUBSHELL;
3468 
3469 #if defined (PROCESS_SUBSTITUTION)
3470       /* Check for the constructs which introduce process substitution.
3471 	 Shells running in `posix mode' don't do process substitution. */
3472       if MBTEST((character != '>' && character != '<') || peek_char != '(') /*)*/
3473 #endif /* PROCESS_SUBSTITUTION */
3474 	return (character);
3475     }
3476 
3477   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */
3478   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3479     return (character);
3480 
3481 tokword:
3482   /* Okay, if we got this far, we have to read a word.  Read one,
3483      and then check it against the known ones. */
3484   result = read_token_word (character);
3485 #if defined (ALIAS)
3486   if (result == RE_READ_TOKEN)
3487     goto re_read_token;
3488 #endif
3489   return result;
3490 }
3491 
3492 /*
3493  * Match a $(...) or other grouping construct.  This has to handle embedded
3494  * quoted strings ('', ``, "") and nested constructs.  It also must handle
3495  * reprompting the user, if necessary, after reading a newline, and returning
3496  * correct error values if it reads EOF.
3497  */
3498 #define P_FIRSTCLOSE	0x0001
3499 #define P_ALLOWESC	0x0002
3500 #define P_DQUOTE	0x0004
3501 #define P_COMMAND	0x0008	/* parsing a command, so look for comments */
3502 #define P_BACKQUOTE	0x0010	/* parsing a backquoted command substitution */
3503 #define P_ARRAYSUB	0x0020	/* parsing a [...] array subscript for assignment */
3504 #define P_DOLBRACE	0x0040	/* parsing a ${...} construct */
3505 
3506 /* Lexical state while parsing a grouping construct or $(...). */
3507 #define LEX_WASDOL	0x0001
3508 #define LEX_CKCOMMENT	0x0002
3509 #define LEX_INCOMMENT	0x0004
3510 #define LEX_PASSNEXT	0x0008
3511 #define LEX_RESWDOK	0x0010
3512 #define LEX_CKCASE	0x0020
3513 #define LEX_INCASE	0x0040
3514 #define LEX_INHEREDOC	0x0080
3515 #define LEX_HEREDELIM	0x0100		/* reading here-doc delimiter */
3516 #define LEX_STRIPDOC	0x0200		/* <<- strip tabs from here doc delim */
3517 #define LEX_QUOTEDDOC	0x0400		/* here doc with quoted delim */
3518 #define LEX_INWORD	0x0800
3519 #define LEX_GTLT	0x1000
3520 
3521 #define COMSUB_META(ch)		((ch) == ';' || (ch) == '&' || (ch) == '|')
3522 
3523 #define CHECK_NESTRET_ERROR() \
3524   do { \
3525     if (nestret == &matched_pair_error) \
3526       { \
3527 	free (ret); \
3528 	return &matched_pair_error; \
3529       } \
3530   } while (0)
3531 
3532 #define APPEND_NESTRET() \
3533   do { \
3534     if (nestlen) \
3535       { \
3536 	RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
3537 	strcpy (ret + retind, nestret); \
3538 	retind += nestlen; \
3539       } \
3540   } while (0)
3541 
3542 static char matched_pair_error;
3543 
3544 static char *
parse_matched_pair(qc,open,close,lenp,flags)3545 parse_matched_pair (qc, open, close, lenp, flags)
3546      int qc;	/* `"' if this construct is within double quotes */
3547      int open, close;
3548      int *lenp, flags;
3549 {
3550   int count, ch, prevch, tflags;
3551   int nestlen, ttranslen, start_lineno;
3552   char *ret, *nestret, *ttrans;
3553   int retind, retsize, rflags;
3554   int dolbrace_state;
3555 
3556   dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
3557 
3558 /*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
3559   count = 1;
3560   tflags = 0;
3561 
3562   if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3563     tflags |= LEX_CKCOMMENT;
3564 
3565   /* RFLAGS is the set of flags we want to pass to recursive calls. */
3566   rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
3567 
3568   ret = (char *)xmalloc (retsize = 64);
3569   retind = 0;
3570 
3571   start_lineno = line_number;
3572   ch = EOF;		/* just in case */
3573   while (count)
3574     {
3575       prevch = ch;
3576       ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
3577 
3578       if (ch == EOF)
3579 	{
3580 	  free (ret);
3581 	  parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3582 	  EOF_Reached = 1;	/* XXX */
3583 	  return (&matched_pair_error);
3584 	}
3585 
3586       /* Possible reprompting. */
3587       if (ch == '\n' && SHOULD_PROMPT ())
3588 	prompt_again ();
3589 
3590       /* Don't bother counting parens or doing anything else if in a comment
3591 	 or part of a case statement */
3592       if (tflags & LEX_INCOMMENT)
3593 	{
3594 	  /* Add this character. */
3595 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3596 	  ret[retind++] = ch;
3597 
3598 	  if (ch == '\n')
3599 	    tflags &= ~LEX_INCOMMENT;
3600 
3601 	  continue;
3602 	}
3603 
3604       /* Not exactly right yet, should handle shell metacharacters, too.  If
3605 	 any changes are made to this test, make analogous changes to subst.c:
3606 	 extract_delimited_string(). */
3607       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
3608 	tflags |= LEX_INCOMMENT;
3609 
3610       if (tflags & LEX_PASSNEXT)		/* last char was backslash */
3611 	{
3612 	  tflags &= ~LEX_PASSNEXT;
3613 	  if (qc != '\'' && ch == '\n')	/* double-quoted \<newline> disappears. */
3614 	    {
3615 	      if (retind > 0)
3616 		retind--;	/* swallow previously-added backslash */
3617 	      continue;
3618 	    }
3619 
3620 	  RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3621 	  if MBTEST(ch == CTLESC)
3622 	    ret[retind++] = CTLESC;
3623 	  ret[retind++] = ch;
3624 	  continue;
3625 	}
3626       /* If we're reparsing the input (e.g., from parse_string_to_word_list),
3627 	 we've already prepended CTLESC to single-quoted results of $'...'.
3628 	 We may want to do this for other CTLESC-quoted characters in
3629 	 reparse, too. */
3630       else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
3631 	{
3632 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3633 	  ret[retind++] = ch;
3634 	  continue;
3635 	}
3636       else if MBTEST(ch == CTLESC || ch == CTLNUL)	/* special shell escapes */
3637 	{
3638 	  RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3639 	  ret[retind++] = CTLESC;
3640 	  ret[retind++] = ch;
3641 	  continue;
3642 	}
3643       else if MBTEST(ch == close)		/* ending delimiter */
3644 	count--;
3645       /* handle nested ${...} specially. */
3646       else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
3647 	count++;
3648       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open)	/* nested begin */
3649 	count++;
3650 
3651       /* Add this character. */
3652       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3653       ret[retind++] = ch;
3654 
3655       /* If we just read the ending character, don't bother continuing. */
3656       if (count == 0)
3657 	break;
3658 
3659       if (open == '\'')			/* '' inside grouping construct */
3660 	{
3661 	  if MBTEST((flags & P_ALLOWESC) && ch == '\\')
3662 	    tflags |= LEX_PASSNEXT;
3663 	  continue;
3664 	}
3665 
3666       if MBTEST(ch == '\\')			/* backslashes */
3667 	tflags |= LEX_PASSNEXT;
3668 
3669       /* Based on which dolstate is currently in (param, op, or word),
3670 	 decide what the op is.  We're really only concerned if it's % or
3671 	 #, so we can turn on a flag that says whether or not we should
3672 	 treat single quotes as special when inside a double-quoted
3673 	 ${...}. This logic must agree with subst.c:extract_dollar_brace_string
3674 	 since they share the same defines. */
3675       /* FLAG POSIX INTERP 221 */
3676       if (flags & P_DOLBRACE)
3677         {
3678           /* ${param%[%]word} */
3679 	  if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
3680 	    dolbrace_state = DOLBRACE_QUOTE;
3681           /* ${param#[#]word} */
3682 	  else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
3683 	    dolbrace_state = DOLBRACE_QUOTE;
3684           /* ${param/[/]pat/rep} */
3685 	  else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1)
3686 	    dolbrace_state = DOLBRACE_QUOTE2;	/* XXX */
3687           /* ${param^[^]pat} */
3688 	  else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1)
3689 	    dolbrace_state = DOLBRACE_QUOTE;
3690           /* ${param,[,]pat} */
3691 	  else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
3692 	    dolbrace_state = DOLBRACE_QUOTE;
3693 	  else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
3694 	    dolbrace_state = DOLBRACE_OP;
3695 	  else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
3696 	    dolbrace_state = DOLBRACE_WORD;
3697         }
3698 
3699       /* The big hammer.  Single quotes aren't special in double quotes.  The
3700          problem is that Posix used to say the single quotes are semi-special:
3701          within a double-quoted ${...} construct "an even number of
3702          unescaped double-quotes or single-quotes, if any, shall occur." */
3703       /* This was changed in Austin Group Interp 221 */
3704       if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
3705 	continue;
3706 
3707       /* Could also check open == '`' if we want to parse grouping constructs
3708 	 inside old-style command substitution. */
3709       if (open != close)		/* a grouping construct */
3710 	{
3711 	  if MBTEST(shellquote (ch))
3712 	    {
3713 	      /* '', ``, or "" inside $(...) or other grouping construct. */
3714 	      push_delimiter (dstack, ch);
3715 	      if MBTEST((tflags & LEX_WASDOL) && ch == '\'')	/* $'...' inside group */
3716 		nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3717 	      else
3718 		nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3719 	      pop_delimiter (dstack);
3720 	      CHECK_NESTRET_ERROR ();
3721 
3722 	      if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3723 		{
3724 		  /* Translate $'...' here. */
3725 		  ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3726 		  free (nestret);
3727 
3728 		  /* If we're parsing a double-quoted brace expansion and we are
3729 		     not in a place where single quotes are treated specially,
3730 		     make sure we single-quote the results of the ansi
3731 		     expansion because quote removal should remove them later */
3732 		  /* FLAG POSIX INTERP 221 */
3733 		  if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE))
3734 		    {
3735 		      nestret = sh_single_quote (ttrans);
3736 		      free (ttrans);
3737 		      nestlen = strlen (nestret);
3738 		    }
3739 		  else if ((rflags & P_DQUOTE) == 0)
3740 		    {
3741 		      nestret = sh_single_quote (ttrans);
3742 		      free (ttrans);
3743 		      nestlen = strlen (nestret);
3744 		    }
3745 		  else
3746 		    {
3747 		      nestret = ttrans;
3748 		      nestlen = ttranslen;
3749 		    }
3750 		  retind -= 2;		/* back up before the $' */
3751 		}
3752 	      else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3753 		{
3754 		  /* Locale expand $"..." here. */
3755 		  ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3756 		  free (nestret);
3757 
3758 		  nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3759 		  free (ttrans);
3760 		  nestlen = ttranslen + 2;
3761 		  retind -= 2;		/* back up before the $" */
3762 		}
3763 
3764 	      APPEND_NESTRET ();
3765 	      FREE (nestret);
3766 	    }
3767 	  else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))	/* ) } ] */
3768 	    goto parse_dollar_word;
3769 #if defined (PROCESS_SUBSTITUTION)
3770 	  /* XXX - technically this should only be recognized at the start of
3771 	     a word */
3772 	  else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_GTLT) && (ch == '('))	/* ) */
3773 	    goto parse_dollar_word;
3774 #endif
3775 	}
3776       /* Parse an old-style command substitution within double quotes as a
3777 	 single word. */
3778       /* XXX - sh and ksh93 don't do this - XXX */
3779       else if MBTEST(open == '"' && ch == '`')
3780 	{
3781 	  nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
3782 
3783 	  CHECK_NESTRET_ERROR ();
3784 	  APPEND_NESTRET ();
3785 
3786 	  FREE (nestret);
3787 	}
3788       else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))	/* ) } ] */
3789 	/* check for $(), $[], or ${} inside quoted string. */
3790 	{
3791 parse_dollar_word:
3792 	  if (open == ch)	/* undo previous increment */
3793 	    count--;
3794 	  if (ch == '(')		/* ) */
3795 	    nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3796 	  else if (ch == '{')		/* } */
3797 	    nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3798 	  else if (ch == '[')		/* ] */
3799 	    nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3800 
3801 	  CHECK_NESTRET_ERROR ();
3802 	  APPEND_NESTRET ();
3803 
3804 	  FREE (nestret);
3805 	}
3806 #if defined (PROCESS_SUBSTITUTION)
3807       if MBTEST((ch == '<' || ch == '>') && (tflags & LEX_GTLT) == 0)
3808 	tflags |= LEX_GTLT;
3809       else
3810 	tflags &= ~LEX_GTLT;
3811 #endif
3812       if MBTEST(ch == '$' && (tflags & LEX_WASDOL) == 0)
3813 	tflags |= LEX_WASDOL;
3814       else
3815 	tflags &= ~LEX_WASDOL;
3816     }
3817 
3818   ret[retind] = '\0';
3819   if (lenp)
3820     *lenp = retind;
3821 /*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
3822   return ret;
3823 }
3824 
3825 #if defined (DEBUG)
3826 static void
dump_tflags(flags)3827 dump_tflags (flags)
3828      int flags;
3829 {
3830   int f;
3831 
3832   f = flags;
3833   fprintf (stderr, "%d -> ", f);
3834   if (f & LEX_WASDOL)
3835     {
3836       f &= ~LEX_WASDOL;
3837       fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
3838     }
3839   if (f & LEX_CKCOMMENT)
3840     {
3841       f &= ~LEX_CKCOMMENT;
3842       fprintf (stderr, "LEX_CKCOMMENT%s", f ? "|" : "");
3843     }
3844   if (f & LEX_INCOMMENT)
3845     {
3846       f &= ~LEX_INCOMMENT;
3847       fprintf (stderr, "LEX_INCOMMENT%s", f ? "|" : "");
3848     }
3849   if (f & LEX_PASSNEXT)
3850     {
3851       f &= ~LEX_PASSNEXT;
3852       fprintf (stderr, "LEX_PASSNEXT%s", f ? "|" : "");
3853     }
3854   if (f & LEX_RESWDOK)
3855     {
3856       f &= ~LEX_RESWDOK;
3857       fprintf (stderr, "LEX_RESWDOK%s", f ? "|" : "");
3858     }
3859   if (f & LEX_CKCASE)
3860     {
3861       f &= ~LEX_CKCASE;
3862       fprintf (stderr, "LEX_CKCASE%s", f ? "|" : "");
3863     }
3864   if (f & LEX_INCASE)
3865     {
3866       f &= ~LEX_INCASE;
3867       fprintf (stderr, "LEX_INCASE%s", f ? "|" : "");
3868     }
3869   if (f & LEX_INHEREDOC)
3870     {
3871       f &= ~LEX_INHEREDOC;
3872       fprintf (stderr, "LEX_INHEREDOC%s", f ? "|" : "");
3873     }
3874   if (f & LEX_HEREDELIM)
3875     {
3876       f &= ~LEX_HEREDELIM;
3877       fprintf (stderr, "LEX_HEREDELIM%s", f ? "|" : "");
3878     }
3879   if (f & LEX_STRIPDOC)
3880     {
3881       f &= ~LEX_STRIPDOC;
3882       fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
3883     }
3884   if (f & LEX_QUOTEDDOC)
3885     {
3886       f &= ~LEX_QUOTEDDOC;
3887       fprintf (stderr, "LEX_QUOTEDDOC%s", f ? "|" : "");
3888     }
3889   if (f & LEX_INWORD)
3890     {
3891       f &= ~LEX_INWORD;
3892       fprintf (stderr, "LEX_INWORD%s", f ? "|" : "");
3893     }
3894 
3895   fprintf (stderr, "\n");
3896   fflush (stderr);
3897 }
3898 #endif
3899 
3900 /* Parse a $(...) command substitution.  This is messier than I'd like, and
3901    reproduces a lot more of the token-reading code than I'd like. */
3902 static char *
parse_comsub(qc,open,close,lenp,flags)3903 parse_comsub (qc, open, close, lenp, flags)
3904      int qc;	/* `"' if this construct is within double quotes */
3905      int open, close;
3906      int *lenp, flags;
3907 {
3908   int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
3909   int nestlen, ttranslen, start_lineno, orig_histexp;
3910   char *ret, *nestret, *ttrans, *heredelim;
3911   int retind, retsize, rflags, hdlen;
3912 
3913   /* Posix interp 217 says arithmetic expressions have precedence, so
3914      assume $(( introduces arithmetic expansion and parse accordingly. */
3915   peekc = shell_getc (0);
3916   shell_ungetc (peekc);
3917   if (peekc == '(')
3918     return (parse_matched_pair (qc, open, close, lenp, 0));
3919 
3920 /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
3921   count = 1;
3922   tflags = LEX_RESWDOK;
3923 #if defined (BANG_HISTORY)
3924   orig_histexp = history_expansion_inhibited;
3925 #endif
3926 
3927   if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3928     tflags |= LEX_CKCASE;
3929   if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
3930     tflags |= LEX_CKCOMMENT;
3931 
3932   /* RFLAGS is the set of flags we want to pass to recursive calls. */
3933   rflags = (flags & P_DQUOTE);
3934 
3935   ret = (char *)xmalloc (retsize = 64);
3936   retind = 0;
3937 
3938   start_lineno = line_number;
3939   lex_rwlen = lex_wlen = 0;
3940 
3941   heredelim = 0;
3942   lex_firstind = -1;
3943 
3944   while (count)
3945     {
3946 comsub_readchar:
3947       ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT|LEX_QUOTEDDOC)) == 0);
3948 
3949       if (ch == EOF)
3950 	{
3951 eof_error:
3952 #if defined (BANG_HISTORY)
3953 	  history_expansion_inhibited = orig_histexp;
3954 #endif
3955 	  free (ret);
3956 	  FREE (heredelim);
3957 	  parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3958 	  EOF_Reached = 1;	/* XXX */
3959 	  return (&matched_pair_error);
3960 	}
3961 
3962       /* If we hit the end of a line and are reading the contents of a here
3963 	 document, and it's not the same line that the document starts on,
3964 	 check for this line being the here doc delimiter.  Otherwise, if
3965 	 we're in a here document, mark the next character as the beginning
3966 	 of a line. */
3967       if (ch == '\n')
3968 	{
3969 	  if ((tflags & LEX_HEREDELIM) && heredelim)
3970 	    {
3971 	      tflags &= ~LEX_HEREDELIM;
3972 	      tflags |= LEX_INHEREDOC;
3973 #if defined (BANG_HISTORY)
3974 	      history_expansion_inhibited = 1;
3975 #endif
3976 	      lex_firstind = retind + 1;
3977 	    }
3978 	  else if (tflags & LEX_INHEREDOC)
3979 	    {
3980 	      int tind;
3981 	      tind = lex_firstind;
3982 	      while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3983 		tind++;
3984 	      if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
3985 		{
3986 		  tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
3987 /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
3988 		  free (heredelim);
3989 		  heredelim = 0;
3990 		  lex_firstind = -1;
3991 #if defined (BANG_HISTORY)
3992 		  history_expansion_inhibited = orig_histexp;
3993 #endif
3994 		}
3995 	      else
3996 		lex_firstind = retind + 1;
3997 	    }
3998 	}
3999 
4000       /* Possible reprompting. */
4001       if (ch == '\n' && SHOULD_PROMPT ())
4002 	prompt_again ();
4003 
4004       /* XXX -- we currently allow here doc to be delimited by ending right
4005 	 paren in default mode and posix mode. To change posix mode, change
4006 	 the #if 1 to #if 0 below */
4007       if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
4008 	{
4009 	  int tind;
4010 /*itrace("parse_comsub:%d: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", line_number, retind-lex_firstind, hdlen, retind);*/
4011 	  tind = lex_firstind;
4012 	  while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
4013 	    tind++;
4014 #if 1
4015   	  if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
4016 #else
4017 	  /* Posix-mode shells require the newline after the here-document
4018 	     delimiter. */
4019 	  if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen) &&
4020 	      posixly_correct == 0)
4021 #endif
4022 	    {
4023 	      tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
4024 /*itrace("parse_comsub:%d: found here doc end `%*s'", line_number, hdlen, ret + tind);*/
4025 	      free (heredelim);
4026 	      heredelim = 0;
4027 	      lex_firstind = -1;
4028 #if defined (BANG_HISTORY)
4029 	      history_expansion_inhibited = orig_histexp;
4030 #endif
4031 	    }
4032 	}
4033 
4034       /* Don't bother counting parens or doing anything else if in a comment or
4035 	 here document (not exactly right for here-docs -- if we want to allow
4036 	 recursive calls to parse_comsub to have their own here documents,
4037 	 change the LEX_INHEREDOC to LEX_QUOTEDDOC here and uncomment the next
4038 	 clause below.  Note that to make this work completely, we need to make
4039 	 additional changes to allow xparse_dolparen to work right when the
4040 	 command substitution is parsed, because read_secondary_line doesn't know
4041 	 to recursively parse through command substitutions embedded in here-
4042 	 documents */
4043       if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
4044 	{
4045 	  /* Add this character. */
4046 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4047 	  ret[retind++] = ch;
4048 
4049 	  if ((tflags & LEX_INCOMMENT) && ch == '\n')
4050 	    {
4051 /*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/
4052 	      tflags &= ~LEX_INCOMMENT;
4053 	    }
4054 
4055 	  continue;
4056 	}
4057 #if 0
4058       /* If we're going to recursively parse a command substitution inside a
4059 	 here-document, make sure we call parse_comsub recursively below.  See
4060 	 above for additional caveats. */
4061       if ((tflags & LEX_INHEREDOC) && ((tflags & LEX_WASDOL) == 0 || ch != '(')) /*)*/
4062 	{
4063 	  /* Add this character. */
4064 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4065 	  ret[retind++] = ch;
4066 	  if MBTEST(ch == '$')
4067 	    tflags |= LEX_WASDOL;
4068 	  else
4069 	    tflags &= ~LEX_WASDOL;
4070 	}
4071 #endif
4072 
4073       if (tflags & LEX_PASSNEXT)		/* last char was backslash */
4074 	{
4075 /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
4076 	  tflags &= ~LEX_PASSNEXT;
4077 	  if (qc != '\'' && ch == '\n')	/* double-quoted \<newline> disappears. */
4078 	    {
4079 	      if (retind > 0)
4080 		retind--;	/* swallow previously-added backslash */
4081 	      continue;
4082 	    }
4083 
4084 	  RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
4085 	  if MBTEST(ch == CTLESC)
4086 	    ret[retind++] = CTLESC;
4087 	  ret[retind++] = ch;
4088 	  continue;
4089 	}
4090 
4091       /* If this is a shell break character, we are not in a word.  If not,
4092 	 we either start or continue a word. */
4093       if MBTEST(shellbreak (ch))
4094 	{
4095 	  tflags &= ~LEX_INWORD;
4096 /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
4097 	}
4098       else
4099 	{
4100 	  if (tflags & LEX_INWORD)
4101 	    {
4102 	      lex_wlen++;
4103 /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
4104 	    }
4105 	  else
4106 	    {
4107 /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
4108 	      tflags |= LEX_INWORD;
4109 	      lex_wlen = 0;
4110 	      if (tflags & LEX_RESWDOK)
4111 		lex_rwlen = 0;
4112 	    }
4113 	}
4114 
4115       /* Skip whitespace */
4116       if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0)
4117         {
4118 	  /* Add this character. */
4119 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4120 	  ret[retind++] = ch;
4121 	  continue;
4122         }
4123 
4124       /* Either we are looking for the start of the here-doc delimiter
4125 	 (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
4126 	 If this character is a shell break character and we are reading
4127 	 the delimiter, save it and note that we are now reading a here
4128 	 document.  If we've found the start of the delimiter, note it by
4129 	 setting lex_firstind.  Backslashes can quote shell metacharacters
4130 	 in here-doc delimiters. */
4131       if (tflags & LEX_HEREDELIM)
4132 	{
4133 	  if (lex_firstind == -1 && shellbreak (ch) == 0)
4134 	    lex_firstind = retind;
4135 #if 0
4136 	  else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n')
4137 	    {
4138 	      tflags |= LEX_INHEREDOC;
4139 	      tflags &= ~LEX_HEREDELIM;
4140 	      lex_firstind = retind + 1;
4141 #if defined (BANG_HISTORY)
4142 	      history_expansion_inhibited = 1;
4143 #endif
4144 	    }
4145 #endif
4146 	  else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
4147 	    {
4148 	      if (heredelim == 0)
4149 		{
4150 		  nestret = substring (ret, lex_firstind, retind);
4151 		  heredelim = string_quote_removal (nestret, 0);
4152 		  hdlen = STRLEN(heredelim);
4153 /*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
4154 		  if (STREQ (heredelim, nestret) == 0)
4155 		    tflags |= LEX_QUOTEDDOC;
4156 		  free (nestret);
4157 		}
4158 	      if (ch == '\n')
4159 		{
4160 		  tflags |= LEX_INHEREDOC;
4161 		  tflags &= ~LEX_HEREDELIM;
4162 		  lex_firstind = retind + 1;
4163 #if defined (BANG_HISTORY)
4164 		  history_expansion_inhibited = 1;
4165 #endif
4166 		}
4167 	      else
4168 		lex_firstind = -1;
4169 	    }
4170 	}
4171 
4172       /* Meta-characters that can introduce a reserved word.  Not perfect yet. */
4173       if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
4174 	{
4175 	  /* Add this character. */
4176 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4177 	  ret[retind++] = ch;
4178 	  peekc = shell_getc (1);
4179 	  if (ch == peekc && (ch == '&' || ch == '|' || ch == ';'))	/* two-character tokens */
4180 	    {
4181 	      RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4182 	      ret[retind++] = peekc;
4183 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
4184 	      tflags |= LEX_RESWDOK;
4185 	      lex_rwlen = 0;
4186 	      continue;
4187 	    }
4188 	  else if (ch == '\n' || COMSUB_META(ch))
4189 	    {
4190 	      shell_ungetc (peekc);
4191 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
4192 	      tflags |= LEX_RESWDOK;
4193 	      lex_rwlen = 0;
4194 	      continue;
4195 	    }
4196 	  else if (ch == EOF)
4197 	    goto eof_error;
4198 	  else
4199 	    {
4200 	      /* `unget' the character we just added and fall through */
4201 	      retind--;
4202 	      shell_ungetc (peekc);
4203 	    }
4204 	}
4205 
4206       /* If we can read a reserved word, try to read one. */
4207       if (tflags & LEX_RESWDOK)
4208 	{
4209 	  if MBTEST(islower ((unsigned char)ch))
4210 	    {
4211 	      /* Add this character. */
4212 	      RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4213 	      ret[retind++] = ch;
4214 	      lex_rwlen++;
4215 	      continue;
4216 	    }
4217 	  else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
4218 	    {
4219 	      if (STREQN (ret + retind - 4, "case", 4))
4220 		{
4221 		  tflags |= LEX_INCASE;
4222 		  tflags &= ~LEX_RESWDOK;
4223 /*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
4224 		}
4225 	      else if (STREQN (ret + retind - 4, "esac", 4))
4226 		{
4227 		  tflags &= ~LEX_INCASE;
4228 /*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 1", line_number);*/
4229 		  tflags |= LEX_RESWDOK;
4230 		  lex_rwlen = 0;
4231 		}
4232 	      else if (STREQN (ret + retind - 4, "done", 4) ||
4233 		       STREQN (ret + retind - 4, "then", 4) ||
4234 		       STREQN (ret + retind - 4, "else", 4) ||
4235 		       STREQN (ret + retind - 4, "elif", 4) ||
4236 		       STREQN (ret + retind - 4, "time", 4))
4237 		{
4238 		  /* these are four-character reserved words that can be
4239 		     followed by a reserved word; anything else turns off
4240 		     the reserved-word-ok flag */
4241 /*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 1", line_number, ret+retind-4);*/
4242 		  tflags |= LEX_RESWDOK;
4243 		  lex_rwlen = 0;
4244 		}
4245 	       else if (shellmeta (ch) == 0)
4246 		{
4247 		  tflags &= ~LEX_RESWDOK;
4248 /*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 0", line_number, ret+retind-4);*/
4249 		}
4250 	      else	/* can't be in a reserved word any more */
4251 	        lex_rwlen = 0;
4252 	    }
4253 	  else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
4254 	    ;	/* don't modify LEX_RESWDOK if we're starting a comment */
4255 	  /* Allow `do' followed by space, tab, or newline to preserve the
4256 	     RESWDOK flag, but reset the reserved word length counter so we
4257 	     can read another one. */
4258 	  else if MBTEST(((tflags & LEX_INCASE) == 0) &&
4259 			  (isblank((unsigned char)ch) || ch == '\n') &&
4260 			  lex_rwlen == 2 &&
4261 			  STREQN (ret + retind - 2, "do", 2))
4262 	    {
4263 /*itrace("parse_comsub:%d: lex_incase == 0 found `%c', found \"do\"", line_number, ch);*/
4264 	      lex_rwlen = 0;
4265 	    }
4266 	  else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
4267 	    /* If we can read a reserved word and we're in case, we're at the
4268 	       point where we can read a new pattern list or an esac.  We
4269 	       handle the esac case above.  If we read a newline, we want to
4270 	       leave LEX_RESWDOK alone.  If we read anything else, we want to
4271 	       turn off LEX_RESWDOK, since we're going to read a pattern list. */
4272 	    {
4273 	      tflags &= ~LEX_RESWDOK;
4274 /*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
4275 	    }
4276 	  else if MBTEST(shellbreak (ch) == 0)
4277 	    {
4278 	      tflags &= ~LEX_RESWDOK;
4279 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
4280 	    }
4281 #if 0
4282 	  /* If we find a space or tab but have read something and it's not
4283 	     `do', turn off the reserved-word-ok flag */
4284 	  else if MBTEST(isblank ((unsigned char)ch) && lex_rwlen > 0)
4285 	    {
4286 	      tflags &= ~LEX_RESWDOK;
4287 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
4288 	    }
4289 #endif
4290 	}
4291 
4292       /* Might be the start of a here-doc delimiter */
4293       if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
4294 	{
4295 	  /* Add this character. */
4296 	  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4297 	  ret[retind++] = ch;
4298 	  peekc = shell_getc (1);
4299 	  if (peekc == EOF)
4300 	    goto eof_error;
4301 	  if (peekc == ch)
4302 	    {
4303 	      RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4304 	      ret[retind++] = peekc;
4305 	      peekc = shell_getc (1);
4306 	      if (peekc == EOF)
4307 		goto eof_error;
4308 	      if (peekc == '-')
4309 		{
4310 		  RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4311 		  ret[retind++] = peekc;
4312 		  tflags |= LEX_STRIPDOC;
4313 		}
4314 	      else
4315 		shell_ungetc (peekc);
4316 	      if (peekc != '<')
4317 		{
4318 		  tflags |= LEX_HEREDELIM;
4319 		  lex_firstind = -1;
4320 		}
4321 	      continue;
4322 	    }
4323 	  else
4324 	    {
4325 	      shell_ungetc (peekc);	/* not a here-doc, start over */
4326 	      continue;
4327 	    }
4328 	}
4329       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
4330 	{
4331 /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
4332 	  tflags |= LEX_INCOMMENT;
4333 	}
4334 
4335       if MBTEST(ch == CTLESC || ch == CTLNUL)	/* special shell escapes */
4336 	{
4337 	  RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
4338 	  ret[retind++] = CTLESC;
4339 	  ret[retind++] = ch;
4340 	  continue;
4341 	}
4342 #if 0
4343       else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
4344         tflags &= ~LEX_INCASE;		/* XXX */
4345 #endif
4346       else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0)		/* ending delimiter */
4347 	{
4348 	  count--;
4349 /*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
4350 	}
4351       else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open)	/* nested begin */
4352 	{
4353 	  count++;
4354 /*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
4355 	}
4356 
4357       /* Add this character. */
4358       RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4359       ret[retind++] = ch;
4360 
4361       /* If we just read the ending character, don't bother continuing. */
4362       if (count == 0)
4363 	break;
4364 
4365       if MBTEST(ch == '\\')			/* backslashes */
4366 	tflags |= LEX_PASSNEXT;
4367 
4368       if MBTEST(shellquote (ch))
4369         {
4370           /* '', ``, or "" inside $(...). */
4371           push_delimiter (dstack, ch);
4372           if MBTEST((tflags & LEX_WASDOL) && ch == '\'')	/* $'...' inside group */
4373 	    nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
4374 	  else
4375 	    nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
4376 	  pop_delimiter (dstack);
4377 	  CHECK_NESTRET_ERROR ();
4378 
4379 	  if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
4380 	    {
4381 	      /* Translate $'...' here. */
4382 	      ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
4383 	      free (nestret);
4384 
4385 	      if ((rflags & P_DQUOTE) == 0)
4386 		{
4387 		  nestret = sh_single_quote (ttrans);
4388 		  free (ttrans);
4389 		  nestlen = strlen (nestret);
4390 		}
4391 	      else
4392 		{
4393 		  nestret = ttrans;
4394 		  nestlen = ttranslen;
4395 		}
4396 	      retind -= 2;		/* back up before the $' */
4397 	    }
4398 	  else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
4399 	    {
4400 	      /* Locale expand $"..." here. */
4401 	      ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
4402 	      free (nestret);
4403 
4404 	      nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
4405 	      free (ttrans);
4406 	      nestlen = ttranslen + 2;
4407 	      retind -= 2;		/* back up before the $" */
4408 	    }
4409 
4410 	  APPEND_NESTRET ();
4411 	  FREE (nestret);
4412 	}
4413       else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))	/* ) } ] */
4414 	/* check for $(), $[], or ${} inside command substitution. */
4415 	{
4416 	  if ((tflags & LEX_INCASE) == 0 && open == ch)	/* undo previous increment */
4417 	    count--;
4418 	  if (ch == '(')		/* ) */
4419 	    nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
4420 	  else if (ch == '{')		/* } */
4421 	    nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
4422 	  else if (ch == '[')		/* ] */
4423 	    nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
4424 
4425 	  CHECK_NESTRET_ERROR ();
4426 	  APPEND_NESTRET ();
4427 
4428 	  FREE (nestret);
4429 	}
4430       if MBTEST(ch == '$' && (tflags & LEX_WASDOL) == 0)
4431 	tflags |= LEX_WASDOL;
4432       else
4433 	tflags &= ~LEX_WASDOL;
4434     }
4435 
4436 #if defined (BANG_HISTORY)
4437   history_expansion_inhibited = orig_histexp;
4438 #endif
4439   FREE (heredelim);
4440   ret[retind] = '\0';
4441   if (lenp)
4442     *lenp = retind;
4443 /*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
4444   return ret;
4445 }
4446 
4447 /* Recursively call the parser to parse a $(...) command substitution. */
4448 char *
xparse_dolparen(base,string,indp,flags)4449 xparse_dolparen (base, string, indp, flags)
4450      char *base;
4451      char *string;
4452      int *indp;
4453      int flags;
4454 {
4455   sh_parser_state_t ps;
4456   sh_input_line_state_t ls;
4457   int orig_ind, nc, sflags, orig_eof_token, start_lineno;
4458   char *ret, *ep, *ostring;
4459 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4460   STRING_SAVER *saved_pushed_strings;
4461 #endif
4462 
4463 /*debug_parser(1);*/
4464   orig_ind = *indp;
4465   ostring = string;
4466   start_lineno = line_number;
4467 
4468   if (*string == 0)
4469     {
4470       if (flags & SX_NOALLOC)
4471 	return (char *)NULL;
4472 
4473       ret = xmalloc (1);
4474       ret[0] = '\0';
4475       return ret;
4476     }
4477 
4478 /*itrace("xparse_dolparen: size = %d shell_input_line = `%s' string=`%s'", shell_input_line_size, shell_input_line, string);*/
4479   sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
4480   if (flags & SX_NOLONGJMP)
4481     sflags |= SEVAL_NOLONGJMP;
4482   save_parser_state (&ps);
4483   save_input_line_state (&ls);
4484   orig_eof_token = shell_eof_token;
4485 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4486   saved_pushed_strings = pushed_string_list;	/* separate parsing context */
4487   pushed_string_list = (STRING_SAVER *)NULL;
4488 #endif
4489 
4490   /*(*/
4491   parser_state |= PST_CMDSUBST|PST_EOFTOKEN;	/* allow instant ')' */ /*(*/
4492   shell_eof_token = ')';
4493 
4494   /* Should we save and restore the bison/yacc lookahead token (yychar) here?
4495      Or only if it's not YYEMPTY? */
4496 
4497   nc = parse_string (string, "command substitution", sflags, &ep);
4498 
4499   if (current_token == shell_eof_token)
4500     yyclearin;		/* might want to clear lookahead token unconditionally */
4501 
4502   reset_parser ();
4503   /* reset_parser() clears shell_input_line and associated variables, including
4504      parser_state, so we want to reset things, then restore what we need. */
4505   restore_input_line_state (&ls);
4506 
4507   shell_eof_token = orig_eof_token;
4508   restore_parser_state (&ps);
4509 
4510 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4511   pushed_string_list = saved_pushed_strings;
4512 #endif
4513 
4514   token_to_read = 0;
4515 
4516   /* If parse_string returns < 0, we need to jump to top level with the
4517      negative of the return value. We abandon the rest of this input line
4518      first */
4519   if (nc < 0)
4520     {
4521       clear_shell_input_line ();	/* XXX */
4522       if (bash_input.type != st_string)	/* paranoia */
4523 	parser_state &= ~(PST_CMDSUBST|PST_EOFTOKEN);
4524       jump_to_top_level (-nc);	/* XXX */
4525     }
4526 
4527   /* Need to find how many characters parse_and_execute consumed, update
4528      *indp, if flags != 0, copy the portion of the string parsed into RET
4529      and return it.  If flags & 1 (SX_NOALLOC) we can return NULL. */
4530 
4531   /*(*/
4532   if (ep[-1] != ')')
4533     {
4534 #if DEBUG
4535       if (ep[-1] != '\n')
4536 	itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
4537 #endif
4538 
4539       while (ep > ostring && ep[-1] == '\n') ep--;
4540     }
4541 
4542   nc = ep - ostring;
4543   *indp = ep - base - 1;
4544 
4545   /*((*/
4546 #if DEBUG
4547   if (base[*indp] != ')')
4548     itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
4549   if (*indp < orig_ind)
4550     itrace("xparse_dolparen:%d: *indp (%d) < orig_ind (%d), orig_string = `%s'", line_number, *indp, orig_ind, ostring);
4551 #endif
4552 
4553   if (base[*indp] != ')')
4554     {
4555       /*(*/
4556       parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), ')');
4557       jump_to_top_level (DISCARD);
4558     }
4559 
4560   if (flags & SX_NOALLOC)
4561     return (char *)NULL;
4562 
4563   if (nc == 0)
4564     {
4565       ret = xmalloc (1);
4566       ret[0] = '\0';
4567     }
4568   else
4569     ret = substring (ostring, 0, nc - 1);
4570 
4571   return ret;
4572 }
4573 
4574 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
4575 /* Parse a double-paren construct.  It can be either an arithmetic
4576    command, an arithmetic `for' command, or a nested subshell.  Returns
4577    the parsed token, -1 on error, or -2 if we didn't do anything and
4578    should just go on. */
4579 static int
parse_dparen(c)4580 parse_dparen (c)
4581      int c;
4582 {
4583   int cmdtyp, sline;
4584   char *wval;
4585   WORD_DESC *wd;
4586 
4587 #if defined (ARITH_FOR_COMMAND)
4588   if (last_read_token == FOR)
4589     {
4590       arith_for_lineno = line_number;
4591       cmdtyp = parse_arith_cmd (&wval, 0);
4592       if (cmdtyp == 1)
4593 	{
4594 	  wd = alloc_word_desc ();
4595 	  wd->word = wval;
4596 	  yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
4597 	  return (ARITH_FOR_EXPRS);
4598 	}
4599       else
4600 	return -1;		/* ERROR */
4601     }
4602 #endif
4603 
4604 #if defined (DPAREN_ARITHMETIC)
4605   if (reserved_word_acceptable (last_read_token))
4606     {
4607       sline = line_number;
4608 
4609       cmdtyp = parse_arith_cmd (&wval, 0);
4610       if (cmdtyp == 1)	/* arithmetic command */
4611 	{
4612 	  wd = alloc_word_desc ();
4613 	  wd->word = wval;
4614 	  wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
4615 	  yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
4616 	  return (ARITH_CMD);
4617 	}
4618       else if (cmdtyp == 0)	/* nested subshell */
4619 	{
4620 	  push_string (wval, 0, (alias_t *)NULL);
4621 	  pushed_string_list->flags = PSH_DPAREN;
4622 	  if ((parser_state & PST_CASEPAT) == 0)
4623 	    parser_state |= PST_SUBSHELL;
4624 	  return (c);
4625 	}
4626       else			/* ERROR */
4627 	return -1;
4628     }
4629 #endif
4630 
4631   return -2;			/* XXX */
4632 }
4633 
4634 /* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
4635    If not, assume it's a nested subshell for backwards compatibility and
4636    return 0.  In any case, put the characters we've consumed into a locally-
4637    allocated buffer and make *ep point to that buffer.  Return -1 on an
4638    error, for example EOF. */
4639 static int
parse_arith_cmd(ep,adddq)4640 parse_arith_cmd (ep, adddq)
4641      char **ep;
4642      int adddq;
4643 {
4644   int exp_lineno, rval, c;
4645   char *ttok, *tokstr;
4646   int ttoklen;
4647 
4648   exp_lineno = line_number;
4649   ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
4650   rval = 1;
4651   if (ttok == &matched_pair_error)
4652     return -1;
4653   /* Check that the next character is the closing right paren.  If
4654      not, this is a syntax error. ( */
4655   c = shell_getc (0);
4656   if MBTEST(c != ')')
4657     rval = 0;
4658 
4659   tokstr = (char *)xmalloc (ttoklen + 4);
4660 
4661   /* if ADDDQ != 0 then (( ... )) -> "..." */
4662   if (rval == 1 && adddq)	/* arith cmd, add double quotes */
4663     {
4664       tokstr[0] = '"';
4665       strncpy (tokstr + 1, ttok, ttoklen - 1);
4666       tokstr[ttoklen] = '"';
4667       tokstr[ttoklen+1] = '\0';
4668     }
4669   else if (rval == 1)		/* arith cmd, don't add double quotes */
4670     {
4671       strncpy (tokstr, ttok, ttoklen - 1);
4672       tokstr[ttoklen-1] = '\0';
4673     }
4674   else				/* nested subshell */
4675     {
4676       tokstr[0] = '(';
4677       strncpy (tokstr + 1, ttok, ttoklen - 1);
4678       tokstr[ttoklen] = ')';
4679       tokstr[ttoklen+1] = c;
4680       tokstr[ttoklen+2] = '\0';
4681     }
4682 
4683   *ep = tokstr;
4684   FREE (ttok);
4685   return rval;
4686 }
4687 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
4688 
4689 #if defined (COND_COMMAND)
4690 static void
cond_error()4691 cond_error ()
4692 {
4693   char *etext;
4694 
4695   if (EOF_Reached && cond_token != COND_ERROR)		/* [[ */
4696     parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
4697   else if (cond_token != COND_ERROR)
4698     {
4699       if (etext = error_token_from_token (cond_token))
4700 	{
4701 	  parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
4702 	  free (etext);
4703 	}
4704       else
4705 	parser_error (cond_lineno, _("syntax error in conditional expression"));
4706     }
4707 }
4708 
4709 static COND_COM *
cond_expr()4710 cond_expr ()
4711 {
4712   return (cond_or ());
4713 }
4714 
4715 static COND_COM *
cond_or()4716 cond_or ()
4717 {
4718   COND_COM *l, *r;
4719 
4720   l = cond_and ();
4721   if (cond_token == OR_OR)
4722     {
4723       r = cond_or ();
4724       l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
4725     }
4726   return l;
4727 }
4728 
4729 static COND_COM *
cond_and()4730 cond_and ()
4731 {
4732   COND_COM *l, *r;
4733 
4734   l = cond_term ();
4735   if (cond_token == AND_AND)
4736     {
4737       r = cond_and ();
4738       l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
4739     }
4740   return l;
4741 }
4742 
4743 static int
cond_skip_newlines()4744 cond_skip_newlines ()
4745 {
4746   while ((cond_token = read_token (READ)) == '\n')
4747     {
4748       if (SHOULD_PROMPT ())
4749 	prompt_again ();
4750     }
4751   return (cond_token);
4752 }
4753 
4754 #define COND_RETURN_ERROR() \
4755   do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
4756 
4757 static COND_COM *
cond_term()4758 cond_term ()
4759 {
4760   WORD_DESC *op;
4761   COND_COM *term, *tleft, *tright;
4762   int tok, lineno;
4763   char *etext;
4764 
4765   /* Read a token.  It can be a left paren, a `!', a unary operator, or a
4766      word that should be the first argument of a binary operator.  Start by
4767      skipping newlines, since this is a compound command. */
4768   tok = cond_skip_newlines ();
4769   lineno = line_number;
4770   if (tok == COND_END)
4771     {
4772       COND_RETURN_ERROR ();
4773     }
4774   else if (tok == '(')
4775     {
4776       term = cond_expr ();
4777       if (cond_token != ')')
4778 	{
4779 	  if (term)
4780 	    dispose_cond_node (term);		/* ( */
4781 	  if (etext = error_token_from_token (cond_token))
4782 	    {
4783 	      parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
4784 	      free (etext);
4785 	    }
4786 	  else
4787 	    parser_error (lineno, _("expected `)'"));
4788 	  COND_RETURN_ERROR ();
4789 	}
4790       term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
4791       (void)cond_skip_newlines ();
4792     }
4793   else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
4794     {
4795       if (tok == WORD)
4796 	dispose_word (yylval.word);	/* not needed */
4797       term = cond_term ();
4798       if (term)
4799 	term->flags |= CMD_INVERT_RETURN;
4800     }
4801   else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[1] && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
4802     {
4803       op = yylval.word;
4804       tok = read_token (READ);
4805       if (tok == WORD)
4806 	{
4807 	  tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4808 	  term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4809 	}
4810       else
4811 	{
4812 	  dispose_word (op);
4813 	  if (etext = error_token_from_token (tok))
4814 	    {
4815 	      parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
4816 	      free (etext);
4817 	    }
4818 	  else
4819 	    parser_error (line_number, _("unexpected argument to conditional unary operator"));
4820 	  COND_RETURN_ERROR ();
4821 	}
4822 
4823       (void)cond_skip_newlines ();
4824     }
4825   else if (tok == WORD)		/* left argument to binary operator */
4826     {
4827       /* lhs */
4828       tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4829 
4830       /* binop */
4831       tok = read_token (READ);
4832       if (tok == WORD && test_binop (yylval.word->word))
4833 	{
4834 	  op = yylval.word;
4835 	  if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
4836 	    parser_state |= PST_EXTPAT;
4837 	  else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
4838 	    parser_state |= PST_EXTPAT;
4839 	}
4840 #if defined (COND_REGEXP)
4841       else if (tok == WORD && STREQ (yylval.word->word, "=~"))
4842 	{
4843 	  op = yylval.word;
4844 	  parser_state |= PST_REGEXP;
4845 	}
4846 #endif
4847       else if (tok == '<' || tok == '>')
4848 	op = make_word_from_token (tok);  /* ( */
4849       /* There should be a check before blindly accepting the `)' that we have
4850 	 seen the opening `('. */
4851       else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
4852 	{
4853 	  /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
4854 	     the test command.  Similarly for [[ x && expr ]] or
4855 	     [[ x || expr ]] or [[ (x) ]]. */
4856 	  op = make_word ("-n");
4857 	  term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4858 	  cond_token = tok;
4859 	  return (term);
4860 	}
4861       else
4862 	{
4863 	  if (etext = error_token_from_token (tok))
4864 	    {
4865 	      parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
4866 	      free (etext);
4867 	    }
4868 	  else
4869 	    parser_error (line_number, _("conditional binary operator expected"));
4870 	  dispose_cond_node (tleft);
4871 	  COND_RETURN_ERROR ();
4872 	}
4873 
4874       /* rhs */
4875       if (parser_state & PST_EXTPAT)
4876 	extended_glob = 1;
4877       tok = read_token (READ);
4878       if (parser_state & PST_EXTPAT)
4879 	extended_glob = global_extglob;
4880       parser_state &= ~(PST_REGEXP|PST_EXTPAT);
4881 
4882       if (tok == WORD)
4883 	{
4884 	  tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4885 	  term = make_cond_node (COND_BINARY, op, tleft, tright);
4886 	}
4887       else
4888 	{
4889 	  if (etext = error_token_from_token (tok))
4890 	    {
4891 	      parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
4892 	      free (etext);
4893 	    }
4894 	  else
4895 	    parser_error (line_number, _("unexpected argument to conditional binary operator"));
4896 	  dispose_cond_node (tleft);
4897 	  dispose_word (op);
4898 	  COND_RETURN_ERROR ();
4899 	}
4900 
4901       (void)cond_skip_newlines ();
4902     }
4903   else
4904     {
4905       if (tok < 256)
4906 	parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
4907       else if (etext = error_token_from_token (tok))
4908 	{
4909 	  parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
4910 	  free (etext);
4911 	}
4912       else
4913 	parser_error (line_number, _("unexpected token %d in conditional command"), tok);
4914       COND_RETURN_ERROR ();
4915     }
4916   return (term);
4917 }
4918 
4919 /* This is kind of bogus -- we slip a mini recursive-descent parser in
4920    here to handle the conditional statement syntax. */
4921 static COMMAND *
parse_cond_command()4922 parse_cond_command ()
4923 {
4924   COND_COM *cexp;
4925 
4926   global_extglob = extended_glob;
4927   cexp = cond_expr ();
4928   return (make_cond_command (cexp));
4929 }
4930 #endif
4931 
4932 #if defined (ARRAY_VARS)
4933 /* When this is called, it's guaranteed that we don't care about anything
4934    in t beyond i.  We use a buffer with room for the characters we add just
4935    in case assignment() ends up doing something like parsing a command
4936    substitution that will reallocate atoken.  We don't want to write beyond
4937    the end of an allocated buffer. */
4938 static int
token_is_assignment(t,i)4939 token_is_assignment (t, i)
4940      char *t;
4941      int i;
4942 {
4943   int r;
4944   char *atoken;
4945 
4946   atoken = xmalloc (i + 3);
4947   memcpy (atoken, t, i);
4948   atoken[i] = '=';
4949   atoken[i+1] = '\0';
4950 
4951   r = assignment (atoken, (parser_state & PST_COMPASSIGN) != 0);
4952 
4953   free (atoken);
4954 
4955   /* XXX - check that r == i to avoid returning false positive for
4956      t containing `=' before t[i]. */
4957   return (r > 0 && r == i);
4958 }
4959 
4960 /* XXX - possible changes here for `+=' */
4961 static int
token_is_ident(t,i)4962 token_is_ident (t, i)
4963      char *t;
4964      int i;
4965 {
4966   unsigned char c;
4967   int r;
4968 
4969   c = t[i];
4970   t[i] = '\0';
4971   r = legal_identifier (t);
4972   t[i] = c;
4973   return r;
4974 }
4975 #endif
4976 
4977 static int
read_token_word(character)4978 read_token_word (character)
4979      int character;
4980 {
4981   /* The value for YYLVAL when a WORD is read. */
4982   WORD_DESC *the_word;
4983 
4984   /* Index into the token that we are building. */
4985   int token_index;
4986 
4987   /* ALL_DIGITS becomes zero when we see a non-digit. */
4988   int all_digit_token;
4989 
4990   /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4991   int dollar_present;
4992 
4993   /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4994      assignment. */
4995   int compound_assignment;
4996 
4997   /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4998   int quoted;
4999 
5000   /* Non-zero means to ignore the value of the next character, and just
5001      to add it no matter what. */
5002   int pass_next_character;
5003 
5004   /* The current delimiting character. */
5005   int cd;
5006   int result, peek_char;
5007   char *ttok, *ttrans;
5008   int ttoklen, ttranslen;
5009   intmax_t lvalue;
5010 
5011   if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
5012     token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
5013 
5014   token_index = 0;
5015   all_digit_token = DIGIT (character);
5016   dollar_present = quoted = pass_next_character = compound_assignment = 0;
5017 
5018   for (;;)
5019     {
5020       if (character == EOF)
5021 	goto got_token;
5022 
5023       if (pass_next_character)
5024 	{
5025 	  pass_next_character = 0;
5026 	  goto got_escaped_character;
5027 	}
5028 
5029       cd = current_delimiter (dstack);
5030 
5031       /* Handle backslashes.  Quote lots of things when not inside of
5032 	 double-quotes, quote some things inside of double-quotes. */
5033       if MBTEST(character == '\\')
5034 	{
5035 	  peek_char = shell_getc (0);
5036 
5037 	  /* Backslash-newline is ignored in all cases except
5038 	     when quoted with single quotes. */
5039 	  if (peek_char == '\n')
5040 	    {
5041 	      character = '\n';
5042 	      goto next_character;
5043 	    }
5044 	  else
5045 	    {
5046 	      shell_ungetc (peek_char);
5047 
5048 	      /* If the next character is to be quoted, note it now. */
5049 	      if (cd == 0 || cd == '`' ||
5050 		  (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
5051 		pass_next_character++;
5052 
5053 	      quoted = 1;
5054 	      goto got_character;
5055 	    }
5056 	}
5057 
5058       /* Parse a matched pair of quote characters. */
5059       if MBTEST(shellquote (character))
5060 	{
5061 	  push_delimiter (dstack, character);
5062 	  ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
5063 	  pop_delimiter (dstack);
5064 	  if (ttok == &matched_pair_error)
5065 	    return -1;		/* Bail immediately. */
5066 	  RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
5067 				  token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
5068 	  token[token_index++] = character;
5069 	  strcpy (token + token_index, ttok);
5070 	  token_index += ttoklen;
5071 	  all_digit_token = 0;
5072 	  if (character != '`')
5073 	    quoted = 1;
5074 	  dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
5075 	  FREE (ttok);
5076 	  goto next_character;
5077 	}
5078 
5079 #ifdef COND_REGEXP
5080       /* When parsing a regexp as a single word inside a conditional command,
5081 	 we need to special-case characters special to both the shell and
5082 	 regular expressions.  Right now, that is only '(' and '|'. */ /*)*/
5083       if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|'))		/*)*/
5084 	{
5085 	  if (character == '|')
5086 	    goto got_character;
5087 
5088 	  push_delimiter (dstack, character);
5089 	  ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
5090 	  pop_delimiter (dstack);
5091 	  if (ttok == &matched_pair_error)
5092 	    return -1;		/* Bail immediately. */
5093 	  RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
5094 				  token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
5095 	  token[token_index++] = character;
5096 	  strcpy (token + token_index, ttok);
5097 	  token_index += ttoklen;
5098 	  FREE (ttok);
5099 	  dollar_present = all_digit_token = 0;
5100 	  goto next_character;
5101 	}
5102 #endif /* COND_REGEXP */
5103 
5104 #ifdef EXTENDED_GLOB
5105       /* Parse a ksh-style extended pattern matching specification. */
5106       if MBTEST(extended_glob && PATTERN_CHAR (character))
5107 	{
5108 	  peek_char = shell_getc (1);
5109 	  if MBTEST(peek_char == '(')		/* ) */
5110 	    {
5111 	      push_delimiter (dstack, peek_char);
5112 	      ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
5113 	      pop_delimiter (dstack);
5114 	      if (ttok == &matched_pair_error)
5115 		return -1;		/* Bail immediately. */
5116 	      RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
5117 				      token_buffer_size,
5118 				      TOKEN_DEFAULT_GROW_SIZE);
5119 	      token[token_index++] = character;
5120 	      token[token_index++] = peek_char;
5121 	      strcpy (token + token_index, ttok);
5122 	      token_index += ttoklen;
5123 	      FREE (ttok);
5124 	      dollar_present = all_digit_token = 0;
5125 	      goto next_character;
5126 	    }
5127 	  else
5128 	    shell_ungetc (peek_char);
5129 	}
5130 #endif /* EXTENDED_GLOB */
5131 
5132       /* If the delimiter character is not single quote, parse some of
5133 	 the shell expansions that must be read as a single word. */
5134       if (shellexp (character))
5135 	{
5136 	  peek_char = shell_getc (1);
5137 	  /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
5138 	  if MBTEST(peek_char == '(' ||
5139 		((peek_char == '{' || peek_char == '[') && character == '$'))	/* ) ] } */
5140 	    {
5141 	      if (peek_char == '{')		/* } */
5142 		ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
5143 	      else if (peek_char == '(')		/* ) */
5144 		{
5145 		  /* XXX - push and pop the `(' as a delimiter for use by
5146 		     the command-oriented-history code.  This way newlines
5147 		     appearing in the $(...) string get added to the
5148 		     history literally rather than causing a possibly-
5149 		     incorrect `;' to be added. ) */
5150 		  push_delimiter (dstack, peek_char);
5151 		  ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
5152 		  pop_delimiter (dstack);
5153 		}
5154 	      else
5155 		ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
5156 	      if (ttok == &matched_pair_error)
5157 		return -1;		/* Bail immediately. */
5158 	      RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
5159 				      token_buffer_size,
5160 				      TOKEN_DEFAULT_GROW_SIZE);
5161 	      token[token_index++] = character;
5162 	      token[token_index++] = peek_char;
5163 	      strcpy (token + token_index, ttok);
5164 	      token_index += ttoklen;
5165 	      FREE (ttok);
5166 	      dollar_present = 1;
5167 	      all_digit_token = 0;
5168 	      goto next_character;
5169 	    }
5170 	  /* This handles $'...' and $"..." new-style quoted strings. */
5171 	  else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
5172 	    {
5173 	      int first_line;
5174 
5175 	      first_line = line_number;
5176 	      push_delimiter (dstack, peek_char);
5177 	      ttok = parse_matched_pair (peek_char, peek_char, peek_char,
5178 					 &ttoklen,
5179 					 (peek_char == '\'') ? P_ALLOWESC : 0);
5180 	      pop_delimiter (dstack);
5181 	      if (ttok == &matched_pair_error)
5182 		return -1;
5183 	      if (peek_char == '\'')
5184 		{
5185 		  ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
5186 		  free (ttok);
5187 
5188 		  /* Insert the single quotes and correctly quote any
5189 		     embedded single quotes (allowed because P_ALLOWESC was
5190 		     passed to parse_matched_pair). */
5191 		  ttok = sh_single_quote (ttrans);
5192 		  free (ttrans);
5193 		  ttranslen = strlen (ttok);
5194 		  ttrans = ttok;
5195 		}
5196 	      else
5197 		{
5198 		  /* Try to locale-expand the converted string. */
5199 		  ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
5200 		  free (ttok);
5201 
5202 		  /* Add the double quotes back */
5203 		  ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
5204 		  free (ttrans);
5205 		  ttranslen += 2;
5206 		  ttrans = ttok;
5207 		}
5208 
5209 	      RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1,
5210 				      token_buffer_size,
5211 				      TOKEN_DEFAULT_GROW_SIZE);
5212 	      strcpy (token + token_index, ttrans);
5213 	      token_index += ttranslen;
5214 	      FREE (ttrans);
5215 	      quoted = 1;
5216 	      all_digit_token = 0;
5217 	      goto next_character;
5218 	    }
5219 	  /* This could eventually be extended to recognize all of the
5220 	     shell's single-character parameter expansions, and set flags.*/
5221 	  else if MBTEST(character == '$' && peek_char == '$')
5222 	    {
5223 	      RESIZE_MALLOCED_BUFFER (token, token_index, 3,
5224 				      token_buffer_size,
5225 				      TOKEN_DEFAULT_GROW_SIZE);
5226 	      token[token_index++] = '$';
5227 	      token[token_index++] = peek_char;
5228 	      dollar_present = 1;
5229 	      all_digit_token = 0;
5230 	      goto next_character;
5231 	    }
5232 	  else
5233 	    shell_ungetc (peek_char);
5234 	}
5235 
5236 #if defined (ARRAY_VARS)
5237       /* Identify possible array subscript assignment; match [...].  If
5238 	 parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
5239 	 `sub' as if it were enclosed in double quotes. */
5240       else if MBTEST(character == '[' &&		/* ] */
5241 		     ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
5242 		      (token_index == 0 && (parser_state&PST_COMPASSIGN))))
5243         {
5244 	  ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
5245 	  if (ttok == &matched_pair_error)
5246 	    return -1;		/* Bail immediately. */
5247 	  RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
5248 				  token_buffer_size,
5249 				  TOKEN_DEFAULT_GROW_SIZE);
5250 	  token[token_index++] = character;
5251 	  strcpy (token + token_index, ttok);
5252 	  token_index += ttoklen;
5253 	  FREE (ttok);
5254 	  all_digit_token = 0;
5255 	  goto next_character;
5256         }
5257       /* Identify possible compound array variable assignment. */
5258       else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
5259 	{
5260 	  peek_char = shell_getc (1);
5261 	  if MBTEST(peek_char == '(')		/* ) */
5262 	    {
5263 	      ttok = parse_compound_assignment (&ttoklen);
5264 
5265 	      RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
5266 				      token_buffer_size,
5267 				      TOKEN_DEFAULT_GROW_SIZE);
5268 
5269 	      token[token_index++] = '=';
5270 	      token[token_index++] = '(';
5271 	      if (ttok)
5272 		{
5273 		  strcpy (token + token_index, ttok);
5274 		  token_index += ttoklen;
5275 		}
5276 	      token[token_index++] = ')';
5277 	      FREE (ttok);
5278 	      all_digit_token = 0;
5279 	      compound_assignment = 1;
5280 #if 1
5281 	      goto next_character;
5282 #else
5283 	      goto got_token;		/* ksh93 seems to do this */
5284 #endif
5285 	    }
5286 	  else
5287 	    shell_ungetc (peek_char);
5288 	}
5289 #endif
5290 
5291       /* When not parsing a multi-character word construct, shell meta-
5292 	 characters break words. */
5293       if MBTEST(shellbreak (character))
5294 	{
5295 	  shell_ungetc (character);
5296 	  goto got_token;
5297 	}
5298 
5299 got_character:
5300       if (character == CTLESC || character == CTLNUL)
5301 	{
5302 	  RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size,
5303 				  TOKEN_DEFAULT_GROW_SIZE);
5304 	  token[token_index++] = CTLESC;
5305 	}
5306       else
5307 got_escaped_character:
5308 	RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
5309 				TOKEN_DEFAULT_GROW_SIZE);
5310 
5311       token[token_index++] = character;
5312 
5313       all_digit_token &= DIGIT (character);
5314       dollar_present |= character == '$';
5315 
5316     next_character:
5317       if (character == '\n' && SHOULD_PROMPT ())
5318 	prompt_again ();
5319 
5320       /* We want to remove quoted newlines (that is, a \<newline> pair)
5321 	 unless we are within single quotes or pass_next_character is
5322 	 set (the shell equivalent of literal-next). */
5323       cd = current_delimiter (dstack);
5324       character = shell_getc (cd != '\'' && pass_next_character == 0);
5325     }	/* end for (;;) */
5326 
5327 got_token:
5328 
5329   /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */
5330   token[token_index] = '\0';
5331 
5332   /* Check to see what thing we should return.  If the last_read_token
5333      is a `<', or a `&', or the character which ended this token is
5334      a '>' or '<', then, and ONLY then, is this input token a NUMBER.
5335      Otherwise, it is just a word, and should be returned as such. */
5336   if MBTEST(all_digit_token && (character == '<' || character == '>' ||
5337 		    last_read_token == LESS_AND ||
5338 		    last_read_token == GREATER_AND))
5339       {
5340 	if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
5341 	  {
5342 	    yylval.number = lvalue;
5343 	    return (NUMBER);
5344 	  }
5345       }
5346 
5347   /* Check for special case tokens. */
5348   result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
5349   if (result >= 0)
5350     return result;
5351 
5352 #if defined (ALIAS)
5353   /* Posix.2 does not allow reserved words to be aliased, so check for all
5354      of them, including special cases, before expanding the current token
5355      as an alias. */
5356   if MBTEST(posixly_correct)
5357     CHECK_FOR_RESERVED_WORD (token);
5358 
5359   /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
5360      inhibits alias expansion. */
5361   if (expand_aliases && quoted == 0)
5362     {
5363       result = alias_expand_token (token);
5364       if (result == RE_READ_TOKEN)
5365 	return (RE_READ_TOKEN);
5366       else if (result == NO_EXPANSION)
5367 	parser_state &= ~PST_ALEXPNEXT;
5368     }
5369 
5370   /* If not in Posix.2 mode, check for reserved words after alias
5371      expansion. */
5372   if MBTEST(posixly_correct == 0)
5373 #endif
5374     CHECK_FOR_RESERVED_WORD (token);
5375 
5376   the_word = alloc_word_desc ();
5377   the_word->word = (char *)xmalloc (1 + token_index);
5378   the_word->flags = 0;
5379   strcpy (the_word->word, token);
5380   if (dollar_present)
5381     the_word->flags |= W_HASDOLLAR;
5382   if (quoted)
5383     the_word->flags |= W_QUOTED;		/*(*/
5384   if (compound_assignment && token[token_index-1] == ')')
5385     the_word->flags |= W_COMPASSIGN;
5386   /* A word is an assignment if it appears at the beginning of a
5387      simple command, or after another assignment word.  This is
5388      context-dependent, so it cannot be handled in the grammar. */
5389   if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
5390     {
5391       the_word->flags |= W_ASSIGNMENT;
5392       /* Don't perform word splitting on assignment statements. */
5393       if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
5394 	{
5395 	  the_word->flags |= W_NOSPLIT;
5396 	  if (parser_state & PST_COMPASSIGN)
5397 	    the_word->flags |= W_NOGLOB;	/* XXX - W_NOBRACE? */
5398 	}
5399     }
5400 
5401   if (command_token_position (last_read_token))
5402     {
5403       struct builtin *b;
5404       b = builtin_address_internal (token, 0);
5405       if (b && (b->flags & ASSIGNMENT_BUILTIN))
5406 	parser_state |= PST_ASSIGNOK;
5407       else if (STREQ (token, "eval") || STREQ (token, "let"))
5408 	parser_state |= PST_ASSIGNOK;
5409     }
5410 
5411   yylval.word = the_word;
5412 
5413   /* should we check that quoted == 0 as well? */
5414   if (token[0] == '{' && token[token_index-1] == '}' &&
5415       (character == '<' || character == '>'))
5416     {
5417       /* can use token; already copied to the_word */
5418       token[token_index-1] = '\0';
5419 #if defined (ARRAY_VARS)
5420       if (legal_identifier (token+1) || valid_array_reference (token+1, 0))
5421 #else
5422       if (legal_identifier (token+1))
5423 #endif
5424 	{
5425 	  strcpy (the_word->word, token+1);
5426 /* itrace("read_token_word: returning REDIR_WORD for %s", the_word->word); */
5427 	  yylval.word = the_word;	/* accommodate recursive call */
5428 	  return (REDIR_WORD);
5429 	}
5430       else
5431         /* valid_array_reference can call the parser recursively; need to
5432 	   make sure that yylval.word doesn't change if we are going to
5433 	   return WORD or ASSIGNMENT_WORD */
5434         yylval.word = the_word;
5435     }
5436 
5437   result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
5438 		? ASSIGNMENT_WORD : WORD;
5439 
5440   switch (last_read_token)
5441     {
5442     case FUNCTION:
5443       parser_state |= PST_ALLOWOPNBRC;
5444       function_dstart = line_number;
5445       break;
5446     case CASE:
5447     case SELECT:
5448     case FOR:
5449       if (word_top < MAX_CASE_NEST)
5450 	word_top++;
5451       word_lineno[word_top] = line_number;
5452       expecting_in_token++;
5453       break;
5454     }
5455 
5456   return (result);
5457 }
5458 
5459 /* Return 1 if TOKSYM is a token that after being read would allow
5460    a reserved word to be seen, else 0. */
5461 static int
reserved_word_acceptable(toksym)5462 reserved_word_acceptable (toksym)
5463      int toksym;
5464 {
5465   switch (toksym)
5466     {
5467     case '\n':
5468     case ';':
5469     case '(':
5470     case ')':
5471     case '|':
5472     case '&':
5473     case '{':
5474     case '}':		/* XXX */
5475     case AND_AND:
5476     case BANG:
5477     case BAR_AND:
5478     case DO:
5479     case DONE:
5480     case ELIF:
5481     case ELSE:
5482     case ESAC:
5483     case FI:
5484     case IF:
5485     case OR_OR:
5486     case SEMI_SEMI:
5487     case SEMI_AND:
5488     case SEMI_SEMI_AND:
5489     case THEN:
5490     case TIME:
5491     case TIMEOPT:
5492     case TIMEIGN:
5493     case COPROC:
5494     case UNTIL:
5495     case WHILE:
5496     case 0:
5497       return 1;
5498     default:
5499 #if defined (COPROCESS_SUPPORT)
5500       if (last_read_token == WORD && token_before_that == COPROC)
5501 	return 1;
5502 #endif
5503       if (last_read_token == WORD && token_before_that == FUNCTION)
5504 	return 1;
5505       return 0;
5506     }
5507 }
5508 
5509 /* Return the index of TOKEN in the alist of reserved words, or -1 if
5510    TOKEN is not a shell reserved word. */
5511 int
find_reserved_word(tokstr)5512 find_reserved_word (tokstr)
5513      char *tokstr;
5514 {
5515   int i;
5516   for (i = 0; word_token_alist[i].word; i++)
5517     if (STREQ (tokstr, word_token_alist[i].word))
5518       return i;
5519   return -1;
5520 }
5521 
5522 /* An interface to let the rest of the shell (primarily the completion
5523    system) know what the parser is expecting. */
5524 int
parser_in_command_position()5525 parser_in_command_position ()
5526 {
5527   return (command_token_position (last_read_token));
5528 }
5529 
5530 #if 0
5531 #if defined (READLINE)
5532 /* Called after each time readline is called.  This insures that whatever
5533    the new prompt string is gets propagated to readline's local prompt
5534    variable. */
5535 static void
5536 reset_readline_prompt ()
5537 {
5538   char *temp_prompt;
5539 
5540   if (prompt_string_pointer)
5541     {
5542       temp_prompt = (*prompt_string_pointer)
5543 			? decode_prompt_string (*prompt_string_pointer)
5544 			: (char *)NULL;
5545 
5546       if (temp_prompt == 0)
5547 	{
5548 	  temp_prompt = (char *)xmalloc (1);
5549 	  temp_prompt[0] = '\0';
5550 	}
5551 
5552       FREE (current_readline_prompt);
5553       current_readline_prompt = temp_prompt;
5554     }
5555 }
5556 #endif /* READLINE */
5557 #endif /* 0 */
5558 
5559 #if defined (HISTORY)
5560 /* A list of tokens which can be followed by newlines, but not by
5561    semi-colons.  When concatenating multiple lines of history, the
5562    newline separator for such tokens is replaced with a space. */
5563 static const int no_semi_successors[] = {
5564   '\n', '{', '(', ')', ';', '&', '|',
5565   CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
5566   WHILE, AND_AND, OR_OR, IN,
5567   0
5568 };
5569 
5570 /* If we are not within a delimited expression, try to be smart
5571    about which separators can be semi-colons and which must be
5572    newlines.  Returns the string that should be added into the
5573    history entry.  LINE is the line we're about to add; it helps
5574    make some more intelligent decisions in certain cases. */
5575 char *
history_delimiting_chars(line)5576 history_delimiting_chars (line)
5577      const char *line;
5578 {
5579   static int last_was_heredoc = 0;	/* was the last entry the start of a here document? */
5580   register int i;
5581 
5582   if ((parser_state & PST_HEREDOC) == 0)
5583     last_was_heredoc = 0;
5584 
5585   if (dstack.delimiter_depth != 0)
5586     return ("\n");
5587 
5588   /* We look for current_command_line_count == 2 because we are looking to
5589      add the first line of the body of the here document (the second line
5590      of the command).  We also keep LAST_WAS_HEREDOC as a private sentinel
5591      variable to note when we think we added the first line of a here doc
5592      (the one with a "<<" somewhere in it) */
5593   if (parser_state & PST_HEREDOC)
5594     {
5595       if (last_was_heredoc)
5596 	{
5597 	  last_was_heredoc = 0;
5598 	  return "\n";
5599 	}
5600       return (here_doc_first_line ? "\n" : "");
5601     }
5602 
5603   if (parser_state & PST_COMPASSIGN)
5604     return (" ");
5605 
5606   /* First, handle some special cases. */
5607   /*(*/
5608   /* If we just read `()', assume it's a function definition, and don't
5609      add a semicolon.  If the token before the `)' was not `(', and we're
5610      not in the midst of parsing a case statement, assume it's a
5611      parenthesized command and add the semicolon. */
5612   /*)(*/
5613   if (token_before_that == ')')
5614     {
5615       if (two_tokens_ago == '(')	/*)*/	/* function def */
5616 	return " ";
5617       /* This does not work for subshells inside case statement
5618 	 command lists.  It's a suboptimal solution. */
5619       else if (parser_state & PST_CASESTMT)	/* case statement pattern */
5620 	return " ";
5621       else
5622 	return "; ";				/* (...) subshell */
5623     }
5624   else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
5625     return " ";		/* function def using `function name' without `()' */
5626 
5627   /* If we're not in a here document, but we think we're about to parse one,
5628      and we would otherwise return a `;', return a newline to delimit the
5629      line with the here-doc delimiter */
5630   else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
5631     {
5632       last_was_heredoc = 1;
5633       return "\n";
5634     }
5635   else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && need_here_doc > 0)
5636     return "\n";
5637   else if (token_before_that == WORD && two_tokens_ago == FOR)
5638     {
5639       /* Tricky.  `for i\nin ...' should not have a semicolon, but
5640 	 `for i\ndo ...' should.  We do what we can. */
5641       for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
5642 	;
5643       if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
5644 	return " ";
5645       return ";";
5646     }
5647   else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
5648     return " ";
5649 
5650   for (i = 0; no_semi_successors[i]; i++)
5651     {
5652       if (token_before_that == no_semi_successors[i])
5653 	return (" ");
5654     }
5655 
5656   if (line_isblank (line))
5657     return ("");
5658 
5659   return ("; ");
5660 }
5661 #endif /* HISTORY */
5662 
5663 /* Issue a prompt, or prepare to issue a prompt when the next character
5664    is read. */
5665 static void
prompt_again()5666 prompt_again ()
5667 {
5668   char *temp_prompt;
5669 
5670   if (interactive == 0 || expanding_alias ())	/* XXX */
5671     return;
5672 
5673   ps1_prompt = get_string_value ("PS1");
5674   ps2_prompt = get_string_value ("PS2");
5675 
5676   ps0_prompt = get_string_value ("PS0");
5677 
5678   if (!prompt_string_pointer)
5679     prompt_string_pointer = &ps1_prompt;
5680 
5681   temp_prompt = *prompt_string_pointer
5682 			? decode_prompt_string (*prompt_string_pointer)
5683 			: (char *)NULL;
5684 
5685   if (temp_prompt == 0)
5686     {
5687       temp_prompt = (char *)xmalloc (1);
5688       temp_prompt[0] = '\0';
5689     }
5690 
5691   current_prompt_string = *prompt_string_pointer;
5692   prompt_string_pointer = &ps2_prompt;
5693 
5694 #if defined (READLINE)
5695   if (!no_line_editing)
5696     {
5697       FREE (current_readline_prompt);
5698       current_readline_prompt = temp_prompt;
5699     }
5700   else
5701 #endif	/* READLINE */
5702     {
5703       FREE (current_decoded_prompt);
5704       current_decoded_prompt = temp_prompt;
5705     }
5706 }
5707 
5708 int
get_current_prompt_level()5709 get_current_prompt_level ()
5710 {
5711   return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
5712 }
5713 
5714 void
set_current_prompt_level(x)5715 set_current_prompt_level (x)
5716      int x;
5717 {
5718   prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
5719   current_prompt_string = *prompt_string_pointer;
5720 }
5721 
5722 static void
print_prompt()5723 print_prompt ()
5724 {
5725   fprintf (stderr, "%s", current_decoded_prompt);
5726   fflush (stderr);
5727 }
5728 
5729 #if defined (HISTORY)
5730   /* The history library increments the history offset as soon as it stores
5731      the first line of a potentially multi-line command, so we compensate
5732      here by returning one fewer when appropriate. */
5733 static int
prompt_history_number(pmt)5734 prompt_history_number (pmt)
5735      char *pmt;
5736 {
5737   int ret;
5738 
5739   ret = history_number ();
5740   if (ret == 1)
5741     return ret;
5742 
5743   if (pmt == ps1_prompt)	/* are we expanding $PS1? */
5744     return ret;
5745   else if (pmt == ps2_prompt && command_oriented_history == 0)
5746     return ret;			/* not command oriented history */
5747   else if (pmt == ps2_prompt && command_oriented_history && current_command_first_line_saved)
5748     return ret - 1;
5749   else
5750     return ret - 1;		/* PS0, PS4, ${var@P}, PS2 other cases */
5751 }
5752 #endif
5753 
5754 /* Return a string which will be printed as a prompt.  The string
5755    may contain special characters which are decoded as follows:
5756 
5757 	\a	bell (ascii 07)
5758 	\d	the date in Day Mon Date format
5759 	\e	escape (ascii 033)
5760 	\h	the hostname up to the first `.'
5761 	\H	the hostname
5762 	\j	the number of active jobs
5763 	\l	the basename of the shell's tty device name
5764 	\n	CRLF
5765 	\r	CR
5766 	\s	the name of the shell
5767 	\t	the time in 24-hour hh:mm:ss format
5768 	\T	the time in 12-hour hh:mm:ss format
5769 	\@	the time in 12-hour hh:mm am/pm format
5770 	\A	the time in 24-hour hh:mm format
5771 	\D{fmt}	the result of passing FMT to strftime(3)
5772 	\u	your username
5773 	\v	the version of bash (e.g., 2.00)
5774 	\V	the release of bash, version + patchlevel (e.g., 2.00.0)
5775 	\w	the current working directory
5776 	\W	the last element of $PWD
5777 	\!	the history number of this command
5778 	\#	the command number of this command
5779 	\$	a $ or a # if you are root
5780 	\nnn	character code nnn in octal
5781 	\\	a backslash
5782 	\[	begin a sequence of non-printing chars
5783 	\]	end a sequence of non-printing chars
5784 */
5785 #define PROMPT_GROWTH 48
5786 char *
decode_prompt_string(string)5787 decode_prompt_string (string)
5788      char *string;
5789 {
5790   WORD_LIST *list;
5791   char *result, *t, *orig_string;
5792   struct dstack save_dstack;
5793   int last_exit_value, last_comsub_pid;
5794 #if defined (PROMPT_STRING_DECODE)
5795   size_t result_size;
5796   int result_index;
5797   int c, n, i;
5798   char *temp, *t_host, octal_string[4];
5799   struct tm *tm;
5800   time_t the_time;
5801   char timebuf[128];
5802   char *timefmt;
5803 
5804   result = (char *)xmalloc (result_size = PROMPT_GROWTH);
5805   result[result_index = 0] = 0;
5806   temp = (char *)NULL;
5807   orig_string = string;
5808 
5809   while (c = *string++)
5810     {
5811       if (posixly_correct && c == '!')
5812 	{
5813 	  if (*string == '!')
5814 	    {
5815 	      temp = savestring ("!");
5816 	      goto add_string;
5817 	    }
5818 	  else
5819 	    {
5820 #if !defined (HISTORY)
5821 		temp = savestring ("1");
5822 #else /* HISTORY */
5823 		temp = itos (prompt_history_number (orig_string));
5824 #endif /* HISTORY */
5825 		string--;	/* add_string increments string again. */
5826 		goto add_string;
5827 	    }
5828 	}
5829       if (c == '\\')
5830 	{
5831 	  c = *string;
5832 
5833 	  switch (c)
5834 	    {
5835 	    case '0':
5836 	    case '1':
5837 	    case '2':
5838 	    case '3':
5839 	    case '4':
5840 	    case '5':
5841 	    case '6':
5842 	    case '7':
5843 	      strncpy (octal_string, string, 3);
5844 	      octal_string[3] = '\0';
5845 
5846 	      n = read_octal (octal_string);
5847 	      temp = (char *)xmalloc (3);
5848 
5849 	      if (n == CTLESC || n == CTLNUL)
5850 		{
5851 		  temp[0] = CTLESC;
5852 		  temp[1] = n;
5853 		  temp[2] = '\0';
5854 		}
5855 	      else if (n == -1)
5856 		{
5857 		  temp[0] = '\\';
5858 		  temp[1] = '\0';
5859 		}
5860 	      else
5861 		{
5862 		  temp[0] = n;
5863 		  temp[1] = '\0';
5864 		}
5865 
5866 	      for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
5867 		string++;
5868 
5869 	      c = 0;		/* tested at add_string: */
5870 	      goto add_string;
5871 
5872 	    case 'd':
5873 	    case 't':
5874 	    case 'T':
5875 	    case '@':
5876 	    case 'A':
5877 	      /* Make the current time/date into a string. */
5878 	      (void) time (&the_time);
5879 #if defined (HAVE_TZSET)
5880 	      sv_tz ("TZ");		/* XXX -- just make sure */
5881 #endif
5882 	      tm = localtime (&the_time);
5883 
5884 	      if (c == 'd')
5885 		n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
5886 	      else if (c == 't')
5887 		n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
5888 	      else if (c == 'T')
5889 		n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
5890 	      else if (c == '@')
5891 		n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
5892 	      else if (c == 'A')
5893 		n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
5894 
5895 	      if (n == 0)
5896 		timebuf[0] = '\0';
5897 	      else
5898 		timebuf[sizeof(timebuf) - 1] = '\0';
5899 
5900 	      temp = savestring (timebuf);
5901 	      goto add_string;
5902 
5903 	    case 'D':		/* strftime format */
5904 	      if (string[1] != '{')		/* } */
5905 		goto not_escape;
5906 
5907 	      (void) time (&the_time);
5908 	      tm = localtime (&the_time);
5909 	      string += 2;			/* skip { */
5910 	      timefmt = xmalloc (strlen (string) + 3);
5911 	      for (t = timefmt; *string && *string != '}'; )
5912 		*t++ = *string++;
5913 	      *t = '\0';
5914 	      c = *string;	/* tested at add_string */
5915 	      if (timefmt[0] == '\0')
5916 		{
5917 		  timefmt[0] = '%';
5918 		  timefmt[1] = 'X';	/* locale-specific current time */
5919 		  timefmt[2] = '\0';
5920 		}
5921 	      n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
5922 	      free (timefmt);
5923 
5924 	      if (n == 0)
5925 		timebuf[0] = '\0';
5926 	      else
5927 		timebuf[sizeof(timebuf) - 1] = '\0';
5928 
5929 	      if (promptvars || posixly_correct)
5930 		/* Make sure that expand_prompt_string is called with a
5931 		   second argument of Q_DOUBLE_QUOTES if we use this
5932 		   function here. */
5933 		temp = sh_backslash_quote_for_double_quotes (timebuf);
5934 	      else
5935 		temp = savestring (timebuf);
5936 	      goto add_string;
5937 
5938 	    case 'n':
5939 	      temp = (char *)xmalloc (3);
5940 	      temp[0] = no_line_editing ? '\n' : '\r';
5941 	      temp[1] = no_line_editing ? '\0' : '\n';
5942 	      temp[2] = '\0';
5943 	      goto add_string;
5944 
5945 	    case 's':
5946 	      temp = base_pathname (shell_name);
5947 	      /* Try to quote anything the user can set in the file system */
5948 	      if (promptvars || posixly_correct)
5949 		temp = sh_backslash_quote_for_double_quotes (temp);
5950 	      else
5951 		temp = savestring (temp);
5952 	      goto add_string;
5953 
5954 	    case 'v':
5955 	    case 'V':
5956 	      temp = (char *)xmalloc (16);
5957 	      if (c == 'v')
5958 		strcpy (temp, dist_version);
5959 	      else
5960 		sprintf (temp, "%s.%d", dist_version, patch_level);
5961 	      goto add_string;
5962 
5963 	    case 'w':
5964 	    case 'W':
5965 	      {
5966 		/* Use the value of PWD because it is much more efficient. */
5967 		char t_string[PATH_MAX];
5968 		int tlen;
5969 
5970 		temp = get_string_value ("PWD");
5971 
5972 		if (temp == 0)
5973 		  {
5974 		    if (getcwd (t_string, sizeof(t_string)) == 0)
5975 		      {
5976 			t_string[0] = '.';
5977 			tlen = 1;
5978 		      }
5979 		    else
5980 		      tlen = strlen (t_string);
5981 		  }
5982 		else
5983 		  {
5984 		    tlen = sizeof (t_string) - 1;
5985 		    strncpy (t_string, temp, tlen);
5986 		  }
5987 		t_string[tlen] = '\0';
5988 
5989 #if defined (MACOSX)
5990 		/* Convert from "fs" format to "input" format */
5991 		temp = fnx_fromfs (t_string, strlen (t_string));
5992 		if (temp != t_string)
5993 		  strcpy (t_string, temp);
5994 #endif
5995 
5996 #define ROOT_PATH(x)	((x)[0] == '/' && (x)[1] == 0)
5997 #define DOUBLE_SLASH_ROOT(x)	((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
5998 		/* Abbreviate \W as ~ if $PWD == $HOME */
5999 		if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
6000 		  {
6001 		    if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
6002 		      {
6003 			t = strrchr (t_string, '/');
6004 			if (t)
6005 			  memmove (t_string, t + 1, strlen (t));	/* strlen(t) to copy NULL */
6006 		      }
6007 		  }
6008 #undef ROOT_PATH
6009 #undef DOUBLE_SLASH_ROOT
6010 		else
6011 		  {
6012 		    /* polite_directory_format is guaranteed to return a string
6013 		       no longer than PATH_MAX - 1 characters. */
6014 		    temp = polite_directory_format (t_string);
6015 		    if (temp != t_string)
6016 		      strcpy (t_string, temp);
6017 		  }
6018 
6019 		temp = trim_pathname (t_string, PATH_MAX - 1);
6020 		/* If we're going to be expanding the prompt string later,
6021 		   quote the directory name. */
6022 		if (promptvars || posixly_correct)
6023 		  /* Make sure that expand_prompt_string is called with a
6024 		     second argument of Q_DOUBLE_QUOTES if we use this
6025 		     function here. */
6026 		  temp = sh_backslash_quote_for_double_quotes (t_string);
6027 		else
6028 		  temp = savestring (t_string);
6029 
6030 		goto add_string;
6031 	      }
6032 
6033 	    case 'u':
6034 	      if (current_user.user_name == 0)
6035 		get_current_user_info ();
6036 	      temp = savestring (current_user.user_name);
6037 	      goto add_string;
6038 
6039 	    case 'h':
6040 	    case 'H':
6041 	      t_host = savestring (current_host_name);
6042 	      if (c == 'h' && (t = (char *)strchr (t_host, '.')))
6043 		*t = '\0';
6044 	      if (promptvars || posixly_correct)
6045 		/* Make sure that expand_prompt_string is called with a
6046 		   second argument of Q_DOUBLE_QUOTES if we use this
6047 		   function here. */
6048 		temp = sh_backslash_quote_for_double_quotes (t_host);
6049 	      else
6050 		temp = savestring (t_host);
6051 	      free (t_host);
6052 	      goto add_string;
6053 
6054 	    case '#':
6055 	      n = current_command_number;
6056 	      /* If we have already incremented current_command_number (PS4,
6057 		 ${var@P}), compensate */
6058 	      if (orig_string != ps0_prompt && orig_string != ps1_prompt && orig_string != ps2_prompt)
6059 		n--;
6060 	      temp = itos (n);
6061 	      goto add_string;
6062 
6063 	    case '!':
6064 #if !defined (HISTORY)
6065 	      temp = savestring ("1");
6066 #else /* HISTORY */
6067 	      temp = itos (prompt_history_number (orig_string));
6068 #endif /* HISTORY */
6069 	      goto add_string;
6070 
6071 	    case '$':
6072 	      t = temp = (char *)xmalloc (3);
6073 	      if ((promptvars || posixly_correct) && (current_user.euid != 0))
6074 		*t++ = '\\';
6075 	      *t++ = current_user.euid == 0 ? '#' : '$';
6076 	      *t = '\0';
6077 	      goto add_string;
6078 
6079 	    case 'j':
6080 	      temp = itos (count_all_jobs ());
6081 	      goto add_string;
6082 
6083 	    case 'l':
6084 #if defined (HAVE_TTYNAME)
6085 	      temp = (char *)ttyname (fileno (stdin));
6086 	      t = temp ? base_pathname (temp) : "tty";
6087 	      temp = savestring (t);
6088 #else
6089 	      temp = savestring ("tty");
6090 #endif /* !HAVE_TTYNAME */
6091 	      goto add_string;
6092 
6093 #if defined (READLINE)
6094 	    case '[':
6095 	    case ']':
6096 	      if (no_line_editing)
6097 		{
6098 		  string++;
6099 		  break;
6100 		}
6101 	      temp = (char *)xmalloc (3);
6102 	      n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
6103 	      i = 0;
6104 	      if (n == CTLESC || n == CTLNUL)
6105 		temp[i++] = CTLESC;
6106 	      temp[i++] = n;
6107 	      temp[i] = '\0';
6108 	      goto add_string;
6109 #endif /* READLINE */
6110 
6111 	    case '\\':
6112 	    case 'a':
6113 	    case 'e':
6114 	    case 'r':
6115 	      temp = (char *)xmalloc (2);
6116 	      if (c == 'a')
6117 		temp[0] = '\07';
6118 	      else if (c == 'e')
6119 		temp[0] = '\033';
6120 	      else if (c == 'r')
6121 		temp[0] = '\r';
6122 	      else			/* (c == '\\') */
6123 	        temp[0] = c;
6124 	      temp[1] = '\0';
6125 	      goto add_string;
6126 
6127 	    default:
6128 not_escape:
6129 	      temp = (char *)xmalloc (3);
6130 	      temp[0] = '\\';
6131 	      temp[1] = c;
6132 	      temp[2] = '\0';
6133 
6134 	    add_string:
6135 	      if (c)
6136 		string++;
6137 	      result =
6138 		sub_append_string (temp, result, &result_index, &result_size);
6139 	      temp = (char *)NULL; /* Freed in sub_append_string (). */
6140 	      result[result_index] = '\0';
6141 	      break;
6142 	    }
6143 	}
6144       else
6145 	{
6146 	  RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
6147 	  /* dequote_string should take care of removing this if we are not
6148 	     performing the rest of the word expansions. */
6149 	  if (c == CTLESC || c == CTLNUL)
6150 	    result[result_index++] = CTLESC;
6151 	  result[result_index++] = c;
6152 	  result[result_index] = '\0';
6153 	}
6154     }
6155 #else /* !PROMPT_STRING_DECODE */
6156   result = savestring (string);
6157 #endif /* !PROMPT_STRING_DECODE */
6158 
6159   /* Save the delimiter stack and point `dstack' to temp space so any
6160      command substitutions in the prompt string won't result in screwing
6161      up the parser's quoting state. */
6162   save_dstack = dstack;
6163   dstack = temp_dstack;
6164   dstack.delimiter_depth = 0;
6165 
6166   /* Perform variable and parameter expansion and command substitution on
6167      the prompt string. */
6168   if (promptvars || posixly_correct)
6169     {
6170       last_exit_value = last_command_exit_value;
6171       last_comsub_pid = last_command_subst_pid;
6172       list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
6173       free (result);
6174       result = string_list (list);
6175       dispose_words (list);
6176       last_command_exit_value = last_exit_value;
6177       last_command_subst_pid = last_comsub_pid;
6178     }
6179   else
6180     {
6181       t = dequote_string (result);
6182       free (result);
6183       result = t;
6184     }
6185 
6186   dstack = save_dstack;
6187 
6188   return (result);
6189 }
6190 
6191 /************************************************
6192  *						*
6193  *		ERROR HANDLING			*
6194  *						*
6195  ************************************************/
6196 
6197 /* Report a syntax error, and restart the parser.  Call here for fatal
6198    errors. */
6199 int
yyerror(msg)6200 yyerror (msg)
6201      const char *msg;
6202 {
6203   report_syntax_error ((char *)NULL);
6204   reset_parser ();
6205   return (0);
6206 }
6207 
6208 static char *
error_token_from_token(tok)6209 error_token_from_token (tok)
6210      int tok;
6211 {
6212   char *t;
6213 
6214   if (t = find_token_in_alist (tok, word_token_alist, 0))
6215     return t;
6216 
6217   if (t = find_token_in_alist (tok, other_token_alist, 0))
6218     return t;
6219 
6220   t = (char *)NULL;
6221   /* This stuff is dicy and needs closer inspection */
6222   switch (current_token)
6223     {
6224     case WORD:
6225     case ASSIGNMENT_WORD:
6226       if (yylval.word)
6227 	t = savestring (yylval.word->word);
6228       break;
6229     case NUMBER:
6230       t = itos (yylval.number);
6231       break;
6232     case ARITH_CMD:
6233       if (yylval.word_list)
6234         t = string_list (yylval.word_list);
6235       break;
6236     case ARITH_FOR_EXPRS:
6237       if (yylval.word_list)
6238 	t = string_list_internal (yylval.word_list, " ; ");
6239       break;
6240     case COND_CMD:
6241       t = (char *)NULL;		/* punt */
6242       break;
6243     }
6244 
6245   return t;
6246 }
6247 
6248 static char *
error_token_from_text()6249 error_token_from_text ()
6250 {
6251   char *msg, *t;
6252   int token_end, i;
6253 
6254   t = shell_input_line;
6255   i = shell_input_line_index;
6256   token_end = 0;
6257   msg = (char *)NULL;
6258 
6259   if (i && t[i] == '\0')
6260     i--;
6261 
6262   while (i && (whitespace (t[i]) || t[i] == '\n'))
6263     i--;
6264 
6265   if (i)
6266     token_end = i + 1;
6267 
6268   while (i && (member (t[i], " \n\t;|&") == 0))
6269     i--;
6270 
6271   while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
6272     i++;
6273 
6274   /* Return our idea of the offending token. */
6275   if (token_end || (i == 0 && token_end == 0))
6276     {
6277       if (token_end)
6278 	msg = substring (t, i, token_end);
6279       else	/* one-character token */
6280 	{
6281 	  msg = (char *)xmalloc (2);
6282 	  msg[0] = t[i];
6283 	  msg[1] = '\0';
6284 	}
6285     }
6286 
6287   return (msg);
6288 }
6289 
6290 static void
print_offending_line()6291 print_offending_line ()
6292 {
6293   char *msg;
6294   int token_end;
6295 
6296   msg = savestring (shell_input_line);
6297   token_end = strlen (msg);
6298   while (token_end && msg[token_end - 1] == '\n')
6299     msg[--token_end] = '\0';
6300 
6301   parser_error (line_number, "`%s'", msg);
6302   free (msg);
6303 }
6304 
6305 /* Report a syntax error with line numbers, etc.
6306    Call here for recoverable errors.  If you have a message to print,
6307    then place it in MESSAGE, otherwise pass NULL and this will figure
6308    out an appropriate message for you. */
6309 static void
report_syntax_error(message)6310 report_syntax_error (message)
6311      char *message;
6312 {
6313   char *msg, *p;
6314 
6315   if (message)
6316     {
6317       parser_error (line_number, "%s", message);
6318       if (interactive && EOF_Reached)
6319 	EOF_Reached = 0;
6320       last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE;
6321       set_pipestatus_from_exit (last_command_exit_value);
6322       return;
6323     }
6324 
6325   /* If the line of input we're reading is not null, try to find the
6326      objectionable token.  First, try to figure out what token the
6327      parser's complaining about by looking at current_token. */
6328   if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
6329     {
6330       if (ansic_shouldquote (msg))
6331 	{
6332 	  p = ansic_quote (msg, 0, NULL);
6333 	  free (msg);
6334 	  msg = p;
6335 	}
6336       parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
6337       free (msg);
6338 
6339       if (interactive == 0)
6340 	print_offending_line ();
6341 
6342       last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE;
6343       set_pipestatus_from_exit (last_command_exit_value);
6344       return;
6345     }
6346 
6347   /* If looking at the current token doesn't prove fruitful, try to find the
6348      offending token by analyzing the text of the input line near the current
6349      input line index and report what we find. */
6350   if (shell_input_line && *shell_input_line)
6351     {
6352       msg = error_token_from_text ();
6353       if (msg)
6354 	{
6355 	  parser_error (line_number, _("syntax error near `%s'"), msg);
6356 	  free (msg);
6357 	}
6358 
6359       /* If not interactive, print the line containing the error. */
6360       if (interactive == 0)
6361         print_offending_line ();
6362     }
6363   else
6364     {
6365       msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
6366       parser_error (line_number, "%s", msg);
6367       /* When the shell is interactive, this file uses EOF_Reached
6368 	 only for error reporting.  Other mechanisms are used to
6369 	 decide whether or not to exit. */
6370       if (interactive && EOF_Reached)
6371 	EOF_Reached = 0;
6372     }
6373 
6374   last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE;
6375   set_pipestatus_from_exit (last_command_exit_value);
6376 }
6377 
6378 /* ??? Needed function. ??? We have to be able to discard the constructs
6379    created during parsing.  In the case of error, we want to return
6380    allocated objects to the memory pool.  In the case of no error, we want
6381    to throw away the information about where the allocated objects live.
6382    (dispose_command () will actually free the command.) */
6383 static void
discard_parser_constructs(error_p)6384 discard_parser_constructs (error_p)
6385      int error_p;
6386 {
6387 }
6388 
6389 /************************************************
6390  *						*
6391  *		EOF HANDLING			*
6392  *						*
6393  ************************************************/
6394 
6395 /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
6396 
6397 /* A flag denoting whether or not ignoreeof is set. */
6398 int ignoreeof = 0;
6399 
6400 /* The number of times that we have encountered an EOF character without
6401    another character intervening.  When this gets above the limit, the
6402    shell terminates. */
6403 int eof_encountered = 0;
6404 
6405 /* The limit for eof_encountered. */
6406 int eof_encountered_limit = 10;
6407 
6408 /* If we have EOF as the only input unit, this user wants to leave
6409    the shell.  If the shell is not interactive, then just leave.
6410    Otherwise, if ignoreeof is set, and we haven't done this the
6411    required number of times in a row, print a message. */
6412 static void
handle_eof_input_unit()6413 handle_eof_input_unit ()
6414 {
6415   if (interactive)
6416     {
6417       /* shell.c may use this to decide whether or not to write out the
6418 	 history, among other things.  We use it only for error reporting
6419 	 in this file. */
6420       if (EOF_Reached)
6421 	EOF_Reached = 0;
6422 
6423       /* If the user wants to "ignore" eof, then let her do so, kind of. */
6424       if (ignoreeof)
6425 	{
6426 	  if (eof_encountered < eof_encountered_limit)
6427 	    {
6428 	      fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
6429 		       login_shell ? "logout" : "exit");
6430 	      eof_encountered++;
6431 	      /* Reset the parsing state. */
6432 	      last_read_token = current_token = '\n';
6433 	      /* Reset the prompt string to be $PS1. */
6434 	      prompt_string_pointer = (char **)NULL;
6435 	      prompt_again ();
6436 	      return;
6437 	    }
6438 	}
6439 
6440       /* In this case EOF should exit the shell.  Do it now. */
6441       reset_parser ();
6442 
6443       last_shell_builtin = this_shell_builtin;
6444       this_shell_builtin = exit_builtin;
6445       exit_builtin ((WORD_LIST *)NULL);
6446     }
6447   else
6448     {
6449       /* We don't write history files, etc., for non-interactive shells. */
6450       EOF_Reached = 1;
6451     }
6452 }
6453 
6454 /************************************************
6455  *						*
6456  *	STRING PARSING FUNCTIONS		*
6457  *						*
6458  ************************************************/
6459 
6460 /* It's very important that these two functions treat the characters
6461    between ( and ) identically. */
6462 
6463 static WORD_LIST parse_string_error;
6464 
6465 /* Take a string and run it through the shell parser, returning the
6466    resultant word list.  Used by compound array assignment. */
6467 WORD_LIST *
parse_string_to_word_list(s,flags,whom)6468 parse_string_to_word_list (s, flags, whom)
6469      char *s;
6470      int flags;
6471      const char *whom;
6472 {
6473   WORD_LIST *wl;
6474   int tok, orig_current_token, orig_line_number, orig_input_terminator;
6475   int orig_line_count;
6476   int old_echo_input, old_expand_aliases, ea;
6477 #if defined (HISTORY)
6478   int old_remember_on_history, old_history_expansion_inhibited;
6479 #endif
6480 
6481 #if defined (HISTORY)
6482   old_remember_on_history = remember_on_history;
6483 #  if defined (BANG_HISTORY)
6484   old_history_expansion_inhibited = history_expansion_inhibited;
6485 #  endif
6486   bash_history_disable ();
6487 #endif
6488 
6489   orig_line_number = line_number;
6490   orig_line_count = current_command_line_count;
6491   orig_input_terminator = shell_input_line_terminator;
6492   old_echo_input = echo_input_at_read;
6493   old_expand_aliases = expand_aliases;
6494 
6495   push_stream (1);
6496   if (ea = expanding_alias ())
6497     parser_save_alias ();
6498   last_read_token = WORD;		/* WORD to allow reserved words here */
6499   current_command_line_count = 0;
6500   echo_input_at_read = expand_aliases = 0;
6501 
6502   with_input_from_string (s, whom);
6503   wl = (WORD_LIST *)NULL;
6504 
6505   if (flags & 1)
6506     parser_state |= PST_COMPASSIGN|PST_REPARSE;
6507 
6508   while ((tok = read_token (READ)) != yacc_EOF)
6509     {
6510       if (tok == '\n' && *bash_input.location.string == '\0')
6511 	break;
6512       if (tok == '\n')		/* Allow newlines in compound assignments */
6513 	continue;
6514       if (tok != WORD && tok != ASSIGNMENT_WORD)
6515 	{
6516 	  line_number = orig_line_number + line_number - 1;
6517 	  orig_current_token = current_token;
6518 	  current_token = tok;
6519 	  yyerror (NULL);	/* does the right thing */
6520 	  current_token = orig_current_token;
6521 	  if (wl)
6522 	    dispose_words (wl);
6523 	  wl = &parse_string_error;
6524 	  break;
6525 	}
6526       wl = make_word_list (yylval.word, wl);
6527     }
6528 
6529   last_read_token = '\n';
6530   pop_stream ();
6531 
6532   if (ea)
6533     parser_restore_alias ();
6534 
6535 #if defined (HISTORY)
6536   remember_on_history = old_remember_on_history;
6537 #  if defined (BANG_HISTORY)
6538   history_expansion_inhibited = old_history_expansion_inhibited;
6539 #  endif /* BANG_HISTORY */
6540 #endif /* HISTORY */
6541 
6542   echo_input_at_read = old_echo_input;
6543   expand_aliases = old_expand_aliases;
6544 
6545   current_command_line_count = orig_line_count;
6546   shell_input_line_terminator = orig_input_terminator;
6547 
6548   if (flags & 1)
6549     parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
6550 
6551   if (wl == &parse_string_error)
6552     {
6553       set_exit_status (EXECUTION_FAILURE);
6554       if (interactive_shell == 0 && posixly_correct)
6555 	jump_to_top_level (FORCE_EOF);
6556       else
6557 	jump_to_top_level (DISCARD);
6558     }
6559 
6560   return (REVERSE_LIST (wl, WORD_LIST *));
6561 }
6562 
6563 static char *
parse_compound_assignment(retlenp)6564 parse_compound_assignment (retlenp)
6565      int *retlenp;
6566 {
6567   WORD_LIST *wl, *rl;
6568   int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
6569   char *saved_token, *ret;
6570 
6571   saved_token = token;
6572   orig_token_size = token_buffer_size;
6573   orig_line_number = line_number;
6574   orig_last_token = last_read_token;
6575 
6576   last_read_token = WORD;	/* WORD to allow reserved words here */
6577 
6578   token = (char *)NULL;
6579   token_buffer_size = 0;
6580 
6581   assignok = parser_state&PST_ASSIGNOK;		/* XXX */
6582 
6583   wl = (WORD_LIST *)NULL;	/* ( */
6584   parser_state |= PST_COMPASSIGN;
6585 
6586   while ((tok = read_token (READ)) != ')')
6587     {
6588       if (tok == '\n')			/* Allow newlines in compound assignments */
6589 	{
6590 	  if (SHOULD_PROMPT ())
6591 	    prompt_again ();
6592 	  continue;
6593 	}
6594       if (tok != WORD && tok != ASSIGNMENT_WORD)
6595 	{
6596 	  current_token = tok;	/* for error reporting */
6597 	  if (tok == yacc_EOF)	/* ( */
6598 	    parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
6599 	  else
6600 	    yyerror(NULL);	/* does the right thing */
6601 	  if (wl)
6602 	    dispose_words (wl);
6603 	  wl = &parse_string_error;
6604 	  break;
6605 	}
6606       wl = make_word_list (yylval.word, wl);
6607     }
6608 
6609   FREE (token);
6610   token = saved_token;
6611   token_buffer_size = orig_token_size;
6612 
6613   parser_state &= ~PST_COMPASSIGN;
6614 
6615   if (wl == &parse_string_error)
6616     {
6617       set_exit_status (EXECUTION_FAILURE);
6618       last_read_token = '\n';	/* XXX */
6619       if (interactive_shell == 0 && posixly_correct)
6620 	jump_to_top_level (FORCE_EOF);
6621       else
6622 	jump_to_top_level (DISCARD);
6623     }
6624 
6625   last_read_token = orig_last_token;		/* XXX - was WORD? */
6626 
6627   if (wl)
6628     {
6629       rl = REVERSE_LIST (wl, WORD_LIST *);
6630       ret = string_list (rl);
6631       dispose_words (rl);
6632     }
6633   else
6634     ret = (char *)NULL;
6635 
6636   if (retlenp)
6637     *retlenp = (ret && *ret) ? strlen (ret) : 0;
6638 
6639   if (assignok)
6640     parser_state |= PST_ASSIGNOK;
6641 
6642   return ret;
6643 }
6644 
6645 /************************************************
6646  *						*
6647  *   SAVING AND RESTORING PARTIAL PARSE STATE   *
6648  *						*
6649  ************************************************/
6650 
6651 sh_parser_state_t *
save_parser_state(ps)6652 save_parser_state (ps)
6653      sh_parser_state_t *ps;
6654 {
6655   if (ps == 0)
6656     ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
6657   if (ps == 0)
6658     return ((sh_parser_state_t *)NULL);
6659 
6660   ps->parser_state = parser_state;
6661   ps->token_state = save_token_state ();
6662 
6663   ps->input_line_terminator = shell_input_line_terminator;
6664   ps->eof_encountered = eof_encountered;
6665 
6666   ps->prompt_string_pointer = prompt_string_pointer;
6667 
6668   ps->current_command_line_count = current_command_line_count;
6669 
6670 #if defined (HISTORY)
6671   ps->remember_on_history = remember_on_history;
6672 #  if defined (BANG_HISTORY)
6673   ps->history_expansion_inhibited = history_expansion_inhibited;
6674 #  endif
6675 #endif
6676 
6677   ps->last_command_exit_value = last_command_exit_value;
6678 #if defined (ARRAY_VARS)
6679   ps->pipestatus = save_pipestatus_array ();
6680 #endif
6681 
6682   ps->last_shell_builtin = last_shell_builtin;
6683   ps->this_shell_builtin = this_shell_builtin;
6684 
6685   ps->expand_aliases = expand_aliases;
6686   ps->echo_input_at_read = echo_input_at_read;
6687   ps->need_here_doc = need_here_doc;
6688   ps->here_doc_first_line = here_doc_first_line;
6689 
6690   if (need_here_doc == 0)
6691     ps->redir_stack[0] = 0;
6692   else
6693     memcpy (ps->redir_stack, redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
6694 
6695   ps->token = token;
6696   ps->token_buffer_size = token_buffer_size;
6697   /* Force reallocation on next call to read_token_word */
6698   token = 0;
6699   token_buffer_size = 0;
6700 
6701   return (ps);
6702 }
6703 
6704 void
restore_parser_state(ps)6705 restore_parser_state (ps)
6706      sh_parser_state_t *ps;
6707 {
6708   int i;
6709 
6710   if (ps == 0)
6711     return;
6712 
6713   parser_state = ps->parser_state;
6714   if (ps->token_state)
6715     {
6716       restore_token_state (ps->token_state);
6717       free (ps->token_state);
6718     }
6719 
6720   shell_input_line_terminator = ps->input_line_terminator;
6721   eof_encountered = ps->eof_encountered;
6722 
6723   prompt_string_pointer = ps->prompt_string_pointer;
6724 
6725   current_command_line_count = ps->current_command_line_count;
6726 
6727 #if defined (HISTORY)
6728   remember_on_history = ps->remember_on_history;
6729 #  if defined (BANG_HISTORY)
6730   history_expansion_inhibited = ps->history_expansion_inhibited;
6731 #  endif
6732 #endif
6733 
6734   last_command_exit_value = ps->last_command_exit_value;
6735 #if defined (ARRAY_VARS)
6736   restore_pipestatus_array (ps->pipestatus);
6737 #endif
6738 
6739   last_shell_builtin = ps->last_shell_builtin;
6740   this_shell_builtin = ps->this_shell_builtin;
6741 
6742   expand_aliases = ps->expand_aliases;
6743   echo_input_at_read = ps->echo_input_at_read;
6744   need_here_doc = ps->need_here_doc;
6745   here_doc_first_line = ps->here_doc_first_line;
6746 
6747 #if 0
6748   for (i = 0; i < HEREDOC_MAX; i++)
6749     redir_stack[i] = ps->redir_stack[i];
6750 #else
6751   if (need_here_doc == 0)
6752     redir_stack[0] = 0;
6753   else
6754     memcpy (redir_stack, ps->redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
6755 #endif
6756 
6757   FREE (token);
6758   token = ps->token;
6759   token_buffer_size = ps->token_buffer_size;
6760 }
6761 
6762 sh_input_line_state_t *
save_input_line_state(ls)6763 save_input_line_state (ls)
6764      sh_input_line_state_t *ls;
6765 {
6766   if (ls == 0)
6767     ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
6768   if (ls == 0)
6769     return ((sh_input_line_state_t *)NULL);
6770 
6771   ls->input_line = shell_input_line;
6772   ls->input_line_size = shell_input_line_size;
6773   ls->input_line_len = shell_input_line_len;
6774   ls->input_line_index = shell_input_line_index;
6775 
6776 #if defined (HANDLE_MULTIBYTE)
6777   ls->input_property = shell_input_line_property;
6778   ls->input_propsize = shell_input_line_propsize;
6779 #endif
6780 
6781   /* force reallocation */
6782   shell_input_line = 0;
6783   shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
6784 
6785 #if defined (HANDLE_MULTIBYTE)
6786   shell_input_line_property = 0;
6787   shell_input_line_propsize = 0;
6788 #endif
6789 
6790   return ls;
6791 }
6792 
6793 void
restore_input_line_state(ls)6794 restore_input_line_state (ls)
6795      sh_input_line_state_t *ls;
6796 {
6797   FREE (shell_input_line);
6798   shell_input_line = ls->input_line;
6799   shell_input_line_size = ls->input_line_size;
6800   shell_input_line_len = ls->input_line_len;
6801   shell_input_line_index = ls->input_line_index;
6802 
6803 #if defined (HANDLE_MULTIBYTE)
6804   FREE (shell_input_line_property);
6805   shell_input_line_property = ls->input_property;
6806   shell_input_line_propsize = ls->input_propsize;
6807 #endif
6808 
6809 #if 0
6810   set_line_mbstate ();
6811 #endif
6812 }
6813 
6814 /************************************************
6815  *						*
6816  *	MULTIBYTE CHARACTER HANDLING		*
6817  *						*
6818  ************************************************/
6819 
6820 #if defined (HANDLE_MULTIBYTE)
6821 
6822 /* We don't let the property buffer get larger than this unless the line is */
6823 #define MAX_PROPSIZE 32768
6824 
6825 static void
set_line_mbstate()6826 set_line_mbstate ()
6827 {
6828   int c;
6829   size_t i, previ, len;
6830   mbstate_t mbs, prevs;
6831   size_t mbclen;
6832   int ilen;
6833 
6834   if (shell_input_line == NULL)
6835     return;
6836   len = STRLEN (shell_input_line);	/* XXX - shell_input_line_len ? */
6837   if (len == 0)
6838     return;
6839   if (shell_input_line_propsize >= MAX_PROPSIZE && len < MAX_PROPSIZE>>1)
6840     {
6841       free (shell_input_line_property);
6842       shell_input_line_property = 0;
6843       shell_input_line_propsize = 0;
6844     }
6845   if (len+1 > shell_input_line_propsize)
6846     {
6847       shell_input_line_propsize = len + 1;
6848       shell_input_line_property = (char *)xrealloc (shell_input_line_property, shell_input_line_propsize);
6849     }
6850 
6851   if (locale_mb_cur_max == 1)
6852     {
6853       memset (shell_input_line_property, 1, len);
6854       return;
6855     }
6856 
6857   /* XXX - use whether or not we are in a UTF-8 locale to avoid calls to
6858      mbrlen */
6859   if (locale_utf8locale == 0)
6860     memset (&prevs, '\0', sizeof (mbstate_t));
6861 
6862   for (i = previ = 0; i < len; i++)
6863     {
6864       if (locale_utf8locale == 0)
6865 	mbs = prevs;
6866 
6867       c = shell_input_line[i];
6868       if (c == EOF)
6869 	{
6870 	  size_t j;
6871 	  for (j = i; j < len; j++)
6872 	    shell_input_line_property[j] = 1;
6873 	  break;
6874 	}
6875 
6876       if (locale_utf8locale)
6877 	{
6878 	  if ((unsigned char)shell_input_line[previ] < 128)	/* i != previ */
6879 	    mbclen = 1;
6880 	  else
6881 	    {
6882 	      ilen = utf8_mblen (shell_input_line + previ, i - previ + 1);
6883 	      mbclen = (ilen == -1) ? (size_t)-1
6884 				    : ((ilen == -2) ? (size_t)-2 : (size_t)ilen);
6885 	    }
6886 	}
6887       else
6888 	mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
6889 
6890       if (mbclen == 1 || mbclen == (size_t)-1)
6891 	{
6892 	  mbclen = 1;
6893 	  previ = i + 1;
6894 	}
6895       else if (mbclen == (size_t)-2)
6896         mbclen = 0;
6897       else if (mbclen > 1)
6898 	{
6899 	  mbclen = 0;
6900 	  previ = i + 1;
6901 	  if (locale_utf8locale == 0)
6902 	    prevs = mbs;
6903 	}
6904       else
6905 	{
6906 	  size_t j;
6907 	  for (j = i; j < len; j++)
6908 	    shell_input_line_property[j] = 1;
6909 	  break;
6910 	}
6911 
6912       shell_input_line_property[i] = mbclen;
6913     }
6914 }
6915 #endif /* HANDLE_MULTIBYTE */
6916