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