]>
Commit | Line | Data |
---|---|---|
ccc6cda3 JA |
1 | /* make_cmd.c -- Functions for making instances of the various |
2 | parser constructs. */ | |
726f6388 | 3 | |
3185942a | 4 | /* Copyright (C) 1989-2009 Free Software Foundation, Inc. |
726f6388 | 5 | |
3185942a | 6 | This file is part of GNU Bash, the Bourne Again SHell. |
726f6388 | 7 | |
3185942a JA |
8 | Bash is free software: you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation, either version 3 of the License, or | |
11 | (at your option) any later version. | |
726f6388 | 12 | |
3185942a JA |
13 | Bash is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
726f6388 | 17 | |
3185942a JA |
18 | You should have received a copy of the GNU General Public License |
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | |
20 | */ | |
726f6388 | 21 | |
ccc6cda3 JA |
22 | #include "config.h" |
23 | ||
726f6388 JA |
24 | #include <stdio.h> |
25 | #include "bashtypes.h" | |
b80f6443 | 26 | #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) |
cce855bc JA |
27 | # include <sys/file.h> |
28 | #endif | |
726f6388 JA |
29 | #include "filecntl.h" |
30 | #include "bashansi.h" | |
ccc6cda3 JA |
31 | #if defined (HAVE_UNISTD_H) |
32 | # include <unistd.h> | |
33 | #endif | |
34 | ||
b80f6443 JA |
35 | #include "bashintl.h" |
36 | ||
0001803f | 37 | #include "parser.h" |
28ef6c31 | 38 | #include "syntax.h" |
726f6388 JA |
39 | #include "command.h" |
40 | #include "general.h" | |
41 | #include "error.h" | |
42 | #include "flags.h" | |
43 | #include "make_cmd.h" | |
7117c2d2 | 44 | #include "dispose_cmd.h" |
ccc6cda3 | 45 | #include "variables.h" |
726f6388 JA |
46 | #include "subst.h" |
47 | #include "input.h" | |
7117c2d2 | 48 | #include "ocache.h" |
726f6388 JA |
49 | #include "externs.h" |
50 | ||
51 | #if defined (JOB_CONTROL) | |
52 | #include "jobs.h" | |
53 | #endif | |
54 | ||
7117c2d2 JA |
55 | #include "shmbutil.h" |
56 | ||
0001803f | 57 | extern int line_number, current_command_line_count, parser_state; |
bb70624e JA |
58 | extern int last_command_exit_value; |
59 | ||
7117c2d2 JA |
60 | /* Object caching */ |
61 | sh_obj_cache_t wdcache = {0, 0, 0}; | |
62 | sh_obj_cache_t wlcache = {0, 0, 0}; | |
63 | ||
64 | #define WDCACHESIZE 60 | |
65 | #define WLCACHESIZE 60 | |
66 | ||
b80f6443 | 67 | static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int)); |
f73dda09 JA |
68 | #if defined (ARITH_FOR_COMMAND) |
69 | static WORD_LIST *make_arith_for_expr __P((char *)); | |
70 | #endif | |
71 | static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *)); | |
726f6388 | 72 | |
7117c2d2 JA |
73 | void |
74 | cmd_init () | |
75 | { | |
76 | ocache_create (wdcache, WORD_DESC, WDCACHESIZE); | |
77 | ocache_create (wlcache, WORD_LIST, WLCACHESIZE); | |
78 | } | |
79 | ||
95732b49 JA |
80 | WORD_DESC * |
81 | alloc_word_desc () | |
82 | { | |
83 | WORD_DESC *temp; | |
84 | ||
85 | ocache_alloc (wdcache, WORD_DESC, temp); | |
86 | temp->flags = 0; | |
87 | temp->word = 0; | |
88 | return temp; | |
89 | } | |
90 | ||
726f6388 | 91 | WORD_DESC * |
ccc6cda3 | 92 | make_bare_word (string) |
f73dda09 | 93 | const char *string; |
726f6388 JA |
94 | { |
95 | WORD_DESC *temp; | |
95732b49 JA |
96 | |
97 | temp = alloc_word_desc (); | |
7117c2d2 | 98 | |
ccc6cda3 JA |
99 | if (*string) |
100 | temp->word = savestring (string); | |
101 | else | |
726f6388 | 102 | { |
f73dda09 | 103 | temp->word = (char *)xmalloc (1); |
ccc6cda3 | 104 | temp->word[0] = '\0'; |
726f6388 | 105 | } |
ccc6cda3 | 106 | |
726f6388 JA |
107 | return (temp); |
108 | } | |
109 | ||
ccc6cda3 JA |
110 | WORD_DESC * |
111 | make_word_flags (w, string) | |
112 | WORD_DESC *w; | |
f73dda09 | 113 | const char *string; |
ccc6cda3 | 114 | { |
7117c2d2 JA |
115 | register int i; |
116 | size_t slen; | |
117 | DECLARE_MBSTATE; | |
ccc6cda3 | 118 | |
7117c2d2 JA |
119 | i = 0; |
120 | slen = strlen (string); | |
121 | while (i < slen) | |
122 | { | |
123 | switch (string[i]) | |
124 | { | |
ccc6cda3 JA |
125 | case '$': |
126 | w->flags |= W_HASDOLLAR; | |
127 | break; | |
128 | case '\\': | |
129 | break; /* continue the loop */ | |
130 | case '\'': | |
131 | case '`': | |
132 | case '"': | |
133 | w->flags |= W_QUOTED; | |
134 | break; | |
7117c2d2 JA |
135 | } |
136 | ||
137 | ADVANCE_CHAR (string, slen, i); | |
138 | } | |
139 | ||
ccc6cda3 JA |
140 | return (w); |
141 | } | |
142 | ||
143 | WORD_DESC * | |
144 | make_word (string) | |
f73dda09 | 145 | const char *string; |
ccc6cda3 JA |
146 | { |
147 | WORD_DESC *temp; | |
148 | ||
149 | temp = make_bare_word (string); | |
150 | return (make_word_flags (temp, string)); | |
151 | } | |
152 | ||
726f6388 JA |
153 | WORD_DESC * |
154 | make_word_from_token (token) | |
155 | int token; | |
156 | { | |
157 | char tokenizer[2]; | |
158 | ||
159 | tokenizer[0] = token; | |
160 | tokenizer[1] = '\0'; | |
161 | ||
162 | return (make_word (tokenizer)); | |
163 | } | |
164 | ||
165 | WORD_LIST * | |
f73dda09 | 166 | make_word_list (word, wlink) |
726f6388 | 167 | WORD_DESC *word; |
f73dda09 | 168 | WORD_LIST *wlink; |
726f6388 JA |
169 | { |
170 | WORD_LIST *temp; | |
171 | ||
7117c2d2 | 172 | ocache_alloc (wlcache, WORD_LIST, temp); |
95732b49 | 173 | |
726f6388 | 174 | temp->word = word; |
f73dda09 | 175 | temp->next = wlink; |
726f6388 JA |
176 | return (temp); |
177 | } | |
178 | ||
726f6388 JA |
179 | COMMAND * |
180 | make_command (type, pointer) | |
181 | enum command_type type; | |
182 | SIMPLE_COM *pointer; | |
183 | { | |
184 | COMMAND *temp; | |
185 | ||
186 | temp = (COMMAND *)xmalloc (sizeof (COMMAND)); | |
187 | temp->type = type; | |
188 | temp->value.Simple = pointer; | |
ccc6cda3 | 189 | temp->value.Simple->flags = temp->flags = 0; |
726f6388 JA |
190 | temp->redirects = (REDIRECT *)NULL; |
191 | return (temp); | |
192 | } | |
193 | ||
194 | COMMAND * | |
195 | command_connect (com1, com2, connector) | |
196 | COMMAND *com1, *com2; | |
197 | int connector; | |
198 | { | |
199 | CONNECTION *temp; | |
200 | ||
201 | temp = (CONNECTION *)xmalloc (sizeof (CONNECTION)); | |
202 | temp->connector = connector; | |
203 | temp->first = com1; | |
204 | temp->second = com2; | |
205 | return (make_command (cm_connection, (SIMPLE_COM *)temp)); | |
206 | } | |
207 | ||
ccc6cda3 | 208 | static COMMAND * |
b80f6443 | 209 | make_for_or_select (type, name, map_list, action, lineno) |
ccc6cda3 | 210 | enum command_type type; |
726f6388 JA |
211 | WORD_DESC *name; |
212 | WORD_LIST *map_list; | |
213 | COMMAND *action; | |
b80f6443 | 214 | int lineno; |
726f6388 | 215 | { |
ccc6cda3 | 216 | FOR_COM *temp; |
726f6388 | 217 | |
ccc6cda3 | 218 | temp = (FOR_COM *)xmalloc (sizeof (FOR_COM)); |
726f6388 JA |
219 | temp->flags = 0; |
220 | temp->name = name; | |
b80f6443 | 221 | temp->line = lineno; |
726f6388 JA |
222 | temp->map_list = map_list; |
223 | temp->action = action; | |
ccc6cda3 | 224 | return (make_command (type, (SIMPLE_COM *)temp)); |
726f6388 JA |
225 | } |
226 | ||
726f6388 | 227 | COMMAND * |
b80f6443 | 228 | make_for_command (name, map_list, action, lineno) |
726f6388 JA |
229 | WORD_DESC *name; |
230 | WORD_LIST *map_list; | |
231 | COMMAND *action; | |
b80f6443 | 232 | int lineno; |
726f6388 | 233 | { |
b80f6443 | 234 | return (make_for_or_select (cm_for, name, map_list, action, lineno)); |
726f6388 | 235 | } |
ccc6cda3 JA |
236 | |
237 | COMMAND * | |
b80f6443 | 238 | make_select_command (name, map_list, action, lineno) |
ccc6cda3 JA |
239 | WORD_DESC *name; |
240 | WORD_LIST *map_list; | |
241 | COMMAND *action; | |
b80f6443 | 242 | int lineno; |
ccc6cda3 JA |
243 | { |
244 | #if defined (SELECT_COMMAND) | |
b80f6443 | 245 | return (make_for_or_select (cm_select, name, map_list, action, lineno)); |
bb70624e JA |
246 | #else |
247 | last_command_exit_value = 2; | |
248 | return ((COMMAND *)NULL); | |
726f6388 | 249 | #endif |
ccc6cda3 | 250 | } |
726f6388 | 251 | |
bb70624e JA |
252 | #if defined (ARITH_FOR_COMMAND) |
253 | static WORD_LIST * | |
254 | make_arith_for_expr (s) | |
255 | char *s; | |
256 | { | |
257 | WORD_LIST *result; | |
b80f6443 | 258 | WORD_DESC *wd; |
bb70624e JA |
259 | |
260 | if (s == 0 || *s == '\0') | |
261 | return ((WORD_LIST *)NULL); | |
b80f6443 | 262 | wd = make_word (s); |
95732b49 | 263 | wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */ |
b80f6443 | 264 | result = make_word_list (wd, (WORD_LIST *)NULL); |
bb70624e JA |
265 | return result; |
266 | } | |
267 | #endif | |
268 | ||
b80f6443 JA |
269 | /* Note that this function calls dispose_words on EXPRS, since it doesn't |
270 | use the word list directly. We free it here rather than at the caller | |
271 | because no other function in this file requires that the caller free | |
272 | any arguments. */ | |
bb70624e JA |
273 | COMMAND * |
274 | make_arith_for_command (exprs, action, lineno) | |
275 | WORD_LIST *exprs; | |
276 | COMMAND *action; | |
277 | int lineno; | |
278 | { | |
279 | #if defined (ARITH_FOR_COMMAND) | |
280 | ARITH_FOR_COM *temp; | |
281 | WORD_LIST *init, *test, *step; | |
282 | char *s, *t, *start; | |
ac50fbac | 283 | int nsemi, i; |
bb70624e JA |
284 | |
285 | init = test = step = (WORD_LIST *)NULL; | |
286 | /* Parse the string into the three component sub-expressions. */ | |
287 | start = t = s = exprs->word->word; | |
288 | for (nsemi = 0; ;) | |
289 | { | |
290 | /* skip whitespace at the start of each sub-expression. */ | |
291 | while (whitespace (*s)) | |
292 | s++; | |
293 | start = s; | |
294 | /* skip to the semicolon or EOS */ | |
ac50fbac CR |
295 | i = skip_to_delim (start, 0, ";", SD_NOJMP); |
296 | s = start + i; | |
bb70624e | 297 | |
ac50fbac | 298 | t = (i > 0) ? substring (start, 0, i) : (char *)NULL; |
bb70624e JA |
299 | |
300 | nsemi++; | |
301 | switch (nsemi) | |
302 | { | |
303 | case 1: | |
304 | init = make_arith_for_expr (t); | |
305 | break; | |
306 | case 2: | |
307 | test = make_arith_for_expr (t); | |
308 | break; | |
309 | case 3: | |
310 | step = make_arith_for_expr (t); | |
311 | break; | |
312 | } | |
313 | ||
314 | FREE (t); | |
315 | if (*s == '\0') | |
28ef6c31 | 316 | break; |
bb70624e JA |
317 | s++; /* skip over semicolon */ |
318 | } | |
319 | ||
320 | if (nsemi != 3) | |
321 | { | |
322 | if (nsemi < 3) | |
b80f6443 | 323 | parser_error (lineno, _("syntax error: arithmetic expression required")); |
bb70624e | 324 | else |
b80f6443 JA |
325 | parser_error (lineno, _("syntax error: `;' unexpected")); |
326 | parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word); | |
ac50fbac CR |
327 | free (init); |
328 | free (test); | |
329 | free (step); | |
bb70624e JA |
330 | last_command_exit_value = 2; |
331 | return ((COMMAND *)NULL); | |
332 | } | |
333 | ||
334 | temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM)); | |
335 | temp->flags = 0; | |
336 | temp->line = lineno; | |
337 | temp->init = init ? init : make_arith_for_expr ("1"); | |
338 | temp->test = test ? test : make_arith_for_expr ("1"); | |
339 | temp->step = step ? step : make_arith_for_expr ("1"); | |
340 | temp->action = action; | |
341 | ||
b80f6443 | 342 | dispose_words (exprs); |
bb70624e JA |
343 | return (make_command (cm_arith_for, (SIMPLE_COM *)temp)); |
344 | #else | |
b80f6443 | 345 | dispose_words (exprs); |
bb70624e JA |
346 | last_command_exit_value = 2; |
347 | return ((COMMAND *)NULL); | |
348 | #endif /* ARITH_FOR_COMMAND */ | |
349 | } | |
350 | ||
726f6388 JA |
351 | COMMAND * |
352 | make_group_command (command) | |
353 | COMMAND *command; | |
354 | { | |
ccc6cda3 | 355 | GROUP_COM *temp; |
726f6388 | 356 | |
ccc6cda3 | 357 | temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM)); |
726f6388 JA |
358 | temp->command = command; |
359 | return (make_command (cm_group, (SIMPLE_COM *)temp)); | |
360 | } | |
361 | ||
362 | COMMAND * | |
b80f6443 | 363 | make_case_command (word, clauses, lineno) |
726f6388 JA |
364 | WORD_DESC *word; |
365 | PATTERN_LIST *clauses; | |
95732b49 | 366 | int lineno; |
726f6388 JA |
367 | { |
368 | CASE_COM *temp; | |
369 | ||
370 | temp = (CASE_COM *)xmalloc (sizeof (CASE_COM)); | |
371 | temp->flags = 0; | |
b80f6443 | 372 | temp->line = lineno; |
726f6388 JA |
373 | temp->word = word; |
374 | temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *); | |
375 | return (make_command (cm_case, (SIMPLE_COM *)temp)); | |
376 | } | |
377 | ||
378 | PATTERN_LIST * | |
379 | make_pattern_list (patterns, action) | |
380 | WORD_LIST *patterns; | |
381 | COMMAND *action; | |
382 | { | |
383 | PATTERN_LIST *temp; | |
384 | ||
385 | temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST)); | |
386 | temp->patterns = REVERSE_LIST (patterns, WORD_LIST *); | |
387 | temp->action = action; | |
388 | temp->next = NULL; | |
95732b49 | 389 | temp->flags = 0; |
726f6388 JA |
390 | return (temp); |
391 | } | |
392 | ||
393 | COMMAND * | |
394 | make_if_command (test, true_case, false_case) | |
395 | COMMAND *test, *true_case, *false_case; | |
396 | { | |
397 | IF_COM *temp; | |
398 | ||
399 | temp = (IF_COM *)xmalloc (sizeof (IF_COM)); | |
400 | temp->flags = 0; | |
401 | temp->test = test; | |
402 | temp->true_case = true_case; | |
403 | temp->false_case = false_case; | |
404 | return (make_command (cm_if, (SIMPLE_COM *)temp)); | |
405 | } | |
406 | ||
407 | static COMMAND * | |
ccc6cda3 | 408 | make_until_or_while (which, test, action) |
726f6388 | 409 | enum command_type which; |
ccc6cda3 | 410 | COMMAND *test, *action; |
726f6388 JA |
411 | { |
412 | WHILE_COM *temp; | |
413 | ||
414 | temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM)); | |
415 | temp->flags = 0; | |
416 | temp->test = test; | |
417 | temp->action = action; | |
418 | return (make_command (which, (SIMPLE_COM *)temp)); | |
419 | } | |
420 | ||
421 | COMMAND * | |
422 | make_while_command (test, action) | |
423 | COMMAND *test, *action; | |
424 | { | |
ccc6cda3 | 425 | return (make_until_or_while (cm_while, test, action)); |
726f6388 JA |
426 | } |
427 | ||
428 | COMMAND * | |
429 | make_until_command (test, action) | |
430 | COMMAND *test, *action; | |
431 | { | |
ccc6cda3 | 432 | return (make_until_or_while (cm_until, test, action)); |
726f6388 JA |
433 | } |
434 | ||
cce855bc JA |
435 | COMMAND * |
436 | make_arith_command (exp) | |
437 | WORD_LIST *exp; | |
438 | { | |
439 | #if defined (DPAREN_ARITHMETIC) | |
440 | COMMAND *command; | |
441 | ARITH_COM *temp; | |
442 | ||
443 | command = (COMMAND *)xmalloc (sizeof (COMMAND)); | |
444 | command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM)); | |
445 | ||
446 | temp->flags = 0; | |
447 | temp->line = line_number; | |
448 | temp->exp = exp; | |
449 | ||
450 | command->type = cm_arith; | |
451 | command->redirects = (REDIRECT *)NULL; | |
452 | command->flags = 0; | |
453 | ||
454 | return (command); | |
455 | #else | |
bb70624e | 456 | last_command_exit_value = 2; |
cce855bc JA |
457 | return ((COMMAND *)NULL); |
458 | #endif | |
459 | } | |
460 | ||
461 | #if defined (COND_COMMAND) | |
462 | struct cond_com * | |
463 | make_cond_node (type, op, left, right) | |
464 | int type; | |
465 | WORD_DESC *op; | |
466 | struct cond_com *left, *right; | |
467 | { | |
468 | COND_COM *temp; | |
469 | ||
470 | temp = (COND_COM *)xmalloc (sizeof (COND_COM)); | |
471 | temp->flags = 0; | |
472 | temp->line = line_number; | |
473 | temp->type = type; | |
474 | temp->op = op; | |
475 | temp->left = left; | |
476 | temp->right = right; | |
477 | ||
478 | return (temp); | |
479 | } | |
480 | #endif | |
481 | ||
482 | COMMAND * | |
483 | make_cond_command (cond_node) | |
484 | COND_COM *cond_node; | |
485 | { | |
486 | #if defined (COND_COMMAND) | |
487 | COMMAND *command; | |
488 | ||
489 | command = (COMMAND *)xmalloc (sizeof (COMMAND)); | |
490 | command->value.Cond = cond_node; | |
491 | ||
492 | command->type = cm_cond; | |
493 | command->redirects = (REDIRECT *)NULL; | |
494 | command->flags = 0; | |
b72432fd | 495 | command->line = cond_node ? cond_node->line : 0; |
cce855bc JA |
496 | |
497 | return (command); | |
498 | #else | |
bb70624e | 499 | last_command_exit_value = 2; |
cce855bc JA |
500 | return ((COMMAND *)NULL); |
501 | #endif | |
502 | } | |
503 | ||
726f6388 JA |
504 | COMMAND * |
505 | make_bare_simple_command () | |
506 | { | |
507 | COMMAND *command; | |
ccc6cda3 JA |
508 | SIMPLE_COM *temp; |
509 | ||
510 | command = (COMMAND *)xmalloc (sizeof (COMMAND)); | |
511 | command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM)); | |
726f6388 JA |
512 | |
513 | temp->flags = 0; | |
514 | temp->line = line_number; | |
515 | temp->words = (WORD_LIST *)NULL; | |
516 | temp->redirects = (REDIRECT *)NULL; | |
ccc6cda3 | 517 | |
726f6388 JA |
518 | command->type = cm_simple; |
519 | command->redirects = (REDIRECT *)NULL; | |
520 | command->flags = 0; | |
ccc6cda3 | 521 | |
726f6388 JA |
522 | return (command); |
523 | } | |
524 | ||
525 | /* Return a command which is the connection of the word or redirection | |
526 | in ELEMENT, and the command * or NULL in COMMAND. */ | |
527 | COMMAND * | |
528 | make_simple_command (element, command) | |
529 | ELEMENT element; | |
530 | COMMAND *command; | |
531 | { | |
532 | /* If we are starting from scratch, then make the initial command | |
533 | structure. Also note that we have to fill in all the slots, since | |
534 | malloc doesn't return zeroed space. */ | |
0001803f CR |
535 | if (command == 0) |
536 | { | |
537 | command = make_bare_simple_command (); | |
538 | parser_state |= PST_REDIRLIST; | |
539 | } | |
ccc6cda3 | 540 | |
726f6388 | 541 | if (element.word) |
0001803f CR |
542 | { |
543 | command->value.Simple->words = make_word_list (element.word, command->value.Simple->words); | |
544 | parser_state &= ~PST_REDIRLIST; | |
545 | } | |
b80f6443 | 546 | else if (element.redirect) |
726f6388 JA |
547 | { |
548 | REDIRECT *r = element.redirect; | |
549 | /* Due to the way <> is implemented, there may be more than a single | |
550 | redirection in element.redirect. We just follow the chain as far | |
551 | as it goes, and hook onto the end. */ | |
552 | while (r->next) | |
553 | r = r->next; | |
554 | r->next = command->value.Simple->redirects; | |
555 | command->value.Simple->redirects = element.redirect; | |
556 | } | |
0001803f | 557 | |
726f6388 JA |
558 | return (command); |
559 | } | |
560 | ||
ccc6cda3 JA |
561 | /* Because we are Bourne compatible, we read the input for this |
562 | << or <<- redirection now, from wherever input is coming from. | |
563 | We store the input read into a WORD_DESC. Replace the text of | |
564 | the redirectee.word with the new input text. If <<- is on, | |
565 | then remove leading TABS from each line. */ | |
726f6388 | 566 | void |
3185942a | 567 | make_here_document (temp, lineno) |
726f6388 | 568 | REDIRECT *temp; |
3185942a | 569 | int lineno; |
726f6388 | 570 | { |
ccc6cda3 JA |
571 | int kill_leading, redir_len; |
572 | char *redir_word, *document, *full_line; | |
573 | int document_index, document_size, delim_unquoted; | |
574 | ||
575 | if (temp->instruction != r_deblank_reading_until && | |
576 | temp->instruction != r_reading_until) | |
577 | { | |
b80f6443 | 578 | internal_error (_("make_here_document: bad instruction type %d"), temp->instruction); |
ccc6cda3 JA |
579 | return; |
580 | } | |
581 | ||
582 | kill_leading = temp->instruction == r_deblank_reading_until; | |
583 | ||
584 | document = (char *)NULL; | |
585 | document_index = document_size = 0; | |
586 | ||
587 | /* Quote removal is the only expansion performed on the delimiter | |
588 | for here documents, making it an extremely special case. */ | |
589 | redir_word = string_quote_removal (temp->redirectee.filename->word, 0); | |
590 | ||
591 | /* redirection_expand will return NULL if the expansion results in | |
592 | multiple words or no words. Check for that here, and just abort | |
593 | this here document if it does. */ | |
594 | if (redir_word) | |
595 | redir_len = strlen (redir_word); | |
596 | else | |
597 | { | |
f73dda09 | 598 | temp->here_doc_eof = (char *)xmalloc (1); |
ccc6cda3 JA |
599 | temp->here_doc_eof[0] = '\0'; |
600 | goto document_done; | |
601 | } | |
726f6388 | 602 | |
ccc6cda3 JA |
603 | free (temp->redirectee.filename->word); |
604 | temp->here_doc_eof = redir_word; | |
605 | ||
606 | /* Read lines from wherever lines are coming from. | |
607 | For each line read, if kill_leading, then kill the | |
608 | leading tab characters. | |
609 | If the line matches redir_word exactly, then we have | |
610 | manufactured the document. Otherwise, add the line to the | |
611 | list of lines in the document. */ | |
612 | ||
613 | /* If the here-document delimiter was quoted, the lines should | |
614 | be read verbatim from the input. If it was not quoted, we | |
615 | need to perform backslash-quoted newline removal. */ | |
616 | delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0; | |
617 | while (full_line = read_secondary_line (delim_unquoted)) | |
726f6388 | 618 | { |
ccc6cda3 JA |
619 | register char *line; |
620 | int len; | |
621 | ||
622 | line = full_line; | |
623 | line_number++; | |
624 | ||
0628567a JA |
625 | /* If set -v is in effect, echo the line read. read_secondary_line/ |
626 | read_a_line leaves the newline at the end, so don't print another. */ | |
627 | if (echo_input_at_read) | |
628 | fprintf (stderr, "%s", line); | |
629 | ||
ccc6cda3 | 630 | if (kill_leading && *line) |
28ef6c31 | 631 | { |
ccc6cda3 JA |
632 | /* Hack: To be compatible with some Bourne shells, we |
633 | check the word before stripping the whitespace. This | |
634 | is a hack, though. */ | |
635 | if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n') | |
636 | goto document_done; | |
637 | ||
638 | while (*line == '\t') | |
639 | line++; | |
640 | } | |
641 | ||
642 | if (*line == 0) | |
28ef6c31 | 643 | continue; |
ccc6cda3 JA |
644 | |
645 | if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n') | |
646 | goto document_done; | |
647 | ||
648 | len = strlen (line); | |
649 | if (len + document_index >= document_size) | |
726f6388 | 650 | { |
bc4cd23c | 651 | document_size = document_size ? 2 * (document_size + len) : len + 2; |
f73dda09 | 652 | document = (char *)xrealloc (document, document_size); |
726f6388 | 653 | } |
ccc6cda3 JA |
654 | |
655 | /* len is guaranteed to be > 0 because of the check for line | |
656 | being an empty string before the call to strlen. */ | |
657 | FASTCOPY (line, document + document_index, len); | |
658 | document_index += len; | |
659 | } | |
660 | ||
3185942a JA |
661 | if (full_line == 0) |
662 | internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word); | |
663 | ||
ccc6cda3 JA |
664 | document_done: |
665 | if (document) | |
666 | document[document_index] = '\0'; | |
667 | else | |
668 | { | |
f73dda09 | 669 | document = (char *)xmalloc (1); |
ccc6cda3 | 670 | document[0] = '\0'; |
726f6388 | 671 | } |
ccc6cda3 | 672 | temp->redirectee.filename->word = document; |
726f6388 | 673 | } |
ccc6cda3 JA |
674 | |
675 | /* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION. | |
726f6388 JA |
676 | INSTRUCTION is the instruction type, SOURCE is a file descriptor, |
677 | and DEST is a file descriptor or a WORD_DESC *. */ | |
678 | REDIRECT * | |
0001803f CR |
679 | make_redirection (source, instruction, dest_and_filename, flags) |
680 | REDIRECTEE source; | |
726f6388 JA |
681 | enum r_instruction instruction; |
682 | REDIRECTEE dest_and_filename; | |
0001803f | 683 | int flags; |
726f6388 | 684 | { |
7117c2d2 JA |
685 | REDIRECT *temp; |
686 | WORD_DESC *w; | |
687 | int wlen; | |
688 | intmax_t lfd; | |
689 | ||
690 | temp = (REDIRECT *)xmalloc (sizeof (REDIRECT)); | |
726f6388 JA |
691 | |
692 | /* First do the common cases. */ | |
693 | temp->redirector = source; | |
694 | temp->redirectee = dest_and_filename; | |
695 | temp->instruction = instruction; | |
696 | temp->flags = 0; | |
0001803f | 697 | temp->rflags = flags; |
726f6388 JA |
698 | temp->next = (REDIRECT *)NULL; |
699 | ||
700 | switch (instruction) | |
701 | { | |
702 | ||
d166f048 JA |
703 | case r_output_direction: /* >foo */ |
704 | case r_output_force: /* >| foo */ | |
3185942a | 705 | case r_err_and_out: /* &>filename */ |
726f6388 JA |
706 | temp->flags = O_TRUNC | O_WRONLY | O_CREAT; |
707 | break; | |
708 | ||
d166f048 | 709 | case r_appending_to: /* >>foo */ |
3185942a | 710 | case r_append_err_and_out: /* &>> filename */ |
d166f048 | 711 | temp->flags = O_APPEND | O_WRONLY | O_CREAT; |
726f6388 JA |
712 | break; |
713 | ||
d166f048 JA |
714 | case r_input_direction: /* <foo */ |
715 | case r_inputa_direction: /* foo & makes this. */ | |
716 | temp->flags = O_RDONLY; | |
726f6388 JA |
717 | break; |
718 | ||
d166f048 JA |
719 | case r_input_output: /* <>foo */ |
720 | temp->flags = O_RDWR | O_CREAT; | |
726f6388 JA |
721 | break; |
722 | ||
d166f048 JA |
723 | case r_deblank_reading_until: /* <<-foo */ |
724 | case r_reading_until: /* << foo */ | |
7117c2d2 | 725 | case r_reading_string: /* <<< foo */ |
ccc6cda3 | 726 | case r_close_this: /* <&- */ |
726f6388 JA |
727 | case r_duplicating_input: /* 1<&2 */ |
728 | case r_duplicating_output: /* 1>&2 */ | |
7117c2d2 JA |
729 | break; |
730 | ||
731 | /* the parser doesn't pass these. */ | |
732 | case r_move_input: /* 1<&2- */ | |
733 | case r_move_output: /* 1>&2- */ | |
734 | case r_move_input_word: /* 1<&$foo- */ | |
735 | case r_move_output_word: /* 1>&$foo- */ | |
736 | break; | |
737 | ||
738 | /* The way the lexer works we have to do this here. */ | |
726f6388 JA |
739 | case r_duplicating_input_word: /* 1<&$foo */ |
740 | case r_duplicating_output_word: /* 1>&$foo */ | |
7117c2d2 JA |
741 | w = dest_and_filename.filename; |
742 | wlen = strlen (w->word) - 1; | |
743 | if (w->word[wlen] == '-') /* Yuck */ | |
744 | { | |
745 | w->word[wlen] = '\0'; | |
746 | if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd) | |
747 | { | |
748 | dispose_word (w); | |
749 | temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output; | |
750 | temp->redirectee.dest = lfd; | |
751 | } | |
752 | else | |
753 | temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word; | |
754 | } | |
755 | ||
726f6388 | 756 | break; |
ccc6cda3 | 757 | |
726f6388 | 758 | default: |
b80f6443 | 759 | programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction); |
726f6388 JA |
760 | abort (); |
761 | break; | |
762 | } | |
763 | return (temp); | |
764 | } | |
765 | ||
766 | COMMAND * | |
ccc6cda3 | 767 | make_function_def (name, command, lineno, lstart) |
726f6388 JA |
768 | WORD_DESC *name; |
769 | COMMAND *command; | |
ccc6cda3 | 770 | int lineno, lstart; |
726f6388 JA |
771 | { |
772 | FUNCTION_DEF *temp; | |
b80f6443 JA |
773 | #if defined (ARRAY_VARS) |
774 | SHELL_VAR *bash_source_v; | |
775 | ARRAY *bash_source_a; | |
b80f6443 | 776 | #endif |
726f6388 JA |
777 | |
778 | temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF)); | |
779 | temp->command = command; | |
780 | temp->name = name; | |
ccc6cda3 | 781 | temp->line = lineno; |
cce855bc | 782 | temp->flags = 0; |
ccc6cda3 | 783 | command->line = lstart; |
b80f6443 JA |
784 | |
785 | /* Information used primarily for debugging. */ | |
786 | temp->source_file = 0; | |
787 | #if defined (ARRAY_VARS) | |
788 | GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); | |
789 | if (bash_source_a && array_num_elements (bash_source_a) > 0) | |
790 | temp->source_file = array_reference (bash_source_a, 0); | |
791 | #endif | |
3185942a | 792 | #if defined (DEBUGGER) |
b80f6443 | 793 | bind_function_def (name->word, temp); |
3185942a | 794 | #endif |
b80f6443 | 795 | |
ac50fbac | 796 | temp->source_file = temp->source_file ? savestring (temp->source_file) : 0; |
726f6388 JA |
797 | return (make_command (cm_function_def, (SIMPLE_COM *)temp)); |
798 | } | |
799 | ||
bb70624e JA |
800 | COMMAND * |
801 | make_subshell_command (command) | |
802 | COMMAND *command; | |
803 | { | |
804 | SUBSHELL_COM *temp; | |
805 | ||
806 | temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM)); | |
807 | temp->command = command; | |
808 | temp->flags = CMD_WANT_SUBSHELL; | |
809 | return (make_command (cm_subshell, (SIMPLE_COM *)temp)); | |
810 | } | |
811 | ||
3185942a JA |
812 | COMMAND * |
813 | make_coproc_command (name, command) | |
814 | char *name; | |
815 | COMMAND *command; | |
816 | { | |
817 | COPROC_COM *temp; | |
818 | ||
819 | temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM)); | |
820 | temp->name = savestring (name); | |
821 | temp->command = command; | |
822 | temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; | |
823 | return (make_command (cm_coproc, (SIMPLE_COM *)temp)); | |
824 | } | |
825 | ||
726f6388 JA |
826 | /* Reverse the word list and redirection list in the simple command |
827 | has just been parsed. It seems simpler to do this here the one | |
828 | time then by any other method that I can think of. */ | |
829 | COMMAND * | |
830 | clean_simple_command (command) | |
831 | COMMAND *command; | |
832 | { | |
833 | if (command->type != cm_simple) | |
b72432fd | 834 | command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0); |
726f6388 JA |
835 | else |
836 | { | |
837 | command->value.Simple->words = | |
838 | REVERSE_LIST (command->value.Simple->words, WORD_LIST *); | |
ccc6cda3 | 839 | command->value.Simple->redirects = |
726f6388 JA |
840 | REVERSE_LIST (command->value.Simple->redirects, REDIRECT *); |
841 | } | |
842 | ||
0001803f | 843 | parser_state &= ~PST_REDIRLIST; |
726f6388 JA |
844 | return (command); |
845 | } | |
846 | ||
726f6388 JA |
847 | /* The Yacc grammar productions have a problem, in that they take a |
848 | list followed by an ampersand (`&') and do a simple command connection, | |
849 | making the entire list effectively asynchronous, instead of just | |
850 | the last command. This means that when the list is executed, all | |
851 | the commands have stdin set to /dev/null when job control is not | |
852 | active, instead of just the last. This is wrong, and needs fixing | |
853 | up. This function takes the `&' and applies it to the last command | |
854 | in the list. This is done only for lists connected by `;'; it makes | |
855 | `;' bind `tighter' than `&'. */ | |
856 | COMMAND * | |
857 | connect_async_list (command, command2, connector) | |
858 | COMMAND *command, *command2; | |
859 | int connector; | |
860 | { | |
861 | COMMAND *t, *t1, *t2; | |
862 | ||
863 | t1 = command; | |
864 | t = command->value.Connection->second; | |
865 | ||
866 | if (!t || (command->flags & CMD_WANT_SUBSHELL) || | |
867 | command->value.Connection->connector != ';') | |
868 | { | |
869 | t = command_connect (command, command2, connector); | |
870 | return t; | |
871 | } | |
872 | ||
873 | /* This is just defensive programming. The Yacc precedence rules | |
874 | will generally hand this function a command where t points directly | |
875 | to the command we want (e.g. given a ; b ; c ; d &, t1 will point | |
876 | to the `a ; b ; c' list and t will be the `d'). We only want to do | |
877 | this if the list is not being executed as a unit in the background | |
878 | with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's | |
879 | the only way to tell. */ | |
880 | while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection && | |
881 | t->value.Connection->connector == ';') | |
882 | { | |
883 | t1 = t; | |
884 | t = t->value.Connection->second; | |
885 | } | |
886 | /* Now we have t pointing to the last command in the list, and | |
887 | t1->value.Connection->second == t. */ | |
888 | t2 = command_connect (t, command2, connector); | |
889 | t1->value.Connection->second = t2; | |
890 | return command; | |
891 | } |