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