]> git.ipfire.org Git - thirdparty/bash.git/blame - dispose_cmd.c
Bash-4.3 patch 7
[thirdparty/bash.git] / dispose_cmd.c
CommitLineData
726f6388
JA
1/* dispose_command.c -- dispose of a COMMAND structure. */
2
3185942a 3/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
726f6388 11
3185942a
JA
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
726f6388
JA
16
17 You should have received a copy of the GNU General Public License
3185942a
JA
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
726f6388 20
ccc6cda3
JA
21#include "config.h"
22
cce855bc
JA
23#include "bashtypes.h"
24
ccc6cda3
JA
25#if defined (HAVE_UNISTD_H)
26# include <unistd.h>
27#endif
28
29#include "bashansi.h"
726f6388
JA
30#include "shell.h"
31
7117c2d2
JA
32extern sh_obj_cache_t wdcache, wlcache;
33
726f6388
JA
34/* Dispose of the command structure passed. */
35void
36dispose_command (command)
37 COMMAND *command;
38{
ccc6cda3
JA
39 if (command == 0)
40 return;
726f6388
JA
41
42 if (command->redirects)
43 dispose_redirects (command->redirects);
44
45 switch (command->type)
46 {
47 case cm_for:
726f6388
JA
48#if defined (SELECT_COMMAND)
49 case cm_select:
ccc6cda3 50#endif
726f6388 51 {
ccc6cda3
JA
52 register FOR_COM *c;
53#if defined (SELECT_COMMAND)
54 if (command->type == cm_select)
55 c = (FOR_COM *)command->value.Select;
56 else
57#endif
58 c = command->value.For;
726f6388
JA
59 dispose_word (c->name);
60 dispose_words (c->map_list);
61 dispose_command (c->action);
62 free (c);
63 break;
64 }
ccc6cda3 65
bb70624e
JA
66#if defined (ARITH_FOR_COMMAND)
67 case cm_arith_for:
68 {
69 register ARITH_FOR_COM *c;
70
71 c = command->value.ArithFor;
72 dispose_words (c->init);
73 dispose_words (c->test);
74 dispose_words (c->step);
75 dispose_command (c->action);
76 free (c);
77 break;
78 }
79#endif /* ARITH_FOR_COMMAND */
80
726f6388
JA
81 case cm_group:
82 {
83 dispose_command (command->value.Group->command);
84 free (command->value.Group);
85 break;
86 }
87
bb70624e
JA
88 case cm_subshell:
89 {
90 dispose_command (command->value.Subshell->command);
91 free (command->value.Subshell);
92 break;
93 }
94
3185942a
JA
95 case cm_coproc:
96 {
97 free (command->value.Coproc->name);
98 dispose_command (command->value.Coproc->command);
99 free (command->value.Coproc);
100 break;
101 }
102
726f6388
JA
103 case cm_case:
104 {
ccc6cda3
JA
105 register CASE_COM *c;
106 PATTERN_LIST *t, *p;
726f6388 107
ccc6cda3 108 c = command->value.Case;
726f6388
JA
109 dispose_word (c->word);
110
ccc6cda3 111 for (p = c->clauses; p; )
726f6388
JA
112 {
113 dispose_words (p->patterns);
114 dispose_command (p->action);
115 t = p;
116 p = p->next;
117 free (t);
118 }
119 free (c);
120 break;
121 }
122
123 case cm_until:
124 case cm_while:
125 {
ccc6cda3 126 register WHILE_COM *c;
726f6388 127
ccc6cda3 128 c = command->value.While;
726f6388
JA
129 dispose_command (c->test);
130 dispose_command (c->action);
131 free (c);
132 break;
133 }
134
135 case cm_if:
136 {
ccc6cda3
JA
137 register IF_COM *c;
138
139 c = command->value.If;
726f6388
JA
140 dispose_command (c->test);
141 dispose_command (c->true_case);
142 dispose_command (c->false_case);
143 free (c);
144 break;
145 }
146
147 case cm_simple:
148 {
ccc6cda3
JA
149 register SIMPLE_COM *c;
150
151 c = command->value.Simple;
726f6388
JA
152 dispose_words (c->words);
153 dispose_redirects (c->redirects);
154 free (c);
155 break;
156 }
157
158 case cm_connection:
159 {
ccc6cda3
JA
160 register CONNECTION *c;
161
162 c = command->value.Connection;
726f6388
JA
163 dispose_command (c->first);
164 dispose_command (c->second);
165 free (c);
166 break;
167 }
168
cce855bc
JA
169#if defined (DPAREN_ARITHMETIC)
170 case cm_arith:
171 {
172 register ARITH_COM *c;
173
174 c = command->value.Arith;
175 dispose_words (c->exp);
176 free (c);
177 break;
178 }
179#endif /* DPAREN_ARITHMETIC */
180
181#if defined (COND_COMMAND)
182 case cm_cond:
183 {
184 register COND_COM *c;
185
186 c = command->value.Cond;
187 dispose_cond_node (c);
188 break;
189 }
190#endif /* COND_COMMAND */
191
726f6388
JA
192 case cm_function_def:
193 {
ccc6cda3
JA
194 register FUNCTION_DEF *c;
195
196 c = command->value.Function_def;
b80f6443 197 dispose_function_def (c);
726f6388
JA
198 break;
199 }
200
201 default:
b72432fd 202 command_error ("dispose_command", CMDERR_BADTYPE, command->type, 0);
726f6388
JA
203 break;
204 }
205 free (command);
206}
207
cce855bc
JA
208#if defined (COND_COMMAND)
209/* How to free a node in a conditional command. */
210void
211dispose_cond_node (cond)
212 COND_COM *cond;
213{
214 if (cond)
215 {
216 if (cond->left)
217 dispose_cond_node (cond->left);
218 if (cond->right)
219 dispose_cond_node (cond->right);
220 if (cond->op)
221 dispose_word (cond->op);
222 free (cond);
223 }
224}
225#endif /* COND_COMMAND */
226
b80f6443
JA
227void
228dispose_function_def_contents (c)
229 FUNCTION_DEF *c;
230{
231 dispose_word (c->name);
232 dispose_command (c->command);
233 FREE (c->source_file);
234}
235
236void
237dispose_function_def (c)
238 FUNCTION_DEF *c;
239{
240 dispose_function_def_contents (c);
241 free (c);
242}
243
726f6388
JA
244/* How to free a WORD_DESC. */
245void
cce855bc
JA
246dispose_word (w)
247 WORD_DESC *w;
726f6388 248{
cce855bc 249 FREE (w->word);
7117c2d2 250 ocache_free (wdcache, WORD_DESC, w);
95732b49
JA
251}
252
253/* Free a WORD_DESC, but not the word contained within. */
254void
255dispose_word_desc (w)
256 WORD_DESC *w;
257{
258 w->word = 0;
259 ocache_free (wdcache, WORD_DESC, w);
726f6388
JA
260}
261
262/* How to get rid of a linked list of words. A WORD_LIST. */
263void
264dispose_words (list)
265 WORD_LIST *list;
266{
267 WORD_LIST *t;
ccc6cda3 268
726f6388
JA
269 while (list)
270 {
271 t = list;
272 list = list->next;
273 dispose_word (t->word);
7117c2d2 274#if 0
726f6388 275 free (t);
7117c2d2
JA
276#else
277 ocache_free (wlcache, WORD_LIST, t);
278#endif
726f6388
JA
279 }
280}
281
d166f048
JA
282#ifdef INCLUDE_UNUSED
283/* How to dispose of an array of pointers to char. This is identical to
284 free_array in stringlib.c. */
726f6388
JA
285void
286dispose_word_array (array)
287 char **array;
288{
289 register int count;
290
d166f048
JA
291 if (array == 0)
292 return;
293
726f6388
JA
294 for (count = 0; array[count]; count++)
295 free (array[count]);
296
297 free (array);
298}
d166f048 299#endif
726f6388
JA
300
301/* How to dispose of an list of redirections. A REDIRECT. */
302void
303dispose_redirects (list)
304 REDIRECT *list;
305{
306 register REDIRECT *t;
307
308 while (list)
309 {
310 t = list;
311 list = list->next;
0001803f
CR
312
313 if (t->rflags & REDIR_VARASSIGN)
314 dispose_word (t->redirector.filename);
315
726f6388
JA
316 switch (t->instruction)
317 {
318 case r_reading_until:
319 case r_deblank_reading_until:
320 free (t->here_doc_eof);
ccc6cda3 321 /*FALLTHROUGH*/
7117c2d2 322 case r_reading_string:
726f6388
JA
323 case r_output_direction:
324 case r_input_direction:
325 case r_inputa_direction:
326 case r_appending_to:
327 case r_err_and_out:
3185942a 328 case r_append_err_and_out:
726f6388
JA
329 case r_input_output:
330 case r_output_force:
331 case r_duplicating_input_word:
332 case r_duplicating_output_word:
7117c2d2
JA
333 case r_move_input_word:
334 case r_move_output_word:
726f6388 335 dispose_word (t->redirectee.filename);
ccc6cda3
JA
336 /* FALLTHROUGH */
337 default:
726f6388
JA
338 break;
339 }
340 free (t);
341 }
342}