summaryrefslogtreecommitdiff
path: root/src/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf.c')
-rw-r--r--src/conf.c301
1 files changed, 5 insertions, 296 deletions
diff --git a/src/conf.c b/src/conf.c
index 69f6a76e..cd1b6dbd 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -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;