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. */
5 /* Copyright (C) 1987-2020 Free Software Foundation, Inc.
7 This file is part of GNU Bush, the Bourne Again SHell.
9 Bush 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.
14 Bush 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.
19 You should have received a copy of the GNU General Public License
20 along with Bush. If not, see <http://www.gnu.org/licenses/>.
25 #include "bushtypes.h"
27 #if defined (HAVE_UNISTD_H)
35 static PATTERN_LIST
*copy_case_clause
PARAMS((PATTERN_LIST
*));
36 static PATTERN_LIST
*copy_case_clauses
PARAMS((PATTERN_LIST
*));
37 static FOR_COM
*copy_for_command
PARAMS((FOR_COM
*));
38 #if defined (ARITH_FOR_COMMAND)
39 static ARITH_FOR_COM
*copy_arith_for_command
PARAMS((ARITH_FOR_COM
*));
41 static GROUP_COM
*copy_group_command
PARAMS((GROUP_COM
*));
42 static SUBSHELL_COM
*copy_subshell_command
PARAMS((SUBSHELL_COM
*));
43 static COPROC_COM
*copy_coproc_command
PARAMS((COPROC_COM
*));
44 static CASE_COM
*copy_case_command
PARAMS((CASE_COM
*));
45 static WHILE_COM
*copy_while_command
PARAMS((WHILE_COM
*));
46 static IF_COM
*copy_if_command
PARAMS((IF_COM
*));
47 #if defined (DPAREN_ARITHMETIC)
48 static ARITH_COM
*copy_arith_command
PARAMS((ARITH_COM
*));
50 #if defined (COND_COMMAND)
51 static COND_COM
*copy_cond_command
PARAMS((COND_COM
*));
53 static SIMPLE_COM
*copy_simple_command
PARAMS((SIMPLE_COM
*));
61 new_word
= make_bare_word (w
->word
);
62 new_word
->flags
= w
->flags
;
66 /* Copy the chain of words in LIST. Return a pointer to
72 WORD_LIST
*new_list
, *tl
;
74 for (new_list
= tl
= (WORD_LIST
*)NULL
; list
; list
= list
->next
)
77 new_list
= tl
= make_word_list (copy_word (list
->word
), new_list
);
80 tl
->next
= make_word_list (copy_word (list
->word
), (WORD_LIST
*)NULL
);
89 copy_case_clause (clause
)
92 PATTERN_LIST
*new_clause
;
94 new_clause
= (PATTERN_LIST
*)xmalloc (sizeof (PATTERN_LIST
));
95 new_clause
->patterns
= copy_word_list (clause
->patterns
);
96 new_clause
->action
= copy_command (clause
->action
);
97 new_clause
->flags
= clause
->flags
;
101 static PATTERN_LIST
*
102 copy_case_clauses (clauses
)
103 PATTERN_LIST
*clauses
;
105 PATTERN_LIST
*new_list
, *new_clause
;
107 for (new_list
= (PATTERN_LIST
*)NULL
; clauses
; clauses
= clauses
->next
)
109 new_clause
= copy_case_clause (clauses
);
110 new_clause
->next
= new_list
;
111 new_list
= new_clause
;
113 return (REVERSE_LIST (new_list
, PATTERN_LIST
*));
116 /* Copy a single redirect. */
118 copy_redirect (redirect
)
121 REDIRECT
*new_redirect
;
123 new_redirect
= (REDIRECT
*)xmalloc (sizeof (REDIRECT
));
125 FASTCOPY ((char *)redirect
, (char *)new_redirect
, (sizeof (REDIRECT
)));
127 *new_redirect
= *redirect
; /* let the compiler do the fast structure copy */
130 if (redirect
->rflags
& REDIR_VARASSIGN
)
131 new_redirect
->redirector
.filename
= copy_word (redirect
->redirector
.filename
);
133 switch (redirect
->instruction
)
135 case r_reading_until
:
136 case r_deblank_reading_until
:
137 new_redirect
->here_doc_eof
= redirect
->here_doc_eof
? savestring (redirect
->here_doc_eof
) : 0;
139 case r_reading_string
:
141 case r_output_direction
:
142 case r_input_direction
:
143 case r_inputa_direction
:
145 case r_append_err_and_out
:
148 case r_duplicating_input_word
:
149 case r_duplicating_output_word
:
150 case r_move_input_word
:
151 case r_move_output_word
:
152 new_redirect
->redirectee
.filename
= copy_word (redirect
->redirectee
.filename
);
154 case r_duplicating_input
:
155 case r_duplicating_output
:
161 return (new_redirect
);
165 copy_redirects (list
)
168 REDIRECT
*new_list
, *temp
;
170 for (new_list
= (REDIRECT
*)NULL
; list
; list
= list
->next
)
172 temp
= copy_redirect (list
);
173 temp
->next
= new_list
;
176 return (REVERSE_LIST (new_list
, REDIRECT
*));
180 copy_for_command (com
)
185 new_for
= (FOR_COM
*)xmalloc (sizeof (FOR_COM
));
186 new_for
->flags
= com
->flags
;
187 new_for
->line
= com
->line
;
188 new_for
->name
= copy_word (com
->name
);
189 new_for
->map_list
= copy_word_list (com
->map_list
);
190 new_for
->action
= copy_command (com
->action
);
194 #if defined (ARITH_FOR_COMMAND)
195 static ARITH_FOR_COM
*
196 copy_arith_for_command (com
)
199 ARITH_FOR_COM
*new_arith_for
;
201 new_arith_for
= (ARITH_FOR_COM
*)xmalloc (sizeof (ARITH_FOR_COM
));
202 new_arith_for
->flags
= com
->flags
;
203 new_arith_for
->line
= com
->line
;
204 new_arith_for
->init
= copy_word_list (com
->init
);
205 new_arith_for
->test
= copy_word_list (com
->test
);
206 new_arith_for
->step
= copy_word_list (com
->step
);
207 new_arith_for
->action
= copy_command (com
->action
);
208 return (new_arith_for
);
210 #endif /* ARITH_FOR_COMMAND */
213 copy_group_command (com
)
216 GROUP_COM
*new_group
;
218 new_group
= (GROUP_COM
*)xmalloc (sizeof (GROUP_COM
));
219 new_group
->command
= copy_command (com
->command
);
223 static SUBSHELL_COM
*
224 copy_subshell_command (com
)
227 SUBSHELL_COM
*new_subshell
;
229 new_subshell
= (SUBSHELL_COM
*)xmalloc (sizeof (SUBSHELL_COM
));
230 new_subshell
->command
= copy_command (com
->command
);
231 new_subshell
->flags
= com
->flags
;
232 new_subshell
->line
= com
->line
;
233 return (new_subshell
);
237 copy_coproc_command (com
)
240 COPROC_COM
*new_coproc
;
242 new_coproc
= (COPROC_COM
*)xmalloc (sizeof (COPROC_COM
));
243 new_coproc
->name
= savestring (com
->name
);
244 new_coproc
->command
= copy_command (com
->command
);
245 new_coproc
->flags
= com
->flags
;
250 copy_case_command (com
)
255 new_case
= (CASE_COM
*)xmalloc (sizeof (CASE_COM
));
256 new_case
->flags
= com
->flags
;
257 new_case
->line
= com
->line
;
258 new_case
->word
= copy_word (com
->word
);
259 new_case
->clauses
= copy_case_clauses (com
->clauses
);
264 copy_while_command (com
)
267 WHILE_COM
*new_while
;
269 new_while
= (WHILE_COM
*)xmalloc (sizeof (WHILE_COM
));
270 new_while
->flags
= com
->flags
;
271 new_while
->test
= copy_command (com
->test
);
272 new_while
->action
= copy_command (com
->action
);
277 copy_if_command (com
)
282 new_if
= (IF_COM
*)xmalloc (sizeof (IF_COM
));
283 new_if
->flags
= com
->flags
;
284 new_if
->test
= copy_command (com
->test
);
285 new_if
->true_case
= copy_command (com
->true_case
);
286 new_if
->false_case
= com
->false_case
? copy_command (com
->false_case
) : com
->false_case
;
290 #if defined (DPAREN_ARITHMETIC)
292 copy_arith_command (com
)
295 ARITH_COM
*new_arith
;
297 new_arith
= (ARITH_COM
*)xmalloc (sizeof (ARITH_COM
));
298 new_arith
->flags
= com
->flags
;
299 new_arith
->exp
= copy_word_list (com
->exp
);
300 new_arith
->line
= com
->line
;
306 #if defined (COND_COMMAND)
308 copy_cond_command (com
)
313 new_cond
= (COND_COM
*)xmalloc (sizeof (COND_COM
));
314 new_cond
->flags
= com
->flags
;
315 new_cond
->line
= com
->line
;
316 new_cond
->type
= com
->type
;
317 new_cond
->op
= com
->op
? copy_word (com
->op
) : com
->op
;
318 new_cond
->left
= com
->left
? copy_cond_command (com
->left
) : (COND_COM
*)NULL
;
319 new_cond
->right
= com
->right
? copy_cond_command (com
->right
) : (COND_COM
*)NULL
;
326 copy_simple_command (com
)
329 SIMPLE_COM
*new_simple
;
331 new_simple
= (SIMPLE_COM
*)xmalloc (sizeof (SIMPLE_COM
));
332 new_simple
->flags
= com
->flags
;
333 new_simple
->words
= copy_word_list (com
->words
);
334 new_simple
->redirects
= com
->redirects
? copy_redirects (com
->redirects
) : (REDIRECT
*)NULL
;
335 new_simple
->line
= com
->line
;
340 copy_function_def_contents (old
, new_def
)
341 FUNCTION_DEF
*old
, *new_def
;
343 new_def
->name
= copy_word (old
->name
);
344 new_def
->command
= old
->command
? copy_command (old
->command
) : old
->command
;
345 new_def
->flags
= old
->flags
;
346 new_def
->line
= old
->line
;
347 new_def
->source_file
= old
->source_file
? savestring (old
->source_file
) : old
->source_file
;
352 copy_function_def (com
)
355 FUNCTION_DEF
*new_def
;
357 new_def
= (FUNCTION_DEF
*)xmalloc (sizeof (FUNCTION_DEF
));
358 new_def
= copy_function_def_contents (com
, new_def
);
362 /* Copy the command structure in COMMAND. Return a pointer to the
363 copy. Don't you forget to dispose_command () on this pointer
366 copy_command (command
)
369 COMMAND
*new_command
;
374 new_command
= (COMMAND
*)xmalloc (sizeof (COMMAND
));
375 FASTCOPY ((char *)command
, (char *)new_command
, sizeof (COMMAND
));
376 new_command
->flags
= command
->flags
;
377 new_command
->line
= command
->line
;
379 if (command
->redirects
)
380 new_command
->redirects
= copy_redirects (command
->redirects
);
382 switch (command
->type
)
385 new_command
->value
.For
= copy_for_command (command
->value
.For
);
388 #if defined (ARITH_FOR_COMMAND)
390 new_command
->value
.ArithFor
= copy_arith_for_command (command
->value
.ArithFor
);
394 #if defined (SELECT_COMMAND)
396 new_command
->value
.Select
=
397 (SELECT_COM
*)copy_for_command ((FOR_COM
*)command
->value
.Select
);
402 new_command
->value
.Group
= copy_group_command (command
->value
.Group
);
406 new_command
->value
.Subshell
= copy_subshell_command (command
->value
.Subshell
);
410 new_command
->value
.Coproc
= copy_coproc_command (command
->value
.Coproc
);
414 new_command
->value
.Case
= copy_case_command (command
->value
.Case
);
419 new_command
->value
.While
= copy_while_command (command
->value
.While
);
423 new_command
->value
.If
= copy_if_command (command
->value
.If
);
426 #if defined (DPAREN_ARITHMETIC)
428 new_command
->value
.Arith
= copy_arith_command (command
->value
.Arith
);
432 #if defined (COND_COMMAND)
434 new_command
->value
.Cond
= copy_cond_command (command
->value
.Cond
);
439 new_command
->value
.Simple
= copy_simple_command (command
->value
.Simple
);
444 CONNECTION
*new_connection
;
446 new_connection
= (CONNECTION
*)xmalloc (sizeof (CONNECTION
));
447 new_connection
->connector
= command
->value
.Connection
->connector
;
448 new_connection
->first
= copy_command (command
->value
.Connection
->first
);
449 new_connection
->second
= copy_command (command
->value
.Connection
->second
);
450 new_command
->value
.Connection
= new_connection
;
454 case cm_function_def
:
455 new_command
->value
.Function_def
= copy_function_def (command
->value
.Function_def
);
458 return (new_command
);