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