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