1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2e42620beSDaniel Verkamp * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3*a6dbe372Spaul luse * Copyright (C) 2016 Intel Corporation.
4e42620beSDaniel Verkamp * All rights reserved.
5e42620beSDaniel Verkamp */
6e42620beSDaniel Verkamp
7b961d9ccSBen Walker #include "spdk/stdinc.h"
8b961d9ccSBen Walker
9e42620beSDaniel Verkamp #include "spdk/conf.h"
10e42620beSDaniel Verkamp #include "spdk/string.h"
112d2fde0dSEd Rodriguez #include "spdk/log.h"
12e42620beSDaniel Verkamp
13396c32c4SDaniel Verkamp struct spdk_conf_value {
14396c32c4SDaniel Verkamp struct spdk_conf_value *next;
15396c32c4SDaniel Verkamp char *value;
16396c32c4SDaniel Verkamp };
17396c32c4SDaniel Verkamp
18396c32c4SDaniel Verkamp struct spdk_conf_item {
19396c32c4SDaniel Verkamp struct spdk_conf_item *next;
20396c32c4SDaniel Verkamp char *key;
21396c32c4SDaniel Verkamp struct spdk_conf_value *val;
22396c32c4SDaniel Verkamp };
23396c32c4SDaniel Verkamp
24396c32c4SDaniel Verkamp struct spdk_conf_section {
25396c32c4SDaniel Verkamp struct spdk_conf_section *next;
26396c32c4SDaniel Verkamp char *name;
27396c32c4SDaniel Verkamp int num;
28396c32c4SDaniel Verkamp struct spdk_conf_item *item;
29396c32c4SDaniel Verkamp };
30396c32c4SDaniel Verkamp
31396c32c4SDaniel Verkamp struct spdk_conf {
32396c32c4SDaniel Verkamp char *file;
33396c32c4SDaniel Verkamp struct spdk_conf_section *current_section;
34396c32c4SDaniel Verkamp struct spdk_conf_section *section;
35800b18d0SVitaliy Mysak bool merge_sections;
36396c32c4SDaniel Verkamp };
37396c32c4SDaniel Verkamp
38e42620beSDaniel Verkamp #define CF_DELIM " \t"
39367c980bSVitaliy Mysak #define CF_DELIM_KEY " \t="
40e42620beSDaniel Verkamp
41e42620beSDaniel Verkamp #define LIB_MAX_TMPBUF 1024
42e42620beSDaniel Verkamp
43e42620beSDaniel Verkamp static struct spdk_conf *default_config = NULL;
44e42620beSDaniel Verkamp
45e42620beSDaniel Verkamp struct spdk_conf *
spdk_conf_allocate(void)46e42620beSDaniel Verkamp spdk_conf_allocate(void)
47e42620beSDaniel Verkamp {
48800b18d0SVitaliy Mysak struct spdk_conf *ret = calloc(1, sizeof(struct spdk_conf));
49800b18d0SVitaliy Mysak
50800b18d0SVitaliy Mysak if (ret) {
51800b18d0SVitaliy Mysak ret->merge_sections = true;
52800b18d0SVitaliy Mysak }
53800b18d0SVitaliy Mysak
54800b18d0SVitaliy Mysak return ret;
55e42620beSDaniel Verkamp }
56e42620beSDaniel Verkamp
57e42620beSDaniel Verkamp static void
free_conf_value(struct spdk_conf_value * vp)58e42620beSDaniel Verkamp free_conf_value(struct spdk_conf_value *vp)
59e42620beSDaniel Verkamp {
60e42620beSDaniel Verkamp if (vp == NULL) {
61e42620beSDaniel Verkamp return;
62e42620beSDaniel Verkamp }
63e42620beSDaniel Verkamp
64e42620beSDaniel Verkamp if (vp->value) {
65e42620beSDaniel Verkamp free(vp->value);
66e42620beSDaniel Verkamp }
67e42620beSDaniel Verkamp
68e42620beSDaniel Verkamp free(vp);
69e42620beSDaniel Verkamp }
70e42620beSDaniel Verkamp
71e42620beSDaniel Verkamp static void
free_all_conf_value(struct spdk_conf_value * vp)72e42620beSDaniel Verkamp free_all_conf_value(struct spdk_conf_value *vp)
73e42620beSDaniel Verkamp {
74e42620beSDaniel Verkamp struct spdk_conf_value *next;
75e42620beSDaniel Verkamp
76e42620beSDaniel Verkamp if (vp == NULL) {
77e42620beSDaniel Verkamp return;
78e42620beSDaniel Verkamp }
79e42620beSDaniel Verkamp
80e42620beSDaniel Verkamp while (vp != NULL) {
81e42620beSDaniel Verkamp next = vp->next;
82e42620beSDaniel Verkamp free_conf_value(vp);
83e42620beSDaniel Verkamp vp = next;
84e42620beSDaniel Verkamp }
85e42620beSDaniel Verkamp }
86e42620beSDaniel Verkamp
87e42620beSDaniel Verkamp static void
free_conf_item(struct spdk_conf_item * ip)88e42620beSDaniel Verkamp free_conf_item(struct spdk_conf_item *ip)
89e42620beSDaniel Verkamp {
90e42620beSDaniel Verkamp if (ip == NULL) {
91e42620beSDaniel Verkamp return;
92e42620beSDaniel Verkamp }
93e42620beSDaniel Verkamp
94e42620beSDaniel Verkamp if (ip->val != NULL) {
95e42620beSDaniel Verkamp free_all_conf_value(ip->val);
96e42620beSDaniel Verkamp }
97e42620beSDaniel Verkamp
98e42620beSDaniel Verkamp if (ip->key != NULL) {
99e42620beSDaniel Verkamp free(ip->key);
100e42620beSDaniel Verkamp }
101e42620beSDaniel Verkamp
102e42620beSDaniel Verkamp free(ip);
103e42620beSDaniel Verkamp }
104e42620beSDaniel Verkamp
105e42620beSDaniel Verkamp static void
free_all_conf_item(struct spdk_conf_item * ip)106e42620beSDaniel Verkamp free_all_conf_item(struct spdk_conf_item *ip)
107e42620beSDaniel Verkamp {
108e42620beSDaniel Verkamp struct spdk_conf_item *next;
109e42620beSDaniel Verkamp
110e42620beSDaniel Verkamp if (ip == NULL) {
111e42620beSDaniel Verkamp return;
112e42620beSDaniel Verkamp }
113e42620beSDaniel Verkamp
114e42620beSDaniel Verkamp while (ip != NULL) {
115e42620beSDaniel Verkamp next = ip->next;
116e42620beSDaniel Verkamp free_conf_item(ip);
117e42620beSDaniel Verkamp ip = next;
118e42620beSDaniel Verkamp }
119e42620beSDaniel Verkamp }
120e42620beSDaniel Verkamp
121e42620beSDaniel Verkamp static void
free_conf_section(struct spdk_conf_section * sp)122e42620beSDaniel Verkamp free_conf_section(struct spdk_conf_section *sp)
123e42620beSDaniel Verkamp {
124e42620beSDaniel Verkamp if (sp == NULL) {
125e42620beSDaniel Verkamp return;
126e42620beSDaniel Verkamp }
127e42620beSDaniel Verkamp
128e42620beSDaniel Verkamp if (sp->item) {
129e42620beSDaniel Verkamp free_all_conf_item(sp->item);
130e42620beSDaniel Verkamp }
131e42620beSDaniel Verkamp
132e42620beSDaniel Verkamp if (sp->name) {
133e42620beSDaniel Verkamp free(sp->name);
134e42620beSDaniel Verkamp }
135e42620beSDaniel Verkamp
136e42620beSDaniel Verkamp free(sp);
137e42620beSDaniel Verkamp }
138e42620beSDaniel Verkamp
139e42620beSDaniel Verkamp static void
free_all_conf_section(struct spdk_conf_section * sp)140e42620beSDaniel Verkamp free_all_conf_section(struct spdk_conf_section *sp)
141e42620beSDaniel Verkamp {
142e42620beSDaniel Verkamp struct spdk_conf_section *next;
143e42620beSDaniel Verkamp
144e42620beSDaniel Verkamp if (sp == NULL) {
145e42620beSDaniel Verkamp return;
146e42620beSDaniel Verkamp }
147e42620beSDaniel Verkamp
148e42620beSDaniel Verkamp while (sp != NULL) {
149e42620beSDaniel Verkamp next = sp->next;
150e42620beSDaniel Verkamp free_conf_section(sp);
151e42620beSDaniel Verkamp sp = next;
152e42620beSDaniel Verkamp }
153e42620beSDaniel Verkamp }
154e42620beSDaniel Verkamp
155e42620beSDaniel Verkamp void
spdk_conf_free(struct spdk_conf * cp)156e42620beSDaniel Verkamp spdk_conf_free(struct spdk_conf *cp)
157e42620beSDaniel Verkamp {
158e42620beSDaniel Verkamp if (cp == NULL) {
159e42620beSDaniel Verkamp return;
160e42620beSDaniel Verkamp }
161e42620beSDaniel Verkamp
162e42620beSDaniel Verkamp if (cp->section != NULL) {
163e42620beSDaniel Verkamp free_all_conf_section(cp->section);
164e42620beSDaniel Verkamp }
165e42620beSDaniel Verkamp
166e42620beSDaniel Verkamp if (cp->file != NULL) {
167e42620beSDaniel Verkamp free(cp->file);
168e42620beSDaniel Verkamp }
169e42620beSDaniel Verkamp
170e42620beSDaniel Verkamp free(cp);
171e42620beSDaniel Verkamp }
172e42620beSDaniel Verkamp
173e42620beSDaniel Verkamp static struct spdk_conf_section *
allocate_cf_section(void)174e42620beSDaniel Verkamp allocate_cf_section(void)
175e42620beSDaniel Verkamp {
176e42620beSDaniel Verkamp return calloc(1, sizeof(struct spdk_conf_section));
177e42620beSDaniel Verkamp }
178e42620beSDaniel Verkamp
179e42620beSDaniel Verkamp static struct spdk_conf_item *
allocate_cf_item(void)180e42620beSDaniel Verkamp allocate_cf_item(void)
181e42620beSDaniel Verkamp {
182e42620beSDaniel Verkamp return calloc(1, sizeof(struct spdk_conf_item));
183e42620beSDaniel Verkamp }
184e42620beSDaniel Verkamp
185e42620beSDaniel Verkamp static struct spdk_conf_value *
allocate_cf_value(void)186e42620beSDaniel Verkamp allocate_cf_value(void)
187e42620beSDaniel Verkamp {
188e42620beSDaniel Verkamp return calloc(1, sizeof(struct spdk_conf_value));
189e42620beSDaniel Verkamp }
190e42620beSDaniel Verkamp
191e42620beSDaniel Verkamp
192e42620beSDaniel Verkamp #define CHECK_CP_OR_USE_DEFAULT(cp) (((cp) == NULL) && (default_config != NULL)) ? default_config : (cp)
193e42620beSDaniel Verkamp
194e42620beSDaniel Verkamp struct spdk_conf_section *
spdk_conf_find_section(struct spdk_conf * cp,const char * name)195e42620beSDaniel Verkamp spdk_conf_find_section(struct spdk_conf *cp, const char *name)
196e42620beSDaniel Verkamp {
197e42620beSDaniel Verkamp struct spdk_conf_section *sp;
198e42620beSDaniel Verkamp
199e42620beSDaniel Verkamp if (name == NULL || name[0] == '\0') {
200e42620beSDaniel Verkamp return NULL;
201e42620beSDaniel Verkamp }
202e42620beSDaniel Verkamp
203e42620beSDaniel Verkamp cp = CHECK_CP_OR_USE_DEFAULT(cp);
204e42620beSDaniel Verkamp if (cp == NULL) {
205e42620beSDaniel Verkamp return NULL;
206e42620beSDaniel Verkamp }
207e42620beSDaniel Verkamp
208e42620beSDaniel Verkamp for (sp = cp->section; sp != NULL; sp = sp->next) {
209e42620beSDaniel Verkamp if (sp->name != NULL && sp->name[0] == name[0]
210e42620beSDaniel Verkamp && strcasecmp(sp->name, name) == 0) {
211e42620beSDaniel Verkamp return sp;
212e42620beSDaniel Verkamp }
213e42620beSDaniel Verkamp }
214e42620beSDaniel Verkamp
215e42620beSDaniel Verkamp return NULL;
216e42620beSDaniel Verkamp }
217e42620beSDaniel Verkamp
21820f59ee1SBen Walker struct spdk_conf_section *
spdk_conf_first_section(struct spdk_conf * cp)21920f59ee1SBen Walker spdk_conf_first_section(struct spdk_conf *cp)
22020f59ee1SBen Walker {
22120f59ee1SBen Walker cp = CHECK_CP_OR_USE_DEFAULT(cp);
22220f59ee1SBen Walker if (cp == NULL) {
22320f59ee1SBen Walker return NULL;
22420f59ee1SBen Walker }
22520f59ee1SBen Walker
22620f59ee1SBen Walker return cp->section;
22720f59ee1SBen Walker }
22820f59ee1SBen Walker
22920f59ee1SBen Walker struct spdk_conf_section *
spdk_conf_next_section(struct spdk_conf_section * sp)23020f59ee1SBen Walker spdk_conf_next_section(struct spdk_conf_section *sp)
23120f59ee1SBen Walker {
23220f59ee1SBen Walker if (sp == NULL) {
23320f59ee1SBen Walker return NULL;
23420f59ee1SBen Walker }
23520f59ee1SBen Walker
23620f59ee1SBen Walker return sp->next;
23720f59ee1SBen Walker }
23820f59ee1SBen Walker
239e42620beSDaniel Verkamp static void
append_cf_section(struct spdk_conf * cp,struct spdk_conf_section * sp)240e42620beSDaniel Verkamp append_cf_section(struct spdk_conf *cp, struct spdk_conf_section *sp)
241e42620beSDaniel Verkamp {
242e42620beSDaniel Verkamp struct spdk_conf_section *last;
243e42620beSDaniel Verkamp
244e42620beSDaniel Verkamp cp = CHECK_CP_OR_USE_DEFAULT(cp);
245e42620beSDaniel Verkamp if (cp == NULL) {
2462d2fde0dSEd Rodriguez SPDK_ERRLOG("cp == NULL\n");
247e42620beSDaniel Verkamp return;
248e42620beSDaniel Verkamp }
249e42620beSDaniel Verkamp
250e42620beSDaniel Verkamp if (cp->section == NULL) {
251e42620beSDaniel Verkamp cp->section = sp;
252e42620beSDaniel Verkamp return;
253e42620beSDaniel Verkamp }
254e42620beSDaniel Verkamp
255e42620beSDaniel Verkamp for (last = cp->section; last->next != NULL; last = last->next)
256e42620beSDaniel Verkamp ;
257e42620beSDaniel Verkamp last->next = sp;
258e42620beSDaniel Verkamp }
259e42620beSDaniel Verkamp
260e42620beSDaniel Verkamp static struct spdk_conf_item *
find_cf_nitem(struct spdk_conf_section * sp,const char * key,int idx)261e42620beSDaniel Verkamp find_cf_nitem(struct spdk_conf_section *sp, const char *key, int idx)
262e42620beSDaniel Verkamp {
263e42620beSDaniel Verkamp struct spdk_conf_item *ip;
264e42620beSDaniel Verkamp int i;
265e42620beSDaniel Verkamp
266e42620beSDaniel Verkamp if (key == NULL || key[0] == '\0') {
267e42620beSDaniel Verkamp return NULL;
268e42620beSDaniel Verkamp }
269e42620beSDaniel Verkamp
270e42620beSDaniel Verkamp i = 0;
271e42620beSDaniel Verkamp for (ip = sp->item; ip != NULL; ip = ip->next) {
272e42620beSDaniel Verkamp if (ip->key != NULL && ip->key[0] == key[0]
273e42620beSDaniel Verkamp && strcasecmp(ip->key, key) == 0) {
274e42620beSDaniel Verkamp if (i == idx) {
275e42620beSDaniel Verkamp return ip;
276e42620beSDaniel Verkamp }
277e42620beSDaniel Verkamp i++;
278e42620beSDaniel Verkamp }
279e42620beSDaniel Verkamp }
280e42620beSDaniel Verkamp
281e42620beSDaniel Verkamp return NULL;
282e42620beSDaniel Verkamp }
283e42620beSDaniel Verkamp
284e42620beSDaniel Verkamp static void
append_cf_item(struct spdk_conf_section * sp,struct spdk_conf_item * ip)285e42620beSDaniel Verkamp append_cf_item(struct spdk_conf_section *sp, struct spdk_conf_item *ip)
286e42620beSDaniel Verkamp {
287e42620beSDaniel Verkamp struct spdk_conf_item *last;
288e42620beSDaniel Verkamp
289e42620beSDaniel Verkamp if (sp == NULL) {
290e42620beSDaniel Verkamp return;
291e42620beSDaniel Verkamp }
292e42620beSDaniel Verkamp
293e42620beSDaniel Verkamp if (sp->item == NULL) {
294e42620beSDaniel Verkamp sp->item = ip;
295e42620beSDaniel Verkamp return;
296e42620beSDaniel Verkamp }
297e42620beSDaniel Verkamp
298e42620beSDaniel Verkamp for (last = sp->item; last->next != NULL; last = last->next)
299e42620beSDaniel Verkamp ;
300e42620beSDaniel Verkamp last->next = ip;
301e42620beSDaniel Verkamp }
302e42620beSDaniel Verkamp
303e42620beSDaniel Verkamp static void
append_cf_value(struct spdk_conf_item * ip,struct spdk_conf_value * vp)304e42620beSDaniel Verkamp append_cf_value(struct spdk_conf_item *ip, struct spdk_conf_value *vp)
305e42620beSDaniel Verkamp {
306e42620beSDaniel Verkamp struct spdk_conf_value *last;
307e42620beSDaniel Verkamp
308e42620beSDaniel Verkamp if (ip == NULL) {
309e42620beSDaniel Verkamp return;
310e42620beSDaniel Verkamp }
311e42620beSDaniel Verkamp
312e42620beSDaniel Verkamp if (ip->val == NULL) {
313e42620beSDaniel Verkamp ip->val = vp;
314e42620beSDaniel Verkamp return;
315e42620beSDaniel Verkamp }
316e42620beSDaniel Verkamp
317e42620beSDaniel Verkamp for (last = ip->val; last->next != NULL; last = last->next)
318e42620beSDaniel Verkamp ;
319e42620beSDaniel Verkamp last->next = vp;
320e42620beSDaniel Verkamp }
321e42620beSDaniel Verkamp
322e42620beSDaniel Verkamp bool
spdk_conf_section_match_prefix(const struct spdk_conf_section * sp,const char * name_prefix)323e42620beSDaniel Verkamp spdk_conf_section_match_prefix(const struct spdk_conf_section *sp, const char *name_prefix)
324e42620beSDaniel Verkamp {
325e42620beSDaniel Verkamp return strncasecmp(sp->name, name_prefix, strlen(name_prefix)) == 0;
326e42620beSDaniel Verkamp }
327e42620beSDaniel Verkamp
32804c48172SDaniel Verkamp const char *
spdk_conf_section_get_name(const struct spdk_conf_section * sp)32904c48172SDaniel Verkamp spdk_conf_section_get_name(const struct spdk_conf_section *sp)
33004c48172SDaniel Verkamp {
33104c48172SDaniel Verkamp return sp->name;
33204c48172SDaniel Verkamp }
33304c48172SDaniel Verkamp
33404c48172SDaniel Verkamp int
spdk_conf_section_get_num(const struct spdk_conf_section * sp)33504c48172SDaniel Verkamp spdk_conf_section_get_num(const struct spdk_conf_section *sp)
33604c48172SDaniel Verkamp {
33704c48172SDaniel Verkamp return sp->num;
33804c48172SDaniel Verkamp }
33904c48172SDaniel Verkamp
340e42620beSDaniel Verkamp char *
spdk_conf_section_get_nmval(struct spdk_conf_section * sp,const char * key,int idx1,int idx2)341e42620beSDaniel Verkamp spdk_conf_section_get_nmval(struct spdk_conf_section *sp, const char *key, int idx1, int idx2)
342e42620beSDaniel Verkamp {
343e42620beSDaniel Verkamp struct spdk_conf_item *ip;
344e42620beSDaniel Verkamp struct spdk_conf_value *vp;
345e42620beSDaniel Verkamp int i;
346e42620beSDaniel Verkamp
347e42620beSDaniel Verkamp ip = find_cf_nitem(sp, key, idx1);
348e42620beSDaniel Verkamp if (ip == NULL) {
349e42620beSDaniel Verkamp return NULL;
350e42620beSDaniel Verkamp }
351e42620beSDaniel Verkamp
352e42620beSDaniel Verkamp vp = ip->val;
353e42620beSDaniel Verkamp if (vp == NULL) {
354e42620beSDaniel Verkamp return NULL;
355e42620beSDaniel Verkamp }
356e42620beSDaniel Verkamp
357e42620beSDaniel Verkamp for (i = 0; vp != NULL; vp = vp->next, i++) {
358e42620beSDaniel Verkamp if (i == idx2) {
359e42620beSDaniel Verkamp return vp->value;
360e42620beSDaniel Verkamp }
361e42620beSDaniel Verkamp }
362e42620beSDaniel Verkamp
363e42620beSDaniel Verkamp return NULL;
364e42620beSDaniel Verkamp }
365e42620beSDaniel Verkamp
366e42620beSDaniel Verkamp char *
spdk_conf_section_get_nval(struct spdk_conf_section * sp,const char * key,int idx)367e42620beSDaniel Verkamp spdk_conf_section_get_nval(struct spdk_conf_section *sp, const char *key, int idx)
368e42620beSDaniel Verkamp {
369e42620beSDaniel Verkamp struct spdk_conf_item *ip;
370e42620beSDaniel Verkamp struct spdk_conf_value *vp;
371e42620beSDaniel Verkamp
372e42620beSDaniel Verkamp ip = find_cf_nitem(sp, key, idx);
373e42620beSDaniel Verkamp if (ip == NULL) {
374e42620beSDaniel Verkamp return NULL;
375e42620beSDaniel Verkamp }
376e42620beSDaniel Verkamp
377e42620beSDaniel Verkamp vp = ip->val;
378e42620beSDaniel Verkamp if (vp == NULL) {
379e42620beSDaniel Verkamp return NULL;
380e42620beSDaniel Verkamp }
381e42620beSDaniel Verkamp
382e42620beSDaniel Verkamp return vp->value;
383e42620beSDaniel Verkamp }
384e42620beSDaniel Verkamp
385e42620beSDaniel Verkamp char *
spdk_conf_section_get_val(struct spdk_conf_section * sp,const char * key)386e42620beSDaniel Verkamp spdk_conf_section_get_val(struct spdk_conf_section *sp, const char *key)
387e42620beSDaniel Verkamp {
388e42620beSDaniel Verkamp return spdk_conf_section_get_nval(sp, key, 0);
389e42620beSDaniel Verkamp }
390e42620beSDaniel Verkamp
391e42620beSDaniel Verkamp int
spdk_conf_section_get_intval(struct spdk_conf_section * sp,const char * key)392e42620beSDaniel Verkamp spdk_conf_section_get_intval(struct spdk_conf_section *sp, const char *key)
393e42620beSDaniel Verkamp {
394e42620beSDaniel Verkamp const char *v;
395e42620beSDaniel Verkamp int value;
396e42620beSDaniel Verkamp
397e42620beSDaniel Verkamp v = spdk_conf_section_get_nval(sp, key, 0);
398e42620beSDaniel Verkamp if (v == NULL) {
399e42620beSDaniel Verkamp return -1;
400e42620beSDaniel Verkamp }
401e42620beSDaniel Verkamp
402b78e763cSShuhei Matsumoto value = (int)spdk_strtol(v, 10);
403e42620beSDaniel Verkamp return value;
404e42620beSDaniel Verkamp }
405e42620beSDaniel Verkamp
406edbca2a6SDaniel Verkamp bool
spdk_conf_section_get_boolval(struct spdk_conf_section * sp,const char * key,bool default_val)407edbca2a6SDaniel Verkamp spdk_conf_section_get_boolval(struct spdk_conf_section *sp, const char *key, bool default_val)
408edbca2a6SDaniel Verkamp {
409edbca2a6SDaniel Verkamp const char *v;
410edbca2a6SDaniel Verkamp
411edbca2a6SDaniel Verkamp v = spdk_conf_section_get_nval(sp, key, 0);
412edbca2a6SDaniel Verkamp if (v == NULL) {
413edbca2a6SDaniel Verkamp return default_val;
414edbca2a6SDaniel Verkamp }
415edbca2a6SDaniel Verkamp
416edbca2a6SDaniel Verkamp if (!strcasecmp(v, "Yes") || !strcasecmp(v, "Y") || !strcasecmp(v, "True")) {
417edbca2a6SDaniel Verkamp return true;
418edbca2a6SDaniel Verkamp }
419edbca2a6SDaniel Verkamp
420edbca2a6SDaniel Verkamp if (!strcasecmp(v, "No") || !strcasecmp(v, "N") || !strcasecmp(v, "False")) {
421edbca2a6SDaniel Verkamp return false;
422edbca2a6SDaniel Verkamp }
423edbca2a6SDaniel Verkamp
424edbca2a6SDaniel Verkamp return default_val;
425edbca2a6SDaniel Verkamp }
426edbca2a6SDaniel Verkamp
427e42620beSDaniel Verkamp static int
parse_line(struct spdk_conf * cp,char * lp)428e42620beSDaniel Verkamp parse_line(struct spdk_conf *cp, char *lp)
429e42620beSDaniel Verkamp {
430e42620beSDaniel Verkamp struct spdk_conf_section *sp;
431e42620beSDaniel Verkamp struct spdk_conf_item *ip;
432e42620beSDaniel Verkamp struct spdk_conf_value *vp;
433e42620beSDaniel Verkamp char *arg;
434e42620beSDaniel Verkamp char *key;
435e42620beSDaniel Verkamp char *val;
436e42620beSDaniel Verkamp char *p;
437e42620beSDaniel Verkamp int num;
438e42620beSDaniel Verkamp
439e42620beSDaniel Verkamp arg = spdk_str_trim(lp);
440e42620beSDaniel Verkamp if (arg == NULL) {
4412d2fde0dSEd Rodriguez SPDK_ERRLOG("no section\n");
442e42620beSDaniel Verkamp return -1;
443e42620beSDaniel Verkamp }
444e42620beSDaniel Verkamp
445e42620beSDaniel Verkamp if (arg[0] == '[') {
446e42620beSDaniel Verkamp /* section */
447e42620beSDaniel Verkamp arg++;
448e42620beSDaniel Verkamp key = spdk_strsepq(&arg, "]");
449e42620beSDaniel Verkamp if (key == NULL || arg != NULL) {
4502d2fde0dSEd Rodriguez SPDK_ERRLOG("broken section\n");
451e42620beSDaniel Verkamp return -1;
452e42620beSDaniel Verkamp }
453e42620beSDaniel Verkamp /* determine section number */
454e42620beSDaniel Verkamp for (p = key; *p != '\0' && !isdigit((int) *p); p++)
455e42620beSDaniel Verkamp ;
456e42620beSDaniel Verkamp if (*p != '\0') {
457b78e763cSShuhei Matsumoto num = (int)spdk_strtol(p, 10);
458e42620beSDaniel Verkamp } else {
459e42620beSDaniel Verkamp num = 0;
460e42620beSDaniel Verkamp }
461e42620beSDaniel Verkamp
462800b18d0SVitaliy Mysak if (cp->merge_sections) {
463e42620beSDaniel Verkamp sp = spdk_conf_find_section(cp, key);
464800b18d0SVitaliy Mysak } else {
465800b18d0SVitaliy Mysak sp = NULL;
466800b18d0SVitaliy Mysak }
467800b18d0SVitaliy Mysak
468e42620beSDaniel Verkamp if (sp == NULL) {
469e42620beSDaniel Verkamp sp = allocate_cf_section();
470d2a07069Ssunshihao520 if (sp == NULL) {
471d2a07069Ssunshihao520 SPDK_ERRLOG("cannot allocate cf section\n");
472d2a07069Ssunshihao520 return -1;
473d2a07069Ssunshihao520 }
474e42620beSDaniel Verkamp append_cf_section(cp, sp);
475eac02a4aSPawel Wodkowski
476e42620beSDaniel Verkamp sp->name = strdup(key);
477e42620beSDaniel Verkamp if (sp->name == NULL) {
478f86f1075SShuhei Matsumoto SPDK_ERRLOG("cannot duplicate %s to sp->name\n", key);
479e42620beSDaniel Verkamp return -1;
480e42620beSDaniel Verkamp }
481eac02a4aSPawel Wodkowski }
482eac02a4aSPawel Wodkowski cp->current_section = sp;
483eac02a4aSPawel Wodkowski
484e42620beSDaniel Verkamp
485e42620beSDaniel Verkamp sp->num = num;
486e42620beSDaniel Verkamp } else {
487e42620beSDaniel Verkamp /* parameters */
488e42620beSDaniel Verkamp sp = cp->current_section;
489e42620beSDaniel Verkamp if (sp == NULL) {
4902d2fde0dSEd Rodriguez SPDK_ERRLOG("unknown section\n");
491e42620beSDaniel Verkamp return -1;
492e42620beSDaniel Verkamp }
493367c980bSVitaliy Mysak key = spdk_strsepq(&arg, CF_DELIM_KEY);
494e42620beSDaniel Verkamp if (key == NULL) {
4952d2fde0dSEd Rodriguez SPDK_ERRLOG("broken key\n");
496e42620beSDaniel Verkamp return -1;
497e42620beSDaniel Verkamp }
498e42620beSDaniel Verkamp
499e42620beSDaniel Verkamp ip = allocate_cf_item();
500e42620beSDaniel Verkamp if (ip == NULL) {
5012d2fde0dSEd Rodriguez SPDK_ERRLOG("cannot allocate cf item\n");
502e42620beSDaniel Verkamp return -1;
503e42620beSDaniel Verkamp }
504e42620beSDaniel Verkamp append_cf_item(sp, ip);
505e42620beSDaniel Verkamp ip->key = strdup(key);
506e42620beSDaniel Verkamp if (ip->key == NULL) {
507f86f1075SShuhei Matsumoto SPDK_ERRLOG("cannot make duplicate of %s\n", key);
508e42620beSDaniel Verkamp return -1;
509e42620beSDaniel Verkamp }
510e42620beSDaniel Verkamp ip->val = NULL;
511e42620beSDaniel Verkamp if (arg != NULL) {
512e42620beSDaniel Verkamp /* key has value(s) */
513e42620beSDaniel Verkamp while (arg != NULL) {
514e42620beSDaniel Verkamp val = spdk_strsepq(&arg, CF_DELIM);
515e42620beSDaniel Verkamp vp = allocate_cf_value();
516e42620beSDaniel Verkamp if (vp == NULL) {
5172d2fde0dSEd Rodriguez SPDK_ERRLOG("cannot allocate cf value\n");
518e42620beSDaniel Verkamp return -1;
519e42620beSDaniel Verkamp }
520e42620beSDaniel Verkamp append_cf_value(ip, vp);
521e42620beSDaniel Verkamp vp->value = strdup(val);
522e42620beSDaniel Verkamp if (vp->value == NULL) {
523f86f1075SShuhei Matsumoto SPDK_ERRLOG("cannot duplicate %s to vp->value\n", val);
524e42620beSDaniel Verkamp return -1;
525e42620beSDaniel Verkamp }
526e42620beSDaniel Verkamp }
527e42620beSDaniel Verkamp }
528e42620beSDaniel Verkamp }
529e42620beSDaniel Verkamp
530e42620beSDaniel Verkamp return 0;
531e42620beSDaniel Verkamp }
532e42620beSDaniel Verkamp
533e42620beSDaniel Verkamp static char *
fgets_line(FILE * fp)534e42620beSDaniel Verkamp fgets_line(FILE *fp)
535e42620beSDaniel Verkamp {
536e42620beSDaniel Verkamp char *dst, *dst2, *p;
537e42620beSDaniel Verkamp size_t total, len;
538e42620beSDaniel Verkamp
539e42620beSDaniel Verkamp dst = p = malloc(LIB_MAX_TMPBUF);
540e42620beSDaniel Verkamp if (!dst) {
541e42620beSDaniel Verkamp return NULL;
542e42620beSDaniel Verkamp }
543e42620beSDaniel Verkamp
544e42620beSDaniel Verkamp dst[0] = '\0';
545e42620beSDaniel Verkamp total = 0;
546e42620beSDaniel Verkamp
547e42620beSDaniel Verkamp while (fgets(p, LIB_MAX_TMPBUF, fp) != NULL) {
548e42620beSDaniel Verkamp len = strlen(p);
549e42620beSDaniel Verkamp total += len;
550e42620beSDaniel Verkamp if (len + 1 < LIB_MAX_TMPBUF || dst[total - 1] == '\n') {
551e42620beSDaniel Verkamp dst2 = realloc(dst, total + 1);
552e42620beSDaniel Verkamp if (!dst2) {
553e42620beSDaniel Verkamp free(dst);
554e42620beSDaniel Verkamp return NULL;
555e42620beSDaniel Verkamp } else {
556e42620beSDaniel Verkamp return dst2;
557e42620beSDaniel Verkamp }
558e42620beSDaniel Verkamp }
559e42620beSDaniel Verkamp
560e42620beSDaniel Verkamp dst2 = realloc(dst, total + LIB_MAX_TMPBUF);
561e42620beSDaniel Verkamp if (!dst2) {
562e42620beSDaniel Verkamp free(dst);
563e42620beSDaniel Verkamp return NULL;
564e42620beSDaniel Verkamp } else {
565e42620beSDaniel Verkamp dst = dst2;
566e42620beSDaniel Verkamp }
567e42620beSDaniel Verkamp
568e42620beSDaniel Verkamp p = dst + total;
569e42620beSDaniel Verkamp }
570e42620beSDaniel Verkamp
571e42620beSDaniel Verkamp if (feof(fp) && total != 0) {
572e42620beSDaniel Verkamp dst2 = realloc(dst, total + 2);
573e42620beSDaniel Verkamp if (!dst2) {
574e42620beSDaniel Verkamp free(dst);
575e42620beSDaniel Verkamp return NULL;
576e42620beSDaniel Verkamp } else {
577e42620beSDaniel Verkamp dst = dst2;
578e42620beSDaniel Verkamp }
579e42620beSDaniel Verkamp
580e42620beSDaniel Verkamp dst[total] = '\n';
581e42620beSDaniel Verkamp dst[total + 1] = '\0';
582e42620beSDaniel Verkamp return dst;
583e42620beSDaniel Verkamp }
584e42620beSDaniel Verkamp
585e42620beSDaniel Verkamp free(dst);
586e42620beSDaniel Verkamp
587e42620beSDaniel Verkamp return NULL;
588e42620beSDaniel Verkamp }
589e42620beSDaniel Verkamp
590e42620beSDaniel Verkamp int
spdk_conf_read(struct spdk_conf * cp,const char * file)591e42620beSDaniel Verkamp spdk_conf_read(struct spdk_conf *cp, const char *file)
592e42620beSDaniel Verkamp {
593e42620beSDaniel Verkamp FILE *fp;
594e42620beSDaniel Verkamp char *lp, *p;
595e42620beSDaniel Verkamp char *lp2, *q;
596e42620beSDaniel Verkamp int line;
597e42620beSDaniel Verkamp int n, n2;
598e42620beSDaniel Verkamp
599e42620beSDaniel Verkamp if (file == NULL || file[0] == '\0') {
600e42620beSDaniel Verkamp return -1;
601e42620beSDaniel Verkamp }
602e42620beSDaniel Verkamp
603e42620beSDaniel Verkamp fp = fopen(file, "r");
604e42620beSDaniel Verkamp if (fp == NULL) {
6052d2fde0dSEd Rodriguez SPDK_ERRLOG("open error: %s\n", file);
606e42620beSDaniel Verkamp return -1;
607e42620beSDaniel Verkamp }
608e42620beSDaniel Verkamp
609e42620beSDaniel Verkamp cp->file = strdup(file);
610e42620beSDaniel Verkamp if (cp->file == NULL) {
611f86f1075SShuhei Matsumoto SPDK_ERRLOG("cannot duplicate %s to cp->file\n", file);
612e42620beSDaniel Verkamp fclose(fp);
613e42620beSDaniel Verkamp return -1;
614e42620beSDaniel Verkamp }
615e42620beSDaniel Verkamp
616e42620beSDaniel Verkamp line = 1;
617e42620beSDaniel Verkamp while ((lp = fgets_line(fp)) != NULL) {
618e42620beSDaniel Verkamp /* skip spaces */
619e42620beSDaniel Verkamp for (p = lp; *p != '\0' && isspace((int) *p); p++)
620e42620beSDaniel Verkamp ;
621e42620beSDaniel Verkamp /* skip comment, empty line */
622e42620beSDaniel Verkamp if (p[0] == '#' || p[0] == '\0') {
623e42620beSDaniel Verkamp goto next_line;
624e42620beSDaniel Verkamp }
625e42620beSDaniel Verkamp
626e42620beSDaniel Verkamp /* concatenate line end with '\' */
627e42620beSDaniel Verkamp n = strlen(p);
628e42620beSDaniel Verkamp while (n > 2 && p[n - 1] == '\n' && p[n - 2] == '\\') {
629e42620beSDaniel Verkamp n -= 2;
630e42620beSDaniel Verkamp lp2 = fgets_line(fp);
631e42620beSDaniel Verkamp if (lp2 == NULL) {
632e42620beSDaniel Verkamp break;
633e42620beSDaniel Verkamp }
634e42620beSDaniel Verkamp
635e42620beSDaniel Verkamp line++;
636e42620beSDaniel Verkamp n2 = strlen(lp2);
637e42620beSDaniel Verkamp
638e42620beSDaniel Verkamp q = malloc(n + n2 + 1);
639e42620beSDaniel Verkamp if (!q) {
640e42620beSDaniel Verkamp free(lp2);
641e42620beSDaniel Verkamp free(lp);
6422d2fde0dSEd Rodriguez SPDK_ERRLOG("malloc failed at line %d of %s\n", line, cp->file);
643e42620beSDaniel Verkamp fclose(fp);
644e42620beSDaniel Verkamp return -1;
645e42620beSDaniel Verkamp }
646e42620beSDaniel Verkamp
647e42620beSDaniel Verkamp memcpy(q, p, n);
648e42620beSDaniel Verkamp memcpy(q + n, lp2, n2);
649e42620beSDaniel Verkamp q[n + n2] = '\0';
650e42620beSDaniel Verkamp free(lp2);
651e42620beSDaniel Verkamp free(lp);
652e42620beSDaniel Verkamp p = lp = q;
653e42620beSDaniel Verkamp n += n2;
654e42620beSDaniel Verkamp }
655e42620beSDaniel Verkamp
656e42620beSDaniel Verkamp /* parse one line */
657e42620beSDaniel Verkamp if (parse_line(cp, p) < 0) {
6582d2fde0dSEd Rodriguez SPDK_ERRLOG("parse error at line %d of %s\n", line, cp->file);
659e42620beSDaniel Verkamp }
660e42620beSDaniel Verkamp next_line:
661e42620beSDaniel Verkamp line++;
662e42620beSDaniel Verkamp free(lp);
663e42620beSDaniel Verkamp }
664e42620beSDaniel Verkamp
665e42620beSDaniel Verkamp fclose(fp);
666e42620beSDaniel Verkamp return 0;
667e42620beSDaniel Verkamp }
668e42620beSDaniel Verkamp
669e42620beSDaniel Verkamp void
spdk_conf_set_as_default(struct spdk_conf * cp)670e42620beSDaniel Verkamp spdk_conf_set_as_default(struct spdk_conf *cp)
671e42620beSDaniel Verkamp {
672e42620beSDaniel Verkamp default_config = cp;
673e42620beSDaniel Verkamp }
674800b18d0SVitaliy Mysak
675800b18d0SVitaliy Mysak void
spdk_conf_disable_sections_merge(struct spdk_conf * cp)676800b18d0SVitaliy Mysak spdk_conf_disable_sections_merge(struct spdk_conf *cp)
677800b18d0SVitaliy Mysak {
678800b18d0SVitaliy Mysak cp->merge_sections = false;
679800b18d0SVitaliy Mysak }
680