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