]> git.ipfire.org Git - thirdparty/bash.git/blob - parse.y
Bash-5.2-rc2 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)
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 current_token = '\n'; /* XXX */
3332 last_read_token = '\n';
3333 token_to_read = '\n';
3334 }
3335
3336 void
3337 reset_readahead_token ()
3338 {
3339 if (token_to_read == '\n')
3340 token_to_read = 0;
3341 }
3342
3343 /* Read the next token. Command can be READ (normal operation) or
3344 RESET (to normalize state). */
3345 static int
3346 read_token (command)
3347 int command;
3348 {
3349 int character; /* Current character. */
3350 int peek_char; /* Temporary look-ahead character. */
3351 int result; /* The thing to return. */
3352
3353 if (command == RESET)
3354 {
3355 reset_parser ();
3356 return ('\n');
3357 }
3358
3359 if (token_to_read)
3360 {
3361 result = token_to_read;
3362 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3363 {
3364 yylval.word = word_desc_to_read;
3365 word_desc_to_read = (WORD_DESC *)NULL;
3366 }
3367 token_to_read = 0;
3368 return (result);
3369 }
3370
3371 #if defined (COND_COMMAND)
3372 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3373 {
3374 cond_lineno = line_number;
3375 parser_state |= PST_CONDEXPR;
3376 yylval.command = parse_cond_command ();
3377 if (cond_token != COND_END)
3378 {
3379 cond_error ();
3380 return (-1);
3381 }
3382 token_to_read = COND_END;
3383 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3384 return (COND_CMD);
3385 }
3386 #endif
3387
3388 #if defined (ALIAS)
3389 /* This is a place to jump back to once we have successfully expanded a
3390 token with an alias and pushed the string with push_string () */
3391 re_read_token:
3392 #endif /* ALIAS */
3393
3394 /* Read a single word from input. Start by skipping blanks. */
3395 while ((character = shell_getc (1)) != EOF && shellblank (character))
3396 ;
3397
3398 if (character == EOF)
3399 {
3400 EOF_Reached = 1;
3401 return (yacc_EOF);
3402 }
3403
3404 /* If we hit the end of the string and we're not expanding an alias (e.g.,
3405 we are eval'ing a string that is an incomplete command), return EOF */
3406 if (character == '\0' && bash_input.type == st_string && expanding_alias() == 0)
3407 {
3408 INTERNAL_DEBUG (("shell_getc: bash_input.location.string = `%s'", bash_input.location.string));
3409 EOF_Reached = 1;
3410 return (yacc_EOF);
3411 }
3412
3413 if MBTEST(character == '#' && (!interactive || interactive_comments))
3414 {
3415 /* A comment. Discard until EOL or EOF, and then return a newline. */
3416 parser_state |= PST_COMMENT;
3417 discard_until ('\n');
3418 shell_getc (0);
3419 parser_state &= ~PST_COMMENT;
3420 character = '\n'; /* this will take the next if statement and return. */
3421 }
3422
3423 if MBTEST(character == '\n')
3424 {
3425 /* If we're about to return an unquoted newline, we can go and collect
3426 the text of any pending here document. */
3427 if (need_here_doc)
3428 gather_here_documents ();
3429
3430 #if defined (ALIAS)
3431 parser_state &= ~PST_ALEXPNEXT;
3432 #endif /* ALIAS */
3433
3434 parser_state &= ~PST_ASSIGNOK;
3435
3436 return (character);
3437 }
3438
3439 if (parser_state & PST_REGEXP)
3440 goto tokword;
3441
3442 /* Shell meta-characters. */
3443 if MBTEST(shellmeta (character))
3444 {
3445 #if defined (ALIAS)
3446 /* Turn off alias tokenization iff this character sequence would
3447 not leave us ready to read a command. */
3448 if (character == '<' || character == '>')
3449 parser_state &= ~PST_ALEXPNEXT;
3450 #endif /* ALIAS */
3451
3452 parser_state &= ~PST_ASSIGNOK;
3453
3454 /* If we are parsing a command substitution and we have read a character
3455 that marks the end of it, don't bother to skip over quoted newlines
3456 when we read the next token. We're just interested in a character
3457 that will turn this into a two-character token, so we let the higher
3458 layers deal with quoted newlines following the command substitution. */
3459 if ((parser_state & PST_CMDSUBST) && character == shell_eof_token)
3460 peek_char = shell_getc (0);
3461 else
3462 peek_char = shell_getc (1);
3463
3464 if MBTEST(character == peek_char)
3465 {
3466 switch (character)
3467 {
3468 case '<':
3469 /* If '<' then we could be at "<<" or at "<<-". We have to
3470 look ahead one more character. */
3471 peek_char = shell_getc (1);
3472 if MBTEST(peek_char == '-')
3473 return (LESS_LESS_MINUS);
3474 else if MBTEST(peek_char == '<')
3475 return (LESS_LESS_LESS);
3476 else
3477 {
3478 shell_ungetc (peek_char);
3479 return (LESS_LESS);
3480 }
3481
3482 case '>':
3483 return (GREATER_GREATER);
3484
3485 case ';':
3486 parser_state |= PST_CASEPAT;
3487 #if defined (ALIAS)
3488 parser_state &= ~PST_ALEXPNEXT;
3489 #endif /* ALIAS */
3490
3491 peek_char = shell_getc (1);
3492 if MBTEST(peek_char == '&')
3493 return (SEMI_SEMI_AND);
3494 else
3495 {
3496 shell_ungetc (peek_char);
3497 return (SEMI_SEMI);
3498 }
3499
3500 case '&':
3501 return (AND_AND);
3502
3503 case '|':
3504 return (OR_OR);
3505
3506 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3507 case '(': /* ) */
3508 result = parse_dparen (character);
3509 if (result == -2)
3510 break;
3511 else
3512 return result;
3513 #endif
3514 }
3515 }
3516 else if MBTEST(character == '<' && peek_char == '&')
3517 return (LESS_AND);
3518 else if MBTEST(character == '>' && peek_char == '&')
3519 return (GREATER_AND);
3520 else if MBTEST(character == '<' && peek_char == '>')
3521 return (LESS_GREATER);
3522 else if MBTEST(character == '>' && peek_char == '|')
3523 return (GREATER_BAR);
3524 else if MBTEST(character == '&' && peek_char == '>')
3525 {
3526 peek_char = shell_getc (1);
3527 if MBTEST(peek_char == '>')
3528 return (AND_GREATER_GREATER);
3529 else
3530 {
3531 shell_ungetc (peek_char);
3532 return (AND_GREATER);
3533 }
3534 }
3535 else if MBTEST(character == '|' && peek_char == '&')
3536 return (BAR_AND);
3537 else if MBTEST(character == ';' && peek_char == '&')
3538 {
3539 parser_state |= PST_CASEPAT;
3540 #if defined (ALIAS)
3541 parser_state &= ~PST_ALEXPNEXT;
3542 #endif /* ALIAS */
3543 return (SEMI_AND);
3544 }
3545
3546 shell_ungetc (peek_char);
3547
3548 /* If we look like we are reading the start of a function
3549 definition, then let the reader know about it so that
3550 we will do the right thing with `{'. */
3551 if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
3552 {
3553 parser_state |= PST_ALLOWOPNBRC;
3554 #if defined (ALIAS)
3555 parser_state &= ~PST_ALEXPNEXT;
3556 #endif /* ALIAS */
3557 function_dstart = line_number;
3558 }
3559
3560 /* case pattern lists may be preceded by an optional left paren. If
3561 we're not trying to parse a case pattern list, the left paren
3562 indicates a subshell. */
3563 if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3564 parser_state |= PST_SUBSHELL;
3565 /*(*/
3566 else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
3567 parser_state &= ~PST_CASEPAT;
3568 /*(*/
3569 else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
3570 parser_state &= ~PST_SUBSHELL;
3571
3572 #if defined (PROCESS_SUBSTITUTION)
3573 /* Check for the constructs which introduce process substitution.
3574 Shells running in `posix mode' don't do process substitution. */
3575 if MBTEST((character != '>' && character != '<') || peek_char != '(') /*)*/
3576 #endif /* PROCESS_SUBSTITUTION */
3577 return (character);
3578 }
3579
3580 /* Hack <&- (close stdin) case. Also <&N- (dup and close). */
3581 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3582 return (character);
3583
3584 tokword:
3585 /* Okay, if we got this far, we have to read a word. Read one,
3586 and then check it against the known ones. */
3587 result = read_token_word (character);
3588 #if defined (ALIAS)
3589 if (result == RE_READ_TOKEN)
3590 goto re_read_token;
3591 #endif
3592 return result;
3593 }
3594
3595 /*
3596 * Match a $(...) or other grouping construct. This has to handle embedded
3597 * quoted strings ('', ``, "") and nested constructs. It also must handle
3598 * reprompting the user, if necessary, after reading a newline, and returning
3599 * correct error values if it reads EOF.
3600 */
3601 #define P_FIRSTCLOSE 0x0001
3602 #define P_ALLOWESC 0x0002
3603 #define P_DQUOTE 0x0004
3604 #define P_COMMAND 0x0008 /* parsing a command, so look for comments */
3605 #define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
3606 #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
3607 #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
3608
3609 /* Lexical state while parsing a grouping construct or $(...). */
3610 #define LEX_WASDOL 0x0001
3611 #define LEX_CKCOMMENT 0x0002
3612 #define LEX_INCOMMENT 0x0004
3613 #define LEX_PASSNEXT 0x0008
3614 #define LEX_RESWDOK 0x0010
3615 #define LEX_CKCASE 0x0020
3616 #define LEX_INCASE 0x0040
3617 #define LEX_INHEREDOC 0x0080
3618 #define LEX_HEREDELIM 0x0100 /* reading here-doc delimiter */
3619 #define LEX_STRIPDOC 0x0200 /* <<- strip tabs from here doc delim */
3620 #define LEX_QUOTEDDOC 0x0400 /* here doc with quoted delim */
3621 #define LEX_INWORD 0x0800
3622 #define LEX_GTLT 0x1000
3623 #define LEX_CKESAC 0x2000 /* check esac after in -- for later */
3624 #define LEX_CASEWD 0x4000 /* word after case */
3625 #define LEX_PATLIST 0x8000 /* case statement pattern list */
3626
3627 #define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
3628
3629 #define CHECK_NESTRET_ERROR() \
3630 do { \
3631 if (nestret == &matched_pair_error) \
3632 { \
3633 free (ret); \
3634 return &matched_pair_error; \
3635 } \
3636 } while (0)
3637
3638 #define APPEND_NESTRET() \
3639 do { \
3640 if (nestlen) \
3641 { \
3642 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
3643 strcpy (ret + retind, nestret); \
3644 retind += nestlen; \
3645 } \
3646 } while (0)
3647
3648 static char matched_pair_error;
3649
3650 static char *
3651 parse_matched_pair (qc, open, close, lenp, flags)
3652 int qc; /* `"' if this construct is within double quotes */
3653 int open, close;
3654 int *lenp, flags;
3655 {
3656 int count, ch, prevch, tflags;
3657 int nestlen, ttranslen, start_lineno;
3658 char *ret, *nestret, *ttrans;
3659 int retind, retsize, rflags;
3660 int dolbrace_state;
3661
3662 dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
3663
3664 /*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
3665 count = 1;
3666 tflags = 0;
3667
3668 if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3669 tflags |= LEX_CKCOMMENT;
3670
3671 /* RFLAGS is the set of flags we want to pass to recursive calls. */
3672 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
3673
3674 ret = (char *)xmalloc (retsize = 64);
3675 retind = 0;
3676
3677 start_lineno = line_number;
3678 ch = EOF; /* just in case */
3679 while (count)
3680 {
3681 prevch = ch;
3682 ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
3683
3684 if (ch == EOF)
3685 {
3686 free (ret);
3687 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3688 EOF_Reached = 1; /* XXX */
3689 return (&matched_pair_error);
3690 }
3691
3692 /* Possible reprompting. */
3693 if MBTEST(ch == '\n' && SHOULD_PROMPT ())
3694 prompt_again (0);
3695
3696 /* Don't bother counting parens or doing anything else if in a comment
3697 or part of a case statement */
3698 if (tflags & LEX_INCOMMENT)
3699 {
3700 /* Add this character. */
3701 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3702 ret[retind++] = ch;
3703
3704 if MBTEST(ch == '\n')
3705 tflags &= ~LEX_INCOMMENT;
3706
3707 continue;
3708 }
3709
3710 /* Not exactly right yet, should handle shell metacharacters, too. If
3711 any changes are made to this test, make analogous changes to subst.c:
3712 extract_delimited_string(). */
3713 else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
3714 tflags |= LEX_INCOMMENT;
3715
3716 if (tflags & LEX_PASSNEXT) /* last char was backslash */
3717 {
3718 tflags &= ~LEX_PASSNEXT;
3719 /* XXX - PST_NOEXPAND? */
3720 if MBTEST(qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3721 {
3722 if (retind > 0)
3723 retind--; /* swallow previously-added backslash */
3724 continue;
3725 }
3726
3727 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3728 if MBTEST(ch == CTLESC)
3729 ret[retind++] = CTLESC;
3730 ret[retind++] = ch;
3731 continue;
3732 }
3733 /* If we're reparsing the input (e.g., from parse_string_to_word_list),
3734 we've already prepended CTLESC to single-quoted results of $'...'.
3735 We may want to do this for other CTLESC-quoted characters in
3736 reparse, too. */
3737 else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
3738 {
3739 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3740 ret[retind++] = ch;
3741 continue;
3742 }
3743 else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3744 {
3745 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3746 ret[retind++] = CTLESC;
3747 ret[retind++] = ch;
3748 continue;
3749 }
3750 else if MBTEST(ch == close) /* ending delimiter */
3751 count--;
3752 /* handle nested ${...} specially. */
3753 else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
3754 count++;
3755 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
3756 count++;
3757
3758 /* Add this character. */
3759 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3760 ret[retind++] = ch;
3761
3762 /* If we just read the ending character, don't bother continuing. */
3763 if (count == 0)
3764 break;
3765
3766 if (open == '\'') /* '' inside grouping construct */
3767 {
3768 if MBTEST((flags & P_ALLOWESC) && ch == '\\')
3769 tflags |= LEX_PASSNEXT;
3770 continue;
3771 }
3772
3773 if MBTEST(ch == '\\') /* backslashes */
3774 tflags |= LEX_PASSNEXT;
3775
3776 /* Based on which dolstate is currently in (param, op, or word),
3777 decide what the op is. We're really only concerned if it's % or
3778 #, so we can turn on a flag that says whether or not we should
3779 treat single quotes as special when inside a double-quoted
3780 ${...}. This logic must agree with subst.c:extract_dollar_brace_string
3781 since they share the same defines. */
3782 /* FLAG POSIX INTERP 221 */
3783 if (flags & P_DOLBRACE)
3784 {
3785 /* ${param%[%]word} */
3786 if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
3787 dolbrace_state = DOLBRACE_QUOTE;
3788 /* ${param#[#]word} */
3789 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
3790 dolbrace_state = DOLBRACE_QUOTE;
3791 /* ${param/[/]pat/rep} */
3792 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1)
3793 dolbrace_state = DOLBRACE_QUOTE2; /* XXX */
3794 /* ${param^[^]pat} */
3795 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1)
3796 dolbrace_state = DOLBRACE_QUOTE;
3797 /* ${param,[,]pat} */
3798 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
3799 dolbrace_state = DOLBRACE_QUOTE;
3800 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
3801 dolbrace_state = DOLBRACE_OP;
3802 else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
3803 dolbrace_state = DOLBRACE_WORD;
3804 }
3805
3806 /* The big hammer. Single quotes aren't special in double quotes. The
3807 problem is that Posix used to say the single quotes are semi-special:
3808 within a double-quoted ${...} construct "an even number of
3809 unescaped double-quotes or single-quotes, if any, shall occur." */
3810 /* This was changed in Austin Group Interp 221 */
3811 if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
3812 continue;
3813
3814 /* Could also check open == '`' if we want to parse grouping constructs
3815 inside old-style command substitution. */
3816 if (open != close) /* a grouping construct */
3817 {
3818 if MBTEST(shellquote (ch))
3819 {
3820 /* '', ``, or "" inside $(...) or other grouping construct. */
3821 push_delimiter (dstack, ch);
3822 if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
3823 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3824 else
3825 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3826 pop_delimiter (dstack);
3827 CHECK_NESTRET_ERROR ();
3828
3829 if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0 || dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_QUOTE2))
3830 {
3831 /* Translate $'...' here. */
3832 /* PST_NOEXPAND */
3833 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3834 free (nestret);
3835
3836 /* If we're parsing a double-quoted brace expansion and we are
3837 not in a place where single quotes are treated specially,
3838 make sure we single-quote the results of the ansi
3839 expansion because quote removal should remove them later */
3840 /* FLAG POSIX INTERP 221 */
3841 if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2 || dolbrace_state == DOLBRACE_QUOTE) && (flags & P_DOLBRACE))
3842 {
3843 nestret = sh_single_quote (ttrans);
3844 free (ttrans);
3845 nestlen = strlen (nestret);
3846 }
3847 #if 0 /* TAG:bash-5.3 */
3848 /* This single-quotes PARAM in ${PARAM OP WORD} when PARAM
3849 contains a $'...' even when extended_quote is set. */
3850 else if ((rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_PARAM) && (flags & P_DOLBRACE))
3851 {
3852 nestret = sh_single_quote (ttrans);
3853 free (ttrans);
3854 nestlen = strlen (nestret);
3855 }
3856 #endif
3857 else if ((rflags & P_DQUOTE) == 0)
3858 {
3859 nestret = sh_single_quote (ttrans);
3860 free (ttrans);
3861 nestlen = strlen (nestret);
3862 }
3863 else
3864 {
3865 /* Should we quote CTLESC here? */
3866 nestret = ttrans;
3867 nestlen = ttranslen;
3868 }
3869 retind -= 2; /* back up before the $' */
3870 }
3871 #if defined (TRANSLATABLE_STRINGS)
3872 else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3873 {
3874 /* Locale expand $"..." here. */
3875 /* PST_NOEXPAND */
3876 ttrans = locale_expand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3877 free (nestret);
3878
3879 /* If we're supposed to single-quote translated strings,
3880 check whether the translated result is different from
3881 the original and single-quote the string if it is. */
3882 if (singlequote_translations &&
3883 ((nestlen - 1) != ttranslen || STREQN (nestret, ttrans, ttranslen) == 0))
3884 {
3885 if ((rflags & P_DQUOTE) == 0)
3886 nestret = sh_single_quote (ttrans);
3887 else if ((rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE))
3888 nestret = sh_single_quote (ttrans);
3889 else
3890 /* single quotes aren't special, use backslash instead */
3891 nestret = sh_backslash_quote_for_double_quotes (ttrans, 0);
3892 }
3893 else
3894 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3895 free (ttrans);
3896 nestlen = strlen (nestret);
3897 retind -= 2; /* back up before the $" */
3898 }
3899 #endif /* TRANSLATABLE_STRINGS */
3900
3901 APPEND_NESTRET ();
3902 FREE (nestret);
3903 }
3904 else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3905 goto parse_dollar_word;
3906 #if defined (PROCESS_SUBSTITUTION)
3907 /* XXX - technically this should only be recognized at the start of
3908 a word */
3909 else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_GTLT) && (ch == '(')) /* ) */
3910 goto parse_dollar_word;
3911 #endif
3912 }
3913 /* Parse an old-style command substitution within double quotes as a
3914 single word. */
3915 /* XXX - sh and ksh93 don't do this - XXX */
3916 else if MBTEST(open == '"' && ch == '`')
3917 {
3918 nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
3919
3920 CHECK_NESTRET_ERROR ();
3921 APPEND_NESTRET ();
3922
3923 FREE (nestret);
3924 }
3925 else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3926 /* check for $(), $[], or ${} inside quoted string. */
3927 {
3928 parse_dollar_word:
3929 if (open == ch) /* undo previous increment */
3930 count--;
3931 if (ch == '(') /* ) */
3932 nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3933 else if (ch == '{') /* } */
3934 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3935 else if (ch == '[') /* ] */
3936 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3937
3938 CHECK_NESTRET_ERROR ();
3939 APPEND_NESTRET ();
3940
3941 FREE (nestret);
3942 }
3943 #if defined (PROCESS_SUBSTITUTION)
3944 if MBTEST((ch == '<' || ch == '>') && (tflags & LEX_GTLT) == 0)
3945 tflags |= LEX_GTLT;
3946 else
3947 tflags &= ~LEX_GTLT;
3948 #endif
3949 if MBTEST(ch == '$' && (tflags & LEX_WASDOL) == 0)
3950 tflags |= LEX_WASDOL;
3951 else
3952 tflags &= ~LEX_WASDOL;
3953 }
3954
3955 ret[retind] = '\0';
3956 if (lenp)
3957 *lenp = retind;
3958 /*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
3959 return ret;
3960 }
3961
3962 #if defined (DEBUG)
3963 static void
3964 dump_tflags (flags)
3965 int flags;
3966 {
3967 int f;
3968
3969 f = flags;
3970 fprintf (stderr, "%d -> ", f);
3971 if (f & LEX_WASDOL)
3972 {
3973 f &= ~LEX_WASDOL;
3974 fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
3975 }
3976 if (f & LEX_CKCOMMENT)
3977 {
3978 f &= ~LEX_CKCOMMENT;
3979 fprintf (stderr, "LEX_CKCOMMENT%s", f ? "|" : "");
3980 }
3981 if (f & LEX_INCOMMENT)
3982 {
3983 f &= ~LEX_INCOMMENT;
3984 fprintf (stderr, "LEX_INCOMMENT%s", f ? "|" : "");
3985 }
3986 if (f & LEX_PASSNEXT)
3987 {
3988 f &= ~LEX_PASSNEXT;
3989 fprintf (stderr, "LEX_PASSNEXT%s", f ? "|" : "");
3990 }
3991 if (f & LEX_RESWDOK)
3992 {
3993 f &= ~LEX_RESWDOK;
3994 fprintf (stderr, "LEX_RESWDOK%s", f ? "|" : "");
3995 }
3996 if (f & LEX_CKCASE)
3997 {
3998 f &= ~LEX_CKCASE;
3999 fprintf (stderr, "LEX_CKCASE%s", f ? "|" : "");
4000 }
4001 if (f & LEX_CKESAC)
4002 {
4003 f &= ~LEX_CKESAC;
4004 fprintf (stderr, "LEX_CKESAC%s", f ? "|" : "");
4005 }
4006 if (f & LEX_INCASE)
4007 {
4008 f &= ~LEX_INCASE;
4009 fprintf (stderr, "LEX_INCASE%s", f ? "|" : "");
4010 }
4011 if (f & LEX_CASEWD)
4012 {
4013 f &= ~LEX_CASEWD;
4014 fprintf (stderr, "LEX_CASEWD%s", f ? "|" : "");
4015 }
4016 if (f & LEX_PATLIST)
4017 {
4018 f &= ~LEX_PATLIST;
4019 fprintf (stderr, "LEX_PATLIST%s", f ? "|" : "");
4020 }
4021 if (f & LEX_INHEREDOC)
4022 {
4023 f &= ~LEX_INHEREDOC;
4024 fprintf (stderr, "LEX_INHEREDOC%s", f ? "|" : "");
4025 }
4026 if (f & LEX_HEREDELIM)
4027 {
4028 f &= ~LEX_HEREDELIM;
4029 fprintf (stderr, "LEX_HEREDELIM%s", f ? "|" : "");
4030 }
4031 if (f & LEX_STRIPDOC)
4032 {
4033 f &= ~LEX_STRIPDOC;
4034 fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
4035 }
4036 if (f & LEX_QUOTEDDOC)
4037 {
4038 f &= ~LEX_QUOTEDDOC;
4039 fprintf (stderr, "LEX_QUOTEDDOC%s", f ? "|" : "");
4040 }
4041 if (f & LEX_INWORD)
4042 {
4043 f &= ~LEX_INWORD;
4044 fprintf (stderr, "LEX_INWORD%s", f ? "|" : "");
4045 }
4046
4047 fprintf (stderr, "\n");
4048 fflush (stderr);
4049 }
4050 #endif
4051
4052 /* Parse a $(...) command substitution. This reads input from the current
4053 input stream. */
4054 static char *
4055 parse_comsub (qc, open, close, lenp, flags)
4056 int qc; /* `"' if this construct is within double quotes */
4057 int open, close;
4058 int *lenp, flags;
4059 {
4060 int peekc, r;
4061 int start_lineno;
4062 char *ret, *tcmd;
4063 int retlen;
4064 sh_parser_state_t ps;
4065 COMMAND *saved_global, *parsed_command;
4066
4067 /* Posix interp 217 says arithmetic expressions have precedence, so
4068 assume $(( introduces arithmetic expansion and parse accordingly. */
4069 if (open == '(') /*)*/
4070 {
4071 peekc = shell_getc (1);
4072 shell_ungetc (peekc);
4073 if (peekc == '(') /*)*/
4074 return (parse_matched_pair (qc, open, close, lenp, 0));
4075 }
4076
4077 /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
4078
4079 /*debug_parser(1);*/
4080 start_lineno = line_number;
4081
4082 save_parser_state (&ps);
4083
4084 pushed_string_list = (STRING_SAVER *)NULL;
4085
4086 /* State flags we don't want to persist into command substitutions. */
4087 parser_state &= ~(PST_REGEXP|PST_EXTPAT|PST_CONDCMD|PST_CONDEXPR|PST_COMPASSIGN);
4088 /* Could do PST_CASESTMT too, but that also affects history. Setting
4089 expecting_in_token below should take care of the parsing requirements.
4090 Unsetting PST_REDIRLIST isn't strictly necessary because of how we set
4091 token_to_read below, but we do it anyway. */
4092 parser_state &= ~(PST_CASEPAT|PST_ALEXPNEXT|PST_SUBSHELL|PST_REDIRLIST);
4093 /* State flags we want to set for this run through the parser. */
4094 parser_state |= PST_CMDSUBST|PST_EOFTOKEN|PST_NOEXPAND;
4095
4096 shell_eof_token = close;
4097
4098 saved_global = global_command; /* might not be necessary */
4099 global_command = (COMMAND *)NULL;
4100
4101 need_here_doc = 0;
4102 esacs_needed_count = expecting_in_token = 0;
4103
4104 /* We want to expand aliases on this pass if we're in posix mode, since the
4105 standard says you have to take aliases into account when looking for the
4106 terminating right paren. Otherwise, we defer until execution time for
4107 backwards compatibility. */
4108 if (expand_aliases)
4109 expand_aliases = posixly_correct != 0;
4110
4111 current_token = '\n'; /* XXX */
4112
4113 token_to_read = DOLPAREN; /* let's trick the parser */
4114
4115 r = yyparse ();
4116
4117 if (need_here_doc > 0)
4118 {
4119 internal_warning ("command substitution: %d unterminated here-document%s", need_here_doc, (need_here_doc == 1) ? "" : "s");
4120 gather_here_documents (); /* XXX check compatibility level? */
4121 }
4122
4123 parsed_command = global_command;
4124
4125 if (EOF_Reached)
4126 /* yyparse() has already called yyerror() */
4127 return (&matched_pair_error);
4128 else if (r != 0)
4129 {
4130 /* parser_error (start_lineno, _("could not parse command substitution")); */
4131 /* Non-interactive shells exit on parse error in a command substitution. */
4132 if (last_command_exit_value == 0)
4133 last_command_exit_value = EXECUTION_FAILURE;
4134 set_exit_status (last_command_exit_value);
4135 if (interactive_shell == 0)
4136 jump_to_top_level (FORCE_EOF); /* This is like reader_loop() */
4137 else
4138 jump_to_top_level (DISCARD);
4139 }
4140
4141 if (current_token != shell_eof_token)
4142 {
4143 INTERNAL_DEBUG(("current_token (%d) != shell_eof_token (%c)", current_token, shell_eof_token));
4144 token_to_read = current_token;
4145 return (&matched_pair_error);
4146 }
4147
4148 restore_parser_state (&ps);
4149
4150 tcmd = print_comsub (parsed_command); /* returns static memory */
4151 retlen = strlen (tcmd);
4152 if (tcmd[0] == '(') /* ) need a space to prevent arithmetic expansion */
4153 retlen++;
4154 ret = xmalloc (retlen + 2);
4155 if (tcmd[0] == '(') /* ) */
4156 {
4157 ret[0] = ' ';
4158 strcpy (ret + 1, tcmd);
4159 }
4160 else
4161 strcpy (ret, tcmd);
4162 ret[retlen++] = ')';
4163 ret[retlen] = '\0';
4164
4165 dispose_command (parsed_command);
4166 global_command = saved_global;
4167
4168 if (lenp)
4169 *lenp = retlen;
4170
4171 /*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
4172 return ret;
4173 }
4174
4175 /* Recursively call the parser to parse a $(...) command substitution. This is
4176 called by the word expansion code and so does not have to reset as much
4177 parser state before calling yyparse(). */
4178 char *
4179 xparse_dolparen (base, string, indp, flags)
4180 char *base;
4181 char *string;
4182 int *indp;
4183 int flags;
4184 {
4185 sh_parser_state_t ps;
4186 sh_input_line_state_t ls;
4187 int orig_ind, nc, sflags, start_lineno;
4188 char *ret, *ep, *ostring;
4189
4190 /*debug_parser(1);*/
4191 orig_ind = *indp;
4192 ostring = string;
4193 start_lineno = line_number;
4194
4195 if (*string == 0)
4196 {
4197 if (flags & SX_NOALLOC)
4198 return (char *)NULL;
4199
4200 ret = xmalloc (1);
4201 ret[0] = '\0';
4202 return ret;
4203 }
4204
4205 /*itrace("xparse_dolparen: size = %d shell_input_line = `%s' string=`%s'", shell_input_line_size, shell_input_line, string);*/
4206
4207 sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
4208 if (flags & SX_NOLONGJMP)
4209 sflags |= SEVAL_NOLONGJMP;
4210
4211 save_parser_state (&ps);
4212 save_input_line_state (&ls);
4213
4214 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4215 pushed_string_list = (STRING_SAVER *)NULL;
4216 #endif
4217 /*(*/
4218 parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
4219 shell_eof_token = ')';
4220 if (flags & SX_COMPLETE)
4221 parser_state |= PST_NOERROR;
4222
4223 /* Don't expand aliases on this pass at all. Either parse_comsub() does it
4224 at parse time, in which case this string already has aliases expanded,
4225 or command_substitute() does it in the child process executing the
4226 command substitution and we want to defer it completely until then. The
4227 old value will be restored by restore_parser_state(). */
4228 expand_aliases = 0;
4229
4230 token_to_read = DOLPAREN; /* let's trick the parser */
4231
4232 nc = parse_string (string, "command substitution", sflags, (COMMAND **)NULL, &ep);
4233
4234 /* Should we save and restore the bison/yacc lookahead token (yychar) here?
4235 Or only if it's not YYEMPTY? */
4236 if (current_token == shell_eof_token)
4237 yyclearin; /* might want to clear lookahead token unconditionally */
4238
4239 reset_parser ();
4240 /* reset_parser() clears shell_input_line and associated variables, including
4241 parser_state, so we want to reset things, then restore what we need. */
4242 restore_input_line_state (&ls);
4243 restore_parser_state (&ps);
4244
4245 token_to_read = 0;
4246
4247 /* If parse_string returns < 0, we need to jump to top level with the
4248 negative of the return value. We abandon the rest of this input line
4249 first */
4250 if (nc < 0)
4251 {
4252 clear_shell_input_line (); /* XXX */
4253 if (bash_input.type != st_string) /* paranoia */
4254 parser_state &= ~(PST_CMDSUBST|PST_EOFTOKEN);
4255 if ((flags & SX_NOLONGJMP) == 0)
4256 jump_to_top_level (-nc); /* XXX */
4257 }
4258
4259 /* Need to find how many characters parse_string() consumed, update
4260 *indp, if flags != 0, copy the portion of the string parsed into RET
4261 and return it. If flags & 1 (SX_NOALLOC) we can return NULL. */
4262
4263 /*(*/
4264 if (ep[-1] != ')')
4265 {
4266 #if 0
4267 if (ep[-1] != '\n')
4268 itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
4269 #endif
4270
4271 while (ep > ostring && ep[-1] == '\n') ep--;
4272 }
4273
4274 nc = ep - ostring;
4275 *indp = ep - base - 1;
4276
4277 /*((*/
4278 #if 0
4279 if (base[*indp] != ')')
4280 itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
4281 if (*indp < orig_ind)
4282 itrace("xparse_dolparen:%d: *indp (%d) < orig_ind (%d), orig_string = `%s'", line_number, *indp, orig_ind, ostring);
4283 #endif
4284
4285 if (base[*indp] != ')' && (flags & SX_NOLONGJMP) == 0)
4286 {
4287 /*(*/
4288 if ((flags & SX_NOERROR) == 0)
4289 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), ')');
4290 jump_to_top_level (DISCARD);
4291 }
4292
4293 if (flags & SX_NOALLOC)
4294 return (char *)NULL;
4295
4296 if (nc == 0)
4297 {
4298 ret = xmalloc (1);
4299 ret[0] = '\0';
4300 }
4301 else
4302 ret = substring (ostring, 0, nc - 1);
4303
4304 return ret;
4305 }
4306
4307 /* Recursively call the parser to parse the string from a $(...) command
4308 substitution to a COMMAND *. This is called from command_substitute() and
4309 has the same parser state constraints as xparse_dolparen(). */
4310 COMMAND *
4311 parse_string_to_command (string, flags)
4312 char *string;
4313 int flags;
4314 {
4315 sh_parser_state_t ps;
4316 sh_input_line_state_t ls;
4317 int nc, sflags;
4318 size_t slen;
4319 char *ret, *ep;
4320 COMMAND *cmd;
4321
4322 if (*string == 0)
4323 return (COMMAND *)NULL;
4324
4325 ep = string;
4326 slen = STRLEN (string);
4327
4328 /*itrace("parse_string_to_command: size = %d shell_input_line = `%s' string=`%s'", shell_input_line_size, shell_input_line, string);*/
4329
4330 sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
4331 if (flags & SX_NOLONGJMP)
4332 sflags |= SEVAL_NOLONGJMP;
4333
4334 save_parser_state (&ps);
4335 save_input_line_state (&ls);
4336
4337 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4338 pushed_string_list = (STRING_SAVER *)NULL;
4339 #endif
4340 if (flags & SX_COMPLETE)
4341 parser_state |= PST_NOERROR;
4342
4343 expand_aliases = 0;
4344
4345 cmd = 0;
4346 nc = parse_string (string, "command substitution", sflags, &cmd, &ep);
4347
4348 reset_parser ();
4349 /* reset_parser() clears shell_input_line and associated variables, including
4350 parser_state, so we want to reset things, then restore what we need. */
4351 restore_input_line_state (&ls);
4352 restore_parser_state (&ps);
4353
4354 /* If parse_string returns < 0, we need to jump to top level with the
4355 negative of the return value. We abandon the rest of this input line
4356 first */
4357 if (nc < 0)
4358 {
4359 clear_shell_input_line (); /* XXX */
4360 if ((flags & SX_NOLONGJMP) == 0)
4361 jump_to_top_level (-nc); /* XXX */
4362 }
4363
4364 /* Need to check how many characters parse_string() consumed, make sure it's
4365 the entire string. */
4366 if (nc < slen)
4367 {
4368 dispose_command (cmd);
4369 return (COMMAND *)NULL;
4370 }
4371
4372 return cmd;
4373 }
4374
4375 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
4376 /* Parse a double-paren construct. It can be either an arithmetic
4377 command, an arithmetic `for' command, or a nested subshell. Returns
4378 the parsed token, -1 on error, or -2 if we didn't do anything and
4379 should just go on. */
4380 static int
4381 parse_dparen (c)
4382 int c;
4383 {
4384 int cmdtyp, sline;
4385 char *wval;
4386 WORD_DESC *wd;
4387
4388 #if defined (ARITH_FOR_COMMAND)
4389 if (last_read_token == FOR)
4390 {
4391 if (word_top < MAX_CASE_NEST)
4392 word_top++;
4393 arith_for_lineno = word_lineno[word_top] = line_number;
4394 cmdtyp = parse_arith_cmd (&wval, 0);
4395 if (cmdtyp == 1)
4396 {
4397 wd = alloc_word_desc ();
4398 wd->word = wval;
4399 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
4400 return (ARITH_FOR_EXPRS);
4401 }
4402 else
4403 return -1; /* ERROR */
4404 }
4405 #endif
4406
4407 #if defined (DPAREN_ARITHMETIC)
4408 if (reserved_word_acceptable (last_read_token))
4409 {
4410 sline = line_number;
4411
4412 cmdtyp = parse_arith_cmd (&wval, 0);
4413 if (cmdtyp == 1) /* arithmetic command */
4414 {
4415 wd = alloc_word_desc ();
4416 wd->word = wval;
4417 wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_NOTILDE|W_NOPROCSUB;
4418 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
4419 return (ARITH_CMD);
4420 }
4421 else if (cmdtyp == 0) /* nested subshell */
4422 {
4423 push_string (wval, 0, (alias_t *)NULL);
4424 pushed_string_list->flags = PSH_DPAREN;
4425 if ((parser_state & PST_CASEPAT) == 0)
4426 parser_state |= PST_SUBSHELL;
4427 return (c);
4428 }
4429 else /* ERROR */
4430 return -1;
4431 }
4432 #endif
4433
4434 return -2; /* XXX */
4435 }
4436
4437 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
4438 If not, assume it's a nested subshell for backwards compatibility and
4439 return 0. In any case, put the characters we've consumed into a locally-
4440 allocated buffer and make *ep point to that buffer. Return -1 on an
4441 error, for example EOF. */
4442 static int
4443 parse_arith_cmd (ep, adddq)
4444 char **ep;
4445 int adddq;
4446 {
4447 int exp_lineno, rval, c;
4448 char *ttok, *tokstr;
4449 int ttoklen;
4450
4451 exp_lineno = line_number;
4452 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
4453 rval = 1;
4454 if (ttok == &matched_pair_error)
4455 return -1;
4456 /* Check that the next character is the closing right paren. If
4457 not, this is a syntax error. ( */
4458 c = shell_getc (0);
4459 if MBTEST(c != ')')
4460 rval = 0;
4461
4462 tokstr = (char *)xmalloc (ttoklen + 4);
4463
4464 /* if ADDDQ != 0 then (( ... )) -> "..." */
4465 if (rval == 1 && adddq) /* arith cmd, add double quotes */
4466 {
4467 tokstr[0] = '"';
4468 strncpy (tokstr + 1, ttok, ttoklen - 1);
4469 tokstr[ttoklen] = '"';
4470 tokstr[ttoklen+1] = '\0';
4471 }
4472 else if (rval == 1) /* arith cmd, don't add double quotes */
4473 {
4474 strncpy (tokstr, ttok, ttoklen - 1);
4475 tokstr[ttoklen-1] = '\0';
4476 }
4477 else /* nested subshell */
4478 {
4479 tokstr[0] = '(';
4480 strncpy (tokstr + 1, ttok, ttoklen - 1);
4481 tokstr[ttoklen] = ')';
4482 tokstr[ttoklen+1] = c;
4483 tokstr[ttoklen+2] = '\0';
4484 }
4485
4486 *ep = tokstr;
4487 FREE (ttok);
4488 return rval;
4489 }
4490 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
4491
4492 #if defined (COND_COMMAND)
4493 static void
4494 cond_error ()
4495 {
4496 char *etext;
4497
4498 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
4499 parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
4500 else if (cond_token != COND_ERROR)
4501 {
4502 if (etext = error_token_from_token (cond_token))
4503 {
4504 parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
4505 free (etext);
4506 }
4507 else
4508 parser_error (cond_lineno, _("syntax error in conditional expression"));
4509 }
4510 }
4511
4512 static COND_COM *
4513 cond_expr ()
4514 {
4515 return (cond_or ());
4516 }
4517
4518 static COND_COM *
4519 cond_or ()
4520 {
4521 COND_COM *l, *r;
4522
4523 l = cond_and ();
4524 if (cond_token == OR_OR)
4525 {
4526 r = cond_or ();
4527 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
4528 }
4529 return l;
4530 }
4531
4532 static COND_COM *
4533 cond_and ()
4534 {
4535 COND_COM *l, *r;
4536
4537 l = cond_term ();
4538 if (cond_token == AND_AND)
4539 {
4540 r = cond_and ();
4541 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
4542 }
4543 return l;
4544 }
4545
4546 static int
4547 cond_skip_newlines ()
4548 {
4549 while ((cond_token = read_token (READ)) == '\n')
4550 {
4551 if (SHOULD_PROMPT ())
4552 prompt_again (0);
4553 }
4554 return (cond_token);
4555 }
4556
4557 #define COND_RETURN_ERROR() \
4558 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
4559
4560 static COND_COM *
4561 cond_term ()
4562 {
4563 WORD_DESC *op;
4564 COND_COM *term, *tleft, *tright;
4565 int tok, lineno;
4566 char *etext;
4567
4568 /* Read a token. It can be a left paren, a `!', a unary operator, or a
4569 word that should be the first argument of a binary operator. Start by
4570 skipping newlines, since this is a compound command. */
4571 tok = cond_skip_newlines ();
4572 lineno = line_number;
4573 if (tok == COND_END)
4574 {
4575 COND_RETURN_ERROR ();
4576 }
4577 else if (tok == '(')
4578 {
4579 term = cond_expr ();
4580 if (cond_token != ')')
4581 {
4582 if (term)
4583 dispose_cond_node (term); /* ( */
4584 if (etext = error_token_from_token (cond_token))
4585 {
4586 parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
4587 free (etext);
4588 }
4589 else
4590 parser_error (lineno, _("expected `)'"));
4591 COND_RETURN_ERROR ();
4592 }
4593 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
4594 (void)cond_skip_newlines ();
4595 }
4596 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
4597 {
4598 if (tok == WORD)
4599 dispose_word (yylval.word); /* not needed */
4600 term = cond_term ();
4601 if (term)
4602 term->flags ^= CMD_INVERT_RETURN;
4603 }
4604 else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[1] && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
4605 {
4606 op = yylval.word;
4607 tok = read_token (READ);
4608 if (tok == WORD)
4609 {
4610 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4611 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4612 }
4613 else
4614 {
4615 dispose_word (op);
4616 if (etext = error_token_from_token (tok))
4617 {
4618 parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
4619 free (etext);
4620 }
4621 else
4622 parser_error (line_number, _("unexpected argument to conditional unary operator"));
4623 COND_RETURN_ERROR ();
4624 }
4625
4626 (void)cond_skip_newlines ();
4627 }
4628 else if (tok == WORD) /* left argument to binary operator */
4629 {
4630 /* lhs */
4631 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4632
4633 /* binop */
4634 /* tok = cond_skip_newlines (); ? */
4635 tok = read_token (READ);
4636 if (tok == WORD && test_binop (yylval.word->word))
4637 {
4638 op = yylval.word;
4639 if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
4640 parser_state |= PST_EXTPAT;
4641 else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
4642 parser_state |= PST_EXTPAT;
4643 }
4644 #if defined (COND_REGEXP)
4645 else if (tok == WORD && STREQ (yylval.word->word, "=~"))
4646 {
4647 op = yylval.word;
4648 parser_state |= PST_REGEXP;
4649 }
4650 #endif
4651 else if (tok == '<' || tok == '>')
4652 op = make_word_from_token (tok); /* ( */
4653 /* There should be a check before blindly accepting the `)' that we have
4654 seen the opening `('. */
4655 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
4656 {
4657 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
4658 the test command. Similarly for [[ x && expr ]] or
4659 [[ x || expr ]] or [[ (x) ]]. */
4660 op = make_word ("-n");
4661 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4662 cond_token = tok;
4663 return (term);
4664 }
4665 else
4666 {
4667 if (etext = error_token_from_token (tok))
4668 {
4669 parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
4670 free (etext);
4671 }
4672 else
4673 parser_error (line_number, _("conditional binary operator expected"));
4674 dispose_cond_node (tleft);
4675 COND_RETURN_ERROR ();
4676 }
4677
4678 /* rhs */
4679 if (parser_state & PST_EXTPAT)
4680 extended_glob = 1;
4681 tok = read_token (READ);
4682 if (parser_state & PST_EXTPAT)
4683 extended_glob = global_extglob;
4684 parser_state &= ~(PST_REGEXP|PST_EXTPAT);
4685
4686 if (tok == WORD)
4687 {
4688 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4689 term = make_cond_node (COND_BINARY, op, tleft, tright);
4690 }
4691 else
4692 {
4693 if (etext = error_token_from_token (tok))
4694 {
4695 parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
4696 free (etext);
4697 }
4698 else
4699 parser_error (line_number, _("unexpected argument to conditional binary operator"));
4700 dispose_cond_node (tleft);
4701 dispose_word (op);
4702 COND_RETURN_ERROR ();
4703 }
4704
4705 (void)cond_skip_newlines ();
4706 }
4707 else
4708 {
4709 if (tok < 256)
4710 parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
4711 else if (etext = error_token_from_token (tok))
4712 {
4713 parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
4714 free (etext);
4715 }
4716 else
4717 parser_error (line_number, _("unexpected token %d in conditional command"), tok);
4718 COND_RETURN_ERROR ();
4719 }
4720 return (term);
4721 }
4722
4723 /* This is kind of bogus -- we slip a mini recursive-descent parser in
4724 here to handle the conditional statement syntax. */
4725 static COMMAND *
4726 parse_cond_command ()
4727 {
4728 COND_COM *cexp;
4729
4730 global_extglob = extended_glob;
4731 cexp = cond_expr ();
4732 return (make_cond_command (cexp));
4733 }
4734 #endif
4735
4736 #if defined (ARRAY_VARS)
4737 /* When this is called, it's guaranteed that we don't care about anything
4738 in t beyond i. We use a buffer with room for the characters we add just
4739 in case assignment() ends up doing something like parsing a command
4740 substitution that will reallocate atoken. We don't want to write beyond
4741 the end of an allocated buffer. */
4742 static int
4743 token_is_assignment (t, i)
4744 char *t;
4745 int i;
4746 {
4747 int r;
4748 char *atoken;
4749
4750 atoken = xmalloc (i + 3);
4751 memcpy (atoken, t, i);
4752 atoken[i] = '=';
4753 atoken[i+1] = '\0';
4754
4755 r = assignment (atoken, (parser_state & PST_COMPASSIGN) != 0);
4756
4757 free (atoken);
4758
4759 /* XXX - check that r == i to avoid returning false positive for
4760 t containing `=' before t[i]. */
4761 return (r > 0 && r == i);
4762 }
4763
4764 /* XXX - possible changes here for `+=' */
4765 static int
4766 token_is_ident (t, i)
4767 char *t;
4768 int i;
4769 {
4770 unsigned char c;
4771 int r;
4772
4773 c = t[i];
4774 t[i] = '\0';
4775 r = legal_identifier (t);
4776 t[i] = c;
4777 return r;
4778 }
4779 #endif
4780
4781 static int
4782 read_token_word (character)
4783 int character;
4784 {
4785 /* The value for YYLVAL when a WORD is read. */
4786 WORD_DESC *the_word;
4787
4788 /* Index into the token that we are building. */
4789 int token_index;
4790
4791 /* ALL_DIGITS becomes zero when we see a non-digit. */
4792 int all_digit_token;
4793
4794 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4795 int dollar_present;
4796
4797 /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4798 assignment. */
4799 int compound_assignment;
4800
4801 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4802 int quoted;
4803
4804 /* Non-zero means to ignore the value of the next character, and just
4805 to add it no matter what. */
4806 int pass_next_character;
4807
4808 /* The current delimiting character. */
4809 int cd;
4810 int result, peek_char;
4811 char *ttok, *ttrans;
4812 int ttoklen, ttranslen;
4813 intmax_t lvalue;
4814
4815 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
4816 token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
4817
4818 token_index = 0;
4819 all_digit_token = DIGIT (character);
4820 dollar_present = quoted = pass_next_character = compound_assignment = 0;
4821
4822 for (;;)
4823 {
4824 if (character == EOF)
4825 goto got_token;
4826
4827 if (pass_next_character)
4828 {
4829 pass_next_character = 0;
4830 goto got_escaped_character;
4831 }
4832
4833 cd = current_delimiter (dstack);
4834
4835 /* Handle backslashes. Quote lots of things when not inside of
4836 double-quotes, quote some things inside of double-quotes. */
4837 if MBTEST(character == '\\')
4838 {
4839 if (parser_state & PST_NOEXPAND)
4840 {
4841 pass_next_character++;
4842 quoted = 1;
4843 goto got_character;
4844 }
4845
4846 peek_char = shell_getc (0);
4847
4848 /* Backslash-newline is ignored in all cases except
4849 when quoted with single quotes. */
4850 if MBTEST(peek_char == '\n')
4851 {
4852 character = '\n';
4853 goto next_character;
4854 }
4855 else
4856 {
4857 shell_ungetc (peek_char);
4858
4859 /* If the next character is to be quoted, note it now. */
4860 if MBTEST(cd == 0 || cd == '`' ||
4861 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
4862 pass_next_character++;
4863
4864 quoted = 1;
4865 goto got_character;
4866 }
4867 }
4868
4869 /* Parse a matched pair of quote characters. */
4870 if MBTEST(shellquote (character))
4871 {
4872 push_delimiter (dstack, character);
4873 ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
4874 pop_delimiter (dstack);
4875 if (ttok == &matched_pair_error)
4876 return -1; /* Bail immediately. */
4877 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4878 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4879 token[token_index++] = character;
4880 strcpy (token + token_index, ttok);
4881 token_index += ttoklen;
4882 all_digit_token = 0;
4883 if (character != '`')
4884 quoted = 1;
4885 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4886 FREE (ttok);
4887 goto next_character;
4888 }
4889
4890 #ifdef COND_REGEXP
4891 /* When parsing a regexp as a single word inside a conditional command,
4892 we need to special-case characters special to both the shell and
4893 regular expressions. Right now, that is only '(' and '|'. */ /*)*/
4894 if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/
4895 {
4896 if (character == '|')
4897 goto got_character;
4898
4899 push_delimiter (dstack, character);
4900 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4901 pop_delimiter (dstack);
4902 if (ttok == &matched_pair_error)
4903 return -1; /* Bail immediately. */
4904 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4905 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4906 token[token_index++] = character;
4907 strcpy (token + token_index, ttok);
4908 token_index += ttoklen;
4909 FREE (ttok);
4910 dollar_present = all_digit_token = 0;
4911 goto next_character;
4912 }
4913 #endif /* COND_REGEXP */
4914
4915 #ifdef EXTENDED_GLOB
4916 /* Parse a ksh-style extended pattern matching specification. */
4917 if MBTEST(extended_glob && PATTERN_CHAR (character))
4918 {
4919 peek_char = shell_getc (1);
4920 if MBTEST(peek_char == '(') /* ) */
4921 {
4922 push_delimiter (dstack, peek_char);
4923 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4924 pop_delimiter (dstack);
4925 if (ttok == &matched_pair_error)
4926 return -1; /* Bail immediately. */
4927 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
4928 token_buffer_size,
4929 TOKEN_DEFAULT_GROW_SIZE);
4930 token[token_index++] = character;
4931 token[token_index++] = peek_char;
4932 strcpy (token + token_index, ttok);
4933 token_index += ttoklen;
4934 FREE (ttok);
4935 dollar_present = all_digit_token = 0;
4936 goto next_character;
4937 }
4938 else
4939 shell_ungetc (peek_char);
4940 }
4941 #endif /* EXTENDED_GLOB */
4942
4943 /* If the delimiter character is not single quote, parse some of
4944 the shell expansions that must be read as a single word. */
4945 if MBTEST(shellexp (character))
4946 {
4947 peek_char = shell_getc (1);
4948 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4949 if MBTEST(peek_char == '(' ||
4950 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4951 {
4952 if (peek_char == '{') /* } */
4953 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
4954 else if (peek_char == '(') /* ) */
4955 {
4956 /* XXX - push and pop the `(' as a delimiter for use by
4957 the command-oriented-history code. This way newlines
4958 appearing in the $(...) string get added to the
4959 history literally rather than causing a possibly-
4960 incorrect `;' to be added. ) */
4961 push_delimiter (dstack, peek_char);
4962 ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
4963 pop_delimiter (dstack);
4964 }
4965 else
4966 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4967 if (ttok == &matched_pair_error)
4968 return -1; /* Bail immediately. */
4969 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
4970 token_buffer_size,
4971 TOKEN_DEFAULT_GROW_SIZE);
4972 token[token_index++] = character;
4973 token[token_index++] = peek_char;
4974 strcpy (token + token_index, ttok);
4975 token_index += ttoklen;
4976 FREE (ttok);
4977 dollar_present = 1;
4978 all_digit_token = 0;
4979 goto next_character;
4980 }
4981 /* This handles $'...' and $"..." new-style quoted strings. */
4982 #if defined (TRANSLATABLE_STRINGS)
4983 else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
4984 #else
4985 else if MBTEST(character == '$' && peek_char == '\'')
4986 #endif
4987 {
4988 int first_line;
4989
4990 first_line = line_number;
4991 push_delimiter (dstack, peek_char);
4992 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4993 &ttoklen,
4994 (peek_char == '\'') ? P_ALLOWESC : 0);
4995 pop_delimiter (dstack);
4996 if (ttok == &matched_pair_error)
4997 return -1;
4998 if (peek_char == '\'')
4999 {
5000 /* PST_NOEXPAND */
5001 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
5002 free (ttok);
5003
5004 /* Insert the single quotes and correctly quote any
5005 embedded single quotes (allowed because P_ALLOWESC was
5006 passed to parse_matched_pair). */
5007 ttok = sh_single_quote (ttrans);
5008 free (ttrans);
5009 ttranslen = strlen (ttok);
5010 ttrans = ttok;
5011 }
5012 #if defined (TRANSLATABLE_STRINGS)
5013 else
5014 {
5015 /* PST_NOEXPAND */
5016 /* Try to locale-expand the converted string. */
5017 ttrans = locale_expand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
5018 free (ttok);
5019
5020 /* Add the double quotes back (or single quotes if the user
5021 has set that option). */
5022 if (singlequote_translations &&
5023 ((ttoklen - 1) != ttranslen || STREQN (ttok, ttrans, ttranslen) == 0))
5024 ttok = sh_single_quote (ttrans);
5025 else
5026 ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
5027
5028 free (ttrans);
5029 ttrans = ttok;
5030 ttranslen = strlen (ttrans);
5031 }
5032 #endif /* TRANSLATABLE_STRINGS */
5033
5034 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1,
5035 token_buffer_size,
5036 TOKEN_DEFAULT_GROW_SIZE);
5037 strcpy (token + token_index, ttrans);
5038 token_index += ttranslen;
5039 FREE (ttrans);
5040 quoted = 1;
5041 all_digit_token = 0;
5042 goto next_character;
5043 }
5044 /* This could eventually be extended to recognize all of the
5045 shell's single-character parameter expansions, and set flags.*/
5046 else if MBTEST(character == '$' && peek_char == '$')
5047 {
5048 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
5049 token_buffer_size,
5050 TOKEN_DEFAULT_GROW_SIZE);
5051 token[token_index++] = '$';
5052 token[token_index++] = peek_char;
5053 dollar_present = 1;
5054 all_digit_token = 0;
5055 goto next_character;
5056 }
5057 else
5058 shell_ungetc (peek_char);
5059 }
5060
5061 #if defined (ARRAY_VARS)
5062 /* Identify possible array subscript assignment; match [...]. If
5063 parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
5064 `sub' as if it were enclosed in double quotes. */
5065 else if MBTEST(character == '[' && /* ] */
5066 ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
5067 (token_index == 0 && (parser_state&PST_COMPASSIGN))))
5068 {
5069 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
5070 if (ttok == &matched_pair_error)
5071 return -1; /* Bail immediately. */
5072 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
5073 token_buffer_size,
5074 TOKEN_DEFAULT_GROW_SIZE);
5075 token[token_index++] = character;
5076 strcpy (token + token_index, ttok);
5077 token_index += ttoklen;
5078 FREE (ttok);
5079 all_digit_token = 0;
5080 goto next_character;
5081 }
5082 /* Identify possible compound array variable assignment. */
5083 else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
5084 {
5085 peek_char = shell_getc (1);
5086 if MBTEST(peek_char == '(') /* ) */
5087 {
5088 ttok = parse_compound_assignment (&ttoklen);
5089
5090 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
5091 token_buffer_size,
5092 TOKEN_DEFAULT_GROW_SIZE);
5093
5094 token[token_index++] = '=';
5095 token[token_index++] = '(';
5096 if (ttok)
5097 {
5098 strcpy (token + token_index, ttok);
5099 token_index += ttoklen;
5100 }
5101 token[token_index++] = ')';
5102 FREE (ttok);
5103 all_digit_token = 0;
5104 compound_assignment = 1;
5105 #if 1
5106 goto next_character;
5107 #else
5108 goto got_token; /* ksh93 seems to do this */
5109 #endif
5110 }
5111 else
5112 shell_ungetc (peek_char);
5113 }
5114 #endif
5115
5116 /* When not parsing a multi-character word construct, shell meta-
5117 characters break words. */
5118 if MBTEST(shellbreak (character))
5119 {
5120 shell_ungetc (character);
5121 goto got_token;
5122 }
5123
5124 got_character:
5125 if MBTEST(character == CTLESC || character == CTLNUL)
5126 {
5127 RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size,
5128 TOKEN_DEFAULT_GROW_SIZE);
5129 token[token_index++] = CTLESC;
5130 }
5131 else
5132 got_escaped_character:
5133 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
5134 TOKEN_DEFAULT_GROW_SIZE);
5135
5136 token[token_index++] = character;
5137
5138 all_digit_token &= DIGIT (character);
5139 dollar_present |= character == '$';
5140
5141 next_character:
5142 if (character == '\n' && SHOULD_PROMPT ())
5143 prompt_again (0);
5144
5145 /* We want to remove quoted newlines (that is, a \<newline> pair)
5146 unless we are within single quotes or pass_next_character is
5147 set (the shell equivalent of literal-next). */
5148 cd = current_delimiter (dstack);
5149 character = shell_getc (cd != '\'' && pass_next_character == 0);
5150 } /* end for (;;) */
5151
5152 got_token:
5153
5154 /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */
5155 token[token_index] = '\0';
5156
5157 /* Check to see what thing we should return. If the last_read_token
5158 is a `<', or a `&', or the character which ended this token is
5159 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
5160 Otherwise, it is just a word, and should be returned as such. */
5161 if MBTEST(all_digit_token && (character == '<' || character == '>' ||
5162 last_read_token == LESS_AND ||
5163 last_read_token == GREATER_AND))
5164 {
5165 if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
5166 {
5167 yylval.number = lvalue;
5168 return (NUMBER);
5169 }
5170 }
5171
5172 /* Check for special case tokens. */
5173 result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
5174 if (result >= 0)
5175 return result;
5176
5177 #if defined (ALIAS)
5178 /* Posix.2 does not allow reserved words to be aliased, so check for all
5179 of them, including special cases, before expanding the current token
5180 as an alias. */
5181 if MBTEST(posixly_correct)
5182 CHECK_FOR_RESERVED_WORD (token);
5183
5184 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
5185 inhibits alias expansion. */
5186 if (expand_aliases && quoted == 0)
5187 {
5188 result = alias_expand_token (token);
5189 if (result == RE_READ_TOKEN)
5190 return (RE_READ_TOKEN);
5191 else if (result == NO_EXPANSION)
5192 parser_state &= ~PST_ALEXPNEXT;
5193 }
5194
5195 /* If not in Posix.2 mode, check for reserved words after alias
5196 expansion. */
5197 if MBTEST(posixly_correct == 0)
5198 #endif
5199 CHECK_FOR_RESERVED_WORD (token);
5200
5201 the_word = alloc_word_desc ();
5202 the_word->word = (char *)xmalloc (1 + token_index);
5203 the_word->flags = 0;
5204 strcpy (the_word->word, token);
5205 if (dollar_present)
5206 the_word->flags |= W_HASDOLLAR;
5207 if (quoted)
5208 the_word->flags |= W_QUOTED; /*(*/
5209 if (compound_assignment && token[token_index-1] == ')')
5210 the_word->flags |= W_COMPASSIGN;
5211 /* A word is an assignment if it appears at the beginning of a
5212 simple command, or after another assignment word. This is
5213 context-dependent, so it cannot be handled in the grammar. */
5214 if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
5215 {
5216 the_word->flags |= W_ASSIGNMENT;
5217 /* Don't perform word splitting on assignment statements. */
5218 if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
5219 {
5220 the_word->flags |= W_NOSPLIT;
5221 if (parser_state & PST_COMPASSIGN)
5222 the_word->flags |= W_NOGLOB; /* XXX - W_NOBRACE? */
5223 }
5224 }
5225
5226 if (command_token_position (last_read_token))
5227 {
5228 struct builtin *b;
5229 b = builtin_address_internal (token, 0);
5230 if (b && (b->flags & ASSIGNMENT_BUILTIN))
5231 parser_state |= PST_ASSIGNOK;
5232 else if (STREQ (token, "eval") || STREQ (token, "let"))
5233 parser_state |= PST_ASSIGNOK;
5234 }
5235
5236 yylval.word = the_word;
5237
5238 /* should we check that quoted == 0 as well? */
5239 if MBTEST(token[0] == '{' && token[token_index-1] == '}' &&
5240 (character == '<' || character == '>'))
5241 {
5242 /* can use token; already copied to the_word */
5243 token[token_index-1] = '\0';
5244 #if defined (ARRAY_VARS)
5245 if (legal_identifier (token+1) || valid_array_reference (token+1, 0))
5246 #else
5247 if (legal_identifier (token+1))
5248 #endif
5249 {
5250 strcpy (the_word->word, token+1);
5251 /* itrace("read_token_word: returning REDIR_WORD for %s", the_word->word); */
5252 yylval.word = the_word; /* accommodate recursive call */
5253 return (REDIR_WORD);
5254 }
5255 else
5256 /* valid_array_reference can call the parser recursively; need to
5257 make sure that yylval.word doesn't change if we are going to
5258 return WORD or ASSIGNMENT_WORD */
5259 yylval.word = the_word;
5260 }
5261
5262 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
5263 ? ASSIGNMENT_WORD : WORD;
5264
5265 switch (last_read_token)
5266 {
5267 case FUNCTION:
5268 parser_state |= PST_ALLOWOPNBRC;
5269 function_dstart = line_number;
5270 break;
5271 case CASE:
5272 case SELECT:
5273 case FOR:
5274 if (word_top < MAX_CASE_NEST)
5275 word_top++;
5276 word_lineno[word_top] = line_number;
5277 expecting_in_token++;
5278 break;
5279 }
5280
5281 return (result);
5282 }
5283
5284 /* Return 1 if TOKSYM is a token that after being read would allow
5285 a reserved word to be seen, else 0. */
5286 static int
5287 reserved_word_acceptable (toksym)
5288 int toksym;
5289 {
5290 switch (toksym)
5291 {
5292 case '\n':
5293 case ';':
5294 case '(':
5295 case ')':
5296 case '|':
5297 case '&':
5298 case '{':
5299 case '}': /* XXX */
5300 case AND_AND:
5301 case ARITH_CMD:
5302 case BANG:
5303 case BAR_AND:
5304 case COND_END:
5305 case DO:
5306 case DONE:
5307 case ELIF:
5308 case ELSE:
5309 case ESAC:
5310 case FI:
5311 case IF:
5312 case OR_OR:
5313 case SEMI_SEMI:
5314 case SEMI_AND:
5315 case SEMI_SEMI_AND:
5316 case THEN:
5317 case TIME:
5318 case TIMEOPT:
5319 case TIMEIGN:
5320 case COPROC:
5321 case UNTIL:
5322 case WHILE:
5323 case 0:
5324 case DOLPAREN:
5325 return 1;
5326 default:
5327 #if defined (COPROCESS_SUPPORT)
5328 if (last_read_token == WORD && token_before_that == COPROC)
5329 return 1;
5330 #endif
5331 if (last_read_token == WORD && token_before_that == FUNCTION)
5332 return 1;
5333 return 0;
5334 }
5335 }
5336
5337 /* Return the index of TOKEN in the alist of reserved words, or -1 if
5338 TOKEN is not a shell reserved word. */
5339 int
5340 find_reserved_word (tokstr)
5341 char *tokstr;
5342 {
5343 int i;
5344 for (i = 0; word_token_alist[i].word; i++)
5345 if (STREQ (tokstr, word_token_alist[i].word))
5346 return i;
5347 return -1;
5348 }
5349
5350 /* An interface to let the rest of the shell (primarily the completion
5351 system) know what the parser is expecting. */
5352 int
5353 parser_in_command_position ()
5354 {
5355 return (command_token_position (last_read_token));
5356 }
5357
5358 #if 0
5359 #if defined (READLINE)
5360 /* Called after each time readline is called. This insures that whatever
5361 the new prompt string is gets propagated to readline's local prompt
5362 variable. */
5363 static void
5364 reset_readline_prompt ()
5365 {
5366 char *temp_prompt;
5367
5368 if (prompt_string_pointer)
5369 {
5370 temp_prompt = (*prompt_string_pointer)
5371 ? decode_prompt_string (*prompt_string_pointer)
5372 : (char *)NULL;
5373
5374 if (temp_prompt == 0)
5375 {
5376 temp_prompt = (char *)xmalloc (1);
5377 temp_prompt[0] = '\0';
5378 }
5379
5380 FREE (current_readline_prompt);
5381 current_readline_prompt = temp_prompt;
5382 }
5383 }
5384 #endif /* READLINE */
5385 #endif /* 0 */
5386
5387 #if defined (HISTORY)
5388 /* A list of tokens which can be followed by newlines, but not by
5389 semi-colons. When concatenating multiple lines of history, the
5390 newline separator for such tokens is replaced with a space. */
5391 static const int no_semi_successors[] = {
5392 '\n', '{', '(', ')', ';', '&', '|',
5393 CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
5394 WHILE, AND_AND, OR_OR, IN,
5395 0
5396 };
5397
5398 /* If we are not within a delimited expression, try to be smart
5399 about which separators can be semi-colons and which must be
5400 newlines. Returns the string that should be added into the
5401 history entry. LINE is the line we're about to add; it helps
5402 make some more intelligent decisions in certain cases. */
5403 char *
5404 history_delimiting_chars (line)
5405 const char *line;
5406 {
5407 static int last_was_heredoc = 0; /* was the last entry the start of a here document? */
5408 register int i;
5409
5410 if ((parser_state & PST_HEREDOC) == 0)
5411 last_was_heredoc = 0;
5412
5413 if (dstack.delimiter_depth != 0)
5414 return ("\n");
5415
5416 /* We look for current_command_line_count == 2 because we are looking to
5417 add the first line of the body of the here document (the second line
5418 of the command). We also keep LAST_WAS_HEREDOC as a private sentinel
5419 variable to note when we think we added the first line of a here doc
5420 (the one with a "<<" somewhere in it) */
5421 if (parser_state & PST_HEREDOC)
5422 {
5423 if (last_was_heredoc)
5424 {
5425 last_was_heredoc = 0;
5426 return "\n";
5427 }
5428 return (here_doc_first_line ? "\n" : "");
5429 }
5430
5431 if (parser_state & PST_COMPASSIGN)
5432 return (" ");
5433
5434 /* First, handle some special cases. */
5435 /*(*/
5436 /* If we just read `()', assume it's a function definition, and don't
5437 add a semicolon. If the token before the `)' was not `(', and we're
5438 not in the midst of parsing a case statement, assume it's a
5439 parenthesized command and add the semicolon. */
5440 /*)(*/
5441 if (token_before_that == ')')
5442 {
5443 if (two_tokens_ago == '(') /*)*/ /* function def */
5444 return " ";
5445 /* This does not work for subshells inside case statement
5446 command lists. It's a suboptimal solution. */
5447 else if (parser_state & PST_CASESTMT) /* case statement pattern */
5448 return " ";
5449 else
5450 return "; "; /* (...) subshell */
5451 }
5452 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
5453 return " "; /* function def using `function name' without `()' */
5454
5455 /* If we're not in a here document, but we think we're about to parse one,
5456 and we would otherwise return a `;', return a newline to delimit the
5457 line with the here-doc delimiter */
5458 else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
5459 {
5460 last_was_heredoc = 1;
5461 return "\n";
5462 }
5463 else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && need_here_doc > 0)
5464 return "\n";
5465 else if (token_before_that == WORD && two_tokens_ago == FOR)
5466 {
5467 /* Tricky. `for i\nin ...' should not have a semicolon, but
5468 `for i\ndo ...' should. We do what we can. */
5469 for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
5470 ;
5471 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
5472 return " ";
5473 return ";";
5474 }
5475 else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
5476 return " ";
5477
5478 for (i = 0; no_semi_successors[i]; i++)
5479 {
5480 if (token_before_that == no_semi_successors[i])
5481 return (" ");
5482 }
5483
5484 /* Assume that by this point we are reading lines in a multi-line command.
5485 If we have multiple consecutive blank lines we want to return only one
5486 semicolon. */
5487 if (line_isblank (line))
5488 return (current_command_line_count > 1 && last_read_token == '\n' && token_before_that != '\n') ? "; " : "";
5489
5490 return ("; ");
5491 }
5492 #endif /* HISTORY */
5493
5494 /* Issue a prompt, or prepare to issue a prompt when the next character
5495 is read. */
5496 static void
5497 prompt_again (force)
5498 int force;
5499 {
5500 char *temp_prompt;
5501
5502 if (interactive == 0 || expanding_alias ()) /* XXX */
5503 return;
5504
5505 ps1_prompt = get_string_value ("PS1");
5506 ps2_prompt = get_string_value ("PS2");
5507
5508 ps0_prompt = get_string_value ("PS0");
5509
5510 if (!prompt_string_pointer)
5511 prompt_string_pointer = &ps1_prompt;
5512
5513 temp_prompt = *prompt_string_pointer
5514 ? decode_prompt_string (*prompt_string_pointer)
5515 : (char *)NULL;
5516
5517 if (temp_prompt == 0)
5518 {
5519 temp_prompt = (char *)xmalloc (1);
5520 temp_prompt[0] = '\0';
5521 }
5522
5523 current_prompt_string = *prompt_string_pointer;
5524 prompt_string_pointer = &ps2_prompt;
5525
5526 #if defined (READLINE)
5527 if (!no_line_editing)
5528 {
5529 FREE (current_readline_prompt);
5530 current_readline_prompt = temp_prompt;
5531 }
5532 else
5533 #endif /* READLINE */
5534 {
5535 FREE (current_decoded_prompt);
5536 current_decoded_prompt = temp_prompt;
5537 }
5538 }
5539
5540 int
5541 get_current_prompt_level ()
5542 {
5543 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
5544 }
5545
5546 void
5547 set_current_prompt_level (x)
5548 int x;
5549 {
5550 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
5551 current_prompt_string = *prompt_string_pointer;
5552 }
5553
5554 static void
5555 print_prompt ()
5556 {
5557 fprintf (stderr, "%s", current_decoded_prompt);
5558 fflush (stderr);
5559 }
5560
5561 #if defined (HISTORY)
5562 /* The history library increments the history offset as soon as it stores
5563 the first line of a potentially multi-line command, so we compensate
5564 here by returning one fewer when appropriate. */
5565 static int
5566 prompt_history_number (pmt)
5567 char *pmt;
5568 {
5569 int ret;
5570
5571 ret = history_number ();
5572 if (ret == 1)
5573 return ret;
5574
5575 if (pmt == ps1_prompt) /* are we expanding $PS1? */
5576 return ret;
5577 else if (pmt == ps2_prompt && command_oriented_history == 0)
5578 return ret; /* not command oriented history */
5579 else if (pmt == ps2_prompt && command_oriented_history && current_command_first_line_saved)
5580 return ret - 1;
5581 else
5582 return ret - 1; /* PS0, PS4, ${var@P}, PS2 other cases */
5583 }
5584 #endif
5585
5586 /* Return a string which will be printed as a prompt. The string
5587 may contain special characters which are decoded as follows:
5588
5589 \a bell (ascii 07)
5590 \d the date in Day Mon Date format
5591 \e escape (ascii 033)
5592 \h the hostname up to the first `.'
5593 \H the hostname
5594 \j the number of active jobs
5595 \l the basename of the shell's tty device name
5596 \n CRLF
5597 \r CR
5598 \s the name of the shell
5599 \t the time in 24-hour hh:mm:ss format
5600 \T the time in 12-hour hh:mm:ss format
5601 \@ the time in 12-hour hh:mm am/pm format
5602 \A the time in 24-hour hh:mm format
5603 \D{fmt} the result of passing FMT to strftime(3)
5604 \u your username
5605 \v the version of bash (e.g., 2.00)
5606 \V the release of bash, version + patchlevel (e.g., 2.00.0)
5607 \w the current working directory
5608 \W the last element of $PWD
5609 \! the history number of this command
5610 \# the command number of this command
5611 \$ a $ or a # if you are root
5612 \nnn character code nnn in octal
5613 \\ a backslash
5614 \[ begin a sequence of non-printing chars
5615 \] end a sequence of non-printing chars
5616 */
5617 #define PROMPT_GROWTH 48
5618 char *
5619 decode_prompt_string (string)
5620 char *string;
5621 {
5622 WORD_LIST *list;
5623 char *result, *t, *orig_string;
5624 struct dstack save_dstack;
5625 int last_exit_value, last_comsub_pid;
5626 #if defined (PROMPT_STRING_DECODE)
5627 size_t result_size;
5628 size_t result_index;
5629 int c, n, i;
5630 char *temp, *t_host, octal_string[4];
5631 struct tm *tm;
5632 time_t the_time;
5633 char timebuf[128];
5634 char *timefmt;
5635
5636 result = (char *)xmalloc (result_size = PROMPT_GROWTH);
5637 result[result_index = 0] = 0;
5638 temp = (char *)NULL;
5639 orig_string = string;
5640
5641 while (c = *string++)
5642 {
5643 if (posixly_correct && c == '!')
5644 {
5645 if (*string == '!')
5646 {
5647 temp = savestring ("!");
5648 goto add_string;
5649 }
5650 else
5651 {
5652 #if !defined (HISTORY)
5653 temp = savestring ("1");
5654 #else /* HISTORY */
5655 temp = itos (prompt_history_number (orig_string));
5656 #endif /* HISTORY */
5657 string--; /* add_string increments string again. */
5658 goto add_string;
5659 }
5660 }
5661 if (c == '\\')
5662 {
5663 c = *string;
5664
5665 switch (c)
5666 {
5667 case '0':
5668 case '1':
5669 case '2':
5670 case '3':
5671 case '4':
5672 case '5':
5673 case '6':
5674 case '7':
5675 strncpy (octal_string, string, 3);
5676 octal_string[3] = '\0';
5677
5678 n = read_octal (octal_string);
5679 temp = (char *)xmalloc (3);
5680
5681 if (n == CTLESC || n == CTLNUL)
5682 {
5683 temp[0] = CTLESC;
5684 temp[1] = n;
5685 temp[2] = '\0';
5686 }
5687 else if (n == -1)
5688 {
5689 temp[0] = '\\';
5690 temp[1] = '\0';
5691 }
5692 else
5693 {
5694 temp[0] = n;
5695 temp[1] = '\0';
5696 }
5697
5698 for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
5699 string++;
5700
5701 c = 0; /* tested at add_string: */
5702 goto add_string;
5703
5704 case 'd':
5705 case 't':
5706 case 'T':
5707 case '@':
5708 case 'A':
5709 /* Make the current time/date into a string. */
5710 (void) time (&the_time);
5711 #if defined (HAVE_TZSET)
5712 sv_tz ("TZ"); /* XXX -- just make sure */
5713 #endif
5714 tm = localtime (&the_time);
5715
5716 if (c == 'd')
5717 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
5718 else if (c == 't')
5719 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
5720 else if (c == 'T')
5721 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
5722 else if (c == '@')
5723 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
5724 else if (c == 'A')
5725 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
5726
5727 if (n == 0)
5728 timebuf[0] = '\0';
5729 else
5730 timebuf[sizeof(timebuf) - 1] = '\0';
5731
5732 temp = savestring (timebuf);
5733 goto add_string;
5734
5735 case 'D': /* strftime format */
5736 if (string[1] != '{') /* } */
5737 goto not_escape;
5738
5739 (void) time (&the_time);
5740 tm = localtime (&the_time);
5741 string += 2; /* skip { */
5742 timefmt = xmalloc (strlen (string) + 3);
5743 for (t = timefmt; *string && *string != '}'; )
5744 *t++ = *string++;
5745 *t = '\0';
5746 c = *string; /* tested at add_string */
5747 if (timefmt[0] == '\0')
5748 {
5749 timefmt[0] = '%';
5750 timefmt[1] = 'X'; /* locale-specific current time */
5751 timefmt[2] = '\0';
5752 }
5753 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
5754 free (timefmt);
5755
5756 if (n == 0)
5757 timebuf[0] = '\0';
5758 else
5759 timebuf[sizeof(timebuf) - 1] = '\0';
5760
5761 if (promptvars || posixly_correct)
5762 /* Make sure that expand_prompt_string is called with a
5763 second argument of Q_DOUBLE_QUOTES if we use this
5764 function here. */
5765 temp = sh_backslash_quote_for_double_quotes (timebuf, 0);
5766 else
5767 temp = savestring (timebuf);
5768 goto add_string;
5769
5770 case 'n':
5771 temp = (char *)xmalloc (3);
5772 temp[0] = no_line_editing ? '\n' : '\r';
5773 temp[1] = no_line_editing ? '\0' : '\n';
5774 temp[2] = '\0';
5775 goto add_string;
5776
5777 case 's':
5778 temp = base_pathname (shell_name);
5779 /* Try to quote anything the user can set in the file system */
5780 if (promptvars || posixly_correct)
5781 {
5782 char *t;
5783 t = sh_strvis (temp);
5784 temp = sh_backslash_quote_for_double_quotes (t, 0);
5785 free (t);
5786 }
5787 else
5788 temp = sh_strvis (temp);
5789 goto add_string;
5790
5791 case 'v':
5792 case 'V':
5793 temp = (char *)xmalloc (16);
5794 if (c == 'v')
5795 strcpy (temp, dist_version);
5796 else
5797 sprintf (temp, "%s.%d", dist_version, patch_level);
5798 goto add_string;
5799
5800 case 'w':
5801 case 'W':
5802 {
5803 /* Use the value of PWD because it is much more efficient. */
5804 char t_string[PATH_MAX];
5805 int tlen;
5806
5807 temp = get_string_value ("PWD");
5808
5809 if (temp == 0)
5810 {
5811 if (getcwd (t_string, sizeof(t_string)) == 0)
5812 {
5813 t_string[0] = '.';
5814 tlen = 1;
5815 }
5816 else
5817 tlen = strlen (t_string);
5818 }
5819 else
5820 {
5821 tlen = sizeof (t_string) - 1;
5822 strncpy (t_string, temp, tlen);
5823 }
5824 t_string[tlen] = '\0';
5825
5826 #if defined (MACOSX)
5827 /* Convert from "fs" format to "input" format */
5828 temp = fnx_fromfs (t_string, strlen (t_string));
5829 if (temp != t_string)
5830 strcpy (t_string, temp);
5831 #endif
5832
5833 #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
5834 #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
5835 /* Abbreviate \W as ~ if $PWD == $HOME */
5836 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
5837 {
5838 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
5839 {
5840 t = strrchr (t_string, '/');
5841 if (t)
5842 memmove (t_string, t + 1, strlen (t)); /* strlen(t) to copy NULL */
5843 }
5844 }
5845 #undef ROOT_PATH
5846 #undef DOUBLE_SLASH_ROOT
5847 else
5848 {
5849 /* polite_directory_format is guaranteed to return a string
5850 no longer than PATH_MAX - 1 characters. */
5851 temp = polite_directory_format (t_string);
5852 if (temp != t_string)
5853 strcpy (t_string, temp);
5854 }
5855
5856 temp = trim_pathname (t_string, PATH_MAX - 1);
5857 /* If we're going to be expanding the prompt string later,
5858 quote the directory name. */
5859 if (promptvars || posixly_correct)
5860 /* Make sure that expand_prompt_string is called with a
5861 second argument of Q_DOUBLE_QUOTES if we use this
5862 function here. */
5863 {
5864 char *t;
5865 t = sh_strvis (t_string);
5866 temp = sh_backslash_quote_for_double_quotes (t, 0);
5867 free (t);
5868 }
5869 else
5870 temp = sh_strvis (t_string);
5871
5872 goto add_string;
5873 }
5874
5875 case 'u':
5876 if (current_user.user_name == 0)
5877 get_current_user_info ();
5878 temp = savestring (current_user.user_name);
5879 goto add_string;
5880
5881 case 'h':
5882 case 'H':
5883 t_host = savestring (current_host_name);
5884 if (c == 'h' && (t = (char *)strchr (t_host, '.')))
5885 *t = '\0';
5886 if (promptvars || posixly_correct)
5887 /* Make sure that expand_prompt_string is called with a
5888 second argument of Q_DOUBLE_QUOTES if we use this
5889 function here. */
5890 temp = sh_backslash_quote_for_double_quotes (t_host, 0);
5891 else
5892 temp = savestring (t_host);
5893 free (t_host);
5894 goto add_string;
5895
5896 case '#':
5897 n = current_command_number;
5898 /* If we have already incremented current_command_number (PS4,
5899 ${var@P}), compensate */
5900 if (orig_string != ps0_prompt && orig_string != ps1_prompt && orig_string != ps2_prompt)
5901 n--;
5902 temp = itos (n);
5903 goto add_string;
5904
5905 case '!':
5906 #if !defined (HISTORY)
5907 temp = savestring ("1");
5908 #else /* HISTORY */
5909 temp = itos (prompt_history_number (orig_string));
5910 #endif /* HISTORY */
5911 goto add_string;
5912
5913 case '$':
5914 t = temp = (char *)xmalloc (3);
5915 if ((promptvars || posixly_correct) && (current_user.euid != 0))
5916 *t++ = '\\';
5917 *t++ = current_user.euid == 0 ? '#' : '$';
5918 *t = '\0';
5919 goto add_string;
5920
5921 case 'j':
5922 temp = itos (count_all_jobs ());
5923 goto add_string;
5924
5925 case 'l':
5926 #if defined (HAVE_TTYNAME)
5927 temp = (char *)ttyname (fileno (stdin));
5928 t = temp ? base_pathname (temp) : "tty";
5929 temp = savestring (t);
5930 #else
5931 temp = savestring ("tty");
5932 #endif /* !HAVE_TTYNAME */
5933 goto add_string;
5934
5935 #if defined (READLINE)
5936 case '[':
5937 case ']':
5938 if (no_line_editing)
5939 {
5940 string++;
5941 break;
5942 }
5943 temp = (char *)xmalloc (3);
5944 n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
5945 i = 0;
5946 if (n == CTLESC || n == CTLNUL)
5947 temp[i++] = CTLESC;
5948 temp[i++] = n;
5949 temp[i] = '\0';
5950 goto add_string;
5951 #endif /* READLINE */
5952
5953 case '\\':
5954 case 'a':
5955 case 'e':
5956 case 'r':
5957 temp = (char *)xmalloc (2);
5958 if (c == 'a')
5959 temp[0] = '\07';
5960 else if (c == 'e')
5961 temp[0] = '\033';
5962 else if (c == 'r')
5963 temp[0] = '\r';
5964 else /* (c == '\\') */
5965 temp[0] = c;
5966 temp[1] = '\0';
5967 goto add_string;
5968
5969 default:
5970 not_escape:
5971 temp = (char *)xmalloc (3);
5972 temp[0] = '\\';
5973 temp[1] = c;
5974 temp[2] = '\0';
5975
5976 add_string:
5977 if (c)
5978 string++;
5979 result =
5980 sub_append_string (temp, result, &result_index, &result_size);
5981 temp = (char *)NULL; /* Freed in sub_append_string (). */
5982 result[result_index] = '\0';
5983 break;
5984 }
5985 }
5986 else
5987 {
5988 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
5989 /* dequote_string should take care of removing this if we are not
5990 performing the rest of the word expansions. */
5991 if (c == CTLESC || c == CTLNUL)
5992 result[result_index++] = CTLESC;
5993 result[result_index++] = c;
5994 result[result_index] = '\0';
5995 }
5996 }
5997 #else /* !PROMPT_STRING_DECODE */
5998 result = savestring (string);
5999 #endif /* !PROMPT_STRING_DECODE */
6000
6001 /* Save the delimiter stack and point `dstack' to temp space so any
6002 command substitutions in the prompt string won't result in screwing
6003 up the parser's quoting state. */
6004 save_dstack = dstack;
6005 dstack = temp_dstack;
6006 dstack.delimiter_depth = 0;
6007
6008 /* Perform variable and parameter expansion and command substitution on
6009 the prompt string. */
6010 if (promptvars || posixly_correct)
6011 {
6012 last_exit_value = last_command_exit_value;
6013 last_comsub_pid = last_command_subst_pid;
6014 list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
6015 free (result);
6016 result = string_list (list);
6017 dispose_words (list);
6018 last_command_exit_value = last_exit_value;
6019 last_command_subst_pid = last_comsub_pid;
6020 }
6021 else
6022 {
6023 t = dequote_string (result);
6024 free (result);
6025 result = t;
6026 }
6027
6028 dstack = save_dstack;
6029
6030 return (result);
6031 }
6032
6033 /************************************************
6034 * *
6035 * ERROR HANDLING *
6036 * *
6037 ************************************************/
6038
6039 /* Report a syntax error, and restart the parser. Call here for fatal
6040 errors. */
6041 int
6042 yyerror (msg)
6043 const char *msg;
6044 {
6045 if ((parser_state & PST_NOERROR) == 0)
6046 report_syntax_error ((char *)NULL);
6047 reset_parser ();
6048 return (0);
6049 }
6050
6051 static char *
6052 error_token_from_token (tok)
6053 int tok;
6054 {
6055 char *t;
6056
6057 if (t = find_token_in_alist (tok, word_token_alist, 0))
6058 return t;
6059
6060 if (t = find_token_in_alist (tok, other_token_alist, 0))
6061 return t;
6062
6063 t = (char *)NULL;
6064 /* This stuff is dicy and needs closer inspection */
6065 switch (current_token)
6066 {
6067 case WORD:
6068 case ASSIGNMENT_WORD:
6069 if (yylval.word)
6070 t = savestring (yylval.word->word);
6071 break;
6072 case NUMBER:
6073 t = itos (yylval.number);
6074 break;
6075 case ARITH_CMD:
6076 if (yylval.word_list)
6077 t = string_list (yylval.word_list);
6078 break;
6079 case ARITH_FOR_EXPRS:
6080 if (yylval.word_list)
6081 t = string_list_internal (yylval.word_list, " ; ");
6082 break;
6083 case COND_CMD:
6084 t = (char *)NULL; /* punt */
6085 break;
6086 }
6087
6088 return t;
6089 }
6090
6091 static char *
6092 error_token_from_text ()
6093 {
6094 char *msg, *t;
6095 int token_end, i;
6096
6097 t = shell_input_line;
6098 i = shell_input_line_index;
6099 token_end = 0;
6100 msg = (char *)NULL;
6101
6102 if (i && t[i] == '\0')
6103 i--;
6104
6105 while (i && (whitespace (t[i]) || t[i] == '\n'))
6106 i--;
6107
6108 if (i)
6109 token_end = i + 1;
6110
6111 while (i && (member (t[i], " \n\t;|&") == 0))
6112 i--;
6113
6114 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
6115 i++;
6116
6117 /* Return our idea of the offending token. */
6118 if (token_end || (i == 0 && token_end == 0))
6119 {
6120 if (token_end)
6121 msg = substring (t, i, token_end);
6122 else /* one-character token */
6123 {
6124 msg = (char *)xmalloc (2);
6125 msg[0] = t[i];
6126 msg[1] = '\0';
6127 }
6128 }
6129
6130 return (msg);
6131 }
6132
6133 static void
6134 print_offending_line ()
6135 {
6136 char *msg;
6137 int token_end;
6138
6139 msg = savestring (shell_input_line);
6140 token_end = strlen (msg);
6141 while (token_end && msg[token_end - 1] == '\n')
6142 msg[--token_end] = '\0';
6143
6144 parser_error (line_number, "`%s'", msg);
6145 free (msg);
6146 }
6147
6148 /* Report a syntax error with line numbers, etc.
6149 Call here for recoverable errors. If you have a message to print,
6150 then place it in MESSAGE, otherwise pass NULL and this will figure
6151 out an appropriate message for you. */
6152 static void
6153 report_syntax_error (message)
6154 char *message;
6155 {
6156 char *msg, *p;
6157
6158 if (message)
6159 {
6160 parser_error (line_number, "%s", message);
6161 if (interactive && EOF_Reached)
6162 EOF_Reached = 0;
6163 last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE;
6164 set_pipestatus_from_exit (last_command_exit_value);
6165 return;
6166 }
6167
6168 /* If the line of input we're reading is not null, try to find the
6169 objectionable token. First, try to figure out what token the
6170 parser's complaining about by looking at current_token. */
6171 if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
6172 {
6173 if (ansic_shouldquote (msg))
6174 {
6175 p = ansic_quote (msg, 0, NULL);
6176 free (msg);
6177 msg = p;
6178 }
6179 parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
6180 free (msg);
6181
6182 if (interactive == 0)
6183 print_offending_line ();
6184
6185 last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE;
6186 set_pipestatus_from_exit (last_command_exit_value);
6187 return;
6188 }
6189
6190 /* If looking at the current token doesn't prove fruitful, try to find the
6191 offending token by analyzing the text of the input line near the current
6192 input line index and report what we find. */
6193 if (shell_input_line && *shell_input_line)
6194 {
6195 msg = error_token_from_text ();
6196 if (msg)
6197 {
6198 parser_error (line_number, _("syntax error near `%s'"), msg);
6199 free (msg);
6200 }
6201
6202 /* If not interactive, print the line containing the error. */
6203 if (interactive == 0)
6204 print_offending_line ();
6205 }
6206 else
6207 {
6208 if (EOF_Reached && shell_eof_token && current_token != shell_eof_token)
6209 parser_error (line_number, _("unexpected EOF while looking for matching `%c'"), shell_eof_token);
6210 else
6211 {
6212 msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
6213 parser_error (line_number, "%s", msg);
6214 }
6215
6216 /* When the shell is interactive, this file uses EOF_Reached
6217 only for error reporting. Other mechanisms are used to
6218 decide whether or not to exit. */
6219 if (interactive && EOF_Reached)
6220 EOF_Reached = 0;
6221 }
6222
6223 last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE;
6224 set_pipestatus_from_exit (last_command_exit_value);
6225 }
6226
6227 /* ??? Needed function. ??? We have to be able to discard the constructs
6228 created during parsing. In the case of error, we want to return
6229 allocated objects to the memory pool. In the case of no error, we want
6230 to throw away the information about where the allocated objects live.
6231 (dispose_command () will actually free the command.) */
6232 static void
6233 discard_parser_constructs (error_p)
6234 int error_p;
6235 {
6236 }
6237
6238 /************************************************
6239 * *
6240 * EOF HANDLING *
6241 * *
6242 ************************************************/
6243
6244 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
6245
6246 /* A flag denoting whether or not ignoreeof is set. */
6247 int ignoreeof = 0;
6248
6249 /* The number of times that we have encountered an EOF character without
6250 another character intervening. When this gets above the limit, the
6251 shell terminates. */
6252 int eof_encountered = 0;
6253
6254 /* The limit for eof_encountered. */
6255 int eof_encountered_limit = 10;
6256
6257 /* If we have EOF as the only input unit, this user wants to leave
6258 the shell. If the shell is not interactive, then just leave.
6259 Otherwise, if ignoreeof is set, and we haven't done this the
6260 required number of times in a row, print a message. */
6261 static void
6262 handle_eof_input_unit ()
6263 {
6264 if (interactive)
6265 {
6266 /* shell.c may use this to decide whether or not to write out the
6267 history, among other things. We use it only for error reporting
6268 in this file. */
6269 if (EOF_Reached)
6270 EOF_Reached = 0;
6271
6272 /* If the user wants to "ignore" eof, then let her do so, kind of. */
6273 if (ignoreeof)
6274 {
6275 if (eof_encountered < eof_encountered_limit)
6276 {
6277 fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
6278 login_shell ? "logout" : "exit");
6279 eof_encountered++;
6280 /* Reset the parsing state. */
6281 last_read_token = current_token = '\n';
6282 /* Reset the prompt string to be $PS1. */
6283 prompt_string_pointer = (char **)NULL;
6284 prompt_again (0);
6285 return;
6286 }
6287 }
6288
6289 /* In this case EOF should exit the shell. Do it now. */
6290 reset_parser ();
6291
6292 last_shell_builtin = this_shell_builtin;
6293 this_shell_builtin = exit_builtin;
6294 exit_builtin ((WORD_LIST *)NULL);
6295 }
6296 else
6297 {
6298 /* We don't write history files, etc., for non-interactive shells. */
6299 EOF_Reached = 1;
6300 }
6301 }
6302
6303 /************************************************
6304 * *
6305 * STRING PARSING FUNCTIONS *
6306 * *
6307 ************************************************/
6308
6309 /* It's very important that these two functions treat the characters
6310 between ( and ) identically. */
6311
6312 static WORD_LIST parse_string_error;
6313
6314 /* Take a string and run it through the shell parser, returning the
6315 resultant word list. Used by compound array assignment. */
6316 WORD_LIST *
6317 parse_string_to_word_list (s, flags, whom)
6318 char *s;
6319 int flags;
6320 const char *whom;
6321 {
6322 WORD_LIST *wl;
6323 int tok, orig_current_token, orig_line_number;
6324 int orig_parser_state;
6325 sh_parser_state_t ps;
6326 int ea;
6327
6328 orig_line_number = line_number;
6329 save_parser_state (&ps);
6330
6331 #if defined (HISTORY)
6332 bash_history_disable ();
6333 #endif
6334
6335 push_stream (1);
6336 if (ea = expanding_alias ())
6337 parser_save_alias ();
6338
6339 /* WORD to avoid parsing reserved words as themselves and just parse them as
6340 WORDs. */
6341 last_read_token = WORD;
6342
6343 current_command_line_count = 0;
6344 echo_input_at_read = expand_aliases = 0;
6345
6346 with_input_from_string (s, whom);
6347 wl = (WORD_LIST *)NULL;
6348
6349 if (flags & 1)
6350 {
6351 orig_parser_state = parser_state; /* XXX - not needed? */
6352 /* State flags we don't want to persist into compound assignments. */
6353 parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */
6354 /* State flags we want to set for this run through the tokenizer. */
6355 parser_state |= PST_COMPASSIGN|PST_REPARSE;
6356 }
6357
6358 while ((tok = read_token (READ)) != yacc_EOF)
6359 {
6360 if (tok == '\n' && *bash_input.location.string == '\0')
6361 break;
6362 if (tok == '\n') /* Allow newlines in compound assignments */
6363 continue;
6364 if (tok != WORD && tok != ASSIGNMENT_WORD)
6365 {
6366 line_number = orig_line_number + line_number - 1;
6367 orig_current_token = current_token;
6368 current_token = tok;
6369 yyerror (NULL); /* does the right thing */
6370 current_token = orig_current_token;
6371 if (wl)
6372 dispose_words (wl);
6373 wl = &parse_string_error;
6374 break;
6375 }
6376 wl = make_word_list (yylval.word, wl);
6377 }
6378
6379 last_read_token = '\n';
6380 pop_stream ();
6381
6382 if (ea)
6383 parser_restore_alias ();
6384
6385 restore_parser_state (&ps);
6386
6387 if (flags & 1)
6388 parser_state = orig_parser_state; /* XXX - not needed? */
6389
6390 if (wl == &parse_string_error)
6391 {
6392 set_exit_status (EXECUTION_FAILURE);
6393 if (interactive_shell == 0 && posixly_correct)
6394 jump_to_top_level (FORCE_EOF);
6395 else
6396 jump_to_top_level (DISCARD);
6397 }
6398
6399 return (REVERSE_LIST (wl, WORD_LIST *));
6400 }
6401
6402 static char *
6403 parse_compound_assignment (retlenp)
6404 int *retlenp;
6405 {
6406 WORD_LIST *wl, *rl;
6407 int tok, orig_line_number, assignok;
6408 sh_parser_state_t ps;
6409 char *ret;
6410
6411 orig_line_number = line_number;
6412 save_parser_state (&ps);
6413
6414 /* WORD to avoid parsing reserved words as themselves and just parse them as
6415 WORDs. Plus it means we won't be in a command position and so alias
6416 expansion won't happen. */
6417 last_read_token = WORD;
6418
6419 token = (char *)NULL;
6420 token_buffer_size = 0;
6421 wl = (WORD_LIST *)NULL; /* ( */
6422
6423 assignok = parser_state&PST_ASSIGNOK; /* XXX */
6424
6425 /* State flags we don't want to persist into compound assignments. */
6426 parser_state &= ~(PST_NOEXPAND|PST_CONDCMD|PST_CONDEXPR|PST_REGEXP|PST_EXTPAT);
6427 /* State flags we want to set for this run through the tokenizer. */
6428 parser_state |= PST_COMPASSIGN;
6429
6430 esacs_needed_count = expecting_in_token = 0;
6431
6432 while ((tok = read_token (READ)) != ')')
6433 {
6434 if (tok == '\n') /* Allow newlines in compound assignments */
6435 {
6436 if (SHOULD_PROMPT ())
6437 prompt_again (0);
6438 continue;
6439 }
6440 if (tok != WORD && tok != ASSIGNMENT_WORD)
6441 {
6442 current_token = tok; /* for error reporting */
6443 if (tok == yacc_EOF) /* ( */
6444 parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
6445 else
6446 yyerror(NULL); /* does the right thing */
6447 if (wl)
6448 dispose_words (wl);
6449 wl = &parse_string_error;
6450 break;
6451 }
6452 wl = make_word_list (yylval.word, wl);
6453 }
6454
6455 restore_parser_state (&ps);
6456
6457 if (wl == &parse_string_error)
6458 {
6459 set_exit_status (EXECUTION_FAILURE);
6460 last_read_token = '\n'; /* XXX */
6461 if (interactive_shell == 0 && posixly_correct)
6462 jump_to_top_level (FORCE_EOF);
6463 else
6464 jump_to_top_level (DISCARD);
6465 }
6466
6467 if (wl)
6468 {
6469 rl = REVERSE_LIST (wl, WORD_LIST *);
6470 ret = string_list (rl);
6471 dispose_words (rl);
6472 }
6473 else
6474 ret = (char *)NULL;
6475
6476 if (retlenp)
6477 *retlenp = (ret && *ret) ? strlen (ret) : 0;
6478
6479 if (assignok)
6480 parser_state |= PST_ASSIGNOK;
6481
6482 return ret;
6483 }
6484
6485 /************************************************
6486 * *
6487 * SAVING AND RESTORING PARTIAL PARSE STATE *
6488 * *
6489 ************************************************/
6490
6491 sh_parser_state_t *
6492 save_parser_state (ps)
6493 sh_parser_state_t *ps;
6494 {
6495 if (ps == 0)
6496 ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
6497 if (ps == 0)
6498 return ((sh_parser_state_t *)NULL);
6499
6500 ps->parser_state = parser_state;
6501 ps->token_state = save_token_state ();
6502
6503 ps->input_line_terminator = shell_input_line_terminator;
6504 ps->eof_encountered = eof_encountered;
6505 ps->eol_lookahead = eol_ungetc_lookahead;
6506
6507 ps->prompt_string_pointer = prompt_string_pointer;
6508
6509 ps->current_command_line_count = current_command_line_count;
6510
6511 #if defined (HISTORY)
6512 ps->remember_on_history = remember_on_history;
6513 # if defined (BANG_HISTORY)
6514 ps->history_expansion_inhibited = history_expansion_inhibited;
6515 # endif
6516 #endif
6517
6518 ps->last_command_exit_value = last_command_exit_value;
6519 #if defined (ARRAY_VARS)
6520 ps->pipestatus = save_pipestatus_array ();
6521 #endif
6522
6523 ps->last_shell_builtin = last_shell_builtin;
6524 ps->this_shell_builtin = this_shell_builtin;
6525
6526 ps->expand_aliases = expand_aliases;
6527 ps->echo_input_at_read = echo_input_at_read;
6528 ps->need_here_doc = need_here_doc;
6529 ps->here_doc_first_line = here_doc_first_line;
6530
6531 ps->esacs_needed = esacs_needed_count;
6532 ps->expecting_in = expecting_in_token;
6533
6534 if (need_here_doc == 0)
6535 ps->redir_stack[0] = 0;
6536 else
6537 memcpy (ps->redir_stack, redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
6538
6539 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
6540 ps->pushed_strings = pushed_string_list;
6541 #endif
6542
6543 ps->eof_token = shell_eof_token;
6544 ps->token = token;
6545 ps->token_buffer_size = token_buffer_size;
6546 /* Force reallocation on next call to read_token_word */
6547 token = 0;
6548 token_buffer_size = 0;
6549
6550 return (ps);
6551 }
6552
6553 void
6554 restore_parser_state (ps)
6555 sh_parser_state_t *ps;
6556 {
6557 int i;
6558
6559 if (ps == 0)
6560 return;
6561
6562 parser_state = ps->parser_state;
6563 if (ps->token_state)
6564 {
6565 restore_token_state (ps->token_state);
6566 free (ps->token_state);
6567 }
6568
6569 shell_input_line_terminator = ps->input_line_terminator;
6570 eof_encountered = ps->eof_encountered;
6571 eol_ungetc_lookahead = ps->eol_lookahead;
6572
6573 prompt_string_pointer = ps->prompt_string_pointer;
6574
6575 current_command_line_count = ps->current_command_line_count;
6576
6577 #if defined (HISTORY)
6578 remember_on_history = ps->remember_on_history;
6579 # if defined (BANG_HISTORY)
6580 history_expansion_inhibited = ps->history_expansion_inhibited;
6581 # endif
6582 #endif
6583
6584 last_command_exit_value = ps->last_command_exit_value;
6585 #if defined (ARRAY_VARS)
6586 restore_pipestatus_array (ps->pipestatus);
6587 #endif
6588
6589 last_shell_builtin = ps->last_shell_builtin;
6590 this_shell_builtin = ps->this_shell_builtin;
6591
6592 expand_aliases = ps->expand_aliases;
6593 echo_input_at_read = ps->echo_input_at_read;
6594 need_here_doc = ps->need_here_doc;
6595 here_doc_first_line = ps->here_doc_first_line;
6596
6597 esacs_needed_count = ps->esacs_needed;
6598 expecting_in_token = ps->expecting_in;
6599
6600 #if 0
6601 for (i = 0; i < HEREDOC_MAX; i++)
6602 redir_stack[i] = ps->redir_stack[i];
6603 #else
6604 if (need_here_doc == 0)
6605 redir_stack[0] = 0;
6606 else
6607 memcpy (redir_stack, ps->redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
6608 #endif
6609
6610 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
6611 pushed_string_list = (STRING_SAVER *)ps->pushed_strings;
6612 #endif
6613
6614 FREE (token);
6615 token = ps->token;
6616 token_buffer_size = ps->token_buffer_size;
6617 shell_eof_token = ps->eof_token;
6618 }
6619
6620 sh_input_line_state_t *
6621 save_input_line_state (ls)
6622 sh_input_line_state_t *ls;
6623 {
6624 if (ls == 0)
6625 ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
6626 if (ls == 0)
6627 return ((sh_input_line_state_t *)NULL);
6628
6629 ls->input_line = shell_input_line;
6630 ls->input_line_size = shell_input_line_size;
6631 ls->input_line_len = shell_input_line_len;
6632 ls->input_line_index = shell_input_line_index;
6633
6634 #if defined (HANDLE_MULTIBYTE)
6635 ls->input_property = shell_input_line_property;
6636 ls->input_propsize = shell_input_line_propsize;
6637 #endif
6638
6639 /* force reallocation */
6640 shell_input_line = 0;
6641 shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
6642
6643 #if defined (HANDLE_MULTIBYTE)
6644 shell_input_line_property = 0;
6645 shell_input_line_propsize = 0;
6646 #endif
6647
6648 return ls;
6649 }
6650
6651 void
6652 restore_input_line_state (ls)
6653 sh_input_line_state_t *ls;
6654 {
6655 FREE (shell_input_line);
6656 shell_input_line = ls->input_line;
6657 shell_input_line_size = ls->input_line_size;
6658 shell_input_line_len = ls->input_line_len;
6659 shell_input_line_index = ls->input_line_index;
6660
6661 #if defined (HANDLE_MULTIBYTE)
6662 FREE (shell_input_line_property);
6663 shell_input_line_property = ls->input_property;
6664 shell_input_line_propsize = ls->input_propsize;
6665 #endif
6666
6667 #if 0
6668 set_line_mbstate ();
6669 #endif
6670 }
6671
6672 /************************************************
6673 * *
6674 * MULTIBYTE CHARACTER HANDLING *
6675 * *
6676 ************************************************/
6677
6678 #if defined (HANDLE_MULTIBYTE)
6679
6680 /* We don't let the property buffer get larger than this unless the line is */
6681 #define MAX_PROPSIZE 32768
6682
6683 static void
6684 set_line_mbstate ()
6685 {
6686 int c;
6687 size_t i, previ, len;
6688 mbstate_t mbs, prevs;
6689 size_t mbclen;
6690 int ilen;
6691
6692 if (shell_input_line == NULL)
6693 return;
6694 len = STRLEN (shell_input_line); /* XXX - shell_input_line_len ? */
6695 if (len == 0)
6696 return;
6697 if (shell_input_line_propsize >= MAX_PROPSIZE && len < MAX_PROPSIZE>>1)
6698 {
6699 free (shell_input_line_property);
6700 shell_input_line_property = 0;
6701 shell_input_line_propsize = 0;
6702 }
6703 if (len+1 > shell_input_line_propsize)
6704 {
6705 shell_input_line_propsize = len + 1;
6706 shell_input_line_property = (char *)xrealloc (shell_input_line_property, shell_input_line_propsize);
6707 }
6708
6709 if (locale_mb_cur_max == 1)
6710 {
6711 memset (shell_input_line_property, 1, len);
6712 return;
6713 }
6714
6715 /* XXX - use whether or not we are in a UTF-8 locale to avoid calls to
6716 mbrlen */
6717 if (locale_utf8locale == 0)
6718 memset (&prevs, '\0', sizeof (mbstate_t));
6719
6720 for (i = previ = 0; i < len; i++)
6721 {
6722 if (locale_utf8locale == 0)
6723 mbs = prevs;
6724
6725 c = shell_input_line[i];
6726 if (c == EOF)
6727 {
6728 size_t j;
6729 for (j = i; j < len; j++)
6730 shell_input_line_property[j] = 1;
6731 break;
6732 }
6733
6734 if (locale_utf8locale)
6735 {
6736 if ((unsigned char)shell_input_line[previ] < 128) /* i != previ */
6737 mbclen = 1;
6738 else
6739 {
6740 ilen = utf8_mblen (shell_input_line + previ, i - previ + 1);
6741 mbclen = (ilen == -1) ? (size_t)-1
6742 : ((ilen == -2) ? (size_t)-2 : (size_t)ilen);
6743 }
6744 }
6745 else
6746 mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
6747
6748 if (mbclen == 1 || mbclen == (size_t)-1)
6749 {
6750 mbclen = 1;
6751 previ = i + 1;
6752 }
6753 else if (mbclen == (size_t)-2)
6754 mbclen = 0;
6755 else if (mbclen > 1)
6756 {
6757 mbclen = 0;
6758 previ = i + 1;
6759 if (locale_utf8locale == 0)
6760 prevs = mbs;
6761 }
6762 else
6763 {
6764 size_t j;
6765 for (j = i; j < len; j++)
6766 shell_input_line_property[j] = 1;
6767 break;
6768 }
6769
6770 shell_input_line_property[i] = mbclen;
6771 }
6772 }
6773 #endif /* HANDLE_MULTIBYTE */