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