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