Line data Source code
1 : /* dispose_command.c -- dispose of a COMMAND structure. */ 2 : 3 : /* Copyright (C) 1987-2009 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 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. 11 : 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. 16 : 17 : You should have received a copy of the GNU General Public License 18 : along with Bash. If not, see <http://www.gnu.org/licenses/>. 19 : */ 20 : 21 : #include "config.h" 22 : 23 : #include "bashtypes.h" 24 : 25 : #if defined (HAVE_UNISTD_H) 26 : # include <unistd.h> 27 : #endif 28 : 29 : #include "bashansi.h" 30 : #include "shell.h" 31 : 32 : extern sh_obj_cache_t wdcache, wlcache; 33 : 34 : /* Dispose of the command structure passed. */ 35 : void 36 538983749 : dispose_command (command) 37 : COMMAND *command; 38 : { 39 538983749 : if (command == 0) 40 : return; 41 : 42 455848380 : if (command->redirects) 43 9 : dispose_redirects (command->redirects); 44 : 45 455848380 : switch (command->type) 46 : { 47 9143260 : case cm_for: 48 : #if defined (SELECT_COMMAND) 49 : case cm_select: 50 : #endif 51 : { 52 9143260 : register FOR_COM *c; 53 : #if defined (SELECT_COMMAND) 54 9143260 : if (command->type == cm_select) 55 0 : c = (FOR_COM *)command->value.Select; 56 : else 57 : #endif 58 9143260 : c = command->value.For; 59 9143260 : dispose_word (c->name); 60 9143260 : dispose_words (c->map_list); 61 9143260 : dispose_command (c->action); 62 9143260 : free (c); 63 9143260 : break; 64 : } 65 : 66 : #if defined (ARITH_FOR_COMMAND) 67 0 : case cm_arith_for: 68 : { 69 0 : register ARITH_FOR_COM *c; 70 : 71 0 : c = command->value.ArithFor; 72 0 : dispose_words (c->init); 73 0 : dispose_words (c->test); 74 0 : dispose_words (c->step); 75 0 : dispose_command (c->action); 76 0 : free (c); 77 0 : break; 78 : } 79 : #endif /* ARITH_FOR_COMMAND */ 80 : 81 17176427 : case cm_group: 82 : { 83 17176427 : dispose_command (command->value.Group->command); 84 17176427 : free (command->value.Group); 85 17176427 : break; 86 : } 87 : 88 77 : case cm_subshell: 89 : { 90 77 : dispose_command (command->value.Subshell->command); 91 77 : free (command->value.Subshell); 92 77 : break; 93 : } 94 : 95 0 : case cm_coproc: 96 : { 97 0 : free (command->value.Coproc->name); 98 0 : dispose_command (command->value.Coproc->command); 99 0 : free (command->value.Coproc); 100 0 : break; 101 : } 102 : 103 14320581 : case cm_case: 104 : { 105 14320581 : register CASE_COM *c; 106 14320581 : PATTERN_LIST *t, *p; 107 : 108 14320581 : c = command->value.Case; 109 14320581 : dispose_word (c->word); 110 : 111 58445523 : for (p = c->clauses; p; ) 112 : { 113 44124942 : dispose_words (p->patterns); 114 44124942 : dispose_command (p->action); 115 44124942 : t = p; 116 44124942 : p = p->next; 117 44124942 : free (t); 118 : } 119 14320581 : free (c); 120 14320581 : break; 121 : } 122 : 123 1309792 : case cm_until: 124 : case cm_while: 125 : { 126 1309792 : register WHILE_COM *c; 127 : 128 1309792 : c = command->value.While; 129 1309792 : dispose_command (c->test); 130 1309792 : dispose_command (c->action); 131 1309792 : free (c); 132 1309792 : break; 133 : } 134 : 135 65662863 : case cm_if: 136 : { 137 65662863 : register IF_COM *c; 138 : 139 65662863 : c = command->value.If; 140 65662863 : dispose_command (c->test); 141 65662863 : dispose_command (c->true_case); 142 65662863 : dispose_command (c->false_case); 143 65662863 : free (c); 144 65662863 : break; 145 : } 146 : 147 251588992 : case cm_simple: 148 : { 149 251588992 : register SIMPLE_COM *c; 150 : 151 251588992 : c = command->value.Simple; 152 251588992 : dispose_words (c->words); 153 251588992 : dispose_redirects (c->redirects); 154 251588992 : free (c); 155 251588992 : break; 156 : } 157 : 158 79479801 : case cm_connection: 159 : { 160 79479801 : register CONNECTION *c; 161 : 162 79479801 : c = command->value.Connection; 163 79479801 : dispose_command (c->first); 164 79479801 : dispose_command (c->second); 165 79479801 : free (c); 166 79479801 : break; 167 : } 168 : 169 : #if defined (DPAREN_ARITHMETIC) 170 0 : case cm_arith: 171 : { 172 0 : register ARITH_COM *c; 173 : 174 0 : c = command->value.Arith; 175 0 : dispose_words (c->exp); 176 0 : free (c); 177 0 : break; 178 : } 179 : #endif /* DPAREN_ARITHMETIC */ 180 : 181 : #if defined (COND_COMMAND) 182 0 : case cm_cond: 183 : { 184 0 : register COND_COM *c; 185 : 186 0 : c = command->value.Cond; 187 0 : dispose_cond_node (c); 188 0 : break; 189 : } 190 : #endif /* COND_COMMAND */ 191 : 192 17166587 : case cm_function_def: 193 : { 194 17166587 : register FUNCTION_DEF *c; 195 : 196 17166587 : c = command->value.Function_def; 197 17166587 : dispose_function_def (c); 198 17166587 : break; 199 : } 200 : 201 0 : default: 202 0 : command_error ("dispose_command", CMDERR_BADTYPE, command->type, 0); 203 0 : break; 204 : } 205 455848380 : free (command); 206 : } 207 : 208 : #if defined (COND_COMMAND) 209 : /* How to free a node in a conditional command. */ 210 : void 211 0 : dispose_cond_node (cond) 212 : COND_COM *cond; 213 : { 214 0 : if (cond) 215 : { 216 0 : if (cond->left) 217 0 : dispose_cond_node (cond->left); 218 0 : if (cond->right) 219 0 : dispose_cond_node (cond->right); 220 0 : if (cond->op) 221 0 : dispose_word (cond->op); 222 0 : free (cond); 223 : } 224 0 : } 225 : #endif /* COND_COMMAND */ 226 : 227 : void 228 34332868 : dispose_function_def_contents (c) 229 : FUNCTION_DEF *c; 230 : { 231 34332868 : dispose_word (c->name); 232 34332868 : dispose_command (c->command); 233 34332868 : FREE (c->source_file); 234 34332868 : } 235 : 236 : void 237 17166587 : dispose_function_def (c) 238 : FUNCTION_DEF *c; 239 : { 240 17166587 : dispose_function_def_contents (c); 241 17166587 : free (c); 242 17166587 : } 243 : 244 : /* How to free a WORD_DESC. */ 245 : void 246 1240570731 : dispose_word (w) 247 : WORD_DESC *w; 248 : { 249 1240570731 : FREE (w->word); 250 2440812177 : ocache_free (wdcache, WORD_DESC, w); 251 1240570731 : } 252 : 253 : /* Free a WORD_DESC, but not the word contained within. */ 254 : void 255 39287403 : dispose_word_desc (w) 256 : WORD_DESC *w; 257 : { 258 39287403 : w->word = 0; 259 81289273 : ocache_free (wdcache, WORD_DESC, w); 260 39287403 : } 261 : 262 : /* How to get rid of a linked list of words. A WORD_LIST. */ 263 : void 264 538580367 : dispose_words (list) 265 : WORD_LIST *list; 266 : { 267 538580367 : WORD_LIST *t; 268 : 269 538580367 : while (list) 270 : { 271 1150997855 : t = list; 272 1150997855 : list = list->next; 273 1150997855 : dispose_word (t->word); 274 : #if 0 275 : free (t); 276 : #else 277 3916531435 : ocache_free (wlcache, WORD_LIST, t); 278 : #endif 279 : } 280 538580367 : } 281 : 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. */ 285 : void 286 : dispose_word_array (array) 287 : char **array; 288 : { 289 : register int count; 290 : 291 : if (array == 0) 292 : return; 293 : 294 : for (count = 0; array[count]; count++) 295 : free (array[count]); 296 : 297 : free (array); 298 : } 299 : #endif 300 : 301 : /* How to dispose of an list of redirections. A REDIRECT. */ 302 : void 303 274958115 : dispose_redirects (list) 304 : REDIRECT *list; 305 : { 306 274958115 : register REDIRECT *t; 307 : 308 288267126 : while (list) 309 : { 310 13309011 : t = list; 311 13309011 : list = list->next; 312 : 313 13309011 : if (t->rflags & REDIR_VARASSIGN) 314 0 : dispose_word (t->redirector.filename); 315 : 316 13309011 : switch (t->instruction) 317 : { 318 230 : case r_reading_until: 319 : case r_deblank_reading_until: 320 230 : free (t->here_doc_eof); 321 : /*FALLTHROUGH*/ 322 11997913 : case r_reading_string: 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: 328 : case r_append_err_and_out: 329 : case r_input_output: 330 : case r_output_force: 331 : case r_duplicating_input_word: 332 : case r_duplicating_output_word: 333 : case r_move_input_word: 334 : case r_move_output_word: 335 11997913 : dispose_word (t->redirectee.filename); 336 : /* FALLTHROUGH */ 337 : default: 338 13309011 : break; 339 : } 340 13309011 : free (t); 341 : } 342 274958115 : }