Mercurial > code
diff ini.c @ 95:cb5d3d66ea04
Merge
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 12 Jan 2012 20:12:48 +0100 |
parents | 145493469aa0 |
children | dcaf2c61c902 |
line wrap: on
line diff
--- a/ini.c Thu Jan 12 15:42:08 2012 +0100 +++ b/ini.c Thu Jan 12 20:12:48 2012 +0100 @@ -26,9 +26,9 @@ #include "ini.h" -/* -------------------------------------------------------- - * structure definitions - * -------------------------------------------------------- */ +/* -------------------------------------------------------- */ +/* structure definitions */ +/* -------------------------------------------------------- */ struct ini_option { char *key; /* option name */ @@ -59,11 +59,11 @@ STAILQ_HEAD(, ini_section) sections; }; -static char iniError[1024 + 1]; +static char ini_error[1024 + 1]; -/* -------------------------------------------------------- - * prototypes - * -------------------------------------------------------- */ +/* -------------------------------------------------------- */ +/* prototypes */ +/* -------------------------------------------------------- */ static void *ini_read(struct ini_config *, FILE *); static int ini_getline(struct ini_config *, FILE *); @@ -119,7 +119,7 @@ */ char ** -ini_get_sections_names(struct ini_config *conf, int *number) +ini_get_sections_names(const struct ini_config *conf, int *number) { struct ini_section *s; char **list; @@ -129,6 +129,10 @@ STAILQ_FOREACH(s, &conf->sections, next) ++ i; + /* For safety */ + if (number != NULL) + *number = 0; + if ((list = calloc(i + 1, sizeof (char *))) == NULL) return NULL; @@ -188,7 +192,7 @@ */ struct ini_section * -ini_select_section(struct ini_config *conf, const char *section) +ini_select_section(const struct ini_config *conf, const char *section) { struct ini_section *s; @@ -207,7 +211,7 @@ */ char * -ini_option_once(struct ini_config *conf, const char *sect, const char *key) +ini_get_option_once(const struct ini_config *conf, const char *sect, const char *key) { struct ini_option *o; struct ini_section *s; @@ -228,7 +232,7 @@ */ char ** -ini_get_option_names(struct ini_section *section, int *nb) +ini_get_option_names(const struct ini_section *section, int *nb) { char **list; struct ini_option *o; @@ -238,6 +242,9 @@ STAILQ_FOREACH(o, §ion->options, next) ++ i; + if (nb != NULL) + *nb = i; + if ((list = calloc(i + 1, sizeof (char *))) == NULL) return NULL; @@ -258,7 +265,7 @@ */ char * -ini_get_option(struct ini_section *section, const char *key) +ini_get_option(const struct ini_section *section, const char *key) { struct ini_option *o; @@ -270,16 +277,101 @@ } /* + * These section provide very small API to convert value + * and store them to the dst pointer. Because you can also + * use your own handlers, the user data here can't be used. + */ + +void +ini_value_dispatch(struct ini_config *config, struct ini_handler *hdrs, int length) +{ + const char *sectionName; + int i; + char *value; + struct ini_section *section; + + sectionName = NULL; + for (i = 0; i < length; ++i) { + /* Do not select the same section for performance. */ + if (sectionName == NULL || strcmp(hdrs[i].section, sectionName) != 0) { + sectionName = hdrs[i].section; + section = ini_select_section(config, hdrs[i].section); + } + + /* Skip the section if does not exists in the config */ + if (section == NULL) + continue; + + value = ini_get_option(section, hdrs[i].option); + hdrs[i].handler(hdrs[i].dst, value, hdrs[i].userdata); + } +} + +void +ini_convert_bool(void *dst, const char *value, void *dummy) +{ + char *p = dst; + + if (value == NULL) + return ; + + if (strcmp(value, "yes") == 0 || + strcmp(value, "true") == 0 || + strcmp(value, "1") == 0) + *p = 1; + else + *p = 0; + (void)dummy; +} + +void +ini_convert_int(void *dst, const char *value, void *dummy) +{ + int *p = dst; + + if (value == NULL) + return ; + + *p = (int) strtol(value, NULL, 10); + (void)dummy; +} + +void +ini_convert_short(void *dst, const char *value, void *dummy) +{ + short *p = dst; + + if (value == NULL) + return ; + + *p = (short) strtol(value, NULL, 10); + (void)dummy; +} + +void +ini_convert_string(void *dst, const char *value, void *dummy) +{ + char **p = dst; + + if (value == NULL) + *p = NULL; + else + *p = strdup(value); + + (void)dummy; +} + +/* * Return the last error or "No error" if there is not error at all. */ char * -ini_error(void) +ini_get_error(void) { - if (iniError[0] == '\0') + if (ini_error[0] == '\0') return "No error"; - return iniError; + return ini_error; } void @@ -410,8 +502,10 @@ handler = &ini_switch; else if (!conf->ignore) handler = &ini_register; - else + else { handler = NULL; + ++ lp; + } /* Success or not? */ if (handler != NULL && handler(conf, &lp) < 0) @@ -522,7 +616,8 @@ /* Find end of option value */ token = *endValue; if (token == '\'' || token == '"') { - for (*lp = ++endValue; *endValue != token && *endValue != '\0'; ++endValue) + for (*lp = ++endValue; *endValue != token && + *endValue != '\0'; ++endValue) continue; length = endValue - *lp; @@ -533,7 +628,8 @@ else WARN(conf, "line %d: missing '%c'\n", conf->lineno, token); } else { - for (*lp = endValue; !isspace(*endValue) && *endValue != '\0'; ++endValue) + for (*lp = endValue; !isspace(*endValue) && *endValue != '\0' && + *endValue != '#' && *endValue != ';'; ++endValue) continue; length = endValue - *lp; @@ -588,11 +684,11 @@ fclose(fp); va_start(ap, fmt); - vsnprintf(iniError, 1024, fmt, ap); + vsnprintf(ini_error, 1024, fmt, ap); va_end(ap); /* Directly print error if VERBOSE is enabled */ - WARN(conf, "%s\n", iniError); + WARN(conf, "%s\n", ini_error); free(conf);