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