]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-settings: Add uintmax setting type
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Sat, 31 Aug 2024 06:23:01 +0000 (09:23 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:13 +0000 (12:34 +0200)
src/config/config-parser.c
src/config/config-request.c
src/lib-settings/settings-parser.c
src/lib-settings/settings-parser.h
src/lib-settings/test-settings-parser.c

index 68938f8cb46e124d1c28a3c1967d09148ffbaad8..6534a0f4b263cb319d5c01b6e897f7a283f98cb5 100644 (file)
@@ -366,6 +366,19 @@ settings_value_check(struct config_parser_context *ctx,
                }
                break;
        }
+       case SET_UINTMAX: {
+               uintmax_t num;
+
+               if (strchr(value, '%') != NULL)
+                       break;
+               if (str_to_uintmax(value, &num) < 0) {
+                       ctx->error = p_strdup_printf(ctx->pool,
+                               "Invalid number %s: %s", value,
+                               str_num_error(value));
+                       return -1;
+               }
+               break;
+       }
        case SET_UINT_OCT:
                if (*value == '0') {
                        unsigned long long octal;
index 81fa839454dc660c36de787ab16042dd6f5e09d0..78c13bb1c727926945cf2a430cea6240099a4cac 100644 (file)
@@ -106,6 +106,11 @@ bool config_export_type(string_t *str, const void *value,
                config_export_size(str, *val);
                break;
        }
+       case SET_UINTMAX: {
+               const uint64_t *val = value;
+               str_printfa(str, "%ju", *val);
+               break;
+       }
        case SET_UINT:
        case SET_UINT_OCT: {
                const unsigned int *val = value;
@@ -208,6 +213,7 @@ settings_export(struct config_export_context *ctx,
                case SET_FILE:
                case SET_BOOL:
                case SET_SIZE:
+               case SET_UINTMAX:
                case SET_UINT:
                case SET_UINT_OCT:
                case SET_TIME:
index 48a336685f1c1b77e7cef9844bf6e8053f0c3e5e..e0c004391ee18c1b6f289e074f0c4ef26014b022 100644 (file)
@@ -187,6 +187,19 @@ get_bool(struct setting_parser_context *ctx, const char *value, bool *result_r)
        return ret;
 }
 
+static int
+get_uintmax(struct setting_parser_context *ctx, const char *value,
+           uintmax_t *result_r)
+{
+       if (str_to_uintmax(value, result_r) < 0) {
+               settings_parser_set_error(ctx, t_strdup_printf(
+                       "Invalid number %s: %s", value,
+                       str_num_error(value)));
+               return -1;
+       }
+       return 0;
+}
+
 static int
 get_uint(struct setting_parser_context *ctx, const char *value,
         unsigned int *result_r)
@@ -595,6 +608,10 @@ settings_parse(struct setting_parser_context *ctx,
                if (get_bool(ctx, value, (bool *)ptr) < 0)
                        return -1;
                break;
+       case SET_UINTMAX:
+               if (get_uintmax(ctx, value, (uintmax_t *)ptr) < 0)
+                       return -1;
+               break;
        case SET_UINT:
                if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
                        return -1;
@@ -935,6 +952,11 @@ unsigned int settings_hash(const struct setting_parser_info *info,
                        crc = crc32_data_more(crc, b, sizeof(*b));
                        break;
                }
+               case SET_UINTMAX: {
+                       const uintmax_t *i = p;
+                       crc = crc32_data_more(crc, i, sizeof(*i));
+                       break;
+               }
                case SET_UINT:
                case SET_UINT_OCT:
                case SET_TIME:
@@ -1011,6 +1033,12 @@ bool settings_equal(const struct setting_parser_info *info,
                                return FALSE;
                        break;
                }
+               case SET_UINTMAX: {
+                       const uintmax_t *i1 = p1, *i2 = p2;
+                       if (*i1 != *i2)
+                               return FALSE;
+                       break;
+               }
                case SET_UINT:
                case SET_UINT_OCT:
                case SET_TIME:
index 204621b20b1cfe1c750dc960b67a21c81ccc3921..7a7555a0bbb8824e67cd58c5728dfbc945477cff 100644 (file)
@@ -27,6 +27,7 @@ struct var_expand_func_table;
 
 enum setting_type {
        SET_BOOL,
+       SET_UINTMAX,
        SET_UINT,
        SET_UINT_OCT,
        SET_TIME,
@@ -74,6 +75,8 @@ struct setting_define {
 
 #define SETTING_DEFINE_STRUCT_BOOL(key, name, struct_name) \
        SETTING_DEFINE_STRUCT_TYPE(SET_BOOL, 0, bool, key, name, struct_name)
+#define SETTING_DEFINE_STRUCT_UINTMAX(key, name, struct_name) \
+       SETTING_DEFINE_STRUCT_TYPE(SET_UINTMAX, 0, uintmax_t, key, name, struct_name)
 #define SETTING_DEFINE_STRUCT_UINT(key, name, struct_name) \
        SETTING_DEFINE_STRUCT_TYPE(SET_UINT, 0, unsigned int, key, name, struct_name)
 #define SETTING_DEFINE_STRUCT_UINT_OCT(key, name, struct_name) \
@@ -101,6 +104,8 @@ struct setting_define {
 
 #define SETTING_DEFINE_STRUCT_BOOL_HIDDEN(key, name, struct_name) \
        SETTING_DEFINE_STRUCT_TYPE(SET_BOOL, SET_FLAG_HIDDEN, bool, key, name, struct_name)
+#define SETTING_DEFINE_STRUCT_UINTMAX_HIDDEN(key, name, struct_name) \
+       SETTING_DEFINE_STRUCT_TYPE(SET_UINTMAX, SET_FLAG_HIDDEN, uintmax_t, key, name, struct_name)
 #define SETTING_DEFINE_STRUCT_UINT_HIDDEN(key, name, struct_name) \
        SETTING_DEFINE_STRUCT_TYPE(SET_UINT, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name)
 #define SETTING_DEFINE_STRUCT_UINT_OCT_HIDDEN(key, name, struct_name) \
index 8791932e3770dc51b597f1db6eb33310a5105a4a..ce8936185472332adddcfc0b6259bf3de9a6249e 100644 (file)
@@ -12,6 +12,7 @@ static const char *const test_settings_blobs[] =
 /* Blob 0 */
        "bool_true", "yes",
        "bool_false", "no",
+       "uintmax_max", "18446744073709551615",
        "uint", "15",
        "uint_oct", "0700",
        "secs", "5s",
@@ -30,6 +31,7 @@ static const char *const test_settings_invalid[] =
 {
        "bool_true", "",
        "bool_false", "x",
+       "uintmax_max", "",
        "uint", "",
        "uint", "15M",
        "uint_oct", "",
@@ -48,6 +50,7 @@ static void test_settings_parser(void)
        struct test_settings {
                bool bool_true;
                bool bool_false;
+               uintmax_t uintmax_max;
                unsigned int uint;
                unsigned int uint_oct;
                unsigned int secs;
@@ -66,6 +69,7 @@ static void test_settings_parser(void)
                0,
                0,
                0,
+               0,
                "",
                "",
                ARRAY_INIT,
@@ -73,6 +77,7 @@ static void test_settings_parser(void)
        const struct setting_define defs[] = {
                SETTING_DEFINE_STRUCT_BOOL("bool_true", bool_true, struct test_settings),
                SETTING_DEFINE_STRUCT_BOOL("bool_false", bool_false, struct test_settings),
+               SETTING_DEFINE_STRUCT_UINTMAX("uintmax_max", uintmax_max, struct test_settings),
                SETTING_DEFINE_STRUCT_UINT("uint", uint, struct test_settings),
                { .type = SET_UINT_OCT, .key = "uint_oct",
                  offsetof(struct test_settings, uint_oct), NULL },
@@ -117,6 +122,7 @@ static void test_settings_parser(void)
 
        test_assert(settings->bool_true == TRUE);
        test_assert(settings->bool_false == FALSE);
+       test_assert(settings->uintmax_max == 18446744073709551615ULL);
        test_assert(settings->uint == 15);
        test_assert(settings->uint_oct == 0700);
        test_assert(settings->secs == 5);