source: mainline/uspace/lib/conf/src/configuration.c@ 172cae4c

Last change on this file since 172cae4c was 172cae4c, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

Create library for reading INI files and defining configuration values
Conflicts:

uspace/Makefile.common

Conflicts:

uspace/Makefile

  • Property mode set to 100644
File size: 2.7 KB
Line 
1#include "conf/configuration.h"
2
3#include <assert.h>
4#include <errno.h>
5#include <str.h>
6
7static int config_load_item(config_item_t *config_item,
8 ini_item_iterator_t *it, void *dst, text_parse_t *parse)
9{
10 size_t cnt = 0;
11 void *field_dst = (char *)dst + config_item->offset;
12 bool has_error = false;
13
14 for (; ini_item_iterator_valid(it); ini_item_iterator_inc(it), ++cnt) {
15 const char *string = ini_item_iterator_value(it);
16 const size_t lineno = ini_item_iterator_lineno(it);
17 has_error = has_error ||
18 config_item->parse(string, field_dst, parse, lineno);
19 }
20
21 if (cnt == 0) {
22 if (config_item->default_value == NULL) {
23 return ENOENT;
24 }
25 bool result = config_item->parse(config_item->default_value,
26 field_dst, parse, 0);
27 /* Default string should be always correct */
28 assert(result);
29 }
30
31 return has_error ? EINVAL : EOK;
32}
33
34/** Process INI section as values to a structure
35 *
36 * @param[in] specification Mark-terminated array of config_item_t specifying
37 * available configuration values. The mark is value
38 * whose name is NULL, you can use
39 * CONFIGURATION_ITEM_SENTINEL.
40 * @param[in] section INI section with raw string data
41 * @param[out] dst pointer to structure that holds parsed values
42 * @param[out] parse structure for recording any parsing errors
43 *
44 * @return EOK on success
45 * @return EINVAL on any parsing errors (details in parse structure)
46 */
47int config_load_ini_section(config_item_t *specification,
48 ini_section_t *section, void *dst, text_parse_t *parse)
49{
50 bool has_error = false;
51
52 config_item_t *config_item = specification;
53 while (config_item->name != NULL) {
54 ini_item_iterator_t iterator =
55 ini_section_get_iterator(section, config_item->name);
56
57 int rc = config_load_item(config_item, &iterator, dst, parse);
58 switch (rc) {
59 case ENOENT:
60 has_error = true;
61 text_parse_raise_error(parse, section->lineno,
62 CONFIGURATION_EMISSING_ITEM);
63 break;
64 case EINVAL:
65 has_error = true;
66 /* Parser should've raised proper errors */
67 break;
68 case EOK:
69 /* empty (nothing to do) */
70 break;
71 default:
72 assert(false);
73 }
74
75 ++config_item;
76 }
77
78 return has_error ? EOK : EINVAL;
79}
80
81/** Parse string (copy) to destination
82 *
83 * @param[out] dst pointer to char * where dedicated copy will be stored
84 *
85 * @return true on success
86 * @return false on error (typically low memory)
87 */
88bool config_parse_string(const char *string, void *dst, text_parse_t *parse,
89 size_t lineno)
90{
91 char *my_string = str_dup(string);
92 if (my_string) {
93 return false;
94 }
95
96 char **char_dst = dst;
97 *char_dst = my_string;
98 return true;
99}
Note: See TracBrowser for help on using the repository browser.