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