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