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