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