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