Line data Source code
1 : /* A Bison parser, made by GNU Bison 3.0.5. */
2 :
3 : /* Bison implementation for Yacc-like parsers in C
4 :
5 : Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
6 :
7 : This program 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 : This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
19 :
20 : /* As a special exception, you may create a larger work that contains
21 : part or all of the Bison parser skeleton and distribute that work
22 : under terms of your choice, so long as that work isn't itself a
23 : parser generator using the skeleton or a modified version thereof
24 : as a parser skeleton. Alternatively, if you modify or redistribute
25 : the parser skeleton itself, you may (at your option) remove this
26 : special exception, which will cause the skeleton and the resulting
27 : Bison output files to be licensed under the GNU General Public
28 : License without this special exception.
29 :
30 : This special exception was added by the Free Software Foundation in
31 : version 2.2 of Bison. */
32 :
33 : /* C LALR(1) parser skeleton written by Richard Stallman, by
34 : simplifying the original so-called "semantic" parser. */
35 :
36 : /* All symbols defined below should begin with yy or YY, to avoid
37 : infringing on user name space. This should be done even for local
38 : variables, as they might otherwise be expanded by user macros.
39 : There are some unavoidable exceptions within include files to
40 : define necessary library symbols; they are noted "INFRINGES ON
41 : USER NAME SPACE" below. */
42 :
43 : /* Identify Bison output. */
44 : #define YYBISON 1
45 :
46 : /* Bison version. */
47 : #define YYBISON_VERSION "3.0.5"
48 :
49 : /* Skeleton name. */
50 : #define YYSKELETON_NAME "yacc.c"
51 :
52 : /* Pure parsers. */
53 : #define YYPURE 0
54 :
55 : /* Push parsers. */
56 : #define YYPUSH 0
57 :
58 : /* Pull parsers. */
59 : #define YYPULL 1
60 :
61 :
62 :
63 :
64 : /* Copy the first part of user declarations. */
65 : #line 21 "../parse.y" /* yacc.c:339 */
66 :
67 : #include "config.h"
68 :
69 : #include "bashtypes.h"
70 : #include "bashansi.h"
71 :
72 : #include "filecntl.h"
73 :
74 : #if defined (HAVE_UNISTD_H)
75 : # include <unistd.h>
76 : #endif
77 :
78 : #if defined (HAVE_LOCALE_H)
79 : # include <locale.h>
80 : #endif
81 :
82 : #include <stdio.h>
83 : #include "chartypes.h"
84 : #include <signal.h>
85 :
86 : #include "memalloc.h"
87 :
88 : #include "bashintl.h"
89 :
90 : #define NEED_STRFTIME_DECL /* used in externs.h */
91 :
92 : #include "shell.h"
93 : #include "typemax.h" /* SIZE_MAX if needed */
94 : #include "trap.h"
95 : #include "flags.h"
96 : #include "parser.h"
97 : #include "mailcheck.h"
98 : #include "test.h"
99 : #include "builtins.h"
100 : #include "builtins/common.h"
101 : #include "builtins/builtext.h"
102 :
103 : #include "shmbutil.h"
104 :
105 : #if defined (READLINE)
106 : # include "bashline.h"
107 : # include <readline/readline.h>
108 : #endif /* READLINE */
109 :
110 : #if defined (HISTORY)
111 : # include "bashhist.h"
112 : # include <readline/history.h>
113 : #endif /* HISTORY */
114 :
115 : #if defined (JOB_CONTROL)
116 : # include "jobs.h"
117 : #else
118 : extern int cleanup_dead_jobs __P((void));
119 : #endif /* JOB_CONTROL */
120 :
121 : #if defined (ALIAS)
122 : # include "alias.h"
123 : #else
124 : typedef void *alias_t;
125 : #endif /* ALIAS */
126 :
127 : #if defined (PROMPT_STRING_DECODE)
128 : # ifndef _MINIX
129 : # include <sys/param.h>
130 : # endif
131 : # include <time.h>
132 : # if defined (TM_IN_SYS_TIME)
133 : # include <sys/types.h>
134 : # include <sys/time.h>
135 : # endif /* TM_IN_SYS_TIME */
136 : # include "maxpath.h"
137 : #endif /* PROMPT_STRING_DECODE */
138 :
139 : #define RE_READ_TOKEN -99
140 : #define NO_EXPANSION -100
141 :
142 : #ifdef DEBUG
143 : # define YYDEBUG 1
144 : #else
145 : # define YYDEBUG 0
146 : #endif
147 :
148 : #if defined (HANDLE_MULTIBYTE)
149 : # define last_shell_getc_is_singlebyte \
150 : ((shell_input_line_index > 1) \
151 : ? shell_input_line_property[shell_input_line_index - 1] \
152 : : 1)
153 : # define MBTEST(x) ((x) && last_shell_getc_is_singlebyte)
154 : #else
155 : # define last_shell_getc_is_singlebyte 1
156 : # define MBTEST(x) ((x))
157 : #endif
158 :
159 : #if defined (EXTENDED_GLOB)
160 : extern int extended_glob;
161 : #endif
162 :
163 : extern int eof_encountered;
164 : extern int no_line_editing, running_under_emacs;
165 : extern int current_command_number;
166 : extern int sourcelevel, parse_and_execute_level;
167 : extern int posixly_correct;
168 : extern int last_command_exit_value;
169 : extern pid_t last_command_subst_pid;
170 : extern char *shell_name, *current_host_name;
171 : extern char *dist_version;
172 : extern int patch_level;
173 : extern int dump_translatable_strings, dump_po_strings;
174 : extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
175 : extern int here_doc_first_line;
176 : #if defined (BUFFERED_INPUT)
177 : extern int bash_input_fd_changed;
178 : #endif
179 :
180 : extern int errno;
181 : /* **************************************************************** */
182 : /* */
183 : /* "Forward" declarations */
184 : /* */
185 : /* **************************************************************** */
186 :
187 : #ifdef DEBUG
188 : static void debug_parser __P((int));
189 : #endif
190 :
191 : static int yy_getc __P((void));
192 : static int yy_ungetc __P((int));
193 :
194 : #if defined (READLINE)
195 : static int yy_readline_get __P((void));
196 : static int yy_readline_unget __P((int));
197 : #endif
198 :
199 : static int yy_string_get __P((void));
200 : static int yy_string_unget __P((int));
201 : static void rewind_input_string __P((void));
202 : static int yy_stream_get __P((void));
203 : static int yy_stream_unget __P((int));
204 :
205 : static int shell_getc __P((int));
206 : static void shell_ungetc __P((int));
207 : static void discard_until __P((int));
208 :
209 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
210 : static void push_string __P((char *, int, alias_t *));
211 : static void pop_string __P((void));
212 : static void free_string_list __P((void));
213 : #endif
214 :
215 : static char *read_a_line __P((int));
216 :
217 : static int reserved_word_acceptable __P((int));
218 : static int yylex __P((void));
219 :
220 : static void push_heredoc __P((REDIRECT *));
221 : static char *mk_alexpansion __P((char *));
222 : static int alias_expand_token __P((char *));
223 : static int time_command_acceptable __P((void));
224 : static int special_case_tokens __P((char *));
225 : static int read_token __P((int));
226 : static char *parse_matched_pair __P((int, int, int, int *, int));
227 : static char *parse_comsub __P((int, int, int, int *, int));
228 : #if defined (ARRAY_VARS)
229 : static char *parse_compound_assignment __P((int *));
230 : #endif
231 : #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
232 : static int parse_dparen __P((int));
233 : static int parse_arith_cmd __P((char **, int));
234 : #endif
235 : #if defined (COND_COMMAND)
236 : static void cond_error __P((void));
237 : static COND_COM *cond_expr __P((void));
238 : static COND_COM *cond_or __P((void));
239 : static COND_COM *cond_and __P((void));
240 : static COND_COM *cond_term __P((void));
241 : static int cond_skip_newlines __P((void));
242 : static COMMAND *parse_cond_command __P((void));
243 : #endif
244 : #if defined (ARRAY_VARS)
245 : static int token_is_assignment __P((char *, int));
246 : static int token_is_ident __P((char *, int));
247 : #endif
248 : static int read_token_word __P((int));
249 : #if 0
250 : static void discard_parser_constructs __P((int));
251 : #endif
252 :
253 : static char *error_token_from_token __P((int));
254 : static char *error_token_from_text __P((void));
255 : static void print_offending_line __P((void));
256 : static void report_syntax_error __P((char *));
257 :
258 : static void handle_eof_input_unit __P((void));
259 : static void prompt_again __P((void));
260 : #if 0
261 : static void reset_readline_prompt __P((void));
262 : #endif
263 : static void print_prompt __P((void));
264 :
265 : #if defined (HANDLE_MULTIBYTE)
266 : static void set_line_mbstate __P((void));
267 : static char *shell_input_line_property = NULL;
268 : #else
269 : # define set_line_mbstate()
270 : #endif
271 :
272 : extern int yyerror __P((const char *));
273 :
274 : #ifdef DEBUG
275 : extern int yydebug;
276 : #endif
277 :
278 : /* Default prompt strings */
279 : char *primary_prompt = PPROMPT;
280 : char *secondary_prompt = SPROMPT;
281 :
282 : /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
283 : char *ps1_prompt, *ps2_prompt;
284 :
285 : /* Displayed after reading a command but before executing it in an interactive shell */
286 : char *ps0_prompt;
287 :
288 : /* Handle on the current prompt string. Indirectly points through
289 : ps1_ or ps2_prompt. */
290 : char **prompt_string_pointer = (char **)NULL;
291 : char *current_prompt_string;
292 :
293 : /* Non-zero means we expand aliases in commands. */
294 : int expand_aliases = 0;
295 :
296 : /* If non-zero, the decoded prompt string undergoes parameter and
297 : variable substitution, command substitution, arithmetic substitution,
298 : string expansion, process substitution, and quote removal in
299 : decode_prompt_string. */
300 : int promptvars = 1;
301 :
302 : /* If non-zero, $'...' and $"..." are expanded when they appear within
303 : a ${...} expansion, even when the expansion appears within double
304 : quotes. */
305 : int extended_quote = 1;
306 :
307 : /* The number of lines read from input while creating the current command. */
308 : int current_command_line_count;
309 :
310 : /* The number of lines in a command saved while we run parse_and_execute */
311 : int saved_command_line_count;
312 :
313 : /* The token that currently denotes the end of parse. */
314 : int shell_eof_token;
315 :
316 : /* The token currently being read. */
317 : int current_token;
318 :
319 : /* The current parser state. */
320 : int parser_state;
321 :
322 : /* Variables to manage the task of reading here documents, because we need to
323 : defer the reading until after a complete command has been collected. */
324 : static REDIRECT *redir_stack[HEREDOC_MAX];
325 : int need_here_doc;
326 :
327 : /* Where shell input comes from. History expansion is performed on each
328 : line when the shell is interactive. */
329 : static char *shell_input_line = (char *)NULL;
330 : static size_t shell_input_line_index;
331 : static size_t shell_input_line_size; /* Amount allocated for shell_input_line. */
332 : static size_t shell_input_line_len; /* strlen (shell_input_line) */
333 :
334 : /* Either zero or EOF. */
335 : static int shell_input_line_terminator;
336 :
337 : /* The line number in a script on which a function definition starts. */
338 : static int function_dstart;
339 :
340 : /* The line number in a script on which a function body starts. */
341 : static int function_bstart;
342 :
343 : /* The line number in a script at which an arithmetic for command starts. */
344 : static int arith_for_lineno;
345 :
346 : /* The decoded prompt string. Used if READLINE is not defined or if
347 : editing is turned off. Analogous to current_readline_prompt. */
348 : static char *current_decoded_prompt;
349 :
350 : /* The last read token, or NULL. read_token () uses this for context
351 : checking. */
352 : static int last_read_token;
353 :
354 : /* The token read prior to last_read_token. */
355 : static int token_before_that;
356 :
357 : /* The token read prior to token_before_that. */
358 : static int two_tokens_ago;
359 :
360 : static int global_extglob;
361 :
362 : /* The line number in a script where the word in a `case WORD', `select WORD'
363 : or `for WORD' begins. This is a nested command maximum, since the array
364 : index is decremented after a case, select, or for command is parsed. */
365 : #define MAX_CASE_NEST 128
366 : static int word_lineno[MAX_CASE_NEST+1];
367 : static int word_top = -1;
368 :
369 : /* If non-zero, it is the token that we want read_token to return
370 : regardless of what text is (or isn't) present to be read. This
371 : is reset by read_token. If token_to_read == WORD or
372 : ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
373 : static int token_to_read;
374 : static WORD_DESC *word_desc_to_read;
375 :
376 : static REDIRECTEE source;
377 : static REDIRECTEE redir;
378 :
379 : #line 380 "y.tab.c" /* yacc.c:339 */
380 :
381 : # ifndef YY_NULLPTR
382 : # if defined __cplusplus && 201103L <= __cplusplus
383 : # define YY_NULLPTR nullptr
384 : # else
385 : # define YY_NULLPTR 0
386 : # endif
387 : # endif
388 :
389 : /* Enabling verbose error messages. */
390 : #ifdef YYERROR_VERBOSE
391 : # undef YYERROR_VERBOSE
392 : # define YYERROR_VERBOSE 1
393 : #else
394 : # define YYERROR_VERBOSE 0
395 : #endif
396 :
397 : /* In a future release of Bison, this section will be replaced
398 : by #include "y.tab.h". */
399 : #ifndef YY_YY_Y_TAB_H_INCLUDED
400 : # define YY_YY_Y_TAB_H_INCLUDED
401 : /* Debug traces. */
402 : #ifndef YYDEBUG
403 : # define YYDEBUG 0
404 : #endif
405 : #if YYDEBUG
406 : extern int yydebug;
407 : #endif
408 :
409 : /* Token type. */
410 : #ifndef YYTOKENTYPE
411 : # define YYTOKENTYPE
412 : enum yytokentype
413 : {
414 : IF = 258,
415 : THEN = 259,
416 : ELSE = 260,
417 : ELIF = 261,
418 : FI = 262,
419 : CASE = 263,
420 : ESAC = 264,
421 : FOR = 265,
422 : SELECT = 266,
423 : WHILE = 267,
424 : UNTIL = 268,
425 : DO = 269,
426 : DONE = 270,
427 : FUNCTION = 271,
428 : COPROC = 272,
429 : COND_START = 273,
430 : COND_END = 274,
431 : COND_ERROR = 275,
432 : IN = 276,
433 : BANG = 277,
434 : TIME = 278,
435 : TIMEOPT = 279,
436 : TIMEIGN = 280,
437 : WORD = 281,
438 : ASSIGNMENT_WORD = 282,
439 : REDIR_WORD = 283,
440 : NUMBER = 284,
441 : ARITH_CMD = 285,
442 : ARITH_FOR_EXPRS = 286,
443 : COND_CMD = 287,
444 : AND_AND = 288,
445 : OR_OR = 289,
446 : GREATER_GREATER = 290,
447 : LESS_LESS = 291,
448 : LESS_AND = 292,
449 : LESS_LESS_LESS = 293,
450 : GREATER_AND = 294,
451 : SEMI_SEMI = 295,
452 : SEMI_AND = 296,
453 : SEMI_SEMI_AND = 297,
454 : LESS_LESS_MINUS = 298,
455 : AND_GREATER = 299,
456 : AND_GREATER_GREATER = 300,
457 : LESS_GREATER = 301,
458 : GREATER_BAR = 302,
459 : BAR_AND = 303,
460 : yacc_EOF = 304
461 : };
462 : #endif
463 : /* Tokens. */
464 : #define IF 258
465 : #define THEN 259
466 : #define ELSE 260
467 : #define ELIF 261
468 : #define FI 262
469 : #define CASE 263
470 : #define ESAC 264
471 : #define FOR 265
472 : #define SELECT 266
473 : #define WHILE 267
474 : #define UNTIL 268
475 : #define DO 269
476 : #define DONE 270
477 : #define FUNCTION 271
478 : #define COPROC 272
479 : #define COND_START 273
480 : #define COND_END 274
481 : #define COND_ERROR 275
482 : #define IN 276
483 : #define BANG 277
484 : #define TIME 278
485 : #define TIMEOPT 279
486 : #define TIMEIGN 280
487 : #define WORD 281
488 : #define ASSIGNMENT_WORD 282
489 : #define REDIR_WORD 283
490 : #define NUMBER 284
491 : #define ARITH_CMD 285
492 : #define ARITH_FOR_EXPRS 286
493 : #define COND_CMD 287
494 : #define AND_AND 288
495 : #define OR_OR 289
496 : #define GREATER_GREATER 290
497 : #define LESS_LESS 291
498 : #define LESS_AND 292
499 : #define LESS_LESS_LESS 293
500 : #define GREATER_AND 294
501 : #define SEMI_SEMI 295
502 : #define SEMI_AND 296
503 : #define SEMI_SEMI_AND 297
504 : #define LESS_LESS_MINUS 298
505 : #define AND_GREATER 299
506 : #define AND_GREATER_GREATER 300
507 : #define LESS_GREATER 301
508 : #define GREATER_BAR 302
509 : #define BAR_AND 303
510 : #define yacc_EOF 304
511 :
512 : /* Value type. */
513 : #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
514 :
515 : union YYSTYPE
516 : {
517 : #line 335 "../parse.y" /* yacc.c:355 */
518 :
519 : WORD_DESC *word; /* the word that we read. */
520 : int number; /* the number that we read. */
521 : WORD_LIST *word_list;
522 : COMMAND *command;
523 : REDIRECT *redirect;
524 : ELEMENT element;
525 : PATTERN_LIST *pattern;
526 :
527 : #line 528 "y.tab.c" /* yacc.c:355 */
528 : };
529 :
530 : typedef union YYSTYPE YYSTYPE;
531 : # define YYSTYPE_IS_TRIVIAL 1
532 : # define YYSTYPE_IS_DECLARED 1
533 : #endif
534 :
535 :
536 : extern YYSTYPE yylval;
537 :
538 : int yyparse (void);
539 :
540 : #endif /* !YY_YY_Y_TAB_H_INCLUDED */
541 :
542 : /* Copy the second part of user declarations. */
543 :
544 : #line 545 "y.tab.c" /* yacc.c:358 */
545 :
546 : #ifdef short
547 : # undef short
548 : #endif
549 :
550 : #ifdef YYTYPE_UINT8
551 : typedef YYTYPE_UINT8 yytype_uint8;
552 : #else
553 : typedef unsigned char yytype_uint8;
554 : #endif
555 :
556 : #ifdef YYTYPE_INT8
557 : typedef YYTYPE_INT8 yytype_int8;
558 : #else
559 : typedef signed char yytype_int8;
560 : #endif
561 :
562 : #ifdef YYTYPE_UINT16
563 : typedef YYTYPE_UINT16 yytype_uint16;
564 : #else
565 : typedef unsigned short int yytype_uint16;
566 : #endif
567 :
568 : #ifdef YYTYPE_INT16
569 : typedef YYTYPE_INT16 yytype_int16;
570 : #else
571 : typedef short int yytype_int16;
572 : #endif
573 :
574 : #ifndef YYSIZE_T
575 : # ifdef __SIZE_TYPE__
576 : # define YYSIZE_T __SIZE_TYPE__
577 : # elif defined size_t
578 : # define YYSIZE_T size_t
579 : # elif ! defined YYSIZE_T
580 : # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
581 : # define YYSIZE_T size_t
582 : # else
583 : # define YYSIZE_T unsigned int
584 : # endif
585 : #endif
586 :
587 : #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
588 :
589 : #ifndef YY_
590 : # if defined YYENABLE_NLS && YYENABLE_NLS
591 : # if ENABLE_NLS
592 : # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
593 : # define YY_(Msgid) dgettext ("bison-runtime", Msgid)
594 : # endif
595 : # endif
596 : # ifndef YY_
597 : # define YY_(Msgid) Msgid
598 : # endif
599 : #endif
600 :
601 : #ifndef YY_ATTRIBUTE
602 : # if (defined __GNUC__ \
603 : && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
604 : || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
605 : # define YY_ATTRIBUTE(Spec) __attribute__(Spec)
606 : # else
607 : # define YY_ATTRIBUTE(Spec) /* empty */
608 : # endif
609 : #endif
610 :
611 : #ifndef YY_ATTRIBUTE_PURE
612 : # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
613 : #endif
614 :
615 : #ifndef YY_ATTRIBUTE_UNUSED
616 : # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
617 : #endif
618 :
619 : #if !defined _Noreturn \
620 : && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
621 : # if defined _MSC_VER && 1200 <= _MSC_VER
622 : # define _Noreturn __declspec (noreturn)
623 : # else
624 : # define _Noreturn YY_ATTRIBUTE ((__noreturn__))
625 : # endif
626 : #endif
627 :
628 : /* Suppress unused-variable warnings by "using" E. */
629 : #if ! defined lint || defined __GNUC__
630 : # define YYUSE(E) ((void) (E))
631 : #else
632 : # define YYUSE(E) /* empty */
633 : #endif
634 :
635 : #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
636 : /* Suppress an incorrect diagnostic about yylval being uninitialized. */
637 : # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
638 : _Pragma ("GCC diagnostic push") \
639 : _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
640 : _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
641 : # define YY_IGNORE_MAYBE_UNINITIALIZED_END \
642 : _Pragma ("GCC diagnostic pop")
643 : #else
644 : # define YY_INITIAL_VALUE(Value) Value
645 : #endif
646 : #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
647 : # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
648 : # define YY_IGNORE_MAYBE_UNINITIALIZED_END
649 : #endif
650 : #ifndef YY_INITIAL_VALUE
651 : # define YY_INITIAL_VALUE(Value) /* Nothing. */
652 : #endif
653 :
654 :
655 : #if ! defined yyoverflow || YYERROR_VERBOSE
656 :
657 : /* The parser invokes alloca or malloc; define the necessary symbols. */
658 :
659 : # ifdef YYSTACK_USE_ALLOCA
660 : # if YYSTACK_USE_ALLOCA
661 : # ifdef __GNUC__
662 : # define YYSTACK_ALLOC __builtin_alloca
663 : # elif defined __BUILTIN_VA_ARG_INCR
664 : # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
665 : # elif defined _AIX
666 : # define YYSTACK_ALLOC __alloca
667 : # elif defined _MSC_VER
668 : # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
669 : # define alloca _alloca
670 : # else
671 : # define YYSTACK_ALLOC alloca
672 : # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
673 : # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
674 : /* Use EXIT_SUCCESS as a witness for stdlib.h. */
675 : # ifndef EXIT_SUCCESS
676 : # define EXIT_SUCCESS 0
677 : # endif
678 : # endif
679 : # endif
680 : # endif
681 : # endif
682 :
683 : # ifdef YYSTACK_ALLOC
684 : /* Pacify GCC's 'empty if-body' warning. */
685 : # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
686 : # ifndef YYSTACK_ALLOC_MAXIMUM
687 : /* The OS might guarantee only one guard page at the bottom of the stack,
688 : and a page size can be as small as 4096 bytes. So we cannot safely
689 : invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
690 : to allow for a few compiler-allocated temporary stack slots. */
691 : # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
692 : # endif
693 : # else
694 : # define YYSTACK_ALLOC YYMALLOC
695 : # define YYSTACK_FREE YYFREE
696 : # ifndef YYSTACK_ALLOC_MAXIMUM
697 : # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
698 : # endif
699 : # if (defined __cplusplus && ! defined EXIT_SUCCESS \
700 : && ! ((defined YYMALLOC || defined malloc) \
701 : && (defined YYFREE || defined free)))
702 : # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
703 : # ifndef EXIT_SUCCESS
704 : # define EXIT_SUCCESS 0
705 : # endif
706 : # endif
707 : # ifndef YYMALLOC
708 : # define YYMALLOC malloc
709 : # if ! defined malloc && ! defined EXIT_SUCCESS
710 : void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
711 : # endif
712 : # endif
713 : # ifndef YYFREE
714 : # define YYFREE free
715 : # if ! defined free && ! defined EXIT_SUCCESS
716 : void free (void *); /* INFRINGES ON USER NAME SPACE */
717 : # endif
718 : # endif
719 : # endif
720 : #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
721 :
722 :
723 : #if (! defined yyoverflow \
724 : && (! defined __cplusplus \
725 : || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
726 :
727 : /* A type that is properly aligned for any stack member. */
728 : union yyalloc
729 : {
730 : yytype_int16 yyss_alloc;
731 : YYSTYPE yyvs_alloc;
732 : };
733 :
734 : /* The size of the maximum gap between one aligned stack and the next. */
735 : # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
736 :
737 : /* The size of an array large to enough to hold all stacks, each with
738 : N elements. */
739 : # define YYSTACK_BYTES(N) \
740 : ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
741 : + YYSTACK_GAP_MAXIMUM)
742 :
743 : # define YYCOPY_NEEDED 1
744 :
745 : /* Relocate STACK from its old location to the new one. The
746 : local variables YYSIZE and YYSTACKSIZE give the old and new number of
747 : elements in the stack, and YYPTR gives the new location of the
748 : stack. Advance YYPTR to a properly aligned location for the next
749 : stack. */
750 : # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
751 : do \
752 : { \
753 : YYSIZE_T yynewbytes; \
754 : YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
755 : Stack = &yyptr->Stack_alloc; \
756 : yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
757 : yyptr += yynewbytes / sizeof (*yyptr); \
758 : } \
759 : while (0)
760 :
761 : #endif
762 :
763 : #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
764 : /* Copy COUNT objects from SRC to DST. The source and destination do
765 : not overlap. */
766 : # ifndef YYCOPY
767 : # if defined __GNUC__ && 1 < __GNUC__
768 : # define YYCOPY(Dst, Src, Count) \
769 : __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
770 : # else
771 : # define YYCOPY(Dst, Src, Count) \
772 : do \
773 : { \
774 : YYSIZE_T yyi; \
775 : for (yyi = 0; yyi < (Count); yyi++) \
776 : (Dst)[yyi] = (Src)[yyi]; \
777 : } \
778 : while (0)
779 : # endif
780 : # endif
781 : #endif /* !YYCOPY_NEEDED */
782 :
783 : /* YYFINAL -- State number of the termination state. */
784 : #define YYFINAL 116
785 : /* YYLAST -- Last index in YYTABLE. */
786 : #define YYLAST 638
787 :
788 : /* YYNTOKENS -- Number of terminals. */
789 : #define YYNTOKENS 61
790 : /* YYNNTS -- Number of nonterminals. */
791 : #define YYNNTS 38
792 : /* YYNRULES -- Number of rules. */
793 : #define YYNRULES 167
794 : /* YYNSTATES -- Number of states. */
795 : #define YYNSTATES 334
796 :
797 : /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
798 : by yylex, with out-of-bounds checking. */
799 : #define YYUNDEFTOK 2
800 : #define YYMAXUTOK 304
801 :
802 : #define YYTRANSLATE(YYX) \
803 : ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
804 :
805 : /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
806 : as returned by yylex, without out-of-bounds checking. */
807 : static const yytype_uint8 yytranslate[] =
808 : {
809 : 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
810 : 51, 2, 2, 2, 2, 2, 2, 2, 2, 2,
811 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
812 : 2, 2, 2, 2, 2, 2, 2, 2, 49, 2,
813 : 59, 60, 2, 2, 2, 56, 2, 2, 2, 2,
814 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 50,
815 : 55, 2, 54, 2, 2, 2, 2, 2, 2, 2,
816 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
817 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
818 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
819 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
820 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
821 : 2, 2, 2, 57, 53, 58, 2, 2, 2, 2,
822 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
823 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
824 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
825 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
826 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
827 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
828 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
829 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
830 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
831 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
832 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
833 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
834 : 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
835 : 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
836 : 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
837 : 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
838 : 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
839 : 45, 46, 47, 48, 52
840 : };
841 :
842 : #if YYDEBUG
843 : /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
844 : static const yytype_uint16 yyrline[] =
845 : {
846 : 0, 388, 388, 399, 408, 423, 433, 435, 439, 445,
847 : 451, 457, 463, 469, 475, 481, 487, 493, 499, 505,
848 : 511, 517, 523, 529, 536, 543, 550, 557, 564, 571,
849 : 577, 583, 589, 595, 601, 607, 613, 619, 625, 631,
850 : 637, 643, 649, 655, 661, 667, 673, 679, 685, 691,
851 : 697, 703, 711, 713, 715, 719, 723, 734, 736, 740,
852 : 742, 744, 760, 762, 766, 768, 770, 772, 774, 776,
853 : 778, 780, 782, 784, 786, 790, 795, 800, 805, 810,
854 : 815, 820, 825, 832, 837, 842, 847, 854, 859, 864,
855 : 869, 874, 879, 886, 891, 896, 903, 906, 909, 913,
856 : 915, 946, 953, 958, 975, 980, 997, 1004, 1006, 1008,
857 : 1013, 1017, 1021, 1025, 1027, 1029, 1033, 1034, 1038, 1040,
858 : 1042, 1044, 1048, 1050, 1052, 1054, 1056, 1058, 1062, 1064,
859 : 1073, 1081, 1082, 1088, 1089, 1096, 1100, 1102, 1104, 1111,
860 : 1113, 1115, 1119, 1120, 1123, 1125, 1127, 1131, 1132, 1141,
861 : 1154, 1170, 1185, 1187, 1189, 1196, 1199, 1203, 1205, 1211,
862 : 1217, 1236, 1258, 1260, 1283, 1287, 1289, 1291
863 : };
864 : #endif
865 :
866 : #if YYDEBUG || YYERROR_VERBOSE || 0
867 : /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
868 : First, the terminals, then, starting at YYNTOKENS, nonterminals. */
869 : static const char *const yytname[] =
870 : {
871 : "$end", "error", "$undefined", "IF", "THEN", "ELSE", "ELIF", "FI",
872 : "CASE", "ESAC", "FOR", "SELECT", "WHILE", "UNTIL", "DO", "DONE",
873 : "FUNCTION", "COPROC", "COND_START", "COND_END", "COND_ERROR", "IN",
874 : "BANG", "TIME", "TIMEOPT", "TIMEIGN", "WORD", "ASSIGNMENT_WORD",
875 : "REDIR_WORD", "NUMBER", "ARITH_CMD", "ARITH_FOR_EXPRS", "COND_CMD",
876 : "AND_AND", "OR_OR", "GREATER_GREATER", "LESS_LESS", "LESS_AND",
877 : "LESS_LESS_LESS", "GREATER_AND", "SEMI_SEMI", "SEMI_AND",
878 : "SEMI_SEMI_AND", "LESS_LESS_MINUS", "AND_GREATER", "AND_GREATER_GREATER",
879 : "LESS_GREATER", "GREATER_BAR", "BAR_AND", "'&'", "';'", "'\\n'",
880 : "yacc_EOF", "'|'", "'>'", "'<'", "'-'", "'{'", "'}'", "'('", "')'",
881 : "$accept", "inputunit", "word_list", "redirection",
882 : "simple_command_element", "redirection_list", "simple_command",
883 : "command", "shell_command", "for_command", "arith_for_command",
884 : "select_command", "case_command", "function_def", "function_body",
885 : "subshell", "coproc", "if_command", "group_command", "arith_command",
886 : "cond_command", "elif_clause", "case_clause", "pattern_list",
887 : "case_clause_sequence", "pattern", "list", "compound_list", "list0",
888 : "list1", "simple_list_terminator", "list_terminator", "newline_list",
889 : "simple_list", "simple_list1", "pipeline_command", "pipeline",
890 : "timespec", YY_NULLPTR
891 : };
892 : #endif
893 :
894 : # ifdef YYPRINT
895 : /* YYTOKNUM[NUM] -- (External) token number corresponding to the
896 : (internal) symbol number NUM (which must be that of a token). */
897 : static const yytype_uint16 yytoknum[] =
898 : {
899 : 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
900 : 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
901 : 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
902 : 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
903 : 295, 296, 297, 298, 299, 300, 301, 302, 303, 38,
904 : 59, 10, 304, 124, 62, 60, 45, 123, 125, 40,
905 : 41
906 : };
907 : # endif
908 :
909 : #define YYPACT_NINF -205
910 :
911 : #define yypact_value_is_default(Yystate) \
912 : (!!((Yystate) == (-205)))
913 :
914 : #define YYTABLE_NINF -1
915 :
916 : #define yytable_value_is_error(Yytable_value) \
917 : 0
918 :
919 : /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
920 : STATE-NUM. */
921 : static const yytype_int16 yypact[] =
922 : {
923 : 308, -28, -205, 6, -1, 37, -205, -205, 57, 558,
924 : 18, 358, 54, 45, -205, 251, 583, -205, 102, 104,
925 : 35, 107, 80, 112, 127, 140, 146, 147, -205, -205,
926 : 153, 154, -205, -205, 188, -205, -205, 196, -205, 219,
927 : -205, -205, -205, -205, -205, -205, -205, -205, -205, -205,
928 : -205, 17, 23, -205, -19, 358, -205, -205, 185, 408,
929 : -205, 144, 51, 166, 189, 207, 133, 28, 196, 219,
930 : 211, -205, -205, -205, -205, -205, 201, 184, 220, 226,
931 : 81, 227, 126, 233, 234, 241, 242, 245, 246, 249,
932 : 142, 255, 148, 256, 257, 259, 266, 267, -205, -205,
933 : -205, -205, -205, -205, -205, -205, -205, -205, -205, -205,
934 : -205, -205, -205, -205, 243, 240, -205, -205, -205, -205,
935 : 219, -205, -205, -205, -205, -205, 458, 458, -205, -205,
936 : -205, -205, -205, -205, -205, 299, -205, 68, -205, 61,
937 : -205, -205, -205, -205, 72, -205, -205, 244, 41, 219,
938 : 219, -205, -205, -205, -205, -205, -205, -205, -205, -205,
939 : -205, -205, -205, -205, -205, -205, -205, -205, -205, -205,
940 : -205, -205, -205, -205, -205, -205, -205, -205, -205, -205,
941 : -205, -205, -205, -205, -205, 408, 408, 63, 63, 508,
942 : 508, 179, -205, -205, -205, -205, -205, -205, 60, -205,
943 : 155, -205, 287, 252, 74, 108, -205, 286, -205, 300,
944 : 302, -205, 219, -205, 219, 41, -205, -205, -19, -19,
945 : -205, -205, -205, 307, 408, 408, 408, 408, 408, 313,
946 : 159, -205, -4, -205, -205, 312, -205, 161, -205, 265,
947 : -205, -205, -205, -205, -205, -205, 314, 408, 161, 270,
948 : -205, -205, 41, 219, -205, 332, 336, -205, -205, -205,
949 : 87, 87, 87, -205, -205, -205, -205, 178, 11, -205,
950 : -205, 315, -43, 327, 298, -205, -205, -205, 110, -205,
951 : 342, 306, 343, 319, -205, 299, -205, -205, -205, -205,
952 : -205, -205, -205, -205, -205, -32, 346, -205, -205, -205,
953 : 113, -205, -205, -205, -205, -205, -205, 118, 137, -205,
954 : -205, -205, 408, -205, -205, 363, 321, -205, -205, -205,
955 : -205, -205, 408, 367, 325, -205, -205, 374, 333, -205,
956 : -205, -205, -205, -205
957 : };
958 :
959 : /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
960 : Performed when YYTABLE does not specify something else to do. Zero
961 : means the default is an error. */
962 : static const yytype_uint8 yydefact[] =
963 : {
964 : 0, 0, 147, 0, 0, 0, 147, 147, 0, 0,
965 : 0, 0, 165, 52, 53, 0, 0, 111, 0, 0,
966 : 0, 0, 0, 0, 0, 0, 0, 0, 3, 5,
967 : 0, 0, 147, 147, 0, 54, 57, 59, 164, 60,
968 : 64, 74, 68, 65, 62, 70, 63, 69, 71, 72,
969 : 73, 0, 149, 156, 157, 0, 4, 131, 0, 0,
970 : 147, 147, 0, 147, 0, 0, 147, 52, 106, 102,
971 : 0, 145, 144, 146, 161, 158, 166, 0, 0, 0,
972 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
973 : 0, 0, 0, 0, 0, 0, 0, 0, 14, 23,
974 : 38, 32, 47, 29, 41, 35, 44, 26, 50, 51,
975 : 20, 17, 8, 9, 0, 0, 1, 52, 58, 55,
976 : 61, 142, 143, 2, 147, 147, 150, 151, 147, 147,
977 : 160, 159, 147, 148, 130, 132, 141, 0, 147, 0,
978 : 147, 147, 147, 147, 0, 147, 147, 0, 0, 104,
979 : 103, 112, 167, 147, 16, 25, 40, 34, 49, 31,
980 : 43, 37, 46, 28, 22, 19, 12, 13, 15, 24,
981 : 39, 33, 48, 30, 42, 36, 45, 27, 21, 18,
982 : 10, 11, 110, 101, 56, 0, 0, 154, 155, 0,
983 : 0, 0, 147, 147, 147, 147, 147, 147, 0, 147,
984 : 0, 147, 0, 0, 0, 0, 147, 0, 147, 0,
985 : 0, 147, 99, 98, 105, 0, 152, 153, 163, 162,
986 : 147, 147, 107, 0, 0, 0, 134, 135, 133, 0,
987 : 116, 147, 0, 147, 147, 0, 6, 0, 147, 0,
988 : 85, 86, 147, 147, 147, 147, 0, 0, 0, 0,
989 : 66, 67, 0, 100, 96, 0, 0, 109, 136, 137,
990 : 138, 139, 140, 95, 122, 124, 126, 117, 0, 93,
991 : 128, 0, 0, 0, 0, 75, 7, 147, 0, 76,
992 : 0, 0, 0, 0, 87, 0, 147, 88, 97, 108,
993 : 147, 123, 125, 127, 94, 0, 0, 147, 77, 78,
994 : 0, 147, 147, 83, 84, 89, 90, 0, 113, 147,
995 : 129, 118, 119, 147, 147, 0, 0, 147, 147, 147,
996 : 115, 120, 121, 0, 0, 81, 82, 0, 0, 114,
997 : 79, 80, 91, 92
998 : };
999 :
1000 : /* YYPGOTO[NTERM-NUM]. */
1001 : static const yytype_int16 yypgoto[] =
1002 : {
1003 : -205, -205, 183, -36, -23, -50, 364, -205, -7, -205,
1004 : -205, -205, -205, -205, -204, -205, -205, -205, -205, -205,
1005 : -205, 84, -205, 167, -205, 128, -202, -6, -205, 52,
1006 : -205, -46, -48, -205, -119, 24, -33, -205
1007 : };
1008 :
1009 : /* YYDEFGOTO[NTERM-NUM]. */
1010 : static const yytype_int16 yydefgoto[] =
1011 : {
1012 : -1, 34, 237, 35, 36, 120, 37, 38, 39, 40,
1013 : 41, 42, 43, 44, 213, 45, 46, 47, 48, 49,
1014 : 50, 223, 229, 230, 231, 272, 57, 58, 134, 135,
1015 : 123, 74, 59, 51, 52, 136, 54, 55
1016 : };
1017 :
1018 : /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
1019 : positive, shift that token. If negative, reduce the rule whose
1020 : number is the opposite. If YYTABLE_NINF, syntax error. */
1021 : static const yytype_uint16 yytable[] =
1022 : {
1023 : 64, 65, 69, 119, 246, 269, 249, 187, 188, 130,
1024 : 296, 254, 137, 139, 118, 144, 142, 297, 148, 150,
1025 : 294, 296, 270, 56, 53, 61, 114, 115, 309, 128,
1026 : 62, 2, 60, 119, 129, 75, 3, 270, 4, 5,
1027 : 6, 7, 282, 283, 2, 118, 10, 133, 288, 3,
1028 : 70, 4, 5, 6, 7, 271, 124, 125, 17, 10,
1029 : 149, 100, 133, 63, 101, 140, 216, 217, 121, 122,
1030 : 271, 17, 126, 127, 233, 199, 185, 186, 76, 131,
1031 : 189, 190, 200, 66, 184, 32, 206, 33, 242, 197,
1032 : 198, 102, 133, 207, 204, 205, 124, 125, 32, 214,
1033 : 33, 71, 72, 73, 77, 215, 104, 156, 141, 105,
1034 : 157, 133, 133, 119, 184, 327, 328, 234, 201, 133,
1035 : 192, 193, 244, 133, 301, 133, 191, 313, 98, 208,
1036 : 99, 243, 317, 103, 202, 203, 106, 158, 107, 209,
1037 : 210, 212, 319, 221, 224, 225, 226, 227, 228, 232,
1038 : 53, 53, 160, 108, 238, 161, 218, 219, 247, 133,
1039 : 247, 133, 253, 252, 133, 245, 109, 302, 170, 133,
1040 : 314, 171, 110, 111, 174, 318, 119, 175, 184, 112,
1041 : 113, 236, 162, 268, 220, 221, 222, 276, 116, 132,
1042 : 278, 277, 147, 235, 138, 239, 247, 247, 172, 264,
1043 : 265, 266, 286, 145, 176, 71, 72, 73, 212, 53,
1044 : 53, 71, 72, 73, 255, 256, 143, 184, 291, 292,
1045 : 293, 146, 117, 14, 15, 16, 152, 273, 274, 300,
1046 : 151, 18, 19, 20, 21, 22, 280, 281, 307, 23,
1047 : 24, 25, 26, 27, 153, 212, 154, 15, 16, 312,
1048 : 30, 31, 155, 159, 18, 19, 20, 21, 22, 163,
1049 : 164, 322, 23, 24, 25, 26, 27, 165, 166, 247,
1050 : 247, 167, 168, 30, 31, 169, 258, 259, 260, 261,
1051 : 262, 173, 177, 178, 308, 179, 78, 79, 80, 81,
1052 : 82, 311, 180, 181, 83, 315, 316, 84, 85, 285,
1053 : 183, 182, 240, 321, 211, 86, 87, 323, 324, 1,
1054 : 241, 2, 236, 329, 257, 250, 3, 251, 4, 5,
1055 : 6, 7, 263, 279, 8, 9, 10, 275, 287, 284,
1056 : 11, 12, 192, 193, 13, 14, 15, 16, 17, 289,
1057 : 290, 270, 298, 18, 19, 20, 21, 22, 194, 195,
1058 : 196, 23, 24, 25, 26, 27, 299, 303, 305, 28,
1059 : 29, 2, 30, 31, 304, 32, 3, 33, 4, 5,
1060 : 6, 7, 310, 68, 8, 9, 10, 306, 325, 326,
1061 : 11, 12, 330, 331, 13, 14, 15, 16, 17, 332,
1062 : 248, 333, 320, 18, 19, 20, 21, 22, 267, 295,
1063 : 0, 23, 24, 25, 26, 27, 0, 0, 71, 72,
1064 : 73, 2, 30, 31, 0, 32, 3, 33, 4, 5,
1065 : 6, 7, 0, 0, 8, 9, 10, 0, 0, 0,
1066 : 11, 12, 0, 0, 13, 14, 15, 16, 17, 0,
1067 : 0, 0, 0, 18, 19, 20, 21, 22, 0, 0,
1068 : 0, 23, 24, 25, 26, 27, 0, 0, 0, 133,
1069 : 0, 2, 30, 31, 0, 32, 3, 33, 4, 5,
1070 : 6, 7, 0, 0, 8, 9, 10, 0, 0, 0,
1071 : 11, 12, 0, 0, 13, 14, 15, 16, 17, 0,
1072 : 0, 0, 0, 18, 19, 20, 21, 22, 0, 0,
1073 : 0, 23, 24, 25, 26, 27, 0, 0, 0, 0,
1074 : 0, 2, 30, 31, 0, 32, 3, 33, 4, 5,
1075 : 6, 7, 0, 0, 8, 9, 10, 0, 0, 0,
1076 : 0, 0, 0, 0, 13, 14, 15, 16, 17, 0,
1077 : 0, 0, 0, 18, 19, 20, 21, 22, 0, 0,
1078 : 0, 23, 24, 25, 26, 27, 0, 0, 0, 133,
1079 : 0, 2, 30, 31, 0, 32, 3, 33, 4, 5,
1080 : 6, 7, 0, 0, 0, 0, 10, 0, 0, 0,
1081 : 0, 0, 0, 0, 67, 14, 15, 16, 17, 0,
1082 : 0, 0, 0, 18, 19, 20, 21, 22, 0, 0,
1083 : 0, 23, 24, 25, 26, 27, 0, 0, 0, 0,
1084 : 0, 0, 30, 31, 0, 32, 0, 33, 88, 89,
1085 : 90, 91, 92, 0, 0, 0, 93, 0, 0, 94,
1086 : 95, 0, 0, 0, 0, 0, 0, 96, 97
1087 : };
1088 :
1089 : static const yytype_int16 yycheck[] =
1090 : {
1091 : 6, 7, 9, 39, 206, 9, 208, 126, 127, 55,
1092 : 53, 215, 60, 61, 37, 63, 62, 60, 66, 69,
1093 : 9, 53, 26, 51, 0, 26, 32, 33, 60, 48,
1094 : 31, 3, 26, 69, 53, 11, 8, 26, 10, 11,
1095 : 12, 13, 244, 245, 3, 68, 18, 51, 252, 8,
1096 : 32, 10, 11, 12, 13, 59, 33, 34, 30, 18,
1097 : 67, 26, 51, 26, 29, 14, 185, 186, 51, 52,
1098 : 59, 30, 49, 50, 14, 14, 124, 125, 24, 55,
1099 : 128, 129, 21, 26, 120, 57, 14, 59, 14, 21,
1100 : 138, 56, 51, 21, 142, 143, 33, 34, 57, 149,
1101 : 59, 50, 51, 52, 59, 153, 26, 26, 57, 29,
1102 : 29, 51, 51, 149, 150, 317, 318, 57, 57, 51,
1103 : 33, 34, 14, 51, 14, 51, 132, 14, 26, 57,
1104 : 26, 57, 14, 26, 140, 141, 56, 56, 26, 145,
1105 : 146, 148, 5, 6, 192, 193, 194, 195, 196, 197,
1106 : 126, 127, 26, 26, 200, 29, 189, 190, 206, 51,
1107 : 208, 51, 212, 211, 51, 57, 26, 57, 26, 51,
1108 : 57, 29, 26, 26, 26, 57, 212, 29, 214, 26,
1109 : 26, 26, 56, 231, 5, 6, 7, 26, 0, 4,
1110 : 238, 237, 59, 199, 50, 201, 244, 245, 56, 40,
1111 : 41, 42, 248, 14, 56, 50, 51, 52, 215, 185,
1112 : 186, 50, 51, 52, 220, 221, 50, 253, 40, 41,
1113 : 42, 14, 26, 27, 28, 29, 25, 233, 234, 277,
1114 : 19, 35, 36, 37, 38, 39, 242, 243, 286, 43,
1115 : 44, 45, 46, 47, 60, 252, 26, 28, 29, 297,
1116 : 54, 55, 26, 26, 35, 36, 37, 38, 39, 26,
1117 : 26, 309, 43, 44, 45, 46, 47, 26, 26, 317,
1118 : 318, 26, 26, 54, 55, 26, 224, 225, 226, 227,
1119 : 228, 26, 26, 26, 290, 26, 35, 36, 37, 38,
1120 : 39, 297, 26, 26, 43, 301, 302, 46, 47, 247,
1121 : 60, 58, 15, 309, 60, 54, 55, 313, 314, 1,
1122 : 58, 3, 26, 319, 7, 15, 8, 15, 10, 11,
1123 : 12, 13, 9, 58, 16, 17, 18, 15, 58, 15,
1124 : 22, 23, 33, 34, 26, 27, 28, 29, 30, 7,
1125 : 4, 26, 15, 35, 36, 37, 38, 39, 49, 50,
1126 : 51, 43, 44, 45, 46, 47, 58, 15, 15, 51,
1127 : 52, 3, 54, 55, 58, 57, 8, 59, 10, 11,
1128 : 12, 13, 26, 9, 16, 17, 18, 58, 15, 58,
1129 : 22, 23, 15, 58, 26, 27, 28, 29, 30, 15,
1130 : 207, 58, 308, 35, 36, 37, 38, 39, 231, 271,
1131 : -1, 43, 44, 45, 46, 47, -1, -1, 50, 51,
1132 : 52, 3, 54, 55, -1, 57, 8, 59, 10, 11,
1133 : 12, 13, -1, -1, 16, 17, 18, -1, -1, -1,
1134 : 22, 23, -1, -1, 26, 27, 28, 29, 30, -1,
1135 : -1, -1, -1, 35, 36, 37, 38, 39, -1, -1,
1136 : -1, 43, 44, 45, 46, 47, -1, -1, -1, 51,
1137 : -1, 3, 54, 55, -1, 57, 8, 59, 10, 11,
1138 : 12, 13, -1, -1, 16, 17, 18, -1, -1, -1,
1139 : 22, 23, -1, -1, 26, 27, 28, 29, 30, -1,
1140 : -1, -1, -1, 35, 36, 37, 38, 39, -1, -1,
1141 : -1, 43, 44, 45, 46, 47, -1, -1, -1, -1,
1142 : -1, 3, 54, 55, -1, 57, 8, 59, 10, 11,
1143 : 12, 13, -1, -1, 16, 17, 18, -1, -1, -1,
1144 : -1, -1, -1, -1, 26, 27, 28, 29, 30, -1,
1145 : -1, -1, -1, 35, 36, 37, 38, 39, -1, -1,
1146 : -1, 43, 44, 45, 46, 47, -1, -1, -1, 51,
1147 : -1, 3, 54, 55, -1, 57, 8, 59, 10, 11,
1148 : 12, 13, -1, -1, -1, -1, 18, -1, -1, -1,
1149 : -1, -1, -1, -1, 26, 27, 28, 29, 30, -1,
1150 : -1, -1, -1, 35, 36, 37, 38, 39, -1, -1,
1151 : -1, 43, 44, 45, 46, 47, -1, -1, -1, -1,
1152 : -1, -1, 54, 55, -1, 57, -1, 59, 35, 36,
1153 : 37, 38, 39, -1, -1, -1, 43, -1, -1, 46,
1154 : 47, -1, -1, -1, -1, -1, -1, 54, 55
1155 : };
1156 :
1157 : /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1158 : symbol of state STATE-NUM. */
1159 : static const yytype_uint8 yystos[] =
1160 : {
1161 : 0, 1, 3, 8, 10, 11, 12, 13, 16, 17,
1162 : 18, 22, 23, 26, 27, 28, 29, 30, 35, 36,
1163 : 37, 38, 39, 43, 44, 45, 46, 47, 51, 52,
1164 : 54, 55, 57, 59, 62, 64, 65, 67, 68, 69,
1165 : 70, 71, 72, 73, 74, 76, 77, 78, 79, 80,
1166 : 81, 94, 95, 96, 97, 98, 51, 87, 88, 93,
1167 : 26, 26, 31, 26, 88, 88, 26, 26, 67, 69,
1168 : 32, 50, 51, 52, 92, 96, 24, 59, 35, 36,
1169 : 37, 38, 39, 43, 46, 47, 54, 55, 35, 36,
1170 : 37, 38, 39, 43, 46, 47, 54, 55, 26, 26,
1171 : 26, 29, 56, 26, 26, 29, 56, 26, 26, 26,
1172 : 26, 26, 26, 26, 88, 88, 0, 26, 65, 64,
1173 : 66, 51, 52, 91, 33, 34, 49, 50, 48, 53,
1174 : 92, 96, 4, 51, 89, 90, 96, 93, 50, 93,
1175 : 14, 57, 92, 50, 93, 14, 14, 59, 93, 69,
1176 : 66, 19, 25, 60, 26, 26, 26, 29, 56, 26,
1177 : 26, 29, 56, 26, 26, 26, 26, 26, 26, 26,
1178 : 26, 29, 56, 26, 26, 29, 56, 26, 26, 26,
1179 : 26, 26, 58, 60, 64, 93, 93, 95, 95, 93,
1180 : 93, 88, 33, 34, 49, 50, 51, 21, 93, 14,
1181 : 21, 57, 88, 88, 93, 93, 14, 21, 57, 88,
1182 : 88, 60, 69, 75, 66, 93, 95, 95, 97, 97,
1183 : 5, 6, 7, 82, 93, 93, 93, 93, 93, 83,
1184 : 84, 85, 93, 14, 57, 88, 26, 63, 92, 88,
1185 : 15, 58, 14, 57, 14, 57, 87, 93, 63, 87,
1186 : 15, 15, 93, 66, 75, 88, 88, 7, 90, 90,
1187 : 90, 90, 90, 9, 40, 41, 42, 84, 93, 9,
1188 : 26, 59, 86, 88, 88, 15, 26, 92, 93, 58,
1189 : 88, 88, 87, 87, 15, 90, 92, 58, 75, 7,
1190 : 4, 40, 41, 42, 9, 86, 53, 60, 15, 58,
1191 : 93, 14, 57, 15, 58, 15, 58, 93, 88, 60,
1192 : 26, 88, 93, 14, 57, 88, 88, 14, 57, 5,
1193 : 82, 88, 93, 88, 88, 15, 58, 87, 87, 88,
1194 : 15, 58, 15, 58
1195 : };
1196 :
1197 : /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
1198 : static const yytype_uint8 yyr1[] =
1199 : {
1200 : 0, 61, 62, 62, 62, 62, 63, 63, 64, 64,
1201 : 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1202 : 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1203 : 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1204 : 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1205 : 64, 64, 65, 65, 65, 66, 66, 67, 67, 68,
1206 : 68, 68, 68, 68, 69, 69, 69, 69, 69, 69,
1207 : 69, 69, 69, 69, 69, 70, 70, 70, 70, 70,
1208 : 70, 70, 70, 71, 71, 71, 71, 72, 72, 72,
1209 : 72, 72, 72, 73, 73, 73, 74, 74, 74, 75,
1210 : 75, 76, 77, 77, 77, 77, 77, 78, 78, 78,
1211 : 79, 80, 81, 82, 82, 82, 83, 83, 84, 84,
1212 : 84, 84, 85, 85, 85, 85, 85, 85, 86, 86,
1213 : 87, 88, 88, 89, 89, 89, 90, 90, 90, 90,
1214 : 90, 90, 91, 91, 92, 92, 92, 93, 93, 94,
1215 : 94, 94, 95, 95, 95, 95, 95, 96, 96, 96,
1216 : 96, 96, 97, 97, 97, 98, 98, 98
1217 : };
1218 :
1219 : /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
1220 : static const yytype_uint8 yyr2[] =
1221 : {
1222 : 0, 2, 2, 1, 2, 1, 1, 2, 2, 2,
1223 : 3, 3, 3, 3, 2, 3, 3, 2, 3, 3,
1224 : 2, 3, 3, 2, 3, 3, 2, 3, 3, 2,
1225 : 3, 3, 2, 3, 3, 2, 3, 3, 2, 3,
1226 : 3, 2, 3, 3, 2, 3, 3, 2, 3, 3,
1227 : 2, 2, 1, 1, 1, 1, 2, 1, 2, 1,
1228 : 1, 2, 1, 1, 1, 1, 5, 5, 1, 1,
1229 : 1, 1, 1, 1, 1, 6, 6, 7, 7, 10,
1230 : 10, 9, 9, 7, 7, 5, 5, 6, 6, 7,
1231 : 7, 10, 10, 6, 7, 6, 5, 6, 4, 1,
1232 : 2, 3, 2, 3, 3, 4, 2, 5, 7, 6,
1233 : 3, 1, 3, 4, 6, 5, 1, 2, 4, 4,
1234 : 5, 5, 2, 3, 2, 3, 2, 3, 1, 3,
1235 : 2, 1, 2, 3, 3, 3, 4, 4, 4, 4,
1236 : 4, 1, 1, 1, 1, 1, 1, 0, 2, 1,
1237 : 2, 2, 4, 4, 3, 3, 1, 1, 2, 2,
1238 : 2, 2, 4, 4, 1, 1, 2, 3
1239 : };
1240 :
1241 :
1242 : #define yyerrok (yyerrstatus = 0)
1243 : #define yyclearin (yychar = YYEMPTY)
1244 : #define YYEMPTY (-2)
1245 : #define YYEOF 0
1246 :
1247 : #define YYACCEPT goto yyacceptlab
1248 : #define YYABORT goto yyabortlab
1249 : #define YYERROR goto yyerrorlab
1250 :
1251 :
1252 : #define YYRECOVERING() (!!yyerrstatus)
1253 :
1254 : #define YYBACKUP(Token, Value) \
1255 : do \
1256 : if (yychar == YYEMPTY) \
1257 : { \
1258 : yychar = (Token); \
1259 : yylval = (Value); \
1260 : YYPOPSTACK (yylen); \
1261 : yystate = *yyssp; \
1262 : goto yybackup; \
1263 : } \
1264 : else \
1265 : { \
1266 : yyerror (YY_("syntax error: cannot back up")); \
1267 : YYERROR; \
1268 : } \
1269 : while (0)
1270 :
1271 : /* Error token number */
1272 : #define YYTERROR 1
1273 : #define YYERRCODE 256
1274 :
1275 :
1276 :
1277 : /* Enable debugging if requested. */
1278 : #if YYDEBUG
1279 :
1280 : # ifndef YYFPRINTF
1281 : # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1282 : # define YYFPRINTF fprintf
1283 : # endif
1284 :
1285 : # define YYDPRINTF(Args) \
1286 : do { \
1287 : if (yydebug) \
1288 : YYFPRINTF Args; \
1289 : } while (0)
1290 :
1291 : /* This macro is provided for backward compatibility. */
1292 : #ifndef YY_LOCATION_PRINT
1293 : # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1294 : #endif
1295 :
1296 :
1297 : # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
1298 : do { \
1299 : if (yydebug) \
1300 : { \
1301 : YYFPRINTF (stderr, "%s ", Title); \
1302 : yy_symbol_print (stderr, \
1303 : Type, Value); \
1304 : YYFPRINTF (stderr, "\n"); \
1305 : } \
1306 : } while (0)
1307 :
1308 :
1309 : /*----------------------------------------.
1310 : | Print this symbol's value on YYOUTPUT. |
1311 : `----------------------------------------*/
1312 :
1313 : static void
1314 : yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1315 : {
1316 : FILE *yyo = yyoutput;
1317 : YYUSE (yyo);
1318 : if (!yyvaluep)
1319 : return;
1320 : # ifdef YYPRINT
1321 : if (yytype < YYNTOKENS)
1322 : YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1323 : # endif
1324 : YYUSE (yytype);
1325 : }
1326 :
1327 :
1328 : /*--------------------------------.
1329 : | Print this symbol on YYOUTPUT. |
1330 : `--------------------------------*/
1331 :
1332 : static void
1333 : yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1334 : {
1335 : YYFPRINTF (yyoutput, "%s %s (",
1336 : yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
1337 :
1338 : yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1339 : YYFPRINTF (yyoutput, ")");
1340 : }
1341 :
1342 : /*------------------------------------------------------------------.
1343 : | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1344 : | TOP (included). |
1345 : `------------------------------------------------------------------*/
1346 :
1347 : static void
1348 : yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1349 : {
1350 : YYFPRINTF (stderr, "Stack now");
1351 : for (; yybottom <= yytop; yybottom++)
1352 : {
1353 : int yybot = *yybottom;
1354 : YYFPRINTF (stderr, " %d", yybot);
1355 : }
1356 : YYFPRINTF (stderr, "\n");
1357 : }
1358 :
1359 : # define YY_STACK_PRINT(Bottom, Top) \
1360 : do { \
1361 : if (yydebug) \
1362 : yy_stack_print ((Bottom), (Top)); \
1363 : } while (0)
1364 :
1365 :
1366 : /*------------------------------------------------.
1367 : | Report that the YYRULE is going to be reduced. |
1368 : `------------------------------------------------*/
1369 :
1370 : static void
1371 : yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
1372 : {
1373 : unsigned long int yylno = yyrline[yyrule];
1374 : int yynrhs = yyr2[yyrule];
1375 : int yyi;
1376 : YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1377 : yyrule - 1, yylno);
1378 : /* The symbols being reduced. */
1379 : for (yyi = 0; yyi < yynrhs; yyi++)
1380 : {
1381 : YYFPRINTF (stderr, " $%d = ", yyi + 1);
1382 : yy_symbol_print (stderr,
1383 : yystos[yyssp[yyi + 1 - yynrhs]],
1384 : &(yyvsp[(yyi + 1) - (yynrhs)])
1385 : );
1386 : YYFPRINTF (stderr, "\n");
1387 : }
1388 : }
1389 :
1390 : # define YY_REDUCE_PRINT(Rule) \
1391 : do { \
1392 : if (yydebug) \
1393 : yy_reduce_print (yyssp, yyvsp, Rule); \
1394 : } while (0)
1395 :
1396 : /* Nonzero means print parse trace. It is left uninitialized so that
1397 : multiple parsers can coexist. */
1398 : int yydebug;
1399 : #else /* !YYDEBUG */
1400 : # define YYDPRINTF(Args)
1401 : # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1402 : # define YY_STACK_PRINT(Bottom, Top)
1403 : # define YY_REDUCE_PRINT(Rule)
1404 : #endif /* !YYDEBUG */
1405 :
1406 :
1407 : /* YYINITDEPTH -- initial size of the parser's stacks. */
1408 : #ifndef YYINITDEPTH
1409 : # define YYINITDEPTH 200
1410 : #endif
1411 :
1412 : /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1413 : if the built-in stack extension method is used).
1414 :
1415 : Do not make this value too large; the results are undefined if
1416 : YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1417 : evaluated with infinite-precision integer arithmetic. */
1418 :
1419 : #ifndef YYMAXDEPTH
1420 : # define YYMAXDEPTH 10000
1421 : #endif
1422 :
1423 :
1424 : #if YYERROR_VERBOSE
1425 :
1426 : # ifndef yystrlen
1427 : # if defined __GLIBC__ && defined _STRING_H
1428 : # define yystrlen strlen
1429 : # else
1430 : /* Return the length of YYSTR. */
1431 : static YYSIZE_T
1432 : yystrlen (const char *yystr)
1433 : {
1434 : YYSIZE_T yylen;
1435 : for (yylen = 0; yystr[yylen]; yylen++)
1436 : continue;
1437 : return yylen;
1438 : }
1439 : # endif
1440 : # endif
1441 :
1442 : # ifndef yystpcpy
1443 : # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1444 : # define yystpcpy stpcpy
1445 : # else
1446 : /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1447 : YYDEST. */
1448 : static char *
1449 : yystpcpy (char *yydest, const char *yysrc)
1450 : {
1451 : char *yyd = yydest;
1452 : const char *yys = yysrc;
1453 :
1454 : while ((*yyd++ = *yys++) != '\0')
1455 : continue;
1456 :
1457 : return yyd - 1;
1458 : }
1459 : # endif
1460 : # endif
1461 :
1462 : # ifndef yytnamerr
1463 : /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1464 : quotes and backslashes, so that it's suitable for yyerror. The
1465 : heuristic is that double-quoting is unnecessary unless the string
1466 : contains an apostrophe, a comma, or backslash (other than
1467 : backslash-backslash). YYSTR is taken from yytname. If YYRES is
1468 : null, do not copy; instead, return the length of what the result
1469 : would have been. */
1470 : static YYSIZE_T
1471 : yytnamerr (char *yyres, const char *yystr)
1472 : {
1473 : if (*yystr == '"')
1474 : {
1475 : YYSIZE_T yyn = 0;
1476 : char const *yyp = yystr;
1477 :
1478 : for (;;)
1479 : switch (*++yyp)
1480 : {
1481 : case '\'':
1482 : case ',':
1483 : goto do_not_strip_quotes;
1484 :
1485 : case '\\':
1486 : if (*++yyp != '\\')
1487 : goto do_not_strip_quotes;
1488 : /* Fall through. */
1489 : default:
1490 : if (yyres)
1491 : yyres[yyn] = *yyp;
1492 : yyn++;
1493 : break;
1494 :
1495 : case '"':
1496 : if (yyres)
1497 : yyres[yyn] = '\0';
1498 : return yyn;
1499 : }
1500 : do_not_strip_quotes: ;
1501 : }
1502 :
1503 : if (! yyres)
1504 : return yystrlen (yystr);
1505 :
1506 : return yystpcpy (yyres, yystr) - yyres;
1507 : }
1508 : # endif
1509 :
1510 : /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1511 : about the unexpected token YYTOKEN for the state stack whose top is
1512 : YYSSP.
1513 :
1514 : Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
1515 : not large enough to hold the message. In that case, also set
1516 : *YYMSG_ALLOC to the required number of bytes. Return 2 if the
1517 : required number of bytes is too large to store. */
1518 : static int
1519 : yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1520 : yytype_int16 *yyssp, int yytoken)
1521 : {
1522 : YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
1523 : YYSIZE_T yysize = yysize0;
1524 : enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1525 : /* Internationalized format string. */
1526 : const char *yyformat = YY_NULLPTR;
1527 : /* Arguments of yyformat. */
1528 : char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1529 : /* Number of reported tokens (one for the "unexpected", one per
1530 : "expected"). */
1531 : int yycount = 0;
1532 :
1533 : /* There are many possibilities here to consider:
1534 : - If this state is a consistent state with a default action, then
1535 : the only way this function was invoked is if the default action
1536 : is an error action. In that case, don't check for expected
1537 : tokens because there are none.
1538 : - The only way there can be no lookahead present (in yychar) is if
1539 : this state is a consistent state with a default action. Thus,
1540 : detecting the absence of a lookahead is sufficient to determine
1541 : that there is no unexpected or expected token to report. In that
1542 : case, just report a simple "syntax error".
1543 : - Don't assume there isn't a lookahead just because this state is a
1544 : consistent state with a default action. There might have been a
1545 : previous inconsistent state, consistent state with a non-default
1546 : action, or user semantic action that manipulated yychar.
1547 : - Of course, the expected token list depends on states to have
1548 : correct lookahead information, and it depends on the parser not
1549 : to perform extra reductions after fetching a lookahead from the
1550 : scanner and before detecting a syntax error. Thus, state merging
1551 : (from LALR or IELR) and default reductions corrupt the expected
1552 : token list. However, the list is correct for canonical LR with
1553 : one exception: it will still contain any token that will not be
1554 : accepted due to an error action in a later state.
1555 : */
1556 : if (yytoken != YYEMPTY)
1557 : {
1558 : int yyn = yypact[*yyssp];
1559 : yyarg[yycount++] = yytname[yytoken];
1560 : if (!yypact_value_is_default (yyn))
1561 : {
1562 : /* Start YYX at -YYN if negative to avoid negative indexes in
1563 : YYCHECK. In other words, skip the first -YYN actions for
1564 : this state because they are default actions. */
1565 : int yyxbegin = yyn < 0 ? -yyn : 0;
1566 : /* Stay within bounds of both yycheck and yytname. */
1567 : int yychecklim = YYLAST - yyn + 1;
1568 : int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1569 : int yyx;
1570 :
1571 : for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1572 : if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1573 : && !yytable_value_is_error (yytable[yyx + yyn]))
1574 : {
1575 : if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1576 : {
1577 : yycount = 1;
1578 : yysize = yysize0;
1579 : break;
1580 : }
1581 : yyarg[yycount++] = yytname[yyx];
1582 : {
1583 : YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
1584 : if (! (yysize <= yysize1
1585 : && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1586 : return 2;
1587 : yysize = yysize1;
1588 : }
1589 : }
1590 : }
1591 : }
1592 :
1593 : switch (yycount)
1594 : {
1595 : # define YYCASE_(N, S) \
1596 : case N: \
1597 : yyformat = S; \
1598 : break
1599 : default: /* Avoid compiler warnings. */
1600 : YYCASE_(0, YY_("syntax error"));
1601 : YYCASE_(1, YY_("syntax error, unexpected %s"));
1602 : YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1603 : YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1604 : YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1605 : YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1606 : # undef YYCASE_
1607 : }
1608 :
1609 : {
1610 : YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1611 : if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1612 : return 2;
1613 : yysize = yysize1;
1614 : }
1615 :
1616 : if (*yymsg_alloc < yysize)
1617 : {
1618 : *yymsg_alloc = 2 * yysize;
1619 : if (! (yysize <= *yymsg_alloc
1620 : && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1621 : *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1622 : return 1;
1623 : }
1624 :
1625 : /* Avoid sprintf, as that infringes on the user's name space.
1626 : Don't have undefined behavior even if the translation
1627 : produced a string with the wrong number of "%s"s. */
1628 : {
1629 : char *yyp = *yymsg;
1630 : int yyi = 0;
1631 : while ((*yyp = *yyformat) != '\0')
1632 : if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1633 : {
1634 : yyp += yytnamerr (yyp, yyarg[yyi++]);
1635 : yyformat += 2;
1636 : }
1637 : else
1638 : {
1639 : yyp++;
1640 : yyformat++;
1641 : }
1642 : }
1643 : return 0;
1644 : }
1645 : #endif /* YYERROR_VERBOSE */
1646 :
1647 : /*-----------------------------------------------.
1648 : | Release the memory associated to this symbol. |
1649 : `-----------------------------------------------*/
1650 :
1651 : static void
1652 0 : yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1653 : {
1654 11915725 : YYUSE (yyvaluep);
1655 11915725 : if (!yymsg)
1656 : yymsg = "Deleting";
1657 11915725 : YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1658 :
1659 : YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1660 11915725 : YYUSE (yytype);
1661 : YY_IGNORE_MAYBE_UNINITIALIZED_END
1662 0 : }
1663 :
1664 :
1665 :
1666 :
1667 : /* The lookahead symbol. */
1668 : int yychar;
1669 :
1670 : /* The semantic value of the lookahead symbol. */
1671 : YYSTYPE yylval;
1672 : /* Number of syntax errors so far. */
1673 : int yynerrs;
1674 :
1675 :
1676 : /*----------.
1677 : | yyparse. |
1678 : `----------*/
1679 :
1680 : int
1681 293622549 : yyparse (void)
1682 : {
1683 293622549 : int yystate;
1684 : /* Number of tokens to shift before error messages enabled. */
1685 293622549 : int yyerrstatus;
1686 :
1687 : /* The stacks and their tools:
1688 : 'yyss': related to states.
1689 : 'yyvs': related to semantic values.
1690 :
1691 : Refer to the stacks through separate pointers, to allow yyoverflow
1692 : to reallocate them elsewhere. */
1693 :
1694 : /* The state stack. */
1695 293622549 : yytype_int16 yyssa[YYINITDEPTH];
1696 293622549 : yytype_int16 *yyss;
1697 293622549 : yytype_int16 *yyssp;
1698 :
1699 : /* The semantic value stack. */
1700 293622549 : YYSTYPE yyvsa[YYINITDEPTH];
1701 293622549 : YYSTYPE *yyvs;
1702 293622549 : YYSTYPE *yyvsp;
1703 :
1704 293622549 : YYSIZE_T yystacksize;
1705 :
1706 293622549 : int yyn;
1707 293622549 : int yyresult;
1708 : /* Lookahead token as an internal (translated) token number. */
1709 293622549 : int yytoken = 0;
1710 : /* The variables used to return semantic value and location from the
1711 : action routines. */
1712 293622549 : YYSTYPE yyval;
1713 :
1714 : #if YYERROR_VERBOSE
1715 : /* Buffer for error messages, and its allocated size. */
1716 : char yymsgbuf[128];
1717 : char *yymsg = yymsgbuf;
1718 : YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1719 : #endif
1720 :
1721 : #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1722 :
1723 : /* The number of symbols on the RHS of the reduced rule.
1724 : Keep to zero when no symbol should be popped. */
1725 293622549 : int yylen = 0;
1726 :
1727 293622549 : yyssp = yyss = yyssa;
1728 293622549 : yyvsp = yyvs = yyvsa;
1729 293622549 : yystacksize = YYINITDEPTH;
1730 :
1731 293622549 : YYDPRINTF ((stderr, "Starting parse\n"));
1732 :
1733 293622549 : yystate = 0;
1734 293622549 : yyerrstatus = 0;
1735 293622549 : yynerrs = 0;
1736 293622549 : yychar = YYEMPTY; /* Cause a token to be read. */
1737 293622549 : goto yysetstate;
1738 :
1739 : /*------------------------------------------------------------.
1740 : | yynewstate -- Push a new state, which is found in yystate. |
1741 : `------------------------------------------------------------*/
1742 7600735624 : yynewstate:
1743 : /* In all cases, when you get here, the value and location stacks
1744 : have just been pushed. So pushing a state here evens the stacks. */
1745 7600735624 : yyssp++;
1746 :
1747 7894358173 : yysetstate:
1748 7894358173 : *yyssp = yystate;
1749 :
1750 7894358173 : if (yyss + yystacksize - 1 <= yyssp)
1751 : {
1752 : /* Get the current used size of the three stacks, in elements. */
1753 0 : YYSIZE_T yysize = yyssp - yyss + 1;
1754 :
1755 : #ifdef yyoverflow
1756 : {
1757 : /* Give user a chance to reallocate the stack. Use copies of
1758 : these so that the &'s don't force the real ones into
1759 : memory. */
1760 : YYSTYPE *yyvs1 = yyvs;
1761 : yytype_int16 *yyss1 = yyss;
1762 :
1763 : /* Each stack pointer address is followed by the size of the
1764 : data in use in that stack, in bytes. This used to be a
1765 : conditional around just the two extra args, but that might
1766 : be undefined if yyoverflow is a macro. */
1767 : yyoverflow (YY_("memory exhausted"),
1768 : &yyss1, yysize * sizeof (*yyssp),
1769 : &yyvs1, yysize * sizeof (*yyvsp),
1770 : &yystacksize);
1771 :
1772 : yyss = yyss1;
1773 : yyvs = yyvs1;
1774 : }
1775 : #else /* no yyoverflow */
1776 : # ifndef YYSTACK_RELOCATE
1777 : goto yyexhaustedlab;
1778 : # else
1779 : /* Extend the stack our own way. */
1780 0 : if (YYMAXDEPTH <= yystacksize)
1781 0 : goto yyexhaustedlab;
1782 0 : yystacksize *= 2;
1783 0 : if (YYMAXDEPTH < yystacksize)
1784 0 : yystacksize = YYMAXDEPTH;
1785 :
1786 : {
1787 0 : yytype_int16 *yyss1 = yyss;
1788 0 : union yyalloc *yyptr =
1789 0 : (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1790 0 : if (! yyptr)
1791 0 : goto yyexhaustedlab;
1792 0 : YYSTACK_RELOCATE (yyss_alloc, yyss);
1793 0 : YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1794 : # undef YYSTACK_RELOCATE
1795 0 : if (yyss1 != yyssa)
1796 0 : YYSTACK_FREE (yyss1);
1797 : }
1798 : # endif
1799 : #endif /* no yyoverflow */
1800 :
1801 0 : yyssp = yyss + yysize - 1;
1802 0 : yyvsp = yyvs + yysize - 1;
1803 :
1804 : YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1805 0 : (unsigned long int) yystacksize));
1806 :
1807 0 : if (yyss + yystacksize - 1 <= yyssp)
1808 0 : YYABORT;
1809 : }
1810 :
1811 7894358173 : YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1812 :
1813 7894358173 : if (yystate == YYFINAL)
1814 0 : YYACCEPT;
1815 :
1816 7894358173 : goto yybackup;
1817 :
1818 : /*-----------.
1819 : | yybackup. |
1820 : `-----------*/
1821 7894358173 : yybackup:
1822 :
1823 : /* Do appropriate processing given the current state. Read a
1824 : lookahead token if we need one and don't already have one. */
1825 :
1826 : /* First try to decide what to do without reference to lookahead token. */
1827 7894358173 : yyn = yypact[yystate];
1828 7894358173 : if (yypact_value_is_default (yyn))
1829 : goto yydefault;
1830 :
1831 : /* Not known => get a lookahead token if don't already have one. */
1832 :
1833 : /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1834 3683915669 : if (yychar == YYEMPTY)
1835 : {
1836 2261648820 : YYDPRINTF ((stderr, "Reading a token: "));
1837 2261648820 : yychar = yylex ();
1838 : }
1839 :
1840 3683915463 : if (yychar <= YYEOF)
1841 : {
1842 615771 : yychar = yytoken = YYEOF;
1843 615771 : YYDPRINTF ((stderr, "Now at end of input.\n"));
1844 : }
1845 : else
1846 : {
1847 3683299692 : yytoken = YYTRANSLATE (yychar);
1848 3683915463 : YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1849 : }
1850 :
1851 : /* If the proper action on seeing token YYTOKEN is to reduce or to
1852 : detect an error, take that action. */
1853 3683915463 : yyn += yytoken;
1854 3683915463 : if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1855 : goto yydefault;
1856 2259606598 : yyn = yytable[yyn];
1857 2259606598 : if (yyn <= 0)
1858 : {
1859 : if (yytable_value_is_error (yyn))
1860 : goto yyerrlab;
1861 : yyn = -yyn;
1862 : goto yyreduce;
1863 : }
1864 :
1865 : /* Count tokens shifted since error; after three, turn off error
1866 : status. */
1867 2259606598 : if (yyerrstatus)
1868 1914028 : yyerrstatus--;
1869 :
1870 : /* Shift the lookahead token. */
1871 2259606598 : YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1872 :
1873 : /* Discard the shifted token. */
1874 2259606598 : yychar = YYEMPTY;
1875 :
1876 2259606598 : yystate = yyn;
1877 : YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1878 2259606598 : *++yyvsp = yylval;
1879 : YY_IGNORE_MAYBE_UNINITIALIZED_END
1880 :
1881 2259606598 : goto yynewstate;
1882 :
1883 :
1884 : /*-----------------------------------------------------------.
1885 : | yydefault -- do the default action for the current state. |
1886 : `-----------------------------------------------------------*/
1887 5634751369 : yydefault:
1888 5634751369 : yyn = yydefact[yystate];
1889 5634751369 : if (yyn == 0)
1890 4146129 : goto yyerrlab;
1891 : goto yyreduce;
1892 :
1893 :
1894 : /*-----------------------------.
1895 : | yyreduce -- Do a reduction. |
1896 : `-----------------------------*/
1897 5630605240 : yyreduce:
1898 : /* yyn is the number of a rule to reduce with. */
1899 5630605240 : yylen = yyr2[yyn];
1900 :
1901 : /* If YYLEN is nonzero, implement the default value of the action:
1902 : '$$ = $1'.
1903 :
1904 : Otherwise, the following line sets YYVAL to garbage.
1905 : This behavior is undocumented and Bison
1906 : users should not rely upon it. Assigning to YYVAL
1907 : unconditionally makes the parser a bit smaller, and it avoids a
1908 : GCC warning that YYVAL may be used uninitialized. */
1909 5630605240 : yyval = yyvsp[1-yylen];
1910 :
1911 :
1912 5630605240 : YY_REDUCE_PRINT (yyn);
1913 5630605240 : switch (yyn)
1914 : {
1915 89378664 : case 2:
1916 : #line 389 "../parse.y" /* yacc.c:1648 */
1917 : {
1918 : /* Case of regular command. Discard the error
1919 : safety net,and return the command just parsed. */
1920 : global_command = (yyvsp[-1].command);
1921 : eof_encountered = 0;
1922 : /* discard_parser_constructs (0); */
1923 : if (parser_state & PST_CMDSUBST)
1924 : parser_state |= PST_EOFTOKEN;
1925 : YYACCEPT;
1926 : }
1927 : #line 1928 "y.tab.c" /* yacc.c:1648 */
1928 202028703 : break;
1929 :
1930 202028703 : case 3:
1931 : #line 400 "../parse.y" /* yacc.c:1648 */
1932 : {
1933 : /* Case of regular command, but not a very
1934 : interesting one. Return a NULL command. */
1935 : global_command = (COMMAND *)NULL;
1936 : if (parser_state & PST_CMDSUBST)
1937 : parser_state |= PST_EOFTOKEN;
1938 : YYACCEPT;
1939 : }
1940 : #line 1941 "y.tab.c" /* yacc.c:1648 */
1941 1914028 : break;
1942 :
1943 1914028 : case 4:
1944 : #line 409 "../parse.y" /* yacc.c:1648 */
1945 : {
1946 : /* Error during parsing. Return NULL command. */
1947 : global_command = (COMMAND *)NULL;
1948 : eof_encountered = 0;
1949 : /* discard_parser_constructs (1); */
1950 : if (interactive && parse_and_execute_level == 0)
1951 : {
1952 : YYACCEPT;
1953 : }
1954 : else
1955 : {
1956 : YYABORT;
1957 : }
1958 : }
1959 : #line 1960 "y.tab.c" /* yacc.c:1648 */
1960 110845 : break;
1961 :
1962 110845 : case 5:
1963 : #line 424 "../parse.y" /* yacc.c:1648 */
1964 : {
1965 : /* Case of EOF seen by itself. Do ignoreeof or
1966 : not. */
1967 : global_command = (COMMAND *)NULL;
1968 : handle_eof_input_unit ();
1969 : YYACCEPT;
1970 : }
1971 : #line 1972 "y.tab.c" /* yacc.c:1648 */
1972 9542969 : break;
1973 :
1974 9542969 : case 6:
1975 : #line 434 "../parse.y" /* yacc.c:1648 */
1976 : { (yyval.word_list) = make_word_list ((yyvsp[0].word), (WORD_LIST *)NULL); }
1977 : #line 1978 "y.tab.c" /* yacc.c:1648 */
1978 9542969 : break;
1979 :
1980 0 : case 7:
1981 : #line 436 "../parse.y" /* yacc.c:1648 */
1982 : { (yyval.word_list) = make_word_list ((yyvsp[0].word), (yyvsp[-1].word_list)); }
1983 : #line 1984 "y.tab.c" /* yacc.c:1648 */
1984 0 : break;
1985 :
1986 6011052 : case 8:
1987 : #line 440 "../parse.y" /* yacc.c:1648 */
1988 : {
1989 : source.dest = 1;
1990 : redir.filename = (yyvsp[0].word);
1991 : (yyval.redirect) = make_redirection (source, r_output_direction, redir, 0);
1992 : }
1993 : #line 1994 "y.tab.c" /* yacc.c:1648 */
1994 6011052 : break;
1995 :
1996 3786649 : case 9:
1997 : #line 446 "../parse.y" /* yacc.c:1648 */
1998 : {
1999 : source.dest = 0;
2000 : redir.filename = (yyvsp[0].word);
2001 : (yyval.redirect) = make_redirection (source, r_input_direction, redir, 0);
2002 : }
2003 : #line 2004 "y.tab.c" /* yacc.c:1648 */
2004 3786649 : break;
2005 :
2006 1635249 : case 10:
2007 : #line 452 "../parse.y" /* yacc.c:1648 */
2008 : {
2009 : source.dest = (yyvsp[-2].number);
2010 : redir.filename = (yyvsp[0].word);
2011 : (yyval.redirect) = make_redirection (source, r_output_direction, redir, 0);
2012 : }
2013 : #line 2014 "y.tab.c" /* yacc.c:1648 */
2014 1635249 : break;
2015 :
2016 61 : case 11:
2017 : #line 458 "../parse.y" /* yacc.c:1648 */
2018 : {
2019 : source.dest = (yyvsp[-2].number);
2020 : redir.filename = (yyvsp[0].word);
2021 : (yyval.redirect) = make_redirection (source, r_input_direction, redir, 0);
2022 : }
2023 : #line 2024 "y.tab.c" /* yacc.c:1648 */
2024 61 : break;
2025 :
2026 0 : case 12:
2027 : #line 464 "../parse.y" /* yacc.c:1648 */
2028 : {
2029 : source.filename = (yyvsp[-2].word);
2030 : redir.filename = (yyvsp[0].word);
2031 : (yyval.redirect) = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN);
2032 : }
2033 : #line 2034 "y.tab.c" /* yacc.c:1648 */
2034 0 : break;
2035 :
2036 0 : case 13:
2037 : #line 470 "../parse.y" /* yacc.c:1648 */
2038 : {
2039 : source.filename = (yyvsp[-2].word);
2040 : redir.filename = (yyvsp[0].word);
2041 : (yyval.redirect) = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN);
2042 : }
2043 : #line 2044 "y.tab.c" /* yacc.c:1648 */
2044 0 : break;
2045 :
2046 3500837 : case 14:
2047 : #line 476 "../parse.y" /* yacc.c:1648 */
2048 : {
2049 : source.dest = 1;
2050 : redir.filename = (yyvsp[0].word);
2051 : (yyval.redirect) = make_redirection (source, r_appending_to, redir, 0);
2052 : }
2053 : #line 2054 "y.tab.c" /* yacc.c:1648 */
2054 3500837 : break;
2055 :
2056 19 : case 15:
2057 : #line 482 "../parse.y" /* yacc.c:1648 */
2058 : {
2059 : source.dest = (yyvsp[-2].number);
2060 : redir.filename = (yyvsp[0].word);
2061 : (yyval.redirect) = make_redirection (source, r_appending_to, redir, 0);
2062 : }
2063 : #line 2064 "y.tab.c" /* yacc.c:1648 */
2064 19 : break;
2065 :
2066 0 : case 16:
2067 : #line 488 "../parse.y" /* yacc.c:1648 */
2068 : {
2069 : source.filename = (yyvsp[-2].word);
2070 : redir.filename = (yyvsp[0].word);
2071 : (yyval.redirect) = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN);
2072 : }
2073 : #line 2074 "y.tab.c" /* yacc.c:1648 */
2074 0 : break;
2075 :
2076 80 : case 17:
2077 : #line 494 "../parse.y" /* yacc.c:1648 */
2078 : {
2079 : source.dest = 1;
2080 : redir.filename = (yyvsp[0].word);
2081 : (yyval.redirect) = make_redirection (source, r_output_force, redir, 0);
2082 : }
2083 : #line 2084 "y.tab.c" /* yacc.c:1648 */
2084 80 : break;
2085 :
2086 0 : case 18:
2087 : #line 500 "../parse.y" /* yacc.c:1648 */
2088 : {
2089 : source.dest = (yyvsp[-2].number);
2090 : redir.filename = (yyvsp[0].word);
2091 : (yyval.redirect) = make_redirection (source, r_output_force, redir, 0);
2092 : }
2093 : #line 2094 "y.tab.c" /* yacc.c:1648 */
2094 0 : break;
2095 :
2096 0 : case 19:
2097 : #line 506 "../parse.y" /* yacc.c:1648 */
2098 : {
2099 : source.filename = (yyvsp[-2].word);
2100 : redir.filename = (yyvsp[0].word);
2101 : (yyval.redirect) = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN);
2102 : }
2103 : #line 2104 "y.tab.c" /* yacc.c:1648 */
2104 0 : break;
2105 :
2106 103 : case 20:
2107 : #line 512 "../parse.y" /* yacc.c:1648 */
2108 : {
2109 : source.dest = 0;
2110 : redir.filename = (yyvsp[0].word);
2111 : (yyval.redirect) = make_redirection (source, r_input_output, redir, 0);
2112 : }
2113 : #line 2114 "y.tab.c" /* yacc.c:1648 */
2114 103 : break;
2115 :
2116 0 : case 21:
2117 : #line 518 "../parse.y" /* yacc.c:1648 */
2118 : {
2119 : source.dest = (yyvsp[-2].number);
2120 : redir.filename = (yyvsp[0].word);
2121 : (yyval.redirect) = make_redirection (source, r_input_output, redir, 0);
2122 : }
2123 : #line 2124 "y.tab.c" /* yacc.c:1648 */
2124 0 : break;
2125 :
2126 0 : case 22:
2127 : #line 524 "../parse.y" /* yacc.c:1648 */
2128 : {
2129 : source.filename = (yyvsp[-2].word);
2130 : redir.filename = (yyvsp[0].word);
2131 : (yyval.redirect) = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN);
2132 : }
2133 : #line 2134 "y.tab.c" /* yacc.c:1648 */
2134 0 : break;
2135 :
2136 285 : case 23:
2137 : #line 530 "../parse.y" /* yacc.c:1648 */
2138 : {
2139 : source.dest = 0;
2140 : redir.filename = (yyvsp[0].word);
2141 : (yyval.redirect) = make_redirection (source, r_reading_until, redir, 0);
2142 : push_heredoc ((yyval.redirect));
2143 : }
2144 : #line 2145 "y.tab.c" /* yacc.c:1648 */
2145 285 : break;
2146 :
2147 0 : case 24:
2148 : #line 537 "../parse.y" /* yacc.c:1648 */
2149 : {
2150 : source.dest = (yyvsp[-2].number);
2151 : redir.filename = (yyvsp[0].word);
2152 : (yyval.redirect) = make_redirection (source, r_reading_until, redir, 0);
2153 : push_heredoc ((yyval.redirect));
2154 : }
2155 : #line 2156 "y.tab.c" /* yacc.c:1648 */
2156 0 : break;
2157 :
2158 0 : case 25:
2159 : #line 544 "../parse.y" /* yacc.c:1648 */
2160 : {
2161 : source.filename = (yyvsp[-2].word);
2162 : redir.filename = (yyvsp[0].word);
2163 : (yyval.redirect) = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN);
2164 : push_heredoc ((yyval.redirect));
2165 : }
2166 : #line 2167 "y.tab.c" /* yacc.c:1648 */
2167 0 : break;
2168 :
2169 0 : case 26:
2170 : #line 551 "../parse.y" /* yacc.c:1648 */
2171 : {
2172 : source.dest = 0;
2173 : redir.filename = (yyvsp[0].word);
2174 : (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, 0);
2175 : push_heredoc ((yyval.redirect));
2176 : }
2177 : #line 2178 "y.tab.c" /* yacc.c:1648 */
2178 0 : break;
2179 :
2180 0 : case 27:
2181 : #line 558 "../parse.y" /* yacc.c:1648 */
2182 : {
2183 : source.dest = (yyvsp[-2].number);
2184 : redir.filename = (yyvsp[0].word);
2185 : (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, 0);
2186 : push_heredoc ((yyval.redirect));
2187 : }
2188 : #line 2189 "y.tab.c" /* yacc.c:1648 */
2189 0 : break;
2190 :
2191 0 : case 28:
2192 : #line 565 "../parse.y" /* yacc.c:1648 */
2193 : {
2194 : source.filename = (yyvsp[-2].word);
2195 : redir.filename = (yyvsp[0].word);
2196 : (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN);
2197 : push_heredoc ((yyval.redirect));
2198 : }
2199 : #line 2200 "y.tab.c" /* yacc.c:1648 */
2200 0 : break;
2201 :
2202 69 : case 29:
2203 : #line 572 "../parse.y" /* yacc.c:1648 */
2204 : {
2205 : source.dest = 0;
2206 : redir.filename = (yyvsp[0].word);
2207 : (yyval.redirect) = make_redirection (source, r_reading_string, redir, 0);
2208 : }
2209 : #line 2210 "y.tab.c" /* yacc.c:1648 */
2210 69 : break;
2211 :
2212 9 : case 30:
2213 : #line 578 "../parse.y" /* yacc.c:1648 */
2214 : {
2215 : source.dest = (yyvsp[-2].number);
2216 : redir.filename = (yyvsp[0].word);
2217 : (yyval.redirect) = make_redirection (source, r_reading_string, redir, 0);
2218 : }
2219 : #line 2220 "y.tab.c" /* yacc.c:1648 */
2220 9 : break;
2221 :
2222 0 : case 31:
2223 : #line 584 "../parse.y" /* yacc.c:1648 */
2224 : {
2225 : source.filename = (yyvsp[-2].word);
2226 : redir.filename = (yyvsp[0].word);
2227 : (yyval.redirect) = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN);
2228 : }
2229 : #line 2230 "y.tab.c" /* yacc.c:1648 */
2230 0 : break;
2231 :
2232 0 : case 32:
2233 : #line 590 "../parse.y" /* yacc.c:1648 */
2234 : {
2235 : source.dest = 0;
2236 : redir.dest = (yyvsp[0].number);
2237 : (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, 0);
2238 : }
2239 : #line 2240 "y.tab.c" /* yacc.c:1648 */
2240 0 : break;
2241 :
2242 9 : case 33:
2243 : #line 596 "../parse.y" /* yacc.c:1648 */
2244 : {
2245 : source.dest = (yyvsp[-2].number);
2246 : redir.dest = (yyvsp[0].number);
2247 : (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, 0);
2248 : }
2249 : #line 2250 "y.tab.c" /* yacc.c:1648 */
2250 9 : break;
2251 :
2252 0 : case 34:
2253 : #line 602 "../parse.y" /* yacc.c:1648 */
2254 : {
2255 : source.filename = (yyvsp[-2].word);
2256 : redir.dest = (yyvsp[0].number);
2257 : (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN);
2258 : }
2259 : #line 2260 "y.tab.c" /* yacc.c:1648 */
2260 0 : break;
2261 :
2262 4963 : case 35:
2263 : #line 608 "../parse.y" /* yacc.c:1648 */
2264 : {
2265 : source.dest = 1;
2266 : redir.dest = (yyvsp[0].number);
2267 : (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, 0);
2268 : }
2269 : #line 2270 "y.tab.c" /* yacc.c:1648 */
2270 4963 : break;
2271 :
2272 1853325 : case 36:
2273 : #line 614 "../parse.y" /* yacc.c:1648 */
2274 : {
2275 : source.dest = (yyvsp[-2].number);
2276 : redir.dest = (yyvsp[0].number);
2277 : (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, 0);
2278 : }
2279 : #line 2280 "y.tab.c" /* yacc.c:1648 */
2280 1853325 : break;
2281 :
2282 0 : case 37:
2283 : #line 620 "../parse.y" /* yacc.c:1648 */
2284 : {
2285 : source.filename = (yyvsp[-2].word);
2286 : redir.dest = (yyvsp[0].number);
2287 : (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN);
2288 : }
2289 : #line 2290 "y.tab.c" /* yacc.c:1648 */
2290 0 : break;
2291 :
2292 51 : case 38:
2293 : #line 626 "../parse.y" /* yacc.c:1648 */
2294 : {
2295 : source.dest = 0;
2296 : redir.filename = (yyvsp[0].word);
2297 : (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, 0);
2298 : }
2299 : #line 2300 "y.tab.c" /* yacc.c:1648 */
2300 51 : break;
2301 :
2302 0 : case 39:
2303 : #line 632 "../parse.y" /* yacc.c:1648 */
2304 : {
2305 : source.dest = (yyvsp[-2].number);
2306 : redir.filename = (yyvsp[0].word);
2307 : (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, 0);
2308 : }
2309 : #line 2310 "y.tab.c" /* yacc.c:1648 */
2310 0 : break;
2311 :
2312 0 : case 40:
2313 : #line 638 "../parse.y" /* yacc.c:1648 */
2314 : {
2315 : source.filename = (yyvsp[-2].word);
2316 : redir.filename = (yyvsp[0].word);
2317 : (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN);
2318 : }
2319 : #line 2320 "y.tab.c" /* yacc.c:1648 */
2320 0 : break;
2321 :
2322 68 : case 41:
2323 : #line 644 "../parse.y" /* yacc.c:1648 */
2324 : {
2325 : source.dest = 1;
2326 : redir.filename = (yyvsp[0].word);
2327 : (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, 0);
2328 : }
2329 : #line 2330 "y.tab.c" /* yacc.c:1648 */
2330 68 : break;
2331 :
2332 5289 : case 42:
2333 : #line 650 "../parse.y" /* yacc.c:1648 */
2334 : {
2335 : source.dest = (yyvsp[-2].number);
2336 : redir.filename = (yyvsp[0].word);
2337 : (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, 0);
2338 : }
2339 : #line 2340 "y.tab.c" /* yacc.c:1648 */
2340 5289 : break;
2341 :
2342 0 : case 43:
2343 : #line 656 "../parse.y" /* yacc.c:1648 */
2344 : {
2345 : source.filename = (yyvsp[-2].word);
2346 : redir.filename = (yyvsp[0].word);
2347 : (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN);
2348 : }
2349 : #line 2350 "y.tab.c" /* yacc.c:1648 */
2350 0 : break;
2351 :
2352 0 : case 44:
2353 : #line 662 "../parse.y" /* yacc.c:1648 */
2354 : {
2355 : source.dest = 1;
2356 : redir.dest = 0;
2357 : (yyval.redirect) = make_redirection (source, r_close_this, redir, 0);
2358 : }
2359 : #line 2360 "y.tab.c" /* yacc.c:1648 */
2360 0 : break;
2361 :
2362 10 : case 45:
2363 : #line 668 "../parse.y" /* yacc.c:1648 */
2364 : {
2365 : source.dest = (yyvsp[-2].number);
2366 : redir.dest = 0;
2367 : (yyval.redirect) = make_redirection (source, r_close_this, redir, 0);
2368 : }
2369 : #line 2370 "y.tab.c" /* yacc.c:1648 */
2370 10 : break;
2371 :
2372 0 : case 46:
2373 : #line 674 "../parse.y" /* yacc.c:1648 */
2374 : {
2375 : source.filename = (yyvsp[-2].word);
2376 : redir.dest = 0;
2377 : (yyval.redirect) = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
2378 : }
2379 : #line 2380 "y.tab.c" /* yacc.c:1648 */
2380 0 : break;
2381 :
2382 0 : case 47:
2383 : #line 680 "../parse.y" /* yacc.c:1648 */
2384 : {
2385 : source.dest = 0;
2386 : redir.dest = 0;
2387 : (yyval.redirect) = make_redirection (source, r_close_this, redir, 0);
2388 : }
2389 : #line 2390 "y.tab.c" /* yacc.c:1648 */
2390 0 : break;
2391 :
2392 0 : case 48:
2393 : #line 686 "../parse.y" /* yacc.c:1648 */
2394 : {
2395 : source.dest = (yyvsp[-2].number);
2396 : redir.dest = 0;
2397 : (yyval.redirect) = make_redirection (source, r_close_this, redir, 0);
2398 : }
2399 : #line 2400 "y.tab.c" /* yacc.c:1648 */
2400 0 : break;
2401 :
2402 0 : case 49:
2403 : #line 692 "../parse.y" /* yacc.c:1648 */
2404 : {
2405 : source.filename = (yyvsp[-2].word);
2406 : redir.dest = 0;
2407 : (yyval.redirect) = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
2408 : }
2409 : #line 2410 "y.tab.c" /* yacc.c:1648 */
2410 0 : break;
2411 :
2412 50 : case 50:
2413 : #line 698 "../parse.y" /* yacc.c:1648 */
2414 : {
2415 : source.dest = 1;
2416 : redir.filename = (yyvsp[0].word);
2417 : (yyval.redirect) = make_redirection (source, r_err_and_out, redir, 0);
2418 : }
2419 : #line 2420 "y.tab.c" /* yacc.c:1648 */
2420 50 : break;
2421 :
2422 12 : case 51:
2423 : #line 704 "../parse.y" /* yacc.c:1648 */
2424 : {
2425 : source.dest = 1;
2426 : redir.filename = (yyvsp[0].word);
2427 : (yyval.redirect) = make_redirection (source, r_append_err_and_out, redir, 0);
2428 : }
2429 : #line 2430 "y.tab.c" /* yacc.c:1648 */
2430 12 : break;
2431 :
2432 642615775 : case 52:
2433 : #line 712 "../parse.y" /* yacc.c:1648 */
2434 : { (yyval.element).word = (yyvsp[0].word); (yyval.element).redirect = 0; }
2435 : #line 2436 "y.tab.c" /* yacc.c:1648 */
2436 642615775 : break;
2437 :
2438 56720875 : case 53:
2439 : #line 714 "../parse.y" /* yacc.c:1648 */
2440 : { (yyval.element).word = (yyvsp[0].word); (yyval.element).redirect = 0; }
2441 : #line 2442 "y.tab.c" /* yacc.c:1648 */
2442 56720875 : break;
2443 :
2444 16798181 : case 54:
2445 : #line 716 "../parse.y" /* yacc.c:1648 */
2446 : { (yyval.element).redirect = (yyvsp[0].redirect); (yyval.element).word = 0; }
2447 : #line 2448 "y.tab.c" /* yacc.c:1648 */
2448 16798181 : break;
2449 :
2450 9 : case 55:
2451 : #line 720 "../parse.y" /* yacc.c:1648 */
2452 : {
2453 : (yyval.redirect) = (yyvsp[0].redirect);
2454 : }
2455 : #line 2456 "y.tab.c" /* yacc.c:1648 */
2456 9 : break;
2457 :
2458 0 : case 56:
2459 : #line 724 "../parse.y" /* yacc.c:1648 */
2460 : {
2461 : register REDIRECT *t;
2462 :
2463 : for (t = (yyvsp[-1].redirect); t->next; t = t->next)
2464 : ;
2465 : t->next = (yyvsp[0].redirect);
2466 : (yyval.redirect) = (yyvsp[-1].redirect);
2467 : }
2468 : #line 2469 "y.tab.c" /* yacc.c:1648 */
2469 0 : break;
2470 :
2471 281725662 : case 57:
2472 : #line 735 "../parse.y" /* yacc.c:1648 */
2473 : { (yyval.command) = make_simple_command ((yyvsp[0].element), (COMMAND *)NULL); }
2474 : #line 2475 "y.tab.c" /* yacc.c:1648 */
2475 281725662 : break;
2476 :
2477 434409169 : case 58:
2478 : #line 737 "../parse.y" /* yacc.c:1648 */
2479 : { (yyval.command) = make_simple_command ((yyvsp[0].element), (yyvsp[-1].command)); }
2480 : #line 2481 "y.tab.c" /* yacc.c:1648 */
2481 434409169 : break;
2482 :
2483 281713534 : case 59:
2484 : #line 741 "../parse.y" /* yacc.c:1648 */
2485 : { (yyval.command) = clean_simple_command ((yyvsp[0].command)); }
2486 : #line 2487 "y.tab.c" /* yacc.c:1648 */
2487 281713534 : break;
2488 :
2489 95088693 : case 60:
2490 : #line 743 "../parse.y" /* yacc.c:1648 */
2491 : { (yyval.command) = (yyvsp[0].command); }
2492 : #line 2493 "y.tab.c" /* yacc.c:1648 */
2493 95088693 : break;
2494 :
2495 9 : case 61:
2496 : #line 745 "../parse.y" /* yacc.c:1648 */
2497 : {
2498 : COMMAND *tc;
2499 :
2500 : tc = (yyvsp[-1].command);
2501 : if (tc->redirects)
2502 : {
2503 : register REDIRECT *t;
2504 : for (t = tc->redirects; t->next; t = t->next)
2505 : ;
2506 : t->next = (yyvsp[0].redirect);
2507 : }
2508 : else
2509 : tc->redirects = (yyvsp[0].redirect);
2510 : (yyval.command) = (yyvsp[-1].command);
2511 : }
2512 : #line 2513 "y.tab.c" /* yacc.c:1648 */
2513 9 : break;
2514 :
2515 18763987 : case 62:
2516 : #line 761 "../parse.y" /* yacc.c:1648 */
2517 : { (yyval.command) = (yyvsp[0].command); }
2518 : #line 2519 "y.tab.c" /* yacc.c:1648 */
2519 18763987 : break;
2520 :
2521 0 : case 63:
2522 : #line 763 "../parse.y" /* yacc.c:1648 */
2523 : { (yyval.command) = (yyvsp[0].command); }
2524 : #line 2525 "y.tab.c" /* yacc.c:1648 */
2525 0 : break;
2526 :
2527 9542969 : case 64:
2528 : #line 767 "../parse.y" /* yacc.c:1648 */
2529 : { (yyval.command) = (yyvsp[0].command); }
2530 : #line 2531 "y.tab.c" /* yacc.c:1648 */
2531 9542969 : break;
2532 :
2533 15245007 : case 65:
2534 : #line 769 "../parse.y" /* yacc.c:1648 */
2535 : { (yyval.command) = (yyvsp[0].command); }
2536 : #line 2537 "y.tab.c" /* yacc.c:1648 */
2537 15245007 : break;
2538 :
2539 1837422 : case 66:
2540 : #line 771 "../parse.y" /* yacc.c:1648 */
2541 : { (yyval.command) = make_while_command ((yyvsp[-3].command), (yyvsp[-1].command)); }
2542 : #line 2543 "y.tab.c" /* yacc.c:1648 */
2543 1837422 : break;
2544 :
2545 0 : case 67:
2546 : #line 773 "../parse.y" /* yacc.c:1648 */
2547 : { (yyval.command) = make_until_command ((yyvsp[-3].command), (yyvsp[-1].command)); }
2548 : #line 2549 "y.tab.c" /* yacc.c:1648 */
2549 0 : break;
2550 :
2551 0 : case 68:
2552 : #line 775 "../parse.y" /* yacc.c:1648 */
2553 : { (yyval.command) = (yyvsp[0].command); }
2554 : #line 2555 "y.tab.c" /* yacc.c:1648 */
2555 0 : break;
2556 :
2557 68460861 : case 69:
2558 : #line 777 "../parse.y" /* yacc.c:1648 */
2559 : { (yyval.command) = (yyvsp[0].command); }
2560 : #line 2561 "y.tab.c" /* yacc.c:1648 */
2561 68460861 : break;
2562 :
2563 213 : case 70:
2564 : #line 779 "../parse.y" /* yacc.c:1648 */
2565 : { (yyval.command) = (yyvsp[0].command); }
2566 : #line 2567 "y.tab.c" /* yacc.c:1648 */
2567 213 : break;
2568 :
2569 18766217 : case 71:
2570 : #line 781 "../parse.y" /* yacc.c:1648 */
2571 : { (yyval.command) = (yyvsp[0].command); }
2572 : #line 2573 "y.tab.c" /* yacc.c:1648 */
2573 18766217 : break;
2574 :
2575 0 : case 72:
2576 : #line 783 "../parse.y" /* yacc.c:1648 */
2577 : { (yyval.command) = (yyvsp[0].command); }
2578 : #line 2579 "y.tab.c" /* yacc.c:1648 */
2579 0 : break;
2580 :
2581 0 : case 73:
2582 : #line 785 "../parse.y" /* yacc.c:1648 */
2583 : { (yyval.command) = (yyvsp[0].command); }
2584 : #line 2585 "y.tab.c" /* yacc.c:1648 */
2585 0 : break;
2586 :
2587 0 : case 74:
2588 : #line 787 "../parse.y" /* yacc.c:1648 */
2589 : { (yyval.command) = (yyvsp[0].command); }
2590 : #line 2591 "y.tab.c" /* yacc.c:1648 */
2591 0 : break;
2592 :
2593 0 : case 75:
2594 : #line 791 "../parse.y" /* yacc.c:1648 */
2595 : {
2596 : (yyval.command) = make_for_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2597 : if (word_top > 0) word_top--;
2598 : }
2599 : #line 2600 "y.tab.c" /* yacc.c:1648 */
2600 : break;
2601 :
2602 0 : case 76:
2603 : #line 796 "../parse.y" /* yacc.c:1648 */
2604 : {
2605 : (yyval.command) = make_for_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2606 : if (word_top > 0) word_top--;
2607 : }
2608 : #line 2609 "y.tab.c" /* yacc.c:1648 */
2609 : break;
2610 :
2611 0 : case 77:
2612 : #line 801 "../parse.y" /* yacc.c:1648 */
2613 : {
2614 : (yyval.command) = make_for_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2615 : if (word_top > 0) word_top--;
2616 : }
2617 : #line 2618 "y.tab.c" /* yacc.c:1648 */
2618 : break;
2619 :
2620 0 : case 78:
2621 : #line 806 "../parse.y" /* yacc.c:1648 */
2622 : {
2623 : (yyval.command) = make_for_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2624 : if (word_top > 0) word_top--;
2625 : }
2626 : #line 2627 "y.tab.c" /* yacc.c:1648 */
2627 : break;
2628 :
2629 9542969 : case 79:
2630 : #line 811 "../parse.y" /* yacc.c:1648 */
2631 : {
2632 : (yyval.command) = make_for_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]);
2633 : if (word_top > 0) word_top--;
2634 : }
2635 : #line 2636 "y.tab.c" /* yacc.c:1648 */
2636 : break;
2637 :
2638 0 : case 80:
2639 : #line 816 "../parse.y" /* yacc.c:1648 */
2640 : {
2641 : (yyval.command) = make_for_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]);
2642 : if (word_top > 0) word_top--;
2643 : }
2644 : #line 2645 "y.tab.c" /* yacc.c:1648 */
2645 : break;
2646 :
2647 0 : case 81:
2648 : #line 821 "../parse.y" /* yacc.c:1648 */
2649 : {
2650 : (yyval.command) = make_for_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]);
2651 : if (word_top > 0) word_top--;
2652 : }
2653 : #line 2654 "y.tab.c" /* yacc.c:1648 */
2654 : break;
2655 :
2656 0 : case 82:
2657 : #line 826 "../parse.y" /* yacc.c:1648 */
2658 : {
2659 : (yyval.command) = make_for_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]);
2660 : if (word_top > 0) word_top--;
2661 : }
2662 : #line 2663 "y.tab.c" /* yacc.c:1648 */
2663 : break;
2664 :
2665 0 : case 83:
2666 : #line 833 "../parse.y" /* yacc.c:1648 */
2667 : {
2668 : (yyval.command) = make_arith_for_command ((yyvsp[-5].word_list), (yyvsp[-1].command), arith_for_lineno);
2669 : if (word_top > 0) word_top--;
2670 : }
2671 : #line 2672 "y.tab.c" /* yacc.c:1648 */
2672 : break;
2673 :
2674 0 : case 84:
2675 : #line 838 "../parse.y" /* yacc.c:1648 */
2676 : {
2677 : (yyval.command) = make_arith_for_command ((yyvsp[-5].word_list), (yyvsp[-1].command), arith_for_lineno);
2678 : if (word_top > 0) word_top--;
2679 : }
2680 : #line 2681 "y.tab.c" /* yacc.c:1648 */
2681 : break;
2682 :
2683 0 : case 85:
2684 : #line 843 "../parse.y" /* yacc.c:1648 */
2685 : {
2686 : (yyval.command) = make_arith_for_command ((yyvsp[-3].word_list), (yyvsp[-1].command), arith_for_lineno);
2687 : if (word_top > 0) word_top--;
2688 : }
2689 : #line 2690 "y.tab.c" /* yacc.c:1648 */
2690 : break;
2691 :
2692 0 : case 86:
2693 : #line 848 "../parse.y" /* yacc.c:1648 */
2694 : {
2695 : (yyval.command) = make_arith_for_command ((yyvsp[-3].word_list), (yyvsp[-1].command), arith_for_lineno);
2696 : if (word_top > 0) word_top--;
2697 : }
2698 : #line 2699 "y.tab.c" /* yacc.c:1648 */
2699 : break;
2700 :
2701 0 : case 87:
2702 : #line 855 "../parse.y" /* yacc.c:1648 */
2703 : {
2704 : (yyval.command) = make_select_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2705 : if (word_top > 0) word_top--;
2706 : }
2707 : #line 2708 "y.tab.c" /* yacc.c:1648 */
2708 : break;
2709 :
2710 0 : case 88:
2711 : #line 860 "../parse.y" /* yacc.c:1648 */
2712 : {
2713 : (yyval.command) = make_select_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2714 : if (word_top > 0) word_top--;
2715 : }
2716 : #line 2717 "y.tab.c" /* yacc.c:1648 */
2717 : break;
2718 :
2719 0 : case 89:
2720 : #line 865 "../parse.y" /* yacc.c:1648 */
2721 : {
2722 : (yyval.command) = make_select_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2723 : if (word_top > 0) word_top--;
2724 : }
2725 : #line 2726 "y.tab.c" /* yacc.c:1648 */
2726 : break;
2727 :
2728 0 : case 90:
2729 : #line 870 "../parse.y" /* yacc.c:1648 */
2730 : {
2731 : (yyval.command) = make_select_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]);
2732 : if (word_top > 0) word_top--;
2733 : }
2734 : #line 2735 "y.tab.c" /* yacc.c:1648 */
2735 : break;
2736 :
2737 0 : case 91:
2738 : #line 875 "../parse.y" /* yacc.c:1648 */
2739 : {
2740 : (yyval.command) = make_select_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]);
2741 : if (word_top > 0) word_top--;
2742 : }
2743 : #line 2744 "y.tab.c" /* yacc.c:1648 */
2744 : break;
2745 :
2746 0 : case 92:
2747 : #line 880 "../parse.y" /* yacc.c:1648 */
2748 : {
2749 : (yyval.command) = make_select_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]);
2750 : if (word_top > 0) word_top--;
2751 : }
2752 : #line 2753 "y.tab.c" /* yacc.c:1648 */
2753 : break;
2754 :
2755 9 : case 93:
2756 : #line 887 "../parse.y" /* yacc.c:1648 */
2757 : {
2758 : (yyval.command) = make_case_command ((yyvsp[-4].word), (PATTERN_LIST *)NULL, word_lineno[word_top]);
2759 : if (word_top > 0) word_top--;
2760 : }
2761 : #line 2762 "y.tab.c" /* yacc.c:1648 */
2762 : break;
2763 :
2764 11494761 : case 94:
2765 : #line 892 "../parse.y" /* yacc.c:1648 */
2766 : {
2767 : (yyval.command) = make_case_command ((yyvsp[-5].word), (yyvsp[-2].pattern), word_lineno[word_top]);
2768 : if (word_top > 0) word_top--;
2769 : }
2770 : #line 2771 "y.tab.c" /* yacc.c:1648 */
2771 : break;
2772 :
2773 3750237 : case 95:
2774 : #line 897 "../parse.y" /* yacc.c:1648 */
2775 : {
2776 : (yyval.command) = make_case_command ((yyvsp[-4].word), (yyvsp[-1].pattern), word_lineno[word_top]);
2777 : if (word_top > 0) word_top--;
2778 : }
2779 : #line 2780 "y.tab.c" /* yacc.c:1648 */
2780 : break;
2781 :
2782 18763978 : case 96:
2783 : #line 904 "../parse.y" /* yacc.c:1648 */
2784 : { (yyval.command) = make_function_def ((yyvsp[-4].word), (yyvsp[0].command), function_dstart, function_bstart); }
2785 : #line 2786 "y.tab.c" /* yacc.c:1648 */
2786 18763978 : break;
2787 :
2788 0 : case 97:
2789 : #line 907 "../parse.y" /* yacc.c:1648 */
2790 : { (yyval.command) = make_function_def ((yyvsp[-4].word), (yyvsp[0].command), function_dstart, function_bstart); }
2791 : #line 2792 "y.tab.c" /* yacc.c:1648 */
2792 0 : break;
2793 :
2794 9 : case 98:
2795 : #line 910 "../parse.y" /* yacc.c:1648 */
2796 : { (yyval.command) = make_function_def ((yyvsp[-2].word), (yyvsp[0].command), function_dstart, function_bstart); }
2797 : #line 2798 "y.tab.c" /* yacc.c:1648 */
2798 9 : break;
2799 :
2800 18763987 : case 99:
2801 : #line 914 "../parse.y" /* yacc.c:1648 */
2802 : { (yyval.command) = (yyvsp[0].command); }
2803 : #line 2804 "y.tab.c" /* yacc.c:1648 */
2804 18763987 : break;
2805 :
2806 0 : case 100:
2807 : #line 916 "../parse.y" /* yacc.c:1648 */
2808 : {
2809 : COMMAND *tc;
2810 :
2811 : tc = (yyvsp[-1].command);
2812 : /* According to Posix.2 3.9.5, redirections
2813 : specified after the body of a function should
2814 : be attached to the function and performed when
2815 : the function is executed, not as part of the
2816 : function definition command. */
2817 : /* XXX - I don't think it matters, but we might
2818 : want to change this in the future to avoid
2819 : problems differentiating between a function
2820 : definition with a redirection and a function
2821 : definition containing a single command with a
2822 : redirection. The two are semantically equivalent,
2823 : though -- the only difference is in how the
2824 : command printing code displays the redirections. */
2825 : if (tc->redirects)
2826 : {
2827 : register REDIRECT *t;
2828 : for (t = tc->redirects; t->next; t = t->next)
2829 : ;
2830 : t->next = (yyvsp[0].redirect);
2831 : }
2832 : else
2833 : tc->redirects = (yyvsp[0].redirect);
2834 : (yyval.command) = (yyvsp[-1].command);
2835 : }
2836 : #line 2837 "y.tab.c" /* yacc.c:1648 */
2837 0 : break;
2838 :
2839 213 : case 101:
2840 : #line 947 "../parse.y" /* yacc.c:1648 */
2841 : {
2842 : (yyval.command) = make_subshell_command ((yyvsp[-1].command));
2843 : (yyval.command)->flags |= CMD_WANT_SUBSHELL;
2844 : }
2845 : #line 2846 "y.tab.c" /* yacc.c:1648 */
2846 213 : break;
2847 :
2848 0 : case 102:
2849 : #line 954 "../parse.y" /* yacc.c:1648 */
2850 : {
2851 : (yyval.command) = make_coproc_command ("COPROC", (yyvsp[0].command));
2852 : (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
2853 : }
2854 : #line 2855 "y.tab.c" /* yacc.c:1648 */
2855 0 : break;
2856 :
2857 0 : case 103:
2858 : #line 959 "../parse.y" /* yacc.c:1648 */
2859 : {
2860 : COMMAND *tc;
2861 :
2862 : tc = (yyvsp[-1].command);
2863 : if (tc->redirects)
2864 : {
2865 : register REDIRECT *t;
2866 : for (t = tc->redirects; t->next; t = t->next)
2867 : ;
2868 : t->next = (yyvsp[0].redirect);
2869 : }
2870 : else
2871 : tc->redirects = (yyvsp[0].redirect);
2872 : (yyval.command) = make_coproc_command ("COPROC", (yyvsp[-1].command));
2873 : (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
2874 : }
2875 : #line 2876 "y.tab.c" /* yacc.c:1648 */
2876 0 : break;
2877 :
2878 0 : case 104:
2879 : #line 976 "../parse.y" /* yacc.c:1648 */
2880 : {
2881 : (yyval.command) = make_coproc_command ((yyvsp[-1].word)->word, (yyvsp[0].command));
2882 : (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
2883 : }
2884 : #line 2885 "y.tab.c" /* yacc.c:1648 */
2885 0 : break;
2886 :
2887 0 : case 105:
2888 : #line 981 "../parse.y" /* yacc.c:1648 */
2889 : {
2890 : COMMAND *tc;
2891 :
2892 : tc = (yyvsp[-1].command);
2893 : if (tc->redirects)
2894 : {
2895 : register REDIRECT *t;
2896 : for (t = tc->redirects; t->next; t = t->next)
2897 : ;
2898 : t->next = (yyvsp[0].redirect);
2899 : }
2900 : else
2901 : tc->redirects = (yyvsp[0].redirect);
2902 : (yyval.command) = make_coproc_command ((yyvsp[-2].word)->word, (yyvsp[-1].command));
2903 : (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
2904 : }
2905 : #line 2906 "y.tab.c" /* yacc.c:1648 */
2906 0 : break;
2907 :
2908 0 : case 106:
2909 : #line 998 "../parse.y" /* yacc.c:1648 */
2910 : {
2911 : (yyval.command) = make_coproc_command ("COPROC", clean_simple_command ((yyvsp[0].command)));
2912 : (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
2913 : }
2914 : #line 2915 "y.tab.c" /* yacc.c:1648 */
2915 0 : break;
2916 :
2917 66804905 : case 107:
2918 : #line 1005 "../parse.y" /* yacc.c:1648 */
2919 : { (yyval.command) = make_if_command ((yyvsp[-3].command), (yyvsp[-1].command), (COMMAND *)NULL); }
2920 : #line 2921 "y.tab.c" /* yacc.c:1648 */
2921 66804905 : break;
2922 :
2923 1655956 : case 108:
2924 : #line 1007 "../parse.y" /* yacc.c:1648 */
2925 : { (yyval.command) = make_if_command ((yyvsp[-5].command), (yyvsp[-3].command), (yyvsp[-1].command)); }
2926 : #line 2927 "y.tab.c" /* yacc.c:1648 */
2927 1655956 : break;
2928 :
2929 0 : case 109:
2930 : #line 1009 "../parse.y" /* yacc.c:1648 */
2931 : { (yyval.command) = make_if_command ((yyvsp[-4].command), (yyvsp[-2].command), (yyvsp[-1].command)); }
2932 : #line 2933 "y.tab.c" /* yacc.c:1648 */
2933 0 : break;
2934 :
2935 18766217 : case 110:
2936 : #line 1014 "../parse.y" /* yacc.c:1648 */
2937 : { (yyval.command) = make_group_command ((yyvsp[-1].command)); }
2938 : #line 2939 "y.tab.c" /* yacc.c:1648 */
2939 18766217 : break;
2940 :
2941 0 : case 111:
2942 : #line 1018 "../parse.y" /* yacc.c:1648 */
2943 : { (yyval.command) = make_arith_command ((yyvsp[0].word_list)); }
2944 : #line 2945 "y.tab.c" /* yacc.c:1648 */
2945 0 : break;
2946 :
2947 0 : case 112:
2948 : #line 1022 "../parse.y" /* yacc.c:1648 */
2949 : { (yyval.command) = (yyvsp[-1].command); }
2950 : #line 2951 "y.tab.c" /* yacc.c:1648 */
2951 0 : break;
2952 :
2953 0 : case 113:
2954 : #line 1026 "../parse.y" /* yacc.c:1648 */
2955 : { (yyval.command) = make_if_command ((yyvsp[-2].command), (yyvsp[0].command), (COMMAND *)NULL); }
2956 : #line 2957 "y.tab.c" /* yacc.c:1648 */
2957 0 : break;
2958 :
2959 0 : case 114:
2960 : #line 1028 "../parse.y" /* yacc.c:1648 */
2961 : { (yyval.command) = make_if_command ((yyvsp[-4].command), (yyvsp[-2].command), (yyvsp[0].command)); }
2962 : #line 2963 "y.tab.c" /* yacc.c:1648 */
2963 0 : break;
2964 :
2965 0 : case 115:
2966 : #line 1030 "../parse.y" /* yacc.c:1648 */
2967 : { (yyval.command) = make_if_command ((yyvsp[-3].command), (yyvsp[-1].command), (yyvsp[0].command)); }
2968 : #line 2969 "y.tab.c" /* yacc.c:1648 */
2969 0 : break;
2970 :
2971 3895982 : case 117:
2972 : #line 1035 "../parse.y" /* yacc.c:1648 */
2973 : { (yyvsp[0].pattern)->next = (yyvsp[-1].pattern); (yyval.pattern) = (yyvsp[0].pattern); }
2974 : #line 2975 "y.tab.c" /* yacc.c:1648 */
2975 3895982 : break;
2976 :
2977 47359442 : case 118:
2978 : #line 1039 "../parse.y" /* yacc.c:1648 */
2979 : { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (yyvsp[0].command)); }
2980 : #line 2981 "y.tab.c" /* yacc.c:1648 */
2981 47359442 : break;
2982 :
2983 1995782 : case 119:
2984 : #line 1041 "../parse.y" /* yacc.c:1648 */
2985 : { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (COMMAND *)NULL); }
2986 : #line 2987 "y.tab.c" /* yacc.c:1648 */
2987 1995782 : break;
2988 :
2989 80 : case 120:
2990 : #line 1043 "../parse.y" /* yacc.c:1648 */
2991 : { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (yyvsp[0].command)); }
2992 : #line 2993 "y.tab.c" /* yacc.c:1648 */
2993 80 : break;
2994 :
2995 10 : case 121:
2996 : #line 1045 "../parse.y" /* yacc.c:1648 */
2997 : { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (COMMAND *)NULL); }
2998 : #line 2999 "y.tab.c" /* yacc.c:1648 */
2999 10 : break;
3000 :
3001 15663833 : case 122:
3002 : #line 1049 "../parse.y" /* yacc.c:1648 */
3003 : { (yyval.pattern) = (yyvsp[-1].pattern); }
3004 : #line 3005 "y.tab.c" /* yacc.c:1648 */
3005 15663833 : break;
3006 :
3007 29780684 : case 123:
3008 : #line 1051 "../parse.y" /* yacc.c:1648 */
3009 : { (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); }
3010 : #line 3011 "y.tab.c" /* yacc.c:1648 */
3011 29780684 : break;
3012 :
3013 12 : case 124:
3014 : #line 1053 "../parse.y" /* yacc.c:1648 */
3015 : { (yyvsp[-1].pattern)->flags |= CASEPAT_FALLTHROUGH; (yyval.pattern) = (yyvsp[-1].pattern); }
3016 : #line 3017 "y.tab.c" /* yacc.c:1648 */
3017 12 : break;
3018 :
3019 35 : case 125:
3020 : #line 1055 "../parse.y" /* yacc.c:1648 */
3021 : { (yyvsp[-1].pattern)->flags |= CASEPAT_FALLTHROUGH; (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); }
3022 : #line 3023 "y.tab.c" /* yacc.c:1648 */
3023 35 : break;
3024 :
3025 13 : case 126:
3026 : #line 1057 "../parse.y" /* yacc.c:1648 */
3027 : { (yyvsp[-1].pattern)->flags |= CASEPAT_TESTNEXT; (yyval.pattern) = (yyvsp[-1].pattern); }
3028 : #line 3029 "y.tab.c" /* yacc.c:1648 */
3029 13 : break;
3030 :
3031 35 : case 127:
3032 : #line 1059 "../parse.y" /* yacc.c:1648 */
3033 : { (yyvsp[-1].pattern)->flags |= CASEPAT_TESTNEXT; (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); }
3034 : #line 3035 "y.tab.c" /* yacc.c:1648 */
3035 35 : break;
3036 :
3037 49637617 : case 128:
3038 : #line 1063 "../parse.y" /* yacc.c:1648 */
3039 : { (yyval.word_list) = make_word_list ((yyvsp[0].word), (WORD_LIST *)NULL); }
3040 : #line 3041 "y.tab.c" /* yacc.c:1648 */
3041 49637617 : break;
3042 :
3043 25139881 : case 129:
3044 : #line 1065 "../parse.y" /* yacc.c:1648 */
3045 : { (yyval.word_list) = make_word_list ((yyvsp[0].word), (yyvsp[-2].word_list)); }
3046 : #line 3047 "y.tab.c" /* yacc.c:1648 */
3047 25139881 : break;
3048 :
3049 218278565 : case 130:
3050 : #line 1074 "../parse.y" /* yacc.c:1648 */
3051 : {
3052 : (yyval.command) = (yyvsp[0].command);
3053 : if (need_here_doc)
3054 : gather_here_documents ();
3055 : }
3056 : #line 3057 "y.tab.c" /* yacc.c:1648 */
3057 : break;
3058 :
3059 229977 : case 132:
3060 : #line 1083 "../parse.y" /* yacc.c:1648 */
3061 : {
3062 : (yyval.command) = (yyvsp[0].command);
3063 : }
3064 : #line 3065 "y.tab.c" /* yacc.c:1648 */
3065 229977 : break;
3066 :
3067 153 : case 134:
3068 : #line 1090 "../parse.y" /* yacc.c:1648 */
3069 : {
3070 : if ((yyvsp[-2].command)->type == cm_connection)
3071 : (yyval.command) = connect_async_list ((yyvsp[-2].command), (COMMAND *)NULL, '&');
3072 : else
3073 : (yyval.command) = command_connect ((yyvsp[-2].command), (COMMAND *)NULL, '&');
3074 : }
3075 : #line 3076 "y.tab.c" /* yacc.c:1648 */
3076 : break;
3077 :
3078 9 : case 136:
3079 : #line 1101 "../parse.y" /* yacc.c:1648 */
3080 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), AND_AND); }
3081 : #line 3082 "y.tab.c" /* yacc.c:1648 */
3082 9 : break;
3083 :
3084 1864345 : case 137:
3085 : #line 1103 "../parse.y" /* yacc.c:1648 */
3086 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), OR_OR); }
3087 : #line 3088 "y.tab.c" /* yacc.c:1648 */
3088 1864345 : break;
3089 :
3090 3476 : case 138:
3091 : #line 1105 "../parse.y" /* yacc.c:1648 */
3092 : {
3093 : if ((yyvsp[-3].command)->type == cm_connection)
3094 : (yyval.command) = connect_async_list ((yyvsp[-3].command), (yyvsp[0].command), '&');
3095 : else
3096 : (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '&');
3097 : }
3098 : #line 3099 "y.tab.c" /* yacc.c:1648 */
3099 : break;
3100 :
3101 135958 : case 139:
3102 : #line 1112 "../parse.y" /* yacc.c:1648 */
3103 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), ';'); }
3104 : #line 3105 "y.tab.c" /* yacc.c:1648 */
3105 135958 : break;
3106 :
3107 79801281 : case 140:
3108 : #line 1114 "../parse.y" /* yacc.c:1648 */
3109 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), ';'); }
3110 : #line 3111 "y.tab.c" /* yacc.c:1648 */
3111 79801281 : break;
3112 :
3113 300405325 : case 141:
3114 : #line 1116 "../parse.y" /* yacc.c:1648 */
3115 : { (yyval.command) = (yyvsp[0].command); }
3116 : #line 3117 "y.tab.c" /* yacc.c:1648 */
3117 300405325 : break;
3118 :
3119 189 : case 144:
3120 : #line 1124 "../parse.y" /* yacc.c:1648 */
3121 : { (yyval.number) = '\n'; }
3122 : #line 3123 "y.tab.c" /* yacc.c:1648 */
3123 189 : break;
3124 :
3125 9543045 : case 145:
3126 : #line 1126 "../parse.y" /* yacc.c:1648 */
3127 : { (yyval.number) = ';'; }
3128 : #line 3129 "y.tab.c" /* yacc.c:1648 */
3129 9543045 : break;
3130 :
3131 0 : case 146:
3132 : #line 1128 "../parse.y" /* yacc.c:1648 */
3133 : { (yyval.number) = yacc_EOF; }
3134 : #line 3135 "y.tab.c" /* yacc.c:1648 */
3135 0 : break;
3136 :
3137 90431718 : case 149:
3138 : #line 1142 "../parse.y" /* yacc.c:1648 */
3139 : {
3140 : (yyval.command) = (yyvsp[0].command);
3141 : if (need_here_doc)
3142 : gather_here_documents ();
3143 : if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
3144 : {
3145 : global_command = (yyvsp[0].command);
3146 : eof_encountered = 0;
3147 : rewind_input_string ();
3148 : YYACCEPT;
3149 : }
3150 : }
3151 : #line 3152 "y.tab.c" /* yacc.c:1648 */
3152 : break;
3153 :
3154 4177 : case 150:
3155 : #line 1155 "../parse.y" /* yacc.c:1648 */
3156 : {
3157 : if ((yyvsp[-1].command)->type == cm_connection)
3158 : (yyval.command) = connect_async_list ((yyvsp[-1].command), (COMMAND *)NULL, '&');
3159 : else
3160 : (yyval.command) = command_connect ((yyvsp[-1].command), (COMMAND *)NULL, '&');
3161 : if (need_here_doc)
3162 : gather_here_documents ();
3163 : if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
3164 : {
3165 : global_command = (yyvsp[-1].command);
3166 : eof_encountered = 0;
3167 : rewind_input_string ();
3168 : YYACCEPT;
3169 : }
3170 : }
3171 : #line 3172 "y.tab.c" /* yacc.c:1648 */
3172 : break;
3173 :
3174 34232 : case 151:
3175 : #line 1171 "../parse.y" /* yacc.c:1648 */
3176 : {
3177 : (yyval.command) = (yyvsp[-1].command);
3178 : if (need_here_doc)
3179 : gather_here_documents ();
3180 : if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
3181 : {
3182 : global_command = (yyvsp[-1].command);
3183 : eof_encountered = 0;
3184 : rewind_input_string ();
3185 : YYACCEPT;
3186 : }
3187 : }
3188 : #line 3189 "y.tab.c" /* yacc.c:1648 */
3189 : break;
3190 :
3191 56 : case 152:
3192 : #line 1186 "../parse.y" /* yacc.c:1648 */
3193 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), AND_AND); }
3194 : #line 3195 "y.tab.c" /* yacc.c:1648 */
3195 56 : break;
3196 :
3197 2364544 : case 153:
3198 : #line 1188 "../parse.y" /* yacc.c:1648 */
3199 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), OR_OR); }
3200 : #line 3201 "y.tab.c" /* yacc.c:1648 */
3201 2364544 : break;
3202 :
3203 17699 : case 154:
3204 : #line 1190 "../parse.y" /* yacc.c:1648 */
3205 : {
3206 : if ((yyvsp[-2].command)->type == cm_connection)
3207 : (yyval.command) = connect_async_list ((yyvsp[-2].command), (yyvsp[0].command), '&');
3208 : else
3209 : (yyval.command) = command_connect ((yyvsp[-2].command), (yyvsp[0].command), '&');
3210 : }
3211 : #line 3212 "y.tab.c" /* yacc.c:1648 */
3212 : break;
3213 :
3214 18653 : case 155:
3215 : #line 1197 "../parse.y" /* yacc.c:1648 */
3216 : { (yyval.command) = command_connect ((yyvsp[-2].command), (yyvsp[0].command), ';'); }
3217 : #line 3218 "y.tab.c" /* yacc.c:1648 */
3218 18653 : break;
3219 :
3220 92877136 : case 156:
3221 : #line 1200 "../parse.y" /* yacc.c:1648 */
3222 : { (yyval.command) = (yyvsp[0].command); }
3223 : #line 3224 "y.tab.c" /* yacc.c:1648 */
3224 92877136 : break;
3225 :
3226 393282196 : case 157:
3227 : #line 1204 "../parse.y" /* yacc.c:1648 */
3228 : { (yyval.command) = (yyvsp[0].command); }
3229 : #line 3230 "y.tab.c" /* yacc.c:1648 */
3230 393282196 : break;
3231 :
3232 455 : case 158:
3233 : #line 1206 "../parse.y" /* yacc.c:1648 */
3234 : {
3235 : if ((yyvsp[0].command))
3236 : (yyvsp[0].command)->flags ^= CMD_INVERT_RETURN; /* toggle */
3237 : (yyval.command) = (yyvsp[0].command);
3238 : }
3239 : #line 3240 "y.tab.c" /* yacc.c:1648 */
3240 455 : break;
3241 :
3242 0 : case 159:
3243 : #line 1212 "../parse.y" /* yacc.c:1648 */
3244 : {
3245 : if ((yyvsp[0].command))
3246 : (yyvsp[0].command)->flags |= (yyvsp[-1].number);
3247 : (yyval.command) = (yyvsp[0].command);
3248 : }
3249 : #line 3250 "y.tab.c" /* yacc.c:1648 */
3250 0 : break;
3251 :
3252 0 : case 160:
3253 : #line 1218 "../parse.y" /* yacc.c:1648 */
3254 : {
3255 : ELEMENT x;
3256 :
3257 : /* Boy, this is unclean. `time' by itself can
3258 : time a null command. We cheat and push a
3259 : newline back if the list_terminator was a newline
3260 : to avoid the double-newline problem (one to
3261 : terminate this, one to terminate the command) */
3262 : x.word = 0;
3263 : x.redirect = 0;
3264 : (yyval.command) = make_simple_command (x, (COMMAND *)NULL);
3265 : (yyval.command)->flags |= (yyvsp[-1].number);
3266 : /* XXX - let's cheat and push a newline back */
3267 : if ((yyvsp[0].number) == '\n')
3268 : token_to_read = '\n';
3269 : else if ((yyvsp[0].number) == ';')
3270 : token_to_read = ';';
3271 : }
3272 : #line 3273 "y.tab.c" /* yacc.c:1648 */
3273 0 : break;
3274 :
3275 265 : case 161:
3276 : #line 1237 "../parse.y" /* yacc.c:1648 */
3277 : {
3278 : ELEMENT x;
3279 :
3280 : /* This is just as unclean. Posix says that `!'
3281 : by itself should be equivalent to `false'.
3282 : We cheat and push a
3283 : newline back if the list_terminator was a newline
3284 : to avoid the double-newline problem (one to
3285 : terminate this, one to terminate the command) */
3286 : x.word = 0;
3287 : x.redirect = 0;
3288 : (yyval.command) = make_simple_command (x, (COMMAND *)NULL);
3289 : (yyval.command)->flags |= CMD_INVERT_RETURN;
3290 : /* XXX - let's cheat and push a newline back */
3291 : if ((yyvsp[0].number) == '\n')
3292 : token_to_read = '\n';
3293 : if ((yyvsp[0].number) == ';')
3294 : token_to_read = ';';
3295 : }
3296 : #line 3297 "y.tab.c" /* yacc.c:1648 */
3297 265 : break;
3298 :
3299 1905840 : case 162:
3300 : #line 1259 "../parse.y" /* yacc.c:1648 */
3301 : { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '|'); }
3302 : #line 3303 "y.tab.c" /* yacc.c:1648 */
3303 1905840 : break;
3304 :
3305 92 : case 163:
3306 : #line 1261 "../parse.y" /* yacc.c:1648 */
3307 : {
3308 : /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
3309 : COMMAND *tc;
3310 : REDIRECTEE rd, sd;
3311 : REDIRECT *r;
3312 :
3313 : tc = (yyvsp[-3].command)->type == cm_simple ? (COMMAND *)(yyvsp[-3].command)->value.Simple : (yyvsp[-3].command);
3314 : sd.dest = 2;
3315 : rd.dest = 1;
3316 : r = make_redirection (sd, r_duplicating_output, rd, 0);
3317 : if (tc->redirects)
3318 : {
3319 : register REDIRECT *t;
3320 : for (t = tc->redirects; t->next; t = t->next)
3321 : ;
3322 : t->next = r;
3323 : }
3324 : else
3325 : tc->redirects = r;
3326 :
3327 : (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '|');
3328 : }
3329 : #line 3330 "y.tab.c" /* yacc.c:1648 */
3330 92 : break;
3331 :
3332 395566223 : case 164:
3333 : #line 1284 "../parse.y" /* yacc.c:1648 */
3334 : { (yyval.command) = (yyvsp[0].command); }
3335 : #line 3336 "y.tab.c" /* yacc.c:1648 */
3336 395566223 : break;
3337 :
3338 0 : case 165:
3339 : #line 1288 "../parse.y" /* yacc.c:1648 */
3340 : { (yyval.number) = CMD_TIME_PIPELINE; }
3341 : #line 3342 "y.tab.c" /* yacc.c:1648 */
3342 0 : break;
3343 :
3344 0 : case 166:
3345 : #line 1290 "../parse.y" /* yacc.c:1648 */
3346 : { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
3347 : #line 3348 "y.tab.c" /* yacc.c:1648 */
3348 0 : break;
3349 :
3350 0 : case 167:
3351 : #line 1292 "../parse.y" /* yacc.c:1648 */
3352 : { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
3353 : #line 3354 "y.tab.c" /* yacc.c:1648 */
3354 0 : break;
3355 :
3356 :
3357 : #line 3358 "y.tab.c" /* yacc.c:1648 */
3358 : default: break;
3359 : }
3360 : /* User semantic actions sometimes alter yychar, and that requires
3361 : that yytoken be updated with the new translation. We take the
3362 : approach of translating immediately before every use of yytoken.
3363 : One alternative is translating here after every semantic action,
3364 : but that translation would be missed if the semantic action invokes
3365 : YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
3366 : if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
3367 : incorrect destructor might then be invoked immediately. In the
3368 : case of YYERROR or YYBACKUP, subsequent parser actions might lead
3369 : to an incorrect destructor call or verbose syntax error message
3370 : before the lookahead is translated. */
3371 5337172991 : YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
3372 :
3373 5337172991 : YYPOPSTACK (yylen);
3374 5337172991 : yylen = 0;
3375 5337172991 : YY_STACK_PRINT (yyss, yyssp);
3376 :
3377 5337172991 : *++yyvsp = yyval;
3378 :
3379 : /* Now 'shift' the result of the reduction. Determine what state
3380 : that goes to, based on the state we popped back to and the rule
3381 : number reduced by. */
3382 :
3383 5337172991 : yyn = yyr1[yyn];
3384 :
3385 5337172991 : yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
3386 5337172991 : if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
3387 1486607620 : yystate = yytable[yystate];
3388 : else
3389 3850565371 : yystate = yydefgoto[yyn - YYNTOKENS];
3390 :
3391 5337172991 : goto yynewstate;
3392 :
3393 :
3394 : /*--------------------------------------.
3395 : | yyerrlab -- here on detecting error. |
3396 : `--------------------------------------*/
3397 4146129 : yyerrlab:
3398 : /* Make sure we have latest lookahead translation. See comments at
3399 : user semantic actions for why this is necessary. */
3400 4146129 : yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
3401 :
3402 : /* If not already recovering from an error, report this error. */
3403 4146129 : if (!yyerrstatus)
3404 : {
3405 2104122 : ++yynerrs;
3406 : #if ! YYERROR_VERBOSE
3407 2104122 : yyerror (YY_("syntax error"));
3408 : #else
3409 : # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
3410 : yyssp, yytoken)
3411 : {
3412 : char const *yymsgp = YY_("syntax error");
3413 : int yysyntax_error_status;
3414 : yysyntax_error_status = YYSYNTAX_ERROR;
3415 : if (yysyntax_error_status == 0)
3416 : yymsgp = yymsg;
3417 : else if (yysyntax_error_status == 1)
3418 : {
3419 : if (yymsg != yymsgbuf)
3420 : YYSTACK_FREE (yymsg);
3421 : yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
3422 : if (!yymsg)
3423 : {
3424 : yymsg = yymsgbuf;
3425 : yymsg_alloc = sizeof yymsgbuf;
3426 : yysyntax_error_status = 2;
3427 : }
3428 : else
3429 : {
3430 : yysyntax_error_status = YYSYNTAX_ERROR;
3431 : yymsgp = yymsg;
3432 : }
3433 : }
3434 : yyerror (yymsgp);
3435 : if (yysyntax_error_status == 2)
3436 : goto yyexhaustedlab;
3437 : }
3438 : # undef YYSYNTAX_ERROR
3439 : #endif
3440 : }
3441 :
3442 :
3443 :
3444 4146129 : if (yyerrstatus == 3)
3445 : {
3446 : /* If just tried and failed to reuse lookahead token after an
3447 : error, discard it. */
3448 :
3449 2042007 : if (yychar <= YYEOF)
3450 : {
3451 : /* Return failure if at end of input. */
3452 190094 : if (yychar == YYEOF)
3453 190094 : YYABORT;
3454 : }
3455 : else
3456 : {
3457 1851913 : yydestruct ("Error: discarding",
3458 : yytoken, &yylval);
3459 1851913 : yychar = YYEMPTY;
3460 : }
3461 : }
3462 :
3463 : /* Else will try to reuse lookahead token after shifting the error
3464 : token. */
3465 3956035 : goto yyerrlab1;
3466 :
3467 :
3468 : /*---------------------------------------------------.
3469 : | yyerrorlab -- error raised explicitly by YYERROR. |
3470 : `---------------------------------------------------*/
3471 : yyerrorlab:
3472 :
3473 : /* Pacify compilers like GCC when the user code never invokes
3474 : YYERROR and the label yyerrorlab therefore never appears in user
3475 : code. */
3476 : if (/*CONSTCOND*/ 0)
3477 : goto yyerrorlab;
3478 :
3479 : /* Do not reclaim the symbols of the rule whose action triggered
3480 : this YYERROR. */
3481 : YYPOPSTACK (yylen);
3482 : yylen = 0;
3483 : YY_STACK_PRINT (yyss, yyssp);
3484 : yystate = *yyssp;
3485 : goto yyerrlab1;
3486 :
3487 :
3488 : /*-------------------------------------------------------------.
3489 : | yyerrlab1 -- common code for both syntax error and YYERROR. |
3490 : `-------------------------------------------------------------*/
3491 3956035 : yyerrlab1:
3492 3956035 : yyerrstatus = 3; /* Each real token shifted decrements this. */
3493 :
3494 24083659 : for (;;)
3495 : {
3496 24083659 : yyn = yypact[yystate];
3497 14019847 : if (!yypact_value_is_default (yyn))
3498 : {
3499 11253019 : yyn += YYTERROR;
3500 11253019 : if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
3501 : {
3502 3956035 : yyn = yytable[yyn];
3503 3956035 : if (0 < yyn)
3504 : break;
3505 : }
3506 : }
3507 :
3508 : /* Pop the current state because it cannot handle the error token. */
3509 10063812 : if (yyssp == yyss)
3510 0 : YYABORT;
3511 :
3512 :
3513 20127624 : yydestruct ("Error: popping",
3514 10063812 : yystos[yystate], yyvsp);
3515 10063812 : YYPOPSTACK (1);
3516 10063812 : yystate = *yyssp;
3517 10063812 : YY_STACK_PRINT (yyss, yyssp);
3518 : }
3519 :
3520 : YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
3521 3956035 : *++yyvsp = yylval;
3522 : YY_IGNORE_MAYBE_UNINITIALIZED_END
3523 :
3524 :
3525 : /* Shift the error token. */
3526 3956035 : YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
3527 :
3528 3956035 : yystate = yyn;
3529 3956035 : goto yynewstate;
3530 :
3531 :
3532 : /*-------------------------------------.
3533 : | yyacceptlab -- YYACCEPT comes here. |
3534 : `-------------------------------------*/
3535 291518221 : yyacceptlab:
3536 291518221 : yyresult = 0;
3537 291518221 : goto yyreturn;
3538 :
3539 : /*-----------------------------------.
3540 : | yyabortlab -- YYABORT comes here. |
3541 : `-----------------------------------*/
3542 2104122 : yyabortlab:
3543 2104122 : yyresult = 1;
3544 2104122 : goto yyreturn;
3545 :
3546 : #if !defined yyoverflow || YYERROR_VERBOSE
3547 : /*-------------------------------------------------.
3548 : | yyexhaustedlab -- memory exhaustion comes here. |
3549 : `-------------------------------------------------*/
3550 0 : yyexhaustedlab:
3551 0 : yyerror (YY_("memory exhausted"));
3552 0 : yyresult = 2;
3553 : /* Fall through. */
3554 : #endif
3555 :
3556 293622343 : yyreturn:
3557 293622343 : if (yychar != YYEMPTY)
3558 : {
3559 : /* Make sure we have latest lookahead translation. See comments at
3560 : user semantic actions for why this is necessary. */
3561 : yytoken = YYTRANSLATE (yychar);
3562 : yydestruct ("Cleanup: discarding lookahead",
3563 : yytoken, &yylval);
3564 : }
3565 : /* Do not reclaim the symbols of the rule whose action triggered
3566 : this YYABORT or YYACCEPT. */
3567 293622343 : YYPOPSTACK (yylen);
3568 293622343 : YY_STACK_PRINT (yyss, yyssp);
3569 293622343 : while (yyssp != yyss)
3570 : {
3571 : yydestruct ("Cleanup: popping",
3572 : yystos[*yyssp], yyvsp);
3573 : YYPOPSTACK (1);
3574 : }
3575 : #ifndef yyoverflow
3576 293622343 : if (yyss != yyssa)
3577 0 : YYSTACK_FREE (yyss);
3578 : #endif
3579 : #if YYERROR_VERBOSE
3580 : if (yymsg != yymsgbuf)
3581 : YYSTACK_FREE (yymsg);
3582 : #endif
3583 293622343 : return yyresult;
3584 : }
3585 : #line 1294 "../parse.y" /* yacc.c:1907 */
3586 :
3587 :
3588 : /* Initial size to allocate for tokens, and the
3589 : amount to grow them by. */
3590 : #define TOKEN_DEFAULT_INITIAL_SIZE 496
3591 : #define TOKEN_DEFAULT_GROW_SIZE 512
3592 :
3593 : /* Should we call prompt_again? */
3594 : #define SHOULD_PROMPT() \
3595 : (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
3596 :
3597 : #if defined (ALIAS)
3598 : # define expanding_alias() (pushed_string_list && pushed_string_list->expander)
3599 : #else
3600 : # define expanding_alias() 0
3601 : #endif
3602 :
3603 : /* Global var is non-zero when end of file has been reached. */
3604 : int EOF_Reached = 0;
3605 :
3606 : #ifdef DEBUG
3607 : static void
3608 : debug_parser (i)
3609 : int i;
3610 : {
3611 : #if YYDEBUG != 0
3612 : yydebug = i;
3613 : #endif
3614 : }
3615 : #endif
3616 :
3617 : /* yy_getc () returns the next available character from input or EOF.
3618 : yy_ungetc (c) makes `c' the next character to read.
3619 : init_yy_io (get, unget, type, location) makes the function GET the
3620 : installed function for getting the next character, makes UNGET the
3621 : installed function for un-getting a character, sets the type of stream
3622 : (either string or file) from TYPE, and makes LOCATION point to where
3623 : the input is coming from. */
3624 :
3625 : /* Unconditionally returns end-of-file. */
3626 : int
3627 : return_EOF ()
3628 : {
3629 : return (EOF);
3630 : }
3631 :
3632 : /* Variable containing the current get and unget functions.
3633 : See ./input.h for a clearer description. */
3634 : BASH_INPUT bash_input;
3635 :
3636 : /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
3637 : is non-null, avoiding a memory leak. */
3638 : void
3639 : initialize_bash_input ()
3640 : {
3641 : bash_input.type = st_none;
3642 : FREE (bash_input.name);
3643 : bash_input.name = (char *)NULL;
3644 : bash_input.location.file = (FILE *)NULL;
3645 : bash_input.location.string = (char *)NULL;
3646 : bash_input.getter = (sh_cget_func_t *)NULL;
3647 : bash_input.ungetter = (sh_cunget_func_t *)NULL;
3648 : }
3649 :
3650 : /* Set the contents of the current bash input stream from
3651 : GET, UNGET, TYPE, NAME, and LOCATION. */
3652 : void
3653 : init_yy_io (get, unget, type, name, location)
3654 : sh_cget_func_t *get;
3655 : sh_cunget_func_t *unget;
3656 : enum stream_type type;
3657 : const char *name;
3658 : INPUT_STREAM location;
3659 : {
3660 : bash_input.type = type;
3661 : FREE (bash_input.name);
3662 : bash_input.name = name ? savestring (name) : (char *)NULL;
3663 :
3664 : /* XXX */
3665 : #if defined (CRAY)
3666 : memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
3667 : #else
3668 : bash_input.location = location;
3669 : #endif
3670 : bash_input.getter = get;
3671 : bash_input.ungetter = unget;
3672 : }
3673 :
3674 : char *
3675 : yy_input_name ()
3676 : {
3677 : return (bash_input.name ? bash_input.name : "stdin");
3678 : }
3679 :
3680 : /* Call this to get the next character of input. */
3681 : static int
3682 : yy_getc ()
3683 : {
3684 : return (*(bash_input.getter)) ();
3685 : }
3686 :
3687 : /* Call this to unget C. That is, to make C the next character
3688 : to be read. */
3689 : static int
3690 : yy_ungetc (c)
3691 : int c;
3692 : {
3693 : return (*(bash_input.ungetter)) (c);
3694 : }
3695 :
3696 : #if defined (BUFFERED_INPUT)
3697 : #ifdef INCLUDE_UNUSED
3698 : int
3699 : input_file_descriptor ()
3700 : {
3701 : switch (bash_input.type)
3702 : {
3703 : case st_stream:
3704 : return (fileno (bash_input.location.file));
3705 : case st_bstream:
3706 : return (bash_input.location.buffered_fd);
3707 : case st_stdin:
3708 : default:
3709 : return (fileno (stdin));
3710 : }
3711 : }
3712 : #endif
3713 : #endif /* BUFFERED_INPUT */
3714 :
3715 : /* **************************************************************** */
3716 : /* */
3717 : /* Let input be read from readline (). */
3718 : /* */
3719 : /* **************************************************************** */
3720 :
3721 : #if defined (READLINE)
3722 : char *current_readline_prompt = (char *)NULL;
3723 : char *current_readline_line = (char *)NULL;
3724 : int current_readline_line_index = 0;
3725 :
3726 : static int
3727 : yy_readline_get ()
3728 : {
3729 : SigHandler *old_sigint;
3730 : int line_len;
3731 : unsigned char c;
3732 :
3733 : if (current_readline_line == 0)
3734 : {
3735 : if (bash_readline_initialized == 0)
3736 : initialize_readline ();
3737 :
3738 : #if defined (JOB_CONTROL)
3739 : if (job_control)
3740 : give_terminal_to (shell_pgrp, 0);
3741 : #endif /* JOB_CONTROL */
3742 :
3743 : old_sigint = IMPOSSIBLE_TRAP_HANDLER;
3744 : if (signal_is_ignored (SIGINT) == 0)
3745 : {
3746 : /* interrupt_immediately++; */
3747 : old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
3748 : }
3749 :
3750 : sh_unset_nodelay_mode (fileno (rl_instream)); /* just in case */
3751 : current_readline_line = readline (current_readline_prompt ?
3752 : current_readline_prompt : "");
3753 :
3754 : CHECK_TERMSIG;
3755 : if (signal_is_ignored (SIGINT) == 0)
3756 : {
3757 : /* interrupt_immediately--; */
3758 : if (old_sigint != IMPOSSIBLE_TRAP_HANDLER)
3759 : set_signal_handler (SIGINT, old_sigint);
3760 : }
3761 :
3762 : #if 0
3763 : /* Reset the prompt to the decoded value of prompt_string_pointer. */
3764 : reset_readline_prompt ();
3765 : #endif
3766 :
3767 : if (current_readline_line == 0)
3768 : return (EOF);
3769 :
3770 : current_readline_line_index = 0;
3771 : line_len = strlen (current_readline_line);
3772 :
3773 : current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
3774 : current_readline_line[line_len++] = '\n';
3775 : current_readline_line[line_len] = '\0';
3776 : }
3777 :
3778 : if (current_readline_line[current_readline_line_index] == 0)
3779 : {
3780 : free (current_readline_line);
3781 : current_readline_line = (char *)NULL;
3782 : return (yy_readline_get ());
3783 : }
3784 : else
3785 : {
3786 : c = current_readline_line[current_readline_line_index++];
3787 : return (c);
3788 : }
3789 : }
3790 :
3791 : static int
3792 : yy_readline_unget (c)
3793 : int c;
3794 : {
3795 : if (current_readline_line_index && current_readline_line)
3796 : current_readline_line[--current_readline_line_index] = c;
3797 : return (c);
3798 : }
3799 :
3800 : void
3801 : with_input_from_stdin ()
3802 : {
3803 : INPUT_STREAM location;
3804 :
3805 : if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
3806 : {
3807 : location.string = current_readline_line;
3808 : init_yy_io (yy_readline_get, yy_readline_unget,
3809 : st_stdin, "readline stdin", location);
3810 : }
3811 : }
3812 :
3813 : #else /* !READLINE */
3814 :
3815 : void
3816 : with_input_from_stdin ()
3817 : {
3818 : with_input_from_stream (stdin, "stdin");
3819 : }
3820 : #endif /* !READLINE */
3821 :
3822 : /* **************************************************************** */
3823 : /* */
3824 : /* Let input come from STRING. STRING is zero terminated. */
3825 : /* */
3826 : /* **************************************************************** */
3827 :
3828 : static int
3829 : yy_string_get ()
3830 : {
3831 : register char *string;
3832 : register unsigned char c;
3833 :
3834 : string = bash_input.location.string;
3835 :
3836 : /* If the string doesn't exist, or is empty, EOF found. */
3837 : if (string && *string)
3838 : {
3839 : c = *string++;
3840 : bash_input.location.string = string;
3841 : return (c);
3842 : }
3843 : else
3844 : return (EOF);
3845 : }
3846 :
3847 : static int
3848 : yy_string_unget (c)
3849 : int c;
3850 : {
3851 : *(--bash_input.location.string) = c;
3852 : return (c);
3853 : }
3854 :
3855 : void
3856 : with_input_from_string (string, name)
3857 : char *string;
3858 : const char *name;
3859 : {
3860 : INPUT_STREAM location;
3861 :
3862 : location.string = string;
3863 : init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
3864 : }
3865 :
3866 : /* Count the number of characters we've consumed from bash_input.location.string
3867 : and read into shell_input_line, but have not returned from shell_getc.
3868 : That is the true input location. Rewind bash_input.location.string by
3869 : that number of characters, so it points to the last character actually
3870 : consumed by the parser. */
3871 : static void
3872 : rewind_input_string ()
3873 : {
3874 : int xchars;
3875 :
3876 : /* number of unconsumed characters in the input -- XXX need to take newlines
3877 : into account, e.g., $(...\n) */
3878 : xchars = shell_input_line_len - shell_input_line_index;
3879 : if (bash_input.location.string[-1] == '\n')
3880 : xchars++;
3881 :
3882 : /* XXX - how to reflect bash_input.location.string back to string passed to
3883 : parse_and_execute or xparse_dolparen? xparse_dolparen needs to know how
3884 : far into the string we parsed. parse_and_execute knows where bash_input.
3885 : location.string is, and how far from orig_string that is -- that's the
3886 : number of characters the command consumed. */
3887 :
3888 : /* bash_input.location.string - xchars should be where we parsed to */
3889 : /* need to do more validation on xchars value for sanity -- test cases. */
3890 : bash_input.location.string -= xchars;
3891 : }
3892 :
3893 : /* **************************************************************** */
3894 : /* */
3895 : /* Let input come from STREAM. */
3896 : /* */
3897 : /* **************************************************************** */
3898 :
3899 : /* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
3900 : define, and just use getc/ungetc if it was defined, but since bash
3901 : installs its signal handlers without the SA_RESTART flag, some signals
3902 : (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
3903 : the read to be restarted. We need to restart it ourselves. */
3904 :
3905 : static int
3906 : yy_stream_get ()
3907 : {
3908 : int result;
3909 :
3910 : result = EOF;
3911 : if (bash_input.location.file)
3912 : {
3913 : #if 0
3914 : if (interactive)
3915 : interrupt_immediately++;
3916 : #endif
3917 :
3918 : /* XXX - don't need terminate_immediately; getc_with_restart checks
3919 : for terminating signals itself if read returns < 0 */
3920 : result = getc_with_restart (bash_input.location.file);
3921 :
3922 : #if 0
3923 : if (interactive)
3924 : interrupt_immediately--;
3925 : #endif
3926 : }
3927 : return (result);
3928 : }
3929 :
3930 : static int
3931 : yy_stream_unget (c)
3932 : int c;
3933 : {
3934 : return (ungetc_with_restart (c, bash_input.location.file));
3935 : }
3936 :
3937 : void
3938 : with_input_from_stream (stream, name)
3939 : FILE *stream;
3940 : const char *name;
3941 : {
3942 : INPUT_STREAM location;
3943 :
3944 : location.file = stream;
3945 : init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
3946 : }
3947 :
3948 : typedef struct stream_saver {
3949 : struct stream_saver *next;
3950 : BASH_INPUT bash_input;
3951 : int line;
3952 : #if defined (BUFFERED_INPUT)
3953 : BUFFERED_STREAM *bstream;
3954 : #endif /* BUFFERED_INPUT */
3955 : } STREAM_SAVER;
3956 :
3957 : /* The globally known line number. */
3958 : int line_number = 0;
3959 :
3960 : /* The line number offset set by assigning to LINENO. Not currently used. */
3961 : int line_number_base = 0;
3962 :
3963 : #if defined (COND_COMMAND)
3964 : static int cond_lineno;
3965 : static int cond_token;
3966 : #endif
3967 :
3968 : STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
3969 :
3970 : void
3971 : push_stream (reset_lineno)
3972 : int reset_lineno;
3973 : {
3974 : STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
3975 :
3976 : xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
3977 :
3978 : #if defined (BUFFERED_INPUT)
3979 : saver->bstream = (BUFFERED_STREAM *)NULL;
3980 : /* If we have a buffered stream, clear out buffers[fd]. */
3981 : if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
3982 : saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
3983 : (BUFFERED_STREAM *)NULL);
3984 : #endif /* BUFFERED_INPUT */
3985 :
3986 : saver->line = line_number;
3987 : bash_input.name = (char *)NULL;
3988 : saver->next = stream_list;
3989 : stream_list = saver;
3990 : EOF_Reached = 0;
3991 : if (reset_lineno)
3992 : line_number = 0;
3993 : }
3994 :
3995 : void
3996 : pop_stream ()
3997 : {
3998 : if (!stream_list)
3999 : EOF_Reached = 1;
4000 : else
4001 : {
4002 : STREAM_SAVER *saver = stream_list;
4003 :
4004 : EOF_Reached = 0;
4005 : stream_list = stream_list->next;
4006 :
4007 : init_yy_io (saver->bash_input.getter,
4008 : saver->bash_input.ungetter,
4009 : saver->bash_input.type,
4010 : saver->bash_input.name,
4011 : saver->bash_input.location);
4012 :
4013 : #if defined (BUFFERED_INPUT)
4014 : /* If we have a buffered stream, restore buffers[fd]. */
4015 : /* If the input file descriptor was changed while this was on the
4016 : save stack, update the buffered fd to the new file descriptor and
4017 : re-establish the buffer <-> bash_input fd correspondence. */
4018 : if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
4019 : {
4020 : if (bash_input_fd_changed)
4021 : {
4022 : bash_input_fd_changed = 0;
4023 : if (default_buffered_input >= 0)
4024 : {
4025 : bash_input.location.buffered_fd = default_buffered_input;
4026 : saver->bstream->b_fd = default_buffered_input;
4027 : SET_CLOSE_ON_EXEC (default_buffered_input);
4028 : }
4029 : }
4030 : /* XXX could free buffered stream returned as result here. */
4031 : set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
4032 : }
4033 : #endif /* BUFFERED_INPUT */
4034 :
4035 : line_number = saver->line;
4036 :
4037 : FREE (saver->bash_input.name);
4038 : free (saver);
4039 : }
4040 : }
4041 :
4042 : /* Return 1 if a stream of type TYPE is saved on the stack. */
4043 : int
4044 : stream_on_stack (type)
4045 : enum stream_type type;
4046 : {
4047 : register STREAM_SAVER *s;
4048 :
4049 : for (s = stream_list; s; s = s->next)
4050 : if (s->bash_input.type == type)
4051 : return 1;
4052 : return 0;
4053 : }
4054 :
4055 : /* Save the current token state and return it in a malloced array. */
4056 : int *
4057 : save_token_state ()
4058 : {
4059 : int *ret;
4060 :
4061 : ret = (int *)xmalloc (4 * sizeof (int));
4062 : ret[0] = last_read_token;
4063 : ret[1] = token_before_that;
4064 : ret[2] = two_tokens_ago;
4065 : ret[3] = current_token;
4066 : return ret;
4067 : }
4068 :
4069 : void
4070 : restore_token_state (ts)
4071 : int *ts;
4072 : {
4073 : if (ts == 0)
4074 : return;
4075 : last_read_token = ts[0];
4076 : token_before_that = ts[1];
4077 : two_tokens_ago = ts[2];
4078 : current_token = ts[3];
4079 : }
4080 :
4081 : /*
4082 : * This is used to inhibit alias expansion and reserved word recognition
4083 : * inside case statement pattern lists. A `case statement pattern list' is:
4084 : *
4085 : * everything between the `in' in a `case word in' and the next ')'
4086 : * or `esac'
4087 : * everything between a `;;' and the next `)' or `esac'
4088 : */
4089 :
4090 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4091 :
4092 : #define END_OF_ALIAS 0
4093 :
4094 : /*
4095 : * Pseudo-global variables used in implementing token-wise alias expansion.
4096 : */
4097 :
4098 : /*
4099 : * Pushing and popping strings. This works together with shell_getc to
4100 : * implement alias expansion on a per-token basis.
4101 : */
4102 :
4103 : #define PSH_ALIAS 0x01
4104 : #define PSH_DPAREN 0x02
4105 : #define PSH_SOURCE 0x04
4106 :
4107 : typedef struct string_saver {
4108 : struct string_saver *next;
4109 : int expand_alias; /* Value to set expand_alias to when string is popped. */
4110 : char *saved_line;
4111 : #if defined (ALIAS)
4112 : alias_t *expander; /* alias that caused this line to be pushed. */
4113 : #endif
4114 : size_t saved_line_size, saved_line_index;
4115 : int saved_line_terminator;
4116 : int flags;
4117 : } STRING_SAVER;
4118 :
4119 : STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
4120 :
4121 : /*
4122 : * Push the current shell_input_line onto a stack of such lines and make S
4123 : * the current input. Used when expanding aliases. EXPAND is used to set
4124 : * the value of expand_next_token when the string is popped, so that the
4125 : * word after the alias in the original line is handled correctly when the
4126 : * alias expands to multiple words. TOKEN is the token that was expanded
4127 : * into S; it is saved and used to prevent infinite recursive expansion.
4128 : */
4129 : static void
4130 : push_string (s, expand, ap)
4131 : char *s;
4132 : int expand;
4133 : alias_t *ap;
4134 : {
4135 : STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
4136 :
4137 : temp->expand_alias = expand;
4138 : temp->saved_line = shell_input_line;
4139 : temp->saved_line_size = shell_input_line_size;
4140 : temp->saved_line_index = shell_input_line_index;
4141 : temp->saved_line_terminator = shell_input_line_terminator;
4142 : temp->flags = 0;
4143 : #if defined (ALIAS)
4144 : temp->expander = ap;
4145 : if (ap)
4146 : temp->flags = PSH_ALIAS;
4147 : #endif
4148 : temp->next = pushed_string_list;
4149 : pushed_string_list = temp;
4150 :
4151 : #if defined (ALIAS)
4152 : if (ap)
4153 : ap->flags |= AL_BEINGEXPANDED;
4154 : #endif
4155 :
4156 : shell_input_line = s;
4157 : shell_input_line_size = STRLEN (s);
4158 : shell_input_line_index = 0;
4159 : shell_input_line_terminator = '\0';
4160 : #if 0
4161 : parser_state &= ~PST_ALEXPNEXT; /* XXX */
4162 : #endif
4163 :
4164 : set_line_mbstate ();
4165 : }
4166 :
4167 : /*
4168 : * Make the top of the pushed_string stack be the current shell input.
4169 : * Only called when there is something on the stack. Called from shell_getc
4170 : * when it thinks it has consumed the string generated by an alias expansion
4171 : * and needs to return to the original input line.
4172 : */
4173 : static void
4174 : pop_string ()
4175 : {
4176 : STRING_SAVER *t;
4177 :
4178 : FREE (shell_input_line);
4179 : shell_input_line = pushed_string_list->saved_line;
4180 : shell_input_line_index = pushed_string_list->saved_line_index;
4181 : shell_input_line_size = pushed_string_list->saved_line_size;
4182 : shell_input_line_terminator = pushed_string_list->saved_line_terminator;
4183 :
4184 : if (pushed_string_list->expand_alias)
4185 : parser_state |= PST_ALEXPNEXT;
4186 : else
4187 : parser_state &= ~PST_ALEXPNEXT;
4188 :
4189 : t = pushed_string_list;
4190 : pushed_string_list = pushed_string_list->next;
4191 :
4192 : #if defined (ALIAS)
4193 : if (t->expander)
4194 : t->expander->flags &= ~AL_BEINGEXPANDED;
4195 : #endif
4196 :
4197 : free ((char *)t);
4198 :
4199 : set_line_mbstate ();
4200 : }
4201 :
4202 : static void
4203 : free_string_list ()
4204 : {
4205 : register STRING_SAVER *t, *t1;
4206 :
4207 : for (t = pushed_string_list; t; )
4208 : {
4209 : t1 = t->next;
4210 : FREE (t->saved_line);
4211 : #if defined (ALIAS)
4212 : if (t->expander)
4213 : t->expander->flags &= ~AL_BEINGEXPANDED;
4214 : #endif
4215 : free ((char *)t);
4216 : t = t1;
4217 : }
4218 : pushed_string_list = (STRING_SAVER *)NULL;
4219 : }
4220 :
4221 : #endif /* ALIAS || DPAREN_ARITHMETIC */
4222 :
4223 : void
4224 : free_pushed_string_input ()
4225 : {
4226 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4227 : free_string_list ();
4228 : #endif
4229 : }
4230 :
4231 : int
4232 : parser_expanding_alias ()
4233 : {
4234 : return (expanding_alias ());
4235 : }
4236 :
4237 : void
4238 : parser_save_alias ()
4239 : {
4240 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4241 : push_string ((char *)NULL, 0, (alias_t *)NULL);
4242 : pushed_string_list->flags = PSH_SOURCE; /* XXX - for now */
4243 : #else
4244 : ;
4245 : #endif
4246 : }
4247 :
4248 : void
4249 : parser_restore_alias ()
4250 : {
4251 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4252 : if (pushed_string_list)
4253 : pop_string ();
4254 : #else
4255 : ;
4256 : #endif
4257 : }
4258 :
4259 : void
4260 : clear_shell_input_line ()
4261 : {
4262 : if (shell_input_line)
4263 : shell_input_line[shell_input_line_index = 0] = '\0';
4264 : }
4265 :
4266 : /* Return a line of text, taken from wherever yylex () reads input.
4267 : If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
4268 : is non-zero, we remove unquoted \<newline> pairs. This is used by
4269 : read_secondary_line to read here documents. */
4270 : static char *
4271 : read_a_line (remove_quoted_newline)
4272 : int remove_quoted_newline;
4273 : {
4274 : static char *line_buffer = (char *)NULL;
4275 : static int buffer_size = 0;
4276 : int indx, c, peekc, pass_next;
4277 :
4278 : #if defined (READLINE)
4279 : if (no_line_editing && SHOULD_PROMPT ())
4280 : #else
4281 : if (SHOULD_PROMPT ())
4282 : #endif
4283 : print_prompt ();
4284 :
4285 : pass_next = indx = 0;
4286 : while (1)
4287 : {
4288 : /* Allow immediate exit if interrupted during input. */
4289 : QUIT;
4290 :
4291 : c = yy_getc ();
4292 :
4293 : /* Ignore null bytes in input. */
4294 : if (c == 0)
4295 : {
4296 : #if 0
4297 : internal_warning ("read_a_line: ignored null byte in input");
4298 : #endif
4299 : continue;
4300 : }
4301 :
4302 : /* If there is no more input, then we return NULL. */
4303 : if (c == EOF)
4304 : {
4305 : if (interactive && bash_input.type == st_stream)
4306 : clearerr (stdin);
4307 : if (indx == 0)
4308 : return ((char *)NULL);
4309 : c = '\n';
4310 : }
4311 :
4312 : /* `+2' in case the final character in the buffer is a newline. */
4313 : RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
4314 :
4315 : /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
4316 : here document with an unquoted delimiter. In this case,
4317 : the line will be expanded as if it were in double quotes.
4318 : We allow a backslash to escape the next character, but we
4319 : need to treat the backslash specially only if a backslash
4320 : quoting a backslash-newline pair appears in the line. */
4321 : if (pass_next)
4322 : {
4323 : line_buffer[indx++] = c;
4324 : pass_next = 0;
4325 : }
4326 : else if (c == '\\' && remove_quoted_newline)
4327 : {
4328 : QUIT;
4329 : peekc = yy_getc ();
4330 : if (peekc == '\n')
4331 : {
4332 : line_number++;
4333 : continue; /* Make the unquoted \<newline> pair disappear. */
4334 : }
4335 : else
4336 : {
4337 : yy_ungetc (peekc);
4338 : pass_next = 1;
4339 : line_buffer[indx++] = c; /* Preserve the backslash. */
4340 : }
4341 : }
4342 : else
4343 : line_buffer[indx++] = c;
4344 :
4345 : if (c == '\n')
4346 : {
4347 : line_buffer[indx] = '\0';
4348 : return (line_buffer);
4349 : }
4350 : }
4351 : }
4352 :
4353 : /* Return a line as in read_a_line (), but insure that the prompt is
4354 : the secondary prompt. This is used to read the lines of a here
4355 : document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
4356 : newlines quoted with backslashes while reading the line. It is
4357 : non-zero unless the delimiter of the here document was quoted. */
4358 : char *
4359 : read_secondary_line (remove_quoted_newline)
4360 : int remove_quoted_newline;
4361 : {
4362 : char *ret;
4363 :
4364 : prompt_string_pointer = &ps2_prompt;
4365 : if (SHOULD_PROMPT())
4366 : prompt_again ();
4367 : ret = read_a_line (remove_quoted_newline);
4368 : #if defined (HISTORY)
4369 : if (ret && remember_on_history && (parser_state & PST_HEREDOC))
4370 : {
4371 : /* To make adding the here-document body right, we need to rely on
4372 : history_delimiting_chars() returning \n for the first line of the
4373 : here-document body and the null string for the second and subsequent
4374 : lines, so we avoid double newlines.
4375 : current_command_line_count == 2 for the first line of the body. */
4376 :
4377 : current_command_line_count++;
4378 : maybe_add_history (ret);
4379 : }
4380 : #endif /* HISTORY */
4381 : return ret;
4382 : }
4383 :
4384 : /* **************************************************************** */
4385 : /* */
4386 : /* YYLEX () */
4387 : /* */
4388 : /* **************************************************************** */
4389 :
4390 : /* Reserved words. These are only recognized as the first word of a
4391 : command. */
4392 : STRING_INT_ALIST word_token_alist[] = {
4393 : { "if", IF },
4394 : { "then", THEN },
4395 : { "else", ELSE },
4396 : { "elif", ELIF },
4397 : { "fi", FI },
4398 : { "case", CASE },
4399 : { "esac", ESAC },
4400 : { "for", FOR },
4401 : #if defined (SELECT_COMMAND)
4402 : { "select", SELECT },
4403 : #endif
4404 : { "while", WHILE },
4405 : { "until", UNTIL },
4406 : { "do", DO },
4407 : { "done", DONE },
4408 : { "in", IN },
4409 : { "function", FUNCTION },
4410 : #if defined (COMMAND_TIMING)
4411 : { "time", TIME },
4412 : #endif
4413 : { "{", '{' },
4414 : { "}", '}' },
4415 : { "!", BANG },
4416 : #if defined (COND_COMMAND)
4417 : { "[[", COND_START },
4418 : { "]]", COND_END },
4419 : #endif
4420 : #if defined (COPROCESS_SUPPORT)
4421 : { "coproc", COPROC },
4422 : #endif
4423 : { (char *)NULL, 0}
4424 : };
4425 :
4426 : /* other tokens that can be returned by read_token() */
4427 : STRING_INT_ALIST other_token_alist[] = {
4428 : /* Multiple-character tokens with special values */
4429 : { "--", TIMEIGN },
4430 : { "-p", TIMEOPT },
4431 : { "&&", AND_AND },
4432 : { "||", OR_OR },
4433 : { ">>", GREATER_GREATER },
4434 : { "<<", LESS_LESS },
4435 : { "<&", LESS_AND },
4436 : { ">&", GREATER_AND },
4437 : { ";;", SEMI_SEMI },
4438 : { ";&", SEMI_AND },
4439 : { ";;&", SEMI_SEMI_AND },
4440 : { "<<-", LESS_LESS_MINUS },
4441 : { "<<<", LESS_LESS_LESS },
4442 : { "&>", AND_GREATER },
4443 : { "&>>", AND_GREATER_GREATER },
4444 : { "<>", LESS_GREATER },
4445 : { ">|", GREATER_BAR },
4446 : { "|&", BAR_AND },
4447 : { "EOF", yacc_EOF },
4448 : /* Tokens whose value is the character itself */
4449 : { ">", '>' },
4450 : { "<", '<' },
4451 : { "-", '-' },
4452 : { "{", '{' },
4453 : { "}", '}' },
4454 : { ";", ';' },
4455 : { "(", '(' },
4456 : { ")", ')' },
4457 : { "|", '|' },
4458 : { "&", '&' },
4459 : { "newline", '\n' },
4460 : { (char *)NULL, 0}
4461 : };
4462 :
4463 : /* others not listed here:
4464 : WORD look at yylval.word
4465 : ASSIGNMENT_WORD look at yylval.word
4466 : NUMBER look at yylval.number
4467 : ARITH_CMD look at yylval.word_list
4468 : ARITH_FOR_EXPRS look at yylval.word_list
4469 : COND_CMD look at yylval.command
4470 : */
4471 :
4472 : /* These are used by read_token_word, but appear up here so that shell_getc
4473 : can use them to decide when to add otherwise blank lines to the history. */
4474 :
4475 : /* The primary delimiter stack. */
4476 : struct dstack dstack = { (char *)NULL, 0, 0 };
4477 :
4478 : /* A temporary delimiter stack to be used when decoding prompt strings.
4479 : This is needed because command substitutions in prompt strings (e.g., PS2)
4480 : can screw up the parser's quoting state. */
4481 : static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
4482 :
4483 : /* Macro for accessing the top delimiter on the stack. Returns the
4484 : delimiter or zero if none. */
4485 : #define current_delimiter(ds) \
4486 : (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
4487 :
4488 : #define push_delimiter(ds, character) \
4489 : do \
4490 : { \
4491 : if (ds.delimiter_depth + 2 > ds.delimiter_space) \
4492 : ds.delimiters = (char *)xrealloc \
4493 : (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
4494 : ds.delimiters[ds.delimiter_depth] = character; \
4495 : ds.delimiter_depth++; \
4496 : } \
4497 : while (0)
4498 :
4499 : #define pop_delimiter(ds) ds.delimiter_depth--
4500 :
4501 : /* Return the next shell input character. This always reads characters
4502 : from shell_input_line; when that line is exhausted, it is time to
4503 : read the next line. This is called by read_token when the shell is
4504 : processing normal command input. */
4505 :
4506 : /* This implements one-character lookahead/lookbehind across physical input
4507 : lines, to avoid something being lost because it's pushed back with
4508 : shell_ungetc when we're at the start of a line. */
4509 : static int eol_ungetc_lookahead = 0;
4510 :
4511 : static int
4512 : shell_getc (remove_quoted_newline)
4513 : int remove_quoted_newline;
4514 : {
4515 : register int i;
4516 : int c, truncating, last_was_backslash;
4517 : unsigned char uc;
4518 :
4519 : QUIT;
4520 :
4521 : last_was_backslash = 0;
4522 : if (sigwinch_received)
4523 : {
4524 : sigwinch_received = 0;
4525 : get_new_window_size (0, (int *)0, (int *)0);
4526 : }
4527 :
4528 : if (eol_ungetc_lookahead)
4529 : {
4530 : c = eol_ungetc_lookahead;
4531 : eol_ungetc_lookahead = 0;
4532 : return (c);
4533 : }
4534 :
4535 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4536 : /* If shell_input_line[shell_input_line_index] == 0, but there is
4537 : something on the pushed list of strings, then we don't want to go
4538 : off and get another line. We let the code down below handle it. */
4539 :
4540 : if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
4541 : (pushed_string_list == (STRING_SAVER *)NULL)))
4542 : #else /* !ALIAS && !DPAREN_ARITHMETIC */
4543 : if (!shell_input_line || !shell_input_line[shell_input_line_index])
4544 : #endif /* !ALIAS && !DPAREN_ARITHMETIC */
4545 : {
4546 : line_number++;
4547 :
4548 : /* Let's not let one really really long line blow up memory allocation */
4549 : if (shell_input_line && shell_input_line_size >= 32768)
4550 : {
4551 : free (shell_input_line);
4552 : shell_input_line = 0;
4553 : shell_input_line_size = 0;
4554 : }
4555 :
4556 : restart_read:
4557 :
4558 : /* Allow immediate exit if interrupted during input. */
4559 : QUIT;
4560 :
4561 : i = truncating = 0;
4562 : shell_input_line_terminator = 0;
4563 :
4564 : /* If the shell is interatctive, but not currently printing a prompt
4565 : (interactive_shell && interactive == 0), we don't want to print
4566 : notifies or cleanup the jobs -- we want to defer it until we do
4567 : print the next prompt. */
4568 : if (interactive_shell == 0 || SHOULD_PROMPT())
4569 : {
4570 : #if defined (JOB_CONTROL)
4571 : /* This can cause a problem when reading a command as the result
4572 : of a trap, when the trap is called from flush_child. This call
4573 : had better not cause jobs to disappear from the job table in
4574 : that case, or we will have big trouble. */
4575 : notify_and_cleanup ();
4576 : #else /* !JOB_CONTROL */
4577 : cleanup_dead_jobs ();
4578 : #endif /* !JOB_CONTROL */
4579 : }
4580 :
4581 : #if defined (READLINE)
4582 : if (no_line_editing && SHOULD_PROMPT())
4583 : #else
4584 : if (SHOULD_PROMPT())
4585 : #endif
4586 : print_prompt ();
4587 :
4588 : if (bash_input.type == st_stream)
4589 : clearerr (stdin);
4590 :
4591 : while (1)
4592 : {
4593 : c = yy_getc ();
4594 :
4595 : /* Allow immediate exit if interrupted during input. */
4596 : QUIT;
4597 :
4598 : if (c == '\0')
4599 : {
4600 : #if 0
4601 : internal_warning ("shell_getc: ignored null byte in input");
4602 : #endif
4603 : continue;
4604 : }
4605 :
4606 : /* Theoretical overflow */
4607 : /* If we can't put 256 bytes more into the buffer, allocate
4608 : everything we can and fill it as full as we can. */
4609 : /* XXX - we ignore rest of line using `truncating' flag */
4610 : if (shell_input_line_size > (SIZE_MAX - 256))
4611 : {
4612 : size_t n;
4613 :
4614 : n = SIZE_MAX - i; /* how much more can we put into the buffer? */
4615 : if (n <= 2) /* we have to save 1 for the newline added below */
4616 : {
4617 : if (truncating == 0)
4618 : internal_warning(_("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%lu): line truncated"), shell_input_line_size, (unsigned long)SIZE_MAX);
4619 : shell_input_line[i] = '\0';
4620 : truncating = 1;
4621 : }
4622 : if (shell_input_line_size < SIZE_MAX)
4623 : {
4624 : shell_input_line_size = SIZE_MAX;
4625 : shell_input_line = xrealloc (shell_input_line, shell_input_line_size);
4626 : }
4627 : }
4628 : else
4629 : RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
4630 :
4631 : if (c == EOF)
4632 : {
4633 : if (bash_input.type == st_stream)
4634 : clearerr (stdin);
4635 :
4636 : if (i == 0)
4637 : shell_input_line_terminator = EOF;
4638 :
4639 : shell_input_line[i] = '\0';
4640 : break;
4641 : }
4642 :
4643 : if (truncating == 0 || c == '\n')
4644 : shell_input_line[i++] = c;
4645 :
4646 : if (c == '\n')
4647 : {
4648 : shell_input_line[--i] = '\0';
4649 : current_command_line_count++;
4650 : break;
4651 : }
4652 :
4653 : last_was_backslash = last_was_backslash == 0 && c == '\\';
4654 : }
4655 :
4656 : shell_input_line_index = 0;
4657 : shell_input_line_len = i; /* == strlen (shell_input_line) */
4658 :
4659 : set_line_mbstate ();
4660 :
4661 : #if defined (HISTORY)
4662 : if (remember_on_history && shell_input_line && shell_input_line[0])
4663 : {
4664 : char *expansions;
4665 : # if defined (BANG_HISTORY)
4666 : int old_hist;
4667 :
4668 : /* If the current delimiter is a single quote, we should not be
4669 : performing history expansion, even if we're on a different
4670 : line from the original single quote. */
4671 : old_hist = history_expansion_inhibited;
4672 : if (current_delimiter (dstack) == '\'')
4673 : history_expansion_inhibited = 1;
4674 : # endif
4675 : /* Calling with a third argument of 1 allows remember_on_history to
4676 : determine whether or not the line is saved to the history list */
4677 : expansions = pre_process_line (shell_input_line, 1, 1);
4678 : # if defined (BANG_HISTORY)
4679 : history_expansion_inhibited = old_hist;
4680 : # endif
4681 : if (expansions != shell_input_line)
4682 : {
4683 : free (shell_input_line);
4684 : shell_input_line = expansions;
4685 : shell_input_line_len = shell_input_line ?
4686 : strlen (shell_input_line) : 0;
4687 : if (shell_input_line_len == 0)
4688 : current_command_line_count--;
4689 :
4690 : /* We have to force the xrealloc below because we don't know
4691 : the true allocated size of shell_input_line anymore. */
4692 : shell_input_line_size = shell_input_line_len;
4693 :
4694 : set_line_mbstate ();
4695 : }
4696 : }
4697 : /* Try to do something intelligent with blank lines encountered while
4698 : entering multi-line commands. XXX - this is grotesque */
4699 : else if (remember_on_history && shell_input_line &&
4700 : shell_input_line[0] == '\0' &&
4701 : current_command_line_count > 1)
4702 : {
4703 : if (current_delimiter (dstack))
4704 : /* We know shell_input_line[0] == 0 and we're reading some sort of
4705 : quoted string. This means we've got a line consisting of only
4706 : a newline in a quoted string. We want to make sure this line
4707 : gets added to the history. */
4708 : maybe_add_history (shell_input_line);
4709 : else
4710 : {
4711 : char *hdcs;
4712 : hdcs = history_delimiting_chars (shell_input_line);
4713 : if (hdcs && hdcs[0] == ';')
4714 : maybe_add_history (shell_input_line);
4715 : }
4716 : }
4717 :
4718 : #endif /* HISTORY */
4719 :
4720 : if (shell_input_line)
4721 : {
4722 : /* Lines that signify the end of the shell's input should not be
4723 : echoed. We should not echo lines while parsing command
4724 : substitutions with recursive calls into the parsing engine; those
4725 : should only be echoed once when we read the word. That is the
4726 : reason for the test against shell_eof_token, which is set to a
4727 : right paren when parsing the contents of command substitutions. */
4728 : if (echo_input_at_read && (shell_input_line[0] ||
4729 : shell_input_line_terminator != EOF) &&
4730 : shell_eof_token == 0)
4731 : fprintf (stderr, "%s\n", shell_input_line);
4732 : }
4733 : else
4734 : {
4735 : shell_input_line_size = 0;
4736 : prompt_string_pointer = ¤t_prompt_string;
4737 : if (SHOULD_PROMPT ())
4738 : prompt_again ();
4739 : goto restart_read;
4740 : }
4741 :
4742 : /* Add the newline to the end of this string, iff the string does
4743 : not already end in an EOF character. */
4744 : if (shell_input_line_terminator != EOF)
4745 : {
4746 : if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size))
4747 : shell_input_line = (char *)xrealloc (shell_input_line,
4748 : 1 + (shell_input_line_size += 2));
4749 :
4750 : /* Don't add a newline to a string that ends with a backslash if we're
4751 : going to be removing quoted newlines, since that will eat the
4752 : backslash. Add another backslash instead (will be removed by
4753 : word expansion). */
4754 : if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
4755 : shell_input_line[shell_input_line_len] = '\\';
4756 : else
4757 : shell_input_line[shell_input_line_len] = '\n';
4758 : shell_input_line[shell_input_line_len + 1] = '\0';
4759 :
4760 : set_line_mbstate ();
4761 : }
4762 : }
4763 :
4764 : next_alias_char:
4765 : uc = shell_input_line[shell_input_line_index];
4766 :
4767 : if (uc)
4768 : shell_input_line_index++;
4769 :
4770 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4771 : /* If UC is NULL, we have reached the end of the current input string. If
4772 : pushed_string_list is non-empty, it's time to pop to the previous string
4773 : because we have fully consumed the result of the last alias expansion.
4774 : Do it transparently; just return the next character of the string popped
4775 : to. */
4776 : /* If pushed_string_list != 0 but pushed_string_list->expander == 0 (not
4777 : currently tested) and the flags value is not PSH_SOURCE, we are not
4778 : parsing an alias, we have just saved one (push_string, when called by
4779 : the parse_dparen code) In this case, just go on as well. The PSH_SOURCE
4780 : case is handled below. */
4781 : pop_alias:
4782 : if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE)
4783 : {
4784 : pop_string ();
4785 : uc = shell_input_line[shell_input_line_index];
4786 : if (uc)
4787 : shell_input_line_index++;
4788 : }
4789 : #endif /* ALIAS || DPAREN_ARITHMETIC */
4790 :
4791 : if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
4792 : {
4793 : if (SHOULD_PROMPT ())
4794 : prompt_again ();
4795 : line_number++;
4796 : /* What do we do here if we're expanding an alias whose definition
4797 : includes an escaped newline? If that's the last character in the
4798 : alias expansion, we just pop the pushed string list (recall that
4799 : we inhibit the appending of a space in mk_alexpansion() if newline
4800 : is the last character). If it's not the last character, we need
4801 : to consume the quoted newline and move to the next character in
4802 : the expansion. */
4803 : #if defined (ALIAS)
4804 : if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
4805 : {
4806 : uc = 0;
4807 : goto pop_alias;
4808 : }
4809 : else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0')
4810 : {
4811 : shell_input_line_index++; /* skip newline */
4812 : goto next_alias_char; /* and get next character */
4813 : }
4814 : else
4815 : #endif
4816 : goto restart_read;
4817 : }
4818 :
4819 : if (uc == 0 && shell_input_line_terminator == EOF)
4820 : return ((shell_input_line_index != 0) ? '\n' : EOF);
4821 :
4822 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
4823 : /* We already know that we are not parsing an alias expansion because of the
4824 : check for expanding_alias() above. This knows how parse_and_execute
4825 : handles switching to st_string input while an alias is being expanded,
4826 : hence the check for pushed_string_list without pushed_string_list->expander
4827 : and the check for PSH_SOURCE as pushed_string_list->flags.
4828 : parse_and_execute and parse_string both change the input type to st_string
4829 : and place the string to be parsed and executed into location.string, so
4830 : we should not stop reading that until the pointer is '\0'.
4831 : The check for shell_input_line_terminator may be superfluous.
4832 :
4833 : This solves the problem of `.' inside a multi-line alias with embedded
4834 : newlines executing things out of order. */
4835 : if (uc == 0 && bash_input.type == st_string && *bash_input.location.string &&
4836 : pushed_string_list && pushed_string_list->flags == PSH_SOURCE &&
4837 : shell_input_line_terminator == 0)
4838 : {
4839 : shell_input_line_index = 0;
4840 : goto restart_read;
4841 : }
4842 : #endif
4843 :
4844 : return (uc);
4845 : }
4846 :
4847 : /* Put C back into the input for the shell. This might need changes for
4848 : HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a
4849 : character different than we read, shell_input_line_property doesn't need
4850 : to change when manipulating shell_input_line. The define for
4851 : last_shell_getc_is_singlebyte should take care of it, though. */
4852 : static void
4853 : shell_ungetc (c)
4854 : int c;
4855 : {
4856 : if (shell_input_line && shell_input_line_index)
4857 : shell_input_line[--shell_input_line_index] = c;
4858 : else
4859 : eol_ungetc_lookahead = c;
4860 : }
4861 :
4862 : char *
4863 : parser_remaining_input ()
4864 : {
4865 : if (shell_input_line == 0)
4866 : return 0;
4867 : if (shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len)
4868 : return ""; /* XXX */
4869 : return (shell_input_line + shell_input_line_index);
4870 : }
4871 :
4872 : #ifdef INCLUDE_UNUSED
4873 : /* Back the input pointer up by one, effectively `ungetting' a character. */
4874 : static void
4875 : shell_ungetchar ()
4876 : {
4877 : if (shell_input_line && shell_input_line_index)
4878 : shell_input_line_index--;
4879 : }
4880 : #endif
4881 :
4882 : /* Discard input until CHARACTER is seen, then push that character back
4883 : onto the input stream. */
4884 : static void
4885 : discard_until (character)
4886 : int character;
4887 : {
4888 : int c;
4889 :
4890 : while ((c = shell_getc (0)) != EOF && c != character)
4891 : ;
4892 :
4893 : if (c != EOF)
4894 : shell_ungetc (c);
4895 : }
4896 :
4897 : void
4898 : execute_variable_command (command, vname)
4899 : char *command, *vname;
4900 : {
4901 : char *last_lastarg;
4902 : sh_parser_state_t ps;
4903 :
4904 : save_parser_state (&ps);
4905 : last_lastarg = get_string_value ("_");
4906 : if (last_lastarg)
4907 : last_lastarg = savestring (last_lastarg);
4908 :
4909 : parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
4910 :
4911 : restore_parser_state (&ps);
4912 : bind_variable ("_", last_lastarg, 0);
4913 : FREE (last_lastarg);
4914 :
4915 : if (token_to_read == '\n') /* reset_parser was called */
4916 : token_to_read = 0;
4917 : }
4918 :
4919 : void
4920 : push_token (x)
4921 : int x;
4922 : {
4923 : two_tokens_ago = token_before_that;
4924 : token_before_that = last_read_token;
4925 : last_read_token = current_token;
4926 :
4927 : current_token = x;
4928 : }
4929 :
4930 : /* Place to remember the token. We try to keep the buffer
4931 : at a reasonable size, but it can grow. */
4932 : static char *token = (char *)NULL;
4933 :
4934 : /* Current size of the token buffer. */
4935 : static int token_buffer_size;
4936 :
4937 : /* Command to read_token () explaining what we want it to do. */
4938 : #define READ 0
4939 : #define RESET 1
4940 : #define prompt_is_ps1 \
4941 : (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
4942 :
4943 : /* Function for yyparse to call. yylex keeps track of
4944 : the last two tokens read, and calls read_token. */
4945 : static int
4946 : yylex ()
4947 : {
4948 : if (interactive && (current_token == 0 || current_token == '\n'))
4949 : {
4950 : /* Before we print a prompt, we might have to check mailboxes.
4951 : We do this only if it is time to do so. Notice that only here
4952 : is the mail alarm reset; nothing takes place in check_mail ()
4953 : except the checking of mail. Please don't change this. */
4954 : if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
4955 : {
4956 : check_mail ();
4957 : reset_mail_timer ();
4958 : }
4959 :
4960 : /* Avoid printing a prompt if we're not going to read anything, e.g.
4961 : after resetting the parser with read_token (RESET). */
4962 : if (token_to_read == 0 && SHOULD_PROMPT ())
4963 : prompt_again ();
4964 : }
4965 :
4966 : two_tokens_ago = token_before_that;
4967 : token_before_that = last_read_token;
4968 : last_read_token = current_token;
4969 : current_token = read_token (READ);
4970 :
4971 : if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
4972 : {
4973 : current_token = yacc_EOF;
4974 : if (bash_input.type == st_string)
4975 : rewind_input_string ();
4976 : }
4977 : parser_state &= ~PST_EOFTOKEN;
4978 :
4979 : return (current_token);
4980 : }
4981 :
4982 : /* When non-zero, we have read the required tokens
4983 : which allow ESAC to be the next one read. */
4984 : static int esacs_needed_count;
4985 :
4986 : static void
4987 : push_heredoc (r)
4988 : REDIRECT *r;
4989 : {
4990 : if (need_here_doc >= HEREDOC_MAX)
4991 : {
4992 : last_command_exit_value = EX_BADUSAGE;
4993 : need_here_doc = 0;
4994 : report_syntax_error (_("maximum here-document count exceeded"));
4995 : reset_parser ();
4996 : exit_shell (last_command_exit_value);
4997 : }
4998 : redir_stack[need_here_doc++] = r;
4999 : }
5000 :
5001 : void
5002 : gather_here_documents ()
5003 : {
5004 : int r;
5005 :
5006 : r = 0;
5007 : here_doc_first_line = 1;
5008 : while (need_here_doc > 0)
5009 : {
5010 : parser_state |= PST_HEREDOC;
5011 : make_here_document (redir_stack[r++], line_number);
5012 : parser_state &= ~PST_HEREDOC;
5013 : need_here_doc--;
5014 : redir_stack[r - 1] = 0; /* XXX */
5015 : }
5016 : here_doc_first_line = 0; /* just in case */
5017 : }
5018 :
5019 : /* When non-zero, an open-brace used to create a group is awaiting a close
5020 : brace partner. */
5021 : static int open_brace_count;
5022 :
5023 : /* In the following three macros, `token' is always last_read_token */
5024 :
5025 : /* Are we in the middle of parsing a redirection where we are about to read
5026 : a word? This is used to make sure alias expansion doesn't happen in the
5027 : middle of a redirection, even though we're parsing a simple command. */
5028 : #define parsing_redirection(token) \
5029 : (token == '<' || token == '>' || \
5030 : token == GREATER_GREATER || token == GREATER_BAR || \
5031 : token == LESS_GREATER || token == LESS_LESS_MINUS || \
5032 : token == LESS_LESS || token == LESS_LESS_LESS || \
5033 : token == LESS_AND || token == GREATER_AND || token == AND_GREATER)
5034 :
5035 : /* Is `token' one that will allow a WORD to be read in a command position?
5036 : We can read a simple command name on which we should attempt alias expansion
5037 : or we can read an assignment statement. */
5038 : #define command_token_position(token) \
5039 : (((token) == ASSIGNMENT_WORD) || \
5040 : ((parser_state&PST_REDIRLIST) && parsing_redirection(token) == 0) || \
5041 : ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
5042 :
5043 : /* Are we in a position where we can read an assignment statement? */
5044 : #define assignment_acceptable(token) \
5045 : (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
5046 :
5047 : /* Check to see if TOKEN is a reserved word and return the token
5048 : value if it is. */
5049 : #define CHECK_FOR_RESERVED_WORD(tok) \
5050 : do { \
5051 : if (!dollar_present && !quoted && \
5052 : reserved_word_acceptable (last_read_token)) \
5053 : { \
5054 : int i; \
5055 : for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
5056 : if (STREQ (tok, word_token_alist[i].word)) \
5057 : { \
5058 : if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
5059 : break; \
5060 : if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
5061 : break; \
5062 : if ((parser_state & PST_CASEPAT) && last_read_token == '|' && word_token_alist[i].token == ESAC) \
5063 : break; /* Posix grammar rule 4 */ \
5064 : if (word_token_alist[i].token == ESAC) \
5065 : parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
5066 : else if (word_token_alist[i].token == CASE) \
5067 : parser_state |= PST_CASESTMT; \
5068 : else if (word_token_alist[i].token == COND_END) \
5069 : parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
5070 : else if (word_token_alist[i].token == COND_START) \
5071 : parser_state |= PST_CONDCMD; \
5072 : else if (word_token_alist[i].token == '{') \
5073 : open_brace_count++; \
5074 : else if (word_token_alist[i].token == '}' && open_brace_count) \
5075 : open_brace_count--; \
5076 : return (word_token_alist[i].token); \
5077 : } \
5078 : } \
5079 : } while (0)
5080 :
5081 : #if defined (ALIAS)
5082 :
5083 : /* OK, we have a token. Let's try to alias expand it, if (and only if)
5084 : it's eligible.
5085 :
5086 : It is eligible for expansion if EXPAND_ALIASES is set, and
5087 : the token is unquoted and the last token read was a command
5088 : separator (or expand_next_token is set), and we are currently
5089 : processing an alias (pushed_string_list is non-empty) and this
5090 : token is not the same as the current or any previously
5091 : processed alias.
5092 :
5093 : Special cases that disqualify:
5094 : In a pattern list in a case statement (parser_state & PST_CASEPAT). */
5095 :
5096 : static char *
5097 : mk_alexpansion (s)
5098 : char *s;
5099 : {
5100 : int l;
5101 : char *r;
5102 :
5103 : l = strlen (s);
5104 : r = xmalloc (l + 2);
5105 : strcpy (r, s);
5106 : /* If the last character in the alias is a newline, don't add a trailing
5107 : space to the expansion. Works with shell_getc above. */
5108 : if (r[l - 1] != ' ' && r[l - 1] != '\n' && shellmeta(r[l - 1]) == 0)
5109 : r[l++] = ' ';
5110 : r[l] = '\0';
5111 : return r;
5112 : }
5113 :
5114 : static int
5115 : alias_expand_token (tokstr)
5116 : char *tokstr;
5117 : {
5118 : char *expanded;
5119 : alias_t *ap;
5120 :
5121 : if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
5122 : (parser_state & PST_CASEPAT) == 0)
5123 : {
5124 : ap = find_alias (tokstr);
5125 :
5126 : /* Currently expanding this token. */
5127 : if (ap && (ap->flags & AL_BEINGEXPANDED))
5128 : return (NO_EXPANSION);
5129 :
5130 : /* mk_alexpansion puts an extra space on the end of the alias expansion,
5131 : so the lookahead by the parser works right. If this gets changed,
5132 : make sure the code in shell_getc that deals with reaching the end of
5133 : an expanded alias is changed with it. */
5134 : expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
5135 :
5136 : if (expanded)
5137 : {
5138 : push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
5139 : return (RE_READ_TOKEN);
5140 : }
5141 : else
5142 : /* This is an eligible token that does not have an expansion. */
5143 : return (NO_EXPANSION);
5144 : }
5145 : return (NO_EXPANSION);
5146 : }
5147 : #endif /* ALIAS */
5148 :
5149 : static int
5150 : time_command_acceptable ()
5151 : {
5152 : #if defined (COMMAND_TIMING)
5153 : int i;
5154 :
5155 : if (posixly_correct && shell_compatibility_level > 41)
5156 : {
5157 : /* Quick check of the rest of the line to find the next token. If it
5158 : begins with a `-', Posix says to not return `time' as the token.
5159 : This was interp 267. */
5160 : i = shell_input_line_index;
5161 : while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
5162 : i++;
5163 : if (shell_input_line[i] == '-')
5164 : return 0;
5165 : }
5166 :
5167 : switch (last_read_token)
5168 : {
5169 : case 0:
5170 : case ';':
5171 : case '\n':
5172 : if (token_before_that == '|')
5173 : return (0);
5174 : /* FALLTHROUGH */
5175 : case AND_AND:
5176 : case OR_OR:
5177 : case '&':
5178 : case WHILE:
5179 : case DO:
5180 : case UNTIL:
5181 : case IF:
5182 : case THEN:
5183 : case ELIF:
5184 : case ELSE:
5185 : case '{': /* } */
5186 : case '(': /* )( */
5187 : case ')': /* only valid in case statement */
5188 : case BANG: /* ! time pipeline */
5189 : case TIME: /* time time pipeline */
5190 : case TIMEOPT: /* time -p time pipeline */
5191 : case TIMEIGN: /* time -p -- ... */
5192 : return 1;
5193 : default:
5194 : return 0;
5195 : }
5196 : #else
5197 : return 0;
5198 : #endif /* COMMAND_TIMING */
5199 : }
5200 :
5201 : /* Handle special cases of token recognition:
5202 : IN is recognized if the last token was WORD and the token
5203 : before that was FOR or CASE or SELECT.
5204 :
5205 : DO is recognized if the last token was WORD and the token
5206 : before that was FOR or SELECT.
5207 :
5208 : ESAC is recognized if the last token caused `esacs_needed_count'
5209 : to be set
5210 :
5211 : `{' is recognized if the last token as WORD and the token
5212 : before that was FUNCTION, or if we just parsed an arithmetic
5213 : `for' command.
5214 :
5215 : `}' is recognized if there is an unclosed `{' present.
5216 :
5217 : `-p' is returned as TIMEOPT if the last read token was TIME.
5218 : `--' is returned as TIMEIGN if the last read token was TIMEOPT.
5219 :
5220 : ']]' is returned as COND_END if the parser is currently parsing
5221 : a conditional expression ((parser_state & PST_CONDEXPR) != 0)
5222 :
5223 : `time' is returned as TIME if and only if it is immediately
5224 : preceded by one of `;', `\n', `||', `&&', or `&'.
5225 : */
5226 :
5227 : static int
5228 : special_case_tokens (tokstr)
5229 : char *tokstr;
5230 : {
5231 : if ((last_read_token == WORD) &&
5232 : #if defined (SELECT_COMMAND)
5233 : ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
5234 : #else
5235 : ((token_before_that == FOR) || (token_before_that == CASE)) &&
5236 : #endif
5237 : (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
5238 : {
5239 : if (token_before_that == CASE)
5240 : {
5241 : parser_state |= PST_CASEPAT;
5242 : esacs_needed_count++;
5243 : }
5244 : return (IN);
5245 : }
5246 :
5247 : if (last_read_token == WORD &&
5248 : #if defined (SELECT_COMMAND)
5249 : (token_before_that == FOR || token_before_that == SELECT) &&
5250 : #else
5251 : (token_before_that == FOR) &&
5252 : #endif
5253 : (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
5254 : return (DO);
5255 :
5256 : /* Ditto for ESAC in the CASE case.
5257 : Specifically, this handles "case word in esac", which is a legal
5258 : construct, certainly because someone will pass an empty arg to the
5259 : case construct, and we don't want it to barf. Of course, we should
5260 : insist that the case construct has at least one pattern in it, but
5261 : the designers disagree. */
5262 : if (esacs_needed_count)
5263 : {
5264 : esacs_needed_count--;
5265 : if (STREQ (tokstr, "esac"))
5266 : {
5267 : parser_state &= ~PST_CASEPAT;
5268 : return (ESAC);
5269 : }
5270 : }
5271 :
5272 : /* The start of a shell function definition. */
5273 : if (parser_state & PST_ALLOWOPNBRC)
5274 : {
5275 : parser_state &= ~PST_ALLOWOPNBRC;
5276 : if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */
5277 : {
5278 : open_brace_count++;
5279 : function_bstart = line_number;
5280 : return ('{'); /* } */
5281 : }
5282 : }
5283 :
5284 : /* We allow a `do' after a for ((...)) without an intervening
5285 : list_terminator */
5286 : if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
5287 : return (DO);
5288 : if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */
5289 : {
5290 : open_brace_count++;
5291 : return ('{'); /* } */
5292 : }
5293 :
5294 : if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
5295 : {
5296 : open_brace_count--; /* { */
5297 : return ('}');
5298 : }
5299 :
5300 : #if defined (COMMAND_TIMING)
5301 : /* Handle -p after `time'. */
5302 : if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
5303 : return (TIMEOPT);
5304 : /* Handle -- after `time -p'. */
5305 : if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
5306 : return (TIMEIGN);
5307 : #endif
5308 :
5309 : #if defined (COND_COMMAND) /* [[ */
5310 : if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
5311 : return (COND_END);
5312 : #endif
5313 :
5314 : return (-1);
5315 : }
5316 :
5317 : /* Called from shell.c when Control-C is typed at top level. Or
5318 : by the error rule at top level. */
5319 : void
5320 : reset_parser ()
5321 : {
5322 : dstack.delimiter_depth = 0; /* No delimiters found so far. */
5323 : open_brace_count = 0;
5324 :
5325 : #if defined (EXTENDED_GLOB)
5326 : /* Reset to global value of extended glob */
5327 : if (parser_state & PST_EXTPAT)
5328 : extended_glob = global_extglob;
5329 : #endif
5330 :
5331 : parser_state = 0;
5332 : here_doc_first_line = 0;
5333 :
5334 : #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
5335 : if (pushed_string_list)
5336 : free_string_list ();
5337 : #endif /* ALIAS || DPAREN_ARITHMETIC */
5338 :
5339 : /* This is where we resynchronize to the next newline on error/reset */
5340 : if (shell_input_line)
5341 : {
5342 : free (shell_input_line);
5343 : shell_input_line = (char *)NULL;
5344 : shell_input_line_size = shell_input_line_index = 0;
5345 : }
5346 :
5347 : FREE (word_desc_to_read);
5348 : word_desc_to_read = (WORD_DESC *)NULL;
5349 :
5350 : eol_ungetc_lookahead = 0;
5351 :
5352 : current_token = '\n'; /* XXX */
5353 : last_read_token = '\n';
5354 : token_to_read = '\n';
5355 : }
5356 :
5357 : /* Read the next token. Command can be READ (normal operation) or
5358 : RESET (to normalize state). */
5359 : static int
5360 : read_token (command)
5361 : int command;
5362 : {
5363 : int character; /* Current character. */
5364 : int peek_char; /* Temporary look-ahead character. */
5365 : int result; /* The thing to return. */
5366 :
5367 : if (command == RESET)
5368 : {
5369 : reset_parser ();
5370 : return ('\n');
5371 : }
5372 :
5373 : if (token_to_read)
5374 : {
5375 : result = token_to_read;
5376 : if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
5377 : {
5378 : yylval.word = word_desc_to_read;
5379 : word_desc_to_read = (WORD_DESC *)NULL;
5380 : }
5381 : token_to_read = 0;
5382 : return (result);
5383 : }
5384 :
5385 : #if defined (COND_COMMAND)
5386 : if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
5387 : {
5388 : cond_lineno = line_number;
5389 : parser_state |= PST_CONDEXPR;
5390 : yylval.command = parse_cond_command ();
5391 : if (cond_token != COND_END)
5392 : {
5393 : cond_error ();
5394 : return (-1);
5395 : }
5396 : token_to_read = COND_END;
5397 : parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
5398 : return (COND_CMD);
5399 : }
5400 : #endif
5401 :
5402 : #if defined (ALIAS)
5403 : /* This is a place to jump back to once we have successfully expanded a
5404 : token with an alias and pushed the string with push_string () */
5405 : re_read_token:
5406 : #endif /* ALIAS */
5407 :
5408 : /* Read a single word from input. Start by skipping blanks. */
5409 : while ((character = shell_getc (1)) != EOF && shellblank (character))
5410 : ;
5411 :
5412 : if (character == EOF)
5413 : {
5414 : EOF_Reached = 1;
5415 : return (yacc_EOF);
5416 : }
5417 :
5418 : if MBTEST(character == '#' && (!interactive || interactive_comments))
5419 : {
5420 : /* A comment. Discard until EOL or EOF, and then return a newline. */
5421 : discard_until ('\n');
5422 : shell_getc (0);
5423 : character = '\n'; /* this will take the next if statement and return. */
5424 : }
5425 :
5426 : if (character == '\n')
5427 : {
5428 : /* If we're about to return an unquoted newline, we can go and collect
5429 : the text of any pending here document. */
5430 : if (need_here_doc)
5431 : gather_here_documents ();
5432 :
5433 : #if defined (ALIAS)
5434 : parser_state &= ~PST_ALEXPNEXT;
5435 : #endif /* ALIAS */
5436 :
5437 : parser_state &= ~PST_ASSIGNOK;
5438 :
5439 : return (character);
5440 : }
5441 :
5442 : if (parser_state & PST_REGEXP)
5443 : goto tokword;
5444 :
5445 : /* Shell meta-characters. */
5446 : if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
5447 : {
5448 : #if defined (ALIAS)
5449 : /* Turn off alias tokenization iff this character sequence would
5450 : not leave us ready to read a command. */
5451 : if (character == '<' || character == '>')
5452 : parser_state &= ~PST_ALEXPNEXT;
5453 : #endif /* ALIAS */
5454 :
5455 : parser_state &= ~PST_ASSIGNOK;
5456 :
5457 : /* If we are parsing a command substitution and we have read a character
5458 : that marks the end of it, don't bother to skip over quoted newlines
5459 : when we read the next token. We're just interested in a character
5460 : that will turn this into a two-character token, so we let the higher
5461 : layers deal with quoted newlines following the command substitution. */
5462 : if ((parser_state & PST_CMDSUBST) && character == shell_eof_token)
5463 : peek_char = shell_getc (0);
5464 : else
5465 : peek_char = shell_getc (1);
5466 :
5467 : if (character == peek_char)
5468 : {
5469 : switch (character)
5470 : {
5471 : case '<':
5472 : /* If '<' then we could be at "<<" or at "<<-". We have to
5473 : look ahead one more character. */
5474 : peek_char = shell_getc (1);
5475 : if MBTEST(peek_char == '-')
5476 : return (LESS_LESS_MINUS);
5477 : else if MBTEST(peek_char == '<')
5478 : return (LESS_LESS_LESS);
5479 : else
5480 : {
5481 : shell_ungetc (peek_char);
5482 : return (LESS_LESS);
5483 : }
5484 :
5485 : case '>':
5486 : return (GREATER_GREATER);
5487 :
5488 : case ';':
5489 : parser_state |= PST_CASEPAT;
5490 : #if defined (ALIAS)
5491 : parser_state &= ~PST_ALEXPNEXT;
5492 : #endif /* ALIAS */
5493 :
5494 : peek_char = shell_getc (1);
5495 : if MBTEST(peek_char == '&')
5496 : return (SEMI_SEMI_AND);
5497 : else
5498 : {
5499 : shell_ungetc (peek_char);
5500 : return (SEMI_SEMI);
5501 : }
5502 :
5503 : case '&':
5504 : return (AND_AND);
5505 :
5506 : case '|':
5507 : return (OR_OR);
5508 :
5509 : #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
5510 : case '(': /* ) */
5511 : result = parse_dparen (character);
5512 : if (result == -2)
5513 : break;
5514 : else
5515 : return result;
5516 : #endif
5517 : }
5518 : }
5519 : else if MBTEST(character == '<' && peek_char == '&')
5520 : return (LESS_AND);
5521 : else if MBTEST(character == '>' && peek_char == '&')
5522 : return (GREATER_AND);
5523 : else if MBTEST(character == '<' && peek_char == '>')
5524 : return (LESS_GREATER);
5525 : else if MBTEST(character == '>' && peek_char == '|')
5526 : return (GREATER_BAR);
5527 : else if MBTEST(character == '&' && peek_char == '>')
5528 : {
5529 : peek_char = shell_getc (1);
5530 : if MBTEST(peek_char == '>')
5531 : return (AND_GREATER_GREATER);
5532 : else
5533 : {
5534 : shell_ungetc (peek_char);
5535 : return (AND_GREATER);
5536 : }
5537 : }
5538 : else if MBTEST(character == '|' && peek_char == '&')
5539 : return (BAR_AND);
5540 : else if MBTEST(character == ';' && peek_char == '&')
5541 : {
5542 : parser_state |= PST_CASEPAT;
5543 : #if defined (ALIAS)
5544 : parser_state &= ~PST_ALEXPNEXT;
5545 : #endif /* ALIAS */
5546 : return (SEMI_AND);
5547 : }
5548 :
5549 : shell_ungetc (peek_char);
5550 :
5551 : /* If we look like we are reading the start of a function
5552 : definition, then let the reader know about it so that
5553 : we will do the right thing with `{'. */
5554 : if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
5555 : {
5556 : parser_state |= PST_ALLOWOPNBRC;
5557 : #if defined (ALIAS)
5558 : parser_state &= ~PST_ALEXPNEXT;
5559 : #endif /* ALIAS */
5560 : function_dstart = line_number;
5561 : }
5562 :
5563 : /* case pattern lists may be preceded by an optional left paren. If
5564 : we're not trying to parse a case pattern list, the left paren
5565 : indicates a subshell. */
5566 : if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
5567 : parser_state |= PST_SUBSHELL;
5568 : /*(*/
5569 : else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
5570 : parser_state &= ~PST_CASEPAT;
5571 : /*(*/
5572 : else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
5573 : parser_state &= ~PST_SUBSHELL;
5574 :
5575 : #if defined (PROCESS_SUBSTITUTION)
5576 : /* Check for the constructs which introduce process substitution.
5577 : Shells running in `posix mode' don't do process substitution. */
5578 : if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
5579 : #endif /* PROCESS_SUBSTITUTION */
5580 : return (character);
5581 : }
5582 :
5583 : /* Hack <&- (close stdin) case. Also <&N- (dup and close). */
5584 : if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
5585 : return (character);
5586 :
5587 : tokword:
5588 : /* Okay, if we got this far, we have to read a word. Read one,
5589 : and then check it against the known ones. */
5590 : result = read_token_word (character);
5591 : #if defined (ALIAS)
5592 : if (result == RE_READ_TOKEN)
5593 : goto re_read_token;
5594 : #endif
5595 : return result;
5596 : }
5597 :
5598 : /*
5599 : * Match a $(...) or other grouping construct. This has to handle embedded
5600 : * quoted strings ('', ``, "") and nested constructs. It also must handle
5601 : * reprompting the user, if necessary, after reading a newline, and returning
5602 : * correct error values if it reads EOF.
5603 : */
5604 : #define P_FIRSTCLOSE 0x0001
5605 : #define P_ALLOWESC 0x0002
5606 : #define P_DQUOTE 0x0004
5607 : #define P_COMMAND 0x0008 /* parsing a command, so look for comments */
5608 : #define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
5609 : #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
5610 : #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
5611 :
5612 : /* Lexical state while parsing a grouping construct or $(...). */
5613 : #define LEX_WASDOL 0x001
5614 : #define LEX_CKCOMMENT 0x002
5615 : #define LEX_INCOMMENT 0x004
5616 : #define LEX_PASSNEXT 0x008
5617 : #define LEX_RESWDOK 0x010
5618 : #define LEX_CKCASE 0x020
5619 : #define LEX_INCASE 0x040
5620 : #define LEX_INHEREDOC 0x080
5621 : #define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
5622 : #define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
5623 : #define LEX_QUOTEDDOC 0x400 /* here doc with quoted delim */
5624 : #define LEX_INWORD 0x800
5625 :
5626 : #define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
5627 :
5628 : #define CHECK_NESTRET_ERROR() \
5629 : do { \
5630 : if (nestret == &matched_pair_error) \
5631 : { \
5632 : free (ret); \
5633 : return &matched_pair_error; \
5634 : } \
5635 : } while (0)
5636 :
5637 : #define APPEND_NESTRET() \
5638 : do { \
5639 : if (nestlen) \
5640 : { \
5641 : RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
5642 : strcpy (ret + retind, nestret); \
5643 : retind += nestlen; \
5644 : } \
5645 : } while (0)
5646 :
5647 : static char matched_pair_error;
5648 :
5649 : static char *
5650 : parse_matched_pair (qc, open, close, lenp, flags)
5651 : int qc; /* `"' if this construct is within double quotes */
5652 : int open, close;
5653 : int *lenp, flags;
5654 : {
5655 : int count, ch, tflags;
5656 : int nestlen, ttranslen, start_lineno;
5657 : char *ret, *nestret, *ttrans;
5658 : int retind, retsize, rflags;
5659 : int dolbrace_state;
5660 :
5661 : dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
5662 :
5663 : /*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
5664 : count = 1;
5665 : tflags = 0;
5666 :
5667 : if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
5668 : tflags |= LEX_CKCOMMENT;
5669 :
5670 : /* RFLAGS is the set of flags we want to pass to recursive calls. */
5671 : rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
5672 :
5673 : ret = (char *)xmalloc (retsize = 64);
5674 : retind = 0;
5675 :
5676 : start_lineno = line_number;
5677 : while (count)
5678 : {
5679 : ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
5680 :
5681 : if (ch == EOF)
5682 : {
5683 : free (ret);
5684 : parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
5685 : EOF_Reached = 1; /* XXX */
5686 : return (&matched_pair_error);
5687 : }
5688 :
5689 : /* Possible reprompting. */
5690 : if (ch == '\n' && SHOULD_PROMPT ())
5691 : prompt_again ();
5692 :
5693 : /* Don't bother counting parens or doing anything else if in a comment
5694 : or part of a case statement */
5695 : if (tflags & LEX_INCOMMENT)
5696 : {
5697 : /* Add this character. */
5698 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
5699 : ret[retind++] = ch;
5700 :
5701 : if (ch == '\n')
5702 : tflags &= ~LEX_INCOMMENT;
5703 :
5704 : continue;
5705 : }
5706 :
5707 : /* Not exactly right yet, should handle shell metacharacters, too. If
5708 : any changes are made to this test, make analogous changes to subst.c:
5709 : extract_delimited_string(). */
5710 : else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
5711 : tflags |= LEX_INCOMMENT;
5712 :
5713 : if (tflags & LEX_PASSNEXT) /* last char was backslash */
5714 : {
5715 : tflags &= ~LEX_PASSNEXT;
5716 : if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
5717 : {
5718 : if (retind > 0)
5719 : retind--; /* swallow previously-added backslash */
5720 : continue;
5721 : }
5722 :
5723 : RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
5724 : if MBTEST(ch == CTLESC)
5725 : ret[retind++] = CTLESC;
5726 : ret[retind++] = ch;
5727 : continue;
5728 : }
5729 : /* If we're reparsing the input (e.g., from parse_string_to_word_list),
5730 : we've already prepended CTLESC to single-quoted results of $'...'.
5731 : We may want to do this for other CTLESC-quoted characters in
5732 : reparse, too. */
5733 : else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
5734 : {
5735 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
5736 : ret[retind++] = ch;
5737 : continue;
5738 : }
5739 : else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
5740 : {
5741 : RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
5742 : ret[retind++] = CTLESC;
5743 : ret[retind++] = ch;
5744 : continue;
5745 : }
5746 : else if MBTEST(ch == close) /* ending delimiter */
5747 : count--;
5748 : /* handle nested ${...} specially. */
5749 : else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
5750 : count++;
5751 : else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
5752 : count++;
5753 :
5754 : /* Add this character. */
5755 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
5756 : ret[retind++] = ch;
5757 :
5758 : /* If we just read the ending character, don't bother continuing. */
5759 : if (count == 0)
5760 : break;
5761 :
5762 : if (open == '\'') /* '' inside grouping construct */
5763 : {
5764 : if MBTEST((flags & P_ALLOWESC) && ch == '\\')
5765 : tflags |= LEX_PASSNEXT;
5766 : continue;
5767 : }
5768 :
5769 : if MBTEST(ch == '\\') /* backslashes */
5770 : tflags |= LEX_PASSNEXT;
5771 :
5772 : /* Based on which dolstate is currently in (param, op, or word),
5773 : decide what the op is. We're really only concerned if it's % or
5774 : #, so we can turn on a flag that says whether or not we should
5775 : treat single quotes as special when inside a double-quoted
5776 : ${...}. This logic must agree with subst.c:extract_dollar_brace_string
5777 : since they share the same defines. */
5778 : /* FLAG POSIX INTERP 221 */
5779 : if (flags & P_DOLBRACE)
5780 : {
5781 : /* ${param%[%]word} */
5782 : if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
5783 : dolbrace_state = DOLBRACE_QUOTE;
5784 : /* ${param#[#]word} */
5785 : else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
5786 : dolbrace_state = DOLBRACE_QUOTE;
5787 : /* ${param/[/]pat/rep} */
5788 : else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1)
5789 : dolbrace_state = DOLBRACE_QUOTE2; /* XXX */
5790 : /* ${param^[^]pat} */
5791 : else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1)
5792 : dolbrace_state = DOLBRACE_QUOTE;
5793 : /* ${param,[,]pat} */
5794 : else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
5795 : dolbrace_state = DOLBRACE_QUOTE;
5796 : else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
5797 : dolbrace_state = DOLBRACE_OP;
5798 : else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
5799 : dolbrace_state = DOLBRACE_WORD;
5800 : }
5801 :
5802 : /* The big hammer. Single quotes aren't special in double quotes. The
5803 : problem is that Posix used to say the single quotes are semi-special:
5804 : within a double-quoted ${...} construct "an even number of
5805 : unescaped double-quotes or single-quotes, if any, shall occur." */
5806 : /* This was changed in Austin Group Interp 221 */
5807 : if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
5808 : continue;
5809 :
5810 : /* Could also check open == '`' if we want to parse grouping constructs
5811 : inside old-style command substitution. */
5812 : if (open != close) /* a grouping construct */
5813 : {
5814 : if MBTEST(shellquote (ch))
5815 : {
5816 : /* '', ``, or "" inside $(...) or other grouping construct. */
5817 : push_delimiter (dstack, ch);
5818 : if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
5819 : nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
5820 : else
5821 : nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
5822 : pop_delimiter (dstack);
5823 : CHECK_NESTRET_ERROR ();
5824 :
5825 : if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
5826 : {
5827 : /* Translate $'...' here. */
5828 : ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
5829 : xfree (nestret);
5830 :
5831 : /* If we're parsing a double-quoted brace expansion and we are
5832 : not in a place where single quotes are treated specially,
5833 : make sure we single-quote the results of the ansi
5834 : expansion because quote removal should remove them later */
5835 : /* FLAG POSIX INTERP 221 */
5836 : if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE))
5837 : {
5838 : nestret = sh_single_quote (ttrans);
5839 : free (ttrans);
5840 : nestlen = strlen (nestret);
5841 : }
5842 : else if ((rflags & P_DQUOTE) == 0)
5843 : {
5844 : nestret = sh_single_quote (ttrans);
5845 : free (ttrans);
5846 : nestlen = strlen (nestret);
5847 : }
5848 : else
5849 : {
5850 : nestret = ttrans;
5851 : nestlen = ttranslen;
5852 : }
5853 : retind -= 2; /* back up before the $' */
5854 : }
5855 : else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
5856 : {
5857 : /* Locale expand $"..." here. */
5858 : ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
5859 : xfree (nestret);
5860 :
5861 : nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
5862 : free (ttrans);
5863 : nestlen = ttranslen + 2;
5864 : retind -= 2; /* back up before the $" */
5865 : }
5866 :
5867 : APPEND_NESTRET ();
5868 : FREE (nestret);
5869 : }
5870 : else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
5871 : goto parse_dollar_word;
5872 : }
5873 : /* Parse an old-style command substitution within double quotes as a
5874 : single word. */
5875 : /* XXX - sh and ksh93 don't do this - XXX */
5876 : else if MBTEST(open == '"' && ch == '`')
5877 : {
5878 : nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
5879 :
5880 : CHECK_NESTRET_ERROR ();
5881 : APPEND_NESTRET ();
5882 :
5883 : FREE (nestret);
5884 : }
5885 : else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
5886 : /* check for $(), $[], or ${} inside quoted string. */
5887 : {
5888 : parse_dollar_word:
5889 : if (open == ch) /* undo previous increment */
5890 : count--;
5891 : if (ch == '(') /* ) */
5892 : nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
5893 : else if (ch == '{') /* } */
5894 : nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
5895 : else if (ch == '[') /* ] */
5896 : nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
5897 :
5898 : CHECK_NESTRET_ERROR ();
5899 : APPEND_NESTRET ();
5900 :
5901 : FREE (nestret);
5902 : }
5903 : if MBTEST(ch == '$')
5904 : tflags |= LEX_WASDOL;
5905 : else
5906 : tflags &= ~LEX_WASDOL;
5907 : }
5908 :
5909 : ret[retind] = '\0';
5910 : if (lenp)
5911 : *lenp = retind;
5912 : /*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
5913 : return ret;
5914 : }
5915 :
5916 : #if defined (DEBUG)
5917 : static void
5918 : dump_tflags (flags)
5919 : int flags;
5920 : {
5921 : int f;
5922 :
5923 : f = flags;
5924 : fprintf (stderr, "%d -> ", f);
5925 : if (f & LEX_WASDOL)
5926 : {
5927 : f &= ~LEX_WASDOL;
5928 : fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
5929 : }
5930 : if (f & LEX_CKCOMMENT)
5931 : {
5932 : f &= ~LEX_CKCOMMENT;
5933 : fprintf (stderr, "LEX_CKCOMMENT%s", f ? "|" : "");
5934 : }
5935 : if (f & LEX_INCOMMENT)
5936 : {
5937 : f &= ~LEX_INCOMMENT;
5938 : fprintf (stderr, "LEX_INCOMMENT%s", f ? "|" : "");
5939 : }
5940 : if (f & LEX_PASSNEXT)
5941 : {
5942 : f &= ~LEX_PASSNEXT;
5943 : fprintf (stderr, "LEX_PASSNEXT%s", f ? "|" : "");
5944 : }
5945 : if (f & LEX_RESWDOK)
5946 : {
5947 : f &= ~LEX_RESWDOK;
5948 : fprintf (stderr, "LEX_RESWDOK%s", f ? "|" : "");
5949 : }
5950 : if (f & LEX_CKCASE)
5951 : {
5952 : f &= ~LEX_CKCASE;
5953 : fprintf (stderr, "LEX_CKCASE%s", f ? "|" : "");
5954 : }
5955 : if (f & LEX_INCASE)
5956 : {
5957 : f &= ~LEX_INCASE;
5958 : fprintf (stderr, "LEX_INCASE%s", f ? "|" : "");
5959 : }
5960 : if (f & LEX_INHEREDOC)
5961 : {
5962 : f &= ~LEX_INHEREDOC;
5963 : fprintf (stderr, "LEX_INHEREDOC%s", f ? "|" : "");
5964 : }
5965 : if (f & LEX_HEREDELIM)
5966 : {
5967 : f &= ~LEX_HEREDELIM;
5968 : fprintf (stderr, "LEX_HEREDELIM%s", f ? "|" : "");
5969 : }
5970 : if (f & LEX_STRIPDOC)
5971 : {
5972 : f &= ~LEX_STRIPDOC;
5973 : fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
5974 : }
5975 : if (f & LEX_QUOTEDDOC)
5976 : {
5977 : f &= ~LEX_QUOTEDDOC;
5978 : fprintf (stderr, "LEX_QUOTEDDOC%s", f ? "|" : "");
5979 : }
5980 : if (f & LEX_INWORD)
5981 : {
5982 : f &= ~LEX_INWORD;
5983 : fprintf (stderr, "LEX_INWORD%s", f ? "|" : "");
5984 : }
5985 :
5986 : fprintf (stderr, "\n");
5987 : fflush (stderr);
5988 : }
5989 : #endif
5990 :
5991 : /* Parse a $(...) command substitution. This is messier than I'd like, and
5992 : reproduces a lot more of the token-reading code than I'd like. */
5993 : static char *
5994 : parse_comsub (qc, open, close, lenp, flags)
5995 : int qc; /* `"' if this construct is within double quotes */
5996 : int open, close;
5997 : int *lenp, flags;
5998 : {
5999 : int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
6000 : int nestlen, ttranslen, start_lineno;
6001 : char *ret, *nestret, *ttrans, *heredelim;
6002 : int retind, retsize, rflags, hdlen = 0;
6003 :
6004 : /* Posix interp 217 says arithmetic expressions have precedence, so
6005 : assume $(( introduces arithmetic expansion and parse accordingly. */
6006 : peekc = shell_getc (0);
6007 : shell_ungetc (peekc);
6008 : if (peekc == '(')
6009 : return (parse_matched_pair (qc, open, close, lenp, 0));
6010 :
6011 : /*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
6012 : count = 1;
6013 : tflags = LEX_RESWDOK;
6014 :
6015 : if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
6016 : tflags |= LEX_CKCASE;
6017 : if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
6018 : tflags |= LEX_CKCOMMENT;
6019 :
6020 : /* RFLAGS is the set of flags we want to pass to recursive calls. */
6021 : rflags = (flags & P_DQUOTE);
6022 :
6023 : ret = (char *)xmalloc (retsize = 64);
6024 : retind = 0;
6025 :
6026 : start_lineno = line_number;
6027 : lex_rwlen = lex_wlen = 0;
6028 :
6029 : heredelim = 0;
6030 : lex_firstind = -1;
6031 :
6032 : while (count)
6033 : {
6034 : ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0);
6035 :
6036 : if (ch == EOF)
6037 : {
6038 : eof_error:
6039 : free (ret);
6040 : FREE (heredelim);
6041 : parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
6042 : EOF_Reached = 1; /* XXX */
6043 : return (&matched_pair_error);
6044 : }
6045 :
6046 : /* If we hit the end of a line and are reading the contents of a here
6047 : document, and it's not the same line that the document starts on,
6048 : check for this line being the here doc delimiter. Otherwise, if
6049 : we're in a here document, mark the next character as the beginning
6050 : of a line. */
6051 : if (ch == '\n')
6052 : {
6053 : if ((tflags & LEX_HEREDELIM) && heredelim)
6054 : {
6055 : tflags &= ~LEX_HEREDELIM;
6056 : tflags |= LEX_INHEREDOC;
6057 : lex_firstind = retind + 1;
6058 : }
6059 : else if (tflags & LEX_INHEREDOC)
6060 : {
6061 : int tind;
6062 : tind = lex_firstind;
6063 : while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
6064 : tind++;
6065 : if (STREQN (ret + tind, heredelim, hdlen))
6066 : {
6067 : tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
6068 : /*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
6069 : free (heredelim);
6070 : heredelim = 0;
6071 : lex_firstind = -1;
6072 : }
6073 : else
6074 : lex_firstind = retind + 1;
6075 : }
6076 : }
6077 :
6078 : /* Possible reprompting. */
6079 : if (ch == '\n' && SHOULD_PROMPT ())
6080 : prompt_again ();
6081 :
6082 : /* XXX -- possibly allow here doc to be delimited by ending right
6083 : paren. */
6084 : if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
6085 : {
6086 : int tind;
6087 : /*itrace("parse_comsub:%d: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", line_number, retind-lex_firstind, hdlen, retind);*/
6088 : tind = lex_firstind;
6089 : while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
6090 : tind++;
6091 : if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
6092 : {
6093 : tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
6094 : /*itrace("parse_comsub:%d: found here doc end `%*s'", line_number, hdlen, ret + tind);*/
6095 : free (heredelim);
6096 : heredelim = 0;
6097 : lex_firstind = -1;
6098 : }
6099 : }
6100 :
6101 : /* Don't bother counting parens or doing anything else if in a comment or
6102 : here document (not exactly right for here-docs -- if we want to allow
6103 : recursive calls to parse_comsub to have their own here documents,
6104 : change the LEX_INHEREDOC to LEX_QUOTEDDOC here and uncomment the next
6105 : clause below. Note that to make this work completely, we need to make
6106 : additional changes to allow xparse_dolparen to work right when the
6107 : command substitution is parsed, because read_secondary_line doesn't know
6108 : to recursively parse through command substitutions embedded in here-
6109 : documents */
6110 : if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
6111 : {
6112 : /* Add this character. */
6113 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6114 : ret[retind++] = ch;
6115 :
6116 : if ((tflags & LEX_INCOMMENT) && ch == '\n')
6117 : {
6118 : /*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/
6119 : tflags &= ~LEX_INCOMMENT;
6120 : }
6121 :
6122 : continue;
6123 : }
6124 : #if 0
6125 : /* If we're going to recursively parse a command substitution inside a
6126 : here-document, make sure we call parse_comsub recursively below. See
6127 : above for additional caveats. */
6128 : if ((tflags & LEX_INHEREDOC) && ((tflags & LEX_WASDOL) == 0 || ch != '(')) /*)*/
6129 : {
6130 : /* Add this character. */
6131 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6132 : ret[retind++] = ch;
6133 : if MBTEST(ch == '$')
6134 : tflags |= LEX_WASDOL;
6135 : else
6136 : tflags &= ~LEX_WASDOL;
6137 : }
6138 : #endif
6139 :
6140 : if (tflags & LEX_PASSNEXT) /* last char was backslash */
6141 : {
6142 : /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
6143 : tflags &= ~LEX_PASSNEXT;
6144 : if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
6145 : {
6146 : if (retind > 0)
6147 : retind--; /* swallow previously-added backslash */
6148 : continue;
6149 : }
6150 :
6151 : RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
6152 : if MBTEST(ch == CTLESC)
6153 : ret[retind++] = CTLESC;
6154 : ret[retind++] = ch;
6155 : continue;
6156 : }
6157 :
6158 : /* If this is a shell break character, we are not in a word. If not,
6159 : we either start or continue a word. */
6160 : if MBTEST(shellbreak (ch))
6161 : {
6162 : tflags &= ~LEX_INWORD;
6163 : /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
6164 : }
6165 : else
6166 : {
6167 : if (tflags & LEX_INWORD)
6168 : {
6169 : lex_wlen++;
6170 : /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
6171 : }
6172 : else
6173 : {
6174 : /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
6175 : tflags |= LEX_INWORD;
6176 : lex_wlen = 0;
6177 : if (tflags & LEX_RESWDOK)
6178 : lex_rwlen = 0;
6179 : }
6180 : }
6181 :
6182 : /* Skip whitespace */
6183 : if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0)
6184 : {
6185 : /* Add this character. */
6186 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6187 : ret[retind++] = ch;
6188 : continue;
6189 : }
6190 :
6191 : /* Either we are looking for the start of the here-doc delimiter
6192 : (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
6193 : If this character is a shell break character and we are reading
6194 : the delimiter, save it and note that we are now reading a here
6195 : document. If we've found the start of the delimiter, note it by
6196 : setting lex_firstind. Backslashes can quote shell metacharacters
6197 : in here-doc delimiters. */
6198 : if (tflags & LEX_HEREDELIM)
6199 : {
6200 : if (lex_firstind == -1 && shellbreak (ch) == 0)
6201 : lex_firstind = retind;
6202 : #if 0
6203 : else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n')
6204 : {
6205 : tflags |= LEX_INHEREDOC;
6206 : tflags &= ~LEX_HEREDELIM;
6207 : lex_firstind = retind + 1;
6208 : }
6209 : #endif
6210 : else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
6211 : {
6212 : if (heredelim == 0)
6213 : {
6214 : nestret = substring (ret, lex_firstind, retind);
6215 : heredelim = string_quote_removal (nestret, 0);
6216 : hdlen = STRLEN(heredelim);
6217 : /*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
6218 : if (STREQ (heredelim, nestret) == 0)
6219 : tflags |= LEX_QUOTEDDOC;
6220 : free (nestret);
6221 : }
6222 : if (ch == '\n')
6223 : {
6224 : tflags |= LEX_INHEREDOC;
6225 : tflags &= ~LEX_HEREDELIM;
6226 : lex_firstind = retind + 1;
6227 : }
6228 : else
6229 : lex_firstind = -1;
6230 : }
6231 : }
6232 :
6233 : /* Meta-characters that can introduce a reserved word. Not perfect yet. */
6234 : if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
6235 : {
6236 : /* Add this character. */
6237 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6238 : ret[retind++] = ch;
6239 : peekc = shell_getc (1);
6240 : if (ch == peekc && (ch == '&' || ch == '|' || ch == ';')) /* two-character tokens */
6241 : {
6242 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6243 : ret[retind++] = peekc;
6244 : /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
6245 : tflags |= LEX_RESWDOK;
6246 : lex_rwlen = 0;
6247 : continue;
6248 : }
6249 : else if (ch == '\n' || COMSUB_META(ch))
6250 : {
6251 : shell_ungetc (peekc);
6252 : /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
6253 : tflags |= LEX_RESWDOK;
6254 : lex_rwlen = 0;
6255 : continue;
6256 : }
6257 : else if (ch == EOF)
6258 : goto eof_error;
6259 : else
6260 : {
6261 : /* `unget' the character we just added and fall through */
6262 : retind--;
6263 : shell_ungetc (peekc);
6264 : }
6265 : }
6266 :
6267 : /* If we can read a reserved word, try to read one. */
6268 : if (tflags & LEX_RESWDOK)
6269 : {
6270 : if MBTEST(islower ((unsigned char)ch))
6271 : {
6272 : /* Add this character. */
6273 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6274 : ret[retind++] = ch;
6275 : lex_rwlen++;
6276 : continue;
6277 : }
6278 : else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
6279 : {
6280 : if (STREQN (ret + retind - 4, "case", 4))
6281 : {
6282 : tflags |= LEX_INCASE;
6283 : tflags &= ~LEX_RESWDOK;
6284 : /*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
6285 : }
6286 : else if (STREQN (ret + retind - 4, "esac", 4))
6287 : {
6288 : tflags &= ~LEX_INCASE;
6289 : /*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 1", line_number);*/
6290 : tflags |= LEX_RESWDOK;
6291 : lex_rwlen = 0;
6292 : }
6293 : else if (STREQN (ret + retind - 4, "done", 4) ||
6294 : STREQN (ret + retind - 4, "then", 4) ||
6295 : STREQN (ret + retind - 4, "else", 4) ||
6296 : STREQN (ret + retind - 4, "elif", 4) ||
6297 : STREQN (ret + retind - 4, "time", 4))
6298 : {
6299 : /* these are four-character reserved words that can be
6300 : followed by a reserved word; anything else turns off
6301 : the reserved-word-ok flag */
6302 : /*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 1", line_number, ret+retind-4);*/
6303 : tflags |= LEX_RESWDOK;
6304 : lex_rwlen = 0;
6305 : }
6306 : else if (shellmeta (ch) == 0)
6307 : {
6308 : tflags &= ~LEX_RESWDOK;
6309 : /*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 0", line_number, ret+retind-4);*/
6310 : }
6311 : else /* can't be in a reserved word any more */
6312 : lex_rwlen = 0;
6313 : }
6314 : else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
6315 : ; /* don't modify LEX_RESWDOK if we're starting a comment */
6316 : /* Allow `do' followed by space, tab, or newline to preserve the
6317 : RESWDOK flag, but reset the reserved word length counter so we
6318 : can read another one. */
6319 : else if MBTEST(((tflags & LEX_INCASE) == 0) &&
6320 : (isblank((unsigned char)ch) || ch == '\n') &&
6321 : lex_rwlen == 2 &&
6322 : STREQN (ret + retind - 2, "do", 2))
6323 : {
6324 : /*itrace("parse_comsub:%d: lex_incase == 0 found `%c', found \"do\"", line_number, ch);*/
6325 : lex_rwlen = 0;
6326 : }
6327 : else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
6328 : /* If we can read a reserved word and we're in case, we're at the
6329 : point where we can read a new pattern list or an esac. We
6330 : handle the esac case above. If we read a newline, we want to
6331 : leave LEX_RESWDOK alone. If we read anything else, we want to
6332 : turn off LEX_RESWDOK, since we're going to read a pattern list. */
6333 : {
6334 : tflags &= ~LEX_RESWDOK;
6335 : /*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
6336 : }
6337 : else if MBTEST(shellbreak (ch) == 0)
6338 : {
6339 : tflags &= ~LEX_RESWDOK;
6340 : /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
6341 : }
6342 : #if 0
6343 : /* If we find a space or tab but have read something and it's not
6344 : `do', turn off the reserved-word-ok flag */
6345 : else if MBTEST(isblank ((unsigned char)ch) && lex_rwlen > 0)
6346 : {
6347 : tflags &= ~LEX_RESWDOK;
6348 : /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
6349 : }
6350 : #endif
6351 : }
6352 :
6353 : /* Might be the start of a here-doc delimiter */
6354 : if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
6355 : {
6356 : /* Add this character. */
6357 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6358 : ret[retind++] = ch;
6359 : peekc = shell_getc (1);
6360 : if (peekc == EOF)
6361 : goto eof_error;
6362 : if (peekc == ch)
6363 : {
6364 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6365 : ret[retind++] = peekc;
6366 : peekc = shell_getc (1);
6367 : if (peekc == EOF)
6368 : goto eof_error;
6369 : if (peekc == '-')
6370 : {
6371 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6372 : ret[retind++] = peekc;
6373 : tflags |= LEX_STRIPDOC;
6374 : }
6375 : else
6376 : shell_ungetc (peekc);
6377 : if (peekc != '<')
6378 : {
6379 : tflags |= LEX_HEREDELIM;
6380 : lex_firstind = -1;
6381 : }
6382 : continue;
6383 : }
6384 : else
6385 : ch = peekc; /* fall through and continue XXX */
6386 : }
6387 : else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
6388 : {
6389 : /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
6390 : tflags |= LEX_INCOMMENT;
6391 : }
6392 :
6393 : if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
6394 : {
6395 : RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
6396 : ret[retind++] = CTLESC;
6397 : ret[retind++] = ch;
6398 : continue;
6399 : }
6400 : #if 0
6401 : else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
6402 : tflags &= ~LEX_INCASE; /* XXX */
6403 : #endif
6404 : else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0) /* ending delimiter */
6405 : {
6406 : count--;
6407 : /*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
6408 : }
6409 : else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */
6410 : {
6411 : count++;
6412 : /*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
6413 : }
6414 :
6415 : /* Add this character. */
6416 : RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
6417 : ret[retind++] = ch;
6418 :
6419 : /* If we just read the ending character, don't bother continuing. */
6420 : if (count == 0)
6421 : break;
6422 :
6423 : if MBTEST(ch == '\\') /* backslashes */
6424 : tflags |= LEX_PASSNEXT;
6425 :
6426 : if MBTEST(shellquote (ch))
6427 : {
6428 : /* '', ``, or "" inside $(...). */
6429 : push_delimiter (dstack, ch);
6430 : if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
6431 : nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
6432 : else
6433 : nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
6434 : pop_delimiter (dstack);
6435 : CHECK_NESTRET_ERROR ();
6436 :
6437 : if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
6438 : {
6439 : /* Translate $'...' here. */
6440 : ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
6441 : xfree (nestret);
6442 :
6443 : if ((rflags & P_DQUOTE) == 0)
6444 : {
6445 : nestret = sh_single_quote (ttrans);
6446 : free (ttrans);
6447 : nestlen = strlen (nestret);
6448 : }
6449 : else
6450 : {
6451 : nestret = ttrans;
6452 : nestlen = ttranslen;
6453 : }
6454 : retind -= 2; /* back up before the $' */
6455 : }
6456 : else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
6457 : {
6458 : /* Locale expand $"..." here. */
6459 : ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
6460 : xfree (nestret);
6461 :
6462 : nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
6463 : free (ttrans);
6464 : nestlen = ttranslen + 2;
6465 : retind -= 2; /* back up before the $" */
6466 : }
6467 :
6468 : APPEND_NESTRET ();
6469 : FREE (nestret);
6470 : }
6471 : else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
6472 : /* check for $(), $[], or ${} inside command substitution. */
6473 : {
6474 : if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */
6475 : count--;
6476 : if (ch == '(') /* ) */
6477 : nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
6478 : else if (ch == '{') /* } */
6479 : nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
6480 : else if (ch == '[') /* ] */
6481 : nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
6482 :
6483 : CHECK_NESTRET_ERROR ();
6484 : APPEND_NESTRET ();
6485 :
6486 : FREE (nestret);
6487 : }
6488 : if MBTEST(ch == '$')
6489 : tflags |= LEX_WASDOL;
6490 : else
6491 : tflags &= ~LEX_WASDOL;
6492 : }
6493 :
6494 : FREE (heredelim);
6495 : ret[retind] = '\0';
6496 : if (lenp)
6497 : *lenp = retind;
6498 : /*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
6499 : return ret;
6500 : }
6501 :
6502 : /* Recursively call the parser to parse a $(...) command substitution. */
6503 : char *
6504 : xparse_dolparen (base, string, indp, flags)
6505 : char *base;
6506 : char *string;
6507 : int *indp;
6508 : int flags;
6509 : {
6510 : sh_parser_state_t ps;
6511 : sh_input_line_state_t ls;
6512 : int nc, sflags, orig_eof_token;
6513 : char *ret, *ep, *ostring;
6514 :
6515 : /*yydebug = 1;*/
6516 : ostring = string;
6517 :
6518 : /*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
6519 : sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
6520 : if (flags & SX_NOLONGJMP)
6521 : sflags |= SEVAL_NOLONGJMP;
6522 : save_parser_state (&ps);
6523 : save_input_line_state (&ls);
6524 : orig_eof_token = shell_eof_token;
6525 :
6526 : /*(*/
6527 : parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
6528 : shell_eof_token = ')';
6529 :
6530 : nc = parse_string (string, "command substitution", sflags, &ep);
6531 :
6532 : shell_eof_token = orig_eof_token;
6533 : restore_parser_state (&ps);
6534 : reset_parser ();
6535 : /* reset_parser clears shell_input_line and associated variables */
6536 : restore_input_line_state (&ls);
6537 :
6538 : token_to_read = 0;
6539 :
6540 : /* If parse_string returns < 0, we need to jump to top level with the
6541 : negative of the return value */
6542 : if (nc < 0)
6543 : jump_to_top_level (-nc); /* XXX */
6544 :
6545 : /* Need to find how many characters parse_and_execute consumed, update
6546 : *indp, if flags != 0, copy the portion of the string parsed into RET
6547 : and return it. If flags & 1 (EX_NOALLOC) we can return NULL. */
6548 :
6549 : /*(*/
6550 : if (ep[-1] != ')')
6551 : {
6552 : #if DEBUG
6553 : if (ep[-1] != '\n')
6554 : itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
6555 : #endif
6556 : while (ep > ostring && ep[-1] == '\n') ep--;
6557 : }
6558 :
6559 : nc = ep - ostring;
6560 : *indp = ep - base - 1;
6561 :
6562 : /*(*/
6563 : #if DEBUG
6564 : if (base[*indp] != ')')
6565 : itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
6566 : #endif
6567 :
6568 : if (flags & SX_NOALLOC)
6569 : return (char *)NULL;
6570 :
6571 : if (nc == 0)
6572 : {
6573 : ret = xmalloc (1);
6574 : ret[0] = '\0';
6575 : }
6576 : else
6577 : ret = substring (ostring, 0, nc - 1);
6578 :
6579 : return ret;
6580 : }
6581 :
6582 : #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
6583 : /* Parse a double-paren construct. It can be either an arithmetic
6584 : command, an arithmetic `for' command, or a nested subshell. Returns
6585 : the parsed token, -1 on error, or -2 if we didn't do anything and
6586 : should just go on. */
6587 : static int
6588 : parse_dparen (c)
6589 : int c;
6590 : {
6591 : int cmdtyp;
6592 : char *wval;
6593 : WORD_DESC *wd;
6594 :
6595 : #if defined (ARITH_FOR_COMMAND)
6596 : if (last_read_token == FOR)
6597 : {
6598 : arith_for_lineno = line_number;
6599 : cmdtyp = parse_arith_cmd (&wval, 0);
6600 : if (cmdtyp == 1)
6601 : {
6602 : wd = alloc_word_desc ();
6603 : wd->word = wval;
6604 : yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
6605 : return (ARITH_FOR_EXPRS);
6606 : }
6607 : else
6608 : return -1; /* ERROR */
6609 : }
6610 : #endif
6611 :
6612 : #if defined (DPAREN_ARITHMETIC)
6613 : if (reserved_word_acceptable (last_read_token))
6614 : {
6615 : cmdtyp = parse_arith_cmd (&wval, 0);
6616 : if (cmdtyp == 1) /* arithmetic command */
6617 : {
6618 : wd = alloc_word_desc ();
6619 : wd->word = wval;
6620 : wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
6621 : yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
6622 : return (ARITH_CMD);
6623 : }
6624 : else if (cmdtyp == 0) /* nested subshell */
6625 : {
6626 : push_string (wval, 0, (alias_t *)NULL);
6627 : pushed_string_list->flags = PSH_DPAREN;
6628 : if ((parser_state & PST_CASEPAT) == 0)
6629 : parser_state |= PST_SUBSHELL;
6630 : return (c);
6631 : }
6632 : else /* ERROR */
6633 : return -1;
6634 : }
6635 : #endif
6636 :
6637 : return -2; /* XXX */
6638 : }
6639 :
6640 : /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
6641 : If not, assume it's a nested subshell for backwards compatibility and
6642 : return 0. In any case, put the characters we've consumed into a locally-
6643 : allocated buffer and make *ep point to that buffer. Return -1 on an
6644 : error, for example EOF. */
6645 : static int
6646 : parse_arith_cmd (ep, adddq)
6647 : char **ep;
6648 : int adddq;
6649 : {
6650 : int rval, c;
6651 : char *ttok, *tokstr;
6652 : int ttoklen;
6653 :
6654 : ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
6655 : rval = 1;
6656 : if (ttok == &matched_pair_error)
6657 : return -1;
6658 : /* Check that the next character is the closing right paren. If
6659 : not, this is a syntax error. ( */
6660 : c = shell_getc (0);
6661 : if MBTEST(c != ')')
6662 : rval = 0;
6663 :
6664 : tokstr = (char *)xmalloc (ttoklen + 4);
6665 :
6666 : /* if ADDDQ != 0 then (( ... )) -> "..." */
6667 : if (rval == 1 && adddq) /* arith cmd, add double quotes */
6668 : {
6669 : tokstr[0] = '"';
6670 : strncpy (tokstr + 1, ttok, ttoklen - 1);
6671 : tokstr[ttoklen] = '"';
6672 : tokstr[ttoklen+1] = '\0';
6673 : }
6674 : else if (rval == 1) /* arith cmd, don't add double quotes */
6675 : {
6676 : strncpy (tokstr, ttok, ttoklen - 1);
6677 : tokstr[ttoklen-1] = '\0';
6678 : }
6679 : else /* nested subshell */
6680 : {
6681 : tokstr[0] = '(';
6682 : strncpy (tokstr + 1, ttok, ttoklen - 1);
6683 : tokstr[ttoklen] = ')';
6684 : tokstr[ttoklen+1] = c;
6685 : tokstr[ttoklen+2] = '\0';
6686 : }
6687 :
6688 : *ep = tokstr;
6689 : FREE (ttok);
6690 : return rval;
6691 : }
6692 : #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
6693 :
6694 : #if defined (COND_COMMAND)
6695 : static void
6696 : cond_error ()
6697 : {
6698 : char *etext;
6699 :
6700 : if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
6701 : parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
6702 : else if (cond_token != COND_ERROR)
6703 : {
6704 : if (etext = error_token_from_token (cond_token))
6705 : {
6706 : parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
6707 : free (etext);
6708 : }
6709 : else
6710 : parser_error (cond_lineno, _("syntax error in conditional expression"));
6711 : }
6712 : }
6713 :
6714 : static COND_COM *
6715 : cond_expr ()
6716 : {
6717 : return (cond_or ());
6718 : }
6719 :
6720 : static COND_COM *
6721 : cond_or ()
6722 : {
6723 : COND_COM *l, *r;
6724 :
6725 : l = cond_and ();
6726 : if (cond_token == OR_OR)
6727 : {
6728 : r = cond_or ();
6729 : l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
6730 : }
6731 : return l;
6732 : }
6733 :
6734 : static COND_COM *
6735 : cond_and ()
6736 : {
6737 : COND_COM *l, *r;
6738 :
6739 : l = cond_term ();
6740 : if (cond_token == AND_AND)
6741 : {
6742 : r = cond_and ();
6743 : l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
6744 : }
6745 : return l;
6746 : }
6747 :
6748 : static int
6749 : cond_skip_newlines ()
6750 : {
6751 : while ((cond_token = read_token (READ)) == '\n')
6752 : {
6753 : if (SHOULD_PROMPT ())
6754 : prompt_again ();
6755 : }
6756 : return (cond_token);
6757 : }
6758 :
6759 : #define COND_RETURN_ERROR() \
6760 : do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
6761 :
6762 : static COND_COM *
6763 : cond_term ()
6764 : {
6765 : WORD_DESC *op;
6766 : COND_COM *term, *tleft, *tright;
6767 : int tok, lineno;
6768 : char *etext;
6769 :
6770 : /* Read a token. It can be a left paren, a `!', a unary operator, or a
6771 : word that should be the first argument of a binary operator. Start by
6772 : skipping newlines, since this is a compound command. */
6773 : tok = cond_skip_newlines ();
6774 : lineno = line_number;
6775 : if (tok == COND_END)
6776 : {
6777 : COND_RETURN_ERROR ();
6778 : }
6779 : else if (tok == '(')
6780 : {
6781 : term = cond_expr ();
6782 : if (cond_token != ')')
6783 : {
6784 : if (term)
6785 : dispose_cond_node (term); /* ( */
6786 : if (etext = error_token_from_token (cond_token))
6787 : {
6788 : parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
6789 : free (etext);
6790 : }
6791 : else
6792 : parser_error (lineno, _("expected `)'"));
6793 : COND_RETURN_ERROR ();
6794 : }
6795 : term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
6796 : (void)cond_skip_newlines ();
6797 : }
6798 : else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
6799 : {
6800 : if (tok == WORD)
6801 : dispose_word (yylval.word); /* not needed */
6802 : term = cond_term ();
6803 : if (term)
6804 : term->flags |= CMD_INVERT_RETURN;
6805 : }
6806 : else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
6807 : {
6808 : op = yylval.word;
6809 : tok = read_token (READ);
6810 : if (tok == WORD)
6811 : {
6812 : tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
6813 : term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
6814 : }
6815 : else
6816 : {
6817 : dispose_word (op);
6818 : if (etext = error_token_from_token (tok))
6819 : {
6820 : parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
6821 : free (etext);
6822 : }
6823 : else
6824 : parser_error (line_number, _("unexpected argument to conditional unary operator"));
6825 : COND_RETURN_ERROR ();
6826 : }
6827 :
6828 : (void)cond_skip_newlines ();
6829 : }
6830 : else if (tok == WORD) /* left argument to binary operator */
6831 : {
6832 : /* lhs */
6833 : tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
6834 :
6835 : /* binop */
6836 : tok = read_token (READ);
6837 : if (tok == WORD && test_binop (yylval.word->word))
6838 : {
6839 : op = yylval.word;
6840 : if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
6841 : parser_state |= PST_EXTPAT;
6842 : else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
6843 : parser_state |= PST_EXTPAT;
6844 : }
6845 : #if defined (COND_REGEXP)
6846 : else if (tok == WORD && STREQ (yylval.word->word, "=~"))
6847 : {
6848 : op = yylval.word;
6849 : parser_state |= PST_REGEXP;
6850 : }
6851 : #endif
6852 : else if (tok == '<' || tok == '>')
6853 : op = make_word_from_token (tok); /* ( */
6854 : /* There should be a check before blindly accepting the `)' that we have
6855 : seen the opening `('. */
6856 : else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
6857 : {
6858 : /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
6859 : the test command. Similarly for [[ x && expr ]] or
6860 : [[ x || expr ]] or [[ (x) ]]. */
6861 : op = make_word ("-n");
6862 : term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
6863 : cond_token = tok;
6864 : return (term);
6865 : }
6866 : else
6867 : {
6868 : if (etext = error_token_from_token (tok))
6869 : {
6870 : parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
6871 : free (etext);
6872 : }
6873 : else
6874 : parser_error (line_number, _("conditional binary operator expected"));
6875 : dispose_cond_node (tleft);
6876 : COND_RETURN_ERROR ();
6877 : }
6878 :
6879 : /* rhs */
6880 : if (parser_state & PST_EXTPAT)
6881 : extended_glob = 1;
6882 : tok = read_token (READ);
6883 : if (parser_state & PST_EXTPAT)
6884 : extended_glob = global_extglob;
6885 : parser_state &= ~(PST_REGEXP|PST_EXTPAT);
6886 :
6887 : if (tok == WORD)
6888 : {
6889 : tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
6890 : term = make_cond_node (COND_BINARY, op, tleft, tright);
6891 : }
6892 : else
6893 : {
6894 : if (etext = error_token_from_token (tok))
6895 : {
6896 : parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
6897 : free (etext);
6898 : }
6899 : else
6900 : parser_error (line_number, _("unexpected argument to conditional binary operator"));
6901 : dispose_cond_node (tleft);
6902 : dispose_word (op);
6903 : COND_RETURN_ERROR ();
6904 : }
6905 :
6906 : (void)cond_skip_newlines ();
6907 : }
6908 : else
6909 : {
6910 : if (tok < 256)
6911 : parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
6912 : else if (etext = error_token_from_token (tok))
6913 : {
6914 : parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
6915 : free (etext);
6916 : }
6917 : else
6918 : parser_error (line_number, _("unexpected token %d in conditional command"), tok);
6919 : COND_RETURN_ERROR ();
6920 : }
6921 : return (term);
6922 : }
6923 :
6924 : /* This is kind of bogus -- we slip a mini recursive-descent parser in
6925 : here to handle the conditional statement syntax. */
6926 : static COMMAND *
6927 : parse_cond_command ()
6928 : {
6929 : COND_COM *cexp;
6930 :
6931 : global_extglob = extended_glob;
6932 : cexp = cond_expr ();
6933 : return (make_cond_command (cexp));
6934 : }
6935 : #endif
6936 :
6937 : #if defined (ARRAY_VARS)
6938 : /* When this is called, it's guaranteed that we don't care about anything
6939 : in t beyond i. We do save and restore the chars, though. */
6940 : static int
6941 : token_is_assignment (t, i)
6942 : char *t;
6943 : int i;
6944 : {
6945 : unsigned char c, c1;
6946 : int r;
6947 :
6948 : c = t[i]; c1 = t[i+1];
6949 : t[i] = '='; t[i+1] = '\0';
6950 : r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
6951 : t[i] = c; t[i+1] = c1;
6952 : return r;
6953 : }
6954 :
6955 : /* XXX - possible changes here for `+=' */
6956 : static int
6957 : token_is_ident (t, i)
6958 : char *t;
6959 : int i;
6960 : {
6961 : unsigned char c;
6962 : int r;
6963 :
6964 : c = t[i];
6965 : t[i] = '\0';
6966 : r = legal_identifier (t);
6967 : t[i] = c;
6968 : return r;
6969 : }
6970 : #endif
6971 :
6972 : static int
6973 : read_token_word (character)
6974 : int character;
6975 : {
6976 : /* The value for YYLVAL when a WORD is read. */
6977 : WORD_DESC *the_word;
6978 :
6979 : /* Index into the token that we are building. */
6980 : int token_index;
6981 :
6982 : /* ALL_DIGITS becomes zero when we see a non-digit. */
6983 : int all_digit_token;
6984 :
6985 : /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
6986 : int dollar_present;
6987 :
6988 : /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
6989 : assignment. */
6990 : int compound_assignment;
6991 :
6992 : /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
6993 : int quoted;
6994 :
6995 : /* Non-zero means to ignore the value of the next character, and just
6996 : to add it no matter what. */
6997 : int pass_next_character;
6998 :
6999 : /* The current delimiting character. */
7000 : int cd;
7001 : int result, peek_char;
7002 : char *ttok, *ttrans;
7003 : int ttoklen, ttranslen;
7004 : intmax_t lvalue;
7005 :
7006 : if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
7007 : token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
7008 :
7009 : token_index = 0;
7010 : all_digit_token = DIGIT (character);
7011 : dollar_present = quoted = pass_next_character = compound_assignment = 0;
7012 :
7013 : for (;;)
7014 : {
7015 : if (character == EOF)
7016 : goto got_token;
7017 :
7018 : if (pass_next_character)
7019 : {
7020 : pass_next_character = 0;
7021 : goto got_escaped_character;
7022 : }
7023 :
7024 : cd = current_delimiter (dstack);
7025 :
7026 : /* Handle backslashes. Quote lots of things when not inside of
7027 : double-quotes, quote some things inside of double-quotes. */
7028 : if MBTEST(character == '\\')
7029 : {
7030 : peek_char = shell_getc (0);
7031 :
7032 : /* Backslash-newline is ignored in all cases except
7033 : when quoted with single quotes. */
7034 : if (peek_char == '\n')
7035 : {
7036 : character = '\n';
7037 : goto next_character;
7038 : }
7039 : else
7040 : {
7041 : shell_ungetc (peek_char);
7042 :
7043 : /* If the next character is to be quoted, note it now. */
7044 : if (cd == 0 || cd == '`' ||
7045 : (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
7046 : pass_next_character++;
7047 :
7048 : quoted = 1;
7049 : goto got_character;
7050 : }
7051 : }
7052 :
7053 : /* Parse a matched pair of quote characters. */
7054 : if MBTEST(shellquote (character))
7055 : {
7056 : push_delimiter (dstack, character);
7057 : ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
7058 : pop_delimiter (dstack);
7059 : if (ttok == &matched_pair_error)
7060 : return -1; /* Bail immediately. */
7061 : RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
7062 : token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
7063 : token[token_index++] = character;
7064 : strcpy (token + token_index, ttok);
7065 : token_index += ttoklen;
7066 : all_digit_token = 0;
7067 : quoted = 1;
7068 : dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
7069 : FREE (ttok);
7070 : goto next_character;
7071 : }
7072 :
7073 : #ifdef COND_REGEXP
7074 : /* When parsing a regexp as a single word inside a conditional command,
7075 : we need to special-case characters special to both the shell and
7076 : regular expressions. Right now, that is only '(' and '|'. */ /*)*/
7077 : if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/
7078 : {
7079 : if (character == '|')
7080 : goto got_character;
7081 :
7082 : push_delimiter (dstack, character);
7083 : ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
7084 : pop_delimiter (dstack);
7085 : if (ttok == &matched_pair_error)
7086 : return -1; /* Bail immediately. */
7087 : RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
7088 : token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
7089 : token[token_index++] = character;
7090 : strcpy (token + token_index, ttok);
7091 : token_index += ttoklen;
7092 : FREE (ttok);
7093 : dollar_present = all_digit_token = 0;
7094 : goto next_character;
7095 : }
7096 : #endif /* COND_REGEXP */
7097 :
7098 : #ifdef EXTENDED_GLOB
7099 : /* Parse a ksh-style extended pattern matching specification. */
7100 : if MBTEST(extended_glob && PATTERN_CHAR (character))
7101 : {
7102 : peek_char = shell_getc (1);
7103 : if MBTEST(peek_char == '(') /* ) */
7104 : {
7105 : push_delimiter (dstack, peek_char);
7106 : ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
7107 : pop_delimiter (dstack);
7108 : if (ttok == &matched_pair_error)
7109 : return -1; /* Bail immediately. */
7110 : RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
7111 : token_buffer_size,
7112 : TOKEN_DEFAULT_GROW_SIZE);
7113 : token[token_index++] = character;
7114 : token[token_index++] = peek_char;
7115 : strcpy (token + token_index, ttok);
7116 : token_index += ttoklen;
7117 : FREE (ttok);
7118 : dollar_present = all_digit_token = 0;
7119 : goto next_character;
7120 : }
7121 : else
7122 : shell_ungetc (peek_char);
7123 : }
7124 : #endif /* EXTENDED_GLOB */
7125 :
7126 : /* If the delimiter character is not single quote, parse some of
7127 : the shell expansions that must be read as a single word. */
7128 : if (shellexp (character))
7129 : {
7130 : peek_char = shell_getc (1);
7131 : /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
7132 : if MBTEST(peek_char == '(' ||
7133 : ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
7134 : {
7135 : if (peek_char == '{') /* } */
7136 : ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
7137 : else if (peek_char == '(') /* ) */
7138 : {
7139 : /* XXX - push and pop the `(' as a delimiter for use by
7140 : the command-oriented-history code. This way newlines
7141 : appearing in the $(...) string get added to the
7142 : history literally rather than causing a possibly-
7143 : incorrect `;' to be added. ) */
7144 : push_delimiter (dstack, peek_char);
7145 : ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
7146 : pop_delimiter (dstack);
7147 : }
7148 : else
7149 : ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
7150 : if (ttok == &matched_pair_error)
7151 : return -1; /* Bail immediately. */
7152 : RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
7153 : token_buffer_size,
7154 : TOKEN_DEFAULT_GROW_SIZE);
7155 : token[token_index++] = character;
7156 : token[token_index++] = peek_char;
7157 : strcpy (token + token_index, ttok);
7158 : token_index += ttoklen;
7159 : FREE (ttok);
7160 : dollar_present = 1;
7161 : all_digit_token = 0;
7162 : goto next_character;
7163 : }
7164 : /* This handles $'...' and $"..." new-style quoted strings. */
7165 : else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
7166 : {
7167 : int first_line;
7168 :
7169 : first_line = line_number;
7170 : push_delimiter (dstack, peek_char);
7171 : ttok = parse_matched_pair (peek_char, peek_char, peek_char,
7172 : &ttoklen,
7173 : (peek_char == '\'') ? P_ALLOWESC : 0);
7174 : pop_delimiter (dstack);
7175 : if (ttok == &matched_pair_error)
7176 : return -1;
7177 : if (peek_char == '\'')
7178 : {
7179 : ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
7180 : free (ttok);
7181 :
7182 : /* Insert the single quotes and correctly quote any
7183 : embedded single quotes (allowed because P_ALLOWESC was
7184 : passed to parse_matched_pair). */
7185 : ttok = sh_single_quote (ttrans);
7186 : free (ttrans);
7187 : ttranslen = strlen (ttok);
7188 : ttrans = ttok;
7189 : }
7190 : else
7191 : {
7192 : /* Try to locale-expand the converted string. */
7193 : ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
7194 : free (ttok);
7195 :
7196 : /* Add the double quotes back */
7197 : ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
7198 : free (ttrans);
7199 : ttranslen += 2;
7200 : ttrans = ttok;
7201 : }
7202 :
7203 : RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1,
7204 : token_buffer_size,
7205 : TOKEN_DEFAULT_GROW_SIZE);
7206 : strcpy (token + token_index, ttrans);
7207 : token_index += ttranslen;
7208 : FREE (ttrans);
7209 : quoted = 1;
7210 : all_digit_token = 0;
7211 : goto next_character;
7212 : }
7213 : /* This could eventually be extended to recognize all of the
7214 : shell's single-character parameter expansions, and set flags.*/
7215 : else if MBTEST(character == '$' && peek_char == '$')
7216 : {
7217 : RESIZE_MALLOCED_BUFFER (token, token_index, 3,
7218 : token_buffer_size,
7219 : TOKEN_DEFAULT_GROW_SIZE);
7220 : token[token_index++] = '$';
7221 : token[token_index++] = peek_char;
7222 : dollar_present = 1;
7223 : all_digit_token = 0;
7224 : goto next_character;
7225 : }
7226 : else
7227 : shell_ungetc (peek_char);
7228 : }
7229 :
7230 : #if defined (ARRAY_VARS)
7231 : /* Identify possible array subscript assignment; match [...]. If
7232 : parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
7233 : `sub' as if it were enclosed in double quotes. */
7234 : else if MBTEST(character == '[' && /* ] */
7235 : ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
7236 : (token_index == 0 && (parser_state&PST_COMPASSIGN))))
7237 : {
7238 : ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
7239 : if (ttok == &matched_pair_error)
7240 : return -1; /* Bail immediately. */
7241 : RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
7242 : token_buffer_size,
7243 : TOKEN_DEFAULT_GROW_SIZE);
7244 : token[token_index++] = character;
7245 : strcpy (token + token_index, ttok);
7246 : token_index += ttoklen;
7247 : FREE (ttok);
7248 : all_digit_token = 0;
7249 : goto next_character;
7250 : }
7251 : /* Identify possible compound array variable assignment. */
7252 : else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
7253 : {
7254 : peek_char = shell_getc (1);
7255 : if MBTEST(peek_char == '(') /* ) */
7256 : {
7257 : ttok = parse_compound_assignment (&ttoklen);
7258 :
7259 : RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
7260 : token_buffer_size,
7261 : TOKEN_DEFAULT_GROW_SIZE);
7262 :
7263 : token[token_index++] = '=';
7264 : token[token_index++] = '(';
7265 : if (ttok)
7266 : {
7267 : strcpy (token + token_index, ttok);
7268 : token_index += ttoklen;
7269 : }
7270 : token[token_index++] = ')';
7271 : FREE (ttok);
7272 : all_digit_token = 0;
7273 : compound_assignment = 1;
7274 : #if 1
7275 : goto next_character;
7276 : #else
7277 : goto got_token; /* ksh93 seems to do this */
7278 : #endif
7279 : }
7280 : else
7281 : shell_ungetc (peek_char);
7282 : }
7283 : #endif
7284 :
7285 : /* When not parsing a multi-character word construct, shell meta-
7286 : characters break words. */
7287 : if MBTEST(shellbreak (character))
7288 : {
7289 : shell_ungetc (character);
7290 : goto got_token;
7291 : }
7292 :
7293 : got_character:
7294 : if (character == CTLESC || character == CTLNUL)
7295 : {
7296 : RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size,
7297 : TOKEN_DEFAULT_GROW_SIZE);
7298 : token[token_index++] = CTLESC;
7299 : }
7300 : else
7301 : got_escaped_character:
7302 : RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
7303 : TOKEN_DEFAULT_GROW_SIZE);
7304 :
7305 : token[token_index++] = character;
7306 :
7307 : all_digit_token &= DIGIT (character);
7308 : dollar_present |= character == '$';
7309 :
7310 : next_character:
7311 : if (character == '\n' && SHOULD_PROMPT ())
7312 : prompt_again ();
7313 :
7314 : /* We want to remove quoted newlines (that is, a \<newline> pair)
7315 : unless we are within single quotes or pass_next_character is
7316 : set (the shell equivalent of literal-next). */
7317 : cd = current_delimiter (dstack);
7318 : character = shell_getc (cd != '\'' && pass_next_character == 0);
7319 : } /* end for (;;) */
7320 :
7321 : got_token:
7322 :
7323 : /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */
7324 : token[token_index] = '\0';
7325 :
7326 : /* Check to see what thing we should return. If the last_read_token
7327 : is a `<', or a `&', or the character which ended this token is
7328 : a '>' or '<', then, and ONLY then, is this input token a NUMBER.
7329 : Otherwise, it is just a word, and should be returned as such. */
7330 : if MBTEST(all_digit_token && (character == '<' || character == '>' ||
7331 : last_read_token == LESS_AND ||
7332 : last_read_token == GREATER_AND))
7333 : {
7334 : if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
7335 : {
7336 : yylval.number = lvalue;
7337 : return (NUMBER);
7338 : }
7339 : }
7340 :
7341 : /* Check for special case tokens. */
7342 : result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
7343 : if (result >= 0)
7344 : return result;
7345 :
7346 : #if defined (ALIAS)
7347 : /* Posix.2 does not allow reserved words to be aliased, so check for all
7348 : of them, including special cases, before expanding the current token
7349 : as an alias. */
7350 : if MBTEST(posixly_correct)
7351 : CHECK_FOR_RESERVED_WORD (token);
7352 :
7353 : /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
7354 : inhibits alias expansion. */
7355 : if (expand_aliases && quoted == 0)
7356 : {
7357 : result = alias_expand_token (token);
7358 : if (result == RE_READ_TOKEN)
7359 : return (RE_READ_TOKEN);
7360 : else if (result == NO_EXPANSION)
7361 : parser_state &= ~PST_ALEXPNEXT;
7362 : }
7363 :
7364 : /* If not in Posix.2 mode, check for reserved words after alias
7365 : expansion. */
7366 : if MBTEST(posixly_correct == 0)
7367 : #endif
7368 : CHECK_FOR_RESERVED_WORD (token);
7369 :
7370 : the_word = alloc_word_desc ();
7371 : the_word->word = (char *)xmalloc (1 + token_index);
7372 : the_word->flags = 0;
7373 : strcpy (the_word->word, token);
7374 : if (dollar_present)
7375 : the_word->flags |= W_HASDOLLAR;
7376 : if (quoted)
7377 : the_word->flags |= W_QUOTED; /*(*/
7378 : if (compound_assignment && token[token_index-1] == ')')
7379 : the_word->flags |= W_COMPASSIGN;
7380 : /* A word is an assignment if it appears at the beginning of a
7381 : simple command, or after another assignment word. This is
7382 : context-dependent, so it cannot be handled in the grammar. */
7383 : if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
7384 : {
7385 : the_word->flags |= W_ASSIGNMENT;
7386 : /* Don't perform word splitting on assignment statements. */
7387 : if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
7388 : {
7389 : the_word->flags |= W_NOSPLIT;
7390 : if (parser_state & PST_COMPASSIGN)
7391 : the_word->flags |= W_NOGLOB; /* XXX - W_NOBRACE? */
7392 : }
7393 : }
7394 :
7395 : if (command_token_position (last_read_token))
7396 : {
7397 : struct builtin *b;
7398 : b = builtin_address_internal (token, 0);
7399 : if (b && (b->flags & ASSIGNMENT_BUILTIN))
7400 : parser_state |= PST_ASSIGNOK;
7401 : else if (STREQ (token, "eval") || STREQ (token, "let"))
7402 : parser_state |= PST_ASSIGNOK;
7403 : }
7404 :
7405 : yylval.word = the_word;
7406 :
7407 : if (token[0] == '{' && token[token_index-1] == '}' &&
7408 : (character == '<' || character == '>'))
7409 : {
7410 : /* can use token; already copied to the_word */
7411 : token[token_index-1] = '\0';
7412 : #if defined (ARRAY_VARS)
7413 : if (legal_identifier (token+1) || valid_array_reference (token+1, 0))
7414 : #else
7415 : if (legal_identifier (token+1))
7416 : #endif
7417 : {
7418 : strcpy (the_word->word, token+1);
7419 : /*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
7420 : return (REDIR_WORD);
7421 : }
7422 : }
7423 :
7424 : result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
7425 : ? ASSIGNMENT_WORD : WORD;
7426 :
7427 : switch (last_read_token)
7428 : {
7429 : case FUNCTION:
7430 : parser_state |= PST_ALLOWOPNBRC;
7431 : function_dstart = line_number;
7432 : break;
7433 : case CASE:
7434 : case SELECT:
7435 : case FOR:
7436 : if (word_top < MAX_CASE_NEST)
7437 : word_top++;
7438 : word_lineno[word_top] = line_number;
7439 : break;
7440 : }
7441 :
7442 : return (result);
7443 : }
7444 :
7445 : /* Return 1 if TOKSYM is a token that after being read would allow
7446 : a reserved word to be seen, else 0. */
7447 : static int
7448 : reserved_word_acceptable (toksym)
7449 : int toksym;
7450 : {
7451 : switch (toksym)
7452 : {
7453 : case '\n':
7454 : case ';':
7455 : case '(':
7456 : case ')':
7457 : case '|':
7458 : case '&':
7459 : case '{':
7460 : case '}': /* XXX */
7461 : case AND_AND:
7462 : case BANG:
7463 : case BAR_AND:
7464 : case DO:
7465 : case DONE:
7466 : case ELIF:
7467 : case ELSE:
7468 : case ESAC:
7469 : case FI:
7470 : case IF:
7471 : case OR_OR:
7472 : case SEMI_SEMI:
7473 : case SEMI_AND:
7474 : case SEMI_SEMI_AND:
7475 : case THEN:
7476 : case TIME:
7477 : case TIMEOPT:
7478 : case TIMEIGN:
7479 : case COPROC:
7480 : case UNTIL:
7481 : case WHILE:
7482 : case 0:
7483 : return 1;
7484 : default:
7485 : #if defined (COPROCESS_SUPPORT)
7486 : if (last_read_token == WORD && token_before_that == COPROC)
7487 : return 1;
7488 : #endif
7489 : if (last_read_token == WORD && token_before_that == FUNCTION)
7490 : return 1;
7491 : return 0;
7492 : }
7493 : }
7494 :
7495 : /* Return the index of TOKEN in the alist of reserved words, or -1 if
7496 : TOKEN is not a shell reserved word. */
7497 : int
7498 : find_reserved_word (tokstr)
7499 : char *tokstr;
7500 : {
7501 : int i;
7502 : for (i = 0; word_token_alist[i].word; i++)
7503 : if (STREQ (tokstr, word_token_alist[i].word))
7504 : return i;
7505 : return -1;
7506 : }
7507 :
7508 : /* An interface to let the rest of the shell (primarily the completion
7509 : system) know what the parser is expecting. */
7510 : int
7511 : parser_in_command_position ()
7512 : {
7513 : return (command_token_position (last_read_token));
7514 : }
7515 :
7516 : #if 0
7517 : #if defined (READLINE)
7518 : /* Called after each time readline is called. This insures that whatever
7519 : the new prompt string is gets propagated to readline's local prompt
7520 : variable. */
7521 : static void
7522 : reset_readline_prompt ()
7523 : {
7524 : char *temp_prompt;
7525 :
7526 : if (prompt_string_pointer)
7527 : {
7528 : temp_prompt = (*prompt_string_pointer)
7529 : ? decode_prompt_string (*prompt_string_pointer)
7530 : : (char *)NULL;
7531 :
7532 : if (temp_prompt == 0)
7533 : {
7534 : temp_prompt = (char *)xmalloc (1);
7535 : temp_prompt[0] = '\0';
7536 : }
7537 :
7538 : FREE (current_readline_prompt);
7539 : current_readline_prompt = temp_prompt;
7540 : }
7541 : }
7542 : #endif /* READLINE */
7543 : #endif /* 0 */
7544 :
7545 : #if defined (HISTORY)
7546 : /* A list of tokens which can be followed by newlines, but not by
7547 : semi-colons. When concatenating multiple lines of history, the
7548 : newline separator for such tokens is replaced with a space. */
7549 : static const int no_semi_successors[] = {
7550 : '\n', '{', '(', ')', ';', '&', '|',
7551 : CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
7552 : WHILE, AND_AND, OR_OR, IN,
7553 : 0
7554 : };
7555 :
7556 : /* If we are not within a delimited expression, try to be smart
7557 : about which separators can be semi-colons and which must be
7558 : newlines. Returns the string that should be added into the
7559 : history entry. LINE is the line we're about to add; it helps
7560 : make some more intelligent decisions in certain cases. */
7561 : char *
7562 : history_delimiting_chars (line)
7563 : const char *line;
7564 : {
7565 : static int last_was_heredoc = 0; /* was the last entry the start of a here document? */
7566 : register int i;
7567 :
7568 : if ((parser_state & PST_HEREDOC) == 0)
7569 : last_was_heredoc = 0;
7570 :
7571 : if (dstack.delimiter_depth != 0)
7572 : return ("\n");
7573 :
7574 : /* We look for current_command_line_count == 2 because we are looking to
7575 : add the first line of the body of the here document (the second line
7576 : of the command). We also keep LAST_WAS_HEREDOC as a private sentinel
7577 : variable to note when we think we added the first line of a here doc
7578 : (the one with a "<<" somewhere in it) */
7579 : if (parser_state & PST_HEREDOC)
7580 : {
7581 : if (last_was_heredoc)
7582 : {
7583 : last_was_heredoc = 0;
7584 : return "\n";
7585 : }
7586 : return (here_doc_first_line ? "\n" : "");
7587 : }
7588 :
7589 : if (parser_state & PST_COMPASSIGN)
7590 : return (" ");
7591 :
7592 : /* First, handle some special cases. */
7593 : /*(*/
7594 : /* If we just read `()', assume it's a function definition, and don't
7595 : add a semicolon. If the token before the `)' was not `(', and we're
7596 : not in the midst of parsing a case statement, assume it's a
7597 : parenthesized command and add the semicolon. */
7598 : /*)(*/
7599 : if (token_before_that == ')')
7600 : {
7601 : if (two_tokens_ago == '(') /*)*/ /* function def */
7602 : return " ";
7603 : /* This does not work for subshells inside case statement
7604 : command lists. It's a suboptimal solution. */
7605 : else if (parser_state & PST_CASESTMT) /* case statement pattern */
7606 : return " ";
7607 : else
7608 : return "; "; /* (...) subshell */
7609 : }
7610 : else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
7611 : return " "; /* function def using `function name' without `()' */
7612 :
7613 : /* If we're not in a here document, but we think we're about to parse one,
7614 : and we would otherwise return a `;', return a newline to delimit the
7615 : line with the here-doc delimiter */
7616 : else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
7617 : {
7618 : last_was_heredoc = 1;
7619 : return "\n";
7620 : }
7621 : else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && need_here_doc > 0)
7622 : return "\n";
7623 : else if (token_before_that == WORD && two_tokens_ago == FOR)
7624 : {
7625 : /* Tricky. `for i\nin ...' should not have a semicolon, but
7626 : `for i\ndo ...' should. We do what we can. */
7627 : for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
7628 : ;
7629 : if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
7630 : return " ";
7631 : return ";";
7632 : }
7633 : else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
7634 : return " ";
7635 :
7636 : for (i = 0; no_semi_successors[i]; i++)
7637 : {
7638 : if (token_before_that == no_semi_successors[i])
7639 : return (" ");
7640 : }
7641 :
7642 : return ("; ");
7643 : }
7644 : #endif /* HISTORY */
7645 :
7646 : /* Issue a prompt, or prepare to issue a prompt when the next character
7647 : is read. */
7648 : static void
7649 : prompt_again ()
7650 : {
7651 : char *temp_prompt;
7652 :
7653 : if (interactive == 0 || expanding_alias ()) /* XXX */
7654 : return;
7655 :
7656 : ps1_prompt = get_string_value ("PS1");
7657 : ps2_prompt = get_string_value ("PS2");
7658 :
7659 : ps0_prompt = get_string_value ("PS0");
7660 :
7661 : if (!prompt_string_pointer)
7662 : prompt_string_pointer = &ps1_prompt;
7663 :
7664 : temp_prompt = *prompt_string_pointer
7665 : ? decode_prompt_string (*prompt_string_pointer)
7666 : : (char *)NULL;
7667 :
7668 : if (temp_prompt == 0)
7669 : {
7670 : temp_prompt = (char *)xmalloc (1);
7671 : temp_prompt[0] = '\0';
7672 : }
7673 :
7674 : current_prompt_string = *prompt_string_pointer;
7675 : prompt_string_pointer = &ps2_prompt;
7676 :
7677 : #if defined (READLINE)
7678 : if (!no_line_editing)
7679 : {
7680 : FREE (current_readline_prompt);
7681 : current_readline_prompt = temp_prompt;
7682 : }
7683 : else
7684 : #endif /* READLINE */
7685 : {
7686 : FREE (current_decoded_prompt);
7687 : current_decoded_prompt = temp_prompt;
7688 : }
7689 : }
7690 :
7691 : int
7692 : get_current_prompt_level ()
7693 : {
7694 : return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
7695 : }
7696 :
7697 : void
7698 : set_current_prompt_level (x)
7699 : int x;
7700 : {
7701 : prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
7702 : current_prompt_string = *prompt_string_pointer;
7703 : }
7704 :
7705 : static void
7706 : print_prompt ()
7707 : {
7708 : fprintf (stderr, "%s", current_decoded_prompt);
7709 : fflush (stderr);
7710 : }
7711 :
7712 : /* Return a string which will be printed as a prompt. The string
7713 : may contain special characters which are decoded as follows:
7714 :
7715 : \a bell (ascii 07)
7716 : \d the date in Day Mon Date format
7717 : \e escape (ascii 033)
7718 : \h the hostname up to the first `.'
7719 : \H the hostname
7720 : \j the number of active jobs
7721 : \l the basename of the shell's tty device name
7722 : \n CRLF
7723 : \r CR
7724 : \s the name of the shell
7725 : \t the time in 24-hour hh:mm:ss format
7726 : \T the time in 12-hour hh:mm:ss format
7727 : \@ the time in 12-hour hh:mm am/pm format
7728 : \A the time in 24-hour hh:mm format
7729 : \D{fmt} the result of passing FMT to strftime(3)
7730 : \u your username
7731 : \v the version of bash (e.g., 2.00)
7732 : \V the release of bash, version + patchlevel (e.g., 2.00.0)
7733 : \w the current working directory
7734 : \W the last element of $PWD
7735 : \! the history number of this command
7736 : \# the command number of this command
7737 : \$ a $ or a # if you are root
7738 : \nnn character code nnn in octal
7739 : \\ a backslash
7740 : \[ begin a sequence of non-printing chars
7741 : \] end a sequence of non-printing chars
7742 : */
7743 : #define PROMPT_GROWTH 48
7744 : char *
7745 : decode_prompt_string (string)
7746 : char *string;
7747 : {
7748 : WORD_LIST *list;
7749 : char *result, *t;
7750 : struct dstack save_dstack;
7751 : int last_exit_value, last_comsub_pid;
7752 : #if defined (PROMPT_STRING_DECODE)
7753 : size_t result_size;
7754 : int result_index;
7755 : int c, n;
7756 : #if defined (READLINE)
7757 : int i;
7758 : #endif
7759 : char *temp, *t_host, octal_string[4];
7760 : struct tm *tm;
7761 : time_t the_time;
7762 : char timebuf[128];
7763 : char *timefmt;
7764 :
7765 : result = (char *)xmalloc (result_size = PROMPT_GROWTH);
7766 : result[result_index = 0] = 0;
7767 : temp = (char *)NULL;
7768 :
7769 : while (c = *string++)
7770 : {
7771 : if (posixly_correct && c == '!')
7772 : {
7773 : if (*string == '!')
7774 : {
7775 : temp = savestring ("!");
7776 : goto add_string;
7777 : }
7778 : else
7779 : {
7780 : #if !defined (HISTORY)
7781 : temp = savestring ("1");
7782 : #else /* HISTORY */
7783 : temp = itos (history_number ());
7784 : #endif /* HISTORY */
7785 : string--; /* add_string increments string again. */
7786 : goto add_string;
7787 : }
7788 : }
7789 : if (c == '\\')
7790 : {
7791 : c = *string;
7792 :
7793 : switch (c)
7794 : {
7795 : case '0':
7796 : case '1':
7797 : case '2':
7798 : case '3':
7799 : case '4':
7800 : case '5':
7801 : case '6':
7802 : case '7':
7803 : strncpy (octal_string, string, 3);
7804 : octal_string[3] = '\0';
7805 :
7806 : n = read_octal (octal_string);
7807 : temp = (char *)xmalloc (3);
7808 :
7809 : if (n == CTLESC || n == CTLNUL)
7810 : {
7811 : temp[0] = CTLESC;
7812 : temp[1] = n;
7813 : temp[2] = '\0';
7814 : }
7815 : else if (n == -1)
7816 : {
7817 : temp[0] = '\\';
7818 : temp[1] = '\0';
7819 : }
7820 : else
7821 : {
7822 : temp[0] = n;
7823 : temp[1] = '\0';
7824 : }
7825 :
7826 : for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
7827 : string++;
7828 :
7829 : c = 0; /* tested at add_string: */
7830 : goto add_string;
7831 :
7832 : case 'd':
7833 : case 't':
7834 : case 'T':
7835 : case '@':
7836 : case 'A':
7837 : /* Make the current time/date into a string. */
7838 : (void) time (&the_time);
7839 : #if defined (HAVE_TZSET)
7840 : sv_tz ("TZ"); /* XXX -- just make sure */
7841 : #endif
7842 : tm = localtime (&the_time);
7843 :
7844 : if (c == 'd')
7845 : n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
7846 : else if (c == 't')
7847 : n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
7848 : else if (c == 'T')
7849 : n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
7850 : else if (c == '@')
7851 : n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
7852 : else if (c == 'A')
7853 : n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
7854 : else
7855 : n = 0;
7856 :
7857 : if (n == 0)
7858 : timebuf[0] = '\0';
7859 : else
7860 : timebuf[sizeof(timebuf) - 1] = '\0';
7861 :
7862 : temp = savestring (timebuf);
7863 : goto add_string;
7864 :
7865 : case 'D': /* strftime format */
7866 : if (string[1] != '{') /* } */
7867 : goto not_escape;
7868 :
7869 : (void) time (&the_time);
7870 : tm = localtime (&the_time);
7871 : string += 2; /* skip { */
7872 : timefmt = xmalloc (strlen (string) + 3);
7873 : for (t = timefmt; *string && *string != '}'; )
7874 : *t++ = *string++;
7875 : *t = '\0';
7876 : c = *string; /* tested at add_string */
7877 : if (timefmt[0] == '\0')
7878 : {
7879 : timefmt[0] = '%';
7880 : timefmt[1] = 'X'; /* locale-specific current time */
7881 : timefmt[2] = '\0';
7882 : }
7883 : n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
7884 : free (timefmt);
7885 :
7886 : if (n == 0)
7887 : timebuf[0] = '\0';
7888 : else
7889 : timebuf[sizeof(timebuf) - 1] = '\0';
7890 :
7891 : if (promptvars || posixly_correct)
7892 : /* Make sure that expand_prompt_string is called with a
7893 : second argument of Q_DOUBLE_QUOTES if we use this
7894 : function here. */
7895 : temp = sh_backslash_quote_for_double_quotes (timebuf);
7896 : else
7897 : temp = savestring (timebuf);
7898 : goto add_string;
7899 :
7900 : case 'n':
7901 : temp = (char *)xmalloc (3);
7902 : temp[0] = no_line_editing ? '\n' : '\r';
7903 : temp[1] = no_line_editing ? '\0' : '\n';
7904 : temp[2] = '\0';
7905 : goto add_string;
7906 :
7907 : case 's':
7908 : temp = base_pathname (shell_name);
7909 : /* Try to quote anything the user can set in the file system */
7910 : if (promptvars || posixly_correct)
7911 : temp = sh_backslash_quote_for_double_quotes (temp);
7912 : else
7913 : temp = savestring (temp);
7914 : goto add_string;
7915 :
7916 : case 'v':
7917 : case 'V':
7918 : temp = (char *)xmalloc (16);
7919 : if (c == 'v')
7920 : strcpy (temp, dist_version);
7921 : else
7922 : sprintf (temp, "%s.%d", dist_version, patch_level);
7923 : goto add_string;
7924 :
7925 : case 'w':
7926 : case 'W':
7927 : {
7928 : /* Use the value of PWD because it is much more efficient. */
7929 : char t_string[PATH_MAX];
7930 : int tlen;
7931 :
7932 : temp = get_string_value ("PWD");
7933 :
7934 : if (temp == 0)
7935 : {
7936 : if (getcwd (t_string, sizeof(t_string)) == 0)
7937 : {
7938 : t_string[0] = '.';
7939 : tlen = 1;
7940 : }
7941 : else
7942 : tlen = strlen (t_string);
7943 : }
7944 : else
7945 : {
7946 : tlen = sizeof (t_string) - 1;
7947 : strncpy (t_string, temp, tlen);
7948 : }
7949 : t_string[tlen] = '\0';
7950 :
7951 : #if defined (MACOSX)
7952 : /* Convert from "fs" format to "input" format */
7953 : temp = fnx_fromfs (t_string, strlen (t_string));
7954 : if (temp != t_string)
7955 : strcpy (t_string, temp);
7956 : #endif
7957 :
7958 : #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
7959 : #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
7960 : /* Abbreviate \W as ~ if $PWD == $HOME */
7961 : if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
7962 : {
7963 : if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
7964 : {
7965 : t = strrchr (t_string, '/');
7966 : if (t)
7967 : memmove (t_string, t + 1, strlen (t)); /* strlen(t) to copy NULL */
7968 : }
7969 : }
7970 : #undef ROOT_PATH
7971 : #undef DOUBLE_SLASH_ROOT
7972 : else
7973 : {
7974 : /* polite_directory_format is guaranteed to return a string
7975 : no longer than PATH_MAX - 1 characters. */
7976 : temp = polite_directory_format (t_string);
7977 : if (temp != t_string)
7978 : strcpy (t_string, temp);
7979 : }
7980 :
7981 : temp = trim_pathname (t_string, PATH_MAX - 1);
7982 : /* If we're going to be expanding the prompt string later,
7983 : quote the directory name. */
7984 : if (promptvars || posixly_correct)
7985 : /* Make sure that expand_prompt_string is called with a
7986 : second argument of Q_DOUBLE_QUOTES if we use this
7987 : function here. */
7988 : temp = sh_backslash_quote_for_double_quotes (t_string);
7989 : else
7990 : temp = savestring (t_string);
7991 :
7992 : goto add_string;
7993 : }
7994 :
7995 : case 'u':
7996 : if (current_user.user_name == 0)
7997 : get_current_user_info ();
7998 : temp = savestring (current_user.user_name);
7999 : goto add_string;
8000 :
8001 : case 'h':
8002 : case 'H':
8003 : t_host = savestring (current_host_name);
8004 : if (c == 'h' && (t = (char *)strchr (t_host, '.')))
8005 : *t = '\0';
8006 : if (promptvars || posixly_correct)
8007 : /* Make sure that expand_prompt_string is called with a
8008 : second argument of Q_DOUBLE_QUOTES if we use this
8009 : function here. */
8010 : temp = sh_backslash_quote_for_double_quotes (t_host);
8011 : else
8012 : temp = savestring (t_host);
8013 : free (t_host);
8014 : goto add_string;
8015 :
8016 : case '#':
8017 : temp = itos (current_command_number);
8018 : goto add_string;
8019 :
8020 : case '!':
8021 : #if !defined (HISTORY)
8022 : temp = savestring ("1");
8023 : #else /* HISTORY */
8024 : temp = itos (history_number ());
8025 : #endif /* HISTORY */
8026 : goto add_string;
8027 :
8028 : case '$':
8029 : t = temp = (char *)xmalloc (3);
8030 : if ((promptvars || posixly_correct) && (current_user.euid != 0))
8031 : *t++ = '\\';
8032 : *t++ = current_user.euid == 0 ? '#' : '$';
8033 : *t = '\0';
8034 : goto add_string;
8035 :
8036 : case 'j':
8037 : temp = itos (count_all_jobs ());
8038 : goto add_string;
8039 :
8040 : case 'l':
8041 : #if defined (HAVE_TTYNAME)
8042 : temp = (char *)ttyname (fileno (stdin));
8043 : t = temp ? base_pathname (temp) : "tty";
8044 : temp = savestring (t);
8045 : #else
8046 : temp = savestring ("tty");
8047 : #endif /* !HAVE_TTYNAME */
8048 : goto add_string;
8049 :
8050 : #if defined (READLINE)
8051 : case '[':
8052 : case ']':
8053 : if (no_line_editing)
8054 : {
8055 : string++;
8056 : break;
8057 : }
8058 : temp = (char *)xmalloc (3);
8059 : n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
8060 : i = 0;
8061 : if (n == CTLESC || n == CTLNUL)
8062 : temp[i++] = CTLESC;
8063 : temp[i++] = n;
8064 : temp[i] = '\0';
8065 : goto add_string;
8066 : #endif /* READLINE */
8067 :
8068 : case '\\':
8069 : case 'a':
8070 : case 'e':
8071 : case 'r':
8072 : temp = (char *)xmalloc (2);
8073 : if (c == 'a')
8074 : temp[0] = '\07';
8075 : else if (c == 'e')
8076 : temp[0] = '\033';
8077 : else if (c == 'r')
8078 : temp[0] = '\r';
8079 : else /* (c == '\\') */
8080 : temp[0] = c;
8081 : temp[1] = '\0';
8082 : goto add_string;
8083 :
8084 : default:
8085 : not_escape:
8086 : temp = (char *)xmalloc (3);
8087 : temp[0] = '\\';
8088 : temp[1] = c;
8089 : temp[2] = '\0';
8090 :
8091 : add_string:
8092 : if (c)
8093 : string++;
8094 : result =
8095 : sub_append_string (temp, result, &result_index, &result_size);
8096 : temp = (char *)NULL; /* Freed in sub_append_string (). */
8097 : result[result_index] = '\0';
8098 : break;
8099 : }
8100 : }
8101 : else
8102 : {
8103 : RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
8104 : /* dequote_string should take care of removing this if we are not
8105 : performing the rest of the word expansions. */
8106 : if (c == CTLESC || c == CTLNUL)
8107 : result[result_index++] = CTLESC;
8108 : result[result_index++] = c;
8109 : result[result_index] = '\0';
8110 : }
8111 : }
8112 : #else /* !PROMPT_STRING_DECODE */
8113 : result = savestring (string);
8114 : #endif /* !PROMPT_STRING_DECODE */
8115 :
8116 : /* Save the delimiter stack and point `dstack' to temp space so any
8117 : command substitutions in the prompt string won't result in screwing
8118 : up the parser's quoting state. */
8119 : save_dstack = dstack;
8120 : dstack = temp_dstack;
8121 : dstack.delimiter_depth = 0;
8122 :
8123 : /* Perform variable and parameter expansion and command substitution on
8124 : the prompt string. */
8125 : if (promptvars || posixly_correct)
8126 : {
8127 : last_exit_value = last_command_exit_value;
8128 : last_comsub_pid = last_command_subst_pid;
8129 : list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
8130 : free (result);
8131 : result = string_list (list);
8132 : dispose_words (list);
8133 : last_command_exit_value = last_exit_value;
8134 : last_command_subst_pid = last_comsub_pid;
8135 : }
8136 : else
8137 : {
8138 : t = dequote_string (result);
8139 : free (result);
8140 : result = t;
8141 : }
8142 :
8143 : dstack = save_dstack;
8144 :
8145 : return (result);
8146 : }
8147 :
8148 : /************************************************
8149 : * *
8150 : * ERROR HANDLING *
8151 : * *
8152 : ************************************************/
8153 :
8154 : /* Report a syntax error, and restart the parser. Call here for fatal
8155 : errors. */
8156 : int
8157 : yyerror (msg)
8158 : const char *msg;
8159 : {
8160 : report_syntax_error ((char *)NULL);
8161 : reset_parser ();
8162 : return (0);
8163 : }
8164 :
8165 : static char *
8166 : error_token_from_token (tok)
8167 : int tok;
8168 : {
8169 : char *t;
8170 :
8171 : if (t = find_token_in_alist (tok, word_token_alist, 0))
8172 : return t;
8173 :
8174 : if (t = find_token_in_alist (tok, other_token_alist, 0))
8175 : return t;
8176 :
8177 : t = (char *)NULL;
8178 : /* This stuff is dicy and needs closer inspection */
8179 : switch (current_token)
8180 : {
8181 : case WORD:
8182 : case ASSIGNMENT_WORD:
8183 : if (yylval.word)
8184 : t = savestring (yylval.word->word);
8185 : break;
8186 : case NUMBER:
8187 : t = itos (yylval.number);
8188 : break;
8189 : case ARITH_CMD:
8190 : if (yylval.word_list)
8191 : t = string_list (yylval.word_list);
8192 : break;
8193 : case ARITH_FOR_EXPRS:
8194 : if (yylval.word_list)
8195 : t = string_list_internal (yylval.word_list, " ; ");
8196 : break;
8197 : case COND_CMD:
8198 : t = (char *)NULL; /* punt */
8199 : break;
8200 : }
8201 :
8202 : return t;
8203 : }
8204 :
8205 : static char *
8206 : error_token_from_text ()
8207 : {
8208 : char *msg, *t;
8209 : int token_end, i;
8210 :
8211 : t = shell_input_line;
8212 : i = shell_input_line_index;
8213 : token_end = 0;
8214 : msg = (char *)NULL;
8215 :
8216 : if (i && t[i] == '\0')
8217 : i--;
8218 :
8219 : while (i && (whitespace (t[i]) || t[i] == '\n'))
8220 : i--;
8221 :
8222 : if (i)
8223 : token_end = i + 1;
8224 :
8225 : while (i && (member (t[i], " \n\t;|&") == 0))
8226 : i--;
8227 :
8228 : while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
8229 : i++;
8230 :
8231 : /* Return our idea of the offending token. */
8232 : if (token_end || (i == 0 && token_end == 0))
8233 : {
8234 : if (token_end)
8235 : msg = substring (t, i, token_end);
8236 : else /* one-character token */
8237 : {
8238 : msg = (char *)xmalloc (2);
8239 : msg[0] = t[i];
8240 : msg[1] = '\0';
8241 : }
8242 : }
8243 :
8244 : return (msg);
8245 : }
8246 :
8247 : static void
8248 : print_offending_line ()
8249 : {
8250 : char *msg;
8251 : int token_end;
8252 :
8253 : msg = savestring (shell_input_line);
8254 : token_end = strlen (msg);
8255 : while (token_end && msg[token_end - 1] == '\n')
8256 : msg[--token_end] = '\0';
8257 :
8258 : parser_error (line_number, "`%s'", msg);
8259 : free (msg);
8260 : }
8261 :
8262 : /* Report a syntax error with line numbers, etc.
8263 : Call here for recoverable errors. If you have a message to print,
8264 : then place it in MESSAGE, otherwise pass NULL and this will figure
8265 : out an appropriate message for you. */
8266 : static void
8267 : report_syntax_error (message)
8268 : char *message;
8269 : {
8270 : char *msg, *p;
8271 :
8272 : if (message)
8273 : {
8274 : parser_error (line_number, "%s", message);
8275 : if (interactive && EOF_Reached)
8276 : EOF_Reached = 0;
8277 : last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
8278 : return;
8279 : }
8280 :
8281 : /* If the line of input we're reading is not null, try to find the
8282 : objectionable token. First, try to figure out what token the
8283 : parser's complaining about by looking at current_token. */
8284 : if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
8285 : {
8286 : if (ansic_shouldquote (msg))
8287 : {
8288 : p = ansic_quote (msg, 0, NULL);
8289 : free (msg);
8290 : msg = p;
8291 : }
8292 : parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
8293 : free (msg);
8294 :
8295 : if (interactive == 0)
8296 : print_offending_line ();
8297 :
8298 : last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
8299 : return;
8300 : }
8301 :
8302 : /* If looking at the current token doesn't prove fruitful, try to find the
8303 : offending token by analyzing the text of the input line near the current
8304 : input line index and report what we find. */
8305 : if (shell_input_line && *shell_input_line)
8306 : {
8307 : msg = error_token_from_text ();
8308 : if (msg)
8309 : {
8310 : parser_error (line_number, _("syntax error near `%s'"), msg);
8311 : free (msg);
8312 : }
8313 :
8314 : /* If not interactive, print the line containing the error. */
8315 : if (interactive == 0)
8316 : print_offending_line ();
8317 : }
8318 : else
8319 : {
8320 : msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
8321 : parser_error (line_number, "%s", msg);
8322 : /* When the shell is interactive, this file uses EOF_Reached
8323 : only for error reporting. Other mechanisms are used to
8324 : decide whether or not to exit. */
8325 : if (interactive && EOF_Reached)
8326 : EOF_Reached = 0;
8327 : }
8328 :
8329 : last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
8330 : }
8331 :
8332 : #if 0
8333 : /* ??? Needed function. ??? We have to be able to discard the constructs
8334 : created during parsing. In the case of error, we want to return
8335 : allocated objects to the memory pool. In the case of no error, we want
8336 : to throw away the information about where the allocated objects live.
8337 : (dispose_command () will actually free the command.) */
8338 : static void
8339 : discard_parser_constructs (error_p)
8340 : int error_p;
8341 : {
8342 : }
8343 : #endif
8344 :
8345 : /************************************************
8346 : * *
8347 : * EOF HANDLING *
8348 : * *
8349 : ************************************************/
8350 :
8351 : /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
8352 :
8353 : /* A flag denoting whether or not ignoreeof is set. */
8354 : int ignoreeof = 0;
8355 :
8356 : /* The number of times that we have encountered an EOF character without
8357 : another character intervening. When this gets above the limit, the
8358 : shell terminates. */
8359 : int eof_encountered = 0;
8360 :
8361 : /* The limit for eof_encountered. */
8362 : int eof_encountered_limit = 10;
8363 :
8364 : /* If we have EOF as the only input unit, this user wants to leave
8365 : the shell. If the shell is not interactive, then just leave.
8366 : Otherwise, if ignoreeof is set, and we haven't done this the
8367 : required number of times in a row, print a message. */
8368 : static void
8369 : handle_eof_input_unit ()
8370 : {
8371 : if (interactive)
8372 : {
8373 : /* shell.c may use this to decide whether or not to write out the
8374 : history, among other things. We use it only for error reporting
8375 : in this file. */
8376 : if (EOF_Reached)
8377 : EOF_Reached = 0;
8378 :
8379 : /* If the user wants to "ignore" eof, then let her do so, kind of. */
8380 : if (ignoreeof)
8381 : {
8382 : if (eof_encountered < eof_encountered_limit)
8383 : {
8384 : fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
8385 : login_shell ? "logout" : "exit");
8386 : eof_encountered++;
8387 : /* Reset the parsing state. */
8388 : last_read_token = current_token = '\n';
8389 : /* Reset the prompt string to be $PS1. */
8390 : prompt_string_pointer = (char **)NULL;
8391 : prompt_again ();
8392 : return;
8393 : }
8394 : }
8395 :
8396 : /* In this case EOF should exit the shell. Do it now. */
8397 : reset_parser ();
8398 : exit_builtin ((WORD_LIST *)NULL);
8399 : }
8400 : else
8401 : {
8402 : /* We don't write history files, etc., for non-interactive shells. */
8403 : EOF_Reached = 1;
8404 : }
8405 : }
8406 :
8407 : /************************************************
8408 : * *
8409 : * STRING PARSING FUNCTIONS *
8410 : * *
8411 : ************************************************/
8412 :
8413 : /* It's very important that these two functions treat the characters
8414 : between ( and ) identically. */
8415 :
8416 : static WORD_LIST parse_string_error;
8417 :
8418 : /* Take a string and run it through the shell parser, returning the
8419 : resultant word list. Used by compound array assignment. */
8420 : WORD_LIST *
8421 : parse_string_to_word_list (s, flags, whom)
8422 : char *s;
8423 : int flags;
8424 : const char *whom;
8425 : {
8426 : WORD_LIST *wl;
8427 : int tok, orig_current_token, orig_line_number, orig_input_terminator;
8428 : int orig_line_count;
8429 : int old_echo_input, old_expand_aliases;
8430 : #if defined (HISTORY)
8431 : int old_remember_on_history, old_history_expansion_inhibited;
8432 : #endif
8433 :
8434 : #if defined (HISTORY)
8435 : old_remember_on_history = remember_on_history;
8436 : # if defined (BANG_HISTORY)
8437 : old_history_expansion_inhibited = history_expansion_inhibited;
8438 : # endif
8439 : bash_history_disable ();
8440 : #endif
8441 :
8442 : orig_line_number = line_number;
8443 : orig_line_count = current_command_line_count;
8444 : orig_input_terminator = shell_input_line_terminator;
8445 : old_echo_input = echo_input_at_read;
8446 : old_expand_aliases = expand_aliases;
8447 :
8448 : push_stream (1);
8449 : last_read_token = WORD; /* WORD to allow reserved words here */
8450 : current_command_line_count = 0;
8451 : echo_input_at_read = expand_aliases = 0;
8452 :
8453 : with_input_from_string (s, whom);
8454 : wl = (WORD_LIST *)NULL;
8455 :
8456 : if (flags & 1)
8457 : parser_state |= PST_COMPASSIGN|PST_REPARSE;
8458 :
8459 : while ((tok = read_token (READ)) != yacc_EOF)
8460 : {
8461 : if (tok == '\n' && *bash_input.location.string == '\0')
8462 : break;
8463 : if (tok == '\n') /* Allow newlines in compound assignments */
8464 : continue;
8465 : if (tok != WORD && tok != ASSIGNMENT_WORD)
8466 : {
8467 : line_number = orig_line_number + line_number - 1;
8468 : orig_current_token = current_token;
8469 : current_token = tok;
8470 : yyerror (NULL); /* does the right thing */
8471 : current_token = orig_current_token;
8472 : if (wl)
8473 : dispose_words (wl);
8474 : wl = &parse_string_error;
8475 : break;
8476 : }
8477 : wl = make_word_list (yylval.word, wl);
8478 : }
8479 :
8480 : last_read_token = '\n';
8481 : pop_stream ();
8482 :
8483 : #if defined (HISTORY)
8484 : remember_on_history = old_remember_on_history;
8485 : # if defined (BANG_HISTORY)
8486 : history_expansion_inhibited = old_history_expansion_inhibited;
8487 : # endif /* BANG_HISTORY */
8488 : #endif /* HISTORY */
8489 :
8490 : echo_input_at_read = old_echo_input;
8491 : expand_aliases = old_expand_aliases;
8492 :
8493 : current_command_line_count = orig_line_count;
8494 : shell_input_line_terminator = orig_input_terminator;
8495 :
8496 : if (flags & 1)
8497 : parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
8498 :
8499 : if (wl == &parse_string_error)
8500 : {
8501 : last_command_exit_value = EXECUTION_FAILURE;
8502 : if (interactive_shell == 0 && posixly_correct)
8503 : jump_to_top_level (FORCE_EOF);
8504 : else
8505 : jump_to_top_level (DISCARD);
8506 : }
8507 :
8508 : return (REVERSE_LIST (wl, WORD_LIST *));
8509 : }
8510 :
8511 : static char *
8512 : parse_compound_assignment (retlenp)
8513 : int *retlenp;
8514 : {
8515 : WORD_LIST *wl, *rl;
8516 : int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
8517 : char *saved_token, *ret;
8518 :
8519 : saved_token = token;
8520 : orig_token_size = token_buffer_size;
8521 : orig_line_number = line_number;
8522 : orig_last_token = last_read_token;
8523 :
8524 : last_read_token = WORD; /* WORD to allow reserved words here */
8525 :
8526 : token = (char *)NULL;
8527 : token_buffer_size = 0;
8528 :
8529 : assignok = parser_state&PST_ASSIGNOK; /* XXX */
8530 :
8531 : wl = (WORD_LIST *)NULL; /* ( */
8532 : parser_state |= PST_COMPASSIGN;
8533 :
8534 : while ((tok = read_token (READ)) != ')')
8535 : {
8536 : if (tok == '\n') /* Allow newlines in compound assignments */
8537 : {
8538 : if (SHOULD_PROMPT ())
8539 : prompt_again ();
8540 : continue;
8541 : }
8542 : if (tok != WORD && tok != ASSIGNMENT_WORD)
8543 : {
8544 : current_token = tok; /* for error reporting */
8545 : if (tok == yacc_EOF) /* ( */
8546 : parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
8547 : else
8548 : yyerror(NULL); /* does the right thing */
8549 : if (wl)
8550 : dispose_words (wl);
8551 : wl = &parse_string_error;
8552 : break;
8553 : }
8554 : wl = make_word_list (yylval.word, wl);
8555 : }
8556 :
8557 : FREE (token);
8558 : token = saved_token;
8559 : token_buffer_size = orig_token_size;
8560 :
8561 : parser_state &= ~PST_COMPASSIGN;
8562 :
8563 : if (wl == &parse_string_error)
8564 : {
8565 : last_command_exit_value = EXECUTION_FAILURE;
8566 : last_read_token = '\n'; /* XXX */
8567 : if (interactive_shell == 0 && posixly_correct)
8568 : jump_to_top_level (FORCE_EOF);
8569 : else
8570 : jump_to_top_level (DISCARD);
8571 : }
8572 :
8573 : last_read_token = orig_last_token; /* XXX - was WORD? */
8574 :
8575 : if (wl)
8576 : {
8577 : rl = REVERSE_LIST (wl, WORD_LIST *);
8578 : ret = string_list (rl);
8579 : dispose_words (rl);
8580 : }
8581 : else
8582 : ret = (char *)NULL;
8583 :
8584 : if (retlenp)
8585 : *retlenp = (ret && *ret) ? strlen (ret) : 0;
8586 :
8587 : if (assignok)
8588 : parser_state |= PST_ASSIGNOK;
8589 :
8590 : return ret;
8591 : }
8592 :
8593 : /************************************************
8594 : * *
8595 : * SAVING AND RESTORING PARTIAL PARSE STATE *
8596 : * *
8597 : ************************************************/
8598 :
8599 : sh_parser_state_t *
8600 : save_parser_state (ps)
8601 : sh_parser_state_t *ps;
8602 : {
8603 : if (ps == 0)
8604 : ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
8605 : if (ps == 0)
8606 : return ((sh_parser_state_t *)NULL);
8607 :
8608 : ps->parser_state = parser_state;
8609 : ps->token_state = save_token_state ();
8610 :
8611 : ps->input_line_terminator = shell_input_line_terminator;
8612 : ps->eof_encountered = eof_encountered;
8613 :
8614 : ps->prompt_string_pointer = prompt_string_pointer;
8615 :
8616 : ps->current_command_line_count = current_command_line_count;
8617 :
8618 : #if defined (HISTORY)
8619 : ps->remember_on_history = remember_on_history;
8620 : # if defined (BANG_HISTORY)
8621 : ps->history_expansion_inhibited = history_expansion_inhibited;
8622 : # endif
8623 : #endif
8624 :
8625 : ps->last_command_exit_value = last_command_exit_value;
8626 : #if defined (ARRAY_VARS)
8627 : ps->pipestatus = save_pipestatus_array ();
8628 : #endif
8629 :
8630 : ps->last_shell_builtin = last_shell_builtin;
8631 : ps->this_shell_builtin = this_shell_builtin;
8632 :
8633 : ps->expand_aliases = expand_aliases;
8634 : ps->echo_input_at_read = echo_input_at_read;
8635 : ps->need_here_doc = need_here_doc;
8636 : ps->here_doc_first_line = here_doc_first_line;
8637 :
8638 : #if 0
8639 : for (i = 0; i < HEREDOC_MAX; i++)
8640 : ps->redir_stack[i] = redir_stack[i];
8641 : #else
8642 : if (need_here_doc == 0)
8643 : ps->redir_stack[0] = 0;
8644 : else
8645 : memcpy (ps->redir_stack, redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
8646 : #endif
8647 :
8648 : ps->token = token;
8649 : ps->token_buffer_size = token_buffer_size;
8650 : /* Force reallocation on next call to read_token_word */
8651 : token = 0;
8652 : token_buffer_size = 0;
8653 :
8654 : return (ps);
8655 : }
8656 :
8657 : void
8658 : restore_parser_state (ps)
8659 : sh_parser_state_t *ps;
8660 : {
8661 : if (ps == 0)
8662 : return;
8663 :
8664 : parser_state = ps->parser_state;
8665 : if (ps->token_state)
8666 : {
8667 : restore_token_state (ps->token_state);
8668 : free (ps->token_state);
8669 : }
8670 :
8671 : shell_input_line_terminator = ps->input_line_terminator;
8672 : eof_encountered = ps->eof_encountered;
8673 :
8674 : prompt_string_pointer = ps->prompt_string_pointer;
8675 :
8676 : current_command_line_count = ps->current_command_line_count;
8677 :
8678 : #if defined (HISTORY)
8679 : remember_on_history = ps->remember_on_history;
8680 : # if defined (BANG_HISTORY)
8681 : history_expansion_inhibited = ps->history_expansion_inhibited;
8682 : # endif
8683 : #endif
8684 :
8685 : last_command_exit_value = ps->last_command_exit_value;
8686 : #if defined (ARRAY_VARS)
8687 : restore_pipestatus_array (ps->pipestatus);
8688 : #endif
8689 :
8690 : last_shell_builtin = ps->last_shell_builtin;
8691 : this_shell_builtin = ps->this_shell_builtin;
8692 :
8693 : expand_aliases = ps->expand_aliases;
8694 : echo_input_at_read = ps->echo_input_at_read;
8695 : need_here_doc = ps->need_here_doc;
8696 : here_doc_first_line = ps->here_doc_first_line;
8697 :
8698 : #if 0
8699 : for (i = 0; i < HEREDOC_MAX; i++)
8700 : redir_stack[i] = ps->redir_stack[i];
8701 : #else
8702 : if (need_here_doc == 0)
8703 : redir_stack[0] = 0;
8704 : else
8705 : memcpy (redir_stack, ps->redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
8706 : #endif
8707 :
8708 : FREE (token);
8709 : token = ps->token;
8710 : token_buffer_size = ps->token_buffer_size;
8711 : }
8712 :
8713 : sh_input_line_state_t *
8714 : save_input_line_state (ls)
8715 : sh_input_line_state_t *ls;
8716 : {
8717 : if (ls == 0)
8718 : ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
8719 : if (ls == 0)
8720 : return ((sh_input_line_state_t *)NULL);
8721 :
8722 : ls->input_line = shell_input_line;
8723 : ls->input_line_size = shell_input_line_size;
8724 : ls->input_line_len = shell_input_line_len;
8725 : ls->input_line_index = shell_input_line_index;
8726 :
8727 : /* force reallocation */
8728 : shell_input_line = 0;
8729 : shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
8730 :
8731 : return ls;
8732 : }
8733 :
8734 : void
8735 : restore_input_line_state (ls)
8736 : sh_input_line_state_t *ls;
8737 : {
8738 : FREE (shell_input_line);
8739 : shell_input_line = ls->input_line;
8740 : shell_input_line_size = ls->input_line_size;
8741 : shell_input_line_len = ls->input_line_len;
8742 : shell_input_line_index = ls->input_line_index;
8743 :
8744 : set_line_mbstate ();
8745 : }
8746 :
8747 : /************************************************
8748 : * *
8749 : * MULTIBYTE CHARACTER HANDLING *
8750 : * *
8751 : ************************************************/
8752 :
8753 : #if defined (HANDLE_MULTIBYTE)
8754 : static void
8755 : set_line_mbstate ()
8756 : {
8757 : int c;
8758 : size_t i, previ, len;
8759 : mbstate_t mbs, prevs;
8760 : size_t mbclen;
8761 :
8762 : if (shell_input_line == NULL)
8763 : return;
8764 : len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */
8765 : shell_input_line_property = (char *)xrealloc (shell_input_line_property, len + 1);
8766 :
8767 : memset (&prevs, '\0', sizeof (mbstate_t));
8768 : for (i = previ = 0; i < len; i++)
8769 : {
8770 : mbs = prevs;
8771 :
8772 : c = shell_input_line[i];
8773 : if (c == EOF)
8774 : {
8775 : size_t j;
8776 : for (j = i; j < len; j++)
8777 : shell_input_line_property[j] = 1;
8778 : break;
8779 : }
8780 :
8781 : mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
8782 : if (mbclen == 1 || mbclen == (size_t)-1)
8783 : {
8784 : mbclen = 1;
8785 : previ = i + 1;
8786 : }
8787 : else if (mbclen == (size_t)-2)
8788 : mbclen = 0;
8789 : else if (mbclen > 1)
8790 : {
8791 : mbclen = 0;
8792 : previ = i + 1;
8793 : prevs = mbs;
8794 : }
8795 : else
8796 : {
8797 : /* XXX - what to do if mbrlen returns 0? (null wide character) */
8798 : size_t j;
8799 : for (j = i; j < len; j++)
8800 : shell_input_line_property[j] = 1;
8801 : break;
8802 : }
8803 :
8804 : shell_input_line_property[i] = mbclen;
8805 : }
8806 : }
8807 : #endif /* HANDLE_MULTIBYTE */
|