]> git.ipfire.org Git - thirdparty/bash.git/blob - y.tab.c
Imported from ../bash-2.02.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 ("()<>;&|", (c)) != 0)
2003 #define shellbreak(c) (strchr ("()<>;&| \t\n", (c)) != 0)
2004 #define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
2005 #define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
2006
2007 /* The token currently being read. */
2008 static int current_token;
2009
2010 /* The last read token, or NULL. read_token () uses this for context
2011 checking. */
2012 static int last_read_token;
2013
2014 /* The token read prior to last_read_token. */
2015 static int token_before_that;
2016
2017 /* The token read prior to token_before_that. */
2018 static int two_tokens_ago;
2019
2020 /* If non-zero, it is the token that we want read_token to return
2021 regardless of what text is (or isn't) present to be read. This
2022 is reset by read_token. If token_to_read == WORD or
2023 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
2024 static int token_to_read;
2025 static WORD_DESC *word_desc_to_read;
2026
2027 /* The current parser state. */
2028 static int parser_state;
2029
2030 /* Global var is non-zero when end of file has been reached. */
2031 int EOF_Reached = 0;
2032
2033 void
2034 debug_parser (i)
2035 int i;
2036 {
2037 #if YYDEBUG != 0
2038 yydebug = i;
2039 #endif
2040 }
2041
2042 /* yy_getc () returns the next available character from input or EOF.
2043 yy_ungetc (c) makes `c' the next character to read.
2044 init_yy_io (get, unget, type, location) makes the function GET the
2045 installed function for getting the next character, makes UNGET the
2046 installed function for un-getting a character, sets the type of stream
2047 (either string or file) from TYPE, and makes LOCATION point to where
2048 the input is coming from. */
2049
2050 /* Unconditionally returns end-of-file. */
2051 int
2052 return_EOF ()
2053 {
2054 return (EOF);
2055 }
2056
2057 /* Variable containing the current get and unget functions.
2058 See ./input.h for a clearer description. */
2059 BASH_INPUT bash_input;
2060
2061 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2062 is non-null, avoiding a memory leak. */
2063 void
2064 initialize_bash_input ()
2065 {
2066 bash_input.type = st_none;
2067 FREE (bash_input.name);
2068 bash_input.name = (char *)NULL;
2069 bash_input.location.file = (FILE *)NULL;
2070 bash_input.location.string = (char *)NULL;
2071 bash_input.getter = (Function *)NULL;
2072 bash_input.ungetter = (Function *)NULL;
2073 }
2074
2075 /* Set the contents of the current bash input stream from
2076 GET, UNGET, TYPE, NAME, and LOCATION. */
2077 void
2078 init_yy_io (get, unget, type, name, location)
2079 Function *get, *unget;
2080 enum stream_type type;
2081 char *name;
2082 INPUT_STREAM location;
2083 {
2084 bash_input.type = type;
2085 FREE (bash_input.name);
2086 bash_input.name = name ? savestring (name) : (char *)NULL;
2087
2088 /* XXX */
2089 #if defined (CRAY)
2090 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2091 #else
2092 bash_input.location = location;
2093 #endif
2094 bash_input.getter = get;
2095 bash_input.ungetter = unget;
2096 }
2097
2098 /* Call this to get the next character of input. */
2099 int
2100 yy_getc ()
2101 {
2102 return (*(bash_input.getter)) ();
2103 }
2104
2105 /* Call this to unget C. That is, to make C the next character
2106 to be read. */
2107 int
2108 yy_ungetc (c)
2109 int c;
2110 {
2111 return (*(bash_input.ungetter)) (c);
2112 }
2113
2114 #if defined (BUFFERED_INPUT)
2115 int
2116 input_file_descriptor ()
2117 {
2118 switch (bash_input.type)
2119 {
2120 case st_stream:
2121 return (fileno (bash_input.location.file));
2122 case st_bstream:
2123 return (bash_input.location.buffered_fd);
2124 case st_stdin:
2125 default:
2126 return (fileno (stdin));
2127 }
2128 }
2129 #endif /* BUFFERED_INPUT */
2130
2131 /* **************************************************************** */
2132 /* */
2133 /* Let input be read from readline (). */
2134 /* */
2135 /* **************************************************************** */
2136
2137 #if defined (READLINE)
2138 char *current_readline_prompt = (char *)NULL;
2139 char *current_readline_line = (char *)NULL;
2140 int current_readline_line_index = 0;
2141
2142 static int
2143 yy_readline_get ()
2144 {
2145 SigHandler *old_sigint;
2146 int line_len, c;
2147
2148 if (!current_readline_line)
2149 {
2150 if (!bash_readline_initialized)
2151 initialize_readline ();
2152
2153 #if defined (JOB_CONTROL)
2154 if (job_control)
2155 give_terminal_to (shell_pgrp);
2156 #endif /* JOB_CONTROL */
2157
2158 if (signal_is_ignored (SIGINT) == 0)
2159 {
2160 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2161 interrupt_immediately++;
2162 }
2163
2164 current_readline_line = readline (current_readline_prompt ?
2165 current_readline_prompt : "");
2166
2167 if (signal_is_ignored (SIGINT) == 0)
2168 {
2169 interrupt_immediately--;
2170 set_signal_handler (SIGINT, old_sigint);
2171 }
2172
2173 #if 0
2174 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2175 reset_readline_prompt ();
2176 #endif
2177
2178 if (current_readline_line == 0)
2179 return (EOF);
2180
2181 current_readline_line_index = 0;
2182 line_len = strlen (current_readline_line);
2183
2184 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
2185 current_readline_line[line_len++] = '\n';
2186 current_readline_line[line_len] = '\0';
2187 }
2188
2189 if (current_readline_line[current_readline_line_index] == 0)
2190 {
2191 free (current_readline_line);
2192 current_readline_line = (char *)NULL;
2193 return (yy_readline_get ());
2194 }
2195 else
2196 {
2197 c = (unsigned char)current_readline_line[current_readline_line_index++];
2198 return (c);
2199 }
2200 }
2201
2202 static int
2203 yy_readline_unget (c)
2204 int c;
2205 {
2206 if (current_readline_line_index && current_readline_line)
2207 current_readline_line[--current_readline_line_index] = c;
2208 return (c);
2209 }
2210
2211 void
2212 with_input_from_stdin ()
2213 {
2214 INPUT_STREAM location;
2215
2216 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2217 {
2218 location.string = current_readline_line;
2219 init_yy_io (yy_readline_get, yy_readline_unget,
2220 st_stdin, "readline stdin", location);
2221 }
2222 }
2223
2224 #else /* !READLINE */
2225
2226 void
2227 with_input_from_stdin ()
2228 {
2229 with_input_from_stream (stdin, "stdin");
2230 }
2231 #endif /* !READLINE */
2232
2233 /* **************************************************************** */
2234 /* */
2235 /* Let input come from STRING. STRING is zero terminated. */
2236 /* */
2237 /* **************************************************************** */
2238
2239 static int
2240 yy_string_get ()
2241 {
2242 register char *string;
2243 register int c;
2244
2245 string = bash_input.location.string;
2246 c = EOF;
2247
2248 /* If the string doesn't exist, or is empty, EOF found. */
2249 if (string && *string)
2250 {
2251 c = *(unsigned char *)string++;
2252 bash_input.location.string = string;
2253 }
2254 return (c);
2255 }
2256
2257 static int
2258 yy_string_unget (c)
2259 int c;
2260 {
2261 *(--bash_input.location.string) = c;
2262 return (c);
2263 }
2264
2265 void
2266 with_input_from_string (string, name)
2267 char *string, *name;
2268 {
2269 INPUT_STREAM location;
2270
2271 location.string = string;
2272 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2273 }
2274
2275 /* **************************************************************** */
2276 /* */
2277 /* Let input come from STREAM. */
2278 /* */
2279 /* **************************************************************** */
2280
2281 static int
2282 yy_stream_get ()
2283 {
2284 int result = EOF;
2285
2286 if (bash_input.location.file)
2287 {
2288 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2289 result = getc_with_restart (bash_input.location.file);
2290 #else /* HAVE_RESTARTABLE_SYSCALLS */
2291 result = getc (bash_input.location.file);
2292 result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
2293 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2294 }
2295 return (result);
2296 }
2297
2298 static int
2299 yy_stream_unget (c)
2300 int c;
2301 {
2302 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2303 return (ungetc_with_restart (c, bash_input.location.file));
2304 #else /* HAVE_RESTARTABLE_SYSCALLS */
2305 return (ungetc (c, bash_input.location.file));
2306 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2307 }
2308
2309 void
2310 with_input_from_stream (stream, name)
2311 FILE *stream;
2312 char *name;
2313 {
2314 INPUT_STREAM location;
2315
2316 location.file = stream;
2317 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2318 }
2319
2320 typedef struct stream_saver {
2321 struct stream_saver *next;
2322 BASH_INPUT bash_input;
2323 int line;
2324 #if defined (BUFFERED_INPUT)
2325 BUFFERED_STREAM *bstream;
2326 #endif /* BUFFERED_INPUT */
2327 } STREAM_SAVER;
2328
2329 /* The globally known line number. */
2330 int line_number = 0;
2331
2332 #if defined (COND_COMMAND)
2333 static int cond_lineno;
2334 static int cond_token;
2335 #endif
2336
2337 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2338
2339 void
2340 push_stream (reset_lineno)
2341 int reset_lineno;
2342 {
2343 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2344
2345 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2346
2347 #if defined (BUFFERED_INPUT)
2348 saver->bstream = (BUFFERED_STREAM *)NULL;
2349 /* If we have a buffered stream, clear out buffers[fd]. */
2350 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2351 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
2352 (BUFFERED_STREAM *)NULL);
2353 #endif /* BUFFERED_INPUT */
2354
2355 saver->line = line_number;
2356 bash_input.name = (char *)NULL;
2357 saver->next = stream_list;
2358 stream_list = saver;
2359 EOF_Reached = 0;
2360 if (reset_lineno)
2361 line_number = 0;
2362 }
2363
2364 void
2365 pop_stream ()
2366 {
2367 if (!stream_list)
2368 EOF_Reached = 1;
2369 else
2370 {
2371 STREAM_SAVER *saver = stream_list;
2372
2373 EOF_Reached = 0;
2374 stream_list = stream_list->next;
2375
2376 init_yy_io (saver->bash_input.getter,
2377 saver->bash_input.ungetter,
2378 saver->bash_input.type,
2379 saver->bash_input.name,
2380 saver->bash_input.location);
2381
2382 #if defined (BUFFERED_INPUT)
2383 /* If we have a buffered stream, restore buffers[fd]. */
2384 /* If the input file descriptor was changed while this was on the
2385 save stack, update the buffered fd to the new file descriptor and
2386 re-establish the buffer <-> bash_input fd correspondence. */
2387 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2388 {
2389 if (bash_input_fd_changed)
2390 {
2391 bash_input_fd_changed = 0;
2392 if (default_buffered_input >= 0)
2393 {
2394 bash_input.location.buffered_fd = default_buffered_input;
2395 saver->bstream->b_fd = default_buffered_input;
2396 }
2397 }
2398 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
2399 }
2400 #endif /* BUFFERED_INPUT */
2401
2402 line_number = saver->line;
2403
2404 FREE (saver->bash_input.name);
2405 free (saver);
2406 }
2407 }
2408
2409 /* Return 1 if a stream of type TYPE is saved on the stack. */
2410 int
2411 stream_on_stack (type)
2412 enum stream_type type;
2413 {
2414 register STREAM_SAVER *s;
2415
2416 for (s = stream_list; s; s = s->next)
2417 if (s->bash_input.type == type)
2418 return 1;
2419 return 0;
2420 }
2421
2422 /*
2423 * This is used to inhibit alias expansion and reserved word recognition
2424 * inside case statement pattern lists. A `case statement pattern list' is:
2425 *
2426 * everything between the `in' in a `case word in' and the next ')'
2427 * or `esac'
2428 * everything between a `;;' and the next `)' or `esac'
2429 */
2430
2431 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2432
2433 #if !defined (ALIAS)
2434 typedef void *alias_t;
2435 #endif
2436
2437 #define END_OF_ALIAS 0
2438
2439 /*
2440 * Pseudo-global variables used in implementing token-wise alias expansion.
2441 */
2442
2443 /*
2444 * Pushing and popping strings. This works together with shell_getc to
2445 * implement alias expansion on a per-token basis.
2446 */
2447
2448 typedef struct string_saver {
2449 struct string_saver *next;
2450 int expand_alias; /* Value to set expand_alias to when string is popped. */
2451 char *saved_line;
2452 #if defined (ALIAS)
2453 alias_t *expander; /* alias that caused this line to be pushed. */
2454 #endif
2455 int saved_line_size, saved_line_index, saved_line_terminator;
2456 } STRING_SAVER;
2457
2458 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2459
2460 /*
2461 * Push the current shell_input_line onto a stack of such lines and make S
2462 * the current input. Used when expanding aliases. EXPAND is used to set
2463 * the value of expand_next_token when the string is popped, so that the
2464 * word after the alias in the original line is handled correctly when the
2465 * alias expands to multiple words. TOKEN is the token that was expanded
2466 * into S; it is saved and used to prevent infinite recursive expansion.
2467 */
2468 static void
2469 push_string (s, expand, ap)
2470 char *s;
2471 int expand;
2472 alias_t *ap;
2473 {
2474 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2475
2476 temp->expand_alias = expand;
2477 temp->saved_line = shell_input_line;
2478 temp->saved_line_size = shell_input_line_size;
2479 temp->saved_line_index = shell_input_line_index;
2480 temp->saved_line_terminator = shell_input_line_terminator;
2481 #if defined (ALIAS)
2482 temp->expander = ap;
2483 #endif
2484 temp->next = pushed_string_list;
2485 pushed_string_list = temp;
2486
2487 #if defined (ALIAS)
2488 if (ap)
2489 ap->flags |= AL_BEINGEXPANDED;
2490 #endif
2491
2492 shell_input_line = s;
2493 shell_input_line_size = strlen (s);
2494 shell_input_line_index = 0;
2495 shell_input_line_terminator = '\0';
2496 parser_state &= ~PST_ALEXPNEXT;
2497 }
2498
2499 /*
2500 * Make the top of the pushed_string stack be the current shell input.
2501 * Only called when there is something on the stack. Called from shell_getc
2502 * when it thinks it has consumed the string generated by an alias expansion
2503 * and needs to return to the original input line.
2504 */
2505 static void
2506 pop_string ()
2507 {
2508 STRING_SAVER *t;
2509
2510 FREE (shell_input_line);
2511 shell_input_line = pushed_string_list->saved_line;
2512 shell_input_line_index = pushed_string_list->saved_line_index;
2513 shell_input_line_size = pushed_string_list->saved_line_size;
2514 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2515
2516 if (pushed_string_list->expand_alias)
2517 parser_state |= PST_ALEXPNEXT;
2518 else
2519 parser_state &= ~PST_ALEXPNEXT;
2520
2521 t = pushed_string_list;
2522 pushed_string_list = pushed_string_list->next;
2523
2524 #if defined (ALIAS)
2525 if (t->expander)
2526 t->expander->flags &= ~AL_BEINGEXPANDED;
2527 #endif
2528
2529 free ((char *)t);
2530 }
2531
2532 static void
2533 free_string_list ()
2534 {
2535 register STRING_SAVER *t, *t1;
2536
2537 for (t = pushed_string_list; t; )
2538 {
2539 t1 = t->next;
2540 FREE (t->saved_line);
2541 #if defined (ALIAS)
2542 if (t->expander)
2543 t->expander->flags &= ~AL_BEINGEXPANDED;
2544 #endif
2545 free ((char *)t);
2546 t = t1;
2547 }
2548 pushed_string_list = (STRING_SAVER *)NULL;
2549 }
2550
2551 #endif /* ALIAS || DPAREN_ARITHMETIC */
2552
2553 /* Return a line of text, taken from wherever yylex () reads input.
2554 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2555 is non-zero, we remove unquoted \<newline> pairs. This is used by
2556 read_secondary_line to read here documents. */
2557 static char *
2558 read_a_line (remove_quoted_newline)
2559 int remove_quoted_newline;
2560 {
2561 static char *line_buffer = (char *)NULL;
2562 static int buffer_size = 0;
2563 int indx = 0, c, peekc, pass_next;
2564
2565 #if defined (READLINE)
2566 if (interactive && bash_input.type != st_string && no_line_editing)
2567 #else
2568 if (interactive && bash_input.type != st_string)
2569 #endif
2570 print_prompt ();
2571
2572 pass_next = 0;
2573 while (1)
2574 {
2575 c = yy_getc ();
2576
2577 /* Allow immediate exit if interrupted during input. */
2578 QUIT;
2579
2580 if (c == 0)
2581 continue;
2582
2583 /* If there is no more input, then we return NULL. */
2584 if (c == EOF)
2585 {
2586 if (interactive && bash_input.type == st_stream)
2587 clearerr (stdin);
2588 if (indx == 0)
2589 return ((char *)NULL);
2590 c = '\n';
2591 }
2592
2593 /* `+2' in case the final character in the buffer is a newline. */
2594 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2595
2596 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2597 here document with an unquoted delimiter. In this case,
2598 the line will be expanded as if it were in double quotes.
2599 We allow a backslash to escape the next character, but we
2600 need to treat the backslash specially only if a backslash
2601 quoting a backslash-newline pair appears in the line. */
2602 if (pass_next)
2603 {
2604 line_buffer[indx++] = c;
2605 pass_next = 0;
2606 }
2607 else if (c == '\\' && remove_quoted_newline)
2608 {
2609 peekc = yy_getc ();
2610 if (peekc == '\n')
2611 continue; /* Make the unquoted \<newline> pair disappear. */
2612 else
2613 {
2614 yy_ungetc (peekc);
2615 pass_next = 1;
2616 line_buffer[indx++] = c; /* Preserve the backslash. */
2617 }
2618 }
2619 else
2620 line_buffer[indx++] = c;
2621
2622 if (c == '\n')
2623 {
2624 line_buffer[indx] = '\0';
2625 return (line_buffer);
2626 }
2627 }
2628 }
2629
2630 /* Return a line as in read_a_line (), but insure that the prompt is
2631 the secondary prompt. This is used to read the lines of a here
2632 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2633 newlines quoted with backslashes while reading the line. It is
2634 non-zero unless the delimiter of the here document was quoted. */
2635 char *
2636 read_secondary_line (remove_quoted_newline)
2637 int remove_quoted_newline;
2638 {
2639 prompt_string_pointer = &ps2_prompt;
2640 prompt_again ();
2641 return (read_a_line (remove_quoted_newline));
2642 }
2643
2644 /* **************************************************************** */
2645 /* */
2646 /* YYLEX () */
2647 /* */
2648 /* **************************************************************** */
2649
2650 /* Reserved words. These are only recognized as the first word of a
2651 command. */
2652 STRING_INT_ALIST word_token_alist[] = {
2653 { "if", IF },
2654 { "then", THEN },
2655 { "else", ELSE },
2656 { "elif", ELIF },
2657 { "fi", FI },
2658 { "case", CASE },
2659 { "esac", ESAC },
2660 { "for", FOR },
2661 #if defined (SELECT_COMMAND)
2662 { "select", SELECT },
2663 #endif
2664 { "while", WHILE },
2665 { "until", UNTIL },
2666 { "do", DO },
2667 { "done", DONE },
2668 { "in", IN },
2669 { "function", FUNCTION },
2670 #if defined (COMMAND_TIMING)
2671 { "time", TIME },
2672 #endif
2673 { "{", '{' },
2674 { "}", '}' },
2675 { "!", BANG },
2676 #if defined (COND_COMMAND)
2677 { "[[", COND_START },
2678 { "]]", COND_END },
2679 #endif
2680 { (char *)NULL, 0}
2681 };
2682
2683 /* These are used by read_token_word, but appear up here so that shell_getc
2684 can use them to decide when to add otherwise blank lines to the history. */
2685
2686 /* The primary delimiter stack. */
2687 struct dstack dstack = { (char *)NULL, 0, 0 };
2688
2689 /* A temporary delimiter stack to be used when decoding prompt strings.
2690 This is needed because command substitutions in prompt strings (e.g., PS2)
2691 can screw up the parser's quoting state. */
2692 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2693
2694 /* Macro for accessing the top delimiter on the stack. Returns the
2695 delimiter or zero if none. */
2696 #define current_delimiter(ds) \
2697 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2698
2699 #define push_delimiter(ds, character) \
2700 do \
2701 { \
2702 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2703 ds.delimiters = xrealloc \
2704 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2705 ds.delimiters[ds.delimiter_depth] = character; \
2706 ds.delimiter_depth++; \
2707 } \
2708 while (0)
2709
2710 #define pop_delimiter(ds) ds.delimiter_depth--
2711
2712 /* Return the next shell input character. This always reads characters
2713 from shell_input_line; when that line is exhausted, it is time to
2714 read the next line. This is called by read_token when the shell is
2715 processing normal command input. */
2716
2717 static int
2718 shell_getc (remove_quoted_newline)
2719 int remove_quoted_newline;
2720 {
2721 register int i;
2722 int c;
2723 static int mustpop = 0;
2724
2725 QUIT;
2726
2727 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2728 /* If shell_input_line[shell_input_line_index] == 0, but there is
2729 something on the pushed list of strings, then we don't want to go
2730 off and get another line. We let the code down below handle it. */
2731
2732 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2733 (pushed_string_list == (STRING_SAVER *)NULL)))
2734 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2735 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2736 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2737 {
2738 line_number++;
2739
2740 restart_read:
2741
2742 /* Allow immediate exit if interrupted during input. */
2743 QUIT;
2744
2745 i = 0;
2746 shell_input_line_terminator = 0;
2747
2748 #if defined (JOB_CONTROL)
2749 /* This can cause a problem when reading a command as the result
2750 of a trap, when the trap is called from flush_child. This call
2751 had better not cause jobs to disappear from the job table in
2752 that case, or we will have big trouble. */
2753 notify_and_cleanup ();
2754 #else /* !JOB_CONTROL */
2755 cleanup_dead_jobs ();
2756 #endif /* !JOB_CONTROL */
2757
2758 #if defined (READLINE)
2759 if (interactive && bash_input.type != st_string && no_line_editing)
2760 #else
2761 if (interactive && bash_input.type != st_string)
2762 #endif
2763 print_prompt ();
2764
2765 if (bash_input.type == st_stream)
2766 clearerr (stdin);
2767
2768 while (c = yy_getc ())
2769 {
2770 /* Allow immediate exit if interrupted during input. */
2771 QUIT;
2772
2773 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2774
2775 if (c == EOF)
2776 {
2777 if (bash_input.type == st_stream)
2778 clearerr (stdin);
2779
2780 if (i == 0)
2781 shell_input_line_terminator = EOF;
2782
2783 shell_input_line[i] = '\0';
2784 break;
2785 }
2786
2787 shell_input_line[i++] = c;
2788
2789 if (c == '\n')
2790 {
2791 shell_input_line[--i] = '\0';
2792 current_command_line_count++;
2793 break;
2794 }
2795 }
2796 shell_input_line_index = 0;
2797 shell_input_line_len = i; /* == strlen (shell_input_line) */
2798
2799 #if defined (HISTORY)
2800 if (remember_on_history && shell_input_line && shell_input_line[0])
2801 {
2802 char *expansions;
2803 # if defined (BANG_HISTORY)
2804 int old_hist;
2805
2806 /* If the current delimiter is a single quote, we should not be
2807 performing history expansion, even if we're on a different
2808 line from the original single quote. */
2809 old_hist = history_expansion_inhibited;
2810 if (current_delimiter (dstack) == '\'')
2811 history_expansion_inhibited = 1;
2812 # endif
2813 expansions = pre_process_line (shell_input_line, 1, 1);
2814 # if defined (BANG_HISTORY)
2815 history_expansion_inhibited = old_hist;
2816 # endif
2817 if (expansions != shell_input_line)
2818 {
2819 free (shell_input_line);
2820 shell_input_line = expansions;
2821 shell_input_line_len = shell_input_line ?
2822 strlen (shell_input_line) : 0;
2823 if (!shell_input_line_len)
2824 current_command_line_count--;
2825
2826 /* We have to force the xrealloc below because we don't know
2827 the true allocated size of shell_input_line anymore. */
2828 shell_input_line_size = shell_input_line_len;
2829 }
2830 }
2831 /* XXX - this is grotesque */
2832 else if (remember_on_history && shell_input_line &&
2833 shell_input_line[0] == '\0' &&
2834 current_command_line_count > 1 && current_delimiter (dstack))
2835 {
2836 /* We know shell_input_line[0] == 0 and we're reading some sort of
2837 quoted string. This means we've got a line consisting of only
2838 a newline in a quoted string. We want to make sure this line
2839 gets added to the history. */
2840 maybe_add_history (shell_input_line);
2841 }
2842
2843 #endif /* HISTORY */
2844
2845 if (shell_input_line)
2846 {
2847 /* Lines that signify the end of the shell's input should not be
2848 echoed. */
2849 if (echo_input_at_read && (shell_input_line[0] ||
2850 shell_input_line_terminator != EOF))
2851 fprintf (stderr, "%s\n", shell_input_line);
2852 }
2853 else
2854 {
2855 shell_input_line_size = 0;
2856 prompt_string_pointer = &current_prompt_string;
2857 prompt_again ();
2858 goto restart_read;
2859 }
2860
2861 /* Add the newline to the end of this string, iff the string does
2862 not already end in an EOF character. */
2863 if (shell_input_line_terminator != EOF)
2864 {
2865 if (shell_input_line_len + 3 > shell_input_line_size)
2866 shell_input_line = xrealloc (shell_input_line,
2867 1 + (shell_input_line_size += 2));
2868
2869 shell_input_line[shell_input_line_len] = '\n';
2870 shell_input_line[shell_input_line_len + 1] = '\0';
2871 }
2872 }
2873
2874 c = shell_input_line[shell_input_line_index];
2875
2876 if (c)
2877 shell_input_line_index++;
2878
2879 if (c == '\\' && remove_quoted_newline &&
2880 shell_input_line[shell_input_line_index] == '\n')
2881 {
2882 prompt_again ();
2883 line_number++;
2884 goto restart_read;
2885 }
2886
2887 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2888 /* If C is NULL, we have reached the end of the current input string. If
2889 pushed_string_list is non-empty, it's time to pop to the previous string
2890 because we have fully consumed the result of the last alias expansion.
2891 Do it transparently; just return the next character of the string popped
2892 to. */
2893 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2894 {
2895 if (mustpop)
2896 {
2897 pop_string ();
2898 c = shell_input_line[shell_input_line_index];
2899 if (c)
2900 shell_input_line_index++;
2901 mustpop--;
2902 }
2903 else
2904 {
2905 mustpop++;
2906 c = ' ';
2907 }
2908 }
2909 #endif /* ALIAS || DPAREN_ARITHMETIC */
2910
2911 if (!c && shell_input_line_terminator == EOF)
2912 return ((shell_input_line_index != 0) ? '\n' : EOF);
2913
2914 return ((unsigned char)c);
2915 }
2916
2917 /* Put C back into the input for the shell. */
2918 static void
2919 shell_ungetc (c)
2920 int c;
2921 {
2922 if (shell_input_line && shell_input_line_index)
2923 shell_input_line[--shell_input_line_index] = c;
2924 }
2925
2926 static void
2927 shell_ungetchar ()
2928 {
2929 if (shell_input_line && shell_input_line_index)
2930 shell_input_line_index--;
2931 }
2932
2933 /* Discard input until CHARACTER is seen, then push that character back
2934 onto the input stream. */
2935 static void
2936 discard_until (character)
2937 int character;
2938 {
2939 int c;
2940
2941 while ((c = shell_getc (0)) != EOF && c != character)
2942 ;
2943
2944 if (c != EOF)
2945 shell_ungetc (c);
2946 }
2947
2948 void
2949 execute_prompt_command (command)
2950 char *command;
2951 {
2952 Function *temp_last, *temp_this;
2953 char *last_lastarg;
2954 int temp_exit_value, temp_eof_encountered;
2955
2956 temp_last = last_shell_builtin;
2957 temp_this = this_shell_builtin;
2958 temp_exit_value = last_command_exit_value;
2959 temp_eof_encountered = eof_encountered;
2960 last_lastarg = get_string_value ("_");
2961 if (last_lastarg)
2962 last_lastarg = savestring (last_lastarg);
2963
2964 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
2965
2966 last_shell_builtin = temp_last;
2967 this_shell_builtin = temp_this;
2968 last_command_exit_value = temp_exit_value;
2969 eof_encountered = temp_eof_encountered;
2970
2971 bind_variable ("_", last_lastarg);
2972 FREE (last_lastarg);
2973
2974 if (token_to_read == '\n') /* reset_parser was called */
2975 token_to_read = 0;
2976 }
2977
2978 /* Place to remember the token. We try to keep the buffer
2979 at a reasonable size, but it can grow. */
2980 static char *token = (char *)NULL;
2981
2982 /* Current size of the token buffer. */
2983 static int token_buffer_size;
2984
2985 /* Command to read_token () explaining what we want it to do. */
2986 #define READ 0
2987 #define RESET 1
2988 #define prompt_is_ps1 \
2989 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2990
2991 /* Function for yyparse to call. yylex keeps track of
2992 the last two tokens read, and calls read_token. */
2993 static int
2994 yylex ()
2995 {
2996 if (interactive && (current_token == 0 || current_token == '\n'))
2997 {
2998 /* Before we print a prompt, we might have to check mailboxes.
2999 We do this only if it is time to do so. Notice that only here
3000 is the mail alarm reset; nothing takes place in check_mail ()
3001 except the checking of mail. Please don't change this. */
3002 if (prompt_is_ps1 && time_to_check_mail ())
3003 {
3004 check_mail ();
3005 reset_mail_timer ();
3006 }
3007
3008 /* Avoid printing a prompt if we're not going to read anything, e.g.
3009 after resetting the parser with read_token (RESET). */
3010 if (token_to_read == 0 && interactive)
3011 prompt_again ();
3012 }
3013
3014 two_tokens_ago = token_before_that;
3015 token_before_that = last_read_token;
3016 last_read_token = current_token;
3017 current_token = read_token (READ);
3018 return (current_token);
3019 }
3020
3021 /* When non-zero, we have read the required tokens
3022 which allow ESAC to be the next one read. */
3023 static int esacs_needed_count;
3024
3025 void
3026 gather_here_documents ()
3027 {
3028 int r = 0;
3029 while (need_here_doc)
3030 {
3031 make_here_document (redir_stack[r++]);
3032 need_here_doc--;
3033 }
3034 }
3035
3036 /* When non-zero, an open-brace used to create a group is awaiting a close
3037 brace partner. */
3038 static int open_brace_count;
3039
3040 #define command_token_position(token) \
3041 (((token) == ASSIGNMENT_WORD) || \
3042 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
3043
3044 #define assignment_acceptable(token) command_token_position(token) && \
3045 ((parser_state & PST_CASEPAT) == 0)
3046
3047 /* Check to see if TOKEN is a reserved word and return the token
3048 value if it is. */
3049 #define CHECK_FOR_RESERVED_WORD(tok) \
3050 do { \
3051 if (!dollar_present && !quoted && \
3052 reserved_word_acceptable (last_read_token)) \
3053 { \
3054 int i; \
3055 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
3056 if (STREQ (tok, word_token_alist[i].word)) \
3057 { \
3058 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
3059 break; \
3060 if (word_token_alist[i].token == TIME) \
3061 break; \
3062 if (word_token_alist[i].token == ESAC) \
3063 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
3064 else if (word_token_alist[i].token == CASE) \
3065 parser_state |= PST_CASESTMT; \
3066 else if (word_token_alist[i].token == COND_END) \
3067 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
3068 else if (word_token_alist[i].token == COND_START) \
3069 parser_state |= PST_CONDCMD; \
3070 else if (word_token_alist[i].token == '{') \
3071 open_brace_count++; \
3072 else if (word_token_alist[i].token == '}' && open_brace_count) \
3073 open_brace_count--; \
3074 return (word_token_alist[i].token); \
3075 } \
3076 } \
3077 } while (0)
3078
3079 #if defined (ALIAS)
3080
3081 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3082 it's eligible.
3083
3084 It is eligible for expansion if the shell is in interactive mode, and
3085 the token is unquoted and the last token read was a command
3086 separator (or expand_next_token is set), and we are currently
3087 processing an alias (pushed_string_list is non-empty) and this
3088 token is not the same as the current or any previously
3089 processed alias.
3090
3091 Special cases that disqualify:
3092 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3093 static int
3094 alias_expand_token (token)
3095 char *token;
3096 {
3097 char *expanded;
3098 alias_t *ap;
3099
3100 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3101 (parser_state & PST_CASEPAT) == 0)
3102 {
3103 ap = find_alias (token);
3104
3105 /* Currently expanding this token. */
3106 if (ap && (ap->flags & AL_BEINGEXPANDED))
3107 return (NO_EXPANSION);
3108
3109 expanded = ap ? savestring (ap->value) : (char *)NULL;
3110 if (expanded)
3111 {
3112 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3113 return (RE_READ_TOKEN);
3114 }
3115 else
3116 /* This is an eligible token that does not have an expansion. */
3117 return (NO_EXPANSION);
3118 }
3119 return (NO_EXPANSION);
3120 }
3121 #endif /* ALIAS */
3122
3123 static int
3124 time_command_acceptable ()
3125 {
3126 #if defined (COMMAND_TIMING)
3127 switch (last_read_token)
3128 {
3129 case 0:
3130 case ';':
3131 case '\n':
3132 case AND_AND:
3133 case OR_OR:
3134 case '&':
3135 return 1;
3136 default:
3137 return 0;
3138 }
3139 #else
3140 return 0;
3141 #endif /* COMMAND_TIMING */
3142 }
3143
3144 /* Handle special cases of token recognition:
3145 IN is recognized if the last token was WORD and the token
3146 before that was FOR or CASE or SELECT.
3147
3148 DO is recognized if the last token was WORD and the token
3149 before that was FOR or SELECT.
3150
3151 ESAC is recognized if the last token caused `esacs_needed_count'
3152 to be set
3153
3154 `{' is recognized if the last token as WORD and the token
3155 before that was FUNCTION.
3156
3157 `}' is recognized if there is an unclosed `{' prsent.
3158
3159 `-p' is returned as TIMEOPT if the last read token was TIME.
3160
3161 ']]' is returned as COND_END if the parser is currently parsing
3162 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
3163
3164 `time' is returned as TIME if and only if it is immediately
3165 preceded by one of `;', `\n', `||', `&&', or `&'.
3166 */
3167
3168 static int
3169 special_case_tokens (token)
3170 char *token;
3171 {
3172 if ((last_read_token == WORD) &&
3173 #if defined (SELECT_COMMAND)
3174 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3175 #else
3176 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3177 #endif
3178 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3179 {
3180 if (token_before_that == CASE)
3181 {
3182 parser_state |= PST_CASEPAT;
3183 esacs_needed_count++;
3184 }
3185 return (IN);
3186 }
3187
3188 if (last_read_token == WORD &&
3189 #if defined (SELECT_COMMAND)
3190 (token_before_that == FOR || token_before_that == SELECT) &&
3191 #else
3192 (token_before_that == FOR) &&
3193 #endif
3194 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3195 return (DO);
3196
3197 /* Ditto for ESAC in the CASE case.
3198 Specifically, this handles "case word in esac", which is a legal
3199 construct, certainly because someone will pass an empty arg to the
3200 case construct, and we don't want it to barf. Of course, we should
3201 insist that the case construct has at least one pattern in it, but
3202 the designers disagree. */
3203 if (esacs_needed_count)
3204 {
3205 esacs_needed_count--;
3206 if (STREQ (token, "esac"))
3207 {
3208 parser_state &= ~PST_CASEPAT;
3209 return (ESAC);
3210 }
3211 }
3212
3213 /* The start of a shell function definition. */
3214 if (parser_state & PST_ALLOWOPNBRC)
3215 {
3216 parser_state &= ~PST_ALLOWOPNBRC;
3217 if (token[0] == '{' && token[1] == '\0') /* } */
3218 {
3219 open_brace_count++;
3220 function_bstart = line_number;
3221 return ('{'); /* } */
3222 }
3223 }
3224
3225 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3226 {
3227 open_brace_count--; /* { */
3228 return ('}');
3229 }
3230
3231 #if defined (COMMAND_TIMING)
3232 /* Handle -p after `time'. */
3233 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3234 return (TIMEOPT);
3235 #endif
3236
3237 #if defined (COMMAND_TIMING)
3238 if (STREQ (token, "time") && time_command_acceptable ())
3239 return (TIME);
3240 #endif /* COMMAND_TIMING */
3241
3242 #if defined (COND_COMMAND) /* [[ */
3243 if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
3244 return (COND_END);
3245 #endif
3246
3247 return (-1);
3248 }
3249
3250 /* Called from shell.c when Control-C is typed at top level. Or
3251 by the error rule at top level. */
3252 void
3253 reset_parser ()
3254 {
3255 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3256 open_brace_count = 0;
3257
3258 parser_state = 0;
3259
3260 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3261 if (pushed_string_list)
3262 free_string_list ();
3263 #endif /* ALIAS || DPAREN_ARITHMETIC */
3264
3265 if (shell_input_line)
3266 {
3267 free (shell_input_line);
3268 shell_input_line = (char *)NULL;
3269 shell_input_line_size = shell_input_line_index = 0;
3270 }
3271
3272 FREE (word_desc_to_read);
3273 word_desc_to_read = (WORD_DESC *)NULL;
3274
3275 last_read_token = '\n';
3276 token_to_read = '\n';
3277 }
3278
3279 /* Read the next token. Command can be READ (normal operation) or
3280 RESET (to normalize state). */
3281 static int
3282 read_token (command)
3283 int command;
3284 {
3285 int character; /* Current character. */
3286 int peek_char; /* Temporary look-ahead character. */
3287 int result; /* The thing to return. */
3288
3289 if (command == RESET)
3290 {
3291 reset_parser ();
3292 return ('\n');
3293 }
3294
3295 if (token_to_read)
3296 {
3297 result = token_to_read;
3298 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3299 {
3300 yylval.word = word_desc_to_read;
3301 word_desc_to_read = (WORD_DESC *)NULL;
3302 }
3303 token_to_read = 0;
3304 return (result);
3305 }
3306
3307 #if defined (COND_COMMAND)
3308 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3309 {
3310 cond_lineno = line_number;
3311 parser_state |= PST_CONDEXPR;
3312 yylval.command = parse_cond_command ();
3313 if (cond_token != COND_END)
3314 {
3315 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
3316 parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
3317 else if (cond_token != COND_ERROR)
3318 parser_error (cond_lineno, "syntax error in conditional expression");
3319 return (-1);
3320 }
3321 token_to_read = COND_END;
3322 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3323 return (COND_CMD);
3324 }
3325 #endif
3326
3327 #if defined (ALIAS)
3328 /* This is a place to jump back to once we have successfully expanded a
3329 token with an alias and pushed the string with push_string () */
3330 re_read_token:
3331 #endif /* ALIAS */
3332
3333 /* Read a single word from input. Start by skipping blanks. */
3334 while ((character = shell_getc (1)) != EOF && whitespace (character))
3335 ;
3336
3337 if (character == EOF)
3338 {
3339 EOF_Reached = 1;
3340 return (yacc_EOF);
3341 }
3342
3343 if (character == '#' && (!interactive || interactive_comments))
3344 {
3345 /* A comment. Discard until EOL or EOF, and then return a newline. */
3346 discard_until ('\n');
3347 shell_getc (0);
3348 character = '\n'; /* this will take the next if statement and return. */
3349 }
3350
3351 if (character == '\n')
3352 {
3353 /* If we're about to return an unquoted newline, we can go and collect
3354 the text of any pending here document. */
3355 if (need_here_doc)
3356 gather_here_documents ();
3357
3358 #if defined (ALIAS)
3359 parser_state &= ~PST_ALEXPNEXT;
3360 #endif /* ALIAS */
3361
3362 return (character);
3363 }
3364
3365 /* Shell meta-characters. */
3366 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3367 {
3368 #if defined (ALIAS)
3369 /* Turn off alias tokenization iff this character sequence would
3370 not leave us ready to read a command. */
3371 if (character == '<' || character == '>')
3372 parser_state &= ~PST_ALEXPNEXT;
3373 #endif /* ALIAS */
3374
3375 peek_char = shell_getc (1);
3376 if (character == peek_char)
3377 {
3378 switch (character)
3379 {
3380 case '<':
3381 /* If '<' then we could be at "<<" or at "<<-". We have to
3382 look ahead one more character. */
3383 peek_char = shell_getc (1);
3384 if (peek_char == '-')
3385 return (LESS_LESS_MINUS);
3386 else
3387 {
3388 shell_ungetc (peek_char);
3389 return (LESS_LESS);
3390 }
3391
3392 case '>':
3393 return (GREATER_GREATER);
3394
3395 case ';':
3396 parser_state |= PST_CASEPAT;
3397 #if defined (ALIAS)
3398 parser_state &= ~PST_ALEXPNEXT;
3399 #endif /* ALIAS */
3400 return (SEMI_SEMI);
3401
3402 case '&':
3403 return (AND_AND);
3404
3405 case '|':
3406 return (OR_OR);
3407
3408 #if defined (DPAREN_ARITHMETIC)
3409 case '(': /* ) */
3410 if (reserved_word_acceptable (last_read_token))
3411 {
3412 int cmdtyp, sline;
3413 char *wval;
3414 WORD_DESC *wd;
3415
3416 sline = line_number;
3417 cmdtyp = parse_arith_cmd (&wval);
3418 if (cmdtyp == 1) /* arithmetic command */
3419 {
3420 wd = make_word (wval);
3421 wd->flags = W_QUOTED;
3422 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3423 free (wval); /* make_word copies it */
3424 return (ARITH_CMD);
3425 }
3426 else if (cmdtyp == 0) /* nested subshell */
3427 {
3428 push_string (wval, 0, (alias_t *)NULL);
3429 if ((parser_state & PST_CASEPAT) == 0)
3430 parser_state |= PST_SUBSHELL;
3431 return (character);
3432 }
3433 else /* ERROR */
3434 return -1;
3435 }
3436 break;
3437 #endif
3438 }
3439 }
3440 else if (character == '<' && peek_char == '&')
3441 return (LESS_AND);
3442 else if (character == '>' && peek_char == '&')
3443 return (GREATER_AND);
3444 else if (character == '<' && peek_char == '>')
3445 return (LESS_GREATER);
3446 else if (character == '>' && peek_char == '|')
3447 return (GREATER_BAR);
3448 else if (peek_char == '>' && character == '&')
3449 return (AND_GREATER);
3450
3451 shell_ungetc (peek_char);
3452
3453 /* If we look like we are reading the start of a function
3454 definition, then let the reader know about it so that
3455 we will do the right thing with `{'. */
3456 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
3457 {
3458 parser_state |= PST_ALLOWOPNBRC;
3459 #if defined (ALIAS)
3460 parser_state &= ~PST_ALEXPNEXT;
3461 #endif /* ALIAS */
3462 function_dstart = line_number;
3463 }
3464
3465 /* case pattern lists may be preceded by an optional left paren. If
3466 we're not trying to parse a case pattern list, the left paren
3467 indicates a subshell. */
3468 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3469 parser_state |= PST_SUBSHELL;
3470 /*(*/
3471 else if ((parser_state & PST_CASEPAT) && character == ')')
3472 parser_state &= ~PST_CASEPAT;
3473 /*(*/
3474 else if ((parser_state & PST_SUBSHELL) && character == ')')
3475 parser_state &= ~PST_SUBSHELL;
3476
3477 #if defined (PROCESS_SUBSTITUTION)
3478 /* Check for the constructs which introduce process substitution.
3479 Shells running in `posix mode' don't do process substitution. */
3480 if (posixly_correct ||
3481 ((character != '>' && character != '<') || peek_char != '('))
3482 #endif /* PROCESS_SUBSTITUTION */
3483 return (character);
3484 }
3485
3486 /* Hack <&- (close stdin) case. */
3487 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3488 return (character);
3489
3490 /* Okay, if we got this far, we have to read a word. Read one,
3491 and then check it against the known ones. */
3492 result = read_token_word (character);
3493 #if defined (ALIAS)
3494 if (result == RE_READ_TOKEN)
3495 goto re_read_token;
3496 #endif
3497 return result;
3498 }
3499
3500 /* Match a $(...) or other grouping construct. This has to handle embedded
3501 quoted strings ('', ``, "") and nested constructs. It also must handle
3502 reprompting the user, if necessary, after reading a newline, and returning
3503 correct error values if it reads EOF. */
3504 static char matched_pair_error;
3505 static char *
3506 parse_matched_pair (qc, open, close, lenp, flags)
3507 int qc; /* `"' if this construct is within double quotes */
3508 int open, close;
3509 int *lenp, flags;
3510 {
3511 int count, ch, was_dollar;
3512 int pass_next_character, nestlen, start_lineno;
3513 char *ret, *nestret;
3514 int retind, retsize;
3515
3516 count = 1;
3517 pass_next_character = was_dollar = 0;
3518
3519 ret = xmalloc (retsize = 64);
3520 retind = 0;
3521
3522 start_lineno = line_number;
3523 while (count)
3524 {
3525 ch = shell_getc (qc != '\'' && pass_next_character == 0);
3526 if (ch == EOF)
3527 {
3528 free (ret);
3529 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3530 EOF_Reached = 1; /* XXX */
3531 return (&matched_pair_error);
3532 }
3533
3534 /* Possible reprompting. */
3535 if (ch == '\n' && interactive &&
3536 (bash_input.type == st_stdin || bash_input.type == st_stream))
3537 prompt_again ();
3538
3539 if (pass_next_character) /* last char was backslash */
3540 {
3541 pass_next_character = 0;
3542 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3543 {
3544 if (retind > 0) retind--; /* swallow previously-added backslash */
3545 continue;
3546 }
3547
3548 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3549 if (ch == CTLESC || ch == CTLNUL)
3550 ret[retind++] = CTLESC;
3551 ret[retind++] = ch;
3552 continue;
3553 }
3554 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3555 {
3556 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3557 ret[retind++] = CTLESC;
3558 ret[retind++] = ch;
3559 continue;
3560 }
3561 else if (ch == close) /* ending delimiter */
3562 count--;
3563 else if (ch == open) /* nested begin */
3564 count++;
3565
3566 /* Add this character. */
3567 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3568 ret[retind++] = ch;
3569
3570 if (open == '\'') /* '' inside grouping construct */
3571 continue;
3572
3573 if (ch == '\\') /* backslashes */
3574 pass_next_character++;
3575
3576 if (open != close) /* a grouping construct */
3577 {
3578 if (shellquote (ch))
3579 {
3580 /* '', ``, or "" inside $(...) or other grouping construct. */
3581 push_delimiter (dstack, ch);
3582 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
3583 pop_delimiter (dstack);
3584 if (nestret == &matched_pair_error)
3585 {
3586 free (ret);
3587 return &matched_pair_error;
3588 }
3589 if (nestlen)
3590 {
3591 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3592 strcpy (ret + retind, nestret);
3593 retind += nestlen;
3594 }
3595 FREE (nestret);
3596 }
3597 }
3598 /* Parse an old-style command substitution within double quotes as a
3599 single word. */
3600 /* XXX - sh and ksh93 don't do this - XXX */
3601 else if (open == '"' && ch == '`')
3602 {
3603 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3604 if (nestret == &matched_pair_error)
3605 {
3606 free (ret);
3607 return &matched_pair_error;
3608 }
3609 if (nestlen)
3610 {
3611 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3612 strcpy (ret + retind, nestret);
3613 retind += nestlen;
3614 }
3615 FREE (nestret);
3616 }
3617 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3618 /* check for $(), $[], or ${} inside quoted string. */
3619 {
3620 if (open == ch) /* undo previous increment */
3621 count--;
3622 if (ch == '(') /* ) */
3623 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
3624 else if (ch == '{') /* } */
3625 nestret = parse_matched_pair (0, '{', '}', &nestlen, 0);
3626 else if (ch == '[') /* ] */
3627 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
3628 if (nestret == &matched_pair_error)
3629 {
3630 free (ret);
3631 return &matched_pair_error;
3632 }
3633 if (nestlen)
3634 {
3635 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3636 strcpy (ret + retind, nestret);
3637 retind += nestlen;
3638 }
3639 FREE (nestret);
3640 }
3641 was_dollar = (ch == '$');
3642 }
3643
3644 ret[retind] = '\0';
3645 if (lenp)
3646 *lenp = retind;
3647 return ret;
3648 }
3649
3650 #if defined (DPAREN_ARITHMETIC)
3651 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
3652 If not, assume it's a nested subshell for backwards compatibility and
3653 return 0. In any case, put the characters we've consumed into a locally-
3654 allocated buffer and make *ep point to that buffer. Return -1 on an
3655 error, for example EOF. */
3656 static int
3657 parse_arith_cmd (ep)
3658 char **ep;
3659 {
3660 int exp_lineno, rval, c;
3661 char *ttok, *token;
3662 int ttoklen;
3663
3664 exp_lineno = line_number;
3665 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3666 rval = 1;
3667 if (ttok == &matched_pair_error)
3668 return -1;
3669 /* Check that the next character is the closing right paren. If
3670 not, this is a syntax error. ( */
3671 if ((c = shell_getc (0)) != ')')
3672 rval = 0;
3673
3674 token = xmalloc(ttoklen + 4);
3675
3676 /* (( ... )) -> "..." */
3677 token[0] = (rval == 1) ? '"' : '(';
3678 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
3679 if (rval == 1)
3680 {
3681 token[ttoklen] = '"';
3682 token[ttoklen+1] = '\0';
3683 }
3684 else
3685 {
3686 token[ttoklen] = ')';
3687 token[ttoklen+1] = c;
3688 token[ttoklen+2] = '\0';
3689 }
3690 *ep = token;
3691 FREE (ttok);
3692 return rval;
3693 }
3694 #endif /* DPAREN_ARITHMETIC */
3695
3696 #if defined (COND_COMMAND)
3697 static COND_COM *cond_term ();
3698 static COND_COM *cond_and ();
3699 static COND_COM *cond_or ();
3700 static COND_COM *cond_expr ();
3701
3702 static COND_COM *
3703 cond_expr ()
3704 {
3705 return (cond_or ());
3706 }
3707
3708 static COND_COM *
3709 cond_or ()
3710 {
3711 COND_COM *l, *r;
3712
3713 l = cond_and ();
3714 if (cond_token == OR_OR)
3715 {
3716 r = cond_or ();
3717 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3718 }
3719 return l;
3720 }
3721
3722 static COND_COM *
3723 cond_and ()
3724 {
3725 COND_COM *l, *r;
3726
3727 l = cond_term ();
3728 if (cond_token == AND_AND)
3729 {
3730 r = cond_and ();
3731 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3732 }
3733 return l;
3734 }
3735
3736 static int
3737 cond_skip_newlines ()
3738 {
3739 while ((cond_token = read_token (READ)) == '\n')
3740 {
3741 if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
3742 prompt_again ();
3743 }
3744 return (cond_token);
3745 }
3746
3747 #define COND_RETURN_ERROR() \
3748 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3749
3750 static COND_COM *
3751 cond_term ()
3752 {
3753 WORD_DESC *op;
3754 COND_COM *term, *tleft, *tright;
3755 int tok, lineno;
3756
3757 /* Read a token. It can be a left paren, a `!', a unary operator, or a
3758 word that should be the first argument of a binary operator. Start by
3759 skipping newlines, since this is a compound command. */
3760 tok = cond_skip_newlines ();
3761 lineno = line_number;
3762 if (tok == COND_END)
3763 {
3764 COND_RETURN_ERROR ();
3765 }
3766 else if (tok == '(')
3767 {
3768 term = cond_expr ();
3769 if (cond_token != ')')
3770 {
3771 if (term)
3772 dispose_cond_node (term); /* ( */
3773 parser_error (lineno, "expected `)'");
3774 COND_RETURN_ERROR ();
3775 }
3776 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3777 (void)cond_skip_newlines ();
3778 }
3779 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3780 {
3781 if (tok == WORD)
3782 dispose_word (yylval.word); /* not needed */
3783 term = cond_term ();
3784 if (term)
3785 term->flags |= CMD_INVERT_RETURN;
3786 }
3787 else if (tok == WORD && test_unop (yylval.word->word))
3788 {
3789 op = yylval.word;
3790 tok = read_token (READ);
3791 if (tok == WORD)
3792 {
3793 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3794 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3795 }
3796 else
3797 {
3798 dispose_word (op);
3799 parser_error (line_number, "unexpected argument to conditional unary operator");
3800 COND_RETURN_ERROR ();
3801 }
3802
3803 (void)cond_skip_newlines ();
3804 }
3805 else /* left argument to binary operator */
3806 {
3807 /* lhs */
3808 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3809
3810 /* binop */
3811 tok = read_token (READ);
3812 if (tok == WORD && test_binop (yylval.word->word))
3813 op = yylval.word;
3814 else if (tok == '<' || tok == '>')
3815 op = make_word_from_token (tok);
3816 else if (tok == COND_END || tok == AND_AND || tok == OR_OR)
3817 {
3818 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
3819 the test command. Similarly for [[ x && expr ]] or
3820 [[ x || expr ]] */
3821 op = make_word ("-n");
3822 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3823 cond_token = tok;
3824 return (term);
3825 }
3826 else
3827 {
3828 parser_error (line_number, "conditional binary operator expected");
3829 dispose_cond_node (tleft);
3830 COND_RETURN_ERROR ();
3831 }
3832
3833 /* rhs */
3834 tok = read_token (READ);
3835 if (tok == WORD)
3836 {
3837 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3838 term = make_cond_node (COND_BINARY, op, tleft, tright);
3839 }
3840 else
3841 {
3842 parser_error (line_number, "unexpected argument to conditional binary operator");
3843 dispose_cond_node (tleft);
3844 dispose_word (op);
3845 COND_RETURN_ERROR ();
3846 }
3847
3848 (void)cond_skip_newlines ();
3849 }
3850 return (term);
3851 }
3852
3853 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3854 here to handle the conditional statement syntax. */
3855 static COMMAND *
3856 parse_cond_command ()
3857 {
3858 COND_COM *cexp;
3859
3860 cexp = cond_expr ();
3861 return (make_cond_command (cexp));
3862 }
3863 #endif
3864
3865 static int
3866 read_token_word (character)
3867 int character;
3868 {
3869 /* The value for YYLVAL when a WORD is read. */
3870 WORD_DESC *the_word;
3871
3872 /* Index into the token that we are building. */
3873 int token_index;
3874
3875 /* ALL_DIGITS becomes zero when we see a non-digit. */
3876 int all_digits;
3877
3878 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3879 int dollar_present;
3880
3881 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3882 int quoted;
3883
3884 /* Non-zero means to ignore the value of the next character, and just
3885 to add it no matter what. */
3886 int pass_next_character;
3887
3888 /* The current delimiting character. */
3889 int cd;
3890 int result, peek_char;
3891 char *ttok, *ttrans;
3892 int ttoklen, ttranslen;
3893
3894 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3895 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3896
3897 token_index = 0;
3898 all_digits = digit (character);
3899 dollar_present = quoted = pass_next_character = 0;
3900
3901 for (;;)
3902 {
3903 if (character == EOF)
3904 goto got_token;
3905
3906 if (pass_next_character)
3907 {
3908 pass_next_character = 0;
3909 goto got_character;
3910 }
3911
3912 cd = current_delimiter (dstack);
3913
3914 /* Handle backslashes. Quote lots of things when not inside of
3915 double-quotes, quote some things inside of double-quotes. */
3916 if (character == '\\')
3917 {
3918 peek_char = shell_getc (0);
3919
3920 /* Backslash-newline is ignored in all cases except
3921 when quoted with single quotes. */
3922 if (peek_char == '\n')
3923 {
3924 character = '\n';
3925 goto next_character;
3926 }
3927 else
3928 {
3929 shell_ungetc (peek_char);
3930
3931 /* If the next character is to be quoted, note it now. */
3932 if (cd == 0 || cd == '`' ||
3933 (cd == '"' && member (peek_char, slashify_in_quotes)))
3934 pass_next_character++;
3935
3936 quoted = 1;
3937 goto got_character;
3938 }
3939 }
3940
3941 /* Parse a matched pair of quote characters. */
3942 if (shellquote (character))
3943 {
3944 push_delimiter (dstack, character);
3945 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
3946 pop_delimiter (dstack);
3947 if (ttok == &matched_pair_error)
3948 return -1; /* Bail immediately. */
3949 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3950 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3951 token[token_index++] = character;
3952 strcpy (token + token_index, ttok);
3953 token_index += ttoklen;
3954 all_digits = 0;
3955 quoted = 1;
3956 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3957 FREE (ttok);
3958 goto next_character;
3959 }
3960
3961 #ifdef EXTENDED_GLOB
3962 /* Parse a ksh-style extended pattern matching specification. */
3963 if (extended_glob && PATTERN_CHAR(character))
3964 {
3965 peek_char = shell_getc (1);
3966 if (peek_char == '(') /* ) */
3967 {
3968 push_delimiter (dstack, peek_char);
3969 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3970 pop_delimiter (dstack);
3971 if (ttok == &matched_pair_error)
3972 return -1; /* Bail immediately. */
3973 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3974 token_buffer_size,
3975 TOKEN_DEFAULT_GROW_SIZE);
3976 token[token_index++] = character;
3977 token[token_index++] = peek_char;
3978 strcpy (token + token_index, ttok);
3979 token_index += ttoklen;
3980 FREE (ttok);
3981 dollar_present = all_digits = 0;
3982 goto next_character;
3983 }
3984 else
3985 shell_ungetc (peek_char);
3986 }
3987 #endif /* EXTENDED_GLOB */
3988
3989 /* If the delimiter character is not single quote, parse some of
3990 the shell expansions that must be read as a single word. */
3991 #if defined (PROCESS_SUBSTITUTION)
3992 if (character == '$' || character == '<' || character == '>')
3993 #else
3994 if (character == '$')
3995 #endif /* !PROCESS_SUBSTITUTION */
3996 {
3997 peek_char = shell_getc (1);
3998 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3999 if (peek_char == '(' ||
4000 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4001 {
4002 if (peek_char == '{') /* } */
4003 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, 0);
4004 else if (peek_char == '(') /* ) */
4005 {
4006 /* XXX - push and pop the `(' as a delimiter for use by
4007 the command-oriented-history code. This way newlines
4008 appearing in the $(...) string get added to the
4009 history literally rather than causing a possibly-
4010 incorrect `;' to be added. */
4011 push_delimiter (dstack, peek_char);
4012 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4013 pop_delimiter (dstack);
4014 }
4015 else
4016 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4017 if (ttok == &matched_pair_error)
4018 return -1; /* Bail immediately. */
4019 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4020 token_buffer_size,
4021 TOKEN_DEFAULT_GROW_SIZE);
4022 token[token_index++] = character;
4023 token[token_index++] = peek_char;
4024 strcpy (token + token_index, ttok);
4025 token_index += ttoklen;
4026 FREE (ttok);
4027 dollar_present = 1;
4028 all_digits = 0;
4029 goto next_character;
4030 }
4031 /* This handles $'...' and $"..." new-style quoted strings. */
4032 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
4033 {
4034 int first_line;
4035
4036 first_line = line_number;
4037 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
4038 if (ttok == &matched_pair_error)
4039 return -1;
4040 if (peek_char == '\'')
4041 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4042 else
4043 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4044 free (ttok);
4045 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4046 token_buffer_size,
4047 TOKEN_DEFAULT_GROW_SIZE);
4048 token[token_index++] = peek_char;
4049 strcpy (token + token_index, ttrans);
4050 token_index += ttranslen;
4051 token[token_index++] = peek_char;
4052 FREE (ttrans);
4053 quoted = 1;
4054 all_digits = 0;
4055 goto next_character;
4056 }
4057 else
4058 shell_ungetc (peek_char);
4059 }
4060
4061 #if defined (ARRAY_VARS)
4062 /* Identify possible compound array variable assignment. */
4063 else if (character == '=' && token_index > 0)
4064 {
4065 peek_char = shell_getc (1);
4066 if (peek_char == '(') /* ) */
4067 {
4068 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4069 if (ttok == &matched_pair_error)
4070 return -1; /* Bail immediately. */
4071 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4072 token_buffer_size,
4073 TOKEN_DEFAULT_GROW_SIZE);
4074 token[token_index++] = character;
4075 token[token_index++] = peek_char;
4076 strcpy (token + token_index, ttok);
4077 token_index += ttoklen;
4078 FREE (ttok);
4079 all_digits = 0;
4080 goto next_character;
4081 }
4082 else
4083 shell_ungetc (peek_char);
4084 }
4085 #endif
4086
4087 /* When not parsing a multi-character word construct, shell meta-
4088 characters break words. */
4089 if (shellbreak (character))
4090 {
4091 shell_ungetc (character);
4092 goto got_token;
4093 }
4094
4095 got_character:
4096
4097 all_digits &= digit (character);
4098 dollar_present |= character == '$';
4099
4100 if (character == CTLESC || character == CTLNUL)
4101 token[token_index++] = CTLESC;
4102
4103 token[token_index++] = character;
4104
4105 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4106 TOKEN_DEFAULT_GROW_SIZE);
4107
4108 next_character:
4109 if (character == '\n' && interactive &&
4110 (bash_input.type == st_stdin || bash_input.type == st_stream))
4111 prompt_again ();
4112
4113 /* We want to remove quoted newlines (that is, a \<newline> pair)
4114 unless we are within single quotes or pass_next_character is
4115 set (the shell equivalent of literal-next). */
4116 cd = current_delimiter (dstack);
4117 character = shell_getc (cd != '\'' && pass_next_character == 0);
4118 } /* end for (;;) */
4119
4120 got_token:
4121
4122 token[token_index] = '\0';
4123
4124 /* Check to see what thing we should return. If the last_read_token
4125 is a `<', or a `&', or the character which ended this token is
4126 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4127 Otherwise, it is just a word, and should be returned as such. */
4128 if (all_digits && (character == '<' || character == '>' ||
4129 last_read_token == LESS_AND ||
4130 last_read_token == GREATER_AND))
4131 {
4132 yylval.number = atoi (token);
4133 return (NUMBER);
4134 }
4135
4136 /* Check for special case tokens. */
4137 result = special_case_tokens (token);
4138 if (result >= 0)
4139 return result;
4140
4141 #if defined (ALIAS)
4142 /* Posix.2 does not allow reserved words to be aliased, so check for all
4143 of them, including special cases, before expanding the current token
4144 as an alias. */
4145 if (posixly_correct)
4146 CHECK_FOR_RESERVED_WORD (token);
4147
4148 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4149 inhibits alias expansion. */
4150 if (expand_aliases && quoted == 0)
4151 {
4152 result = alias_expand_token (token);
4153 if (result == RE_READ_TOKEN)
4154 return (RE_READ_TOKEN);
4155 else if (result == NO_EXPANSION)
4156 parser_state &= ~PST_ALEXPNEXT;
4157 }
4158
4159 /* If not in Posix.2 mode, check for reserved words after alias
4160 expansion. */
4161 if (posixly_correct == 0)
4162 #endif
4163 CHECK_FOR_RESERVED_WORD (token);
4164
4165 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4166 the_word->word = xmalloc (1 + token_index);
4167 the_word->flags = 0;
4168 strcpy (the_word->word, token);
4169 if (dollar_present)
4170 the_word->flags |= W_HASDOLLAR;
4171 if (quoted)
4172 the_word->flags |= W_QUOTED;
4173 /* A word is an assignment if it appears at the beginning of a
4174 simple command, or after another assignment word. This is
4175 context-dependent, so it cannot be handled in the grammar. */
4176 if (assignment (token))
4177 {
4178 the_word->flags |= W_ASSIGNMENT;
4179 /* Don't perform word splitting on assignment statements. */
4180 if (assignment_acceptable (last_read_token))
4181 the_word->flags |= W_NOSPLIT;
4182 }
4183
4184 yylval.word = the_word;
4185
4186 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4187 ? ASSIGNMENT_WORD : WORD;
4188
4189 if (last_read_token == FUNCTION)
4190 {
4191 parser_state |= PST_ALLOWOPNBRC;
4192 function_dstart = line_number;
4193 }
4194
4195 return (result);
4196 }
4197
4198 /* $'...' ANSI-C expand the portion of STRING between START and END and
4199 return the result. The result cannot be longer than the input string. */
4200 static char *
4201 ansiexpand (string, start, end, lenp)
4202 char *string;
4203 int start, end, *lenp;
4204 {
4205 char *temp, *t;
4206 int len, tlen;
4207
4208 temp = xmalloc (end - start + 1);
4209 for (tlen = 0, len = start; len < end; )
4210 temp[tlen++] = string[len++];
4211 temp[tlen] = '\0';
4212
4213 if (*temp)
4214 {
4215 t = ansicstr (temp, tlen, (int *)NULL, lenp);
4216 free (temp);
4217 return (t);
4218 }
4219 else
4220 {
4221 if (lenp)
4222 *lenp = 0;
4223 return (temp);
4224 }
4225 }
4226
4227 /* $"..." -- Translate the portion of STRING between START and END
4228 according to current locale using gettext (if available) and return
4229 the result. The caller will take care of leaving the quotes intact.
4230 The string will be left without the leading `$' by the caller.
4231 If translation is performed, the translated string will be double-quoted
4232 by the caller. The length of the translated string is returned in LENP,
4233 if non-null. */
4234 static char *
4235 localeexpand (string, start, end, lineno, lenp)
4236 char *string;
4237 int start, end, lineno, *lenp;
4238 {
4239 int len, tlen;
4240 char *temp, *t;
4241
4242 temp = xmalloc (end - start + 1);
4243 for (tlen = 0, len = start; len < end; )
4244 temp[tlen++] = string[len++];
4245 temp[tlen] = '\0';
4246
4247 /* If we're just dumping translatable strings, don't do anything. */
4248 if (dump_translatable_strings)
4249 {
4250 if (dump_po_strings)
4251 printf ("#: %s:%d\nmsgid \"%s\"\nmsgstr \"\"\n",
4252 (bash_input.name ? bash_input.name : "stdin"), lineno, temp);
4253 else
4254 printf ("\"%s\"\n", temp);
4255 if (lenp)
4256 *lenp = tlen;
4257 return (temp);
4258 }
4259 else if (*temp)
4260 {
4261 t = localetrans (temp, tlen, &len);
4262 free (temp);
4263 if (lenp)
4264 *lenp = len;
4265 return (t);
4266 }
4267 else
4268 {
4269 if (lenp)
4270 *lenp = 0;
4271 return (temp);
4272 }
4273 }
4274
4275 /* Return 1 if TOKEN is a token that after being read would allow
4276 a reserved word to be seen, else 0. */
4277 static int
4278 reserved_word_acceptable (token)
4279 int token;
4280 {
4281 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
4282 token == '|' || token == '&' || token == '{' ||
4283 token == '}' || /* XXX */
4284 token == AND_AND ||
4285 token == BANG ||
4286 token == TIME || token == TIMEOPT ||
4287 token == DO ||
4288 token == ELIF ||
4289 token == ELSE ||
4290 token == FI ||
4291 token == IF ||
4292 token == OR_OR ||
4293 token == SEMI_SEMI ||
4294 token == THEN ||
4295 token == UNTIL ||
4296 token == WHILE ||
4297 token == DONE || /* XXX these two are experimental */
4298 token == ESAC ||
4299 token == 0)
4300 return (1);
4301 else
4302 return (0);
4303 }
4304
4305 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4306 TOKEN is not a shell reserved word. */
4307 int
4308 find_reserved_word (token)
4309 char *token;
4310 {
4311 int i;
4312 for (i = 0; word_token_alist[i].word; i++)
4313 if (STREQ (token, word_token_alist[i].word))
4314 return i;
4315 return -1;
4316 }
4317
4318 #if 0
4319 #if defined (READLINE)
4320 /* Called after each time readline is called. This insures that whatever
4321 the new prompt string is gets propagated to readline's local prompt
4322 variable. */
4323 static void
4324 reset_readline_prompt ()
4325 {
4326 char *temp_prompt;
4327
4328 if (prompt_string_pointer)
4329 {
4330 temp_prompt = (*prompt_string_pointer)
4331 ? decode_prompt_string (*prompt_string_pointer)
4332 : (char *)NULL;
4333
4334 if (temp_prompt == 0)
4335 {
4336 temp_prompt = xmalloc (1);
4337 temp_prompt[0] = '\0';
4338 }
4339
4340 FREE (current_readline_prompt);
4341 current_readline_prompt = temp_prompt;
4342 }
4343 }
4344 #endif /* READLINE */
4345 #endif /* 0 */
4346
4347 #if defined (HISTORY)
4348 /* A list of tokens which can be followed by newlines, but not by
4349 semi-colons. When concatenating multiple lines of history, the
4350 newline separator for such tokens is replaced with a space. */
4351 static int no_semi_successors[] = {
4352 '\n', '{', '(', ')', ';', '&', '|',
4353 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
4354 0
4355 };
4356
4357 /* If we are not within a delimited expression, try to be smart
4358 about which separators can be semi-colons and which must be
4359 newlines. Returns the string that should be added into the
4360 history entry. */
4361 char *
4362 history_delimiting_chars ()
4363 {
4364 register int i;
4365
4366 if (dstack.delimiter_depth != 0)
4367 return ("\n");
4368
4369 /* First, handle some special cases. */
4370 /*(*/
4371 /* If we just read `()', assume it's a function definition, and don't
4372 add a semicolon. If the token before the `)' was not `(', and we're
4373 not in the midst of parsing a case statement, assume it's a
4374 parenthesized command and add the semicolon. */
4375 /*)(*/
4376 if (token_before_that == ')')
4377 {
4378 if (two_tokens_ago == '(') /*)*/ /* function def */
4379 return " ";
4380 /* This does not work for subshells inside case statement
4381 command lists. It's a suboptimal solution. */
4382 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4383 return " ";
4384 else
4385 return "; "; /* (...) subshell */
4386 }
4387 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4388 return " "; /* function def using `function name' without `()' */
4389
4390 for (i = 0; no_semi_successors[i]; i++)
4391 {
4392 if (token_before_that == no_semi_successors[i])
4393 return (" ");
4394 }
4395
4396 return ("; ");
4397 }
4398 #endif /* HISTORY */
4399
4400 /* Issue a prompt, or prepare to issue a prompt when the next character
4401 is read. */
4402 static void
4403 prompt_again ()
4404 {
4405 char *temp_prompt;
4406
4407 if (!interactive) /* XXX */
4408 return;
4409
4410 ps1_prompt = get_string_value ("PS1");
4411 ps2_prompt = get_string_value ("PS2");
4412
4413 if (!prompt_string_pointer)
4414 prompt_string_pointer = &ps1_prompt;
4415
4416 temp_prompt = *prompt_string_pointer
4417 ? decode_prompt_string (*prompt_string_pointer)
4418 : (char *)NULL;
4419
4420 if (temp_prompt == 0)
4421 {
4422 temp_prompt = xmalloc (1);
4423 temp_prompt[0] = '\0';
4424 }
4425
4426 current_prompt_string = *prompt_string_pointer;
4427 prompt_string_pointer = &ps2_prompt;
4428
4429 #if defined (READLINE)
4430 if (!no_line_editing)
4431 {
4432 FREE (current_readline_prompt);
4433 current_readline_prompt = temp_prompt;
4434 }
4435 else
4436 #endif /* READLINE */
4437 {
4438 FREE (current_decoded_prompt);
4439 current_decoded_prompt = temp_prompt;
4440 }
4441 }
4442
4443 static void
4444 print_prompt ()
4445 {
4446 fprintf (stderr, "%s", current_decoded_prompt);
4447 fflush (stderr);
4448 }
4449
4450 /* Return a string which will be printed as a prompt. The string
4451 may contain special characters which are decoded as follows:
4452
4453 \a bell (ascii 07)
4454 \e escape (ascii 033)
4455 \d the date in Day Mon Date format
4456 \h the hostname up to the first `.'
4457 \H the hostname
4458 \n CRLF
4459 \s the name of the shell
4460 \t the time in 24-hour hh:mm:ss format
4461 \T the time in 12-hour hh:mm:ss format
4462 \@ the time in 12-hour am/pm format
4463 \v the version of bash (e.g., 2.00)
4464 \V the release of bash, version + patchlevel (e.g., 2.00.0)
4465 \w the current working directory
4466 \W the last element of $PWD
4467 \u your username
4468 \# the command number of this command
4469 \! the history number of this command
4470 \$ a $ or a # if you are root
4471 \nnn character code nnn in octal
4472 \\ a backslash
4473 \[ begin a sequence of non-printing chars
4474 \] end a sequence of non-printing chars
4475 */
4476 #define PROMPT_GROWTH 48
4477 char *
4478 decode_prompt_string (string)
4479 char *string;
4480 {
4481 WORD_LIST *list;
4482 char *result, *t;
4483 struct dstack save_dstack;
4484 #if defined (PROMPT_STRING_DECODE)
4485 int result_size, result_index;
4486 int c, n;
4487 char *temp, octal_string[4];
4488 time_t the_time;
4489
4490 result = xmalloc (result_size = PROMPT_GROWTH);
4491 result[result_index = 0] = 0;
4492 temp = (char *)NULL;
4493
4494 while (c = *string++)
4495 {
4496 if (posixly_correct && c == '!')
4497 {
4498 if (*string == '!')
4499 {
4500 temp = savestring ("!");
4501 goto add_string;
4502 }
4503 else
4504 {
4505 #if !defined (HISTORY)
4506 temp = savestring ("1");
4507 #else /* HISTORY */
4508 temp = itos (history_number ());
4509 #endif /* HISTORY */
4510 string--; /* add_string increments string again. */
4511 goto add_string;
4512 }
4513 }
4514 if (c == '\\')
4515 {
4516 c = *string;
4517
4518 switch (c)
4519 {
4520 case '0':
4521 case '1':
4522 case '2':
4523 case '3':
4524 case '4':
4525 case '5':
4526 case '6':
4527 case '7':
4528 strncpy (octal_string, string, 3);
4529 octal_string[3] = '\0';
4530
4531 n = read_octal (octal_string);
4532 temp = xmalloc (3);
4533
4534 if (n == CTLESC || n == CTLNUL)
4535 {
4536 string += 3;
4537 temp[0] = CTLESC;
4538 temp[1] = n;
4539 temp[2] = '\0';
4540 }
4541 else if (n == -1)
4542 {
4543 temp[0] = '\\';
4544 temp[1] = '\0';
4545 }
4546 else
4547 {
4548 string += 3;
4549 temp[0] = n;
4550 temp[1] = '\0';
4551 }
4552
4553 c = 0;
4554 goto add_string;
4555
4556 case 't':
4557 case 'd':
4558 case 'T':
4559 case '@':
4560 /* Make the current time/date into a string. */
4561 the_time = time (0);
4562 temp = ctime (&the_time);
4563
4564 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4565 temp[(c != 'd') ? 8 : 10] = '\0';
4566
4567 /* quick and dirty conversion to 12-hour time */
4568 if (c == 'T' || c == '@')
4569 {
4570 if (c == '@')
4571 {
4572 temp[5] = 'a'; /* am/pm format */
4573 temp[6] = 'm';
4574 temp[7] = '\0';
4575 }
4576 c = temp[2];
4577 temp[2] = '\0';
4578 n = atoi (temp);
4579 temp[2] = c;
4580 n -= 12;
4581 if (n > 0)
4582 {
4583 temp[0] = (n / 10) + '0';
4584 temp[1] = (n % 10) + '0';
4585 }
4586 if (n >= 0 && temp[5] == 'a')
4587 temp[5] = 'p';
4588 }
4589 goto add_string;
4590
4591 case 'r':
4592 temp = xmalloc (2);
4593 temp[0] = '\r';
4594 temp[1] = '\0';
4595 goto add_string;
4596
4597 case 'n':
4598 temp = xmalloc (3);
4599 temp[0] = no_line_editing ? '\n' : '\r';
4600 temp[1] = no_line_editing ? '\0' : '\n';
4601 temp[2] = '\0';
4602 goto add_string;
4603
4604 case 's':
4605 temp = base_pathname (shell_name);
4606 temp = savestring (temp);
4607 goto add_string;
4608
4609 case 'v':
4610 case 'V':
4611 temp = xmalloc (8);
4612 if (c == 'v')
4613 strcpy (temp, dist_version);
4614 else
4615 sprintf (temp, "%s.%d", dist_version, patch_level);
4616 goto add_string;
4617
4618 case 'w':
4619 case 'W':
4620 {
4621 /* Use the value of PWD because it is much more efficient. */
4622 char t_string[PATH_MAX];
4623 int tlen;
4624
4625 temp = get_string_value ("PWD");
4626
4627 if (temp == 0)
4628 {
4629 if (getcwd (t_string, sizeof(t_string)) == 0)
4630 {
4631 t_string[0] = '.';
4632 tlen = 1;
4633 }
4634 else
4635 tlen = strlen (t_string);
4636 }
4637 else
4638 {
4639 tlen = sizeof (t_string) - 1;
4640 strncpy (t_string, temp, tlen);
4641 }
4642 t_string[tlen] = '\0';
4643
4644 if (c == 'W')
4645 {
4646 t = strrchr (t_string, '/');
4647 if (t && t != t_string)
4648 strcpy (t_string, t + 1);
4649 }
4650 else
4651 /* polite_directory_format is guaranteed to return a string
4652 no longer than PATH_MAX - 1 characters. */
4653 strcpy (t_string, polite_directory_format (t_string));
4654
4655 /* If we're going to be expanding the prompt string later,
4656 quote the directory name. */
4657 if (promptvars || posixly_correct)
4658 temp = backslash_quote (t_string);
4659 else
4660 temp = savestring (t_string);
4661
4662 goto add_string;
4663 }
4664
4665 case 'u':
4666 temp = savestring (current_user.user_name);
4667 goto add_string;
4668
4669 case 'h':
4670 case 'H':
4671 temp = savestring (current_host_name);
4672 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4673 *t = '\0';
4674 goto add_string;
4675
4676 case '#':
4677 temp = itos (current_command_number);
4678 goto add_string;
4679
4680 case '!':
4681 #if !defined (HISTORY)
4682 temp = savestring ("1");
4683 #else /* HISTORY */
4684 temp = itos (history_number ());
4685 #endif /* HISTORY */
4686 goto add_string;
4687
4688 case '$':
4689 temp = xmalloc (2);
4690 temp[0] = current_user.euid == 0 ? '#' : '$';
4691 temp[1] = '\0';
4692 goto add_string;
4693
4694 #if defined (READLINE)
4695 case '[':
4696 case ']':
4697 temp = xmalloc (3);
4698 temp[0] = '\001';
4699 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4700 temp[2] = '\0';
4701 goto add_string;
4702 #endif /* READLINE */
4703
4704 case '\\':
4705 temp = xmalloc (2);
4706 temp[0] = c;
4707 temp[1] = '\0';
4708 goto add_string;
4709
4710 case 'a':
4711 case 'e':
4712 temp = xmalloc (2);
4713 temp[0] = (c == 'a') ? '\07' : '\033';
4714 temp[1] = '\0';
4715 goto add_string;
4716
4717 default:
4718 temp = xmalloc (3);
4719 temp[0] = '\\';
4720 temp[1] = c;
4721 temp[2] = '\0';
4722
4723 add_string:
4724 if (c)
4725 string++;
4726 result =
4727 sub_append_string (temp, result, &result_index, &result_size);
4728 temp = (char *)NULL; /* Freed in sub_append_string (). */
4729 result[result_index] = '\0';
4730 break;
4731 }
4732 }
4733 else
4734 {
4735 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4736 result[result_index++] = c;
4737 result[result_index] = '\0';
4738 }
4739 }
4740 #else /* !PROMPT_STRING_DECODE */
4741 result = savestring (string);
4742 #endif /* !PROMPT_STRING_DECODE */
4743
4744 /* Save the delimiter stack and point `dstack' to temp space so any
4745 command substitutions in the prompt string won't result in screwing
4746 up the parser's quoting state. */
4747 save_dstack = dstack;
4748 dstack = temp_dstack;
4749 dstack.delimiter_depth = 0;
4750
4751 /* Perform variable and parameter expansion and command substitution on
4752 the prompt string. */
4753 if (promptvars || posixly_correct)
4754 {
4755 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
4756 free (result);
4757 result = string_list (list);
4758 dispose_words (list);
4759 }
4760 else
4761 {
4762 t = dequote_string (result);
4763 free (result);
4764 result = t;
4765 }
4766
4767 dstack = save_dstack;
4768
4769 return (result);
4770 }
4771
4772 /* Report a syntax error, and restart the parser. Call here for fatal
4773 errors. */
4774 int
4775 yyerror ()
4776 {
4777 report_syntax_error ((char *)NULL);
4778 reset_parser ();
4779 return (0);
4780 }
4781
4782 /* Report a syntax error with line numbers, etc.
4783 Call here for recoverable errors. If you have a message to print,
4784 then place it in MESSAGE, otherwise pass NULL and this will figure
4785 out an appropriate message for you. */
4786 static void
4787 report_syntax_error (message)
4788 char *message;
4789 {
4790 char *msg, *t;
4791 int token_end, i;
4792 char msg2[2];
4793
4794 if (message)
4795 {
4796 parser_error (line_number, "%s", message);
4797 if (interactive && EOF_Reached)
4798 EOF_Reached = 0;
4799 last_command_exit_value = EX_USAGE;
4800 return;
4801 }
4802
4803 /* If the line of input we're reading is not null, try to find the
4804 objectionable token. */
4805 if (shell_input_line && *shell_input_line)
4806 {
4807 t = shell_input_line;
4808 i = shell_input_line_index;
4809 token_end = 0;
4810
4811 if (i && t[i] == '\0')
4812 i--;
4813
4814 while (i && (whitespace (t[i]) || t[i] == '\n'))
4815 i--;
4816
4817 if (i)
4818 token_end = i + 1;
4819
4820 while (i && (member (t[i], " \n\t;|&") == 0))
4821 i--;
4822
4823 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4824 i++;
4825
4826 /* Print the offending token. */
4827 if (token_end || (i == 0 && token_end == 0))
4828 {
4829 if (token_end)
4830 {
4831 msg = xmalloc (1 + (token_end - i));
4832 strncpy (msg, t + i, token_end - i);
4833 msg[token_end - i] = '\0';
4834 }
4835 else /* one-character token */
4836 {
4837 msg2[0] = t[i];
4838 msg2[1] = '\0';
4839 msg = msg2;
4840 }
4841
4842 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4843
4844 if (msg != msg2)
4845 free (msg);
4846 }
4847
4848 /* If not interactive, print the line containing the error. */
4849 if (interactive == 0)
4850 {
4851 msg = savestring (shell_input_line);
4852 token_end = strlen (msg);
4853 while (token_end && msg[token_end - 1] == '\n')
4854 msg[--token_end] = '\0';
4855
4856 parser_error (line_number, "`%s'", msg);
4857 free (msg);
4858 }
4859 }
4860 else
4861 {
4862 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
4863 parser_error (line_number, "%s", msg);
4864 /* When the shell is interactive, this file uses EOF_Reached
4865 only for error reporting. Other mechanisms are used to
4866 decide whether or not to exit. */
4867 if (interactive && EOF_Reached)
4868 EOF_Reached = 0;
4869 }
4870 last_command_exit_value = EX_USAGE;
4871 }
4872
4873 /* ??? Needed function. ??? We have to be able to discard the constructs
4874 created during parsing. In the case of error, we want to return
4875 allocated objects to the memory pool. In the case of no error, we want
4876 to throw away the information about where the allocated objects live.
4877 (dispose_command () will actually free the command. */
4878 static void
4879 discard_parser_constructs (error_p)
4880 int error_p;
4881 {
4882 }
4883
4884 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4885
4886 /* A flag denoting whether or not ignoreeof is set. */
4887 int ignoreeof = 0;
4888
4889 /* The number of times that we have encountered an EOF character without
4890 another character intervening. When this gets above the limit, the
4891 shell terminates. */
4892 int eof_encountered = 0;
4893
4894 /* The limit for eof_encountered. */
4895 int eof_encountered_limit = 10;
4896
4897 /* If we have EOF as the only input unit, this user wants to leave
4898 the shell. If the shell is not interactive, then just leave.
4899 Otherwise, if ignoreeof is set, and we haven't done this the
4900 required number of times in a row, print a message. */
4901 static void
4902 handle_eof_input_unit ()
4903 {
4904 if (interactive)
4905 {
4906 /* shell.c may use this to decide whether or not to write out the
4907 history, among other things. We use it only for error reporting
4908 in this file. */
4909 if (EOF_Reached)
4910 EOF_Reached = 0;
4911
4912 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4913 if (ignoreeof)
4914 {
4915 if (eof_encountered < eof_encountered_limit)
4916 {
4917 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4918 login_shell ? "logout" : "exit");
4919 eof_encountered++;
4920 /* Reset the prompt string to be $PS1. */
4921 prompt_string_pointer = (char **)NULL;
4922 prompt_again ();
4923 last_read_token = current_token = '\n';
4924 return;
4925 }
4926 }
4927
4928 /* In this case EOF should exit the shell. Do it now. */
4929 reset_parser ();
4930 exit_builtin ((WORD_LIST *)NULL);
4931 }
4932 else
4933 {
4934 /* We don't write history files, etc., for non-interactive shells. */
4935 EOF_Reached = 1;
4936 }
4937 }