1 /*
2 * Copyright 2008-2013 Various Authors
3 * Copyright 2008 Timo Hirvonen
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "debug.h"
20 #include "keyval.h"
21 #include "xmalloc.h"
22
23 #include <strings.h>
24
keyvals_new(int num)25 struct keyval *keyvals_new(int num)
26 {
27 struct keyval *c = xnew(struct keyval, num + 1);
28 int i;
29
30 for (i = 0; i <= num; i++) {
31 c[i].key = NULL;
32 c[i].val = NULL;
33 }
34 return c;
35 }
36
keyvals_dup(const struct keyval * keyvals)37 struct keyval *keyvals_dup(const struct keyval *keyvals)
38 {
39 struct keyval *c;
40 int i;
41
42 for (i = 0; keyvals[i].key; i++)
43 ; /* nothing */
44 c = xnew(struct keyval, i + 1);
45 for (i = 0; keyvals[i].key; i++) {
46 c[i].key = xstrdup(keyvals[i].key);
47 c[i].val = xstrdup(keyvals[i].val);
48 }
49 c[i].key = NULL;
50 c[i].val = NULL;
51 return c;
52 }
53
keyvals_free(struct keyval * keyvals)54 void keyvals_free(struct keyval *keyvals)
55 {
56 int i;
57
58 for (i = 0; keyvals[i].key; i++) {
59 free(keyvals[i].key);
60 free(keyvals[i].val);
61 }
62 free(keyvals);
63 }
64
keyvals_get_val(const struct keyval * keyvals,const char * key)65 const char *keyvals_get_val(const struct keyval *keyvals, const char *key)
66 {
67 int i;
68
69 for (i = 0; keyvals[i].key; i++) {
70 if (strcasecmp(keyvals[i].key, key) == 0)
71 return keyvals[i].val;
72 }
73 return NULL;
74 }
75
keyvals_init(struct growing_keyvals * c,const struct keyval * keyvals)76 void keyvals_init(struct growing_keyvals *c, const struct keyval *keyvals)
77 {
78 int i;
79
80 BUG_ON(c->keyvals);
81
82 for (i = 0; keyvals[i].key; i++)
83 ; /* nothing */
84
85 c->keyvals = keyvals_dup(keyvals);
86 c->alloc = i;
87 c->count = i;
88 }
89
keyvals_add(struct growing_keyvals * c,const char * key,char * val)90 void keyvals_add(struct growing_keyvals *c, const char *key, char *val)
91 {
92 int n = c->count + 1;
93
94 if (n > c->alloc) {
95 n = (n + 3) & ~3;
96 c->keyvals = xrenew(struct keyval, c->keyvals, n);
97 c->alloc = n;
98 }
99
100 c->keyvals[c->count].key = xstrdup(key);
101 c->keyvals[c->count].val = val;
102 c->count++;
103 }
104
keyvals_get_val_growing(const struct growing_keyvals * c,const char * key)105 const char *keyvals_get_val_growing(const struct growing_keyvals *c, const char *key)
106 {
107 int i;
108
109 for (i = 0; i < c->count; ++i)
110 if (strcasecmp(c->keyvals[i].key, key) == 0)
111 return c->keyvals[i].val;
112
113 return NULL;
114 }
115
keyvals_terminate(struct growing_keyvals * c)116 void keyvals_terminate(struct growing_keyvals *c)
117 {
118 int alloc = c->count + 1;
119
120 if (alloc > c->alloc) {
121 c->keyvals = xrenew(struct keyval, c->keyvals, alloc);
122 c->alloc = alloc;
123 }
124 c->keyvals[c->count].key = NULL;
125 c->keyvals[c->count].val = NULL;
126 }
127