]> git.ipfire.org Git - thirdparty/bash.git/blob - y.tab.c
Imported from ../bash-2.03.tar.gz.
[thirdparty/bash.git] / y.tab.c
1
2 /* A Bison parser, made from /usr/homes/chet/src/bash/src/parse.y
3 by GNU Bison version 1.25
4 */
5
6 #define YYBISON 1 /* Identify Bison output. */
7
8 #define IF 258
9 #define THEN 259
10 #define ELSE 260
11 #define ELIF 261
12 #define FI 262
13 #define CASE 263
14 #define ESAC 264
15 #define FOR 265
16 #define SELECT 266
17 #define WHILE 267
18 #define UNTIL 268
19 #define DO 269
20 #define DONE 270
21 #define FUNCTION 271
22 #define COND_START 272
23 #define COND_END 273
24 #define COND_ERROR 274
25 #define IN 275
26 #define BANG 276
27 #define TIME 277
28 #define TIMEOPT 278
29 #define WORD 279
30 #define ASSIGNMENT_WORD 280
31 #define NUMBER 281
32 #define ARITH_CMD 282
33 #define COND_CMD 283
34 #define AND_AND 284
35 #define OR_OR 285
36 #define GREATER_GREATER 286
37 #define LESS_LESS 287
38 #define LESS_AND 288
39 #define GREATER_AND 289
40 #define SEMI_SEMI 290
41 #define LESS_LESS_MINUS 291
42 #define AND_GREATER 292
43 #define LESS_GREATER 293
44 #define GREATER_BAR 294
45 #define yacc_EOF 295
46
47 #line 21 "/usr/homes/chet/src/bash/src/parse.y"
48
49 #include "config.h"
50
51 #include "bashtypes.h"
52 #include "bashansi.h"
53
54 #if defined (HAVE_UNISTD_H)
55 # include <unistd.h>
56 #endif
57
58 #if defined (HAVE_LOCALE_H)
59 # include <locale.h>
60 #endif
61
62 #include <stdio.h>
63 #include <signal.h>
64
65 #include "memalloc.h"
66
67 #include "shell.h"
68 #include "trap.h"
69 #include "flags.h"
70 #include "parser.h"
71 #include "mailcheck.h"
72 #include "builtins/common.h"
73 #include "builtins/builtext.h"
74
75 #if defined (READLINE)
76 # include "bashline.h"
77 # include <readline/readline.h>
78 #endif /* READLINE */
79
80 #if defined (HISTORY)
81 # include "bashhist.h"
82 # include <readline/history.h>
83 #endif /* HISTORY */
84
85 #if defined (JOB_CONTROL)
86 # include "jobs.h"
87 #endif /* JOB_CONTROL */
88
89 #if defined (ALIAS)
90 # include "alias.h"
91 #endif /* ALIAS */
92
93 #if defined (PROMPT_STRING_DECODE)
94 # ifndef _MINIX
95 # include <sys/param.h>
96 # endif
97 # include <time.h>
98 # include "maxpath.h"
99 #endif /* PROMPT_STRING_DECODE */
100
101 #define RE_READ_TOKEN -99
102 #define NO_EXPANSION -100
103
104 #define YYDEBUG 0
105
106 #if defined (EXTENDED_GLOB)
107 #define PATTERN_CHAR(c) \
108 ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!')
109
110 extern int extended_glob;
111 #endif
112
113 extern int eof_encountered;
114 extern int no_line_editing, running_under_emacs;
115 extern int current_command_number;
116 extern int interactive, interactive_shell, login_shell;
117 extern int sourcelevel;
118 extern int posixly_correct;
119 extern int last_command_exit_value;
120 extern int interrupt_immediately;
121 extern char *shell_name, *current_host_name;
122 extern char *dist_version;
123 extern int patch_level;
124 extern int dump_translatable_strings, dump_po_strings;
125 extern Function *last_shell_builtin, *this_shell_builtin;
126 #if defined (BUFFERED_INPUT)
127 extern int bash_input_fd_changed;
128 #endif
129
130 /* **************************************************************** */
131 /* */
132 /* "Forward" declarations */
133 /* */
134 /* **************************************************************** */
135
136 static char *ansiexpand ();
137 static char *localeexpand ();
138 static int reserved_word_acceptable ();
139 static int read_token ();
140 static int yylex ();
141 static int parse_arith_cmd ();
142 #if defined (COND_COMMAND)
143 static COMMAND *parse_cond_command ();
144 #endif
145 static int read_token_word ();
146 static void discard_parser_constructs ();
147
148 static void report_syntax_error ();
149 static void handle_eof_input_unit ();
150 static void prompt_again ();
151 #if 0
152 static void reset_readline_prompt ();
153 #endif
154 static void print_prompt ();
155
156 extern int yyerror ();
157
158 /* Default prompt strings */
159 char *primary_prompt = PPROMPT;
160 char *secondary_prompt = SPROMPT;
161
162 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
163 char *ps1_prompt, *ps2_prompt;
164
165 /* Handle on the current prompt string. Indirectly points through
166 ps1_ or ps2_prompt. */
167 char **prompt_string_pointer = (char **)NULL;
168 char *current_prompt_string;
169
170 /* Non-zero means we expand aliases in commands. */
171 int expand_aliases = 0;
172
173 /* If non-zero, the decoded prompt string undergoes parameter and
174 variable substitution, command substitution, arithmetic substitution,
175 string expansion, process substitution, and quote removal in
176 decode_prompt_string. */
177 int promptvars = 1;
178
179 /* The decoded prompt string. Used if READLINE is not defined or if
180 editing is turned off. Analogous to current_readline_prompt. */
181 static char *current_decoded_prompt;
182
183 /* The number of lines read from input while creating the current command. */
184 int current_command_line_count;
185
186 /* Variables to manage the task of reading here documents, because we need to
187 defer the reading until after a complete command has been collected. */
188 static REDIRECT *redir_stack[10];
189 int need_here_doc;
190
191 /* Where shell input comes from. History expansion is performed on each
192 line when the shell is interactive. */
193 static char *shell_input_line = (char *)NULL;
194 static int shell_input_line_index;
195 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
196 static int shell_input_line_len; /* strlen (shell_input_line) */
197
198 /* Either zero or EOF. */
199 static int shell_input_line_terminator;
200
201 /* The line number in a script on which a function definition starts. */
202 static int function_dstart;
203
204 /* The line number in a script on which a function body starts. */
205 static int function_bstart;
206
207 static REDIRECTEE redir;
208
209 #line 183 "/usr/homes/chet/src/bash/src/parse.y"
210 typedef union {
211 WORD_DESC *word; /* the word that we read. */
212 int number; /* the number that we read. */
213 WORD_LIST *word_list;
214 COMMAND *command;
215 REDIRECT *redirect;
216 ELEMENT element;
217 PATTERN_LIST *pattern;
218 } YYSTYPE;
219 #include <stdio.h>
220
221 #ifndef __cplusplus
222 #ifndef __STDC__
223 #define const
224 #endif
225 #endif
226
227
228
229 #define YYFINAL 269
230 #define YYFLAG -32768
231 #define YYNTBASE 52
232
233 #define YYTRANSLATE(x) ((unsigned)(x) <= 295 ? yytranslate[x] : 85)
234
235 static const char yytranslate[] = { 0,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 42,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 2, 2, 40, 2, 50,
240 51, 2, 2, 2, 47, 2, 2, 2, 2, 2,
241 2, 2, 2, 2, 2, 2, 2, 2, 41, 46,
242 2, 45, 2, 2, 2, 2, 2, 2, 2, 2,
243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
245 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
246 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 48, 44, 49, 2, 2, 2, 2, 2,
249 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
250 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
251 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
252 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
253 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
254 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
255 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
256 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
257 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
258 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
259 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
260 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
261 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
262 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
263 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
264 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
265 36, 37, 38, 39, 43
266 };
267
268 #if YYDEBUG != 0
269 static const short yyprhs[] = { 0,
270 0, 3, 5, 8, 10, 12, 15, 18, 21, 25,
271 29, 32, 36, 39, 43, 46, 50, 53, 57, 60,
272 64, 67, 71, 74, 78, 81, 85, 88, 92, 95,
273 99, 102, 105, 109, 111, 113, 115, 117, 120, 122,
274 125, 127, 129, 132, 134, 136, 142, 148, 150, 152,
275 154, 156, 158, 160, 162, 169, 176, 184, 192, 203,
276 214, 221, 228, 236, 244, 255, 266, 273, 281, 288,
277 294, 301, 306, 310, 316, 324, 331, 335, 337, 341,
278 346, 353, 359, 361, 364, 369, 374, 380, 386, 389,
279 393, 395, 399, 402, 404, 407, 411, 415, 419, 424,
280 429, 434, 439, 444, 446, 448, 450, 452, 453, 456,
281 458, 461, 464, 469, 474, 478, 482, 484, 486, 489,
282 492, 496, 500, 505, 507, 509
283 };
284
285 static const short yyrhs[] = { 80,
286 42, 0, 42, 0, 1, 42, 0, 43, 0, 24,
287 0, 53, 24, 0, 45, 24, 0, 46, 24, 0,
288 26, 45, 24, 0, 26, 46, 24, 0, 31, 24,
289 0, 26, 31, 24, 0, 32, 24, 0, 26, 32,
290 24, 0, 33, 26, 0, 26, 33, 26, 0, 34,
291 26, 0, 26, 34, 26, 0, 33, 24, 0, 26,
292 33, 24, 0, 34, 24, 0, 26, 34, 24, 0,
293 36, 24, 0, 26, 36, 24, 0, 34, 47, 0,
294 26, 34, 47, 0, 33, 47, 0, 26, 33, 47,
295 0, 37, 24, 0, 26, 38, 24, 0, 38, 24,
296 0, 39, 24, 0, 26, 39, 24, 0, 24, 0,
297 25, 0, 54, 0, 54, 0, 56, 54, 0, 55,
298 0, 57, 55, 0, 57, 0, 59, 0, 59, 56,
299 0, 60, 0, 62, 0, 12, 75, 14, 75, 15,
300 0, 13, 75, 14, 75, 15, 0, 61, 0, 65,
301 0, 64, 0, 66, 0, 67, 0, 68, 0, 63,
302 0, 10, 24, 79, 14, 75, 15, 0, 10, 24,
303 79, 48, 75, 49, 0, 10, 24, 41, 79, 14,
304 75, 15, 0, 10, 24, 41, 79, 48, 75, 49,
305 0, 10, 24, 79, 20, 53, 78, 79, 14, 75,
306 15, 0, 10, 24, 79, 20, 53, 78, 79, 48,
307 75, 49, 0, 11, 24, 79, 14, 74, 15, 0,
308 11, 24, 79, 48, 74, 49, 0, 11, 24, 41,
309 79, 14, 74, 15, 0, 11, 24, 41, 79, 48,
310 74, 49, 0, 11, 24, 79, 20, 53, 78, 79,
311 14, 74, 15, 0, 11, 24, 79, 20, 53, 78,
312 79, 48, 74, 49, 0, 8, 24, 79, 20, 79,
313 9, 0, 8, 24, 79, 20, 72, 79, 9, 0,
314 8, 24, 79, 20, 70, 9, 0, 24, 50, 51,
315 79, 66, 0, 16, 24, 50, 51, 79, 66, 0,
316 16, 24, 79, 66, 0, 50, 75, 51, 0, 3,
317 75, 4, 75, 7, 0, 3, 75, 4, 75, 5,
318 75, 7, 0, 3, 75, 4, 75, 69, 7, 0,
319 48, 74, 49, 0, 27, 0, 17, 28, 18, 0,
320 6, 75, 4, 75, 0, 6, 75, 4, 75, 5,
321 75, 0, 6, 75, 4, 75, 69, 0, 71, 0,
322 72, 71, 0, 79, 73, 51, 75, 0, 79, 73,
323 51, 79, 0, 79, 50, 73, 51, 75, 0, 79,
324 50, 73, 51, 79, 0, 71, 35, 0, 72, 71,
325 35, 0, 24, 0, 73, 44, 24, 0, 79, 76,
326 0, 74, 0, 79, 77, 0, 77, 42, 79, 0,
327 77, 40, 79, 0, 77, 41, 79, 0, 77, 29,
328 79, 77, 0, 77, 30, 79, 77, 0, 77, 40,
329 79, 77, 0, 77, 41, 79, 77, 0, 77, 42,
330 79, 77, 0, 82, 0, 42, 0, 41, 0, 43,
331 0, 0, 79, 42, 0, 81, 0, 81, 40, 0,
332 81, 41, 0, 81, 29, 79, 81, 0, 81, 30,
333 79, 81, 0, 81, 40, 81, 0, 81, 41, 81,
334 0, 82, 0, 83, 0, 21, 83, 0, 84, 83,
335 0, 84, 21, 83, 0, 21, 84, 83, 0, 83,
336 44, 79, 83, 0, 58, 0, 22, 0, 22, 23,
337 0
338 };
339
340 #endif
341
342 #if YYDEBUG != 0
343 static const short yyrline[] = { 0,
344 232, 241, 248, 263, 273, 275, 279, 284, 289, 294,
345 299, 304, 309, 315, 321, 326, 331, 336, 341, 346,
346 351, 356, 361, 368, 375, 380, 385, 390, 395, 400,
347 405, 410, 415, 422, 424, 426, 430, 434, 445, 447,
348 451, 453, 455, 484, 486, 488, 490, 492, 494, 496,
349 498, 500, 502, 504, 508, 510, 512, 514, 516, 518,
350 522, 526, 530, 534, 538, 542, 548, 550, 552, 556,
351 560, 563, 567, 571, 573, 575, 580, 584, 588, 592,
352 594, 596, 600, 601, 605, 607, 609, 611, 615, 616,
353 620, 622, 631, 639, 640, 646, 647, 654, 658, 660,
354 662, 669, 671, 673, 677, 678, 679, 682, 683, 692,
355 698, 707, 715, 717, 719, 726, 729, 733, 735, 740,
356 745, 750, 757, 760, 764, 766
357 };
358 #endif
359
360
361 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
362
363 static const char * const yytname[] = { "$","error","$undefined.","IF","THEN",
364 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
365 "FUNCTION","COND_START","COND_END","COND_ERROR","IN","BANG","TIME","TIMEOPT",
366 "WORD","ASSIGNMENT_WORD","NUMBER","ARITH_CMD","COND_CMD","AND_AND","OR_OR","GREATER_GREATER",
367 "LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS","AND_GREATER",
368 "LESS_GREATER","GREATER_BAR","'&'","';'","'\\n'","yacc_EOF","'|'","'>'","'<'",
369 "'-'","'{'","'}'","'('","')'","inputunit","word_list","redirection","simple_command_element",
370 "redirection_list","simple_command","command","shell_command","for_command",
371 "select_command","case_command","function_def","subshell","if_command","group_command",
372 "arith_command","cond_command","elif_clause","case_clause","pattern_list","case_clause_sequence",
373 "pattern","list","compound_list","list0","list1","list_terminator","newline_list",
374 "simple_list","simple_list1","pipeline_command","pipeline","timespec", NULL
375 };
376 #endif
377
378 static const short yyr1[] = { 0,
379 52, 52, 52, 52, 53, 53, 54, 54, 54, 54,
380 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
381 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
382 54, 54, 54, 55, 55, 55, 56, 56, 57, 57,
383 58, 58, 58, 59, 59, 59, 59, 59, 59, 59,
384 59, 59, 59, 59, 60, 60, 60, 60, 60, 60,
385 61, 61, 61, 61, 61, 61, 62, 62, 62, 63,
386 63, 63, 64, 65, 65, 65, 66, 67, 68, 69,
387 69, 69, 70, 70, 71, 71, 71, 71, 72, 72,
388 73, 73, 74, 75, 75, 76, 76, 76, 77, 77,
389 77, 77, 77, 77, 78, 78, 78, 79, 79, 80,
390 80, 80, 81, 81, 81, 81, 81, 82, 82, 82,
391 82, 82, 83, 83, 84, 84
392 };
393
394 static const short yyr2[] = { 0,
395 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
396 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
397 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
398 2, 2, 3, 1, 1, 1, 1, 2, 1, 2,
399 1, 1, 2, 1, 1, 5, 5, 1, 1, 1,
400 1, 1, 1, 1, 6, 6, 7, 7, 10, 10,
401 6, 6, 7, 7, 10, 10, 6, 7, 6, 5,
402 6, 4, 3, 5, 7, 6, 3, 1, 3, 4,
403 6, 5, 1, 2, 4, 4, 5, 5, 2, 3,
404 1, 3, 2, 1, 2, 3, 3, 3, 4, 4,
405 4, 4, 4, 1, 1, 1, 1, 0, 2, 1,
406 2, 2, 4, 4, 3, 3, 1, 1, 2, 2,
407 3, 3, 4, 1, 1, 2
408 };
409
410 static const short yydefact[] = { 0,
411 0, 108, 0, 0, 0, 108, 108, 0, 0, 0,
412 125, 34, 35, 0, 78, 0, 0, 0, 0, 0,
413 0, 0, 0, 2, 4, 0, 0, 108, 108, 36,
414 39, 41, 124, 42, 44, 48, 45, 54, 50, 49,
415 51, 52, 53, 0, 110, 117, 118, 0, 3, 94,
416 0, 0, 108, 108, 108, 0, 0, 108, 0, 119,
417 0, 126, 0, 0, 0, 0, 0, 0, 0, 0,
418 0, 0, 11, 13, 19, 15, 27, 21, 17, 25,
419 23, 29, 31, 32, 7, 8, 0, 0, 0, 34,
420 40, 37, 43, 1, 108, 108, 111, 112, 108, 0,
421 120, 108, 109, 93, 95, 104, 0, 108, 0, 108,
422 0, 108, 108, 0, 0, 79, 122, 108, 12, 14,
423 20, 16, 28, 22, 18, 26, 24, 30, 33, 9,
424 10, 77, 0, 73, 38, 0, 0, 115, 116, 0,
425 121, 0, 108, 108, 108, 108, 108, 108, 0, 108,
426 0, 108, 0, 108, 0, 108, 0, 0, 108, 72,
427 0, 113, 114, 0, 0, 123, 108, 108, 74, 0,
428 0, 0, 97, 98, 96, 0, 83, 108, 0, 108,
429 108, 0, 5, 0, 0, 108, 108, 0, 0, 0,
430 46, 47, 0, 70, 0, 0, 76, 99, 100, 101,
431 102, 103, 69, 89, 84, 0, 67, 91, 0, 0,
432 0, 0, 55, 6, 106, 105, 107, 108, 56, 0,
433 0, 61, 108, 62, 71, 75, 108, 108, 108, 108,
434 90, 68, 0, 0, 108, 57, 58, 0, 63, 64,
435 0, 80, 0, 0, 0, 108, 92, 85, 86, 108,
436 108, 108, 108, 108, 82, 87, 88, 0, 0, 0,
437 0, 81, 59, 60, 65, 66, 0, 0, 0
438 };
439
440 static const short yydefgoto[] = { 267,
441 184, 30, 31, 93, 32, 33, 34, 35, 36, 37,
442 38, 39, 40, 41, 42, 43, 170, 176, 177, 178,
443 210, 50, 51, 104, 105, 218, 52, 44, 138, 106,
444 47, 48
445 };
446
447 static const short yypact[] = { 246,
448 -34,-32768, 11, 20, 24,-32768,-32768, 33, -10, 369,
449 29, 19,-32768, 529,-32768, 42, 47, 30, 36, 64,
450 66, 78, 81,-32768,-32768, 84, 92,-32768,-32768,-32768,
451 -32768, 155,-32768, 513,-32768,-32768,-32768,-32768,-32768,-32768,
452 -32768,-32768,-32768, 89, -15,-32768, 77, 410,-32768,-32768,
453 130, 287,-32768, 95, 99, 127, 131, 97, 132, 77,
454 492,-32768, 100, 128, 129, 44, 56, 134, 135, 136,
455 139, 140,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
456 -32768,-32768,-32768,-32768,-32768,-32768, 105, 287, 104,-32768,
457 -32768,-32768, 513,-32768,-32768,-32768, 328, 328,-32768, 492,
458 77,-32768,-32768,-32768, 88,-32768, 1,-32768, -1,-32768,
459 16,-32768,-32768, 116, -32,-32768, 77,-32768,-32768,-32768,
460 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
461 -32768,-32768, 88,-32768,-32768, 287, 287, 69, 69, 451,
462 77, 79,-32768,-32768,-32768,-32768,-32768,-32768, 3,-32768,
463 144,-32768, 13,-32768, 144,-32768, 141, 157,-32768,-32768,
464 -32,-32768,-32768, 328, 328, 77,-32768,-32768,-32768, 166,
465 287, 287, 287, 287, 287, 169, 147,-32768, -4,-32768,
466 -32768, 175,-32768, 52, 146,-32768,-32768, 181, 52, 149,
467 -32768,-32768, -32,-32768, 192, 199,-32768,-32768,-32768, 71,
468 71, 71,-32768,-32768, 170, 0,-32768,-32768, 180, -22,
469 191, 161,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 196,
470 163,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
471 -32768,-32768, 28, 189,-32768,-32768,-32768, 17,-32768,-32768,
472 25, 114, 287, 287, 287,-32768,-32768,-32768, 287,-32768,
473 -32768,-32768,-32768,-32768,-32768,-32768, 287, 200, 167, 202,
474 171,-32768,-32768,-32768,-32768,-32768, 218, 219,-32768
475 };
476
477 static const short yypgoto[] = {-32768,
478 67, -30, 194,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
479 -32768,-32768,-32768, -112,-32768,-32768, -19,-32768, 46,-32768,
480 18, -17, -6,-32768, -60, 39, -21,-32768, 6, 12,
481 -8, 220
482 };
483
484
485 #define YYLAST 575
486
487
488 static const short yytable[] = { 56,
489 57, 60, 160, 92, 207, 45, 88, 49, 232, 103,
490 87, 46, 150, 95, 96, 28, 180, 59, 151, 208,
491 148, 234, 89, 208, 97, 98, 186, 133, 235, 154,
492 250, 107, 109, 111, 53, 155, 115, 103, 252, 101,
493 103, 103, 103, 54, 103, 209, 152, 55, 194, 209,
494 181, 62, 117, 75, 103, 76, 58, 103, 103, 78,
495 187, 79, 135, 156, 251, 73, 103, 121, 63, 122,
496 74, 234, 253, 136, 137, 214, 77, 140, 246, 124,
497 225, 125, 80, 167, 168, 169, 149, 81, 153, 82,
498 123, 141, 215, 216, 217, 142, 161, 95, 96, 143,
499 144, 83, 126, 139, 84, 157, 158, 85, 46, 46,
500 198, 199, 200, 201, 202, 86, 143, 144, 254, 168,
501 99, 171, 172, 173, 174, 175, 179, 145, 146, 147,
502 94, 166, 88, 102, 88, 108, 188, 193, 190, 110,
503 112, 162, 163, 182, 113, 185, 114, 46, 46, 116,
504 118, 119, 120, 132, 134, 191, 206, 127, 128, 129,
505 195, 196, 130, 131, 88, 88, 159, 183, 220, 221,
506 139, 192, 197, 211, 212, 46, 46, 203, 90, 13,
507 14, 204, 200, 201, 202, 16, 17, 18, 19, 213,
508 20, 21, 22, 23, 219, 222, 238, 224, 226, 26,
509 27, 241, 227, 208, 231, 236, 243, 244, 245, 237,
510 239, 240, 247, 249, 263, 264, 265, 268, 269, 266,
511 242, 189, 255, 205, 257, 91, 233, 223, 248, 61,
512 88, 88, 0, 0, 260, 261, 0, 0, 0, 256,
513 0, 0, 0, 258, 259, 0, 1, 262, 2, 0,
514 0, 0, 0, 3, 0, 4, 5, 6, 7, 0,
515 0, 8, 9, 0, 0, 0, 10, 11, 0, 12,
516 13, 14, 15, 0, 0, 0, 16, 17, 18, 19,
517 0, 20, 21, 22, 23, 0, 0, 24, 25, 2,
518 26, 27, 0, 28, 3, 29, 4, 5, 6, 7,
519 0, 0, 8, 9, 0, 0, 0, 10, 11, 0,
520 12, 13, 14, 15, 0, 0, 0, 16, 17, 18,
521 19, 0, 20, 21, 22, 23, 0, 0, 103, 0,
522 2, 26, 27, 0, 28, 3, 29, 4, 5, 6,
523 7, 0, 0, 8, 9, 0, 0, 0, 10, 11,
524 0, 12, 13, 14, 15, 0, 0, 0, 16, 17,
525 18, 19, 0, 20, 21, 22, 23, 0, 0, 0,
526 0, 2, 26, 27, 0, 28, 3, 29, 4, 5,
527 6, 7, 0, 0, 8, 9, 0, 0, 0, 0,
528 11, 0, 12, 13, 14, 15, 0, 0, 0, 16,
529 17, 18, 19, 0, 20, 21, 22, 23, 0, 0,
530 0, 0, 2, 26, 27, 0, 28, 3, 29, 4,
531 5, 6, 7, 0, 0, 8, 9, 0, 0, 0,
532 100, 0, 0, 12, 13, 14, 15, 0, 0, 0,
533 16, 17, 18, 19, 0, 20, 21, 22, 23, 0,
534 0, 0, 0, 2, 26, 27, 0, 28, 3, 29,
535 4, 5, 6, 7, 0, 0, 8, 9, 0, 0,
536 0, 0, 0, 0, 12, 13, 14, 15, 0, 0,
537 0, 16, 17, 18, 19, 0, 20, 21, 22, 23,
538 0, 0, 103, 0, 2, 26, 27, 0, 28, 3,
539 29, 4, 5, 6, 7, 0, 0, 8, 9, 0,
540 0, 0, 0, 0, 0, 12, 13, 14, 15, 0,
541 0, 0, 16, 17, 18, 19, 0, 20, 21, 22,
542 23, 0, 0, 0, 0, 0, 26, 27, 14, 28,
543 0, 29, 0, 16, 17, 18, 19, 0, 20, 21,
544 22, 23, 0, 0, 0, 0, 0, 26, 27, 64,
545 65, 66, 67, 0, 68, 0, 69, 70, 0, 0,
546 0, 0, 0, 71, 72
547 };
548
549 static const short yycheck[] = { 6,
550 7, 10, 115, 34, 9, 0, 28, 42, 9, 42,
551 28, 0, 14, 29, 30, 48, 14, 28, 20, 24,
552 20, 44, 29, 24, 40, 41, 14, 88, 51, 14,
553 14, 53, 54, 55, 24, 20, 58, 42, 14, 48,
554 42, 42, 42, 24, 42, 50, 48, 24, 161, 50,
555 48, 23, 61, 24, 42, 26, 24, 42, 42, 24,
556 48, 26, 93, 48, 48, 24, 42, 24, 50, 26,
557 24, 44, 48, 95, 96, 24, 47, 99, 51, 24,
558 193, 26, 47, 5, 6, 7, 108, 24, 110, 24,
559 47, 100, 41, 42, 43, 102, 118, 29, 30, 29,
560 30, 24, 47, 98, 24, 112, 113, 24, 97, 98,
561 171, 172, 173, 174, 175, 24, 29, 30, 5, 6,
562 44, 143, 144, 145, 146, 147, 148, 40, 41, 42,
563 42, 140, 154, 4, 156, 41, 154, 159, 156, 41,
564 14, 136, 137, 150, 14, 152, 50, 136, 137, 18,
565 51, 24, 24, 49, 51, 15, 178, 24, 24, 24,
566 167, 168, 24, 24, 186, 187, 51, 24, 186, 187,
567 165, 15, 7, 180, 181, 164, 165, 9, 24, 25,
568 26, 35, 243, 244, 245, 31, 32, 33, 34, 15,
569 36, 37, 38, 39, 49, 15, 218, 49, 7, 45,
570 46, 223, 4, 24, 35, 15, 228, 229, 230, 49,
571 15, 49, 24, 235, 15, 49, 15, 0, 0, 49,
572 227, 155, 242, 178, 246, 32, 209, 189, 235, 10,
573 252, 253, -1, -1, 252, 253, -1, -1, -1, 246,
574 -1, -1, -1, 250, 251, -1, 1, 254, 3, -1,
575 -1, -1, -1, 8, -1, 10, 11, 12, 13, -1,
576 -1, 16, 17, -1, -1, -1, 21, 22, -1, 24,
577 25, 26, 27, -1, -1, -1, 31, 32, 33, 34,
578 -1, 36, 37, 38, 39, -1, -1, 42, 43, 3,
579 45, 46, -1, 48, 8, 50, 10, 11, 12, 13,
580 -1, -1, 16, 17, -1, -1, -1, 21, 22, -1,
581 24, 25, 26, 27, -1, -1, -1, 31, 32, 33,
582 34, -1, 36, 37, 38, 39, -1, -1, 42, -1,
583 3, 45, 46, -1, 48, 8, 50, 10, 11, 12,
584 13, -1, -1, 16, 17, -1, -1, -1, 21, 22,
585 -1, 24, 25, 26, 27, -1, -1, -1, 31, 32,
586 33, 34, -1, 36, 37, 38, 39, -1, -1, -1,
587 -1, 3, 45, 46, -1, 48, 8, 50, 10, 11,
588 12, 13, -1, -1, 16, 17, -1, -1, -1, -1,
589 22, -1, 24, 25, 26, 27, -1, -1, -1, 31,
590 32, 33, 34, -1, 36, 37, 38, 39, -1, -1,
591 -1, -1, 3, 45, 46, -1, 48, 8, 50, 10,
592 11, 12, 13, -1, -1, 16, 17, -1, -1, -1,
593 21, -1, -1, 24, 25, 26, 27, -1, -1, -1,
594 31, 32, 33, 34, -1, 36, 37, 38, 39, -1,
595 -1, -1, -1, 3, 45, 46, -1, 48, 8, 50,
596 10, 11, 12, 13, -1, -1, 16, 17, -1, -1,
597 -1, -1, -1, -1, 24, 25, 26, 27, -1, -1,
598 -1, 31, 32, 33, 34, -1, 36, 37, 38, 39,
599 -1, -1, 42, -1, 3, 45, 46, -1, 48, 8,
600 50, 10, 11, 12, 13, -1, -1, 16, 17, -1,
601 -1, -1, -1, -1, -1, 24, 25, 26, 27, -1,
602 -1, -1, 31, 32, 33, 34, -1, 36, 37, 38,
603 39, -1, -1, -1, -1, -1, 45, 46, 26, 48,
604 -1, 50, -1, 31, 32, 33, 34, -1, 36, 37,
605 38, 39, -1, -1, -1, -1, -1, 45, 46, 31,
606 32, 33, 34, -1, 36, -1, 38, 39, -1, -1,
607 -1, -1, -1, 45, 46
608 };
609 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
610 #line 3 "/usr/share/misc/bison.simple"
611
612 /* Skeleton output parser for bison,
613 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
614
615 This program is free software; you can redistribute it and/or modify
616 it under the terms of the GNU General Public License as published by
617 the Free Software Foundation; either version 2, or (at your option)
618 any later version.
619
620 This program is distributed in the hope that it will be useful,
621 but WITHOUT ANY WARRANTY; without even the implied warranty of
622 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
623 GNU General Public License for more details.
624
625 You should have received a copy of the GNU General Public License
626 along with this program; if not, write to the Free Software
627 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
628
629 /* As a special exception, when this file is copied by Bison into a
630 Bison output file, you may use that output file without restriction.
631 This special exception was added by the Free Software Foundation
632 in version 1.24 of Bison. */
633
634 #ifndef alloca
635 #ifdef __GNUC__
636 #define alloca __builtin_alloca
637 #else /* not GNU C. */
638 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
639 #include <alloca.h>
640 #else /* not sparc */
641 #if defined (MSDOS) && !defined (__TURBOC__)
642 #include <malloc.h>
643 #else /* not MSDOS, or __TURBOC__ */
644 #if defined(_AIX)
645 #include <malloc.h>
646 #pragma alloca
647 #else /* not MSDOS, __TURBOC__, or _AIX */
648 #ifdef __hpux
649 #ifdef __cplusplus
650 extern "C" {
651 void *alloca (unsigned int);
652 };
653 #else /* not __cplusplus */
654 void *alloca ();
655 #endif /* not __cplusplus */
656 #endif /* __hpux */
657 #endif /* not _AIX */
658 #endif /* not MSDOS, or __TURBOC__ */
659 #endif /* not sparc. */
660 #endif /* not GNU C. */
661 #endif /* alloca not defined. */
662
663 /* This is the parser code that is written into each bison parser
664 when the %semantic_parser declaration is not specified in the grammar.
665 It was written by Richard Stallman by simplifying the hairy parser
666 used when %semantic_parser is specified. */
667
668 /* Note: there must be only one dollar sign in this file.
669 It is replaced by the list of actions, each action
670 as one case of the switch. */
671
672 #define yyerrok (yyerrstatus = 0)
673 #define yyclearin (yychar = YYEMPTY)
674 #define YYEMPTY -2
675 #define YYEOF 0
676 #define YYACCEPT return(0)
677 #define YYABORT return(1)
678 #define YYERROR goto yyerrlab1
679 /* Like YYERROR except do call yyerror.
680 This remains here temporarily to ease the
681 transition to the new meaning of YYERROR, for GCC.
682 Once GCC version 2 has supplanted version 1, this can go. */
683 #define YYFAIL goto yyerrlab
684 #define YYRECOVERING() (!!yyerrstatus)
685 #define YYBACKUP(token, value) \
686 do \
687 if (yychar == YYEMPTY && yylen == 1) \
688 { yychar = (token), yylval = (value); \
689 yychar1 = YYTRANSLATE (yychar); \
690 YYPOPSTACK; \
691 goto yybackup; \
692 } \
693 else \
694 { yyerror ("syntax error: cannot back up"); YYERROR; } \
695 while (0)
696
697 #define YYTERROR 1
698 #define YYERRCODE 256
699
700 #ifndef YYPURE
701 #define YYLEX yylex()
702 #endif
703
704 #ifdef YYPURE
705 #ifdef YYLSP_NEEDED
706 #ifdef YYLEX_PARAM
707 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
708 #else
709 #define YYLEX yylex(&yylval, &yylloc)
710 #endif
711 #else /* not YYLSP_NEEDED */
712 #ifdef YYLEX_PARAM
713 #define YYLEX yylex(&yylval, YYLEX_PARAM)
714 #else
715 #define YYLEX yylex(&yylval)
716 #endif
717 #endif /* not YYLSP_NEEDED */
718 #endif
719
720 /* If nonreentrant, generate the variables here */
721
722 #ifndef YYPURE
723
724 int yychar; /* the lookahead symbol */
725 YYSTYPE yylval; /* the semantic value of the */
726 /* lookahead symbol */
727
728 #ifdef YYLSP_NEEDED
729 YYLTYPE yylloc; /* location data for the lookahead */
730 /* symbol */
731 #endif
732
733 int yynerrs; /* number of parse errors so far */
734 #endif /* not YYPURE */
735
736 #if YYDEBUG != 0
737 int yydebug; /* nonzero means print parse trace */
738 /* Since this is uninitialized, it does not stop multiple parsers
739 from coexisting. */
740 #endif
741
742 /* YYINITDEPTH indicates the initial size of the parser's stacks */
743
744 #ifndef YYINITDEPTH
745 #define YYINITDEPTH 200
746 #endif
747
748 /* YYMAXDEPTH is the maximum size the stacks can grow to
749 (effective only if the built-in stack extension method is used). */
750
751 #if YYMAXDEPTH == 0
752 #undef YYMAXDEPTH
753 #endif
754
755 #ifndef YYMAXDEPTH
756 #define YYMAXDEPTH 10000
757 #endif
758
759 /* Prevent warning if -Wstrict-prototypes. */
760 #ifdef __GNUC__
761 int yyparse (void);
762 #endif
763 \f
764 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
765 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
766 #else /* not GNU C or C++ */
767 #ifndef __cplusplus
768
769 /* This is the most reliable way to avoid incompatibilities
770 in available built-in functions on various systems. */
771 static void
772 __yy_memcpy (to, from, count)
773 char *to;
774 char *from;
775 int count;
776 {
777 register char *f = from;
778 register char *t = to;
779 register int i = count;
780
781 while (i-- > 0)
782 *t++ = *f++;
783 }
784
785 #else /* __cplusplus */
786
787 /* This is the most reliable way to avoid incompatibilities
788 in available built-in functions on various systems. */
789 static void
790 __yy_memcpy (char *to, char *from, int count)
791 {
792 register char *f = from;
793 register char *t = to;
794 register int i = count;
795
796 while (i-- > 0)
797 *t++ = *f++;
798 }
799
800 #endif
801 #endif
802 \f
803 #line 196 "/usr/share/misc/bison.simple"
804
805 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
806 into yyparse. The argument should have type void *.
807 It should actually point to an object.
808 Grammar actions can access the variable by casting it
809 to the proper pointer type. */
810
811 #ifdef YYPARSE_PARAM
812 #ifdef __cplusplus
813 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
814 #define YYPARSE_PARAM_DECL
815 #else /* not __cplusplus */
816 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
817 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
818 #endif /* not __cplusplus */
819 #else /* not YYPARSE_PARAM */
820 #define YYPARSE_PARAM_ARG
821 #define YYPARSE_PARAM_DECL
822 #endif /* not YYPARSE_PARAM */
823
824 int
825 yyparse(YYPARSE_PARAM_ARG)
826 YYPARSE_PARAM_DECL
827 {
828 register int yystate;
829 register int yyn;
830 register short *yyssp;
831 register YYSTYPE *yyvsp;
832 int yyerrstatus; /* number of tokens to shift before error messages enabled */
833 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
834
835 short yyssa[YYINITDEPTH]; /* the state stack */
836 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
837
838 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
839 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
840
841 #ifdef YYLSP_NEEDED
842 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
843 YYLTYPE *yyls = yylsa;
844 YYLTYPE *yylsp;
845
846 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
847 #else
848 #define YYPOPSTACK (yyvsp--, yyssp--)
849 #endif
850
851 int yystacksize = YYINITDEPTH;
852
853 #ifdef YYPURE
854 int yychar;
855 YYSTYPE yylval;
856 int yynerrs;
857 #ifdef YYLSP_NEEDED
858 YYLTYPE yylloc;
859 #endif
860 #endif
861
862 YYSTYPE yyval; /* the variable used to return */
863 /* semantic values from the action */
864 /* routines */
865
866 int yylen;
867
868 #if YYDEBUG != 0
869 if (yydebug)
870 fprintf(stderr, "Starting parse\n");
871 #endif
872
873 yystate = 0;
874 yyerrstatus = 0;
875 yynerrs = 0;
876 yychar = YYEMPTY; /* Cause a token to be read. */
877
878 /* Initialize stack pointers.
879 Waste one element of value and location stack
880 so that they stay on the same level as the state stack.
881 The wasted elements are never initialized. */
882
883 yyssp = yyss - 1;
884 yyvsp = yyvs;
885 #ifdef YYLSP_NEEDED
886 yylsp = yyls;
887 #endif
888
889 /* Push a new state, which is found in yystate . */
890 /* In all cases, when you get here, the value and location stacks
891 have just been pushed. so pushing a state here evens the stacks. */
892 yynewstate:
893
894 *++yyssp = yystate;
895
896 if (yyssp >= yyss + yystacksize - 1)
897 {
898 /* Give user a chance to reallocate the stack */
899 /* Use copies of these so that the &'s don't force the real ones into memory. */
900 YYSTYPE *yyvs1 = yyvs;
901 short *yyss1 = yyss;
902 #ifdef YYLSP_NEEDED
903 YYLTYPE *yyls1 = yyls;
904 #endif
905
906 /* Get the current used size of the three stacks, in elements. */
907 int size = yyssp - yyss + 1;
908
909 #ifdef yyoverflow
910 /* Each stack pointer address is followed by the size of
911 the data in use in that stack, in bytes. */
912 #ifdef YYLSP_NEEDED
913 /* This used to be a conditional around just the two extra args,
914 but that might be undefined if yyoverflow is a macro. */
915 yyoverflow("parser stack overflow",
916 &yyss1, size * sizeof (*yyssp),
917 &yyvs1, size * sizeof (*yyvsp),
918 &yyls1, size * sizeof (*yylsp),
919 &yystacksize);
920 #else
921 yyoverflow("parser stack overflow",
922 &yyss1, size * sizeof (*yyssp),
923 &yyvs1, size * sizeof (*yyvsp),
924 &yystacksize);
925 #endif
926
927 yyss = yyss1; yyvs = yyvs1;
928 #ifdef YYLSP_NEEDED
929 yyls = yyls1;
930 #endif
931 #else /* no yyoverflow */
932 /* Extend the stack our own way. */
933 if (yystacksize >= YYMAXDEPTH)
934 {
935 yyerror("parser stack overflow");
936 return 2;
937 }
938 yystacksize *= 2;
939 if (yystacksize > YYMAXDEPTH)
940 yystacksize = YYMAXDEPTH;
941 yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
942 __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
943 yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
944 __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
945 #ifdef YYLSP_NEEDED
946 yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
947 __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
948 #endif
949 #endif /* no yyoverflow */
950
951 yyssp = yyss + size - 1;
952 yyvsp = yyvs + size - 1;
953 #ifdef YYLSP_NEEDED
954 yylsp = yyls + size - 1;
955 #endif
956
957 #if YYDEBUG != 0
958 if (yydebug)
959 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
960 #endif
961
962 if (yyssp >= yyss + yystacksize - 1)
963 YYABORT;
964 }
965
966 #if YYDEBUG != 0
967 if (yydebug)
968 fprintf(stderr, "Entering state %d\n", yystate);
969 #endif
970
971 goto yybackup;
972 yybackup:
973
974 /* Do appropriate processing given the current state. */
975 /* Read a lookahead token if we need one and don't already have one. */
976 /* yyresume: */
977
978 /* First try to decide what to do without reference to lookahead token. */
979
980 yyn = yypact[yystate];
981 if (yyn == YYFLAG)
982 goto yydefault;
983
984 /* Not known => get a lookahead token if don't already have one. */
985
986 /* yychar is either YYEMPTY or YYEOF
987 or a valid token in external form. */
988
989 if (yychar == YYEMPTY)
990 {
991 #if YYDEBUG != 0
992 if (yydebug)
993 fprintf(stderr, "Reading a token: ");
994 #endif
995 yychar = YYLEX;
996 }
997
998 /* Convert token to internal form (in yychar1) for indexing tables with */
999
1000 if (yychar <= 0) /* This means end of input. */
1001 {
1002 yychar1 = 0;
1003 yychar = YYEOF; /* Don't call YYLEX any more */
1004
1005 #if YYDEBUG != 0
1006 if (yydebug)
1007 fprintf(stderr, "Now at end of input.\n");
1008 #endif
1009 }
1010 else
1011 {
1012 yychar1 = YYTRANSLATE(yychar);
1013
1014 #if YYDEBUG != 0
1015 if (yydebug)
1016 {
1017 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
1018 /* Give the individual parser a way to print the precise meaning
1019 of a token, for further debugging info. */
1020 #ifdef YYPRINT
1021 YYPRINT (stderr, yychar, yylval);
1022 #endif
1023 fprintf (stderr, ")\n");
1024 }
1025 #endif
1026 }
1027
1028 yyn += yychar1;
1029 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
1030 goto yydefault;
1031
1032 yyn = yytable[yyn];
1033
1034 /* yyn is what to do for this token type in this state.
1035 Negative => reduce, -yyn is rule number.
1036 Positive => shift, yyn is new state.
1037 New state is final state => don't bother to shift,
1038 just return success.
1039 0, or most negative number => error. */
1040
1041 if (yyn < 0)
1042 {
1043 if (yyn == YYFLAG)
1044 goto yyerrlab;
1045 yyn = -yyn;
1046 goto yyreduce;
1047 }
1048 else if (yyn == 0)
1049 goto yyerrlab;
1050
1051 if (yyn == YYFINAL)
1052 YYACCEPT;
1053
1054 /* Shift the lookahead token. */
1055
1056 #if YYDEBUG != 0
1057 if (yydebug)
1058 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1059 #endif
1060
1061 /* Discard the token being shifted unless it is eof. */
1062 if (yychar != YYEOF)
1063 yychar = YYEMPTY;
1064
1065 *++yyvsp = yylval;
1066 #ifdef YYLSP_NEEDED
1067 *++yylsp = yylloc;
1068 #endif
1069
1070 /* count tokens shifted since error; after three, turn off error status. */
1071 if (yyerrstatus) yyerrstatus--;
1072
1073 yystate = yyn;
1074 goto yynewstate;
1075
1076 /* Do the default action for the current state. */
1077 yydefault:
1078
1079 yyn = yydefact[yystate];
1080 if (yyn == 0)
1081 goto yyerrlab;
1082
1083 /* Do a reduction. yyn is the number of a rule to reduce with. */
1084 yyreduce:
1085 yylen = yyr2[yyn];
1086 if (yylen > 0)
1087 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1088
1089 #if YYDEBUG != 0
1090 if (yydebug)
1091 {
1092 int i;
1093
1094 fprintf (stderr, "Reducing via rule %d (line %d), ",
1095 yyn, yyrline[yyn]);
1096
1097 /* Print the symbols being reduced, and their result. */
1098 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
1099 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
1100 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
1101 }
1102 #endif
1103
1104
1105 switch (yyn) {
1106
1107 case 1:
1108 #line 233 "/usr/homes/chet/src/bash/src/parse.y"
1109 {
1110 /* Case of regular command. Discard the error
1111 safety net,and return the command just parsed. */
1112 global_command = yyvsp[-1].command;
1113 eof_encountered = 0;
1114 discard_parser_constructs (0);
1115 YYACCEPT;
1116 ;
1117 break;}
1118 case 2:
1119 #line 242 "/usr/homes/chet/src/bash/src/parse.y"
1120 {
1121 /* Case of regular command, but not a very
1122 interesting one. Return a NULL command. */
1123 global_command = (COMMAND *)NULL;
1124 YYACCEPT;
1125 ;
1126 break;}
1127 case 3:
1128 #line 249 "/usr/homes/chet/src/bash/src/parse.y"
1129 {
1130 /* Error during parsing. Return NULL command. */
1131 global_command = (COMMAND *)NULL;
1132 eof_encountered = 0;
1133 discard_parser_constructs (1);
1134 if (interactive)
1135 {
1136 YYACCEPT;
1137 }
1138 else
1139 {
1140 YYABORT;
1141 }
1142 ;
1143 break;}
1144 case 4:
1145 #line 264 "/usr/homes/chet/src/bash/src/parse.y"
1146 {
1147 /* Case of EOF seen by itself. Do ignoreeof or
1148 not. */
1149 global_command = (COMMAND *)NULL;
1150 handle_eof_input_unit ();
1151 YYACCEPT;
1152 ;
1153 break;}
1154 case 5:
1155 #line 274 "/usr/homes/chet/src/bash/src/parse.y"
1156 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1157 break;}
1158 case 6:
1159 #line 276 "/usr/homes/chet/src/bash/src/parse.y"
1160 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
1161 break;}
1162 case 7:
1163 #line 280 "/usr/homes/chet/src/bash/src/parse.y"
1164 {
1165 redir.filename = yyvsp[0].word;
1166 yyval.redirect = make_redirection (1, r_output_direction, redir);
1167 ;
1168 break;}
1169 case 8:
1170 #line 285 "/usr/homes/chet/src/bash/src/parse.y"
1171 {
1172 redir.filename = yyvsp[0].word;
1173 yyval.redirect = make_redirection (0, r_input_direction, redir);
1174 ;
1175 break;}
1176 case 9:
1177 #line 290 "/usr/homes/chet/src/bash/src/parse.y"
1178 {
1179 redir.filename = yyvsp[0].word;
1180 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1181 ;
1182 break;}
1183 case 10:
1184 #line 295 "/usr/homes/chet/src/bash/src/parse.y"
1185 {
1186 redir.filename = yyvsp[0].word;
1187 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1188 ;
1189 break;}
1190 case 11:
1191 #line 300 "/usr/homes/chet/src/bash/src/parse.y"
1192 {
1193 redir.filename = yyvsp[0].word;
1194 yyval.redirect = make_redirection (1, r_appending_to, redir);
1195 ;
1196 break;}
1197 case 12:
1198 #line 305 "/usr/homes/chet/src/bash/src/parse.y"
1199 {
1200 redir.filename = yyvsp[0].word;
1201 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1202 ;
1203 break;}
1204 case 13:
1205 #line 310 "/usr/homes/chet/src/bash/src/parse.y"
1206 {
1207 redir.filename = yyvsp[0].word;
1208 yyval.redirect = make_redirection (0, r_reading_until, redir);
1209 redir_stack[need_here_doc++] = yyval.redirect;
1210 ;
1211 break;}
1212 case 14:
1213 #line 316 "/usr/homes/chet/src/bash/src/parse.y"
1214 {
1215 redir.filename = yyvsp[0].word;
1216 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
1217 redir_stack[need_here_doc++] = yyval.redirect;
1218 ;
1219 break;}
1220 case 15:
1221 #line 322 "/usr/homes/chet/src/bash/src/parse.y"
1222 {
1223 redir.dest = yyvsp[0].number;
1224 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1225 ;
1226 break;}
1227 case 16:
1228 #line 327 "/usr/homes/chet/src/bash/src/parse.y"
1229 {
1230 redir.dest = yyvsp[0].number;
1231 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1232 ;
1233 break;}
1234 case 17:
1235 #line 332 "/usr/homes/chet/src/bash/src/parse.y"
1236 {
1237 redir.dest = yyvsp[0].number;
1238 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1239 ;
1240 break;}
1241 case 18:
1242 #line 337 "/usr/homes/chet/src/bash/src/parse.y"
1243 {
1244 redir.dest = yyvsp[0].number;
1245 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1246 ;
1247 break;}
1248 case 19:
1249 #line 342 "/usr/homes/chet/src/bash/src/parse.y"
1250 {
1251 redir.filename = yyvsp[0].word;
1252 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1253 ;
1254 break;}
1255 case 20:
1256 #line 347 "/usr/homes/chet/src/bash/src/parse.y"
1257 {
1258 redir.filename = yyvsp[0].word;
1259 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1260 ;
1261 break;}
1262 case 21:
1263 #line 352 "/usr/homes/chet/src/bash/src/parse.y"
1264 {
1265 redir.filename = yyvsp[0].word;
1266 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1267 ;
1268 break;}
1269 case 22:
1270 #line 357 "/usr/homes/chet/src/bash/src/parse.y"
1271 {
1272 redir.filename = yyvsp[0].word;
1273 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1274 ;
1275 break;}
1276 case 23:
1277 #line 362 "/usr/homes/chet/src/bash/src/parse.y"
1278 {
1279 redir.filename = yyvsp[0].word;
1280 yyval.redirect = make_redirection
1281 (0, r_deblank_reading_until, redir);
1282 redir_stack[need_here_doc++] = yyval.redirect;
1283 ;
1284 break;}
1285 case 24:
1286 #line 369 "/usr/homes/chet/src/bash/src/parse.y"
1287 {
1288 redir.filename = yyvsp[0].word;
1289 yyval.redirect = make_redirection
1290 (yyvsp[-2].number, r_deblank_reading_until, redir);
1291 redir_stack[need_here_doc++] = yyval.redirect;
1292 ;
1293 break;}
1294 case 25:
1295 #line 376 "/usr/homes/chet/src/bash/src/parse.y"
1296 {
1297 redir.dest = 0L;
1298 yyval.redirect = make_redirection (1, r_close_this, redir);
1299 ;
1300 break;}
1301 case 26:
1302 #line 381 "/usr/homes/chet/src/bash/src/parse.y"
1303 {
1304 redir.dest = 0L;
1305 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1306 ;
1307 break;}
1308 case 27:
1309 #line 386 "/usr/homes/chet/src/bash/src/parse.y"
1310 {
1311 redir.dest = 0L;
1312 yyval.redirect = make_redirection (0, r_close_this, redir);
1313 ;
1314 break;}
1315 case 28:
1316 #line 391 "/usr/homes/chet/src/bash/src/parse.y"
1317 {
1318 redir.dest = 0L;
1319 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1320 ;
1321 break;}
1322 case 29:
1323 #line 396 "/usr/homes/chet/src/bash/src/parse.y"
1324 {
1325 redir.filename = yyvsp[0].word;
1326 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1327 ;
1328 break;}
1329 case 30:
1330 #line 401 "/usr/homes/chet/src/bash/src/parse.y"
1331 {
1332 redir.filename = yyvsp[0].word;
1333 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1334 ;
1335 break;}
1336 case 31:
1337 #line 406 "/usr/homes/chet/src/bash/src/parse.y"
1338 {
1339 redir.filename = yyvsp[0].word;
1340 yyval.redirect = make_redirection (0, r_input_output, redir);
1341 ;
1342 break;}
1343 case 32:
1344 #line 411 "/usr/homes/chet/src/bash/src/parse.y"
1345 {
1346 redir.filename = yyvsp[0].word;
1347 yyval.redirect = make_redirection (1, r_output_force, redir);
1348 ;
1349 break;}
1350 case 33:
1351 #line 416 "/usr/homes/chet/src/bash/src/parse.y"
1352 {
1353 redir.filename = yyvsp[0].word;
1354 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1355 ;
1356 break;}
1357 case 34:
1358 #line 423 "/usr/homes/chet/src/bash/src/parse.y"
1359 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1360 break;}
1361 case 35:
1362 #line 425 "/usr/homes/chet/src/bash/src/parse.y"
1363 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1364 break;}
1365 case 36:
1366 #line 427 "/usr/homes/chet/src/bash/src/parse.y"
1367 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
1368 break;}
1369 case 37:
1370 #line 431 "/usr/homes/chet/src/bash/src/parse.y"
1371 {
1372 yyval.redirect = yyvsp[0].redirect;
1373 ;
1374 break;}
1375 case 38:
1376 #line 435 "/usr/homes/chet/src/bash/src/parse.y"
1377 {
1378 register REDIRECT *t;
1379
1380 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1381 ;
1382 t->next = yyvsp[0].redirect;
1383 yyval.redirect = yyvsp[-1].redirect;
1384 ;
1385 break;}
1386 case 39:
1387 #line 446 "/usr/homes/chet/src/bash/src/parse.y"
1388 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
1389 break;}
1390 case 40:
1391 #line 448 "/usr/homes/chet/src/bash/src/parse.y"
1392 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
1393 break;}
1394 case 41:
1395 #line 452 "/usr/homes/chet/src/bash/src/parse.y"
1396 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1397 break;}
1398 case 42:
1399 #line 454 "/usr/homes/chet/src/bash/src/parse.y"
1400 { yyval.command = yyvsp[0].command; ;
1401 break;}
1402 case 43:
1403 #line 456 "/usr/homes/chet/src/bash/src/parse.y"
1404 {
1405 COMMAND *tc;
1406
1407 tc = yyvsp[-1].command;
1408 /* According to Posix.2 3.9.5, redirections
1409 specified after the body of a function should
1410 be attached to the function and performed when
1411 the function is executed, not as part of the
1412 function definition command. */
1413 if (tc->type == cm_function_def)
1414 {
1415 tc = tc->value.Function_def->command;
1416 if (tc->type == cm_group)
1417 tc = tc->value.Group->command;
1418 }
1419 if (tc->redirects)
1420 {
1421 register REDIRECT *t;
1422 for (t = tc->redirects; t->next; t = t->next)
1423 ;
1424 t->next = yyvsp[0].redirect;
1425 }
1426 else
1427 tc->redirects = yyvsp[0].redirect;
1428 yyval.command = yyvsp[-1].command;
1429 ;
1430 break;}
1431 case 44:
1432 #line 485 "/usr/homes/chet/src/bash/src/parse.y"
1433 { yyval.command = yyvsp[0].command; ;
1434 break;}
1435 case 45:
1436 #line 487 "/usr/homes/chet/src/bash/src/parse.y"
1437 { yyval.command = yyvsp[0].command; ;
1438 break;}
1439 case 46:
1440 #line 489 "/usr/homes/chet/src/bash/src/parse.y"
1441 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
1442 break;}
1443 case 47:
1444 #line 491 "/usr/homes/chet/src/bash/src/parse.y"
1445 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
1446 break;}
1447 case 48:
1448 #line 493 "/usr/homes/chet/src/bash/src/parse.y"
1449 { yyval.command = yyvsp[0].command; ;
1450 break;}
1451 case 49:
1452 #line 495 "/usr/homes/chet/src/bash/src/parse.y"
1453 { yyval.command = yyvsp[0].command; ;
1454 break;}
1455 case 50:
1456 #line 497 "/usr/homes/chet/src/bash/src/parse.y"
1457 { yyval.command = yyvsp[0].command; ;
1458 break;}
1459 case 51:
1460 #line 499 "/usr/homes/chet/src/bash/src/parse.y"
1461 { yyval.command = yyvsp[0].command; ;
1462 break;}
1463 case 52:
1464 #line 501 "/usr/homes/chet/src/bash/src/parse.y"
1465 { yyval.command = yyvsp[0].command; ;
1466 break;}
1467 case 53:
1468 #line 503 "/usr/homes/chet/src/bash/src/parse.y"
1469 { yyval.command = yyvsp[0].command; ;
1470 break;}
1471 case 54:
1472 #line 505 "/usr/homes/chet/src/bash/src/parse.y"
1473 { yyval.command = yyvsp[0].command; ;
1474 break;}
1475 case 55:
1476 #line 509 "/usr/homes/chet/src/bash/src/parse.y"
1477 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1478 break;}
1479 case 56:
1480 #line 511 "/usr/homes/chet/src/bash/src/parse.y"
1481 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1482 break;}
1483 case 57:
1484 #line 513 "/usr/homes/chet/src/bash/src/parse.y"
1485 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1486 break;}
1487 case 58:
1488 #line 515 "/usr/homes/chet/src/bash/src/parse.y"
1489 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1490 break;}
1491 case 59:
1492 #line 517 "/usr/homes/chet/src/bash/src/parse.y"
1493 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1494 break;}
1495 case 60:
1496 #line 519 "/usr/homes/chet/src/bash/src/parse.y"
1497 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1498 break;}
1499 case 61:
1500 #line 523 "/usr/homes/chet/src/bash/src/parse.y"
1501 {
1502 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1503 ;
1504 break;}
1505 case 62:
1506 #line 527 "/usr/homes/chet/src/bash/src/parse.y"
1507 {
1508 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
1509 ;
1510 break;}
1511 case 63:
1512 #line 531 "/usr/homes/chet/src/bash/src/parse.y"
1513 {
1514 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1515 ;
1516 break;}
1517 case 64:
1518 #line 535 "/usr/homes/chet/src/bash/src/parse.y"
1519 {
1520 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1521 ;
1522 break;}
1523 case 65:
1524 #line 539 "/usr/homes/chet/src/bash/src/parse.y"
1525 {
1526 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1527 ;
1528 break;}
1529 case 66:
1530 #line 543 "/usr/homes/chet/src/bash/src/parse.y"
1531 {
1532 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1533 ;
1534 break;}
1535 case 67:
1536 #line 549 "/usr/homes/chet/src/bash/src/parse.y"
1537 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
1538 break;}
1539 case 68:
1540 #line 551 "/usr/homes/chet/src/bash/src/parse.y"
1541 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
1542 break;}
1543 case 69:
1544 #line 553 "/usr/homes/chet/src/bash/src/parse.y"
1545 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
1546 break;}
1547 case 70:
1548 #line 557 "/usr/homes/chet/src/bash/src/parse.y"
1549 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1550 break;}
1551 case 71:
1552 #line 561 "/usr/homes/chet/src/bash/src/parse.y"
1553 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1554 break;}
1555 case 72:
1556 #line 564 "/usr/homes/chet/src/bash/src/parse.y"
1557 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
1558 break;}
1559 case 73:
1560 #line 568 "/usr/homes/chet/src/bash/src/parse.y"
1561 { yyvsp[-1].command->flags |= CMD_WANT_SUBSHELL; yyval.command = yyvsp[-1].command; ;
1562 break;}
1563 case 74:
1564 #line 572 "/usr/homes/chet/src/bash/src/parse.y"
1565 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
1566 break;}
1567 case 75:
1568 #line 574 "/usr/homes/chet/src/bash/src/parse.y"
1569 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
1570 break;}
1571 case 76:
1572 #line 576 "/usr/homes/chet/src/bash/src/parse.y"
1573 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
1574 break;}
1575 case 77:
1576 #line 581 "/usr/homes/chet/src/bash/src/parse.y"
1577 { yyval.command = make_group_command (yyvsp[-1].command); ;
1578 break;}
1579 case 78:
1580 #line 585 "/usr/homes/chet/src/bash/src/parse.y"
1581 { yyval.command = make_arith_command (yyvsp[0].word_list); ;
1582 break;}
1583 case 79:
1584 #line 589 "/usr/homes/chet/src/bash/src/parse.y"
1585 { yyval.command = yyvsp[-1].command; ;
1586 break;}
1587 case 80:
1588 #line 593 "/usr/homes/chet/src/bash/src/parse.y"
1589 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
1590 break;}
1591 case 81:
1592 #line 595 "/usr/homes/chet/src/bash/src/parse.y"
1593 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
1594 break;}
1595 case 82:
1596 #line 597 "/usr/homes/chet/src/bash/src/parse.y"
1597 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
1598 break;}
1599 case 84:
1600 #line 602 "/usr/homes/chet/src/bash/src/parse.y"
1601 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
1602 break;}
1603 case 85:
1604 #line 606 "/usr/homes/chet/src/bash/src/parse.y"
1605 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1606 break;}
1607 case 86:
1608 #line 608 "/usr/homes/chet/src/bash/src/parse.y"
1609 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1610 break;}
1611 case 87:
1612 #line 610 "/usr/homes/chet/src/bash/src/parse.y"
1613 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1614 break;}
1615 case 88:
1616 #line 612 "/usr/homes/chet/src/bash/src/parse.y"
1617 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1618 break;}
1619 case 90:
1620 #line 617 "/usr/homes/chet/src/bash/src/parse.y"
1621 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
1622 break;}
1623 case 91:
1624 #line 621 "/usr/homes/chet/src/bash/src/parse.y"
1625 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1626 break;}
1627 case 92:
1628 #line 623 "/usr/homes/chet/src/bash/src/parse.y"
1629 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
1630 break;}
1631 case 93:
1632 #line 632 "/usr/homes/chet/src/bash/src/parse.y"
1633 {
1634 yyval.command = yyvsp[0].command;
1635 if (need_here_doc)
1636 gather_here_documents ();
1637 ;
1638 break;}
1639 case 95:
1640 #line 641 "/usr/homes/chet/src/bash/src/parse.y"
1641 {
1642 yyval.command = yyvsp[0].command;
1643 ;
1644 break;}
1645 case 97:
1646 #line 648 "/usr/homes/chet/src/bash/src/parse.y"
1647 {
1648 if (yyvsp[-2].command->type == cm_connection)
1649 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1650 else
1651 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1652 ;
1653 break;}
1654 case 99:
1655 #line 659 "/usr/homes/chet/src/bash/src/parse.y"
1656 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1657 break;}
1658 case 100:
1659 #line 661 "/usr/homes/chet/src/bash/src/parse.y"
1660 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1661 break;}
1662 case 101:
1663 #line 663 "/usr/homes/chet/src/bash/src/parse.y"
1664 {
1665 if (yyvsp[-3].command->type == cm_connection)
1666 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1667 else
1668 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1669 ;
1670 break;}
1671 case 102:
1672 #line 670 "/usr/homes/chet/src/bash/src/parse.y"
1673 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1674 break;}
1675 case 103:
1676 #line 672 "/usr/homes/chet/src/bash/src/parse.y"
1677 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1678 break;}
1679 case 104:
1680 #line 674 "/usr/homes/chet/src/bash/src/parse.y"
1681 { yyval.command = yyvsp[0].command; ;
1682 break;}
1683 case 110:
1684 #line 693 "/usr/homes/chet/src/bash/src/parse.y"
1685 {
1686 yyval.command = yyvsp[0].command;
1687 if (need_here_doc)
1688 gather_here_documents ();
1689 ;
1690 break;}
1691 case 111:
1692 #line 699 "/usr/homes/chet/src/bash/src/parse.y"
1693 {
1694 if (yyvsp[-1].command->type == cm_connection)
1695 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
1696 else
1697 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
1698 if (need_here_doc)
1699 gather_here_documents ();
1700 ;
1701 break;}
1702 case 112:
1703 #line 708 "/usr/homes/chet/src/bash/src/parse.y"
1704 {
1705 yyval.command = yyvsp[-1].command;
1706 if (need_here_doc)
1707 gather_here_documents ();
1708 ;
1709 break;}
1710 case 113:
1711 #line 716 "/usr/homes/chet/src/bash/src/parse.y"
1712 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1713 break;}
1714 case 114:
1715 #line 718 "/usr/homes/chet/src/bash/src/parse.y"
1716 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1717 break;}
1718 case 115:
1719 #line 720 "/usr/homes/chet/src/bash/src/parse.y"
1720 {
1721 if (yyvsp[-2].command->type == cm_connection)
1722 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
1723 else
1724 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
1725 ;
1726 break;}
1727 case 116:
1728 #line 727 "/usr/homes/chet/src/bash/src/parse.y"
1729 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
1730 break;}
1731 case 117:
1732 #line 730 "/usr/homes/chet/src/bash/src/parse.y"
1733 { yyval.command = yyvsp[0].command; ;
1734 break;}
1735 case 118:
1736 #line 734 "/usr/homes/chet/src/bash/src/parse.y"
1737 { yyval.command = yyvsp[0].command; ;
1738 break;}
1739 case 119:
1740 #line 736 "/usr/homes/chet/src/bash/src/parse.y"
1741 {
1742 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
1743 yyval.command = yyvsp[0].command;
1744 ;
1745 break;}
1746 case 120:
1747 #line 741 "/usr/homes/chet/src/bash/src/parse.y"
1748 {
1749 yyvsp[0].command->flags |= yyvsp[-1].number;
1750 yyval.command = yyvsp[0].command;
1751 ;
1752 break;}
1753 case 121:
1754 #line 746 "/usr/homes/chet/src/bash/src/parse.y"
1755 {
1756 yyvsp[0].command->flags |= yyvsp[-2].number;
1757 yyval.command = yyvsp[0].command;
1758 ;
1759 break;}
1760 case 122:
1761 #line 751 "/usr/homes/chet/src/bash/src/parse.y"
1762 {
1763 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
1764 yyval.command = yyvsp[0].command;
1765 ;
1766 break;}
1767 case 123:
1768 #line 759 "/usr/homes/chet/src/bash/src/parse.y"
1769 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
1770 break;}
1771 case 124:
1772 #line 761 "/usr/homes/chet/src/bash/src/parse.y"
1773 { yyval.command = yyvsp[0].command; ;
1774 break;}
1775 case 125:
1776 #line 765 "/usr/homes/chet/src/bash/src/parse.y"
1777 { yyval.number = CMD_TIME_PIPELINE; ;
1778 break;}
1779 case 126:
1780 #line 767 "/usr/homes/chet/src/bash/src/parse.y"
1781 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
1782 break;}
1783 }
1784 /* the action file gets copied in in place of this dollarsign */
1785 #line 498 "/usr/share/misc/bison.simple"
1786 \f
1787 yyvsp -= yylen;
1788 yyssp -= yylen;
1789 #ifdef YYLSP_NEEDED
1790 yylsp -= yylen;
1791 #endif
1792
1793 #if YYDEBUG != 0
1794 if (yydebug)
1795 {
1796 short *ssp1 = yyss - 1;
1797 fprintf (stderr, "state stack now");
1798 while (ssp1 != yyssp)
1799 fprintf (stderr, " %d", *++ssp1);
1800 fprintf (stderr, "\n");
1801 }
1802 #endif
1803
1804 *++yyvsp = yyval;
1805
1806 #ifdef YYLSP_NEEDED
1807 yylsp++;
1808 if (yylen == 0)
1809 {
1810 yylsp->first_line = yylloc.first_line;
1811 yylsp->first_column = yylloc.first_column;
1812 yylsp->last_line = (yylsp-1)->last_line;
1813 yylsp->last_column = (yylsp-1)->last_column;
1814 yylsp->text = 0;
1815 }
1816 else
1817 {
1818 yylsp->last_line = (yylsp+yylen-1)->last_line;
1819 yylsp->last_column = (yylsp+yylen-1)->last_column;
1820 }
1821 #endif
1822
1823 /* Now "shift" the result of the reduction.
1824 Determine what state that goes to,
1825 based on the state we popped back to
1826 and the rule number reduced by. */
1827
1828 yyn = yyr1[yyn];
1829
1830 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1831 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1832 yystate = yytable[yystate];
1833 else
1834 yystate = yydefgoto[yyn - YYNTBASE];
1835
1836 goto yynewstate;
1837
1838 yyerrlab: /* here on detecting error */
1839
1840 if (! yyerrstatus)
1841 /* If not already recovering from an error, report this error. */
1842 {
1843 ++yynerrs;
1844
1845 #ifdef YYERROR_VERBOSE
1846 yyn = yypact[yystate];
1847
1848 if (yyn > YYFLAG && yyn < YYLAST)
1849 {
1850 int size = 0;
1851 char *msg;
1852 int x, count;
1853
1854 count = 0;
1855 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1856 for (x = (yyn < 0 ? -yyn : 0);
1857 x < (sizeof(yytname) / sizeof(char *)); x++)
1858 if (yycheck[x + yyn] == x)
1859 size += strlen(yytname[x]) + 15, count++;
1860 msg = (char *) malloc(size + 15);
1861 if (msg != 0)
1862 {
1863 strcpy(msg, "parse error");
1864
1865 if (count < 5)
1866 {
1867 count = 0;
1868 for (x = (yyn < 0 ? -yyn : 0);
1869 x < (sizeof(yytname) / sizeof(char *)); x++)
1870 if (yycheck[x + yyn] == x)
1871 {
1872 strcat(msg, count == 0 ? ", expecting `" : " or `");
1873 strcat(msg, yytname[x]);
1874 strcat(msg, "'");
1875 count++;
1876 }
1877 }
1878 yyerror(msg);
1879 free(msg);
1880 }
1881 else
1882 yyerror ("parse error; also virtual memory exceeded");
1883 }
1884 else
1885 #endif /* YYERROR_VERBOSE */
1886 yyerror("parse error");
1887 }
1888
1889 goto yyerrlab1;
1890 yyerrlab1: /* here on error raised explicitly by an action */
1891
1892 if (yyerrstatus == 3)
1893 {
1894 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1895
1896 /* return failure if at end of input */
1897 if (yychar == YYEOF)
1898 YYABORT;
1899
1900 #if YYDEBUG != 0
1901 if (yydebug)
1902 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1903 #endif
1904
1905 yychar = YYEMPTY;
1906 }
1907
1908 /* Else will try to reuse lookahead token
1909 after shifting the error token. */
1910
1911 yyerrstatus = 3; /* Each real token shifted decrements this */
1912
1913 goto yyerrhandle;
1914
1915 yyerrdefault: /* current state does not do anything special for the error token. */
1916
1917 #if 0
1918 /* This is wrong; only states that explicitly want error tokens
1919 should shift them. */
1920 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1921 if (yyn) goto yydefault;
1922 #endif
1923
1924 yyerrpop: /* pop the current state because it cannot handle the error token */
1925
1926 if (yyssp == yyss) YYABORT;
1927 yyvsp--;
1928 yystate = *--yyssp;
1929 #ifdef YYLSP_NEEDED
1930 yylsp--;
1931 #endif
1932
1933 #if YYDEBUG != 0
1934 if (yydebug)
1935 {
1936 short *ssp1 = yyss - 1;
1937 fprintf (stderr, "Error: state stack now");
1938 while (ssp1 != yyssp)
1939 fprintf (stderr, " %d", *++ssp1);
1940 fprintf (stderr, "\n");
1941 }
1942 #endif
1943
1944 yyerrhandle:
1945
1946 yyn = yypact[yystate];
1947 if (yyn == YYFLAG)
1948 goto yyerrdefault;
1949
1950 yyn += YYTERROR;
1951 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1952 goto yyerrdefault;
1953
1954 yyn = yytable[yyn];
1955 if (yyn < 0)
1956 {
1957 if (yyn == YYFLAG)
1958 goto yyerrpop;
1959 yyn = -yyn;
1960 goto yyreduce;
1961 }
1962 else if (yyn == 0)
1963 goto yyerrpop;
1964
1965 if (yyn == YYFINAL)
1966 YYACCEPT;
1967
1968 #if YYDEBUG != 0
1969 if (yydebug)
1970 fprintf(stderr, "Shifting error token, ");
1971 #endif
1972
1973 *++yyvsp = yylval;
1974 #ifdef YYLSP_NEEDED
1975 *++yylsp = yylloc;
1976 #endif
1977
1978 yystate = yyn;
1979 goto yynewstate;
1980 }
1981 #line 769 "/usr/homes/chet/src/bash/src/parse.y"
1982
1983
1984 /* Possible states for the parser that require it to do special things. */
1985 #define PST_CASEPAT 0x001 /* in a case pattern list */
1986 #define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
1987 #define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
1988 #define PST_NEEDCLOSBRC 0x008 /* need close brace */
1989 #define PST_DBLPAREN 0x010 /* double-paren parsing */
1990 #define PST_SUBSHELL 0x020 /* ( ... ) subshell */
1991 #define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
1992 #define PST_CASESTMT 0x080 /* parsing a case statement */
1993 #define PST_CONDCMD 0x100 /* parsing a [[...]] command */
1994 #define PST_CONDEXPR 0x200 /* parsing the guts of [[...]] */
1995
1996 /* Initial size to allocate for tokens, and the
1997 amount to grow them by. */
1998 #define TOKEN_DEFAULT_INITIAL_SIZE 496
1999 #define TOKEN_DEFAULT_GROW_SIZE 512
2000
2001 /* Shell meta-characters that, when unquoted, separate words. */
2002 #define shellmeta(c) (strchr (shell_meta_chars, (c)) != 0)
2003 #define shellbreak(c) (strchr (shell_break_chars, (c)) != 0)
2004 #define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
2005 #define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
2006
2007 char *shell_meta_chars = "()<>;&|";
2008 char *shell_break_chars = "()<>;&| \t\n";
2009
2010 /* The token currently being read. */
2011 static int current_token;
2012
2013 /* The last read token, or NULL. read_token () uses this for context
2014 checking. */
2015 static int last_read_token;
2016
2017 /* The token read prior to last_read_token. */
2018 static int token_before_that;
2019
2020 /* The token read prior to token_before_that. */
2021 static int two_tokens_ago;
2022
2023 /* If non-zero, it is the token that we want read_token to return
2024 regardless of what text is (or isn't) present to be read. This
2025 is reset by read_token. If token_to_read == WORD or
2026 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
2027 static int token_to_read;
2028 static WORD_DESC *word_desc_to_read;
2029
2030 /* The current parser state. */
2031 static int parser_state;
2032
2033 /* Global var is non-zero when end of file has been reached. */
2034 int EOF_Reached = 0;
2035
2036 void
2037 debug_parser (i)
2038 int i;
2039 {
2040 #if YYDEBUG != 0
2041 yydebug = i;
2042 #endif
2043 }
2044
2045 /* yy_getc () returns the next available character from input or EOF.
2046 yy_ungetc (c) makes `c' the next character to read.
2047 init_yy_io (get, unget, type, location) makes the function GET the
2048 installed function for getting the next character, makes UNGET the
2049 installed function for un-getting a character, sets the type of stream
2050 (either string or file) from TYPE, and makes LOCATION point to where
2051 the input is coming from. */
2052
2053 /* Unconditionally returns end-of-file. */
2054 int
2055 return_EOF ()
2056 {
2057 return (EOF);
2058 }
2059
2060 /* Variable containing the current get and unget functions.
2061 See ./input.h for a clearer description. */
2062 BASH_INPUT bash_input;
2063
2064 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2065 is non-null, avoiding a memory leak. */
2066 void
2067 initialize_bash_input ()
2068 {
2069 bash_input.type = st_none;
2070 FREE (bash_input.name);
2071 bash_input.name = (char *)NULL;
2072 bash_input.location.file = (FILE *)NULL;
2073 bash_input.location.string = (char *)NULL;
2074 bash_input.getter = (Function *)NULL;
2075 bash_input.ungetter = (Function *)NULL;
2076 }
2077
2078 /* Set the contents of the current bash input stream from
2079 GET, UNGET, TYPE, NAME, and LOCATION. */
2080 void
2081 init_yy_io (get, unget, type, name, location)
2082 Function *get, *unget;
2083 enum stream_type type;
2084 char *name;
2085 INPUT_STREAM location;
2086 {
2087 bash_input.type = type;
2088 FREE (bash_input.name);
2089 bash_input.name = name ? savestring (name) : (char *)NULL;
2090
2091 /* XXX */
2092 #if defined (CRAY)
2093 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2094 #else
2095 bash_input.location = location;
2096 #endif
2097 bash_input.getter = get;
2098 bash_input.ungetter = unget;
2099 }
2100
2101 /* Call this to get the next character of input. */
2102 int
2103 yy_getc ()
2104 {
2105 return (*(bash_input.getter)) ();
2106 }
2107
2108 /* Call this to unget C. That is, to make C the next character
2109 to be read. */
2110 int
2111 yy_ungetc (c)
2112 int c;
2113 {
2114 return (*(bash_input.ungetter)) (c);
2115 }
2116
2117 #if defined (BUFFERED_INPUT)
2118 int
2119 input_file_descriptor ()
2120 {
2121 switch (bash_input.type)
2122 {
2123 case st_stream:
2124 return (fileno (bash_input.location.file));
2125 case st_bstream:
2126 return (bash_input.location.buffered_fd);
2127 case st_stdin:
2128 default:
2129 return (fileno (stdin));
2130 }
2131 }
2132 #endif /* BUFFERED_INPUT */
2133
2134 /* **************************************************************** */
2135 /* */
2136 /* Let input be read from readline (). */
2137 /* */
2138 /* **************************************************************** */
2139
2140 #if defined (READLINE)
2141 char *current_readline_prompt = (char *)NULL;
2142 char *current_readline_line = (char *)NULL;
2143 int current_readline_line_index = 0;
2144
2145 static int
2146 yy_readline_get ()
2147 {
2148 SigHandler *old_sigint;
2149 int line_len, c;
2150
2151 if (!current_readline_line)
2152 {
2153 if (!bash_readline_initialized)
2154 initialize_readline ();
2155
2156 #if defined (JOB_CONTROL)
2157 if (job_control)
2158 give_terminal_to (shell_pgrp);
2159 #endif /* JOB_CONTROL */
2160
2161 if (signal_is_ignored (SIGINT) == 0)
2162 {
2163 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2164 interrupt_immediately++;
2165 }
2166
2167 current_readline_line = readline (current_readline_prompt ?
2168 current_readline_prompt : "");
2169
2170 if (signal_is_ignored (SIGINT) == 0)
2171 {
2172 interrupt_immediately--;
2173 set_signal_handler (SIGINT, old_sigint);
2174 }
2175
2176 #if 0
2177 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2178 reset_readline_prompt ();
2179 #endif
2180
2181 if (current_readline_line == 0)
2182 return (EOF);
2183
2184 current_readline_line_index = 0;
2185 line_len = strlen (current_readline_line);
2186
2187 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
2188 current_readline_line[line_len++] = '\n';
2189 current_readline_line[line_len] = '\0';
2190 }
2191
2192 if (current_readline_line[current_readline_line_index] == 0)
2193 {
2194 free (current_readline_line);
2195 current_readline_line = (char *)NULL;
2196 return (yy_readline_get ());
2197 }
2198 else
2199 {
2200 c = (unsigned char)current_readline_line[current_readline_line_index++];
2201 return (c);
2202 }
2203 }
2204
2205 static int
2206 yy_readline_unget (c)
2207 int c;
2208 {
2209 if (current_readline_line_index && current_readline_line)
2210 current_readline_line[--current_readline_line_index] = c;
2211 return (c);
2212 }
2213
2214 void
2215 with_input_from_stdin ()
2216 {
2217 INPUT_STREAM location;
2218
2219 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2220 {
2221 location.string = current_readline_line;
2222 init_yy_io (yy_readline_get, yy_readline_unget,
2223 st_stdin, "readline stdin", location);
2224 }
2225 }
2226
2227 #else /* !READLINE */
2228
2229 void
2230 with_input_from_stdin ()
2231 {
2232 with_input_from_stream (stdin, "stdin");
2233 }
2234 #endif /* !READLINE */
2235
2236 /* **************************************************************** */
2237 /* */
2238 /* Let input come from STRING. STRING is zero terminated. */
2239 /* */
2240 /* **************************************************************** */
2241
2242 static int
2243 yy_string_get ()
2244 {
2245 register char *string;
2246 register int c;
2247
2248 string = bash_input.location.string;
2249 c = EOF;
2250
2251 /* If the string doesn't exist, or is empty, EOF found. */
2252 if (string && *string)
2253 {
2254 c = *(unsigned char *)string++;
2255 bash_input.location.string = string;
2256 }
2257 return (c);
2258 }
2259
2260 static int
2261 yy_string_unget (c)
2262 int c;
2263 {
2264 *(--bash_input.location.string) = c;
2265 return (c);
2266 }
2267
2268 void
2269 with_input_from_string (string, name)
2270 char *string, *name;
2271 {
2272 INPUT_STREAM location;
2273
2274 location.string = string;
2275 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2276 }
2277
2278 /* **************************************************************** */
2279 /* */
2280 /* Let input come from STREAM. */
2281 /* */
2282 /* **************************************************************** */
2283
2284 static int
2285 yy_stream_get ()
2286 {
2287 int result = EOF;
2288
2289 if (bash_input.location.file)
2290 {
2291 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2292 result = getc_with_restart (bash_input.location.file);
2293 #else /* HAVE_RESTARTABLE_SYSCALLS */
2294 result = getc (bash_input.location.file);
2295 result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
2296 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2297 }
2298 return (result);
2299 }
2300
2301 static int
2302 yy_stream_unget (c)
2303 int c;
2304 {
2305 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2306 return (ungetc_with_restart (c, bash_input.location.file));
2307 #else /* HAVE_RESTARTABLE_SYSCALLS */
2308 return (ungetc (c, bash_input.location.file));
2309 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2310 }
2311
2312 void
2313 with_input_from_stream (stream, name)
2314 FILE *stream;
2315 char *name;
2316 {
2317 INPUT_STREAM location;
2318
2319 location.file = stream;
2320 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2321 }
2322
2323 typedef struct stream_saver {
2324 struct stream_saver *next;
2325 BASH_INPUT bash_input;
2326 int line;
2327 #if defined (BUFFERED_INPUT)
2328 BUFFERED_STREAM *bstream;
2329 #endif /* BUFFERED_INPUT */
2330 } STREAM_SAVER;
2331
2332 /* The globally known line number. */
2333 int line_number = 0;
2334
2335 #if defined (COND_COMMAND)
2336 static int cond_lineno;
2337 static int cond_token;
2338 #endif
2339
2340 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2341
2342 void
2343 push_stream (reset_lineno)
2344 int reset_lineno;
2345 {
2346 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2347
2348 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2349
2350 #if defined (BUFFERED_INPUT)
2351 saver->bstream = (BUFFERED_STREAM *)NULL;
2352 /* If we have a buffered stream, clear out buffers[fd]. */
2353 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2354 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
2355 (BUFFERED_STREAM *)NULL);
2356 #endif /* BUFFERED_INPUT */
2357
2358 saver->line = line_number;
2359 bash_input.name = (char *)NULL;
2360 saver->next = stream_list;
2361 stream_list = saver;
2362 EOF_Reached = 0;
2363 if (reset_lineno)
2364 line_number = 0;
2365 }
2366
2367 void
2368 pop_stream ()
2369 {
2370 if (!stream_list)
2371 EOF_Reached = 1;
2372 else
2373 {
2374 STREAM_SAVER *saver = stream_list;
2375
2376 EOF_Reached = 0;
2377 stream_list = stream_list->next;
2378
2379 init_yy_io (saver->bash_input.getter,
2380 saver->bash_input.ungetter,
2381 saver->bash_input.type,
2382 saver->bash_input.name,
2383 saver->bash_input.location);
2384
2385 #if defined (BUFFERED_INPUT)
2386 /* If we have a buffered stream, restore buffers[fd]. */
2387 /* If the input file descriptor was changed while this was on the
2388 save stack, update the buffered fd to the new file descriptor and
2389 re-establish the buffer <-> bash_input fd correspondence. */
2390 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2391 {
2392 if (bash_input_fd_changed)
2393 {
2394 bash_input_fd_changed = 0;
2395 if (default_buffered_input >= 0)
2396 {
2397 bash_input.location.buffered_fd = default_buffered_input;
2398 saver->bstream->b_fd = default_buffered_input;
2399 }
2400 }
2401 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
2402 }
2403 #endif /* BUFFERED_INPUT */
2404
2405 line_number = saver->line;
2406
2407 FREE (saver->bash_input.name);
2408 free (saver);
2409 }
2410 }
2411
2412 /* Return 1 if a stream of type TYPE is saved on the stack. */
2413 int
2414 stream_on_stack (type)
2415 enum stream_type type;
2416 {
2417 register STREAM_SAVER *s;
2418
2419 for (s = stream_list; s; s = s->next)
2420 if (s->bash_input.type == type)
2421 return 1;
2422 return 0;
2423 }
2424
2425 /*
2426 * This is used to inhibit alias expansion and reserved word recognition
2427 * inside case statement pattern lists. A `case statement pattern list' is:
2428 *
2429 * everything between the `in' in a `case word in' and the next ')'
2430 * or `esac'
2431 * everything between a `;;' and the next `)' or `esac'
2432 */
2433
2434 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2435
2436 #if !defined (ALIAS)
2437 typedef void *alias_t;
2438 #endif
2439
2440 #define END_OF_ALIAS 0
2441
2442 /*
2443 * Pseudo-global variables used in implementing token-wise alias expansion.
2444 */
2445
2446 /*
2447 * Pushing and popping strings. This works together with shell_getc to
2448 * implement alias expansion on a per-token basis.
2449 */
2450
2451 typedef struct string_saver {
2452 struct string_saver *next;
2453 int expand_alias; /* Value to set expand_alias to when string is popped. */
2454 char *saved_line;
2455 #if defined (ALIAS)
2456 alias_t *expander; /* alias that caused this line to be pushed. */
2457 #endif
2458 int saved_line_size, saved_line_index, saved_line_terminator;
2459 } STRING_SAVER;
2460
2461 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2462
2463 /*
2464 * Push the current shell_input_line onto a stack of such lines and make S
2465 * the current input. Used when expanding aliases. EXPAND is used to set
2466 * the value of expand_next_token when the string is popped, so that the
2467 * word after the alias in the original line is handled correctly when the
2468 * alias expands to multiple words. TOKEN is the token that was expanded
2469 * into S; it is saved and used to prevent infinite recursive expansion.
2470 */
2471 static void
2472 push_string (s, expand, ap)
2473 char *s;
2474 int expand;
2475 alias_t *ap;
2476 {
2477 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2478
2479 temp->expand_alias = expand;
2480 temp->saved_line = shell_input_line;
2481 temp->saved_line_size = shell_input_line_size;
2482 temp->saved_line_index = shell_input_line_index;
2483 temp->saved_line_terminator = shell_input_line_terminator;
2484 #if defined (ALIAS)
2485 temp->expander = ap;
2486 #endif
2487 temp->next = pushed_string_list;
2488 pushed_string_list = temp;
2489
2490 #if defined (ALIAS)
2491 if (ap)
2492 ap->flags |= AL_BEINGEXPANDED;
2493 #endif
2494
2495 shell_input_line = s;
2496 shell_input_line_size = strlen (s);
2497 shell_input_line_index = 0;
2498 shell_input_line_terminator = '\0';
2499 parser_state &= ~PST_ALEXPNEXT;
2500 }
2501
2502 /*
2503 * Make the top of the pushed_string stack be the current shell input.
2504 * Only called when there is something on the stack. Called from shell_getc
2505 * when it thinks it has consumed the string generated by an alias expansion
2506 * and needs to return to the original input line.
2507 */
2508 static void
2509 pop_string ()
2510 {
2511 STRING_SAVER *t;
2512
2513 FREE (shell_input_line);
2514 shell_input_line = pushed_string_list->saved_line;
2515 shell_input_line_index = pushed_string_list->saved_line_index;
2516 shell_input_line_size = pushed_string_list->saved_line_size;
2517 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2518
2519 if (pushed_string_list->expand_alias)
2520 parser_state |= PST_ALEXPNEXT;
2521 else
2522 parser_state &= ~PST_ALEXPNEXT;
2523
2524 t = pushed_string_list;
2525 pushed_string_list = pushed_string_list->next;
2526
2527 #if defined (ALIAS)
2528 if (t->expander)
2529 t->expander->flags &= ~AL_BEINGEXPANDED;
2530 #endif
2531
2532 free ((char *)t);
2533 }
2534
2535 static void
2536 free_string_list ()
2537 {
2538 register STRING_SAVER *t, *t1;
2539
2540 for (t = pushed_string_list; t; )
2541 {
2542 t1 = t->next;
2543 FREE (t->saved_line);
2544 #if defined (ALIAS)
2545 if (t->expander)
2546 t->expander->flags &= ~AL_BEINGEXPANDED;
2547 #endif
2548 free ((char *)t);
2549 t = t1;
2550 }
2551 pushed_string_list = (STRING_SAVER *)NULL;
2552 }
2553
2554 #endif /* ALIAS || DPAREN_ARITHMETIC */
2555
2556 /* Return a line of text, taken from wherever yylex () reads input.
2557 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2558 is non-zero, we remove unquoted \<newline> pairs. This is used by
2559 read_secondary_line to read here documents. */
2560 static char *
2561 read_a_line (remove_quoted_newline)
2562 int remove_quoted_newline;
2563 {
2564 static char *line_buffer = (char *)NULL;
2565 static int buffer_size = 0;
2566 int indx = 0, c, peekc, pass_next;
2567
2568 #if defined (READLINE)
2569 if (interactive && bash_input.type != st_string && no_line_editing)
2570 #else
2571 if (interactive && bash_input.type != st_string)
2572 #endif
2573 print_prompt ();
2574
2575 pass_next = 0;
2576 while (1)
2577 {
2578 c = yy_getc ();
2579
2580 /* Allow immediate exit if interrupted during input. */
2581 QUIT;
2582
2583 if (c == 0)
2584 continue;
2585
2586 /* If there is no more input, then we return NULL. */
2587 if (c == EOF)
2588 {
2589 if (interactive && bash_input.type == st_stream)
2590 clearerr (stdin);
2591 if (indx == 0)
2592 return ((char *)NULL);
2593 c = '\n';
2594 }
2595
2596 /* `+2' in case the final character in the buffer is a newline. */
2597 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2598
2599 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2600 here document with an unquoted delimiter. In this case,
2601 the line will be expanded as if it were in double quotes.
2602 We allow a backslash to escape the next character, but we
2603 need to treat the backslash specially only if a backslash
2604 quoting a backslash-newline pair appears in the line. */
2605 if (pass_next)
2606 {
2607 line_buffer[indx++] = c;
2608 pass_next = 0;
2609 }
2610 else if (c == '\\' && remove_quoted_newline)
2611 {
2612 peekc = yy_getc ();
2613 if (peekc == '\n')
2614 continue; /* Make the unquoted \<newline> pair disappear. */
2615 else
2616 {
2617 yy_ungetc (peekc);
2618 pass_next = 1;
2619 line_buffer[indx++] = c; /* Preserve the backslash. */
2620 }
2621 }
2622 else
2623 line_buffer[indx++] = c;
2624
2625 if (c == '\n')
2626 {
2627 line_buffer[indx] = '\0';
2628 return (line_buffer);
2629 }
2630 }
2631 }
2632
2633 /* Return a line as in read_a_line (), but insure that the prompt is
2634 the secondary prompt. This is used to read the lines of a here
2635 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2636 newlines quoted with backslashes while reading the line. It is
2637 non-zero unless the delimiter of the here document was quoted. */
2638 char *
2639 read_secondary_line (remove_quoted_newline)
2640 int remove_quoted_newline;
2641 {
2642 prompt_string_pointer = &ps2_prompt;
2643 prompt_again ();
2644 return (read_a_line (remove_quoted_newline));
2645 }
2646
2647 /* **************************************************************** */
2648 /* */
2649 /* YYLEX () */
2650 /* */
2651 /* **************************************************************** */
2652
2653 /* Reserved words. These are only recognized as the first word of a
2654 command. */
2655 STRING_INT_ALIST word_token_alist[] = {
2656 { "if", IF },
2657 { "then", THEN },
2658 { "else", ELSE },
2659 { "elif", ELIF },
2660 { "fi", FI },
2661 { "case", CASE },
2662 { "esac", ESAC },
2663 { "for", FOR },
2664 #if defined (SELECT_COMMAND)
2665 { "select", SELECT },
2666 #endif
2667 { "while", WHILE },
2668 { "until", UNTIL },
2669 { "do", DO },
2670 { "done", DONE },
2671 { "in", IN },
2672 { "function", FUNCTION },
2673 #if defined (COMMAND_TIMING)
2674 { "time", TIME },
2675 #endif
2676 { "{", '{' },
2677 { "}", '}' },
2678 { "!", BANG },
2679 #if defined (COND_COMMAND)
2680 { "[[", COND_START },
2681 { "]]", COND_END },
2682 #endif
2683 { (char *)NULL, 0}
2684 };
2685
2686 /* XXX - we should also have an alist with strings for other tokens, so we
2687 can give more descriptive error messages. Look at y.tab.h for the
2688 other tokens. */
2689
2690 /* These are used by read_token_word, but appear up here so that shell_getc
2691 can use them to decide when to add otherwise blank lines to the history. */
2692
2693 /* The primary delimiter stack. */
2694 struct dstack dstack = { (char *)NULL, 0, 0 };
2695
2696 /* A temporary delimiter stack to be used when decoding prompt strings.
2697 This is needed because command substitutions in prompt strings (e.g., PS2)
2698 can screw up the parser's quoting state. */
2699 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2700
2701 /* Macro for accessing the top delimiter on the stack. Returns the
2702 delimiter or zero if none. */
2703 #define current_delimiter(ds) \
2704 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2705
2706 #define push_delimiter(ds, character) \
2707 do \
2708 { \
2709 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2710 ds.delimiters = xrealloc \
2711 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2712 ds.delimiters[ds.delimiter_depth] = character; \
2713 ds.delimiter_depth++; \
2714 } \
2715 while (0)
2716
2717 #define pop_delimiter(ds) ds.delimiter_depth--
2718
2719 /* Return the next shell input character. This always reads characters
2720 from shell_input_line; when that line is exhausted, it is time to
2721 read the next line. This is called by read_token when the shell is
2722 processing normal command input. */
2723
2724 static int
2725 shell_getc (remove_quoted_newline)
2726 int remove_quoted_newline;
2727 {
2728 register int i;
2729 int c;
2730 static int mustpop = 0;
2731
2732 QUIT;
2733
2734 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2735 /* If shell_input_line[shell_input_line_index] == 0, but there is
2736 something on the pushed list of strings, then we don't want to go
2737 off and get another line. We let the code down below handle it. */
2738
2739 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2740 (pushed_string_list == (STRING_SAVER *)NULL)))
2741 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2742 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2743 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2744 {
2745 line_number++;
2746
2747 restart_read:
2748
2749 /* Allow immediate exit if interrupted during input. */
2750 QUIT;
2751
2752 i = 0;
2753 shell_input_line_terminator = 0;
2754
2755 #if defined (JOB_CONTROL)
2756 /* This can cause a problem when reading a command as the result
2757 of a trap, when the trap is called from flush_child. This call
2758 had better not cause jobs to disappear from the job table in
2759 that case, or we will have big trouble. */
2760 notify_and_cleanup ();
2761 #else /* !JOB_CONTROL */
2762 cleanup_dead_jobs ();
2763 #endif /* !JOB_CONTROL */
2764
2765 #if defined (READLINE)
2766 if (interactive && bash_input.type != st_string && no_line_editing)
2767 #else
2768 if (interactive && bash_input.type != st_string)
2769 #endif
2770 print_prompt ();
2771
2772 if (bash_input.type == st_stream)
2773 clearerr (stdin);
2774
2775 while (c = yy_getc ())
2776 {
2777 /* Allow immediate exit if interrupted during input. */
2778 QUIT;
2779
2780 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2781
2782 if (c == EOF)
2783 {
2784 if (bash_input.type == st_stream)
2785 clearerr (stdin);
2786
2787 if (i == 0)
2788 shell_input_line_terminator = EOF;
2789
2790 shell_input_line[i] = '\0';
2791 break;
2792 }
2793
2794 shell_input_line[i++] = c;
2795
2796 if (c == '\n')
2797 {
2798 shell_input_line[--i] = '\0';
2799 current_command_line_count++;
2800 break;
2801 }
2802 }
2803 shell_input_line_index = 0;
2804 shell_input_line_len = i; /* == strlen (shell_input_line) */
2805
2806 #if defined (HISTORY)
2807 if (remember_on_history && shell_input_line && shell_input_line[0])
2808 {
2809 char *expansions;
2810 # if defined (BANG_HISTORY)
2811 int old_hist;
2812
2813 /* If the current delimiter is a single quote, we should not be
2814 performing history expansion, even if we're on a different
2815 line from the original single quote. */
2816 old_hist = history_expansion_inhibited;
2817 if (current_delimiter (dstack) == '\'')
2818 history_expansion_inhibited = 1;
2819 # endif
2820 expansions = pre_process_line (shell_input_line, 1, 1);
2821 # if defined (BANG_HISTORY)
2822 history_expansion_inhibited = old_hist;
2823 # endif
2824 if (expansions != shell_input_line)
2825 {
2826 free (shell_input_line);
2827 shell_input_line = expansions;
2828 shell_input_line_len = shell_input_line ?
2829 strlen (shell_input_line) : 0;
2830 if (!shell_input_line_len)
2831 current_command_line_count--;
2832
2833 /* We have to force the xrealloc below because we don't know
2834 the true allocated size of shell_input_line anymore. */
2835 shell_input_line_size = shell_input_line_len;
2836 }
2837 }
2838 /* XXX - this is grotesque */
2839 else if (remember_on_history && shell_input_line &&
2840 shell_input_line[0] == '\0' &&
2841 current_command_line_count > 1 && current_delimiter (dstack))
2842 {
2843 /* We know shell_input_line[0] == 0 and we're reading some sort of
2844 quoted string. This means we've got a line consisting of only
2845 a newline in a quoted string. We want to make sure this line
2846 gets added to the history. */
2847 maybe_add_history (shell_input_line);
2848 }
2849
2850 #endif /* HISTORY */
2851
2852 if (shell_input_line)
2853 {
2854 /* Lines that signify the end of the shell's input should not be
2855 echoed. */
2856 if (echo_input_at_read && (shell_input_line[0] ||
2857 shell_input_line_terminator != EOF))
2858 fprintf (stderr, "%s\n", shell_input_line);
2859 }
2860 else
2861 {
2862 shell_input_line_size = 0;
2863 prompt_string_pointer = &current_prompt_string;
2864 prompt_again ();
2865 goto restart_read;
2866 }
2867
2868 /* Add the newline to the end of this string, iff the string does
2869 not already end in an EOF character. */
2870 if (shell_input_line_terminator != EOF)
2871 {
2872 if (shell_input_line_len + 3 > shell_input_line_size)
2873 shell_input_line = xrealloc (shell_input_line,
2874 1 + (shell_input_line_size += 2));
2875
2876 shell_input_line[shell_input_line_len] = '\n';
2877 shell_input_line[shell_input_line_len + 1] = '\0';
2878 }
2879 }
2880
2881 c = shell_input_line[shell_input_line_index];
2882
2883 if (c)
2884 shell_input_line_index++;
2885
2886 if (c == '\\' && remove_quoted_newline &&
2887 shell_input_line[shell_input_line_index] == '\n')
2888 {
2889 prompt_again ();
2890 line_number++;
2891 goto restart_read;
2892 }
2893
2894 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2895 /* If C is NULL, we have reached the end of the current input string. If
2896 pushed_string_list is non-empty, it's time to pop to the previous string
2897 because we have fully consumed the result of the last alias expansion.
2898 Do it transparently; just return the next character of the string popped
2899 to. */
2900 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2901 {
2902 if (mustpop)
2903 {
2904 pop_string ();
2905 c = shell_input_line[shell_input_line_index];
2906 if (c)
2907 shell_input_line_index++;
2908 mustpop--;
2909 }
2910 else
2911 {
2912 mustpop++;
2913 c = ' ';
2914 }
2915 }
2916 #endif /* ALIAS || DPAREN_ARITHMETIC */
2917
2918 if (!c && shell_input_line_terminator == EOF)
2919 return ((shell_input_line_index != 0) ? '\n' : EOF);
2920
2921 return ((unsigned char)c);
2922 }
2923
2924 /* Put C back into the input for the shell. */
2925 static void
2926 shell_ungetc (c)
2927 int c;
2928 {
2929 if (shell_input_line && shell_input_line_index)
2930 shell_input_line[--shell_input_line_index] = c;
2931 }
2932
2933 static void
2934 shell_ungetchar ()
2935 {
2936 if (shell_input_line && shell_input_line_index)
2937 shell_input_line_index--;
2938 }
2939
2940 /* Discard input until CHARACTER is seen, then push that character back
2941 onto the input stream. */
2942 static void
2943 discard_until (character)
2944 int character;
2945 {
2946 int c;
2947
2948 while ((c = shell_getc (0)) != EOF && c != character)
2949 ;
2950
2951 if (c != EOF)
2952 shell_ungetc (c);
2953 }
2954
2955 void
2956 execute_prompt_command (command)
2957 char *command;
2958 {
2959 Function *temp_last, *temp_this;
2960 char *last_lastarg;
2961 int temp_exit_value, temp_eof_encountered;
2962
2963 temp_last = last_shell_builtin;
2964 temp_this = this_shell_builtin;
2965 temp_exit_value = last_command_exit_value;
2966 temp_eof_encountered = eof_encountered;
2967 last_lastarg = get_string_value ("_");
2968 if (last_lastarg)
2969 last_lastarg = savestring (last_lastarg);
2970
2971 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
2972
2973 last_shell_builtin = temp_last;
2974 this_shell_builtin = temp_this;
2975 last_command_exit_value = temp_exit_value;
2976 eof_encountered = temp_eof_encountered;
2977
2978 bind_variable ("_", last_lastarg);
2979 FREE (last_lastarg);
2980
2981 if (token_to_read == '\n') /* reset_parser was called */
2982 token_to_read = 0;
2983 }
2984
2985 /* Place to remember the token. We try to keep the buffer
2986 at a reasonable size, but it can grow. */
2987 static char *token = (char *)NULL;
2988
2989 /* Current size of the token buffer. */
2990 static int token_buffer_size;
2991
2992 /* Command to read_token () explaining what we want it to do. */
2993 #define READ 0
2994 #define RESET 1
2995 #define prompt_is_ps1 \
2996 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2997
2998 /* Function for yyparse to call. yylex keeps track of
2999 the last two tokens read, and calls read_token. */
3000 static int
3001 yylex ()
3002 {
3003 if (interactive && (current_token == 0 || current_token == '\n'))
3004 {
3005 /* Before we print a prompt, we might have to check mailboxes.
3006 We do this only if it is time to do so. Notice that only here
3007 is the mail alarm reset; nothing takes place in check_mail ()
3008 except the checking of mail. Please don't change this. */
3009 if (prompt_is_ps1 && time_to_check_mail ())
3010 {
3011 check_mail ();
3012 reset_mail_timer ();
3013 }
3014
3015 /* Avoid printing a prompt if we're not going to read anything, e.g.
3016 after resetting the parser with read_token (RESET). */
3017 if (token_to_read == 0 && interactive)
3018 prompt_again ();
3019 }
3020
3021 two_tokens_ago = token_before_that;
3022 token_before_that = last_read_token;
3023 last_read_token = current_token;
3024 current_token = read_token (READ);
3025 return (current_token);
3026 }
3027
3028 /* When non-zero, we have read the required tokens
3029 which allow ESAC to be the next one read. */
3030 static int esacs_needed_count;
3031
3032 void
3033 gather_here_documents ()
3034 {
3035 int r = 0;
3036 while (need_here_doc)
3037 {
3038 make_here_document (redir_stack[r++]);
3039 need_here_doc--;
3040 }
3041 }
3042
3043 /* When non-zero, an open-brace used to create a group is awaiting a close
3044 brace partner. */
3045 static int open_brace_count;
3046
3047 #define command_token_position(token) \
3048 (((token) == ASSIGNMENT_WORD) || \
3049 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
3050
3051 #define assignment_acceptable(token) command_token_position(token) && \
3052 ((parser_state & PST_CASEPAT) == 0)
3053
3054 /* Check to see if TOKEN is a reserved word and return the token
3055 value if it is. */
3056 #define CHECK_FOR_RESERVED_WORD(tok) \
3057 do { \
3058 if (!dollar_present && !quoted && \
3059 reserved_word_acceptable (last_read_token)) \
3060 { \
3061 int i; \
3062 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
3063 if (STREQ (tok, word_token_alist[i].word)) \
3064 { \
3065 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
3066 break; \
3067 if (word_token_alist[i].token == TIME) \
3068 break; \
3069 if (word_token_alist[i].token == ESAC) \
3070 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
3071 else if (word_token_alist[i].token == CASE) \
3072 parser_state |= PST_CASESTMT; \
3073 else if (word_token_alist[i].token == COND_END) \
3074 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
3075 else if (word_token_alist[i].token == COND_START) \
3076 parser_state |= PST_CONDCMD; \
3077 else if (word_token_alist[i].token == '{') \
3078 open_brace_count++; \
3079 else if (word_token_alist[i].token == '}' && open_brace_count) \
3080 open_brace_count--; \
3081 return (word_token_alist[i].token); \
3082 } \
3083 } \
3084 } while (0)
3085
3086 #if defined (ALIAS)
3087
3088 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3089 it's eligible.
3090
3091 It is eligible for expansion if the shell is in interactive mode, and
3092 the token is unquoted and the last token read was a command
3093 separator (or expand_next_token is set), and we are currently
3094 processing an alias (pushed_string_list is non-empty) and this
3095 token is not the same as the current or any previously
3096 processed alias.
3097
3098 Special cases that disqualify:
3099 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3100 static int
3101 alias_expand_token (token)
3102 char *token;
3103 {
3104 char *expanded;
3105 alias_t *ap;
3106
3107 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3108 (parser_state & PST_CASEPAT) == 0)
3109 {
3110 ap = find_alias (token);
3111
3112 /* Currently expanding this token. */
3113 if (ap && (ap->flags & AL_BEINGEXPANDED))
3114 return (NO_EXPANSION);
3115
3116 expanded = ap ? savestring (ap->value) : (char *)NULL;
3117 if (expanded)
3118 {
3119 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3120 return (RE_READ_TOKEN);
3121 }
3122 else
3123 /* This is an eligible token that does not have an expansion. */
3124 return (NO_EXPANSION);
3125 }
3126 return (NO_EXPANSION);
3127 }
3128 #endif /* ALIAS */
3129
3130 static int
3131 time_command_acceptable ()
3132 {
3133 #if defined (COMMAND_TIMING)
3134 switch (last_read_token)
3135 {
3136 case 0:
3137 case ';':
3138 case '\n':
3139 case AND_AND:
3140 case OR_OR:
3141 case '&':
3142 case DO:
3143 case THEN:
3144 case ELSE:
3145 case '{':
3146 case '(':
3147 return 1;
3148 default:
3149 return 0;
3150 }
3151 #else
3152 return 0;
3153 #endif /* COMMAND_TIMING */
3154 }
3155
3156 /* Handle special cases of token recognition:
3157 IN is recognized if the last token was WORD and the token
3158 before that was FOR or CASE or SELECT.
3159
3160 DO is recognized if the last token was WORD and the token
3161 before that was FOR or SELECT.
3162
3163 ESAC is recognized if the last token caused `esacs_needed_count'
3164 to be set
3165
3166 `{' is recognized if the last token as WORD and the token
3167 before that was FUNCTION.
3168
3169 `}' is recognized if there is an unclosed `{' prsent.
3170
3171 `-p' is returned as TIMEOPT if the last read token was TIME.
3172
3173 ']]' is returned as COND_END if the parser is currently parsing
3174 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
3175
3176 `time' is returned as TIME if and only if it is immediately
3177 preceded by one of `;', `\n', `||', `&&', or `&'.
3178 */
3179
3180 static int
3181 special_case_tokens (token)
3182 char *token;
3183 {
3184 if ((last_read_token == WORD) &&
3185 #if defined (SELECT_COMMAND)
3186 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3187 #else
3188 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3189 #endif
3190 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3191 {
3192 if (token_before_that == CASE)
3193 {
3194 parser_state |= PST_CASEPAT;
3195 esacs_needed_count++;
3196 }
3197 return (IN);
3198 }
3199
3200 if (last_read_token == WORD &&
3201 #if defined (SELECT_COMMAND)
3202 (token_before_that == FOR || token_before_that == SELECT) &&
3203 #else
3204 (token_before_that == FOR) &&
3205 #endif
3206 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3207 return (DO);
3208
3209 /* Ditto for ESAC in the CASE case.
3210 Specifically, this handles "case word in esac", which is a legal
3211 construct, certainly because someone will pass an empty arg to the
3212 case construct, and we don't want it to barf. Of course, we should
3213 insist that the case construct has at least one pattern in it, but
3214 the designers disagree. */
3215 if (esacs_needed_count)
3216 {
3217 esacs_needed_count--;
3218 if (STREQ (token, "esac"))
3219 {
3220 parser_state &= ~PST_CASEPAT;
3221 return (ESAC);
3222 }
3223 }
3224
3225 /* The start of a shell function definition. */
3226 if (parser_state & PST_ALLOWOPNBRC)
3227 {
3228 parser_state &= ~PST_ALLOWOPNBRC;
3229 if (token[0] == '{' && token[1] == '\0') /* } */
3230 {
3231 open_brace_count++;
3232 function_bstart = line_number;
3233 return ('{'); /* } */
3234 }
3235 }
3236
3237 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3238 {
3239 open_brace_count--; /* { */
3240 return ('}');
3241 }
3242
3243 #if defined (COMMAND_TIMING)
3244 /* Handle -p after `time'. */
3245 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3246 return (TIMEOPT);
3247 #endif
3248
3249 #if defined (COMMAND_TIMING)
3250 if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
3251 return (TIME);
3252 #endif /* COMMAND_TIMING */
3253
3254 #if defined (COND_COMMAND) /* [[ */
3255 if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
3256 return (COND_END);
3257 #endif
3258
3259 return (-1);
3260 }
3261
3262 /* Called from shell.c when Control-C is typed at top level. Or
3263 by the error rule at top level. */
3264 void
3265 reset_parser ()
3266 {
3267 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3268 open_brace_count = 0;
3269
3270 parser_state = 0;
3271
3272 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3273 if (pushed_string_list)
3274 free_string_list ();
3275 #endif /* ALIAS || DPAREN_ARITHMETIC */
3276
3277 if (shell_input_line)
3278 {
3279 free (shell_input_line);
3280 shell_input_line = (char *)NULL;
3281 shell_input_line_size = shell_input_line_index = 0;
3282 }
3283
3284 FREE (word_desc_to_read);
3285 word_desc_to_read = (WORD_DESC *)NULL;
3286
3287 last_read_token = '\n';
3288 token_to_read = '\n';
3289 }
3290
3291 /* Read the next token. Command can be READ (normal operation) or
3292 RESET (to normalize state). */
3293 static int
3294 read_token (command)
3295 int command;
3296 {
3297 int character; /* Current character. */
3298 int peek_char; /* Temporary look-ahead character. */
3299 int result; /* The thing to return. */
3300
3301 if (command == RESET)
3302 {
3303 reset_parser ();
3304 return ('\n');
3305 }
3306
3307 if (token_to_read)
3308 {
3309 result = token_to_read;
3310 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3311 {
3312 yylval.word = word_desc_to_read;
3313 word_desc_to_read = (WORD_DESC *)NULL;
3314 }
3315 token_to_read = 0;
3316 return (result);
3317 }
3318
3319 #if defined (COND_COMMAND)
3320 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3321 {
3322 cond_lineno = line_number;
3323 parser_state |= PST_CONDEXPR;
3324 yylval.command = parse_cond_command ();
3325 if (cond_token != COND_END)
3326 {
3327 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
3328 parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
3329 else if (cond_token != COND_ERROR)
3330 parser_error (cond_lineno, "syntax error in conditional expression");
3331 return (-1);
3332 }
3333 token_to_read = COND_END;
3334 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3335 return (COND_CMD);
3336 }
3337 #endif
3338
3339 #if defined (ALIAS)
3340 /* This is a place to jump back to once we have successfully expanded a
3341 token with an alias and pushed the string with push_string () */
3342 re_read_token:
3343 #endif /* ALIAS */
3344
3345 /* Read a single word from input. Start by skipping blanks. */
3346 while ((character = shell_getc (1)) != EOF && whitespace (character))
3347 ;
3348
3349 if (character == EOF)
3350 {
3351 EOF_Reached = 1;
3352 return (yacc_EOF);
3353 }
3354
3355 if (character == '#' && (!interactive || interactive_comments))
3356 {
3357 /* A comment. Discard until EOL or EOF, and then return a newline. */
3358 discard_until ('\n');
3359 shell_getc (0);
3360 character = '\n'; /* this will take the next if statement and return. */
3361 }
3362
3363 if (character == '\n')
3364 {
3365 /* If we're about to return an unquoted newline, we can go and collect
3366 the text of any pending here document. */
3367 if (need_here_doc)
3368 gather_here_documents ();
3369
3370 #if defined (ALIAS)
3371 parser_state &= ~PST_ALEXPNEXT;
3372 #endif /* ALIAS */
3373
3374 return (character);
3375 }
3376
3377 /* Shell meta-characters. */
3378 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3379 {
3380 #if defined (ALIAS)
3381 /* Turn off alias tokenization iff this character sequence would
3382 not leave us ready to read a command. */
3383 if (character == '<' || character == '>')
3384 parser_state &= ~PST_ALEXPNEXT;
3385 #endif /* ALIAS */
3386
3387 peek_char = shell_getc (1);
3388 if (character == peek_char)
3389 {
3390 switch (character)
3391 {
3392 case '<':
3393 /* If '<' then we could be at "<<" or at "<<-". We have to
3394 look ahead one more character. */
3395 peek_char = shell_getc (1);
3396 if (peek_char == '-')
3397 return (LESS_LESS_MINUS);
3398 else
3399 {
3400 shell_ungetc (peek_char);
3401 return (LESS_LESS);
3402 }
3403
3404 case '>':
3405 return (GREATER_GREATER);
3406
3407 case ';':
3408 parser_state |= PST_CASEPAT;
3409 #if defined (ALIAS)
3410 parser_state &= ~PST_ALEXPNEXT;
3411 #endif /* ALIAS */
3412 return (SEMI_SEMI);
3413
3414 case '&':
3415 return (AND_AND);
3416
3417 case '|':
3418 return (OR_OR);
3419
3420 #if defined (DPAREN_ARITHMETIC)
3421 case '(': /* ) */
3422 if (reserved_word_acceptable (last_read_token))
3423 {
3424 int cmdtyp, sline;
3425 char *wval;
3426 WORD_DESC *wd;
3427
3428 sline = line_number;
3429 cmdtyp = parse_arith_cmd (&wval);
3430 if (cmdtyp == 1) /* arithmetic command */
3431 {
3432 wd = make_word (wval);
3433 wd->flags = W_QUOTED;
3434 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3435 free (wval); /* make_word copies it */
3436 return (ARITH_CMD);
3437 }
3438 else if (cmdtyp == 0) /* nested subshell */
3439 {
3440 push_string (wval, 0, (alias_t *)NULL);
3441 if ((parser_state & PST_CASEPAT) == 0)
3442 parser_state |= PST_SUBSHELL;
3443 return (character);
3444 }
3445 else /* ERROR */
3446 return -1;
3447 }
3448 break;
3449 #endif
3450 }
3451 }
3452 else if (character == '<' && peek_char == '&')
3453 return (LESS_AND);
3454 else if (character == '>' && peek_char == '&')
3455 return (GREATER_AND);
3456 else if (character == '<' && peek_char == '>')
3457 return (LESS_GREATER);
3458 else if (character == '>' && peek_char == '|')
3459 return (GREATER_BAR);
3460 else if (peek_char == '>' && character == '&')
3461 return (AND_GREATER);
3462
3463 shell_ungetc (peek_char);
3464
3465 /* If we look like we are reading the start of a function
3466 definition, then let the reader know about it so that
3467 we will do the right thing with `{'. */
3468 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
3469 {
3470 parser_state |= PST_ALLOWOPNBRC;
3471 #if defined (ALIAS)
3472 parser_state &= ~PST_ALEXPNEXT;
3473 #endif /* ALIAS */
3474 function_dstart = line_number;
3475 }
3476
3477 /* case pattern lists may be preceded by an optional left paren. If
3478 we're not trying to parse a case pattern list, the left paren
3479 indicates a subshell. */
3480 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3481 parser_state |= PST_SUBSHELL;
3482 /*(*/
3483 else if ((parser_state & PST_CASEPAT) && character == ')')
3484 parser_state &= ~PST_CASEPAT;
3485 /*(*/
3486 else if ((parser_state & PST_SUBSHELL) && character == ')')
3487 parser_state &= ~PST_SUBSHELL;
3488
3489 #if defined (PROCESS_SUBSTITUTION)
3490 /* Check for the constructs which introduce process substitution.
3491 Shells running in `posix mode' don't do process substitution. */
3492 if (posixly_correct ||
3493 ((character != '>' && character != '<') || peek_char != '('))
3494 #endif /* PROCESS_SUBSTITUTION */
3495 return (character);
3496 }
3497
3498 /* Hack <&- (close stdin) case. */
3499 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3500 return (character);
3501
3502 /* Okay, if we got this far, we have to read a word. Read one,
3503 and then check it against the known ones. */
3504 result = read_token_word (character);
3505 #if defined (ALIAS)
3506 if (result == RE_READ_TOKEN)
3507 goto re_read_token;
3508 #endif
3509 return result;
3510 }
3511
3512 /* Match a $(...) or other grouping construct. This has to handle embedded
3513 quoted strings ('', ``, "") and nested constructs. It also must handle
3514 reprompting the user, if necessary, after reading a newline, and returning
3515 correct error values if it reads EOF. */
3516
3517 #define P_FIRSTCLOSE 0x01
3518
3519 static char matched_pair_error;
3520 static char *
3521 parse_matched_pair (qc, open, close, lenp, flags)
3522 int qc; /* `"' if this construct is within double quotes */
3523 int open, close;
3524 int *lenp, flags;
3525 {
3526 int count, ch, was_dollar;
3527 int pass_next_character, nestlen, start_lineno;
3528 char *ret, *nestret;
3529 int retind, retsize;
3530
3531 count = 1;
3532 pass_next_character = was_dollar = 0;
3533
3534 ret = xmalloc (retsize = 64);
3535 retind = 0;
3536
3537 start_lineno = line_number;
3538 while (count)
3539 {
3540 ch = shell_getc (qc != '\'' && pass_next_character == 0);
3541 if (ch == EOF)
3542 {
3543 free (ret);
3544 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3545 EOF_Reached = 1; /* XXX */
3546 return (&matched_pair_error);
3547 }
3548
3549 /* Possible reprompting. */
3550 if (ch == '\n' && interactive &&
3551 (bash_input.type == st_stdin || bash_input.type == st_stream))
3552 prompt_again ();
3553
3554 if (pass_next_character) /* last char was backslash */
3555 {
3556 pass_next_character = 0;
3557 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3558 {
3559 if (retind > 0) retind--; /* swallow previously-added backslash */
3560 continue;
3561 }
3562
3563 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3564 if (ch == CTLESC || ch == CTLNUL)
3565 ret[retind++] = CTLESC;
3566 ret[retind++] = ch;
3567 continue;
3568 }
3569 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3570 {
3571 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3572 ret[retind++] = CTLESC;
3573 ret[retind++] = ch;
3574 continue;
3575 }
3576 else if (ch == close) /* ending delimiter */
3577 count--;
3578 else if (((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
3579 count++;
3580
3581 /* Add this character. */
3582 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3583 ret[retind++] = ch;
3584
3585 if (open == '\'') /* '' inside grouping construct */
3586 continue;
3587
3588 if (ch == '\\') /* backslashes */
3589 pass_next_character++;
3590
3591 if (open != close) /* a grouping construct */
3592 {
3593 if (shellquote (ch))
3594 {
3595 /* '', ``, or "" inside $(...) or other grouping construct. */
3596 push_delimiter (dstack, ch);
3597 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
3598 pop_delimiter (dstack);
3599 if (nestret == &matched_pair_error)
3600 {
3601 free (ret);
3602 return &matched_pair_error;
3603 }
3604 if (nestlen)
3605 {
3606 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3607 strcpy (ret + retind, nestret);
3608 retind += nestlen;
3609 }
3610 FREE (nestret);
3611 }
3612 }
3613 /* Parse an old-style command substitution within double quotes as a
3614 single word. */
3615 /* XXX - sh and ksh93 don't do this - XXX */
3616 else if (open == '"' && ch == '`')
3617 {
3618 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3619 if (nestret == &matched_pair_error)
3620 {
3621 free (ret);
3622 return &matched_pair_error;
3623 }
3624 if (nestlen)
3625 {
3626 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3627 strcpy (ret + retind, nestret);
3628 retind += nestlen;
3629 }
3630 FREE (nestret);
3631 }
3632 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3633 /* check for $(), $[], or ${} inside quoted string. */
3634 {
3635 if (open == ch) /* undo previous increment */
3636 count--;
3637 if (ch == '(') /* ) */
3638 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
3639 else if (ch == '{') /* } */
3640 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE);
3641 else if (ch == '[') /* ] */
3642 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
3643 if (nestret == &matched_pair_error)
3644 {
3645 free (ret);
3646 return &matched_pair_error;
3647 }
3648 if (nestlen)
3649 {
3650 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3651 strcpy (ret + retind, nestret);
3652 retind += nestlen;
3653 }
3654 FREE (nestret);
3655 }
3656 was_dollar = (ch == '$');
3657 }
3658
3659 ret[retind] = '\0';
3660 if (lenp)
3661 *lenp = retind;
3662 return ret;
3663 }
3664
3665 #if defined (DPAREN_ARITHMETIC)
3666 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
3667 If not, assume it's a nested subshell for backwards compatibility and
3668 return 0. In any case, put the characters we've consumed into a locally-
3669 allocated buffer and make *ep point to that buffer. Return -1 on an
3670 error, for example EOF. */
3671 static int
3672 parse_arith_cmd (ep)
3673 char **ep;
3674 {
3675 int exp_lineno, rval, c;
3676 char *ttok, *token;
3677 int ttoklen;
3678
3679 exp_lineno = line_number;
3680 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3681 rval = 1;
3682 if (ttok == &matched_pair_error)
3683 return -1;
3684 /* Check that the next character is the closing right paren. If
3685 not, this is a syntax error. ( */
3686 if ((c = shell_getc (0)) != ')')
3687 rval = 0;
3688
3689 token = xmalloc(ttoklen + 4);
3690
3691 /* (( ... )) -> "..." */
3692 token[0] = (rval == 1) ? '"' : '(';
3693 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
3694 if (rval == 1)
3695 {
3696 token[ttoklen] = '"';
3697 token[ttoklen+1] = '\0';
3698 }
3699 else
3700 {
3701 token[ttoklen] = ')';
3702 token[ttoklen+1] = c;
3703 token[ttoklen+2] = '\0';
3704 }
3705 *ep = token;
3706 FREE (ttok);
3707 return rval;
3708 }
3709 #endif /* DPAREN_ARITHMETIC */
3710
3711 #if defined (COND_COMMAND)
3712 static COND_COM *cond_term ();
3713 static COND_COM *cond_and ();
3714 static COND_COM *cond_or ();
3715 static COND_COM *cond_expr ();
3716
3717 static COND_COM *
3718 cond_expr ()
3719 {
3720 return (cond_or ());
3721 }
3722
3723 static COND_COM *
3724 cond_or ()
3725 {
3726 COND_COM *l, *r;
3727
3728 l = cond_and ();
3729 if (cond_token == OR_OR)
3730 {
3731 r = cond_or ();
3732 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3733 }
3734 return l;
3735 }
3736
3737 static COND_COM *
3738 cond_and ()
3739 {
3740 COND_COM *l, *r;
3741
3742 l = cond_term ();
3743 if (cond_token == AND_AND)
3744 {
3745 r = cond_and ();
3746 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3747 }
3748 return l;
3749 }
3750
3751 static int
3752 cond_skip_newlines ()
3753 {
3754 while ((cond_token = read_token (READ)) == '\n')
3755 {
3756 if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
3757 prompt_again ();
3758 }
3759 return (cond_token);
3760 }
3761
3762 #define COND_RETURN_ERROR() \
3763 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3764
3765 static COND_COM *
3766 cond_term ()
3767 {
3768 WORD_DESC *op;
3769 COND_COM *term, *tleft, *tright;
3770 int tok, lineno;
3771
3772 /* Read a token. It can be a left paren, a `!', a unary operator, or a
3773 word that should be the first argument of a binary operator. Start by
3774 skipping newlines, since this is a compound command. */
3775 tok = cond_skip_newlines ();
3776 lineno = line_number;
3777 if (tok == COND_END)
3778 {
3779 COND_RETURN_ERROR ();
3780 }
3781 else if (tok == '(')
3782 {
3783 term = cond_expr ();
3784 if (cond_token != ')')
3785 {
3786 if (term)
3787 dispose_cond_node (term); /* ( */
3788 parser_error (lineno, "expected `)'");
3789 COND_RETURN_ERROR ();
3790 }
3791 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3792 (void)cond_skip_newlines ();
3793 }
3794 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3795 {
3796 if (tok == WORD)
3797 dispose_word (yylval.word); /* not needed */
3798 term = cond_term ();
3799 if (term)
3800 term->flags |= CMD_INVERT_RETURN;
3801 }
3802 else if (tok == WORD && test_unop (yylval.word->word))
3803 {
3804 op = yylval.word;
3805 tok = read_token (READ);
3806 if (tok == WORD)
3807 {
3808 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3809 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3810 }
3811 else
3812 {
3813 dispose_word (op);
3814 parser_error (line_number, "unexpected argument to conditional unary operator");
3815 COND_RETURN_ERROR ();
3816 }
3817
3818 (void)cond_skip_newlines ();
3819 }
3820 else /* left argument to binary operator */
3821 {
3822 /* lhs */
3823 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3824
3825 /* binop */
3826 tok = read_token (READ);
3827 if (tok == WORD && test_binop (yylval.word->word))
3828 op = yylval.word;
3829 else if (tok == '<' || tok == '>')
3830 op = make_word_from_token (tok);
3831 else if (tok == COND_END || tok == AND_AND || tok == OR_OR)
3832 {
3833 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
3834 the test command. Similarly for [[ x && expr ]] or
3835 [[ x || expr ]] */
3836 op = make_word ("-n");
3837 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3838 cond_token = tok;
3839 return (term);
3840 }
3841 else
3842 {
3843 parser_error (line_number, "conditional binary operator expected");
3844 dispose_cond_node (tleft);
3845 COND_RETURN_ERROR ();
3846 }
3847
3848 /* rhs */
3849 tok = read_token (READ);
3850 if (tok == WORD)
3851 {
3852 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3853 term = make_cond_node (COND_BINARY, op, tleft, tright);
3854 }
3855 else
3856 {
3857 parser_error (line_number, "unexpected argument to conditional binary operator");
3858 dispose_cond_node (tleft);
3859 dispose_word (op);
3860 COND_RETURN_ERROR ();
3861 }
3862
3863 (void)cond_skip_newlines ();
3864 }
3865 return (term);
3866 }
3867
3868 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3869 here to handle the conditional statement syntax. */
3870 static COMMAND *
3871 parse_cond_command ()
3872 {
3873 COND_COM *cexp;
3874
3875 cexp = cond_expr ();
3876 return (make_cond_command (cexp));
3877 }
3878 #endif
3879
3880 static int
3881 read_token_word (character)
3882 int character;
3883 {
3884 /* The value for YYLVAL when a WORD is read. */
3885 WORD_DESC *the_word;
3886
3887 /* Index into the token that we are building. */
3888 int token_index;
3889
3890 /* ALL_DIGITS becomes zero when we see a non-digit. */
3891 int all_digits;
3892
3893 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3894 int dollar_present;
3895
3896 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3897 int quoted;
3898
3899 /* Non-zero means to ignore the value of the next character, and just
3900 to add it no matter what. */
3901 int pass_next_character;
3902
3903 /* The current delimiting character. */
3904 int cd;
3905 int result, peek_char;
3906 char *ttok, *ttrans;
3907 int ttoklen, ttranslen;
3908
3909 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3910 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3911
3912 token_index = 0;
3913 all_digits = digit (character);
3914 dollar_present = quoted = pass_next_character = 0;
3915
3916 for (;;)
3917 {
3918 if (character == EOF)
3919 goto got_token;
3920
3921 if (pass_next_character)
3922 {
3923 pass_next_character = 0;
3924 goto got_character;
3925 }
3926
3927 cd = current_delimiter (dstack);
3928
3929 /* Handle backslashes. Quote lots of things when not inside of
3930 double-quotes, quote some things inside of double-quotes. */
3931 if (character == '\\')
3932 {
3933 peek_char = shell_getc (0);
3934
3935 /* Backslash-newline is ignored in all cases except
3936 when quoted with single quotes. */
3937 if (peek_char == '\n')
3938 {
3939 character = '\n';
3940 goto next_character;
3941 }
3942 else
3943 {
3944 shell_ungetc (peek_char);
3945
3946 /* If the next character is to be quoted, note it now. */
3947 if (cd == 0 || cd == '`' ||
3948 (cd == '"' && member (peek_char, slashify_in_quotes)))
3949 pass_next_character++;
3950
3951 quoted = 1;
3952 goto got_character;
3953 }
3954 }
3955
3956 /* Parse a matched pair of quote characters. */
3957 if (shellquote (character))
3958 {
3959 push_delimiter (dstack, character);
3960 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
3961 pop_delimiter (dstack);
3962 if (ttok == &matched_pair_error)
3963 return -1; /* Bail immediately. */
3964 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3965 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3966 token[token_index++] = character;
3967 strcpy (token + token_index, ttok);
3968 token_index += ttoklen;
3969 all_digits = 0;
3970 quoted = 1;
3971 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3972 FREE (ttok);
3973 goto next_character;
3974 }
3975
3976 #ifdef EXTENDED_GLOB
3977 /* Parse a ksh-style extended pattern matching specification. */
3978 if (extended_glob && PATTERN_CHAR(character))
3979 {
3980 peek_char = shell_getc (1);
3981 if (peek_char == '(') /* ) */
3982 {
3983 push_delimiter (dstack, peek_char);
3984 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3985 pop_delimiter (dstack);
3986 if (ttok == &matched_pair_error)
3987 return -1; /* Bail immediately. */
3988 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3989 token_buffer_size,
3990 TOKEN_DEFAULT_GROW_SIZE);
3991 token[token_index++] = character;
3992 token[token_index++] = peek_char;
3993 strcpy (token + token_index, ttok);
3994 token_index += ttoklen;
3995 FREE (ttok);
3996 dollar_present = all_digits = 0;
3997 goto next_character;
3998 }
3999 else
4000 shell_ungetc (peek_char);
4001 }
4002 #endif /* EXTENDED_GLOB */
4003
4004 /* If the delimiter character is not single quote, parse some of
4005 the shell expansions that must be read as a single word. */
4006 #if defined (PROCESS_SUBSTITUTION)
4007 if (character == '$' || character == '<' || character == '>')
4008 #else
4009 if (character == '$')
4010 #endif /* !PROCESS_SUBSTITUTION */
4011 {
4012 peek_char = shell_getc (1);
4013 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4014 if (peek_char == '(' ||
4015 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4016 {
4017 if (peek_char == '{') /* } */
4018 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
4019 else if (peek_char == '(') /* ) */
4020 {
4021 /* XXX - push and pop the `(' as a delimiter for use by
4022 the command-oriented-history code. This way newlines
4023 appearing in the $(...) string get added to the
4024 history literally rather than causing a possibly-
4025 incorrect `;' to be added. */
4026 push_delimiter (dstack, peek_char);
4027 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4028 pop_delimiter (dstack);
4029 }
4030 else
4031 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4032 if (ttok == &matched_pair_error)
4033 return -1; /* Bail immediately. */
4034 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4035 token_buffer_size,
4036 TOKEN_DEFAULT_GROW_SIZE);
4037 token[token_index++] = character;
4038 token[token_index++] = peek_char;
4039 strcpy (token + token_index, ttok);
4040 token_index += ttoklen;
4041 FREE (ttok);
4042 dollar_present = 1;
4043 all_digits = 0;
4044 goto next_character;
4045 }
4046 /* This handles $'...' and $"..." new-style quoted strings. */
4047 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
4048 {
4049 int first_line;
4050
4051 first_line = line_number;
4052 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
4053 if (ttok == &matched_pair_error)
4054 return -1;
4055 if (peek_char == '\'')
4056 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4057 else
4058 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4059 free (ttok);
4060 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4061 token_buffer_size,
4062 TOKEN_DEFAULT_GROW_SIZE);
4063 token[token_index++] = peek_char;
4064 strcpy (token + token_index, ttrans);
4065 token_index += ttranslen;
4066 token[token_index++] = peek_char;
4067 FREE (ttrans);
4068 quoted = 1;
4069 all_digits = 0;
4070 goto next_character;
4071 }
4072 /* This could eventually be extended to recognize all of the
4073 shell's single-character parameter expansions, and set flags.*/
4074 else if (character == '$' && peek_char == '$')
4075 {
4076 ttok = xmalloc (3);
4077 ttok[0] = ttok[1] = '$';
4078 ttok[2] = '\0';
4079 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4080 token_buffer_size,
4081 TOKEN_DEFAULT_GROW_SIZE);
4082 strcpy (token + token_index, ttok);
4083 token_index += 2;
4084 dollar_present = 1;
4085 all_digits = 0;
4086 FREE (ttok);
4087 goto next_character;
4088 }
4089 else
4090 shell_ungetc (peek_char);
4091 }
4092
4093 #if defined (ARRAY_VARS)
4094 /* Identify possible compound array variable assignment. */
4095 else if (character == '=' && token_index > 0)
4096 {
4097 peek_char = shell_getc (1);
4098 if (peek_char == '(') /* ) */
4099 {
4100 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4101 if (ttok == &matched_pair_error)
4102 return -1; /* Bail immediately. */
4103 if (ttok[0] == '(') /* ) */
4104 {
4105 FREE (ttok);
4106 return -1;
4107 }
4108 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4109 token_buffer_size,
4110 TOKEN_DEFAULT_GROW_SIZE);
4111 token[token_index++] = character;
4112 token[token_index++] = peek_char;
4113 strcpy (token + token_index, ttok);
4114 token_index += ttoklen;
4115 FREE (ttok);
4116 all_digits = 0;
4117 goto next_character;
4118 }
4119 else
4120 shell_ungetc (peek_char);
4121 }
4122 #endif
4123
4124 /* When not parsing a multi-character word construct, shell meta-
4125 characters break words. */
4126 if (shellbreak (character))
4127 {
4128 shell_ungetc (character);
4129 goto got_token;
4130 }
4131
4132 got_character:
4133
4134 all_digits &= digit (character);
4135 dollar_present |= character == '$';
4136
4137 if (character == CTLESC || character == CTLNUL)
4138 token[token_index++] = CTLESC;
4139
4140 token[token_index++] = character;
4141
4142 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4143 TOKEN_DEFAULT_GROW_SIZE);
4144
4145 next_character:
4146 if (character == '\n' && interactive &&
4147 (bash_input.type == st_stdin || bash_input.type == st_stream))
4148 prompt_again ();
4149
4150 /* We want to remove quoted newlines (that is, a \<newline> pair)
4151 unless we are within single quotes or pass_next_character is
4152 set (the shell equivalent of literal-next). */
4153 cd = current_delimiter (dstack);
4154 character = shell_getc (cd != '\'' && pass_next_character == 0);
4155 } /* end for (;;) */
4156
4157 got_token:
4158
4159 token[token_index] = '\0';
4160
4161 /* Check to see what thing we should return. If the last_read_token
4162 is a `<', or a `&', or the character which ended this token is
4163 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4164 Otherwise, it is just a word, and should be returned as such. */
4165 if (all_digits && (character == '<' || character == '>' ||
4166 last_read_token == LESS_AND ||
4167 last_read_token == GREATER_AND))
4168 {
4169 yylval.number = atoi (token);
4170 return (NUMBER);
4171 }
4172
4173 /* Check for special case tokens. */
4174 result = special_case_tokens (token);
4175 if (result >= 0)
4176 return result;
4177
4178 #if defined (ALIAS)
4179 /* Posix.2 does not allow reserved words to be aliased, so check for all
4180 of them, including special cases, before expanding the current token
4181 as an alias. */
4182 if (posixly_correct)
4183 CHECK_FOR_RESERVED_WORD (token);
4184
4185 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4186 inhibits alias expansion. */
4187 if (expand_aliases && quoted == 0)
4188 {
4189 result = alias_expand_token (token);
4190 if (result == RE_READ_TOKEN)
4191 return (RE_READ_TOKEN);
4192 else if (result == NO_EXPANSION)
4193 parser_state &= ~PST_ALEXPNEXT;
4194 }
4195
4196 /* If not in Posix.2 mode, check for reserved words after alias
4197 expansion. */
4198 if (posixly_correct == 0)
4199 #endif
4200 CHECK_FOR_RESERVED_WORD (token);
4201
4202 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4203 the_word->word = xmalloc (1 + token_index);
4204 the_word->flags = 0;
4205 strcpy (the_word->word, token);
4206 if (dollar_present)
4207 the_word->flags |= W_HASDOLLAR;
4208 if (quoted)
4209 the_word->flags |= W_QUOTED;
4210 /* A word is an assignment if it appears at the beginning of a
4211 simple command, or after another assignment word. This is
4212 context-dependent, so it cannot be handled in the grammar. */
4213 if (assignment (token))
4214 {
4215 the_word->flags |= W_ASSIGNMENT;
4216 /* Don't perform word splitting on assignment statements. */
4217 if (assignment_acceptable (last_read_token))
4218 the_word->flags |= W_NOSPLIT;
4219 }
4220
4221 yylval.word = the_word;
4222
4223 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4224 ? ASSIGNMENT_WORD : WORD;
4225
4226 if (last_read_token == FUNCTION)
4227 {
4228 parser_state |= PST_ALLOWOPNBRC;
4229 function_dstart = line_number;
4230 }
4231
4232 return (result);
4233 }
4234
4235 /* $'...' ANSI-C expand the portion of STRING between START and END and
4236 return the result. The result cannot be longer than the input string. */
4237 static char *
4238 ansiexpand (string, start, end, lenp)
4239 char *string;
4240 int start, end, *lenp;
4241 {
4242 char *temp, *t;
4243 int len, tlen;
4244
4245 temp = xmalloc (end - start + 1);
4246 for (tlen = 0, len = start; len < end; )
4247 temp[tlen++] = string[len++];
4248 temp[tlen] = '\0';
4249
4250 if (*temp)
4251 {
4252 t = ansicstr (temp, tlen, (int *)NULL, lenp);
4253 free (temp);
4254 return (t);
4255 }
4256 else
4257 {
4258 if (lenp)
4259 *lenp = 0;
4260 return (temp);
4261 }
4262 }
4263
4264 /* $"..." -- Translate the portion of STRING between START and END
4265 according to current locale using gettext (if available) and return
4266 the result. The caller will take care of leaving the quotes intact.
4267 The string will be left without the leading `$' by the caller.
4268 If translation is performed, the translated string will be double-quoted
4269 by the caller. The length of the translated string is returned in LENP,
4270 if non-null. */
4271 static char *
4272 localeexpand (string, start, end, lineno, lenp)
4273 char *string;
4274 int start, end, lineno, *lenp;
4275 {
4276 int len, tlen;
4277 char *temp, *t;
4278
4279 temp = xmalloc (end - start + 1);
4280 for (tlen = 0, len = start; len < end; )
4281 temp[tlen++] = string[len++];
4282 temp[tlen] = '\0';
4283
4284 /* If we're just dumping translatable strings, don't do anything. */
4285 if (dump_translatable_strings)
4286 {
4287 if (dump_po_strings)
4288 printf ("#: %s:%d\nmsgid \"%s\"\nmsgstr \"\"\n",
4289 (bash_input.name ? bash_input.name : "stdin"), lineno, temp);
4290 else
4291 printf ("\"%s\"\n", temp);
4292 if (lenp)
4293 *lenp = tlen;
4294 return (temp);
4295 }
4296 else if (*temp)
4297 {
4298 t = localetrans (temp, tlen, &len);
4299 free (temp);
4300 if (lenp)
4301 *lenp = len;
4302 return (t);
4303 }
4304 else
4305 {
4306 if (lenp)
4307 *lenp = 0;
4308 return (temp);
4309 }
4310 }
4311
4312 /* Return 1 if TOKEN is a token that after being read would allow
4313 a reserved word to be seen, else 0. */
4314 static int
4315 reserved_word_acceptable (token)
4316 int token;
4317 {
4318 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
4319 token == '|' || token == '&' || token == '{' ||
4320 token == '}' || /* XXX */
4321 token == AND_AND ||
4322 token == BANG ||
4323 token == TIME || token == TIMEOPT ||
4324 token == DO ||
4325 token == ELIF ||
4326 token == ELSE ||
4327 token == FI ||
4328 token == IF ||
4329 token == OR_OR ||
4330 token == SEMI_SEMI ||
4331 token == THEN ||
4332 token == UNTIL ||
4333 token == WHILE ||
4334 token == DONE || /* XXX these two are experimental */
4335 token == ESAC ||
4336 token == 0)
4337 return (1);
4338 else
4339 return (0);
4340 }
4341
4342 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4343 TOKEN is not a shell reserved word. */
4344 int
4345 find_reserved_word (token)
4346 char *token;
4347 {
4348 int i;
4349 for (i = 0; word_token_alist[i].word; i++)
4350 if (STREQ (token, word_token_alist[i].word))
4351 return i;
4352 return -1;
4353 }
4354
4355 #if 0
4356 #if defined (READLINE)
4357 /* Called after each time readline is called. This insures that whatever
4358 the new prompt string is gets propagated to readline's local prompt
4359 variable. */
4360 static void
4361 reset_readline_prompt ()
4362 {
4363 char *temp_prompt;
4364
4365 if (prompt_string_pointer)
4366 {
4367 temp_prompt = (*prompt_string_pointer)
4368 ? decode_prompt_string (*prompt_string_pointer)
4369 : (char *)NULL;
4370
4371 if (temp_prompt == 0)
4372 {
4373 temp_prompt = xmalloc (1);
4374 temp_prompt[0] = '\0';
4375 }
4376
4377 FREE (current_readline_prompt);
4378 current_readline_prompt = temp_prompt;
4379 }
4380 }
4381 #endif /* READLINE */
4382 #endif /* 0 */
4383
4384 #if defined (HISTORY)
4385 /* A list of tokens which can be followed by newlines, but not by
4386 semi-colons. When concatenating multiple lines of history, the
4387 newline separator for such tokens is replaced with a space. */
4388 static int no_semi_successors[] = {
4389 '\n', '{', '(', ')', ';', '&', '|',
4390 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
4391 0
4392 };
4393
4394 /* If we are not within a delimited expression, try to be smart
4395 about which separators can be semi-colons and which must be
4396 newlines. Returns the string that should be added into the
4397 history entry. */
4398 char *
4399 history_delimiting_chars ()
4400 {
4401 register int i;
4402
4403 if (dstack.delimiter_depth != 0)
4404 return ("\n");
4405
4406 /* First, handle some special cases. */
4407 /*(*/
4408 /* If we just read `()', assume it's a function definition, and don't
4409 add a semicolon. If the token before the `)' was not `(', and we're
4410 not in the midst of parsing a case statement, assume it's a
4411 parenthesized command and add the semicolon. */
4412 /*)(*/
4413 if (token_before_that == ')')
4414 {
4415 if (two_tokens_ago == '(') /*)*/ /* function def */
4416 return " ";
4417 /* This does not work for subshells inside case statement
4418 command lists. It's a suboptimal solution. */
4419 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4420 return " ";
4421 else
4422 return "; "; /* (...) subshell */
4423 }
4424 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4425 return " "; /* function def using `function name' without `()' */
4426
4427 for (i = 0; no_semi_successors[i]; i++)
4428 {
4429 if (token_before_that == no_semi_successors[i])
4430 return (" ");
4431 }
4432
4433 return ("; ");
4434 }
4435 #endif /* HISTORY */
4436
4437 /* Issue a prompt, or prepare to issue a prompt when the next character
4438 is read. */
4439 static void
4440 prompt_again ()
4441 {
4442 char *temp_prompt;
4443
4444 if (!interactive) /* XXX */
4445 return;
4446
4447 ps1_prompt = get_string_value ("PS1");
4448 ps2_prompt = get_string_value ("PS2");
4449
4450 if (!prompt_string_pointer)
4451 prompt_string_pointer = &ps1_prompt;
4452
4453 temp_prompt = *prompt_string_pointer
4454 ? decode_prompt_string (*prompt_string_pointer)
4455 : (char *)NULL;
4456
4457 if (temp_prompt == 0)
4458 {
4459 temp_prompt = xmalloc (1);
4460 temp_prompt[0] = '\0';
4461 }
4462
4463 current_prompt_string = *prompt_string_pointer;
4464 prompt_string_pointer = &ps2_prompt;
4465
4466 #if defined (READLINE)
4467 if (!no_line_editing)
4468 {
4469 FREE (current_readline_prompt);
4470 current_readline_prompt = temp_prompt;
4471 }
4472 else
4473 #endif /* READLINE */
4474 {
4475 FREE (current_decoded_prompt);
4476 current_decoded_prompt = temp_prompt;
4477 }
4478 }
4479
4480 static void
4481 print_prompt ()
4482 {
4483 fprintf (stderr, "%s", current_decoded_prompt);
4484 fflush (stderr);
4485 }
4486
4487 /* Return a string which will be printed as a prompt. The string
4488 may contain special characters which are decoded as follows:
4489
4490 \a bell (ascii 07)
4491 \e escape (ascii 033)
4492 \d the date in Day Mon Date format
4493 \h the hostname up to the first `.'
4494 \H the hostname
4495 \n CRLF
4496 \s the name of the shell
4497 \t the time in 24-hour hh:mm:ss format
4498 \T the time in 12-hour hh:mm:ss format
4499 \@ the time in 12-hour am/pm format
4500 \v the version of bash (e.g., 2.00)
4501 \V the release of bash, version + patchlevel (e.g., 2.00.0)
4502 \w the current working directory
4503 \W the last element of $PWD
4504 \u your username
4505 \# the command number of this command
4506 \! the history number of this command
4507 \$ a $ or a # if you are root
4508 \nnn character code nnn in octal
4509 \\ a backslash
4510 \[ begin a sequence of non-printing chars
4511 \] end a sequence of non-printing chars
4512 */
4513 #define PROMPT_GROWTH 48
4514 char *
4515 decode_prompt_string (string)
4516 char *string;
4517 {
4518 WORD_LIST *list;
4519 char *result, *t;
4520 struct dstack save_dstack;
4521 #if defined (PROMPT_STRING_DECODE)
4522 int result_size, result_index;
4523 int c, n;
4524 char *temp, octal_string[4];
4525 time_t the_time;
4526
4527 result = xmalloc (result_size = PROMPT_GROWTH);
4528 result[result_index = 0] = 0;
4529 temp = (char *)NULL;
4530
4531 while (c = *string++)
4532 {
4533 if (posixly_correct && c == '!')
4534 {
4535 if (*string == '!')
4536 {
4537 temp = savestring ("!");
4538 goto add_string;
4539 }
4540 else
4541 {
4542 #if !defined (HISTORY)
4543 temp = savestring ("1");
4544 #else /* HISTORY */
4545 temp = itos (history_number ());
4546 #endif /* HISTORY */
4547 string--; /* add_string increments string again. */
4548 goto add_string;
4549 }
4550 }
4551 if (c == '\\')
4552 {
4553 c = *string;
4554
4555 switch (c)
4556 {
4557 case '0':
4558 case '1':
4559 case '2':
4560 case '3':
4561 case '4':
4562 case '5':
4563 case '6':
4564 case '7':
4565 strncpy (octal_string, string, 3);
4566 octal_string[3] = '\0';
4567
4568 n = read_octal (octal_string);
4569 temp = xmalloc (3);
4570
4571 if (n == CTLESC || n == CTLNUL)
4572 {
4573 string += 3;
4574 temp[0] = CTLESC;
4575 temp[1] = n;
4576 temp[2] = '\0';
4577 }
4578 else if (n == -1)
4579 {
4580 temp[0] = '\\';
4581 temp[1] = '\0';
4582 }
4583 else
4584 {
4585 string += 3;
4586 temp[0] = n;
4587 temp[1] = '\0';
4588 }
4589
4590 c = 0;
4591 goto add_string;
4592
4593 case 't':
4594 case 'd':
4595 case 'T':
4596 case '@':
4597 /* Make the current time/date into a string. */
4598 the_time = time (0);
4599 temp = ctime (&the_time);
4600
4601 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4602 temp[(c != 'd') ? 8 : 10] = '\0';
4603
4604 /* quick and dirty conversion to 12-hour time */
4605 if (c == 'T' || c == '@')
4606 {
4607 if (c == '@')
4608 {
4609 temp[5] = 'a'; /* am/pm format */
4610 temp[6] = 'm';
4611 temp[7] = '\0';
4612 }
4613 c = temp[2];
4614 temp[2] = '\0';
4615 n = atoi (temp);
4616 temp[2] = c;
4617 n -= 12;
4618 if (n > 0)
4619 {
4620 temp[0] = (n / 10) + '0';
4621 temp[1] = (n % 10) + '0';
4622 }
4623 if (n >= 0 && temp[5] == 'a')
4624 temp[5] = 'p';
4625 }
4626 goto add_string;
4627
4628 case 'r':
4629 temp = xmalloc (2);
4630 temp[0] = '\r';
4631 temp[1] = '\0';
4632 goto add_string;
4633
4634 case 'n':
4635 temp = xmalloc (3);
4636 temp[0] = no_line_editing ? '\n' : '\r';
4637 temp[1] = no_line_editing ? '\0' : '\n';
4638 temp[2] = '\0';
4639 goto add_string;
4640
4641 case 's':
4642 temp = base_pathname (shell_name);
4643 temp = savestring (temp);
4644 goto add_string;
4645
4646 case 'v':
4647 case 'V':
4648 temp = xmalloc (8);
4649 if (c == 'v')
4650 strcpy (temp, dist_version);
4651 else
4652 sprintf (temp, "%s.%d", dist_version, patch_level);
4653 goto add_string;
4654
4655 case 'w':
4656 case 'W':
4657 {
4658 /* Use the value of PWD because it is much more efficient. */
4659 char t_string[PATH_MAX];
4660 int tlen;
4661
4662 temp = get_string_value ("PWD");
4663
4664 if (temp == 0)
4665 {
4666 if (getcwd (t_string, sizeof(t_string)) == 0)
4667 {
4668 t_string[0] = '.';
4669 tlen = 1;
4670 }
4671 else
4672 tlen = strlen (t_string);
4673 }
4674 else
4675 {
4676 tlen = sizeof (t_string) - 1;
4677 strncpy (t_string, temp, tlen);
4678 }
4679 t_string[tlen] = '\0';
4680
4681 if (c == 'W')
4682 {
4683 t = strrchr (t_string, '/');
4684 if (t && t != t_string)
4685 strcpy (t_string, t + 1);
4686 }
4687 else
4688 /* polite_directory_format is guaranteed to return a string
4689 no longer than PATH_MAX - 1 characters. */
4690 strcpy (t_string, polite_directory_format (t_string));
4691
4692 /* If we're going to be expanding the prompt string later,
4693 quote the directory name. */
4694 if (promptvars || posixly_correct)
4695 temp = backslash_quote (t_string);
4696 else
4697 temp = savestring (t_string);
4698
4699 goto add_string;
4700 }
4701
4702 case 'u':
4703 temp = savestring (current_user.user_name);
4704 goto add_string;
4705
4706 case 'h':
4707 case 'H':
4708 temp = savestring (current_host_name);
4709 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4710 *t = '\0';
4711 goto add_string;
4712
4713 case '#':
4714 temp = itos (current_command_number);
4715 goto add_string;
4716
4717 case '!':
4718 #if !defined (HISTORY)
4719 temp = savestring ("1");
4720 #else /* HISTORY */
4721 temp = itos (history_number ());
4722 #endif /* HISTORY */
4723 goto add_string;
4724
4725 case '$':
4726 t = temp = xmalloc (3);
4727 if ((promptvars || posixly_correct) && (current_user.euid != 0))
4728 *t++ = '\\';
4729 *t++ = current_user.euid == 0 ? '#' : '$';
4730 *t = '\0';
4731 goto add_string;
4732
4733 #if defined (READLINE)
4734 case '[':
4735 case ']':
4736 temp = xmalloc (3);
4737 temp[0] = '\001';
4738 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4739 temp[2] = '\0';
4740 goto add_string;
4741 #endif /* READLINE */
4742
4743 case '\\':
4744 temp = xmalloc (2);
4745 temp[0] = c;
4746 temp[1] = '\0';
4747 goto add_string;
4748
4749 case 'a':
4750 case 'e':
4751 temp = xmalloc (2);
4752 temp[0] = (c == 'a') ? '\07' : '\033';
4753 temp[1] = '\0';
4754 goto add_string;
4755
4756 default:
4757 temp = xmalloc (3);
4758 temp[0] = '\\';
4759 temp[1] = c;
4760 temp[2] = '\0';
4761
4762 add_string:
4763 if (c)
4764 string++;
4765 result =
4766 sub_append_string (temp, result, &result_index, &result_size);
4767 temp = (char *)NULL; /* Freed in sub_append_string (). */
4768 result[result_index] = '\0';
4769 break;
4770 }
4771 }
4772 else
4773 {
4774 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4775 result[result_index++] = c;
4776 result[result_index] = '\0';
4777 }
4778 }
4779 #else /* !PROMPT_STRING_DECODE */
4780 result = savestring (string);
4781 #endif /* !PROMPT_STRING_DECODE */
4782
4783 /* Save the delimiter stack and point `dstack' to temp space so any
4784 command substitutions in the prompt string won't result in screwing
4785 up the parser's quoting state. */
4786 save_dstack = dstack;
4787 dstack = temp_dstack;
4788 dstack.delimiter_depth = 0;
4789
4790 /* Perform variable and parameter expansion and command substitution on
4791 the prompt string. */
4792 if (promptvars || posixly_correct)
4793 {
4794 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
4795 free (result);
4796 result = string_list (list);
4797 dispose_words (list);
4798 }
4799 else
4800 {
4801 t = dequote_string (result);
4802 free (result);
4803 result = t;
4804 }
4805
4806 dstack = save_dstack;
4807
4808 return (result);
4809 }
4810
4811 /* Report a syntax error, and restart the parser. Call here for fatal
4812 errors. */
4813 int
4814 yyerror ()
4815 {
4816 report_syntax_error ((char *)NULL);
4817 reset_parser ();
4818 return (0);
4819 }
4820
4821 /* Report a syntax error with line numbers, etc.
4822 Call here for recoverable errors. If you have a message to print,
4823 then place it in MESSAGE, otherwise pass NULL and this will figure
4824 out an appropriate message for you. */
4825 static void
4826 report_syntax_error (message)
4827 char *message;
4828 {
4829 char *msg, *t;
4830 int token_end, i;
4831 char msg2[2];
4832
4833 if (message)
4834 {
4835 parser_error (line_number, "%s", message);
4836 if (interactive && EOF_Reached)
4837 EOF_Reached = 0;
4838 last_command_exit_value = EX_USAGE;
4839 return;
4840 }
4841
4842 /* If the line of input we're reading is not null, try to find the
4843 objectionable token. */
4844 if (shell_input_line && *shell_input_line)
4845 {
4846 t = shell_input_line;
4847 i = shell_input_line_index;
4848 token_end = 0;
4849
4850 if (i && t[i] == '\0')
4851 i--;
4852
4853 while (i && (whitespace (t[i]) || t[i] == '\n'))
4854 i--;
4855
4856 if (i)
4857 token_end = i + 1;
4858
4859 while (i && (member (t[i], " \n\t;|&") == 0))
4860 i--;
4861
4862 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4863 i++;
4864
4865 /* Print the offending token. */
4866 if (token_end || (i == 0 && token_end == 0))
4867 {
4868 if (token_end)
4869 {
4870 msg = xmalloc (1 + (token_end - i));
4871 strncpy (msg, t + i, token_end - i);
4872 msg[token_end - i] = '\0';
4873 }
4874 else /* one-character token */
4875 {
4876 msg2[0] = t[i];
4877 msg2[1] = '\0';
4878 msg = msg2;
4879 }
4880
4881 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4882
4883 if (msg != msg2)
4884 free (msg);
4885 }
4886
4887 /* If not interactive, print the line containing the error. */
4888 if (interactive == 0)
4889 {
4890 msg = savestring (shell_input_line);
4891 token_end = strlen (msg);
4892 while (token_end && msg[token_end - 1] == '\n')
4893 msg[--token_end] = '\0';
4894
4895 parser_error (line_number, "`%s'", msg);
4896 free (msg);
4897 }
4898 }
4899 else
4900 {
4901 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
4902 parser_error (line_number, "%s", msg);
4903 /* When the shell is interactive, this file uses EOF_Reached
4904 only for error reporting. Other mechanisms are used to
4905 decide whether or not to exit. */
4906 if (interactive && EOF_Reached)
4907 EOF_Reached = 0;
4908 }
4909 last_command_exit_value = EX_USAGE;
4910 }
4911
4912 /* ??? Needed function. ??? We have to be able to discard the constructs
4913 created during parsing. In the case of error, we want to return
4914 allocated objects to the memory pool. In the case of no error, we want
4915 to throw away the information about where the allocated objects live.
4916 (dispose_command () will actually free the command. */
4917 static void
4918 discard_parser_constructs (error_p)
4919 int error_p;
4920 {
4921 }
4922
4923 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4924
4925 /* A flag denoting whether or not ignoreeof is set. */
4926 int ignoreeof = 0;
4927
4928 /* The number of times that we have encountered an EOF character without
4929 another character intervening. When this gets above the limit, the
4930 shell terminates. */
4931 int eof_encountered = 0;
4932
4933 /* The limit for eof_encountered. */
4934 int eof_encountered_limit = 10;
4935
4936 /* If we have EOF as the only input unit, this user wants to leave
4937 the shell. If the shell is not interactive, then just leave.
4938 Otherwise, if ignoreeof is set, and we haven't done this the
4939 required number of times in a row, print a message. */
4940 static void
4941 handle_eof_input_unit ()
4942 {
4943 if (interactive)
4944 {
4945 /* shell.c may use this to decide whether or not to write out the
4946 history, among other things. We use it only for error reporting
4947 in this file. */
4948 if (EOF_Reached)
4949 EOF_Reached = 0;
4950
4951 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4952 if (ignoreeof)
4953 {
4954 if (eof_encountered < eof_encountered_limit)
4955 {
4956 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4957 login_shell ? "logout" : "exit");
4958 eof_encountered++;
4959 /* Reset the prompt string to be $PS1. */
4960 prompt_string_pointer = (char **)NULL;
4961 prompt_again ();
4962 last_read_token = current_token = '\n';
4963 return;
4964 }
4965 }
4966
4967 /* In this case EOF should exit the shell. Do it now. */
4968 reset_parser ();
4969 exit_builtin ((WORD_LIST *)NULL);
4970 }
4971 else
4972 {
4973 /* We don't write history files, etc., for non-interactive shells. */
4974 EOF_Reached = 1;
4975 }
4976 }