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