diff options
Diffstat (limited to 'src/conf.c')
-rw-r--r-- | src/conf.c | 301 |
1 files changed, 5 insertions, 296 deletions
@@ -15,301 +15,10 @@ // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "conf.h" +#include "confitems.h" +#include "envtoconfitems.h" #include "ccache.h" -typedef bool (*conf_item_parser)(const char *str, void *result, char **errmsg); -typedef bool (*conf_item_verifier)(void *value, char **errmsg); -typedef char *(*conf_item_formatter)(void *value); - -struct conf_item { - const char *name; - size_t number; - conf_item_parser parser; - size_t offset; - conf_item_verifier verifier; - conf_item_formatter formatter; -}; - -struct env_to_conf_item { - const char *env_name; - const char *conf_name; -}; - -static bool -parse_bool(const char *str, void *result, char **errmsg) -{ - bool *value = (bool *)result; - - if (str_eq(str, "true")) { - *value = true; - return true; - } else if (str_eq(str, "false")) { - *value = false; - return true; - } else { - *errmsg = format("not a boolean value: \"%s\"", str); - return false; - } -} - -static const char * -bool_to_string(bool value) -{ - return value ? "true" : "false"; -} - -static char * -format_bool(void *value) -{ - bool *b = (bool *)value; - return x_strdup(bool_to_string(*b)); -} - -static bool -parse_env_string(const char *str, void *result, char **errmsg) -{ - char **value = (char **)result; - free(*value); - *value = subst_env_in_string(str, errmsg); - return *value != NULL; -} - -static char * -format_string(void *value) -{ - char **str = (char **)value; - return x_strdup(*str); -} - -static char * -format_env_string(void *value) -{ - return format_string(value); -} - -static bool -parse_float(const char *str, void *result, char **errmsg) -{ - float *value = (float *)result; - errno = 0; - char *endptr; - float x = strtof(str, &endptr); - if (errno == 0 && *str != '\0' && *endptr == '\0') { - *value = x; - return true; - } else { - *errmsg = format("invalid floating point: \"%s\"", str); - return false; - } -} - -static char * -format_float(void *value) -{ - float *x = (float *)value; - return format("%.1f", *x); -} - -static bool -parse_size(const char *str, void *result, char **errmsg) -{ - uint64_t *value = (uint64_t *)result; - uint64_t size; - if (parse_size_with_suffix(str, &size)) { - *value = size; - return true; - } else { - *errmsg = format("invalid size: \"%s\"", str); - return false; - } -} - -static char * -format_size(void *value) -{ - uint64_t *size = (uint64_t *)value; - return format_parsable_size_with_suffix(*size); -} - -static bool -parse_sloppiness(const char *str, void *result, char **errmsg) -{ - unsigned *value = (unsigned *)result; - if (!str) { - return *value; - } - - char *p = x_strdup(str); - char *q = p; - char *word; - char *saveptr = NULL; - while ((word = strtok_r(q, ", ", &saveptr))) { - if (str_eq(word, "file_macro")) { - *value |= SLOPPY_FILE_MACRO; - } else if (str_eq(word, "file_stat_matches")) { - *value |= SLOPPY_FILE_STAT_MATCHES; - } else if (str_eq(word, "file_stat_matches_ctime")) { - *value |= SLOPPY_FILE_STAT_MATCHES_CTIME; - } else if (str_eq(word, "include_file_ctime")) { - *value |= SLOPPY_INCLUDE_FILE_CTIME; - } else if (str_eq(word, "include_file_mtime")) { - *value |= SLOPPY_INCLUDE_FILE_MTIME; - } else if (str_eq(word, "no_system_headers")) { - *value |= SLOPPY_NO_SYSTEM_HEADERS; - } else if (str_eq(word, "pch_defines")) { - *value |= SLOPPY_PCH_DEFINES; - } else if (str_eq(word, "time_macros")) { - *value |= SLOPPY_TIME_MACROS; - } else { - *errmsg = format("unknown sloppiness: \"%s\"", word); - free(p); - return false; - } - q = NULL; - } - free(p); - return true; -} - -static char * -format_sloppiness(void *value) -{ - unsigned *sloppiness = (unsigned *)value; - char *s = x_strdup(""); - if (*sloppiness & SLOPPY_FILE_MACRO) { - reformat(&s, "%sfile_macro, ", s); - } - if (*sloppiness & SLOPPY_INCLUDE_FILE_MTIME) { - reformat(&s, "%sinclude_file_mtime, ", s); - } - if (*sloppiness & SLOPPY_INCLUDE_FILE_CTIME) { - reformat(&s, "%sinclude_file_ctime, ", s); - } - if (*sloppiness & SLOPPY_TIME_MACROS) { - reformat(&s, "%stime_macros, ", s); - } - if (*sloppiness & SLOPPY_PCH_DEFINES) { - reformat(&s, "%spch_defines, ", s); - } - if (*sloppiness & SLOPPY_FILE_STAT_MATCHES) { - reformat(&s, "%sfile_stat_matches, ", s); - } - if (*sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME) { - reformat(&s, "%sfile_stat_matches_ctime, ", s); - } - if (*sloppiness & SLOPPY_NO_SYSTEM_HEADERS) { - reformat(&s, "%sno_system_headers, ", s); - } - if (*sloppiness) { - // Strip last ", ". - s[strlen(s) - 2] = '\0'; - } - return s; -} - -static bool -parse_string(const char *str, void *result, char **errmsg) -{ - (void)errmsg; - - char **value = (char **)result; - free(*value); - *value = x_strdup(str); - return true; -} - -static bool -parse_umask(const char *str, void *result, char **errmsg) -{ - unsigned *value = (unsigned *)result; - if (str_eq(str, "")) { - *value = UINT_MAX; - return true; - } - - errno = 0; - char *endptr; - *value = strtoul(str, &endptr, 8); - if (errno == 0 && *str != '\0' && *endptr == '\0') { - return true; - } else { - *errmsg = format("not an octal integer: \"%s\"", str); - return false; - } -} - -static char * -format_umask(void *value) -{ - unsigned *umask = (unsigned *)value; - if (*umask == UINT_MAX) { - return x_strdup(""); - } else { - return format("%03o", *umask); - } -} - -static bool -parse_unsigned(const char *str, void *result, char **errmsg) -{ - unsigned *value = (unsigned *)result; - errno = 0; - char *endptr; - long x = strtol(str, &endptr, 10); - if (errno == 0 && x >= 0 && *str != '\0' && *endptr == '\0') { - *value = x; - return true; - } else { - *errmsg = format("invalid unsigned integer: \"%s\"", str); - return false; - } -} - -static char * -format_unsigned(void *value) -{ - unsigned *i = (unsigned *)value; - return format("%u", *i); -} - -static bool -verify_absolute_path(void *value, char **errmsg) -{ - char **path = (char **)value; - assert(*path); - if (str_eq(*path, "")) { - // The empty string means "disable" in this case. - return true; - } else if (is_absolute_path(*path)) { - return true; - } else { - *errmsg = format("not an absolute path: \"%s\"", *path); - return false; - } -} - -static bool -verify_dir_levels(void *value, char **errmsg) -{ - unsigned *levels = (unsigned *)value; - assert(levels); - if (*levels >= 1 && *levels <= 8) { - return true; - } else { - *errmsg = format("cache directory levels must be between 1 and 8"); - return false; - } -} - -#define ITEM(name, type) \ - parse_ ## type, offsetof(struct conf, name), NULL, format_ ## type -#define ITEM_V(name, type, verification) \ - parse_ ## type, offsetof(struct conf, name), \ - verify_ ## verification, format_ ## type - -#include "confitems_lookup.c" -#include "envtoconfitems_lookup.c" - static const struct conf_item * find_conf(const char *name) { @@ -333,7 +42,7 @@ handle_conf_setting(struct conf *conf, const char *key, const char *value, return false; } - if (from_env_variable && item->parser == parse_bool) { + if (from_env_variable && item->parser == confitem_parse_bool) { // Special rule for boolean settings from the environment: "0", "false", // "disable" and "no" (case insensitive) are invalid, and all other values // mean true. @@ -446,8 +155,8 @@ conf_create(void) conf->temporary_dir = x_strdup(""); conf->umask = UINT_MAX; // Default: don't set umask. conf->unify = false; - conf->item_origins = x_malloc(CONFITEMS_TOTAL_KEYWORDS * sizeof(char *)); - for (size_t i = 0; i < CONFITEMS_TOTAL_KEYWORDS; ++i) { + conf->item_origins = x_malloc(confitems_count() * sizeof(char *)); + for (size_t i = 0; i < confitems_count(); ++i) { conf->item_origins[i] = "default"; } return conf; |