1 /* ccparray.c - A simple dynamic array for character pointer.
2 * Copyright (C) 2016 g10 Code GmbH
4 * This file is part of GnuPG.
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of either
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.
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.
19 * or both in parallel, as here.
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.
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/>.
39 /* A simple implementation of a dynamic array of const char pointers.
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);
53 * die ("error building array: %s\n", strerror (errno));
54 * for (i=0; argv[i]; i++)
55 * printf ("[%d] = '%s'\n", i, argv[i]);
58 * will result in this output:
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
69 ccparray_init (ccparray_t *cpa, unsigned int initialsize)
73 else if (initialsize < (1<<16))
74 cpa->size = initialsize;
80 cpa->array = xtrycalloc (cpa->size, sizeof *cpa->array);
82 cpa->out_of_core = errno;
87 ccparray_put (ccparray_t *cpa, const char *value)
92 if (cpa->count + 1 >= cpa->size)
94 const char **newarray;
99 else if (cpa->size < 4096)
100 newsize = 2 * cpa->size;
101 else if (cpa->size < (1<<16))
102 newsize = cpa->size + 2048;
105 cpa->out_of_core = ENOMEM;
109 newarray = xtrycalloc (newsize, sizeof *newarray);
112 cpa->out_of_core = errno ? errno : ENOMEM;
115 for (n=0; n < cpa->size; n++)
116 newarray[n] = cpa->array[n];
118 cpa->array = newarray;
122 cpa->array[cpa->count++] = value;
127 ccparray_get (ccparray_t *cpa, size_t *r_count)
131 if (cpa->out_of_core)
138 gpg_err_set_errno (cpa->out_of_core);
144 *r_count = cpa->count;
146 cpa->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */