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