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