]> git.ipfire.org Git - thirdparty/bash.git/blob - parse.y
Bash-4.2 patch 5
[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 /* The line number offset set by assigning to LINENO. Not currently used. */
1651 int line_number_base = 0;
1652
1653 #if defined (COND_COMMAND)
1654 static int cond_lineno;
1655 static int cond_token;
1656 #endif
1657
1658 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1659
1660 void
1661 push_stream (reset_lineno)
1662 int reset_lineno;
1663 {
1664 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1665
1666 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1667
1668 #if defined (BUFFERED_INPUT)
1669 saver->bstream = (BUFFERED_STREAM *)NULL;
1670 /* If we have a buffered stream, clear out buffers[fd]. */
1671 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1672 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1673 (BUFFERED_STREAM *)NULL);
1674 #endif /* BUFFERED_INPUT */
1675
1676 saver->line = line_number;
1677 bash_input.name = (char *)NULL;
1678 saver->next = stream_list;
1679 stream_list = saver;
1680 EOF_Reached = 0;
1681 if (reset_lineno)
1682 line_number = 0;
1683 }
1684
1685 void
1686 pop_stream ()
1687 {
1688 if (!stream_list)
1689 EOF_Reached = 1;
1690 else
1691 {
1692 STREAM_SAVER *saver = stream_list;
1693
1694 EOF_Reached = 0;
1695 stream_list = stream_list->next;
1696
1697 init_yy_io (saver->bash_input.getter,
1698 saver->bash_input.ungetter,
1699 saver->bash_input.type,
1700 saver->bash_input.name,
1701 saver->bash_input.location);
1702
1703 #if defined (BUFFERED_INPUT)
1704 /* If we have a buffered stream, restore buffers[fd]. */
1705 /* If the input file descriptor was changed while this was on the
1706 save stack, update the buffered fd to the new file descriptor and
1707 re-establish the buffer <-> bash_input fd correspondence. */
1708 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1709 {
1710 if (bash_input_fd_changed)
1711 {
1712 bash_input_fd_changed = 0;
1713 if (default_buffered_input >= 0)
1714 {
1715 bash_input.location.buffered_fd = default_buffered_input;
1716 saver->bstream->b_fd = default_buffered_input;
1717 SET_CLOSE_ON_EXEC (default_buffered_input);
1718 }
1719 }
1720 /* XXX could free buffered stream returned as result here. */
1721 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
1722 }
1723 #endif /* BUFFERED_INPUT */
1724
1725 line_number = saver->line;
1726
1727 FREE (saver->bash_input.name);
1728 free (saver);
1729 }
1730 }
1731
1732 /* Return 1 if a stream of type TYPE is saved on the stack. */
1733 int
1734 stream_on_stack (type)
1735 enum stream_type type;
1736 {
1737 register STREAM_SAVER *s;
1738
1739 for (s = stream_list; s; s = s->next)
1740 if (s->bash_input.type == type)
1741 return 1;
1742 return 0;
1743 }
1744
1745 /* Save the current token state and return it in a malloced array. */
1746 int *
1747 save_token_state ()
1748 {
1749 int *ret;
1750
1751 ret = (int *)xmalloc (4 * sizeof (int));
1752 ret[0] = last_read_token;
1753 ret[1] = token_before_that;
1754 ret[2] = two_tokens_ago;
1755 ret[3] = current_token;
1756 return ret;
1757 }
1758
1759 void
1760 restore_token_state (ts)
1761 int *ts;
1762 {
1763 if (ts == 0)
1764 return;
1765 last_read_token = ts[0];
1766 token_before_that = ts[1];
1767 two_tokens_ago = ts[2];
1768 current_token = ts[3];
1769 }
1770
1771 /*
1772 * This is used to inhibit alias expansion and reserved word recognition
1773 * inside case statement pattern lists. A `case statement pattern list' is:
1774 *
1775 * everything between the `in' in a `case word in' and the next ')'
1776 * or `esac'
1777 * everything between a `;;' and the next `)' or `esac'
1778 */
1779
1780 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1781
1782 #define END_OF_ALIAS 0
1783
1784 /*
1785 * Pseudo-global variables used in implementing token-wise alias expansion.
1786 */
1787
1788 /*
1789 * Pushing and popping strings. This works together with shell_getc to
1790 * implement alias expansion on a per-token basis.
1791 */
1792
1793 typedef struct string_saver {
1794 struct string_saver *next;
1795 int expand_alias; /* Value to set expand_alias to when string is popped. */
1796 char *saved_line;
1797 #if defined (ALIAS)
1798 alias_t *expander; /* alias that caused this line to be pushed. */
1799 #endif
1800 int saved_line_size, saved_line_index, saved_line_terminator;
1801 } STRING_SAVER;
1802
1803 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1804
1805 /*
1806 * Push the current shell_input_line onto a stack of such lines and make S
1807 * the current input. Used when expanding aliases. EXPAND is used to set
1808 * the value of expand_next_token when the string is popped, so that the
1809 * word after the alias in the original line is handled correctly when the
1810 * alias expands to multiple words. TOKEN is the token that was expanded
1811 * into S; it is saved and used to prevent infinite recursive expansion.
1812 */
1813 static void
1814 push_string (s, expand, ap)
1815 char *s;
1816 int expand;
1817 alias_t *ap;
1818 {
1819 STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
1820
1821 temp->expand_alias = expand;
1822 temp->saved_line = shell_input_line;
1823 temp->saved_line_size = shell_input_line_size;
1824 temp->saved_line_index = shell_input_line_index;
1825 temp->saved_line_terminator = shell_input_line_terminator;
1826 #if defined (ALIAS)
1827 temp->expander = ap;
1828 #endif
1829 temp->next = pushed_string_list;
1830 pushed_string_list = temp;
1831
1832 #if defined (ALIAS)
1833 if (ap)
1834 ap->flags |= AL_BEINGEXPANDED;
1835 #endif
1836
1837 shell_input_line = s;
1838 shell_input_line_size = strlen (s);
1839 shell_input_line_index = 0;
1840 shell_input_line_terminator = '\0';
1841 #if 0
1842 parser_state &= ~PST_ALEXPNEXT; /* XXX */
1843 #endif
1844
1845 set_line_mbstate ();
1846 }
1847
1848 /*
1849 * Make the top of the pushed_string stack be the current shell input.
1850 * Only called when there is something on the stack. Called from shell_getc
1851 * when it thinks it has consumed the string generated by an alias expansion
1852 * and needs to return to the original input line.
1853 */
1854 static void
1855 pop_string ()
1856 {
1857 STRING_SAVER *t;
1858
1859 FREE (shell_input_line);
1860 shell_input_line = pushed_string_list->saved_line;
1861 shell_input_line_index = pushed_string_list->saved_line_index;
1862 shell_input_line_size = pushed_string_list->saved_line_size;
1863 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
1864
1865 if (pushed_string_list->expand_alias)
1866 parser_state |= PST_ALEXPNEXT;
1867 else
1868 parser_state &= ~PST_ALEXPNEXT;
1869
1870 t = pushed_string_list;
1871 pushed_string_list = pushed_string_list->next;
1872
1873 #if defined (ALIAS)
1874 if (t->expander)
1875 t->expander->flags &= ~AL_BEINGEXPANDED;
1876 #endif
1877
1878 free ((char *)t);
1879
1880 set_line_mbstate ();
1881 }
1882
1883 static void
1884 free_string_list ()
1885 {
1886 register STRING_SAVER *t, *t1;
1887
1888 for (t = pushed_string_list; t; )
1889 {
1890 t1 = t->next;
1891 FREE (t->saved_line);
1892 #if defined (ALIAS)
1893 if (t->expander)
1894 t->expander->flags &= ~AL_BEINGEXPANDED;
1895 #endif
1896 free ((char *)t);
1897 t = t1;
1898 }
1899 pushed_string_list = (STRING_SAVER *)NULL;
1900 }
1901
1902 #endif /* ALIAS || DPAREN_ARITHMETIC */
1903
1904 void
1905 free_pushed_string_input ()
1906 {
1907 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1908 free_string_list ();
1909 #endif
1910 }
1911
1912 /* Return a line of text, taken from wherever yylex () reads input.
1913 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
1914 is non-zero, we remove unquoted \<newline> pairs. This is used by
1915 read_secondary_line to read here documents. */
1916 static char *
1917 read_a_line (remove_quoted_newline)
1918 int remove_quoted_newline;
1919 {
1920 static char *line_buffer = (char *)NULL;
1921 static int buffer_size = 0;
1922 int indx, c, peekc, pass_next;
1923
1924 #if defined (READLINE)
1925 if (no_line_editing && SHOULD_PROMPT ())
1926 #else
1927 if (SHOULD_PROMPT ())
1928 #endif
1929 print_prompt ();
1930
1931 pass_next = indx = 0;
1932 while (1)
1933 {
1934 /* Allow immediate exit if interrupted during input. */
1935 QUIT;
1936
1937 c = yy_getc ();
1938
1939 /* Ignore null bytes in input. */
1940 if (c == 0)
1941 {
1942 #if 0
1943 internal_warning ("read_a_line: ignored null byte in input");
1944 #endif
1945 continue;
1946 }
1947
1948 /* If there is no more input, then we return NULL. */
1949 if (c == EOF)
1950 {
1951 if (interactive && bash_input.type == st_stream)
1952 clearerr (stdin);
1953 if (indx == 0)
1954 return ((char *)NULL);
1955 c = '\n';
1956 }
1957
1958 /* `+2' in case the final character in the buffer is a newline. */
1959 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
1960
1961 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1962 here document with an unquoted delimiter. In this case,
1963 the line will be expanded as if it were in double quotes.
1964 We allow a backslash to escape the next character, but we
1965 need to treat the backslash specially only if a backslash
1966 quoting a backslash-newline pair appears in the line. */
1967 if (pass_next)
1968 {
1969 line_buffer[indx++] = c;
1970 pass_next = 0;
1971 }
1972 else if (c == '\\' && remove_quoted_newline)
1973 {
1974 QUIT;
1975 peekc = yy_getc ();
1976 if (peekc == '\n')
1977 {
1978 line_number++;
1979 continue; /* Make the unquoted \<newline> pair disappear. */
1980 }
1981 else
1982 {
1983 yy_ungetc (peekc);
1984 pass_next = 1;
1985 line_buffer[indx++] = c; /* Preserve the backslash. */
1986 }
1987 }
1988 else
1989 line_buffer[indx++] = c;
1990
1991 if (c == '\n')
1992 {
1993 line_buffer[indx] = '\0';
1994 return (line_buffer);
1995 }
1996 }
1997 }
1998
1999 /* Return a line as in read_a_line (), but insure that the prompt is
2000 the secondary prompt. This is used to read the lines of a here
2001 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2002 newlines quoted with backslashes while reading the line. It is
2003 non-zero unless the delimiter of the here document was quoted. */
2004 char *
2005 read_secondary_line (remove_quoted_newline)
2006 int remove_quoted_newline;
2007 {
2008 char *ret;
2009 int n, c;
2010
2011 prompt_string_pointer = &ps2_prompt;
2012 if (SHOULD_PROMPT())
2013 prompt_again ();
2014 ret = read_a_line (remove_quoted_newline);
2015 #if defined (HISTORY)
2016 if (ret && remember_on_history && (parser_state & PST_HEREDOC))
2017 {
2018 /* To make adding the the here-document body right, we need to rely
2019 on history_delimiting_chars() returning \n for the first line of
2020 the here-document body and the null string for the second and
2021 subsequent lines, so we avoid double newlines.
2022 current_command_line_count == 2 for the first line of the body. */
2023
2024 current_command_line_count++;
2025 maybe_add_history (ret);
2026 }
2027 #endif /* HISTORY */
2028 return ret;
2029 }
2030
2031 /* **************************************************************** */
2032 /* */
2033 /* YYLEX () */
2034 /* */
2035 /* **************************************************************** */
2036
2037 /* Reserved words. These are only recognized as the first word of a
2038 command. */
2039 STRING_INT_ALIST word_token_alist[] = {
2040 { "if", IF },
2041 { "then", THEN },
2042 { "else", ELSE },
2043 { "elif", ELIF },
2044 { "fi", FI },
2045 { "case", CASE },
2046 { "esac", ESAC },
2047 { "for", FOR },
2048 #if defined (SELECT_COMMAND)
2049 { "select", SELECT },
2050 #endif
2051 { "while", WHILE },
2052 { "until", UNTIL },
2053 { "do", DO },
2054 { "done", DONE },
2055 { "in", IN },
2056 { "function", FUNCTION },
2057 #if defined (COMMAND_TIMING)
2058 { "time", TIME },
2059 #endif
2060 { "{", '{' },
2061 { "}", '}' },
2062 { "!", BANG },
2063 #if defined (COND_COMMAND)
2064 { "[[", COND_START },
2065 { "]]", COND_END },
2066 #endif
2067 #if defined (COPROCESS_SUPPORT)
2068 { "coproc", COPROC },
2069 #endif
2070 { (char *)NULL, 0}
2071 };
2072
2073 /* other tokens that can be returned by read_token() */
2074 STRING_INT_ALIST other_token_alist[] = {
2075 /* Multiple-character tokens with special values */
2076 { "--", TIMEIGN },
2077 { "-p", TIMEOPT },
2078 { "&&", AND_AND },
2079 { "||", OR_OR },
2080 { ">>", GREATER_GREATER },
2081 { "<<", LESS_LESS },
2082 { "<&", LESS_AND },
2083 { ">&", GREATER_AND },
2084 { ";;", SEMI_SEMI },
2085 { ";&", SEMI_AND },
2086 { ";;&", SEMI_SEMI_AND },
2087 { "<<-", LESS_LESS_MINUS },
2088 { "<<<", LESS_LESS_LESS },
2089 { "&>", AND_GREATER },
2090 { "&>>", AND_GREATER_GREATER },
2091 { "<>", LESS_GREATER },
2092 { ">|", GREATER_BAR },
2093 { "|&", BAR_AND },
2094 { "EOF", yacc_EOF },
2095 /* Tokens whose value is the character itself */
2096 { ">", '>' },
2097 { "<", '<' },
2098 { "-", '-' },
2099 { "{", '{' },
2100 { "}", '}' },
2101 { ";", ';' },
2102 { "(", '(' },
2103 { ")", ')' },
2104 { "|", '|' },
2105 { "&", '&' },
2106 { "newline", '\n' },
2107 { (char *)NULL, 0}
2108 };
2109
2110 /* others not listed here:
2111 WORD look at yylval.word
2112 ASSIGNMENT_WORD look at yylval.word
2113 NUMBER look at yylval.number
2114 ARITH_CMD look at yylval.word_list
2115 ARITH_FOR_EXPRS look at yylval.word_list
2116 COND_CMD look at yylval.command
2117 */
2118
2119 /* These are used by read_token_word, but appear up here so that shell_getc
2120 can use them to decide when to add otherwise blank lines to the history. */
2121
2122 /* The primary delimiter stack. */
2123 struct dstack dstack = { (char *)NULL, 0, 0 };
2124
2125 /* A temporary delimiter stack to be used when decoding prompt strings.
2126 This is needed because command substitutions in prompt strings (e.g., PS2)
2127 can screw up the parser's quoting state. */
2128 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2129
2130 /* Macro for accessing the top delimiter on the stack. Returns the
2131 delimiter or zero if none. */
2132 #define current_delimiter(ds) \
2133 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2134
2135 #define push_delimiter(ds, character) \
2136 do \
2137 { \
2138 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2139 ds.delimiters = (char *)xrealloc \
2140 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2141 ds.delimiters[ds.delimiter_depth] = character; \
2142 ds.delimiter_depth++; \
2143 } \
2144 while (0)
2145
2146 #define pop_delimiter(ds) ds.delimiter_depth--
2147
2148 /* Return the next shell input character. This always reads characters
2149 from shell_input_line; when that line is exhausted, it is time to
2150 read the next line. This is called by read_token when the shell is
2151 processing normal command input. */
2152
2153 /* This implements one-character lookahead/lookbehind across physical input
2154 lines, to avoid something being lost because it's pushed back with
2155 shell_ungetc when we're at the start of a line. */
2156 static int eol_ungetc_lookahead = 0;
2157
2158 static int
2159 shell_getc (remove_quoted_newline)
2160 int remove_quoted_newline;
2161 {
2162 register int i;
2163 int c;
2164 unsigned char uc;
2165
2166 QUIT;
2167
2168 if (sigwinch_received)
2169 {
2170 sigwinch_received = 0;
2171 get_new_window_size (0, (int *)0, (int *)0);
2172 }
2173
2174 if (eol_ungetc_lookahead)
2175 {
2176 c = eol_ungetc_lookahead;
2177 eol_ungetc_lookahead = 0;
2178 return (c);
2179 }
2180
2181 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2182 /* If shell_input_line[shell_input_line_index] == 0, but there is
2183 something on the pushed list of strings, then we don't want to go
2184 off and get another line. We let the code down below handle it. */
2185
2186 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2187 (pushed_string_list == (STRING_SAVER *)NULL)))
2188 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2189 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2190 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2191 {
2192 line_number++;
2193
2194 restart_read:
2195
2196 /* Allow immediate exit if interrupted during input. */
2197 QUIT;
2198
2199 i = 0;
2200 shell_input_line_terminator = 0;
2201
2202 /* If the shell is interatctive, but not currently printing a prompt
2203 (interactive_shell && interactive == 0), we don't want to print
2204 notifies or cleanup the jobs -- we want to defer it until we do
2205 print the next prompt. */
2206 if (interactive_shell == 0 || SHOULD_PROMPT())
2207 {
2208 #if defined (JOB_CONTROL)
2209 /* This can cause a problem when reading a command as the result
2210 of a trap, when the trap is called from flush_child. This call
2211 had better not cause jobs to disappear from the job table in
2212 that case, or we will have big trouble. */
2213 notify_and_cleanup ();
2214 #else /* !JOB_CONTROL */
2215 cleanup_dead_jobs ();
2216 #endif /* !JOB_CONTROL */
2217 }
2218
2219 #if defined (READLINE)
2220 if (no_line_editing && SHOULD_PROMPT())
2221 #else
2222 if (SHOULD_PROMPT())
2223 #endif
2224 print_prompt ();
2225
2226 if (bash_input.type == st_stream)
2227 clearerr (stdin);
2228
2229 while (1)
2230 {
2231 c = yy_getc ();
2232
2233 /* Allow immediate exit if interrupted during input. */
2234 QUIT;
2235
2236 if (c == '\0')
2237 {
2238 #if 0
2239 internal_warning ("shell_getc: ignored null byte in input");
2240 #endif
2241 continue;
2242 }
2243
2244 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2245
2246 if (c == EOF)
2247 {
2248 if (bash_input.type == st_stream)
2249 clearerr (stdin);
2250
2251 if (i == 0)
2252 shell_input_line_terminator = EOF;
2253
2254 shell_input_line[i] = '\0';
2255 break;
2256 }
2257
2258 shell_input_line[i++] = c;
2259
2260 if (c == '\n')
2261 {
2262 shell_input_line[--i] = '\0';
2263 current_command_line_count++;
2264 break;
2265 }
2266 }
2267
2268 shell_input_line_index = 0;
2269 shell_input_line_len = i; /* == strlen (shell_input_line) */
2270
2271 set_line_mbstate ();
2272
2273 #if defined (HISTORY)
2274 if (remember_on_history && shell_input_line && shell_input_line[0])
2275 {
2276 char *expansions;
2277 # if defined (BANG_HISTORY)
2278 int old_hist;
2279
2280 /* If the current delimiter is a single quote, we should not be
2281 performing history expansion, even if we're on a different
2282 line from the original single quote. */
2283 old_hist = history_expansion_inhibited;
2284 if (current_delimiter (dstack) == '\'')
2285 history_expansion_inhibited = 1;
2286 # endif
2287 expansions = pre_process_line (shell_input_line, 1, 1);
2288 # if defined (BANG_HISTORY)
2289 history_expansion_inhibited = old_hist;
2290 # endif
2291 if (expansions != shell_input_line)
2292 {
2293 free (shell_input_line);
2294 shell_input_line = expansions;
2295 shell_input_line_len = shell_input_line ?
2296 strlen (shell_input_line) : 0;
2297 if (shell_input_line_len == 0)
2298 current_command_line_count--;
2299
2300 /* We have to force the xrealloc below because we don't know
2301 the true allocated size of shell_input_line anymore. */
2302 shell_input_line_size = shell_input_line_len;
2303
2304 set_line_mbstate ();
2305 }
2306 }
2307 /* Try to do something intelligent with blank lines encountered while
2308 entering multi-line commands. XXX - this is grotesque */
2309 else if (remember_on_history && shell_input_line &&
2310 shell_input_line[0] == '\0' &&
2311 current_command_line_count > 1)
2312 {
2313 if (current_delimiter (dstack))
2314 /* We know shell_input_line[0] == 0 and we're reading some sort of
2315 quoted string. This means we've got a line consisting of only
2316 a newline in a quoted string. We want to make sure this line
2317 gets added to the history. */
2318 maybe_add_history (shell_input_line);
2319 else
2320 {
2321 char *hdcs;
2322 hdcs = history_delimiting_chars (shell_input_line);
2323 if (hdcs && hdcs[0] == ';')
2324 maybe_add_history (shell_input_line);
2325 }
2326 }
2327
2328 #endif /* HISTORY */
2329
2330 if (shell_input_line)
2331 {
2332 /* Lines that signify the end of the shell's input should not be
2333 echoed. */
2334 if (echo_input_at_read && (shell_input_line[0] ||
2335 shell_input_line_terminator != EOF))
2336 fprintf (stderr, "%s\n", shell_input_line);
2337 }
2338 else
2339 {
2340 shell_input_line_size = 0;
2341 prompt_string_pointer = &current_prompt_string;
2342 if (SHOULD_PROMPT ())
2343 prompt_again ();
2344 goto restart_read;
2345 }
2346
2347 /* Add the newline to the end of this string, iff the string does
2348 not already end in an EOF character. */
2349 if (shell_input_line_terminator != EOF)
2350 {
2351 if (shell_input_line_len + 3 > shell_input_line_size)
2352 shell_input_line = (char *)xrealloc (shell_input_line,
2353 1 + (shell_input_line_size += 2));
2354
2355 shell_input_line[shell_input_line_len] = '\n';
2356 shell_input_line[shell_input_line_len + 1] = '\0';
2357
2358 set_line_mbstate ();
2359 }
2360 }
2361
2362 next_alias_char:
2363 uc = shell_input_line[shell_input_line_index];
2364
2365 if (uc)
2366 shell_input_line_index++;
2367
2368 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2369 /* If UC is NULL, we have reached the end of the current input string. If
2370 pushed_string_list is non-empty, it's time to pop to the previous string
2371 because we have fully consumed the result of the last alias expansion.
2372 Do it transparently; just return the next character of the string popped
2373 to. */
2374 pop_alias:
2375 if (uc == 0 && (pushed_string_list != (STRING_SAVER *)NULL))
2376 {
2377 pop_string ();
2378 uc = shell_input_line[shell_input_line_index];
2379 if (uc)
2380 shell_input_line_index++;
2381 }
2382 #endif /* ALIAS || DPAREN_ARITHMETIC */
2383
2384 if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
2385 {
2386 if (SHOULD_PROMPT ())
2387 prompt_again ();
2388 line_number++;
2389 /* What do we do here if we're expanding an alias whose definition
2390 includes an escaped newline? If that's the last character in the
2391 alias expansion, we just pop the pushed string list (recall that
2392 we inhibit the appending of a space in mk_alexpansion() if newline
2393 is the last character). If it's not the last character, we need
2394 to consume the quoted newline and move to the next character in
2395 the expansion. */
2396 if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
2397 {
2398 uc = 0;
2399 goto pop_alias;
2400 }
2401 else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0')
2402 {
2403 shell_input_line_index++; /* skip newline */
2404 goto next_alias_char; /* and get next character */
2405 }
2406 else
2407 goto restart_read;
2408 }
2409
2410 if (uc == 0 && shell_input_line_terminator == EOF)
2411 return ((shell_input_line_index != 0) ? '\n' : EOF);
2412
2413 return (uc);
2414 }
2415
2416 /* Put C back into the input for the shell. This might need changes for
2417 HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a
2418 character different than we read, shell_input_line_property doesn't need
2419 to change when manipulating shell_input_line. The define for
2420 last_shell_getc_is_singlebyte should take care of it, though. */
2421 static void
2422 shell_ungetc (c)
2423 int c;
2424 {
2425 if (shell_input_line && shell_input_line_index)
2426 shell_input_line[--shell_input_line_index] = c;
2427 else
2428 eol_ungetc_lookahead = c;
2429 }
2430
2431 #ifdef INCLUDE_UNUSED
2432 /* Back the input pointer up by one, effectively `ungetting' a character. */
2433 static void
2434 shell_ungetchar ()
2435 {
2436 if (shell_input_line && shell_input_line_index)
2437 shell_input_line_index--;
2438 }
2439 #endif
2440
2441 /* Discard input until CHARACTER is seen, then push that character back
2442 onto the input stream. */
2443 static void
2444 discard_until (character)
2445 int character;
2446 {
2447 int c;
2448
2449 while ((c = shell_getc (0)) != EOF && c != character)
2450 ;
2451
2452 if (c != EOF)
2453 shell_ungetc (c);
2454 }
2455
2456 void
2457 execute_variable_command (command, vname)
2458 char *command, *vname;
2459 {
2460 char *last_lastarg;
2461 sh_parser_state_t ps;
2462
2463 save_parser_state (&ps);
2464 last_lastarg = get_string_value ("_");
2465 if (last_lastarg)
2466 last_lastarg = savestring (last_lastarg);
2467
2468 parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
2469
2470 restore_parser_state (&ps);
2471 bind_variable ("_", last_lastarg, 0);
2472 FREE (last_lastarg);
2473
2474 if (token_to_read == '\n') /* reset_parser was called */
2475 token_to_read = 0;
2476 }
2477
2478 /* Place to remember the token. We try to keep the buffer
2479 at a reasonable size, but it can grow. */
2480 static char *token = (char *)NULL;
2481
2482 /* Current size of the token buffer. */
2483 static int token_buffer_size;
2484
2485 /* Command to read_token () explaining what we want it to do. */
2486 #define READ 0
2487 #define RESET 1
2488 #define prompt_is_ps1 \
2489 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2490
2491 /* Function for yyparse to call. yylex keeps track of
2492 the last two tokens read, and calls read_token. */
2493 static int
2494 yylex ()
2495 {
2496 if (interactive && (current_token == 0 || current_token == '\n'))
2497 {
2498 /* Before we print a prompt, we might have to check mailboxes.
2499 We do this only if it is time to do so. Notice that only here
2500 is the mail alarm reset; nothing takes place in check_mail ()
2501 except the checking of mail. Please don't change this. */
2502 if (prompt_is_ps1 && time_to_check_mail ())
2503 {
2504 check_mail ();
2505 reset_mail_timer ();
2506 }
2507
2508 /* Avoid printing a prompt if we're not going to read anything, e.g.
2509 after resetting the parser with read_token (RESET). */
2510 if (token_to_read == 0 && SHOULD_PROMPT ())
2511 prompt_again ();
2512 }
2513
2514 two_tokens_ago = token_before_that;
2515 token_before_that = last_read_token;
2516 last_read_token = current_token;
2517 current_token = read_token (READ);
2518
2519 if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
2520 {
2521 current_token = yacc_EOF;
2522 if (bash_input.type == st_string)
2523 rewind_input_string ();
2524 }
2525 parser_state &= ~PST_EOFTOKEN;
2526
2527 return (current_token);
2528 }
2529
2530 /* When non-zero, we have read the required tokens
2531 which allow ESAC to be the next one read. */
2532 static int esacs_needed_count;
2533
2534 void
2535 gather_here_documents ()
2536 {
2537 int r;
2538
2539 r = 0;
2540 while (need_here_doc)
2541 {
2542 parser_state |= PST_HEREDOC;
2543 make_here_document (redir_stack[r++], line_number);
2544 parser_state &= ~PST_HEREDOC;
2545 need_here_doc--;
2546 }
2547 }
2548
2549 /* When non-zero, an open-brace used to create a group is awaiting a close
2550 brace partner. */
2551 static int open_brace_count;
2552
2553 #define command_token_position(token) \
2554 (((token) == ASSIGNMENT_WORD) || (parser_state&PST_REDIRLIST) || \
2555 ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
2556
2557 #define assignment_acceptable(token) \
2558 (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
2559
2560 /* Check to see if TOKEN is a reserved word and return the token
2561 value if it is. */
2562 #define CHECK_FOR_RESERVED_WORD(tok) \
2563 do { \
2564 if (!dollar_present && !quoted && \
2565 reserved_word_acceptable (last_read_token)) \
2566 { \
2567 int i; \
2568 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2569 if (STREQ (tok, word_token_alist[i].word)) \
2570 { \
2571 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2572 break; \
2573 if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
2574 break; \
2575 if (word_token_alist[i].token == ESAC) \
2576 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2577 else if (word_token_alist[i].token == CASE) \
2578 parser_state |= PST_CASESTMT; \
2579 else if (word_token_alist[i].token == COND_END) \
2580 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2581 else if (word_token_alist[i].token == COND_START) \
2582 parser_state |= PST_CONDCMD; \
2583 else if (word_token_alist[i].token == '{') \
2584 open_brace_count++; \
2585 else if (word_token_alist[i].token == '}' && open_brace_count) \
2586 open_brace_count--; \
2587 return (word_token_alist[i].token); \
2588 } \
2589 } \
2590 } while (0)
2591
2592 #if defined (ALIAS)
2593
2594 /* OK, we have a token. Let's try to alias expand it, if (and only if)
2595 it's eligible.
2596
2597 It is eligible for expansion if EXPAND_ALIASES is set, and
2598 the token is unquoted and the last token read was a command
2599 separator (or expand_next_token is set), and we are currently
2600 processing an alias (pushed_string_list is non-empty) and this
2601 token is not the same as the current or any previously
2602 processed alias.
2603
2604 Special cases that disqualify:
2605 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
2606
2607 static char *
2608 mk_alexpansion (s)
2609 char *s;
2610 {
2611 int l;
2612 char *r;
2613
2614 l = strlen (s);
2615 r = xmalloc (l + 2);
2616 strcpy (r, s);
2617 /* If the last character in the alias is a newline, don't add a trailing
2618 space to the expansion. Works with shell_getc above. */
2619 if (r[l - 1] != ' ' && r[l - 1] != '\n')
2620 r[l++] = ' ';
2621 r[l] = '\0';
2622 return r;
2623 }
2624
2625 static int
2626 alias_expand_token (tokstr)
2627 char *tokstr;
2628 {
2629 char *expanded;
2630 alias_t *ap;
2631
2632 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2633 (parser_state & PST_CASEPAT) == 0)
2634 {
2635 ap = find_alias (tokstr);
2636
2637 /* Currently expanding this token. */
2638 if (ap && (ap->flags & AL_BEINGEXPANDED))
2639 return (NO_EXPANSION);
2640
2641 /* mk_alexpansion puts an extra space on the end of the alias expansion,
2642 so the lookahead by the parser works right. If this gets changed,
2643 make sure the code in shell_getc that deals with reaching the end of
2644 an expanded alias is changed with it. */
2645 expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2646
2647 if (expanded)
2648 {
2649 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2650 return (RE_READ_TOKEN);
2651 }
2652 else
2653 /* This is an eligible token that does not have an expansion. */
2654 return (NO_EXPANSION);
2655 }
2656 return (NO_EXPANSION);
2657 }
2658 #endif /* ALIAS */
2659
2660 static int
2661 time_command_acceptable ()
2662 {
2663 #if defined (COMMAND_TIMING)
2664 int i;
2665
2666 if (posixly_correct && shell_compatibility_level > 41)
2667 {
2668 /* Quick check of the rest of the line to find the next token. If it
2669 begins with a `-', Posix says to not return `time' as the token.
2670 This was interp 267. */
2671 i = shell_input_line_index;
2672 while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
2673 i++;
2674 if (shell_input_line[i] == '-')
2675 return 0;
2676 }
2677
2678 switch (last_read_token)
2679 {
2680 case 0:
2681 case ';':
2682 case '\n':
2683 case AND_AND:
2684 case OR_OR:
2685 case '&':
2686 case DO:
2687 case THEN:
2688 case ELSE:
2689 case '{': /* } */
2690 case '(': /* ) */
2691 case BANG: /* ! time pipeline */
2692 case TIME: /* time time pipeline */
2693 case TIMEOPT: /* time -p time pipeline */
2694 case TIMEIGN: /* time -p -- ... */
2695 return 1;
2696 default:
2697 return 0;
2698 }
2699 #else
2700 return 0;
2701 #endif /* COMMAND_TIMING */
2702 }
2703
2704 /* Handle special cases of token recognition:
2705 IN is recognized if the last token was WORD and the token
2706 before that was FOR or CASE or SELECT.
2707
2708 DO is recognized if the last token was WORD and the token
2709 before that was FOR or SELECT.
2710
2711 ESAC is recognized if the last token caused `esacs_needed_count'
2712 to be set
2713
2714 `{' is recognized if the last token as WORD and the token
2715 before that was FUNCTION, or if we just parsed an arithmetic
2716 `for' command.
2717
2718 `}' is recognized if there is an unclosed `{' present.
2719
2720 `-p' is returned as TIMEOPT if the last read token was TIME.
2721 `--' is returned as TIMEIGN if the last read token was TIMEOPT.
2722
2723 ']]' is returned as COND_END if the parser is currently parsing
2724 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2725
2726 `time' is returned as TIME if and only if it is immediately
2727 preceded by one of `;', `\n', `||', `&&', or `&'.
2728 */
2729
2730 static int
2731 special_case_tokens (tokstr)
2732 char *tokstr;
2733 {
2734 if ((last_read_token == WORD) &&
2735 #if defined (SELECT_COMMAND)
2736 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2737 #else
2738 ((token_before_that == FOR) || (token_before_that == CASE)) &&
2739 #endif
2740 (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
2741 {
2742 if (token_before_that == CASE)
2743 {
2744 parser_state |= PST_CASEPAT;
2745 esacs_needed_count++;
2746 }
2747 return (IN);
2748 }
2749
2750 if (last_read_token == WORD &&
2751 #if defined (SELECT_COMMAND)
2752 (token_before_that == FOR || token_before_that == SELECT) &&
2753 #else
2754 (token_before_that == FOR) &&
2755 #endif
2756 (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
2757 return (DO);
2758
2759 /* Ditto for ESAC in the CASE case.
2760 Specifically, this handles "case word in esac", which is a legal
2761 construct, certainly because someone will pass an empty arg to the
2762 case construct, and we don't want it to barf. Of course, we should
2763 insist that the case construct has at least one pattern in it, but
2764 the designers disagree. */
2765 if (esacs_needed_count)
2766 {
2767 esacs_needed_count--;
2768 if (STREQ (tokstr, "esac"))
2769 {
2770 parser_state &= ~PST_CASEPAT;
2771 return (ESAC);
2772 }
2773 }
2774
2775 /* The start of a shell function definition. */
2776 if (parser_state & PST_ALLOWOPNBRC)
2777 {
2778 parser_state &= ~PST_ALLOWOPNBRC;
2779 if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */
2780 {
2781 open_brace_count++;
2782 function_bstart = line_number;
2783 return ('{'); /* } */
2784 }
2785 }
2786
2787 /* We allow a `do' after a for ((...)) without an intervening
2788 list_terminator */
2789 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
2790 return (DO);
2791 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */
2792 {
2793 open_brace_count++;
2794 return ('{'); /* } */
2795 }
2796
2797 if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
2798 {
2799 open_brace_count--; /* { */
2800 return ('}');
2801 }
2802
2803 #if defined (COMMAND_TIMING)
2804 /* Handle -p after `time'. */
2805 if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
2806 return (TIMEOPT);
2807 /* Handle -- after `time -p'. */
2808 if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
2809 return (TIMEIGN);
2810 #endif
2811
2812 #if defined (COND_COMMAND) /* [[ */
2813 if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
2814 return (COND_END);
2815 #endif
2816
2817 return (-1);
2818 }
2819
2820 /* Called from shell.c when Control-C is typed at top level. Or
2821 by the error rule at top level. */
2822 void
2823 reset_parser ()
2824 {
2825 dstack.delimiter_depth = 0; /* No delimiters found so far. */
2826 open_brace_count = 0;
2827
2828 #if defined (EXTENDED_GLOB)
2829 /* Reset to global value of extended glob */
2830 if (parser_state & PST_EXTPAT)
2831 extended_glob = global_extglob;
2832 #endif
2833
2834 parser_state = 0;
2835
2836 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2837 if (pushed_string_list)
2838 free_string_list ();
2839 #endif /* ALIAS || DPAREN_ARITHMETIC */
2840
2841 if (shell_input_line)
2842 {
2843 free (shell_input_line);
2844 shell_input_line = (char *)NULL;
2845 shell_input_line_size = shell_input_line_index = 0;
2846 }
2847
2848 FREE (word_desc_to_read);
2849 word_desc_to_read = (WORD_DESC *)NULL;
2850
2851 current_token = '\n'; /* XXX */
2852 last_read_token = '\n';
2853 token_to_read = '\n';
2854 }
2855
2856 /* Read the next token. Command can be READ (normal operation) or
2857 RESET (to normalize state). */
2858 static int
2859 read_token (command)
2860 int command;
2861 {
2862 int character; /* Current character. */
2863 int peek_char; /* Temporary look-ahead character. */
2864 int result; /* The thing to return. */
2865
2866 if (command == RESET)
2867 {
2868 reset_parser ();
2869 return ('\n');
2870 }
2871
2872 if (token_to_read)
2873 {
2874 result = token_to_read;
2875 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
2876 {
2877 yylval.word = word_desc_to_read;
2878 word_desc_to_read = (WORD_DESC *)NULL;
2879 }
2880 token_to_read = 0;
2881 return (result);
2882 }
2883
2884 #if defined (COND_COMMAND)
2885 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2886 {
2887 cond_lineno = line_number;
2888 parser_state |= PST_CONDEXPR;
2889 yylval.command = parse_cond_command ();
2890 if (cond_token != COND_END)
2891 {
2892 cond_error ();
2893 return (-1);
2894 }
2895 token_to_read = COND_END;
2896 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2897 return (COND_CMD);
2898 }
2899 #endif
2900
2901 #if defined (ALIAS)
2902 /* This is a place to jump back to once we have successfully expanded a
2903 token with an alias and pushed the string with push_string () */
2904 re_read_token:
2905 #endif /* ALIAS */
2906
2907 /* Read a single word from input. Start by skipping blanks. */
2908 while ((character = shell_getc (1)) != EOF && shellblank (character))
2909 ;
2910
2911 if (character == EOF)
2912 {
2913 EOF_Reached = 1;
2914 return (yacc_EOF);
2915 }
2916
2917 if MBTEST(character == '#' && (!interactive || interactive_comments))
2918 {
2919 /* A comment. Discard until EOL or EOF, and then return a newline. */
2920 discard_until ('\n');
2921 shell_getc (0);
2922 character = '\n'; /* this will take the next if statement and return. */
2923 }
2924
2925 if (character == '\n')
2926 {
2927 /* If we're about to return an unquoted newline, we can go and collect
2928 the text of any pending here document. */
2929 if (need_here_doc)
2930 gather_here_documents ();
2931
2932 #if defined (ALIAS)
2933 parser_state &= ~PST_ALEXPNEXT;
2934 #endif /* ALIAS */
2935
2936 parser_state &= ~PST_ASSIGNOK;
2937
2938 return (character);
2939 }
2940
2941 if (parser_state & PST_REGEXP)
2942 goto tokword;
2943
2944 /* Shell meta-characters. */
2945 if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
2946 {
2947 #if defined (ALIAS)
2948 /* Turn off alias tokenization iff this character sequence would
2949 not leave us ready to read a command. */
2950 if (character == '<' || character == '>')
2951 parser_state &= ~PST_ALEXPNEXT;
2952 #endif /* ALIAS */
2953
2954 parser_state &= ~PST_ASSIGNOK;
2955
2956 peek_char = shell_getc (1);
2957 if (character == peek_char)
2958 {
2959 switch (character)
2960 {
2961 case '<':
2962 /* If '<' then we could be at "<<" or at "<<-". We have to
2963 look ahead one more character. */
2964 peek_char = shell_getc (1);
2965 if MBTEST(peek_char == '-')
2966 return (LESS_LESS_MINUS);
2967 else if MBTEST(peek_char == '<')
2968 return (LESS_LESS_LESS);
2969 else
2970 {
2971 shell_ungetc (peek_char);
2972 return (LESS_LESS);
2973 }
2974
2975 case '>':
2976 return (GREATER_GREATER);
2977
2978 case ';':
2979 parser_state |= PST_CASEPAT;
2980 #if defined (ALIAS)
2981 parser_state &= ~PST_ALEXPNEXT;
2982 #endif /* ALIAS */
2983
2984 peek_char = shell_getc (1);
2985 if MBTEST(peek_char == '&')
2986 return (SEMI_SEMI_AND);
2987 else
2988 {
2989 shell_ungetc (peek_char);
2990 return (SEMI_SEMI);
2991 }
2992
2993 case '&':
2994 return (AND_AND);
2995
2996 case '|':
2997 return (OR_OR);
2998
2999 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3000 case '(': /* ) */
3001 result = parse_dparen (character);
3002 if (result == -2)
3003 break;
3004 else
3005 return result;
3006 #endif
3007 }
3008 }
3009 else if MBTEST(character == '<' && peek_char == '&')
3010 return (LESS_AND);
3011 else if MBTEST(character == '>' && peek_char == '&')
3012 return (GREATER_AND);
3013 else if MBTEST(character == '<' && peek_char == '>')
3014 return (LESS_GREATER);
3015 else if MBTEST(character == '>' && peek_char == '|')
3016 return (GREATER_BAR);
3017 else if MBTEST(character == '&' && peek_char == '>')
3018 {
3019 peek_char = shell_getc (1);
3020 if MBTEST(peek_char == '>')
3021 return (AND_GREATER_GREATER);
3022 else
3023 {
3024 shell_ungetc (peek_char);
3025 return (AND_GREATER);
3026 }
3027 }
3028 else if MBTEST(character == '|' && peek_char == '&')
3029 return (BAR_AND);
3030 else if MBTEST(character == ';' && peek_char == '&')
3031 {
3032 parser_state |= PST_CASEPAT;
3033 #if defined (ALIAS)
3034 parser_state &= ~PST_ALEXPNEXT;
3035 #endif /* ALIAS */
3036 return (SEMI_AND);
3037 }
3038
3039 shell_ungetc (peek_char);
3040
3041 /* If we look like we are reading the start of a function
3042 definition, then let the reader know about it so that
3043 we will do the right thing with `{'. */
3044 if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
3045 {
3046 parser_state |= PST_ALLOWOPNBRC;
3047 #if defined (ALIAS)
3048 parser_state &= ~PST_ALEXPNEXT;
3049 #endif /* ALIAS */
3050 function_dstart = line_number;
3051 }
3052
3053 /* case pattern lists may be preceded by an optional left paren. If
3054 we're not trying to parse a case pattern list, the left paren
3055 indicates a subshell. */
3056 if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3057 parser_state |= PST_SUBSHELL;
3058 /*(*/
3059 else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
3060 parser_state &= ~PST_CASEPAT;
3061 /*(*/
3062 else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
3063 parser_state &= ~PST_SUBSHELL;
3064
3065 #if defined (PROCESS_SUBSTITUTION)
3066 /* Check for the constructs which introduce process substitution.
3067 Shells running in `posix mode' don't do process substitution. */
3068 if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
3069 #endif /* PROCESS_SUBSTITUTION */
3070 return (character);
3071 }
3072
3073 /* Hack <&- (close stdin) case. Also <&N- (dup and close). */
3074 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3075 return (character);
3076
3077 tokword:
3078 /* Okay, if we got this far, we have to read a word. Read one,
3079 and then check it against the known ones. */
3080 result = read_token_word (character);
3081 #if defined (ALIAS)
3082 if (result == RE_READ_TOKEN)
3083 goto re_read_token;
3084 #endif
3085 return result;
3086 }
3087
3088 /*
3089 * Match a $(...) or other grouping construct. This has to handle embedded
3090 * quoted strings ('', ``, "") and nested constructs. It also must handle
3091 * reprompting the user, if necessary, after reading a newline, and returning
3092 * correct error values if it reads EOF.
3093 */
3094 #define P_FIRSTCLOSE 0x0001
3095 #define P_ALLOWESC 0x0002
3096 #define P_DQUOTE 0x0004
3097 #define P_COMMAND 0x0008 /* parsing a command, so look for comments */
3098 #define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
3099 #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
3100 #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
3101
3102 /* Lexical state while parsing a grouping construct or $(...). */
3103 #define LEX_WASDOL 0x001
3104 #define LEX_CKCOMMENT 0x002
3105 #define LEX_INCOMMENT 0x004
3106 #define LEX_PASSNEXT 0x008
3107 #define LEX_RESWDOK 0x010
3108 #define LEX_CKCASE 0x020
3109 #define LEX_INCASE 0x040
3110 #define LEX_INHEREDOC 0x080
3111 #define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
3112 #define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
3113 #define LEX_INWORD 0x400
3114
3115 #define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
3116
3117 #define CHECK_NESTRET_ERROR() \
3118 do { \
3119 if (nestret == &matched_pair_error) \
3120 { \
3121 free (ret); \
3122 return &matched_pair_error; \
3123 } \
3124 } while (0)
3125
3126 #define APPEND_NESTRET() \
3127 do { \
3128 if (nestlen) \
3129 { \
3130 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
3131 strcpy (ret + retind, nestret); \
3132 retind += nestlen; \
3133 } \
3134 } while (0)
3135
3136 static char matched_pair_error;
3137
3138 static char *
3139 parse_matched_pair (qc, open, close, lenp, flags)
3140 int qc; /* `"' if this construct is within double quotes */
3141 int open, close;
3142 int *lenp, flags;
3143 {
3144 int count, ch, tflags;
3145 int nestlen, ttranslen, start_lineno;
3146 char *ret, *nestret, *ttrans;
3147 int retind, retsize, rflags;
3148 int dolbrace_state;
3149
3150 dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
3151
3152 /*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
3153 count = 1;
3154 tflags = 0;
3155
3156 if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3157 tflags |= LEX_CKCOMMENT;
3158
3159 /* RFLAGS is the set of flags we want to pass to recursive calls. */
3160 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
3161
3162 ret = (char *)xmalloc (retsize = 64);
3163 retind = 0;
3164
3165 start_lineno = line_number;
3166 while (count)
3167 {
3168 ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
3169
3170 if (ch == EOF)
3171 {
3172 free (ret);
3173 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3174 EOF_Reached = 1; /* XXX */
3175 return (&matched_pair_error);
3176 }
3177
3178 /* Possible reprompting. */
3179 if (ch == '\n' && SHOULD_PROMPT ())
3180 prompt_again ();
3181
3182 /* Don't bother counting parens or doing anything else if in a comment
3183 or part of a case statement */
3184 if (tflags & LEX_INCOMMENT)
3185 {
3186 /* Add this character. */
3187 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3188 ret[retind++] = ch;
3189
3190 if (ch == '\n')
3191 tflags &= ~LEX_INCOMMENT;
3192
3193 continue;
3194 }
3195
3196 /* Not exactly right yet, should handle shell metacharacters, too. If
3197 any changes are made to this test, make analogous changes to subst.c:
3198 extract_delimited_string(). */
3199 else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
3200 tflags |= LEX_INCOMMENT;
3201
3202 if (tflags & LEX_PASSNEXT) /* last char was backslash */
3203 {
3204 tflags &= ~LEX_PASSNEXT;
3205 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3206 {
3207 if (retind > 0)
3208 retind--; /* swallow previously-added backslash */
3209 continue;
3210 }
3211
3212 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3213 if MBTEST(ch == CTLESC || ch == CTLNUL)
3214 ret[retind++] = CTLESC;
3215 ret[retind++] = ch;
3216 continue;
3217 }
3218 /* If we're reparsing the input (e.g., from parse_string_to_word_list),
3219 we've already prepended CTLESC to single-quoted results of $'...'.
3220 We may want to do this for other CTLESC-quoted characters in
3221 reparse, too. */
3222 else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
3223 {
3224 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3225 ret[retind++] = ch;
3226 continue;
3227 }
3228 else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3229 {
3230 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3231 ret[retind++] = CTLESC;
3232 ret[retind++] = ch;
3233 continue;
3234 }
3235 else if MBTEST(ch == close) /* ending delimiter */
3236 count--;
3237 /* handle nested ${...} specially. */
3238 else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
3239 count++;
3240 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
3241 count++;
3242
3243 /* Add this character. */
3244 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3245 ret[retind++] = ch;
3246
3247 /* If we just read the ending character, don't bother continuing. */
3248 if (count == 0)
3249 break;
3250
3251 if (open == '\'') /* '' inside grouping construct */
3252 {
3253 if MBTEST((flags & P_ALLOWESC) && ch == '\\')
3254 tflags |= LEX_PASSNEXT;
3255 continue;
3256 }
3257
3258 if MBTEST(ch == '\\') /* backslashes */
3259 tflags |= LEX_PASSNEXT;
3260
3261 /* Based on which dolstate is currently in (param, op, or word),
3262 decide what the op is. We're really only concerned if it's % or
3263 #, so we can turn on a flag that says whether or not we should
3264 treat single quotes as special when inside a double-quoted
3265 ${...}. This logic must agree with subst.c:extract_dollar_brace_string
3266 since they share the same defines. */
3267 if (flags & P_DOLBRACE)
3268 {
3269 /* ${param%[%]word} */
3270 if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
3271 dolbrace_state = DOLBRACE_QUOTE;
3272 /* ${param#[#]word} */
3273 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
3274 dolbrace_state = DOLBRACE_QUOTE;
3275 /* ${param/[/]pat/rep} */
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 /* ${param,[,]pat} */
3282 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
3283 dolbrace_state = DOLBRACE_QUOTE;
3284 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
3285 dolbrace_state = DOLBRACE_OP;
3286 else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
3287 dolbrace_state = DOLBRACE_WORD;
3288 }
3289
3290 /* The big hammer. Single quotes aren't special in double quotes. The
3291 problem is that Posix used to say the single quotes are semi-special:
3292 within a double-quoted ${...} construct "an even number of
3293 unescaped double-quotes or single-quotes, if any, shall occur." */
3294 /* This was changed in Austin Group Interp 221 */
3295 if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
3296 continue;
3297
3298 /* Could also check open == '`' if we want to parse grouping constructs
3299 inside old-style command substitution. */
3300 if (open != close) /* a grouping construct */
3301 {
3302 if MBTEST(shellquote (ch))
3303 {
3304 /* '', ``, or "" inside $(...) or other grouping construct. */
3305 push_delimiter (dstack, ch);
3306 if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
3307 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3308 else
3309 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3310 pop_delimiter (dstack);
3311 CHECK_NESTRET_ERROR ();
3312
3313 if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3314 {
3315 /* Translate $'...' here. */
3316 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3317 xfree (nestret);
3318
3319 if ((rflags & P_DQUOTE) == 0)
3320 {
3321 nestret = sh_single_quote (ttrans);
3322 free (ttrans);
3323 nestlen = strlen (nestret);
3324 }
3325 else
3326 {
3327 nestret = ttrans;
3328 nestlen = ttranslen;
3329 }
3330 retind -= 2; /* back up before the $' */
3331 }
3332 else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3333 {
3334 /* Locale expand $"..." here. */
3335 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3336 xfree (nestret);
3337
3338 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3339 free (ttrans);
3340 nestlen = ttranslen + 2;
3341 retind -= 2; /* back up before the $" */
3342 }
3343
3344 APPEND_NESTRET ();
3345 FREE (nestret);
3346 }
3347 else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3348 goto parse_dollar_word;
3349 }
3350 /* Parse an old-style command substitution within double quotes as a
3351 single word. */
3352 /* XXX - sh and ksh93 don't do this - XXX */
3353 else if MBTEST(open == '"' && ch == '`')
3354 {
3355 nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
3356
3357 CHECK_NESTRET_ERROR ();
3358 APPEND_NESTRET ();
3359
3360 FREE (nestret);
3361 }
3362 else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3363 /* check for $(), $[], or ${} inside quoted string. */
3364 {
3365 parse_dollar_word:
3366 if (open == ch) /* undo previous increment */
3367 count--;
3368 if (ch == '(') /* ) */
3369 nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3370 else if (ch == '{') /* } */
3371 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3372 else if (ch == '[') /* ] */
3373 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3374
3375 CHECK_NESTRET_ERROR ();
3376 APPEND_NESTRET ();
3377
3378 FREE (nestret);
3379 }
3380 if MBTEST(ch == '$')
3381 tflags |= LEX_WASDOL;
3382 else
3383 tflags &= ~LEX_WASDOL;
3384 }
3385
3386 ret[retind] = '\0';
3387 if (lenp)
3388 *lenp = retind;
3389 /*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
3390 return ret;
3391 }
3392
3393 /* Parse a $(...) command substitution. This is messier than I'd like, and
3394 reproduces a lot more of the token-reading code than I'd like. */
3395 static char *
3396 parse_comsub (qc, open, close, lenp, flags)
3397 int qc; /* `"' if this construct is within double quotes */
3398 int open, close;
3399 int *lenp, flags;
3400 {
3401 int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
3402 int nestlen, ttranslen, start_lineno;
3403 char *ret, *nestret, *ttrans, *heredelim;
3404 int retind, retsize, rflags, hdlen;
3405
3406 /* Posix interp 217 says arithmetic expressions have precedence, so
3407 assume $(( introduces arithmetic expansion and parse accordingly. */
3408 peekc = shell_getc (0);
3409 shell_ungetc (peekc);
3410 if (peekc == '(')
3411 return (parse_matched_pair (qc, open, close, lenp, 0));
3412
3413 /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
3414 count = 1;
3415 tflags = LEX_RESWDOK;
3416
3417 if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3418 tflags |= LEX_CKCASE;
3419 if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
3420 tflags |= LEX_CKCOMMENT;
3421
3422 /* RFLAGS is the set of flags we want to pass to recursive calls. */
3423 rflags = (flags & P_DQUOTE);
3424
3425 ret = (char *)xmalloc (retsize = 64);
3426 retind = 0;
3427
3428 start_lineno = line_number;
3429 lex_rwlen = lex_wlen = 0;
3430
3431 heredelim = 0;
3432 lex_firstind = -1;
3433
3434 while (count)
3435 {
3436 comsub_readchar:
3437 ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0);
3438
3439 if (ch == EOF)
3440 {
3441 eof_error:
3442 free (ret);
3443 FREE (heredelim);
3444 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3445 EOF_Reached = 1; /* XXX */
3446 return (&matched_pair_error);
3447 }
3448
3449 /* If we hit the end of a line and are reading the contents of a here
3450 document, and it's not the same line that the document starts on,
3451 check for this line being the here doc delimiter. Otherwise, if
3452 we're in a here document, mark the next character as the beginning
3453 of a line. */
3454 if (ch == '\n')
3455 {
3456 if ((tflags & LEX_HEREDELIM) && heredelim)
3457 {
3458 tflags &= ~LEX_HEREDELIM;
3459 tflags |= LEX_INHEREDOC;
3460 lex_firstind = retind + 1;
3461 }
3462 else if (tflags & LEX_INHEREDOC)
3463 {
3464 int tind;
3465 tind = lex_firstind;
3466 while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3467 tind++;
3468 if (STREQN (ret + tind, heredelim, hdlen))
3469 {
3470 tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
3471 /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
3472 free (heredelim);
3473 heredelim = 0;
3474 lex_firstind = -1;
3475 }
3476 else
3477 lex_firstind = retind + 1;
3478 }
3479 }
3480
3481 /* Possible reprompting. */
3482 if (ch == '\n' && SHOULD_PROMPT ())
3483 prompt_again ();
3484
3485 /* XXX -- possibly allow here doc to be delimited by ending right
3486 paren. */
3487 if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
3488 {
3489 int tind;
3490 /*itrace("parse_comsub: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", retind-lex_firstind, hdlen, retind);*/
3491 tind = lex_firstind;
3492 while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3493 tind++;
3494 if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
3495 {
3496 tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
3497 /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
3498 free (heredelim);
3499 heredelim = 0;
3500 lex_firstind = -1;
3501 }
3502 }
3503
3504 /* Don't bother counting parens or doing anything else if in a comment */
3505 if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
3506 {
3507 /* Add this character. */
3508 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3509 ret[retind++] = ch;
3510
3511 if ((tflags & LEX_INCOMMENT) && ch == '\n')
3512 {
3513 /*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/
3514 tflags &= ~LEX_INCOMMENT;
3515 }
3516
3517 continue;
3518 }
3519
3520 if (tflags & LEX_PASSNEXT) /* last char was backslash */
3521 {
3522 /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3523 tflags &= ~LEX_PASSNEXT;
3524 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3525 {
3526 if (retind > 0)
3527 retind--; /* swallow previously-added backslash */
3528 continue;
3529 }
3530
3531 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3532 if MBTEST(ch == CTLESC || ch == CTLNUL)
3533 ret[retind++] = CTLESC;
3534 ret[retind++] = ch;
3535 continue;
3536 }
3537
3538 /* If this is a shell break character, we are not in a word. If not,
3539 we either start or continue a word. */
3540 if MBTEST(shellbreak (ch))
3541 {
3542 tflags &= ~LEX_INWORD;
3543 /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3544 }
3545 else
3546 {
3547 if (tflags & LEX_INWORD)
3548 {
3549 lex_wlen++;
3550 /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
3551 }
3552 else
3553 {
3554 /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3555 tflags |= LEX_INWORD;
3556 lex_wlen = 0;
3557 }
3558 }
3559
3560 /* Skip whitespace */
3561 if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0)
3562 {
3563 /* Add this character. */
3564 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3565 ret[retind++] = ch;
3566 continue;
3567 }
3568
3569 /* Either we are looking for the start of the here-doc delimiter
3570 (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
3571 If this character is a shell break character and we are reading
3572 the delimiter, save it and note that we are now reading a here
3573 document. If we've found the start of the delimiter, note it by
3574 setting lex_firstind. Backslashes can quote shell metacharacters
3575 in here-doc delimiters. */
3576 if (tflags & LEX_HEREDELIM)
3577 {
3578 if (lex_firstind == -1 && shellbreak (ch) == 0)
3579 lex_firstind = retind;
3580 #if 0
3581 else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n')
3582 {
3583 tflags |= LEX_INHEREDOC;
3584 tflags &= ~LEX_HEREDELIM;
3585 lex_firstind = retind + 1;
3586 }
3587 #endif
3588 else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
3589 {
3590 if (heredelim == 0)
3591 {
3592 nestret = substring (ret, lex_firstind, retind);
3593 heredelim = string_quote_removal (nestret, 0);
3594 free (nestret);
3595 hdlen = STRLEN(heredelim);
3596 /*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
3597 }
3598 if (ch == '\n')
3599 {
3600 tflags |= LEX_INHEREDOC;
3601 tflags &= ~LEX_HEREDELIM;
3602 lex_firstind = retind + 1;
3603 }
3604 else
3605 lex_firstind = -1;
3606 }
3607 }
3608
3609 /* Meta-characters that can introduce a reserved word. Not perfect yet. */
3610 if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
3611 {
3612 /* Add this character. */
3613 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3614 ret[retind++] = ch;
3615 peekc = shell_getc (1);
3616 if (ch == peekc && (ch == '&' || ch == '|' || ch == ';')) /* two-character tokens */
3617 {
3618 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3619 ret[retind++] = peekc;
3620 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
3621 tflags |= LEX_RESWDOK;
3622 lex_rwlen = 0;
3623 continue;
3624 }
3625 else if (ch == '\n' || COMSUB_META(ch))
3626 {
3627 shell_ungetc (peekc);
3628 /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
3629 tflags |= LEX_RESWDOK;
3630 lex_rwlen = 0;
3631 continue;
3632 }
3633 else if (ch == EOF)
3634 goto eof_error;
3635 else
3636 {
3637 /* `unget' the character we just added and fall through */
3638 retind--;
3639 shell_ungetc (peekc);
3640 }
3641 }
3642
3643 /* If we can read a reserved word, try to read one. */
3644 if (tflags & LEX_RESWDOK)
3645 {
3646 if MBTEST(islower (ch))
3647 {
3648 /* Add this character. */
3649 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3650 ret[retind++] = ch;
3651 lex_rwlen++;
3652 continue;
3653 }
3654 else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
3655 {
3656 if (STREQN (ret + retind - 4, "case", 4))
3657 {
3658 tflags |= LEX_INCASE;
3659 /*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
3660 }
3661 else if (STREQN (ret + retind - 4, "esac", 4))
3662 {
3663 tflags &= ~LEX_INCASE;
3664 /*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 0", line_number);*/
3665 }
3666 tflags &= ~LEX_RESWDOK;
3667 }
3668 else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
3669 ; /* don't modify LEX_RESWDOK if we're starting a comment */
3670 else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
3671 /* If we can read a reserved word and we're in case, we're at the
3672 point where we can read a new pattern list or an esac. We
3673 handle the esac case above. If we read a newline, we want to
3674 leave LEX_RESWDOK alone. If we read anything else, we want to
3675 turn off LEX_RESWDOK, since we're going to read a pattern list. */
3676 {
3677 tflags &= ~LEX_RESWDOK;
3678 /*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
3679 }
3680 else if MBTEST(shellbreak (ch) == 0)
3681 {
3682 tflags &= ~LEX_RESWDOK;
3683 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
3684 }
3685 }
3686
3687 /* Might be the start of a here-doc delimiter */
3688 if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
3689 {
3690 /* Add this character. */
3691 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3692 ret[retind++] = ch;
3693 peekc = shell_getc (1);
3694 if (peekc == EOF)
3695 goto eof_error;
3696 if (peekc == ch)
3697 {
3698 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3699 ret[retind++] = peekc;
3700 peekc = shell_getc (1);
3701 if (peekc == EOF)
3702 goto eof_error;
3703 if (peekc == '-')
3704 {
3705 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3706 ret[retind++] = peekc;
3707 tflags |= LEX_STRIPDOC;
3708 }
3709 else
3710 shell_ungetc (peekc);
3711 if (peekc != '<')
3712 {
3713 tflags |= LEX_HEREDELIM;
3714 lex_firstind = -1;
3715 }
3716 continue;
3717 }
3718 else
3719 ch = peekc; /* fall through and continue XXX */
3720 }
3721 else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
3722 {
3723 /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
3724 tflags |= LEX_INCOMMENT;
3725 }
3726
3727 if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3728 {
3729 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3730 ret[retind++] = CTLESC;
3731 ret[retind++] = ch;
3732 continue;
3733 }
3734 #if 0
3735 else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
3736 tflags &= ~LEX_INCASE; /* XXX */
3737 #endif
3738 else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0) /* ending delimiter */
3739 {
3740 count--;
3741 /*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
3742 }
3743 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */
3744 {
3745 count++;
3746 /*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
3747 }
3748
3749 /* Add this character. */
3750 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3751 ret[retind++] = ch;
3752
3753 /* If we just read the ending character, don't bother continuing. */
3754 if (count == 0)
3755 break;
3756
3757 if MBTEST(ch == '\\') /* backslashes */
3758 tflags |= LEX_PASSNEXT;
3759
3760 if MBTEST(shellquote (ch))
3761 {
3762 /* '', ``, or "" inside $(...). */
3763 push_delimiter (dstack, ch);
3764 if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
3765 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
3766 else
3767 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
3768 pop_delimiter (dstack);
3769 CHECK_NESTRET_ERROR ();
3770
3771 if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
3772 {
3773 /* Translate $'...' here. */
3774 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
3775 xfree (nestret);
3776
3777 if ((rflags & P_DQUOTE) == 0)
3778 {
3779 nestret = sh_single_quote (ttrans);
3780 free (ttrans);
3781 nestlen = strlen (nestret);
3782 }
3783 else
3784 {
3785 nestret = ttrans;
3786 nestlen = ttranslen;
3787 }
3788 retind -= 2; /* back up before the $' */
3789 }
3790 else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
3791 {
3792 /* Locale expand $"..." here. */
3793 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
3794 xfree (nestret);
3795
3796 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
3797 free (ttrans);
3798 nestlen = ttranslen + 2;
3799 retind -= 2; /* back up before the $" */
3800 }
3801
3802 APPEND_NESTRET ();
3803 FREE (nestret);
3804 }
3805 else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3806 /* check for $(), $[], or ${} inside command substitution. */
3807 {
3808 if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */
3809 count--;
3810 if (ch == '(') /* ) */
3811 nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3812 else if (ch == '{') /* } */
3813 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3814 else if (ch == '[') /* ] */
3815 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3816
3817 CHECK_NESTRET_ERROR ();
3818 APPEND_NESTRET ();
3819
3820 FREE (nestret);
3821 }
3822 if MBTEST(ch == '$')
3823 tflags |= LEX_WASDOL;
3824 else
3825 tflags &= ~LEX_WASDOL;
3826 }
3827
3828 FREE (heredelim);
3829 ret[retind] = '\0';
3830 if (lenp)
3831 *lenp = retind;
3832 /*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
3833 return ret;
3834 }
3835
3836 /* Recursively call the parser to parse a $(...) command substitution. */
3837 char *
3838 xparse_dolparen (base, string, indp, flags)
3839 char *base;
3840 char *string;
3841 int *indp;
3842 int flags;
3843 {
3844 sh_parser_state_t ps;
3845 int orig_ind, nc, sflags;
3846 char *ret, *s, *ep, *ostring;
3847
3848 /*yydebug = 1;*/
3849 orig_ind = *indp;
3850 ostring = string;
3851
3852 sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
3853 if (flags & SX_NOLONGJMP)
3854 sflags |= SEVAL_NOLONGJMP;
3855 save_parser_state (&ps);
3856
3857 /*(*/
3858 parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
3859 shell_eof_token = ')';
3860 parse_string (string, "command substitution", sflags, &ep);
3861
3862 restore_parser_state (&ps);
3863 reset_parser ();
3864 if (interactive)
3865 token_to_read = 0;
3866
3867 /* Need to find how many characters parse_and_execute consumed, update
3868 *indp, if flags != 0, copy the portion of the string parsed into RET
3869 and return it. If flags & 1 (EX_NOALLOC) we can return NULL. */
3870
3871 /*(*/
3872 if (ep[-1] != ')')
3873 {
3874 #if DEBUG
3875 if (ep[-1] != '\n')
3876 itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
3877 #endif
3878 while (ep > ostring && ep[-1] == '\n') ep--;
3879 }
3880
3881 nc = ep - ostring;
3882 *indp = ep - base - 1;
3883
3884 /*(*/
3885 #if DEBUG
3886 if (base[*indp] != ')')
3887 itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
3888 #endif
3889
3890 if (flags & SX_NOALLOC)
3891 return (char *)NULL;
3892
3893 if (nc == 0)
3894 {
3895 ret = xmalloc (1);
3896 ret[0] = '\0';
3897 }
3898 else
3899 ret = substring (ostring, 0, nc - 1);
3900
3901 return ret;
3902 }
3903
3904 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3905 /* Parse a double-paren construct. It can be either an arithmetic
3906 command, an arithmetic `for' command, or a nested subshell. Returns
3907 the parsed token, -1 on error, or -2 if we didn't do anything and
3908 should just go on. */
3909 static int
3910 parse_dparen (c)
3911 int c;
3912 {
3913 int cmdtyp, sline;
3914 char *wval;
3915 WORD_DESC *wd;
3916
3917 #if defined (ARITH_FOR_COMMAND)
3918 if (last_read_token == FOR)
3919 {
3920 arith_for_lineno = line_number;
3921 cmdtyp = parse_arith_cmd (&wval, 0);
3922 if (cmdtyp == 1)
3923 {
3924 wd = alloc_word_desc ();
3925 wd->word = wval;
3926 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3927 return (ARITH_FOR_EXPRS);
3928 }
3929 else
3930 return -1; /* ERROR */
3931 }
3932 #endif
3933
3934 #if defined (DPAREN_ARITHMETIC)
3935 if (reserved_word_acceptable (last_read_token))
3936 {
3937 sline = line_number;
3938
3939 cmdtyp = parse_arith_cmd (&wval, 0);
3940 if (cmdtyp == 1) /* arithmetic command */
3941 {
3942 wd = alloc_word_desc ();
3943 wd->word = wval;
3944 wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
3945 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3946 return (ARITH_CMD);
3947 }
3948 else if (cmdtyp == 0) /* nested subshell */
3949 {
3950 push_string (wval, 0, (alias_t *)NULL);
3951 if ((parser_state & PST_CASEPAT) == 0)
3952 parser_state |= PST_SUBSHELL;
3953 return (c);
3954 }
3955 else /* ERROR */
3956 return -1;
3957 }
3958 #endif
3959
3960 return -2; /* XXX */
3961 }
3962
3963 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
3964 If not, assume it's a nested subshell for backwards compatibility and
3965 return 0. In any case, put the characters we've consumed into a locally-
3966 allocated buffer and make *ep point to that buffer. Return -1 on an
3967 error, for example EOF. */
3968 static int
3969 parse_arith_cmd (ep, adddq)
3970 char **ep;
3971 int adddq;
3972 {
3973 int exp_lineno, rval, c;
3974 char *ttok, *tokstr;
3975 int ttoklen;
3976
3977 exp_lineno = line_number;
3978 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3979 rval = 1;
3980 if (ttok == &matched_pair_error)
3981 return -1;
3982 /* Check that the next character is the closing right paren. If
3983 not, this is a syntax error. ( */
3984 c = shell_getc (0);
3985 if MBTEST(c != ')')
3986 rval = 0;
3987
3988 tokstr = (char *)xmalloc (ttoklen + 4);
3989
3990 /* if ADDDQ != 0 then (( ... )) -> "..." */
3991 if (rval == 1 && adddq) /* arith cmd, add double quotes */
3992 {
3993 tokstr[0] = '"';
3994 strncpy (tokstr + 1, ttok, ttoklen - 1);
3995 tokstr[ttoklen] = '"';
3996 tokstr[ttoklen+1] = '\0';
3997 }
3998 else if (rval == 1) /* arith cmd, don't add double quotes */
3999 {
4000 strncpy (tokstr, ttok, ttoklen - 1);
4001 tokstr[ttoklen-1] = '\0';
4002 }
4003 else /* nested subshell */
4004 {
4005 tokstr[0] = '(';
4006 strncpy (tokstr + 1, ttok, ttoklen - 1);
4007 tokstr[ttoklen] = ')';
4008 tokstr[ttoklen+1] = c;
4009 tokstr[ttoklen+2] = '\0';
4010 }
4011
4012 *ep = tokstr;
4013 FREE (ttok);
4014 return rval;
4015 }
4016 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
4017
4018 #if defined (COND_COMMAND)
4019 static void
4020 cond_error ()
4021 {
4022 char *etext;
4023
4024 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
4025 parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
4026 else if (cond_token != COND_ERROR)
4027 {
4028 if (etext = error_token_from_token (cond_token))
4029 {
4030 parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
4031 free (etext);
4032 }
4033 else
4034 parser_error (cond_lineno, _("syntax error in conditional expression"));
4035 }
4036 }
4037
4038 static COND_COM *
4039 cond_expr ()
4040 {
4041 return (cond_or ());
4042 }
4043
4044 static COND_COM *
4045 cond_or ()
4046 {
4047 COND_COM *l, *r;
4048
4049 l = cond_and ();
4050 if (cond_token == OR_OR)
4051 {
4052 r = cond_or ();
4053 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
4054 }
4055 return l;
4056 }
4057
4058 static COND_COM *
4059 cond_and ()
4060 {
4061 COND_COM *l, *r;
4062
4063 l = cond_term ();
4064 if (cond_token == AND_AND)
4065 {
4066 r = cond_and ();
4067 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
4068 }
4069 return l;
4070 }
4071
4072 static int
4073 cond_skip_newlines ()
4074 {
4075 while ((cond_token = read_token (READ)) == '\n')
4076 {
4077 if (SHOULD_PROMPT ())
4078 prompt_again ();
4079 }
4080 return (cond_token);
4081 }
4082
4083 #define COND_RETURN_ERROR() \
4084 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
4085
4086 static COND_COM *
4087 cond_term ()
4088 {
4089 WORD_DESC *op;
4090 COND_COM *term, *tleft, *tright;
4091 int tok, lineno;
4092 char *etext;
4093
4094 /* Read a token. It can be a left paren, a `!', a unary operator, or a
4095 word that should be the first argument of a binary operator. Start by
4096 skipping newlines, since this is a compound command. */
4097 tok = cond_skip_newlines ();
4098 lineno = line_number;
4099 if (tok == COND_END)
4100 {
4101 COND_RETURN_ERROR ();
4102 }
4103 else if (tok == '(')
4104 {
4105 term = cond_expr ();
4106 if (cond_token != ')')
4107 {
4108 if (term)
4109 dispose_cond_node (term); /* ( */
4110 if (etext = error_token_from_token (cond_token))
4111 {
4112 parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
4113 free (etext);
4114 }
4115 else
4116 parser_error (lineno, _("expected `)'"));
4117 COND_RETURN_ERROR ();
4118 }
4119 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
4120 (void)cond_skip_newlines ();
4121 }
4122 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
4123 {
4124 if (tok == WORD)
4125 dispose_word (yylval.word); /* not needed */
4126 term = cond_term ();
4127 if (term)
4128 term->flags |= CMD_INVERT_RETURN;
4129 }
4130 else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
4131 {
4132 op = yylval.word;
4133 tok = read_token (READ);
4134 if (tok == WORD)
4135 {
4136 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4137 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4138 }
4139 else
4140 {
4141 dispose_word (op);
4142 if (etext = error_token_from_token (tok))
4143 {
4144 parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
4145 free (etext);
4146 }
4147 else
4148 parser_error (line_number, _("unexpected argument to conditional unary operator"));
4149 COND_RETURN_ERROR ();
4150 }
4151
4152 (void)cond_skip_newlines ();
4153 }
4154 else if (tok == WORD) /* left argument to binary operator */
4155 {
4156 /* lhs */
4157 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4158
4159 /* binop */
4160 tok = read_token (READ);
4161 if (tok == WORD && test_binop (yylval.word->word))
4162 {
4163 op = yylval.word;
4164 if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
4165 parser_state |= PST_EXTPAT;
4166 else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
4167 parser_state |= PST_EXTPAT;
4168 }
4169 #if defined (COND_REGEXP)
4170 else if (tok == WORD && STREQ (yylval.word->word, "=~"))
4171 {
4172 op = yylval.word;
4173 parser_state |= PST_REGEXP;
4174 }
4175 #endif
4176 else if (tok == '<' || tok == '>')
4177 op = make_word_from_token (tok); /* ( */
4178 /* There should be a check before blindly accepting the `)' that we have
4179 seen the opening `('. */
4180 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
4181 {
4182 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
4183 the test command. Similarly for [[ x && expr ]] or
4184 [[ x || expr ]] or [[ (x) ]]. */
4185 op = make_word ("-n");
4186 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4187 cond_token = tok;
4188 return (term);
4189 }
4190 else
4191 {
4192 if (etext = error_token_from_token (tok))
4193 {
4194 parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
4195 free (etext);
4196 }
4197 else
4198 parser_error (line_number, _("conditional binary operator expected"));
4199 dispose_cond_node (tleft);
4200 COND_RETURN_ERROR ();
4201 }
4202
4203 /* rhs */
4204 if (parser_state & PST_EXTPAT)
4205 extended_glob = 1;
4206 tok = read_token (READ);
4207 if (parser_state & PST_EXTPAT)
4208 extended_glob = global_extglob;
4209 parser_state &= ~(PST_REGEXP|PST_EXTPAT);
4210
4211 if (tok == WORD)
4212 {
4213 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4214 term = make_cond_node (COND_BINARY, op, tleft, tright);
4215 }
4216 else
4217 {
4218 if (etext = error_token_from_token (tok))
4219 {
4220 parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
4221 free (etext);
4222 }
4223 else
4224 parser_error (line_number, _("unexpected argument to conditional binary operator"));
4225 dispose_cond_node (tleft);
4226 dispose_word (op);
4227 COND_RETURN_ERROR ();
4228 }
4229
4230 (void)cond_skip_newlines ();
4231 }
4232 else
4233 {
4234 if (tok < 256)
4235 parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
4236 else if (etext = error_token_from_token (tok))
4237 {
4238 parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
4239 free (etext);
4240 }
4241 else
4242 parser_error (line_number, _("unexpected token %d in conditional command"), tok);
4243 COND_RETURN_ERROR ();
4244 }
4245 return (term);
4246 }
4247
4248 /* This is kind of bogus -- we slip a mini recursive-descent parser in
4249 here to handle the conditional statement syntax. */
4250 static COMMAND *
4251 parse_cond_command ()
4252 {
4253 COND_COM *cexp;
4254
4255 global_extglob = extended_glob;
4256 cexp = cond_expr ();
4257 return (make_cond_command (cexp));
4258 }
4259 #endif
4260
4261 #if defined (ARRAY_VARS)
4262 /* When this is called, it's guaranteed that we don't care about anything
4263 in t beyond i. We do save and restore the chars, though. */
4264 static int
4265 token_is_assignment (t, i)
4266 char *t;
4267 int i;
4268 {
4269 unsigned char c, c1;
4270 int r;
4271
4272 c = t[i]; c1 = t[i+1];
4273 t[i] = '='; t[i+1] = '\0';
4274 r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
4275 t[i] = c; t[i+1] = c1;
4276 return r;
4277 }
4278
4279 /* XXX - possible changes here for `+=' */
4280 static int
4281 token_is_ident (t, i)
4282 char *t;
4283 int i;
4284 {
4285 unsigned char c;
4286 int r;
4287
4288 c = t[i];
4289 t[i] = '\0';
4290 r = legal_identifier (t);
4291 t[i] = c;
4292 return r;
4293 }
4294 #endif
4295
4296 static int
4297 read_token_word (character)
4298 int character;
4299 {
4300 /* The value for YYLVAL when a WORD is read. */
4301 WORD_DESC *the_word;
4302
4303 /* Index into the token that we are building. */
4304 int token_index;
4305
4306 /* ALL_DIGITS becomes zero when we see a non-digit. */
4307 int all_digit_token;
4308
4309 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4310 int dollar_present;
4311
4312 /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4313 assignment. */
4314 int compound_assignment;
4315
4316 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4317 int quoted;
4318
4319 /* Non-zero means to ignore the value of the next character, and just
4320 to add it no matter what. */
4321 int pass_next_character;
4322
4323 /* The current delimiting character. */
4324 int cd;
4325 int result, peek_char;
4326 char *ttok, *ttrans;
4327 int ttoklen, ttranslen;
4328 intmax_t lvalue;
4329
4330 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
4331 token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
4332
4333 token_index = 0;
4334 all_digit_token = DIGIT (character);
4335 dollar_present = quoted = pass_next_character = compound_assignment = 0;
4336
4337 for (;;)
4338 {
4339 if (character == EOF)
4340 goto got_token;
4341
4342 if (pass_next_character)
4343 {
4344 pass_next_character = 0;
4345 goto got_escaped_character;
4346 }
4347
4348 cd = current_delimiter (dstack);
4349
4350 /* Handle backslashes. Quote lots of things when not inside of
4351 double-quotes, quote some things inside of double-quotes. */
4352 if MBTEST(character == '\\')
4353 {
4354 peek_char = shell_getc (0);
4355
4356 /* Backslash-newline is ignored in all cases except
4357 when quoted with single quotes. */
4358 if (peek_char == '\n')
4359 {
4360 character = '\n';
4361 goto next_character;
4362 }
4363 else
4364 {
4365 shell_ungetc (peek_char);
4366
4367 /* If the next character is to be quoted, note it now. */
4368 if (cd == 0 || cd == '`' ||
4369 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
4370 pass_next_character++;
4371
4372 quoted = 1;
4373 goto got_character;
4374 }
4375 }
4376
4377 /* Parse a matched pair of quote characters. */
4378 if MBTEST(shellquote (character))
4379 {
4380 push_delimiter (dstack, character);
4381 ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
4382 pop_delimiter (dstack);
4383 if (ttok == &matched_pair_error)
4384 return -1; /* Bail immediately. */
4385 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4386 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4387 token[token_index++] = character;
4388 strcpy (token + token_index, ttok);
4389 token_index += ttoklen;
4390 all_digit_token = 0;
4391 quoted = 1;
4392 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4393 FREE (ttok);
4394 goto next_character;
4395 }
4396
4397 #ifdef COND_REGEXP
4398 /* When parsing a regexp as a single word inside a conditional command,
4399 we need to special-case characters special to both the shell and
4400 regular expressions. Right now, that is only '(' and '|'. */ /*)*/
4401 if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/
4402 {
4403 if (character == '|')
4404 goto got_character;
4405
4406 push_delimiter (dstack, character);
4407 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4408 pop_delimiter (dstack);
4409 if (ttok == &matched_pair_error)
4410 return -1; /* Bail immediately. */
4411 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4412 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4413 token[token_index++] = character;
4414 strcpy (token + token_index, ttok);
4415 token_index += ttoklen;
4416 FREE (ttok);
4417 dollar_present = all_digit_token = 0;
4418 goto next_character;
4419 }
4420 #endif /* COND_REGEXP */
4421
4422 #ifdef EXTENDED_GLOB
4423 /* Parse a ksh-style extended pattern matching specification. */
4424 if MBTEST(extended_glob && PATTERN_CHAR (character))
4425 {
4426 peek_char = shell_getc (1);
4427 if MBTEST(peek_char == '(') /* ) */
4428 {
4429 push_delimiter (dstack, peek_char);
4430 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4431 pop_delimiter (dstack);
4432 if (ttok == &matched_pair_error)
4433 return -1; /* Bail immediately. */
4434 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4435 token_buffer_size,
4436 TOKEN_DEFAULT_GROW_SIZE);
4437 token[token_index++] = character;
4438 token[token_index++] = peek_char;
4439 strcpy (token + token_index, ttok);
4440 token_index += ttoklen;
4441 FREE (ttok);
4442 dollar_present = all_digit_token = 0;
4443 goto next_character;
4444 }
4445 else
4446 shell_ungetc (peek_char);
4447 }
4448 #endif /* EXTENDED_GLOB */
4449
4450 /* If the delimiter character is not single quote, parse some of
4451 the shell expansions that must be read as a single word. */
4452 if (shellexp (character))
4453 {
4454 peek_char = shell_getc (1);
4455 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4456 if MBTEST(peek_char == '(' || \
4457 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4458 {
4459 if (peek_char == '{') /* } */
4460 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
4461 else if (peek_char == '(') /* ) */
4462 {
4463 /* XXX - push and pop the `(' as a delimiter for use by
4464 the command-oriented-history code. This way newlines
4465 appearing in the $(...) string get added to the
4466 history literally rather than causing a possibly-
4467 incorrect `;' to be added. ) */
4468 push_delimiter (dstack, peek_char);
4469 ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
4470 pop_delimiter (dstack);
4471 }
4472 else
4473 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4474 if (ttok == &matched_pair_error)
4475 return -1; /* Bail immediately. */
4476 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4477 token_buffer_size,
4478 TOKEN_DEFAULT_GROW_SIZE);
4479 token[token_index++] = character;
4480 token[token_index++] = peek_char;
4481 strcpy (token + token_index, ttok);
4482 token_index += ttoklen;
4483 FREE (ttok);
4484 dollar_present = 1;
4485 all_digit_token = 0;
4486 goto next_character;
4487 }
4488 /* This handles $'...' and $"..." new-style quoted strings. */
4489 else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
4490 {
4491 int first_line;
4492
4493 first_line = line_number;
4494 push_delimiter (dstack, peek_char);
4495 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4496 &ttoklen,
4497 (peek_char == '\'') ? P_ALLOWESC : 0);
4498 pop_delimiter (dstack);
4499 if (ttok == &matched_pair_error)
4500 return -1;
4501 if (peek_char == '\'')
4502 {
4503 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4504 free (ttok);
4505
4506 /* Insert the single quotes and correctly quote any
4507 embedded single quotes (allowed because P_ALLOWESC was
4508 passed to parse_matched_pair). */
4509 ttok = sh_single_quote (ttrans);
4510 free (ttrans);
4511 ttranslen = strlen (ttok);
4512 ttrans = ttok;
4513 }
4514 else
4515 {
4516 /* Try to locale-expand the converted string. */
4517 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4518 free (ttok);
4519
4520 /* Add the double quotes back */
4521 ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
4522 free (ttrans);
4523 ttranslen += 2;
4524 ttrans = ttok;
4525 }
4526
4527 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4528 token_buffer_size,
4529 TOKEN_DEFAULT_GROW_SIZE);
4530 strcpy (token + token_index, ttrans);
4531 token_index += ttranslen;
4532 FREE (ttrans);
4533 quoted = 1;
4534 all_digit_token = 0;
4535 goto next_character;
4536 }
4537 /* This could eventually be extended to recognize all of the
4538 shell's single-character parameter expansions, and set flags.*/
4539 else if MBTEST(character == '$' && peek_char == '$')
4540 {
4541 ttok = (char *)xmalloc (3);
4542 ttok[0] = ttok[1] = '$';
4543 ttok[2] = '\0';
4544 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4545 token_buffer_size,
4546 TOKEN_DEFAULT_GROW_SIZE);
4547 strcpy (token + token_index, ttok);
4548 token_index += 2;
4549 dollar_present = 1;
4550 all_digit_token = 0;
4551 FREE (ttok);
4552 goto next_character;
4553 }
4554 else
4555 shell_ungetc (peek_char);
4556 }
4557
4558 #if defined (ARRAY_VARS)
4559 /* Identify possible array subscript assignment; match [...]. If
4560 parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
4561 `sub' as if it were enclosed in double quotes. */
4562 else if MBTEST(character == '[' && /* ] */
4563 ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
4564 (token_index == 0 && (parser_state&PST_COMPASSIGN))))
4565 {
4566 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
4567 if (ttok == &matched_pair_error)
4568 return -1; /* Bail immediately. */
4569 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4570 token_buffer_size,
4571 TOKEN_DEFAULT_GROW_SIZE);
4572 token[token_index++] = character;
4573 strcpy (token + token_index, ttok);
4574 token_index += ttoklen;
4575 FREE (ttok);
4576 all_digit_token = 0;
4577 goto next_character;
4578 }
4579 /* Identify possible compound array variable assignment. */
4580 else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
4581 {
4582 peek_char = shell_getc (1);
4583 if MBTEST(peek_char == '(') /* ) */
4584 {
4585 ttok = parse_compound_assignment (&ttoklen);
4586
4587 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
4588 token_buffer_size,
4589 TOKEN_DEFAULT_GROW_SIZE);
4590
4591 token[token_index++] = '=';
4592 token[token_index++] = '(';
4593 if (ttok)
4594 {
4595 strcpy (token + token_index, ttok);
4596 token_index += ttoklen;
4597 }
4598 token[token_index++] = ')';
4599 FREE (ttok);
4600 all_digit_token = 0;
4601 compound_assignment = 1;
4602 #if 1
4603 goto next_character;
4604 #else
4605 goto got_token; /* ksh93 seems to do this */
4606 #endif
4607 }
4608 else
4609 shell_ungetc (peek_char);
4610 }
4611 #endif
4612
4613 /* When not parsing a multi-character word construct, shell meta-
4614 characters break words. */
4615 if MBTEST(shellbreak (character))
4616 {
4617 shell_ungetc (character);
4618 goto got_token;
4619 }
4620
4621 got_character:
4622
4623 if (character == CTLESC || character == CTLNUL)
4624 token[token_index++] = CTLESC;
4625
4626 got_escaped_character:
4627
4628 all_digit_token &= DIGIT (character);
4629 dollar_present |= character == '$';
4630
4631 token[token_index++] = character;
4632
4633 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4634 TOKEN_DEFAULT_GROW_SIZE);
4635
4636 next_character:
4637 if (character == '\n' && SHOULD_PROMPT ())
4638 prompt_again ();
4639
4640 /* We want to remove quoted newlines (that is, a \<newline> pair)
4641 unless we are within single quotes or pass_next_character is
4642 set (the shell equivalent of literal-next). */
4643 cd = current_delimiter (dstack);
4644 character = shell_getc (cd != '\'' && pass_next_character == 0);
4645 } /* end for (;;) */
4646
4647 got_token:
4648
4649 token[token_index] = '\0';
4650
4651 /* Check to see what thing we should return. If the last_read_token
4652 is a `<', or a `&', or the character which ended this token is
4653 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4654 Otherwise, it is just a word, and should be returned as such. */
4655 if MBTEST(all_digit_token && (character == '<' || character == '>' || \
4656 last_read_token == LESS_AND || \
4657 last_read_token == GREATER_AND))
4658 {
4659 if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
4660 yylval.number = lvalue;
4661 else
4662 yylval.number = -1;
4663 return (NUMBER);
4664 }
4665
4666 /* Check for special case tokens. */
4667 result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
4668 if (result >= 0)
4669 return result;
4670
4671 #if defined (ALIAS)
4672 /* Posix.2 does not allow reserved words to be aliased, so check for all
4673 of them, including special cases, before expanding the current token
4674 as an alias. */
4675 if MBTEST(posixly_correct)
4676 CHECK_FOR_RESERVED_WORD (token);
4677
4678 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4679 inhibits alias expansion. */
4680 if (expand_aliases && quoted == 0)
4681 {
4682 result = alias_expand_token (token);
4683 if (result == RE_READ_TOKEN)
4684 return (RE_READ_TOKEN);
4685 else if (result == NO_EXPANSION)
4686 parser_state &= ~PST_ALEXPNEXT;
4687 }
4688
4689 /* If not in Posix.2 mode, check for reserved words after alias
4690 expansion. */
4691 if MBTEST(posixly_correct == 0)
4692 #endif
4693 CHECK_FOR_RESERVED_WORD (token);
4694
4695 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4696 the_word->word = (char *)xmalloc (1 + token_index);
4697 the_word->flags = 0;
4698 strcpy (the_word->word, token);
4699 if (dollar_present)
4700 the_word->flags |= W_HASDOLLAR;
4701 if (quoted)
4702 the_word->flags |= W_QUOTED; /*(*/
4703 if (compound_assignment && token[token_index-1] == ')')
4704 the_word->flags |= W_COMPASSIGN;
4705 /* A word is an assignment if it appears at the beginning of a
4706 simple command, or after another assignment word. This is
4707 context-dependent, so it cannot be handled in the grammar. */
4708 if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
4709 {
4710 the_word->flags |= W_ASSIGNMENT;
4711 /* Don't perform word splitting on assignment statements. */
4712 if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
4713 the_word->flags |= W_NOSPLIT;
4714 }
4715
4716 if (command_token_position (last_read_token))
4717 {
4718 struct builtin *b;
4719 b = builtin_address_internal (token, 0);
4720 if (b && (b->flags & ASSIGNMENT_BUILTIN))
4721 parser_state |= PST_ASSIGNOK;
4722 else if (STREQ (token, "eval") || STREQ (token, "let"))
4723 parser_state |= PST_ASSIGNOK;
4724 }
4725
4726 yylval.word = the_word;
4727
4728 if (token[0] == '{' && token[token_index-1] == '}' &&
4729 (character == '<' || character == '>'))
4730 {
4731 /* can use token; already copied to the_word */
4732 token[token_index-1] = '\0';
4733 if (legal_identifier (token+1))
4734 {
4735 strcpy (the_word->word, token+1);
4736 /*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
4737 return (REDIR_WORD);
4738 }
4739 }
4740
4741 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4742 ? ASSIGNMENT_WORD : WORD;
4743
4744 switch (last_read_token)
4745 {
4746 case FUNCTION:
4747 parser_state |= PST_ALLOWOPNBRC;
4748 function_dstart = line_number;
4749 break;
4750 case CASE:
4751 case SELECT:
4752 case FOR:
4753 if (word_top < MAX_CASE_NEST)
4754 word_top++;
4755 word_lineno[word_top] = line_number;
4756 break;
4757 }
4758
4759 return (result);
4760 }
4761
4762 /* Return 1 if TOKSYM is a token that after being read would allow
4763 a reserved word to be seen, else 0. */
4764 static int
4765 reserved_word_acceptable (toksym)
4766 int toksym;
4767 {
4768 switch (toksym)
4769 {
4770 case '\n':
4771 case ';':
4772 case '(':
4773 case ')':
4774 case '|':
4775 case '&':
4776 case '{':
4777 case '}': /* XXX */
4778 case AND_AND:
4779 case BANG:
4780 case BAR_AND:
4781 case DO:
4782 case DONE:
4783 case ELIF:
4784 case ELSE:
4785 case ESAC:
4786 case FI:
4787 case IF:
4788 case OR_OR:
4789 case SEMI_SEMI:
4790 case SEMI_AND:
4791 case SEMI_SEMI_AND:
4792 case THEN:
4793 case TIME:
4794 case TIMEOPT:
4795 case TIMEIGN:
4796 case COPROC:
4797 case UNTIL:
4798 case WHILE:
4799 case 0:
4800 return 1;
4801 default:
4802 #if defined (COPROCESS_SUPPORT)
4803 if (last_read_token == WORD && token_before_that == COPROC)
4804 return 1;
4805 #endif
4806 if (last_read_token == WORD && token_before_that == FUNCTION)
4807 return 1;
4808 return 0;
4809 }
4810 }
4811
4812 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4813 TOKEN is not a shell reserved word. */
4814 int
4815 find_reserved_word (tokstr)
4816 char *tokstr;
4817 {
4818 int i;
4819 for (i = 0; word_token_alist[i].word; i++)
4820 if (STREQ (tokstr, word_token_alist[i].word))
4821 return i;
4822 return -1;
4823 }
4824
4825 #if 0
4826 #if defined (READLINE)
4827 /* Called after each time readline is called. This insures that whatever
4828 the new prompt string is gets propagated to readline's local prompt
4829 variable. */
4830 static void
4831 reset_readline_prompt ()
4832 {
4833 char *temp_prompt;
4834
4835 if (prompt_string_pointer)
4836 {
4837 temp_prompt = (*prompt_string_pointer)
4838 ? decode_prompt_string (*prompt_string_pointer)
4839 : (char *)NULL;
4840
4841 if (temp_prompt == 0)
4842 {
4843 temp_prompt = (char *)xmalloc (1);
4844 temp_prompt[0] = '\0';
4845 }
4846
4847 FREE (current_readline_prompt);
4848 current_readline_prompt = temp_prompt;
4849 }
4850 }
4851 #endif /* READLINE */
4852 #endif /* 0 */
4853
4854 #if defined (HISTORY)
4855 /* A list of tokens which can be followed by newlines, but not by
4856 semi-colons. When concatenating multiple lines of history, the
4857 newline separator for such tokens is replaced with a space. */
4858 static const int no_semi_successors[] = {
4859 '\n', '{', '(', ')', ';', '&', '|',
4860 CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
4861 WHILE, AND_AND, OR_OR, IN,
4862 0
4863 };
4864
4865 /* If we are not within a delimited expression, try to be smart
4866 about which separators can be semi-colons and which must be
4867 newlines. Returns the string that should be added into the
4868 history entry. LINE is the line we're about to add; it helps
4869 make some more intelligent decisions in certain cases. */
4870 char *
4871 history_delimiting_chars (line)
4872 const char *line;
4873 {
4874 static int last_was_heredoc = 0; /* was the last entry the start of a here document? */
4875 register int i;
4876
4877 if ((parser_state & PST_HEREDOC) == 0)
4878 last_was_heredoc = 0;
4879
4880 if (dstack.delimiter_depth != 0)
4881 return ("\n");
4882
4883 /* We look for current_command_line_count == 2 because we are looking to
4884 add the first line of the body of the here document (the second line
4885 of the command). We also keep LAST_WAS_HEREDOC as a private sentinel
4886 variable to note when we think we added the first line of a here doc
4887 (the one with a "<<" somewhere in it) */
4888 if (parser_state & PST_HEREDOC)
4889 {
4890 if (last_was_heredoc)
4891 {
4892 last_was_heredoc = 0;
4893 return "\n";
4894 }
4895 return (current_command_line_count == 2 ? "\n" : "");
4896 }
4897
4898 /* First, handle some special cases. */
4899 /*(*/
4900 /* If we just read `()', assume it's a function definition, and don't
4901 add a semicolon. If the token before the `)' was not `(', and we're
4902 not in the midst of parsing a case statement, assume it's a
4903 parenthesized command and add the semicolon. */
4904 /*)(*/
4905 if (token_before_that == ')')
4906 {
4907 if (two_tokens_ago == '(') /*)*/ /* function def */
4908 return " ";
4909 /* This does not work for subshells inside case statement
4910 command lists. It's a suboptimal solution. */
4911 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4912 return " ";
4913 else
4914 return "; "; /* (...) subshell */
4915 }
4916 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4917 return " "; /* function def using `function name' without `()' */
4918
4919 /* If we're not in a here document, but we think we're about to parse one,
4920 and we would otherwise return a `;', return a newline to delimit the
4921 line with the here-doc delimiter */
4922 else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
4923 {
4924 last_was_heredoc = 1;
4925 return "\n";
4926 }
4927
4928 else if (token_before_that == WORD && two_tokens_ago == FOR)
4929 {
4930 /* Tricky. `for i\nin ...' should not have a semicolon, but
4931 `for i\ndo ...' should. We do what we can. */
4932 for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
4933 ;
4934 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
4935 return " ";
4936 return ";";
4937 }
4938 else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
4939 return " ";
4940
4941 for (i = 0; no_semi_successors[i]; i++)
4942 {
4943 if (token_before_that == no_semi_successors[i])
4944 return (" ");
4945 }
4946
4947 return ("; ");
4948 }
4949 #endif /* HISTORY */
4950
4951 /* Issue a prompt, or prepare to issue a prompt when the next character
4952 is read. */
4953 static void
4954 prompt_again ()
4955 {
4956 char *temp_prompt;
4957
4958 if (interactive == 0 || expanding_alias ()) /* XXX */
4959 return;
4960
4961 ps1_prompt = get_string_value ("PS1");
4962 ps2_prompt = get_string_value ("PS2");
4963
4964 if (!prompt_string_pointer)
4965 prompt_string_pointer = &ps1_prompt;
4966
4967 temp_prompt = *prompt_string_pointer
4968 ? decode_prompt_string (*prompt_string_pointer)
4969 : (char *)NULL;
4970
4971 if (temp_prompt == 0)
4972 {
4973 temp_prompt = (char *)xmalloc (1);
4974 temp_prompt[0] = '\0';
4975 }
4976
4977 current_prompt_string = *prompt_string_pointer;
4978 prompt_string_pointer = &ps2_prompt;
4979
4980 #if defined (READLINE)
4981 if (!no_line_editing)
4982 {
4983 FREE (current_readline_prompt);
4984 current_readline_prompt = temp_prompt;
4985 }
4986 else
4987 #endif /* READLINE */
4988 {
4989 FREE (current_decoded_prompt);
4990 current_decoded_prompt = temp_prompt;
4991 }
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 #if defined (HAVE_TZSET)
5139 sv_tz ("TZ"); /* XXX -- just make sure */
5140 #endif
5141 tm = localtime (&the_time);
5142
5143 if (c == 'd')
5144 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
5145 else if (c == 't')
5146 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
5147 else if (c == 'T')
5148 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
5149 else if (c == '@')
5150 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
5151 else if (c == 'A')
5152 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
5153
5154 if (n == 0)
5155 timebuf[0] = '\0';
5156 else
5157 timebuf[sizeof(timebuf) - 1] = '\0';
5158
5159 temp = savestring (timebuf);
5160 goto add_string;
5161
5162 case 'D': /* strftime format */
5163 if (string[1] != '{') /* } */
5164 goto not_escape;
5165
5166 (void) time (&the_time);
5167 tm = localtime (&the_time);
5168 string += 2; /* skip { */
5169 timefmt = xmalloc (strlen (string) + 3);
5170 for (t = timefmt; *string && *string != '}'; )
5171 *t++ = *string++;
5172 *t = '\0';
5173 c = *string; /* tested at add_string */
5174 if (timefmt[0] == '\0')
5175 {
5176 timefmt[0] = '%';
5177 timefmt[1] = 'X'; /* locale-specific current time */
5178 timefmt[2] = '\0';
5179 }
5180 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
5181 free (timefmt);
5182
5183 if (n == 0)
5184 timebuf[0] = '\0';
5185 else
5186 timebuf[sizeof(timebuf) - 1] = '\0';
5187
5188 if (promptvars || posixly_correct)
5189 /* Make sure that expand_prompt_string is called with a
5190 second argument of Q_DOUBLE_QUOTES if we use this
5191 function here. */
5192 temp = sh_backslash_quote_for_double_quotes (timebuf);
5193 else
5194 temp = savestring (timebuf);
5195 goto add_string;
5196
5197 case 'n':
5198 temp = (char *)xmalloc (3);
5199 temp[0] = no_line_editing ? '\n' : '\r';
5200 temp[1] = no_line_editing ? '\0' : '\n';
5201 temp[2] = '\0';
5202 goto add_string;
5203
5204 case 's':
5205 temp = base_pathname (shell_name);
5206 temp = savestring (temp);
5207 goto add_string;
5208
5209 case 'v':
5210 case 'V':
5211 temp = (char *)xmalloc (16);
5212 if (c == 'v')
5213 strcpy (temp, dist_version);
5214 else
5215 sprintf (temp, "%s.%d", dist_version, patch_level);
5216 goto add_string;
5217
5218 case 'w':
5219 case 'W':
5220 {
5221 /* Use the value of PWD because it is much more efficient. */
5222 char t_string[PATH_MAX];
5223 int tlen;
5224
5225 temp = get_string_value ("PWD");
5226
5227 if (temp == 0)
5228 {
5229 if (getcwd (t_string, sizeof(t_string)) == 0)
5230 {
5231 t_string[0] = '.';
5232 tlen = 1;
5233 }
5234 else
5235 tlen = strlen (t_string);
5236 }
5237 else
5238 {
5239 tlen = sizeof (t_string) - 1;
5240 strncpy (t_string, temp, tlen);
5241 }
5242 t_string[tlen] = '\0';
5243
5244 #if defined (MACOSX)
5245 /* Convert from "fs" format to "input" format */
5246 temp = fnx_fromfs (t_string, strlen (t_string));
5247 if (temp != t_string)
5248 strcpy (t_string, temp);
5249 #endif
5250
5251 #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
5252 #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
5253 /* Abbreviate \W as ~ if $PWD == $HOME */
5254 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
5255 {
5256 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
5257 {
5258 t = strrchr (t_string, '/');
5259 if (t)
5260 memmove (t_string, t + 1, strlen (t)); /* strlen(t) to copy NULL */
5261 }
5262 }
5263 #undef ROOT_PATH
5264 #undef DOUBLE_SLASH_ROOT
5265 else
5266 /* polite_directory_format is guaranteed to return a string
5267 no longer than PATH_MAX - 1 characters. */
5268 strcpy (t_string, polite_directory_format (t_string));
5269
5270 temp = trim_pathname (t_string, PATH_MAX - 1);
5271 /* If we're going to be expanding the prompt string later,
5272 quote the directory name. */
5273 if (promptvars || posixly_correct)
5274 /* Make sure that expand_prompt_string is called with a
5275 second argument of Q_DOUBLE_QUOTES if we use this
5276 function here. */
5277 temp = sh_backslash_quote_for_double_quotes (t_string);
5278 else
5279 temp = savestring (t_string);
5280
5281 goto add_string;
5282 }
5283
5284 case 'u':
5285 if (current_user.user_name == 0)
5286 get_current_user_info ();
5287 temp = savestring (current_user.user_name);
5288 goto add_string;
5289
5290 case 'h':
5291 case 'H':
5292 temp = savestring (current_host_name);
5293 if (c == 'h' && (t = (char *)strchr (temp, '.')))
5294 *t = '\0';
5295 goto add_string;
5296
5297 case '#':
5298 temp = itos (current_command_number);
5299 goto add_string;
5300
5301 case '!':
5302 #if !defined (HISTORY)
5303 temp = savestring ("1");
5304 #else /* HISTORY */
5305 temp = itos (history_number ());
5306 #endif /* HISTORY */
5307 goto add_string;
5308
5309 case '$':
5310 t = temp = (char *)xmalloc (3);
5311 if ((promptvars || posixly_correct) && (current_user.euid != 0))
5312 *t++ = '\\';
5313 *t++ = current_user.euid == 0 ? '#' : '$';
5314 *t = '\0';
5315 goto add_string;
5316
5317 case 'j':
5318 temp = itos (count_all_jobs ());
5319 goto add_string;
5320
5321 case 'l':
5322 #if defined (HAVE_TTYNAME)
5323 temp = (char *)ttyname (fileno (stdin));
5324 t = temp ? base_pathname (temp) : "tty";
5325 temp = savestring (t);
5326 #else
5327 temp = savestring ("tty");
5328 #endif /* !HAVE_TTYNAME */
5329 goto add_string;
5330
5331 #if defined (READLINE)
5332 case '[':
5333 case ']':
5334 if (no_line_editing)
5335 {
5336 string++;
5337 break;
5338 }
5339 temp = (char *)xmalloc (3);
5340 n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
5341 i = 0;
5342 if (n == CTLESC || n == CTLNUL)
5343 temp[i++] = CTLESC;
5344 temp[i++] = n;
5345 temp[i] = '\0';
5346 goto add_string;
5347 #endif /* READLINE */
5348
5349 case '\\':
5350 case 'a':
5351 case 'e':
5352 case 'r':
5353 temp = (char *)xmalloc (2);
5354 if (c == 'a')
5355 temp[0] = '\07';
5356 else if (c == 'e')
5357 temp[0] = '\033';
5358 else if (c == 'r')
5359 temp[0] = '\r';
5360 else /* (c == '\\') */
5361 temp[0] = c;
5362 temp[1] = '\0';
5363 goto add_string;
5364
5365 default:
5366 not_escape:
5367 temp = (char *)xmalloc (3);
5368 temp[0] = '\\';
5369 temp[1] = c;
5370 temp[2] = '\0';
5371
5372 add_string:
5373 if (c)
5374 string++;
5375 result =
5376 sub_append_string (temp, result, &result_index, &result_size);
5377 temp = (char *)NULL; /* Freed in sub_append_string (). */
5378 result[result_index] = '\0';
5379 break;
5380 }
5381 }
5382 else
5383 {
5384 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
5385 result[result_index++] = c;
5386 result[result_index] = '\0';
5387 }
5388 }
5389 #else /* !PROMPT_STRING_DECODE */
5390 result = savestring (string);
5391 #endif /* !PROMPT_STRING_DECODE */
5392
5393 /* Save the delimiter stack and point `dstack' to temp space so any
5394 command substitutions in the prompt string won't result in screwing
5395 up the parser's quoting state. */
5396 save_dstack = dstack;
5397 dstack = temp_dstack;
5398 dstack.delimiter_depth = 0;
5399
5400 /* Perform variable and parameter expansion and command substitution on
5401 the prompt string. */
5402 if (promptvars || posixly_correct)
5403 {
5404 last_exit_value = last_command_exit_value;
5405 last_comsub_pid = last_command_subst_pid;
5406 list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
5407 free (result);
5408 result = string_list (list);
5409 dispose_words (list);
5410 last_command_exit_value = last_exit_value;
5411 last_command_subst_pid = last_comsub_pid;
5412 }
5413 else
5414 {
5415 t = dequote_string (result);
5416 free (result);
5417 result = t;
5418 }
5419
5420 dstack = save_dstack;
5421
5422 return (result);
5423 }
5424
5425 /************************************************
5426 * *
5427 * ERROR HANDLING *
5428 * *
5429 ************************************************/
5430
5431 /* Report a syntax error, and restart the parser. Call here for fatal
5432 errors. */
5433 int
5434 yyerror (msg)
5435 const char *msg;
5436 {
5437 report_syntax_error ((char *)NULL);
5438 reset_parser ();
5439 return (0);
5440 }
5441
5442 static char *
5443 error_token_from_token (tok)
5444 int tok;
5445 {
5446 char *t;
5447
5448 if (t = find_token_in_alist (tok, word_token_alist, 0))
5449 return t;
5450
5451 if (t = find_token_in_alist (tok, other_token_alist, 0))
5452 return t;
5453
5454 t = (char *)NULL;
5455 /* This stuff is dicy and needs closer inspection */
5456 switch (current_token)
5457 {
5458 case WORD:
5459 case ASSIGNMENT_WORD:
5460 if (yylval.word)
5461 t = savestring (yylval.word->word);
5462 break;
5463 case NUMBER:
5464 t = itos (yylval.number);
5465 break;
5466 case ARITH_CMD:
5467 if (yylval.word_list)
5468 t = string_list (yylval.word_list);
5469 break;
5470 case ARITH_FOR_EXPRS:
5471 if (yylval.word_list)
5472 t = string_list_internal (yylval.word_list, " ; ");
5473 break;
5474 case COND_CMD:
5475 t = (char *)NULL; /* punt */
5476 break;
5477 }
5478
5479 return t;
5480 }
5481
5482 static char *
5483 error_token_from_text ()
5484 {
5485 char *msg, *t;
5486 int token_end, i;
5487
5488 t = shell_input_line;
5489 i = shell_input_line_index;
5490 token_end = 0;
5491 msg = (char *)NULL;
5492
5493 if (i && t[i] == '\0')
5494 i--;
5495
5496 while (i && (whitespace (t[i]) || t[i] == '\n'))
5497 i--;
5498
5499 if (i)
5500 token_end = i + 1;
5501
5502 while (i && (member (t[i], " \n\t;|&") == 0))
5503 i--;
5504
5505 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
5506 i++;
5507
5508 /* Return our idea of the offending token. */
5509 if (token_end || (i == 0 && token_end == 0))
5510 {
5511 if (token_end)
5512 msg = substring (t, i, token_end);
5513 else /* one-character token */
5514 {
5515 msg = (char *)xmalloc (2);
5516 msg[0] = t[i];
5517 msg[1] = '\0';
5518 }
5519 }
5520
5521 return (msg);
5522 }
5523
5524 static void
5525 print_offending_line ()
5526 {
5527 char *msg;
5528 int token_end;
5529
5530 msg = savestring (shell_input_line);
5531 token_end = strlen (msg);
5532 while (token_end && msg[token_end - 1] == '\n')
5533 msg[--token_end] = '\0';
5534
5535 parser_error (line_number, "`%s'", msg);
5536 free (msg);
5537 }
5538
5539 /* Report a syntax error with line numbers, etc.
5540 Call here for recoverable errors. If you have a message to print,
5541 then place it in MESSAGE, otherwise pass NULL and this will figure
5542 out an appropriate message for you. */
5543 static void
5544 report_syntax_error (message)
5545 char *message;
5546 {
5547 char *msg, *p;
5548
5549 if (message)
5550 {
5551 parser_error (line_number, "%s", message);
5552 if (interactive && EOF_Reached)
5553 EOF_Reached = 0;
5554 last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
5555 return;
5556 }
5557
5558 /* If the line of input we're reading is not null, try to find the
5559 objectionable token. First, try to figure out what token the
5560 parser's complaining about by looking at current_token. */
5561 if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
5562 {
5563 if (ansic_shouldquote (msg))
5564 {
5565 p = ansic_quote (msg, 0, NULL);
5566 free (msg);
5567 msg = p;
5568 }
5569 parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
5570 free (msg);
5571
5572 if (interactive == 0)
5573 print_offending_line ();
5574
5575 last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
5576 return;
5577 }
5578
5579 /* If looking at the current token doesn't prove fruitful, try to find the
5580 offending token by analyzing the text of the input line near the current
5581 input line index and report what we find. */
5582 if (shell_input_line && *shell_input_line)
5583 {
5584 msg = error_token_from_text ();
5585 if (msg)
5586 {
5587 parser_error (line_number, _("syntax error near `%s'"), msg);
5588 free (msg);
5589 }
5590
5591 /* If not interactive, print the line containing the error. */
5592 if (interactive == 0)
5593 print_offending_line ();
5594 }
5595 else
5596 {
5597 msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
5598 parser_error (line_number, "%s", msg);
5599 /* When the shell is interactive, this file uses EOF_Reached
5600 only for error reporting. Other mechanisms are used to
5601 decide whether or not to exit. */
5602 if (interactive && EOF_Reached)
5603 EOF_Reached = 0;
5604 }
5605
5606 last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
5607 }
5608
5609 /* ??? Needed function. ??? We have to be able to discard the constructs
5610 created during parsing. In the case of error, we want to return
5611 allocated objects to the memory pool. In the case of no error, we want
5612 to throw away the information about where the allocated objects live.
5613 (dispose_command () will actually free the command.) */
5614 static void
5615 discard_parser_constructs (error_p)
5616 int error_p;
5617 {
5618 }
5619
5620 /************************************************
5621 * *
5622 * EOF HANDLING *
5623 * *
5624 ************************************************/
5625
5626 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
5627
5628 /* A flag denoting whether or not ignoreeof is set. */
5629 int ignoreeof = 0;
5630
5631 /* The number of times that we have encountered an EOF character without
5632 another character intervening. When this gets above the limit, the
5633 shell terminates. */
5634 int eof_encountered = 0;
5635
5636 /* The limit for eof_encountered. */
5637 int eof_encountered_limit = 10;
5638
5639 /* If we have EOF as the only input unit, this user wants to leave
5640 the shell. If the shell is not interactive, then just leave.
5641 Otherwise, if ignoreeof is set, and we haven't done this the
5642 required number of times in a row, print a message. */
5643 static void
5644 handle_eof_input_unit ()
5645 {
5646 if (interactive)
5647 {
5648 /* shell.c may use this to decide whether or not to write out the
5649 history, among other things. We use it only for error reporting
5650 in this file. */
5651 if (EOF_Reached)
5652 EOF_Reached = 0;
5653
5654 /* If the user wants to "ignore" eof, then let her do so, kind of. */
5655 if (ignoreeof)
5656 {
5657 if (eof_encountered < eof_encountered_limit)
5658 {
5659 fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
5660 login_shell ? "logout" : "exit");
5661 eof_encountered++;
5662 /* Reset the parsing state. */
5663 last_read_token = current_token = '\n';
5664 /* Reset the prompt string to be $PS1. */
5665 prompt_string_pointer = (char **)NULL;
5666 prompt_again ();
5667 return;
5668 }
5669 }
5670
5671 /* In this case EOF should exit the shell. Do it now. */
5672 reset_parser ();
5673 exit_builtin ((WORD_LIST *)NULL);
5674 }
5675 else
5676 {
5677 /* We don't write history files, etc., for non-interactive shells. */
5678 EOF_Reached = 1;
5679 }
5680 }
5681
5682 /************************************************
5683 * *
5684 * STRING PARSING FUNCTIONS *
5685 * *
5686 ************************************************/
5687
5688 /* It's very important that these two functions treat the characters
5689 between ( and ) identically. */
5690
5691 static WORD_LIST parse_string_error;
5692
5693 /* Take a string and run it through the shell parser, returning the
5694 resultant word list. Used by compound array assignment. */
5695 WORD_LIST *
5696 parse_string_to_word_list (s, flags, whom)
5697 char *s;
5698 int flags;
5699 const char *whom;
5700 {
5701 WORD_LIST *wl;
5702 int tok, orig_current_token, orig_line_number, orig_input_terminator;
5703 int orig_line_count;
5704 int old_echo_input, old_expand_aliases;
5705 #if defined (HISTORY)
5706 int old_remember_on_history, old_history_expansion_inhibited;
5707 #endif
5708
5709 #if defined (HISTORY)
5710 old_remember_on_history = remember_on_history;
5711 # if defined (BANG_HISTORY)
5712 old_history_expansion_inhibited = history_expansion_inhibited;
5713 # endif
5714 bash_history_disable ();
5715 #endif
5716
5717 orig_line_number = line_number;
5718 orig_line_count = current_command_line_count;
5719 orig_input_terminator = shell_input_line_terminator;
5720 old_echo_input = echo_input_at_read;
5721 old_expand_aliases = expand_aliases;
5722
5723 push_stream (1);
5724 last_read_token = WORD; /* WORD to allow reserved words here */
5725 current_command_line_count = 0;
5726 echo_input_at_read = expand_aliases = 0;
5727
5728 with_input_from_string (s, whom);
5729 wl = (WORD_LIST *)NULL;
5730
5731 if (flags & 1)
5732 parser_state |= PST_COMPASSIGN|PST_REPARSE;
5733
5734 while ((tok = read_token (READ)) != yacc_EOF)
5735 {
5736 if (tok == '\n' && *bash_input.location.string == '\0')
5737 break;
5738 if (tok == '\n') /* Allow newlines in compound assignments */
5739 continue;
5740 if (tok != WORD && tok != ASSIGNMENT_WORD)
5741 {
5742 line_number = orig_line_number + line_number - 1;
5743 orig_current_token = current_token;
5744 current_token = tok;
5745 yyerror (NULL); /* does the right thing */
5746 current_token = orig_current_token;
5747 if (wl)
5748 dispose_words (wl);
5749 wl = &parse_string_error;
5750 break;
5751 }
5752 wl = make_word_list (yylval.word, wl);
5753 }
5754
5755 last_read_token = '\n';
5756 pop_stream ();
5757
5758 #if defined (HISTORY)
5759 remember_on_history = old_remember_on_history;
5760 # if defined (BANG_HISTORY)
5761 history_expansion_inhibited = old_history_expansion_inhibited;
5762 # endif /* BANG_HISTORY */
5763 #endif /* HISTORY */
5764
5765 echo_input_at_read = old_echo_input;
5766 expand_aliases = old_expand_aliases;
5767
5768 current_command_line_count = orig_line_count;
5769 shell_input_line_terminator = orig_input_terminator;
5770
5771 if (flags & 1)
5772 parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
5773
5774 if (wl == &parse_string_error)
5775 {
5776 last_command_exit_value = EXECUTION_FAILURE;
5777 if (interactive_shell == 0 && posixly_correct)
5778 jump_to_top_level (FORCE_EOF);
5779 else
5780 jump_to_top_level (DISCARD);
5781 }
5782
5783 return (REVERSE_LIST (wl, WORD_LIST *));
5784 }
5785
5786 static char *
5787 parse_compound_assignment (retlenp)
5788 int *retlenp;
5789 {
5790 WORD_LIST *wl, *rl;
5791 int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
5792 char *saved_token, *ret;
5793
5794 saved_token = token;
5795 orig_token_size = token_buffer_size;
5796 orig_line_number = line_number;
5797 orig_last_token = last_read_token;
5798
5799 last_read_token = WORD; /* WORD to allow reserved words here */
5800
5801 token = (char *)NULL;
5802 token_buffer_size = 0;
5803
5804 assignok = parser_state&PST_ASSIGNOK; /* XXX */
5805
5806 wl = (WORD_LIST *)NULL; /* ( */
5807 parser_state |= PST_COMPASSIGN;
5808
5809 while ((tok = read_token (READ)) != ')')
5810 {
5811 if (tok == '\n') /* Allow newlines in compound assignments */
5812 {
5813 if (SHOULD_PROMPT ())
5814 prompt_again ();
5815 continue;
5816 }
5817 if (tok != WORD && tok != ASSIGNMENT_WORD)
5818 {
5819 current_token = tok; /* for error reporting */
5820 if (tok == yacc_EOF) /* ( */
5821 parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
5822 else
5823 yyerror(NULL); /* does the right thing */
5824 if (wl)
5825 dispose_words (wl);
5826 wl = &parse_string_error;
5827 break;
5828 }
5829 wl = make_word_list (yylval.word, wl);
5830 }
5831
5832 FREE (token);
5833 token = saved_token;
5834 token_buffer_size = orig_token_size;
5835
5836 parser_state &= ~PST_COMPASSIGN;
5837
5838 if (wl == &parse_string_error)
5839 {
5840 last_command_exit_value = EXECUTION_FAILURE;
5841 last_read_token = '\n'; /* XXX */
5842 if (interactive_shell == 0 && posixly_correct)
5843 jump_to_top_level (FORCE_EOF);
5844 else
5845 jump_to_top_level (DISCARD);
5846 }
5847
5848 last_read_token = orig_last_token; /* XXX - was WORD? */
5849
5850 if (wl)
5851 {
5852 rl = REVERSE_LIST (wl, WORD_LIST *);
5853 ret = string_list (rl);
5854 dispose_words (rl);
5855 }
5856 else
5857 ret = (char *)NULL;
5858
5859 if (retlenp)
5860 *retlenp = (ret && *ret) ? strlen (ret) : 0;
5861
5862 if (assignok)
5863 parser_state |= PST_ASSIGNOK;
5864
5865 return ret;
5866 }
5867
5868 /************************************************
5869 * *
5870 * SAVING AND RESTORING PARTIAL PARSE STATE *
5871 * *
5872 ************************************************/
5873
5874 sh_parser_state_t *
5875 save_parser_state (ps)
5876 sh_parser_state_t *ps;
5877 {
5878 if (ps == 0)
5879 ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
5880 if (ps == 0)
5881 return ((sh_parser_state_t *)NULL);
5882
5883 ps->parser_state = parser_state;
5884 ps->token_state = save_token_state ();
5885
5886 ps->input_line_terminator = shell_input_line_terminator;
5887 ps->eof_encountered = eof_encountered;
5888
5889 ps->prompt_string_pointer = prompt_string_pointer;
5890
5891 ps->current_command_line_count = current_command_line_count;
5892
5893 #if defined (HISTORY)
5894 ps->remember_on_history = remember_on_history;
5895 # if defined (BANG_HISTORY)
5896 ps->history_expansion_inhibited = history_expansion_inhibited;
5897 # endif
5898 #endif
5899
5900 ps->last_command_exit_value = last_command_exit_value;
5901 #if defined (ARRAY_VARS)
5902 ps->pipestatus = save_pipestatus_array ();
5903 #endif
5904
5905 ps->last_shell_builtin = last_shell_builtin;
5906 ps->this_shell_builtin = this_shell_builtin;
5907
5908 ps->expand_aliases = expand_aliases;
5909 ps->echo_input_at_read = echo_input_at_read;
5910
5911 return (ps);
5912 }
5913
5914 void
5915 restore_parser_state (ps)
5916 sh_parser_state_t *ps;
5917 {
5918 if (ps == 0)
5919 return;
5920
5921 parser_state = ps->parser_state;
5922 if (ps->token_state)
5923 {
5924 restore_token_state (ps->token_state);
5925 free (ps->token_state);
5926 }
5927
5928 shell_input_line_terminator = ps->input_line_terminator;
5929 eof_encountered = ps->eof_encountered;
5930
5931 prompt_string_pointer = ps->prompt_string_pointer;
5932
5933 current_command_line_count = ps->current_command_line_count;
5934
5935 #if defined (HISTORY)
5936 remember_on_history = ps->remember_on_history;
5937 # if defined (BANG_HISTORY)
5938 history_expansion_inhibited = ps->history_expansion_inhibited;
5939 # endif
5940 #endif
5941
5942 last_command_exit_value = ps->last_command_exit_value;
5943 #if defined (ARRAY_VARS)
5944 restore_pipestatus_array (ps->pipestatus);
5945 #endif
5946
5947 last_shell_builtin = ps->last_shell_builtin;
5948 this_shell_builtin = ps->this_shell_builtin;
5949
5950 expand_aliases = ps->expand_aliases;
5951 echo_input_at_read = ps->echo_input_at_read;
5952 }
5953
5954 /************************************************
5955 * *
5956 * MULTIBYTE CHARACTER HANDLING *
5957 * *
5958 ************************************************/
5959
5960 #if defined (HANDLE_MULTIBYTE)
5961 static void
5962 set_line_mbstate ()
5963 {
5964 int i, previ, len, c;
5965 mbstate_t mbs, prevs;
5966 size_t mbclen;
5967
5968 if (shell_input_line == NULL)
5969 return;
5970 len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */
5971 FREE (shell_input_line_property);
5972 shell_input_line_property = (char *)xmalloc (len + 1);
5973
5974 memset (&prevs, '\0', sizeof (mbstate_t));
5975 for (i = previ = 0; i < len; i++)
5976 {
5977 mbs = prevs;
5978
5979 c = shell_input_line[i];
5980 if (c == EOF)
5981 {
5982 int j;
5983 for (j = i; j < len; j++)
5984 shell_input_line_property[j] = 1;
5985 break;
5986 }
5987
5988 mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
5989 if (mbclen == 1 || mbclen == (size_t)-1)
5990 {
5991 mbclen = 1;
5992 previ = i + 1;
5993 }
5994 else if (mbclen == (size_t)-2)
5995 mbclen = 0;
5996 else if (mbclen > 1)
5997 {
5998 mbclen = 0;
5999 previ = i + 1;
6000 prevs = mbs;
6001 }
6002 else
6003 {
6004 /* XXX - what to do if mbrlen returns 0? (null wide character) */
6005 int j;
6006 for (j = i; j < len; j++)
6007 shell_input_line_property[j] = 1;
6008 break;
6009 }
6010
6011 shell_input_line_property[i] = mbclen;
6012 }
6013 }
6014 #endif /* HANDLE_MULTIBYTE */