diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index c2d353476d..f4b9b4e7e1 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -64,11 +64,11 @@ struct json_variant_foreach_state { type cc = func(sd_json_variant_string(variant)); \ if (cc < 0) { \ /* Maybe this enum is recognizable if we replace "_" (i.e. Varlink syntax) with "-" (how we usually prefer it). */ \ - _cleanup_free_ char *z = strreplace(sd_json_variant_string(variant), "_", "-"); \ + _cleanup_free_ char *z = strdup(sd_json_variant_string(variant)); \ if (!z) \ return json_log_oom(variant, flags); \ \ - cc = func(z); \ + cc = func(json_dashify(z)); \ if (cc < 0) \ return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Value of JSON field '%s' not recognized: %s", strna(n), sd_json_variant_string(variant)); \ } \ @@ -261,3 +261,6 @@ enum { int json_variant_new_pidref(sd_json_variant **ret, PidRef *pidref); int json_variant_new_devnum(sd_json_variant **ret, dev_t devnum); int json_variant_new_fd_info(sd_json_variant **ret, int fd); + +char *json_underscorify(char *p); +char *json_dashify(char *p); diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 776df25b8e..1ef99550b6 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -3474,8 +3474,9 @@ _public_ int sd_json_parse_file( return sd_json_parse_file_at(f, AT_FDCWD, path, flags, ret, reterr_line, reterr_column); } -static char *underscorify(char *p) { - assert(p); +char *json_underscorify(char *p) { + if (!p) + return NULL; /* Replaces "-", "+" by "_", to deal with the usual enum naming rules we have. */ @@ -3485,6 +3486,18 @@ static char *underscorify(char *p) { return p; } +char *json_dashify(char *p) { + if (!p) + return NULL; + + /* Replaces "-", "+" by "-", to (somewhat) undo what json_underscorify() does */ + + for (char *q = p; *q; q++) + *q = IN_SET(*q, '_', '-', '+') ? '-' : *q; + + return p; +} + _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { JsonStack *stack = NULL; size_t n_stack = 1; @@ -3538,7 +3551,7 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { goto finish; } - p = underscorify(c); + p = json_underscorify(c); } r = sd_json_variant_new_string(&add, p); diff --git a/src/shared/varlink-io.systemd.BootControl.c b/src/shared/varlink-io.systemd.BootControl.c index 305fac5c38..11dcb4d095 100644 --- a/src/shared/varlink-io.systemd.BootControl.c +++ b/src/shared/varlink-io.systemd.BootControl.c @@ -2,7 +2,7 @@ #include "varlink-io.systemd.BootControl.h" -static SD_VARLINK_DEFINE_ENUM_TYPE( +SD_VARLINK_DEFINE_ENUM_TYPE( BootEntryType, SD_VARLINK_FIELD_COMMENT("Boot Loader Specification Type #1 entries (.conf files)"), SD_VARLINK_DEFINE_ENUM_VALUE(type1), @@ -13,7 +13,7 @@ static SD_VARLINK_DEFINE_ENUM_TYPE( SD_VARLINK_FIELD_COMMENT("Automatically generated entries"), SD_VARLINK_DEFINE_ENUM_VALUE(auto)); -static SD_VARLINK_DEFINE_ENUM_TYPE( +SD_VARLINK_DEFINE_ENUM_TYPE( BootEntrySource, SD_VARLINK_FIELD_COMMENT("Boot entry found in EFI system partition (ESP)"), SD_VARLINK_DEFINE_ENUM_VALUE(esp), diff --git a/src/shared/varlink-io.systemd.BootControl.h b/src/shared/varlink-io.systemd.BootControl.h index 2c1fecf446..1b09f4f0b2 100644 --- a/src/shared/varlink-io.systemd.BootControl.h +++ b/src/shared/varlink-io.systemd.BootControl.h @@ -3,4 +3,7 @@ #include "sd-varlink-idl.h" +extern const sd_varlink_symbol vl_type_BootEntryType; +extern const sd_varlink_symbol vl_type_BootEntrySource; + extern const sd_varlink_interface vl_interface_io_systemd_BootControl; diff --git a/src/shared/varlink-io.systemd.MountFileSystem.c b/src/shared/varlink-io.systemd.MountFileSystem.c index 4d87040338..e9c69f07d8 100644 --- a/src/shared/varlink-io.systemd.MountFileSystem.c +++ b/src/shared/varlink-io.systemd.MountFileSystem.c @@ -3,7 +3,7 @@ #include "bus-polkit.h" #include "varlink-io.systemd.MountFileSystem.h" -static SD_VARLINK_DEFINE_ENUM_TYPE( +SD_VARLINK_DEFINE_ENUM_TYPE( PartitionDesignator, SD_VARLINK_DEFINE_ENUM_VALUE(root), SD_VARLINK_DEFINE_ENUM_VALUE(usr), diff --git a/src/shared/varlink-io.systemd.MountFileSystem.h b/src/shared/varlink-io.systemd.MountFileSystem.h index 0e6ad51e64..6450705892 100644 --- a/src/shared/varlink-io.systemd.MountFileSystem.h +++ b/src/shared/varlink-io.systemd.MountFileSystem.h @@ -3,4 +3,6 @@ #include "sd-varlink-idl.h" +extern const sd_varlink_symbol vl_type_PartitionDesignator; + extern const sd_varlink_interface vl_interface_io_systemd_MountFileSystem; diff --git a/src/test/test-varlink-idl.c b/src/test/test-varlink-idl.c index 97e3c154c3..c449d1b3c0 100644 --- a/src/test/test-varlink-idl.c +++ b/src/test/test-varlink-idl.c @@ -7,7 +7,10 @@ #include "sd-varlink.h" #include "sd-varlink-idl.h" +#include "bootspec.h" +#include "dissect-image.h" #include "fd-util.h" +#include "json-util.h" #include "pretty-print.h" #include "tests.h" #include "varlink-idl-util.h" @@ -457,4 +460,58 @@ TEST(validate_method_call) { assert_se(pthread_join(t, NULL) == 0); } +static void test_enum_to_string_name(const char *n, const sd_varlink_symbol *symbol) { + assert(n); + assert(symbol); + + assert(symbol->symbol_type == SD_VARLINK_ENUM_TYPE); + _cleanup_free_ char *m = ASSERT_PTR(json_underscorify(strdup(n))); + + bool found = false; + for (const sd_varlink_field *f = symbol->fields; f->name; f++) { + if (f->field_type == _SD_VARLINK_FIELD_COMMENT) + continue; + + assert(f->field_type == SD_VARLINK_ENUM_VALUE); + if (streq(m, f->name)) { + found = true; + break; + } + } + + log_debug("'%s' found in '%s': %s", m, strna(symbol->name), yes_no(found)); + assert(found); +} + +#define TEST_IDL_ENUM_TO_STRING(type, ename, symbol) \ + for (type t = 0;; t++) { \ + const char *n = ename##_to_string(t); \ + if (!n) \ + break; \ + test_enum_to_string_name(n, &(symbol)); \ + } + +#define TEST_IDL_ENUM_FROM_STRING(type, ename, symbol) \ + for (const sd_varlink_field *f = (symbol).fields; f->name; f++) { \ + if (f->field_type == _SD_VARLINK_FIELD_COMMENT) \ + continue; \ + assert(f->field_type == SD_VARLINK_ENUM_VALUE); \ + _cleanup_free_ char *m = ASSERT_PTR(json_dashify(strdup(f->name))); \ + type t = ename##_from_string(m); \ + log_debug("'%s' of '%s' translates: %s", f->name, strna((symbol).name), yes_no(t >= 0)); \ + assert(t >= 0); \ + } + +#define TEST_IDL_ENUM(type, name, symbol) \ + do { \ + TEST_IDL_ENUM_TO_STRING(type, name, symbol); \ + TEST_IDL_ENUM_FROM_STRING(type, name, symbol); \ + } while (false) + +TEST(enums_idl) { + TEST_IDL_ENUM(BootEntryType, boot_entry_type, vl_type_BootEntryType); + TEST_IDL_ENUM_TO_STRING(BootEntrySource, boot_entry_source, vl_type_BootEntrySource); + TEST_IDL_ENUM(PartitionDesignator, partition_designator, vl_type_PartitionDesignator); +} + DEFINE_TEST_MAIN(LOG_DEBUG);