]> git.ipfire.org Git - thirdparty/bash.git/blame - copy_cmd.c
Imported from ../bash-4.0-rc1.tar.gz.
[thirdparty/bash.git] / copy_cmd.c
CommitLineData
726f6388
JA
1/* copy_command.c -- copy a COMMAND structure. This is needed
2 primarily for making function definitions, but I'm not sure
3 that anyone else will need it. */
4
3185942a 5/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
726f6388
JA
6
7 This file is part of GNU Bash, the Bourne Again SHell.
8
3185942a
JA
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
726f6388 13
3185942a
JA
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
726f6388
JA
18
19 You should have received a copy of the GNU General Public License
3185942a
JA
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21*/
726f6388 22
ccc6cda3
JA
23#include "config.h"
24
cce855bc 25#include "bashtypes.h"
726f6388 26
ccc6cda3
JA
27#if defined (HAVE_UNISTD_H)
28# include <unistd.h>
29#endif
30
cce855bc
JA
31#include <stdio.h>
32
726f6388
JA
33#include "shell.h"
34
f73dda09
JA
35static PATTERN_LIST *copy_case_clause __P((PATTERN_LIST *));
36static PATTERN_LIST *copy_case_clauses __P((PATTERN_LIST *));
37static FOR_COM *copy_for_command __P((FOR_COM *));
38#if defined (ARITH_FOR_COMMAND)
39static ARITH_FOR_COM *copy_arith_for_command __P((ARITH_FOR_COM *));
40#endif
41static GROUP_COM *copy_group_command __P((GROUP_COM *));
42static SUBSHELL_COM *copy_subshell_command __P((SUBSHELL_COM *));
3185942a 43static COPROC_COM *copy_coproc_command __P((COPROC_COM *));
f73dda09
JA
44static CASE_COM *copy_case_command __P((CASE_COM *));
45static WHILE_COM *copy_while_command __P((WHILE_COM *));
46static IF_COM *copy_if_command __P((IF_COM *));
47#if defined (DPAREN_ARITHMETIC)
48static ARITH_COM *copy_arith_command __P((ARITH_COM *));
49#endif
50#if defined (COND_COMMAND)
51static COND_COM *copy_cond_command __P((COND_COM *));
52#endif
53static SIMPLE_COM *copy_simple_command __P((SIMPLE_COM *));
f73dda09 54
726f6388 55WORD_DESC *
cce855bc
JA
56copy_word (w)
57 WORD_DESC *w;
726f6388 58{
ccc6cda3
JA
59 WORD_DESC *new_word;
60
7117c2d2 61 new_word = make_bare_word (w->word);
28ef6c31 62 new_word->flags = w->flags;
726f6388
JA
63 return (new_word);
64}
65
ccc6cda3 66/* Copy the chain of words in LIST. Return a pointer to
726f6388
JA
67 the new chain. */
68WORD_LIST *
69copy_word_list (list)
70 WORD_LIST *list;
71{
7117c2d2 72 WORD_LIST *new_list;
726f6388 73
ccc6cda3 74 for (new_list = (WORD_LIST *)NULL; list; list = list->next)
7117c2d2
JA
75 new_list = make_word_list (copy_word (list->word), new_list);
76
726f6388
JA
77 return (REVERSE_LIST (new_list, WORD_LIST *));
78}
79
80static PATTERN_LIST *
81copy_case_clause (clause)
82 PATTERN_LIST *clause;
83{
ccc6cda3
JA
84 PATTERN_LIST *new_clause;
85
86 new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
726f6388
JA
87 new_clause->patterns = copy_word_list (clause->patterns);
88 new_clause->action = copy_command (clause->action);
3185942a 89 new_clause->flags = clause->flags;
726f6388
JA
90 return (new_clause);
91}
92
93static PATTERN_LIST *
94copy_case_clauses (clauses)
95 PATTERN_LIST *clauses;
96{
ccc6cda3 97 PATTERN_LIST *new_list, *new_clause;
726f6388 98
ccc6cda3 99 for (new_list = (PATTERN_LIST *)NULL; clauses; clauses = clauses->next)
726f6388 100 {
ccc6cda3 101 new_clause = copy_case_clause (clauses);
726f6388
JA
102 new_clause->next = new_list;
103 new_list = new_clause;
726f6388
JA
104 }
105 return (REVERSE_LIST (new_list, PATTERN_LIST *));
106}
107
108/* Copy a single redirect. */
109REDIRECT *
110copy_redirect (redirect)
111 REDIRECT *redirect;
112{
ccc6cda3
JA
113 REDIRECT *new_redirect;
114
115 new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT));
726f6388
JA
116 FASTCOPY ((char *)redirect, (char *)new_redirect, (sizeof (REDIRECT)));
117 switch (redirect->instruction)
118 {
119 case r_reading_until:
120 case r_deblank_reading_until:
121 new_redirect->here_doc_eof = savestring (redirect->here_doc_eof);
ccc6cda3 122 /*FALLTHROUGH*/
7117c2d2 123 case r_reading_string:
726f6388
JA
124 case r_appending_to:
125 case r_output_direction:
126 case r_input_direction:
127 case r_inputa_direction:
128 case r_err_and_out:
3185942a 129 case r_append_err_and_out:
726f6388
JA
130 case r_input_output:
131 case r_output_force:
132 case r_duplicating_input_word:
133 case r_duplicating_output_word:
7117c2d2
JA
134 case r_move_input_word:
135 case r_move_output_word:
ccc6cda3 136 new_redirect->redirectee.filename = copy_word (redirect->redirectee.filename);
726f6388 137 break;
d166f048
JA
138 case r_duplicating_input:
139 case r_duplicating_output:
7117c2d2
JA
140 case r_move_input:
141 case r_move_output:
d166f048
JA
142 case r_close_this:
143 break;
726f6388
JA
144 }
145 return (new_redirect);
146}
ccc6cda3 147
726f6388
JA
148REDIRECT *
149copy_redirects (list)
150 REDIRECT *list;
151{
ccc6cda3 152 REDIRECT *new_list, *temp;
726f6388 153
ccc6cda3 154 for (new_list = (REDIRECT *)NULL; list; list = list->next)
726f6388 155 {
ccc6cda3 156 temp = copy_redirect (list);
726f6388
JA
157 temp->next = new_list;
158 new_list = temp;
726f6388
JA
159 }
160 return (REVERSE_LIST (new_list, REDIRECT *));
161}
ccc6cda3 162
726f6388
JA
163static FOR_COM *
164copy_for_command (com)
165 FOR_COM *com;
166{
ccc6cda3
JA
167 FOR_COM *new_for;
168
169 new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM));
726f6388 170 new_for->flags = com->flags;
b80f6443 171 new_for->line = com->line;
726f6388
JA
172 new_for->name = copy_word (com->name);
173 new_for->map_list = copy_word_list (com->map_list);
174 new_for->action = copy_command (com->action);
175 return (new_for);
176}
177
bb70624e
JA
178#if defined (ARITH_FOR_COMMAND)
179static ARITH_FOR_COM *
180copy_arith_for_command (com)
181 ARITH_FOR_COM *com;
182{
183 ARITH_FOR_COM *new_arith_for;
184
185 new_arith_for = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
186 new_arith_for->flags = com->flags;
187 new_arith_for->line = com->line;
188 new_arith_for->init = copy_word_list (com->init);
189 new_arith_for->test = copy_word_list (com->test);
190 new_arith_for->step = copy_word_list (com->step);
191 new_arith_for->action = copy_command (com->action);
192 return (new_arith_for);
193}
194#endif /* ARITH_FOR_COMMAND */
195
726f6388
JA
196static GROUP_COM *
197copy_group_command (com)
198 GROUP_COM *com;
199{
ccc6cda3 200 GROUP_COM *new_group;
726f6388 201
ccc6cda3 202 new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
726f6388
JA
203 new_group->command = copy_command (com->command);
204 return (new_group);
205}
206
bb70624e
JA
207static SUBSHELL_COM *
208copy_subshell_command (com)
209 SUBSHELL_COM *com;
210{
211 SUBSHELL_COM *new_subshell;
212
213 new_subshell = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
214 new_subshell->command = copy_command (com->command);
215 new_subshell->flags = com->flags;
216 return (new_subshell);
217}
218
3185942a
JA
219static COPROC_COM *
220copy_coproc_command (com)
221 COPROC_COM *com;
222{
223 COPROC_COM *new_coproc;
224
225 new_coproc = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
226 new_coproc->name = savestring (com->name);
227 new_coproc->command = copy_command (com->command);
228 new_coproc->flags = com->flags;
229 return (new_coproc);
230}
231
726f6388
JA
232static CASE_COM *
233copy_case_command (com)
234 CASE_COM *com;
235{
ccc6cda3 236 CASE_COM *new_case;
726f6388 237
ccc6cda3 238 new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM));
726f6388 239 new_case->flags = com->flags;
b80f6443 240 new_case->line = com->line;
726f6388
JA
241 new_case->word = copy_word (com->word);
242 new_case->clauses = copy_case_clauses (com->clauses);
243 return (new_case);
244}
245
246static WHILE_COM *
247copy_while_command (com)
248 WHILE_COM *com;
249{
ccc6cda3 250 WHILE_COM *new_while;
726f6388 251
ccc6cda3 252 new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
726f6388
JA
253 new_while->flags = com->flags;
254 new_while->test = copy_command (com->test);
255 new_while->action = copy_command (com->action);
256 return (new_while);
257}
258
259static IF_COM *
260copy_if_command (com)
261 IF_COM *com;
262{
ccc6cda3 263 IF_COM *new_if;
726f6388 264
ccc6cda3 265 new_if = (IF_COM *)xmalloc (sizeof (IF_COM));
726f6388
JA
266 new_if->flags = com->flags;
267 new_if->test = copy_command (com->test);
268 new_if->true_case = copy_command (com->true_case);
7117c2d2 269 new_if->false_case = com->false_case ? copy_command (com->false_case) : com->false_case;
726f6388
JA
270 return (new_if);
271}
272
cce855bc
JA
273#if defined (DPAREN_ARITHMETIC)
274static ARITH_COM *
275copy_arith_command (com)
276 ARITH_COM *com;
277{
278 ARITH_COM *new_arith;
279
280 new_arith = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
281 new_arith->flags = com->flags;
282 new_arith->exp = copy_word_list (com->exp);
283 new_arith->line = com->line;
284
285 return (new_arith);
286}
287#endif
288
289#if defined (COND_COMMAND)
290static COND_COM *
291copy_cond_command (com)
292 COND_COM *com;
293{
294 COND_COM *new_cond;
295
296 new_cond = (COND_COM *)xmalloc (sizeof (COND_COM));
297 new_cond->flags = com->flags;
298 new_cond->line = com->line;
bc4cd23c
JA
299 new_cond->type = com->type;
300 new_cond->op = com->op ? copy_word (com->op) : com->op;
cce855bc
JA
301 new_cond->left = com->left ? copy_cond_command (com->left) : (COND_COM *)NULL;
302 new_cond->right = com->right ? copy_cond_command (com->right) : (COND_COM *)NULL;
303
304 return (new_cond);
305}
306#endif
307
726f6388
JA
308static SIMPLE_COM *
309copy_simple_command (com)
310 SIMPLE_COM *com;
311{
cce855bc 312 SIMPLE_COM *new_simple;
726f6388 313
cce855bc 314 new_simple = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
726f6388
JA
315 new_simple->flags = com->flags;
316 new_simple->words = copy_word_list (com->words);
7117c2d2 317 new_simple->redirects = com->redirects ? copy_redirects (com->redirects) : (REDIRECT *)NULL;
726f6388
JA
318 new_simple->line = com->line;
319 return (new_simple);
320}
321
b80f6443
JA
322FUNCTION_DEF *
323copy_function_def_contents (old, new_def)
324 FUNCTION_DEF *old, *new_def;
325{
326 new_def->name = copy_word (old->name);
327 new_def->command = old->command ? copy_command (old->command) : old->command;
328 new_def->flags = old->flags;
329 new_def->line = old->line;
330 new_def->source_file = old->source_file ? savestring (old->source_file) : old->source_file;
331 return (new_def);
332}
333
334FUNCTION_DEF *
726f6388
JA
335copy_function_def (com)
336 FUNCTION_DEF *com;
337{
ccc6cda3 338 FUNCTION_DEF *new_def;
726f6388 339
ccc6cda3 340 new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
b80f6443 341 new_def = copy_function_def_contents (com, new_def);
726f6388
JA
342 return (new_def);
343}
344
345/* Copy the command structure in COMMAND. Return a pointer to the
346 copy. Don't you forget to dispose_command () on this pointer
347 later! */
348COMMAND *
349copy_command (command)
350 COMMAND *command;
351{
ccc6cda3 352 COMMAND *new_command;
726f6388 353
ccc6cda3
JA
354 if (command == NULL)
355 return (command);
726f6388 356
ccc6cda3
JA
357 new_command = (COMMAND *)xmalloc (sizeof (COMMAND));
358 FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND));
359 new_command->flags = command->flags;
360 new_command->line = command->line;
726f6388 361
ccc6cda3
JA
362 if (command->redirects)
363 new_command->redirects = copy_redirects (command->redirects);
364
365 switch (command->type)
366 {
367 case cm_for:
368 new_command->value.For = copy_for_command (command->value.For);
369 break;
726f6388 370
bb70624e
JA
371#if defined (ARITH_FOR_COMMAND)
372 case cm_arith_for:
373 new_command->value.ArithFor = copy_arith_for_command (command->value.ArithFor);
374 break;
375#endif
376
726f6388 377#if defined (SELECT_COMMAND)
ccc6cda3
JA
378 case cm_select:
379 new_command->value.Select =
380 (SELECT_COM *)copy_for_command ((FOR_COM *)command->value.Select);
381 break;
726f6388
JA
382#endif
383
ccc6cda3
JA
384 case cm_group:
385 new_command->value.Group = copy_group_command (command->value.Group);
386 break;
726f6388 387
bb70624e 388 case cm_subshell:
28ef6c31
JA
389 new_command->value.Subshell = copy_subshell_command (command->value.Subshell);
390 break;
bb70624e 391
3185942a
JA
392 case cm_coproc:
393 new_command->value.Coproc = copy_coproc_command (command->value.Coproc);
394 break;
395
ccc6cda3
JA
396 case cm_case:
397 new_command->value.Case = copy_case_command (command->value.Case);
398 break;
399
400 case cm_until:
401 case cm_while:
402 new_command->value.While = copy_while_command (command->value.While);
403 break;
404
405 case cm_if:
406 new_command->value.If = copy_if_command (command->value.If);
407 break;
408
cce855bc
JA
409#if defined (DPAREN_ARITHMETIC)
410 case cm_arith:
28ef6c31
JA
411 new_command->value.Arith = copy_arith_command (command->value.Arith);
412 break;
cce855bc
JA
413#endif
414
415#if defined (COND_COMMAND)
416 case cm_cond:
417 new_command->value.Cond = copy_cond_command (command->value.Cond);
418 break;
419#endif
420
ccc6cda3
JA
421 case cm_simple:
422 new_command->value.Simple = copy_simple_command (command->value.Simple);
423 break;
424
425 case cm_connection:
426 {
427 CONNECTION *new_connection;
428
429 new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION));
430 new_connection->connector = command->value.Connection->connector;
431 new_connection->first = copy_command (command->value.Connection->first);
432 new_connection->second = copy_command (command->value.Connection->second);
433 new_command->value.Connection = new_connection;
726f6388
JA
434 break;
435 }
ccc6cda3
JA
436
437 case cm_function_def:
438 new_command->value.Function_def = copy_function_def (command->value.Function_def);
439 break;
726f6388
JA
440 }
441 return (new_command);
442}