]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-varlink: Expose sd_varlink_idl_parse() 37513/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 19 May 2025 12:49:43 +0000 (14:49 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 19 May 2025 13:19:24 +0000 (15:19 +0200)
We're planning to do code generation based on the systemd varlink
APIs. To simplify this, let's expose the IDL parser, so we can use
it to do code generation instead of having to write our own IDL
parser.

src/fuzz/fuzz-varlink-idl.c
src/libsystemd/libsystemd.sym
src/libsystemd/sd-varlink/sd-varlink-idl.c
src/libsystemd/sd-varlink/varlink-idl-util.h
src/systemd/sd-varlink-idl.h
src/test/test-varlink-idl.c
src/varlinkctl/varlinkctl.c

index 8981a363ec17421673ac1a7d507394c3ab35c523..9eb021a7d12f2af97218d6997e5ecbb07739e3c4 100644 (file)
@@ -14,7 +14,7 @@
 #include "varlink-idl-util.h"
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *vi = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *vi = NULL;
         _cleanup_free_ char *str = NULL, *dump = NULL;
         int r;
 
@@ -25,7 +25,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
 
         assert_se(str = memdup_suffix0(data, size));
 
-        r = varlink_idl_parse(str, /* ret_line= */ NULL, /* column= */ NULL, &vi);
+        r = sd_varlink_idl_parse(str, /* ret_line= */ NULL, /* column= */ NULL, &vi);
         if (r < 0) {
                 log_debug_errno(r, "Failed to parse varlink interface definition: %m");
                 return 0;
index 4543fb0e60d45aa3a83cbbd791a312b9b04a8c6f..d16c7265f2db238373d388f92673a6865c347c40 100644 (file)
@@ -1072,6 +1072,8 @@ global:
         sd_varlink_get_input_fd;
         sd_varlink_get_n_fds;
         sd_varlink_get_output_fd;
+        sd_varlink_idl_parse;
+        sd_varlink_interface_free;
         sd_varlink_reset_fds;
         sd_varlink_server_listen_name;
 } LIBSYSTEMD_257;
index 0a57e2eb5d30704da511d5f19db1dd8da8d7b3fe..1184bd5951cd5ca7d6f785d09f9720c1c35115a1 100644 (file)
@@ -588,7 +588,7 @@ static sd_varlink_symbol* varlink_symbol_free(sd_varlink_symbol *symbol) {
         return mfree(symbol);
 }
 
-sd_varlink_interface* varlink_interface_free(sd_varlink_interface *interface) {
+_public_ sd_varlink_interface* sd_varlink_interface_free(sd_varlink_interface *interface) {
         if (!interface)
                 return NULL;
 
@@ -1139,13 +1139,13 @@ static int varlink_idl_resolve_types(sd_varlink_interface *interface) {
         return 0;
 }
 
-int varlink_idl_parse(
+_public_ int sd_varlink_idl_parse(
                 const char *text,
                 unsigned *reterr_line,
                 unsigned *reterr_column,
                 sd_varlink_interface **ret) {
 
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *interface = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *interface = NULL;
         _cleanup_(varlink_symbol_freep) sd_varlink_symbol *symbol = NULL;
         enum {
                 STATE_PRE_INTERFACE,
index 9c5df26d122fb231930c29a8ba5b8ba0410b44e7..990eb804a976a3173c50d62640d58313a759da82 100644 (file)
@@ -6,10 +6,6 @@
 
 #include "memory-util.h"
 
-int varlink_idl_parse(const char *text, unsigned *ret_line, unsigned *ret_column, sd_varlink_interface **ret);
-sd_varlink_interface* varlink_interface_free(sd_varlink_interface *interface);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_varlink_interface*, varlink_interface_free);
-
 bool varlink_idl_field_name_is_valid(const char *name);
 bool varlink_idl_symbol_name_is_valid(const char *name);
 bool varlink_idl_interface_name_is_valid(const char *name);
index c580a0d990341cd456504a74b4a9523a4bdd3664..0fe49b8677e454959e6326058fc26ace5bd2a234 100644 (file)
@@ -221,6 +221,10 @@ int sd_varlink_idl_dump(FILE *f, const sd_varlink_interface *interface, sd_varli
 int sd_varlink_idl_format_full(const sd_varlink_interface *interface, sd_varlink_idl_format_flags_t flags, size_t cols, char **ret);
 int sd_varlink_idl_format(const sd_varlink_interface *interface, char **ret);
 
+int sd_varlink_idl_parse(const char *text, unsigned *reterr_line, unsigned *reterr_column, sd_varlink_interface **ret);
+sd_varlink_interface* sd_varlink_interface_free(sd_varlink_interface *interface);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_varlink_interface, sd_varlink_interface_free);
+
 _SD_END_DECLARATIONS;
 
 #endif
index c2e8891edbe745f1d7de20ad579e13334a7c629a..009d143fbc9daef48681b731a3b8beca8a55132e 100644 (file)
@@ -129,7 +129,7 @@ static SD_VARLINK_DEFINE_INTERFACE(
                 &vl_error_ErrorTest);
 
 static void test_parse_format_one(const sd_varlink_interface *iface) {
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *parsed = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *parsed = NULL;
         _cleanup_free_ char *text = NULL, *text2 = NULL;
 
         assert_se(iface);
@@ -137,7 +137,7 @@ static void test_parse_format_one(const sd_varlink_interface *iface) {
         assert_se(sd_varlink_idl_dump(stdout, iface, SD_VARLINK_IDL_FORMAT_COLOR, /* cols= */ SIZE_MAX) >= 0);
         assert_se(varlink_idl_consistent(iface, LOG_ERR) >= 0);
         assert_se(sd_varlink_idl_format(iface, &text) >= 0);
-        assert_se(varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
+        assert_se(sd_varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
         assert_se(varlink_idl_consistent(parsed, LOG_ERR) >= 0);
         assert_se(sd_varlink_idl_format(parsed, &text2) >= 0);
 
@@ -145,13 +145,13 @@ static void test_parse_format_one(const sd_varlink_interface *iface) {
 
         text = mfree(text);
         text2 = mfree(text2);
-        parsed = varlink_interface_free(parsed);
+        parsed = sd_varlink_interface_free(parsed);
 
         /* Do the same thing, but aggressively line break, and make sure this is roundtrippable as well */
         assert_se(sd_varlink_idl_dump(stdout, iface, SD_VARLINK_IDL_FORMAT_COLOR, 23) >= 0);
         assert_se(varlink_idl_consistent(iface, LOG_ERR) >= 0);
         assert_se(sd_varlink_idl_format_full(iface, 0, 23, &text) >= 0);
-        assert_se(varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
+        assert_se(sd_varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
         assert_se(varlink_idl_consistent(parsed, LOG_ERR) >= 0);
         assert_se(sd_varlink_idl_format_full(parsed, 0, 23, &text2) >= 0);
 
@@ -213,7 +213,7 @@ TEST(parse_format) {
 }
 
 TEST(parse) {
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *parsed = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *parsed = NULL;
 
         /* This one has (nested) enonymous enums and structs */
         static const char text[] =
@@ -222,13 +222,13 @@ TEST(parse) {
                 "type Barstruct ( a : (x, y, z), b : (x : int), c: (f, ff, fff), d: object, e : (sub : (subsub: (subsubsub: string, subsubsub2: (iii, ooo)))))"
                 ;
 
-        assert_se(varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
+        assert_se(sd_varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
         test_parse_format_one(parsed);
 
-        assert_se(varlink_idl_parse("interface org.freedesktop.Foo\n"
-                                    "type Foo (b: bool, c: foo, c: int)", NULL, NULL, NULL) == -ENETUNREACH); /* unresolved type */
-        assert_se(varlink_idl_parse("interface org.freedesktop.Foo\n"
-                                    "type Foo ()", NULL, NULL, NULL) == -EBADMSG); /* empty struct/enum */
+        assert_se(sd_varlink_idl_parse("interface org.freedesktop.Foo\n"
+                                       "type Foo (b: bool, c: foo, c: int)", NULL, NULL, NULL) == -ENETUNREACH); /* unresolved type */
+        assert_se(sd_varlink_idl_parse("interface org.freedesktop.Foo\n"
+                                       "type Foo ()", NULL, NULL, NULL) == -EBADMSG); /* empty struct/enum */
 }
 
 TEST(interface_name_is_valid) {
@@ -300,7 +300,7 @@ TEST(qualified_symbol_name_is_valid) {
 
 TEST(validate_json) {
 
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *parsed = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *parsed = NULL;
 
         /* This one has (nested) enonymous enums and structs */
         static const char text[] =
@@ -311,7 +311,7 @@ TEST(validate_json) {
                 "#paff\n"
                 "b:int, c:?bool, d:[]int, e:?[string]bool, f:?(piff, paff), g:(f:float) ) -> ()\n";
 
-        assert_se(varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
+        assert_se(sd_varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
         test_parse_format_one(parsed);
 
         _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
@@ -330,7 +330,7 @@ TEST(validate_json) {
 }
 
 static int test_recursive_one(unsigned depth) {
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *parsed = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *parsed = NULL;
         _cleanup_free_ char *pre = NULL, *post = NULL, *text = NULL;
         static const char header[] =
                 "interface recursive.test\n"
@@ -346,7 +346,7 @@ static int test_recursive_one(unsigned depth) {
         if (!text)
                 return log_oom();
 
-        return varlink_idl_parse(text, NULL, NULL, &parsed);
+        return sd_varlink_idl_parse(text, NULL, NULL, &parsed);
 }
 
 TEST(recursive) {
index 74f9151a4d5dbbfd35de8e6526fc8fdf71dec3a5..d34ef55cf8b7b11b55e1ad9b9fc82fbd1fc731da 100644 (file)
@@ -449,7 +449,7 @@ static int verb_introspect(int argc, char *argv[], void *userdata) {
                                 { "description", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY },
                                 {}
                         };
-                        _cleanup_(varlink_interface_freep) sd_varlink_interface *vi = NULL;
+                        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *vi = NULL;
                         const char *description = NULL;
                         unsigned line = 0, column = 0;
 
@@ -461,7 +461,7 @@ static int verb_introspect(int argc, char *argv[], void *userdata) {
                                 print_separator();
 
                         /* Try to parse the returned description, so that we can add syntax highlighting */
-                        r = varlink_idl_parse(ASSERT_PTR(description), &line, &column, &vi);
+                        r = sd_varlink_idl_parse(ASSERT_PTR(description), &line, &column, &vi);
                         if (r < 0) {
                                 if (list_methods)
                                         return log_error_errno(r, "Failed to parse returned interface description at %u:%u: %m", line, column);
@@ -818,7 +818,7 @@ static int verb_call(int argc, char *argv[], void *userdata) {
 }
 
 static int verb_validate_idl(int argc, char *argv[], void *userdata) {
-        _cleanup_(varlink_interface_freep) sd_varlink_interface *vi = NULL;
+        _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *vi = NULL;
         _cleanup_free_ char *text = NULL;
         const char *fname;
         unsigned line = 1, column = 1;
@@ -838,7 +838,7 @@ static int verb_validate_idl(int argc, char *argv[], void *userdata) {
                 fname = "<stdin>";
         }
 
-        r = varlink_idl_parse(text, &line, &column, &vi);
+        r = sd_varlink_idl_parse(text, &line, &column, &vi);
         if (r == -EBADMSG)
                 return log_error_errno(r, "%s:%u:%u: Bad syntax.", fname, line, column);
         if (r == -ENETUNREACH)