]>
Commit | Line | Data |
---|---|---|
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 | ||
35 | WORD_DESC * | |
cce855bc JA |
36 | copy_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. */ |
53 | WORD_LIST * | |
54 | copy_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 | ||
69 | static PATTERN_LIST * | |
70 | copy_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 | ||
81 | static PATTERN_LIST * | |
82 | copy_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. */ | |
97 | REDIRECT * | |
98 | copy_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 |
130 | REDIRECT * |
131 | copy_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 |
145 | static FOR_COM * |
146 | copy_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) |
160 | static ARITH_FOR_COM * | |
161 | copy_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 |
177 | static GROUP_COM * |
178 | copy_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 |
188 | static SUBSHELL_COM * |
189 | copy_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 |
200 | static CASE_COM * |
201 | copy_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 | ||
213 | static WHILE_COM * | |
214 | copy_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 | ||
226 | static IF_COM * | |
227 | copy_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) |
241 | static ARITH_COM * | |
242 | copy_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) | |
257 | static COND_COM * | |
258 | copy_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 |
275 | static SIMPLE_COM * |
276 | copy_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 | ||
289 | static FUNCTION_DEF * | |
290 | copy_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! */ | |
306 | COMMAND * | |
307 | copy_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 | } |