Imported Upstream version 3.5.1
[platform/upstream/ccache.git] / src / conf.c
index 404d2d7..b9ca0a2 100644 (file)
 // 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 const 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 const 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 const char *
-format_string(void *value)
-{
-       char **str = (char **)value;
-       return x_strdup(*str);
-}
-
-static const 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 const 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 const 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 const 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 const 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 const 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.
@@ -429,7 +138,7 @@ conf_create(void)
        conf->hash_dir = true;
        conf->ignore_headers_in_manifest = x_strdup("");
        conf->keep_comments_cpp = false;
-       conf->limit_multiple = 0.8f;
+       conf->limit_multiple = 0.8;
        conf->log_file = x_strdup("");
        conf->max_files = 0;
        conf->max_size = (uint64_t)5 * 1000 * 1000 * 1000;
@@ -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;
@@ -639,7 +348,7 @@ conf_print_value(struct conf *conf, const char *key,
                return false;
        }
        void *value = (char *)conf + item->offset;
-       char *str = (char *)item->formatter(value);
+       char *str = item->formatter(value);
        fprintf(file, "%s\n", str);
        free(str);
        return true;
@@ -656,7 +365,7 @@ print_item(struct conf *conf, const char *key,
                return false;
        }
        void *value = (char *)conf + item->offset;
-       char *str = (char *)item->formatter(value);
+       char *str = item->formatter(value);
        char *buf = x_strdup("");
        reformat(&buf, "%s = %s", key, str);
        printer(buf, conf->item_origins[item->number], context);