LCOV - code coverage report
Current view: top level - bash-4.4.23 - dispose_cmd.c (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 117 149 78.5 %
Date: 2020-10-29 14:49:55 Functions: 8 8 100.0 %

          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   572275482 : dispose_command (command)
      37             :      COMMAND *command;
      38             : {
      39   572275482 :   if (command == 0)
      40             :     return;
      41             : 
      42   485198323 :   if (command->redirects)
      43           9 :     dispose_redirects (command->redirects);
      44             : 
      45   485198323 :   switch (command->type)
      46             :     {
      47     9542894 :     case cm_for:
      48             : #if defined (SELECT_COMMAND)
      49             :     case cm_select:
      50             : #endif
      51             :       {
      52     9542894 :         register FOR_COM *c;
      53             : #if defined (SELECT_COMMAND)
      54     9542894 :         if (command->type == cm_select)
      55           0 :           c = (FOR_COM *)command->value.Select;
      56             :         else
      57             : #endif
      58     9542894 :         c = command->value.For;
      59     9542894 :         dispose_word (c->name);
      60     9542894 :         dispose_words (c->map_list);
      61     9542894 :         dispose_command (c->action);
      62     9542894 :         free (c);
      63     9542894 :         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    18715565 :     case cm_group:
      82             :       {
      83    18715565 :         dispose_command (command->value.Group->command);
      84    18715565 :         free (command->value.Group);
      85    18715565 :         break;
      86             :       }
      87             : 
      88         114 :     case cm_subshell:
      89             :       {
      90         114 :         dispose_command (command->value.Subshell->command);
      91         114 :         free (command->value.Subshell);
      92         114 :         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    15186727 :     case cm_case:
     104             :       {
     105    15186727 :         register CASE_COM *c;
     106    15186727 :         PATTERN_LIST *t, *p;
     107             : 
     108    15186727 :         c = command->value.Case;
     109    15186727 :         dispose_word (c->word);
     110             : 
     111    62512478 :         for (p = c->clauses; p; )
     112             :           {
     113    47325751 :             dispose_words (p->patterns);
     114    47325751 :             dispose_command (p->action);
     115    47325751 :             t = p;
     116    47325751 :             p = p->next;
     117    47325751 :             free (t);
     118             :           }
     119    15186727 :         free (c);
     120    15186727 :         break;
     121             :       }
     122             : 
     123     1833490 :     case cm_until:
     124             :     case cm_while:
     125             :       {
     126     1833490 :         register WHILE_COM *c;
     127             : 
     128     1833490 :         c = command->value.While;
     129     1833490 :         dispose_command (c->test);
     130     1833490 :         dispose_command (c->action);
     131     1833490 :         free (c);
     132     1833490 :         break;
     133             :       }
     134             : 
     135    68066630 :     case cm_if:
     136             :       {
     137    68066630 :         register IF_COM *c;
     138             : 
     139    68066630 :         c = command->value.If;
     140    68066630 :         dispose_command (c->test);
     141    68066630 :         dispose_command (c->true_case);
     142    68066630 :         dispose_command (c->false_case);
     143    68066630 :         free (c);
     144    68066630 :         break;
     145             :       }
     146             : 
     147   268467421 :     case cm_simple:
     148             :       {
     149   268467421 :         register SIMPLE_COM *c;
     150             : 
     151   268467421 :         c = command->value.Simple;
     152   268467421 :         dispose_words (c->words);
     153   268467421 :         dispose_redirects (c->redirects);
     154   268467421 :         free (c);
     155   268467421 :         break;
     156             :       }
     157             : 
     158    84681462 :     case cm_connection:
     159             :       {
     160    84681462 :         register CONNECTION *c;
     161             : 
     162    84681462 :         c = command->value.Connection;
     163    84681462 :         dispose_command (c->first);
     164    84681462 :         dispose_command (c->second);
     165    84681462 :         free (c);
     166    84681462 :         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    18704020 :     case cm_function_def:
     193             :       {
     194    18704020 :         register FUNCTION_DEF *c;
     195             : 
     196    18704020 :         c = command->value.Function_def;
     197    18704020 :         dispose_function_def (c);
     198    18704020 :         break;
     199             :       }
     200             : 
     201           0 :     default:
     202           0 :       command_error ("dispose_command", CMDERR_BADTYPE, command->type, 0);
     203           0 :       break;
     204             :     }
     205   485198323 :   free (command);
     206             : }
     207             : 
     208             : #if defined (COND_COMMAND)
     209             : /* How to free a node in a conditional command. */
     210             : void
     211          18 : dispose_cond_node (cond)
     212             :      COND_COM *cond;
     213             : {
     214          18 :   if (cond)
     215             :     {
     216          18 :       if (cond->left)
     217           0 :         dispose_cond_node (cond->left);
     218          18 :       if (cond->right)
     219           0 :         dispose_cond_node (cond->right);
     220          18 :       if (cond->op)
     221          18 :         dispose_word (cond->op);
     222          18 :       free (cond);
     223             :     }
     224          18 : }
     225             : #endif /* COND_COMMAND */
     226             : 
     227             : void
     228    37407533 : dispose_function_def_contents (c)
     229             :      FUNCTION_DEF *c;
     230             : {
     231    37407533 :   dispose_word (c->name);
     232    37407533 :   dispose_command (c->command);
     233    37407533 :   FREE (c->source_file);
     234    37407533 : }
     235             : 
     236             : void
     237    18704020 : dispose_function_def (c)
     238             :      FUNCTION_DEF *c;
     239             : {
     240    18704020 :   dispose_function_def_contents (c);
     241    18704020 :   free (c);
     242    18704020 : }
     243             : 
     244             : /* How to free a WORD_DESC. */
     245             : void
     246  1319030450 : dispose_word (w)
     247             :      WORD_DESC *w;
     248             : {
     249  1319030450 :   FREE (w->word);
     250  2619425060 :   ocache_free (wdcache, WORD_DESC, w);
     251  1319030450 : }
     252             : 
     253             : /* Free a WORD_DESC, but not the word contained within. */
     254             : void
     255    41985474 : dispose_word_desc (w)
     256             :      WORD_DESC *w;
     257             : {
     258    41985474 :   w->word = 0;
     259    87784878 :   ocache_free (wdcache, WORD_DESC, w);
     260    41985474 : }
     261             : 
     262             : /* How to get rid of a linked list of words.  A WORD_LIST. */
     263             : void
     264   576677343 : dispose_words (list)
     265             :      WORD_LIST *list;
     266             : {
     267   576677343 :   WORD_LIST *t;
     268             : 
     269   576677343 :   while (list)
     270             :     {
     271  1222192080 :       t = list;
     272  1222192080 :       list = list->next;
     273  1222192080 :       dispose_word (t->word);
     274             : #if 0
     275             :       free (t);
     276             : #else
     277  4185036973 :       ocache_free (wlcache, WORD_LIST, t);
     278             : #endif
     279             :     }
     280   576677343 : }
     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   293408975 : dispose_redirects (list)
     304             :      REDIRECT *list;
     305             : {
     306   293408975 :   register REDIRECT *t;
     307             : 
     308   308816957 :   while (list)
     309             :     {
     310    15407982 :       t = list;
     311    15407982 :       list = list->next;
     312             : 
     313    15407982 :       if (t->rflags & REDIR_VARASSIGN)
     314           0 :         dispose_word (t->redirector.filename);
     315             : 
     316    15407982 :       switch (t->instruction)
     317             :         {
     318         292 :         case r_reading_until:
     319             :         case r_deblank_reading_until:
     320         292 :           free (t->here_doc_eof);
     321             :         /*FALLTHROUGH*/
     322    13580006 :         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    13580006 :           dispose_word (t->redirectee.filename);
     336             :           /* FALLTHROUGH */
     337             :         default:
     338    15407982 :           break;
     339             :         }
     340    15407982 :       free (t);
     341             :     }
     342   293408975 : }

Generated by: LCOV version 1.14.0.6.4058