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