Imported from ../bash-2.0.tar.gz.
[platform/upstream/bash.git] / dispose_cmd.c
1 /* dispose_command.c -- dispose of a COMMAND structure. */
2
3 /* Copyright (C) 1987,1991 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 1, or (at your option)
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
19    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include "config.h"
22
23 #if defined (HAVE_UNISTD_H)
24 #  include <unistd.h>
25 #endif
26
27 #include "bashansi.h"
28 #include "shell.h"
29
30 /* Dispose of the command structure passed. */
31 void
32 dispose_command (command)
33      COMMAND *command;
34 {
35   if (command == 0)
36     return;
37
38   if (command->redirects)
39     dispose_redirects (command->redirects);
40
41   switch (command->type)
42     {
43     case cm_for:
44 #if defined (SELECT_COMMAND)
45     case cm_select:
46 #endif
47       {
48         register FOR_COM *c;
49 #if defined (SELECT_COMMAND)
50         if (command->type == cm_select)
51           c = (FOR_COM *)command->value.Select;
52         else
53 #endif
54         c = command->value.For;
55         dispose_word (c->name);
56         dispose_words (c->map_list);
57         dispose_command (c->action);
58         free (c);
59         break;
60       }
61
62     case cm_group:
63       {
64         dispose_command (command->value.Group->command);
65         free (command->value.Group);
66         break;
67       }
68
69     case cm_case:
70       {
71         register CASE_COM *c;
72         PATTERN_LIST *t, *p;
73
74         c = command->value.Case;
75         dispose_word (c->word);
76
77         for (p = c->clauses; p; )
78           {
79             dispose_words (p->patterns);
80             dispose_command (p->action);
81             t = p;
82             p = p->next;
83             free (t);
84           }
85         free (c);
86         break;
87       }
88
89     case cm_until:
90     case cm_while:
91       {
92         register WHILE_COM *c;
93
94         c = command->value.While;
95         dispose_command (c->test);
96         dispose_command (c->action);
97         free (c);
98         break;
99       }
100
101     case cm_if:
102       {
103         register IF_COM *c;
104
105         c = command->value.If;
106         dispose_command (c->test);
107         dispose_command (c->true_case);
108         dispose_command (c->false_case);
109         free (c);
110         break;
111       }
112
113     case cm_simple:
114       {
115         register SIMPLE_COM *c;
116
117         c = command->value.Simple;
118         dispose_words (c->words);
119         dispose_redirects (c->redirects);
120         free (c);
121         break;
122       }
123
124     case cm_connection:
125       {
126         register CONNECTION *c;
127
128         c = command->value.Connection;
129         dispose_command (c->first);
130         dispose_command (c->second);
131         free (c);
132         break;
133       }
134
135     case cm_function_def:
136       {
137         register FUNCTION_DEF *c;
138
139         c = command->value.Function_def;
140         dispose_word (c->name);
141         dispose_command (c->command);
142         free (c);
143         break;
144       }
145
146     default:
147       programming_error ("dispose_command: bad command type `%d'", command->type);
148       break;
149     }
150   free (command);
151 }
152
153 /* How to free a WORD_DESC. */
154 void
155 dispose_word (word)
156      WORD_DESC *word;
157 {
158   FREE (word->word);
159   free (word);
160 }
161
162 /* How to get rid of a linked list of words.  A WORD_LIST. */
163 void
164 dispose_words (list)
165      WORD_LIST *list;
166 {
167   WORD_LIST *t;
168
169   while (list)
170     {
171       t = list;
172       list = list->next;
173       dispose_word (t->word);
174       free (t);
175     }
176 }
177
178 /* How to dispose of an array of pointers to char. */
179 void
180 dispose_word_array (array)
181      char **array;
182 {
183   register int count;
184
185   for (count = 0; array[count]; count++)
186     free (array[count]);
187
188   free (array);
189 }
190
191 /* How to dispose of an list of redirections.  A REDIRECT. */
192 void
193 dispose_redirects (list)
194      REDIRECT *list;
195 {
196   register REDIRECT *t;
197
198   while (list)
199     {
200       t = list;
201       list = list->next;
202       switch (t->instruction)
203         {
204         case r_reading_until:
205         case r_deblank_reading_until:
206           free (t->here_doc_eof);
207         /*FALLTHROUGH*/
208         case r_output_direction:
209         case r_input_direction:
210         case r_inputa_direction:
211         case r_appending_to:
212         case r_err_and_out:
213         case r_input_output:
214         case r_output_force:
215         case r_duplicating_input_word:
216         case r_duplicating_output_word:
217           dispose_word (t->redirectee.filename);
218           /* FALLTHROUGH */
219         default:
220           break;
221         }
222       free (t);
223     }
224 }