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