Code

b6a49e10ab36831d709f559cda7de4f5cfd8d79a
[sysdb.git] / src / utils / strings.c
1 /*
2  * SysDB - src/utils/strings.c
3  * Copyright (C) 2016 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #if HAVE_CONFIG_H
29 #       include "config.h"
30 #endif
32 #include "utils/strings.h"
34 #include <assert.h>
36 #include <stdlib.h>
37 #include <string.h>
39 /*
40  * private helper functions
41  */
43 static int
44 ensure_len(char ***s, size_t *s_len, size_t len)
45 {
46         char **tmp;
48         if ((! s) || (! s_len))
49                 return -1;
51         if (! len) {
52                 if (*s)
53                         free(*s);
54                 *s = NULL;
55                 *s_len = 0;
56                 return 0;
57         }
59         if (*s) {
60                 tmp = realloc(*s, len * sizeof(*tmp));
61                 if (tmp && (len > *s_len))
62                         memset(tmp + *s_len, 0, (len - *s_len) * sizeof(*tmp));
63         }
64         else
65                 tmp = calloc(len, sizeof(*tmp));
67         if (! tmp)
68                 return -1;
70         *s = tmp;
71         *s_len = len;
72         return 0;
73 } /* ensure_len */
75 /*
76  * public API
77  */
79 int
80 stringv_copy(char ***dst, size_t *dst_len,
81                 const char * const *src, size_t src_len)
82 {
83         size_t i;
85         if (src_len && (! src))
86                 return -1;
87         if (ensure_len(dst, dst_len, src_len))
88                 return -1;
89         assert(dst);
91         for (i = 0; i < src_len; ++i) {
92                 if ((*dst)[i])
93                         free((*dst)[i]);
94                 (*dst)[i] = strdup(src[i]);
95                 if (! (*dst)[i])
96                         return -1;
97         }
98         return 0;
99 } /* stringv_copy */
101 int
102 stringv_append(char ***s, size_t *s_len, const char *elem)
104         size_t i;
106         if ((! s_len) || ensure_len(s, s_len, *s_len + 1))
107                 return -1;
108         assert(s);
110         i = *s_len - 1;
111         (*s)[i] = strdup(elem);
112         if (! (*s)[i])
113                 return -1;
114         return 0;
115 } /* stringv_append */
117 void
118 stringv_free(char ***s, size_t *s_len)
120         size_t i;
122         if (*s) {
123                 for (i = 0; i < *s_len; ++i) {
124                         if ((*s)[i])
125                                 free((*s)[i]);
126                         (*s)[i] = NULL;
127                 }
128                 free(*s);
129         }
131         *s = NULL;
132         *s_len = 0;
133 } /* stringv_free */
135 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */