]> git.ipfire.org Git - thirdparty/bash.git/blame - dispose_cmd.c
commit bash-20080515 snapshot
[thirdparty/bash.git] / dispose_cmd.c
CommitLineData
726f6388
JA
1/* dispose_command.c -- dispose of a COMMAND structure. */
2
cc87ba64 3/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
bb70624e 9 the Free Software Foundation; either version 2, or (at your option)
726f6388
JA
10 any later version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash; see the file COPYING. If not, write to the Free
bb70624e 19 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
726f6388
JA
95 case cm_case:
96 {
ccc6cda3
JA
97 register CASE_COM *c;
98 PATTERN_LIST *t, *p;
726f6388 99
ccc6cda3 100 c = command->value.Case;
726f6388
JA
101 dispose_word (c->word);
102
ccc6cda3 103 for (p = c->clauses; p; )
726f6388
JA
104 {
105 dispose_words (p->patterns);
106 dispose_command (p->action);
107 t = p;
108 p = p->next;
109 free (t);
110 }
111 free (c);
112 break;
113 }
114
115 case cm_until:
116 case cm_while:
117 {
ccc6cda3 118 register WHILE_COM *c;
726f6388 119
ccc6cda3 120 c = command->value.While;
726f6388
JA
121 dispose_command (c->test);
122 dispose_command (c->action);
123 free (c);
124 break;
125 }
126
127 case cm_if:
128 {
ccc6cda3
JA
129 register IF_COM *c;
130
131 c = command->value.If;
726f6388
JA
132 dispose_command (c->test);
133 dispose_command (c->true_case);
134 dispose_command (c->false_case);
135 free (c);
136 break;
137 }
138
139 case cm_simple:
140 {
ccc6cda3
JA
141 register SIMPLE_COM *c;
142
143 c = command->value.Simple;
726f6388
JA
144 dispose_words (c->words);
145 dispose_redirects (c->redirects);
146 free (c);
147 break;
148 }
149
150 case cm_connection:
151 {
ccc6cda3
JA
152 register CONNECTION *c;
153
154 c = command->value.Connection;
726f6388
JA
155 dispose_command (c->first);
156 dispose_command (c->second);
157 free (c);
158 break;
159 }
160
cce855bc
JA
161#if defined (DPAREN_ARITHMETIC)
162 case cm_arith:
163 {
164 register ARITH_COM *c;
165
166 c = command->value.Arith;
167 dispose_words (c->exp);
168 free (c);
169 break;
170 }
171#endif /* DPAREN_ARITHMETIC */
172
173#if defined (COND_COMMAND)
174 case cm_cond:
175 {
176 register COND_COM *c;
177
178 c = command->value.Cond;
179 dispose_cond_node (c);
180 break;
181 }
182#endif /* COND_COMMAND */
183
726f6388
JA
184 case cm_function_def:
185 {
ccc6cda3
JA
186 register FUNCTION_DEF *c;
187
188 c = command->value.Function_def;
d3a24ed2 189 dispose_function_def (c);
726f6388
JA
190 break;
191 }
192
193 default:
b72432fd 194 command_error ("dispose_command", CMDERR_BADTYPE, command->type, 0);
726f6388
JA
195 break;
196 }
197 free (command);
198}
199
cce855bc
JA
200#if defined (COND_COMMAND)
201/* How to free a node in a conditional command. */
202void
203dispose_cond_node (cond)
204 COND_COM *cond;
205{
206 if (cond)
207 {
208 if (cond->left)
209 dispose_cond_node (cond->left);
210 if (cond->right)
211 dispose_cond_node (cond->right);
212 if (cond->op)
213 dispose_word (cond->op);
214 free (cond);
215 }
216}
217#endif /* COND_COMMAND */
218
d3a24ed2
CR
219void
220dispose_function_def_contents (c)
221 FUNCTION_DEF *c;
222{
223 dispose_word (c->name);
224 dispose_command (c->command);
225 FREE (c->source_file);
226}
227
228void
229dispose_function_def (c)
230 FUNCTION_DEF *c;
231{
232 dispose_function_def_contents (c);
233 free (c);
234}
235
726f6388
JA
236/* How to free a WORD_DESC. */
237void
cce855bc
JA
238dispose_word (w)
239 WORD_DESC *w;
726f6388 240{
cce855bc 241 FREE (w->word);
7117c2d2 242 ocache_free (wdcache, WORD_DESC, w);
227f982e
CR
243}
244
245/* Free a WORD_DESC, but not the word contained within. */
246void
247dispose_word_desc (w)
248 WORD_DESC *w;
249{
250 w->word = 0;
251 ocache_free (wdcache, WORD_DESC, w);
726f6388
JA
252}
253
254/* How to get rid of a linked list of words. A WORD_LIST. */
255void
256dispose_words (list)
257 WORD_LIST *list;
258{
259 WORD_LIST *t;
ccc6cda3 260
726f6388
JA
261 while (list)
262 {
263 t = list;
264 list = list->next;
265 dispose_word (t->word);
7117c2d2 266#if 0
726f6388 267 free (t);
7117c2d2
JA
268#else
269 ocache_free (wlcache, WORD_LIST, t);
270#endif
726f6388
JA
271 }
272}
273
d166f048
JA
274#ifdef INCLUDE_UNUSED
275/* How to dispose of an array of pointers to char. This is identical to
276 free_array in stringlib.c. */
726f6388
JA
277void
278dispose_word_array (array)
279 char **array;
280{
281 register int count;
282
d166f048
JA
283 if (array == 0)
284 return;
285
726f6388
JA
286 for (count = 0; array[count]; count++)
287 free (array[count]);
288
289 free (array);
290}
d166f048 291#endif
726f6388
JA
292
293/* How to dispose of an list of redirections. A REDIRECT. */
294void
295dispose_redirects (list)
296 REDIRECT *list;
297{
298 register REDIRECT *t;
299
300 while (list)
301 {
302 t = list;
303 list = list->next;
304 switch (t->instruction)
305 {
306 case r_reading_until:
307 case r_deblank_reading_until:
308 free (t->here_doc_eof);
ccc6cda3 309 /*FALLTHROUGH*/
7117c2d2 310 case r_reading_string:
726f6388
JA
311 case r_output_direction:
312 case r_input_direction:
313 case r_inputa_direction:
314 case r_appending_to:
315 case r_err_and_out:
316 case r_input_output:
317 case r_output_force:
318 case r_duplicating_input_word:
319 case r_duplicating_output_word:
7117c2d2
JA
320 case r_move_input_word:
321 case r_move_output_word:
726f6388 322 dispose_word (t->redirectee.filename);
ccc6cda3
JA
323 /* FALLTHROUGH */
324 default:
726f6388
JA
325 break;
326 }
327 free (t);
328 }
329}