LCOV - code coverage report
Current view: top level - common - ccparray.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 32 47 68.1 %
Date: 2016-11-29 15:00:56 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* ccparray.c - A simple dynamic array for character pointer.
       2             :  * Copyright (C) 2016 g10 Code GmbH
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * This file is free software; you can redistribute it and/or modify
       7             :  * it under the terms of either
       8             :  *
       9             :  *   - the GNU Lesser General Public License as published by the Free
      10             :  *     Software Foundation; either version 3 of the License, or (at
      11             :  *     your option) any later version.
      12             :  *
      13             :  * or
      14             :  *
      15             :  *   - the GNU General Public License as published by the Free
      16             :  *     Software Foundation; either version 2 of the License, or (at
      17             :  *     your option) any later version.
      18             :  *
      19             :  * or both in parallel, as here.
      20             :  *
      21             :  * This file is distributed in the hope that it will be useful,
      22             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :  * GNU General Public License for more details.
      25             :  *
      26             :  * You should have received a copy of the GNU General Public License
      27             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      28             :  */
      29             : 
      30             : #include <config.h>
      31             : #include <stdlib.h>
      32             : #include <errno.h>
      33             : #include <stdarg.h>
      34             : 
      35             : #include "util.h"
      36             : #include "ccparray.h"
      37             : 
      38             : 
      39             : /* A simple implementation of a dynamic array of const char pointers.
      40             :  * The example code:
      41             :  *
      42             :  *   ccparray_t ccp;
      43             :  *   const char **argv;
      44             :  *   int i;
      45             :  *
      46             :  *   ccparray_init (&ccp, 0);
      47             :  *   ccparray_put (&ccp, "First arg");
      48             :  *   ccparray_put (&ccp, "Second arg");
      49             :  *   ccparray_put (&ccp, NULL);
      50             :  *   ccparray_put (&ccp, "Fourth arg");
      51             :  *   argv = ccparray_get (&ccp, NULL);
      52             :  *   if (!argv)
      53             :  *     die ("error building array: %s\n", strerror (errno));
      54             :  *   for (i=0; argv[i]; i++)
      55             :  *     printf ("[%d] = '%s'\n", i, argv[i]);
      56             :  *   xfree (argv);
      57             :  *
      58             :  * will result in this output:
      59             :  *
      60             :  *   [0] = 'First arg'
      61             :  *   [1] = 'Second arg'
      62             :  *
      63             :  * Note that allocation errors are detected but only returned with the
      64             :  * final ccparray_get(); this helps not to clutter the code with out
      65             :  * of core checks.
      66             :  */
      67             : 
      68             : void
      69          24 : ccparray_init (ccparray_t *cpa, unsigned int initialsize)
      70             : {
      71          24 :   if (!initialsize)
      72          24 :     cpa->size = 16;
      73           0 :   else if (initialsize < (1<<16))
      74           0 :     cpa->size = initialsize;
      75             :   else
      76           0 :     cpa->size = (1<<16);
      77             : 
      78          24 :   cpa->count = 0;
      79          24 :   cpa->out_of_core = 0;
      80          24 :   cpa->array = xtrycalloc (cpa->size, sizeof *cpa->array);
      81          24 :   if (!cpa->array)
      82           0 :     cpa->out_of_core = errno;
      83          24 : }
      84             : 
      85             : 
      86             : void
      87        4221 : ccparray_put (ccparray_t *cpa, const char *value)
      88             : {
      89        4221 :   if (cpa->out_of_core)
      90           0 :     return;
      91             : 
      92        4221 :   if (cpa->count + 1 >= cpa->size)
      93             :     {
      94             :       const char **newarray;
      95             :       size_t n, newsize;
      96             : 
      97           9 :       if (cpa->size < 8)
      98           0 :         newsize = 16;
      99           9 :       else if (cpa->size < 4096)
     100           8 :         newsize = 2 * cpa->size;
     101           1 :       else if (cpa->size < (1<<16))
     102           1 :         newsize = cpa->size + 2048;
     103             :       else
     104             :         {
     105           0 :           cpa->out_of_core = ENOMEM;
     106           0 :           return;
     107             :         }
     108             : 
     109           9 :       newarray = xtrycalloc (newsize, sizeof *newarray);
     110           9 :       if (!newarray)
     111             :         {
     112           0 :           cpa->out_of_core = errno ? errno : ENOMEM;
     113           0 :           return;
     114             :         }
     115        8185 :       for (n=0; n < cpa->size; n++)
     116        8176 :         newarray[n] = cpa->array[n];
     117           9 :       xfree (cpa->array);
     118           9 :       cpa->array = newarray;
     119           9 :       cpa->size = newsize;
     120             : 
     121             :     }
     122        4221 :   cpa->array[cpa->count++] = value;
     123             : }
     124             : 
     125             : 
     126             : const char **
     127          24 : ccparray_get (ccparray_t *cpa, size_t *r_count)
     128             : {
     129             :   const char **result;
     130             : 
     131          24 :   if (cpa->out_of_core)
     132             :     {
     133           0 :       if (cpa->array)
     134             :         {
     135           0 :           xfree (cpa->array);
     136           0 :           cpa->array = NULL;
     137             :         }
     138           0 :       gpg_err_set_errno (cpa->out_of_core);
     139           0 :       return NULL;
     140             :     }
     141             : 
     142          24 :   result= cpa->array;
     143          24 :   if (r_count)
     144           6 :     *r_count = cpa->count;
     145          24 :   cpa->array = NULL;
     146          24 :   cpa->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
     147          24 :   return result;
     148             : }

Generated by: LCOV version 1.11