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