]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/varlink-idl.h
hwdb: Add mapping for Xiaomi Mipad 2 bottom bezel capacitive buttons
[thirdparty/systemd.git] / src / shared / varlink-idl.h
CommitLineData
e50b2a93
LP
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2#pragma once
3
4#include <errno.h>
5#include <stdbool.h>
6#include <stdio.h>
7
8#include "json.h"
9#include "macro.h"
10
11/* This implements the Varlink Interface Definition Language ("Varlink IDL"),
12 * i.e. https://varlink.org/Interface-Definition
13 *
14 * Primarily allows encoding static interface definitions in C code, that can be converted to the textual IDL
15 * format on-the-fly. Can also parse the textual format back to C structures. Validates the interface
16 * definitions for internal consistency and validates JSON objects against the interface definitions. */
17
18typedef enum VarlinkSymbolType {
19 VARLINK_ENUM_TYPE,
20 VARLINK_STRUCT_TYPE,
21 VARLINK_METHOD,
22 VARLINK_ERROR,
23 _VARLINK_SYMBOL_TYPE_MAX,
24 _VARLINK_SYMBOL_TYPE_INVALID = -EINVAL,
25} VarlinkSymbolType;
26
27typedef enum VarlinkFieldType {
28 _VARLINK_FIELD_TYPE_END_MARKER = 0, /* zero type means: this is the last entry in the fields[] array of VarlinkSymbol */
29 VARLINK_STRUCT,
30 VARLINK_ENUM,
31 VARLINK_NAMED_TYPE,
32 VARLINK_BOOL,
33 VARLINK_INT,
34 VARLINK_FLOAT,
35 VARLINK_STRING,
36 VARLINK_OBJECT,
37 VARLINK_ENUM_VALUE,
38 _VARLINK_FIELD_TYPE_MAX,
39 _VARLINK_FIELD_TYPE_INVALID = -EINVAL,
40} VarlinkFieldType;
41
42typedef enum VarlinkFieldDirection {
43 VARLINK_REGULAR,
44 VARLINK_INPUT,
45 VARLINK_OUTPUT,
46 _VARLINK_FIELD_DIRECTION_MAX,
47 _VARLINK_FIELD_DIRECTION_INVALID = -EINVAL,
48} VarlinkFieldDirection;
49
50typedef enum VarlinkFieldFlags {
51 VARLINK_ARRAY = 1 << 0,
52 VARLINK_MAP = 1 << 1,
53 VARLINK_NULLABLE = 1 << 2,
54 _VARLINK_FIELD_FLAGS_MAX = (1 << 3) - 1,
55 _VARLINK_FIELD_FLAGS_INVALID = -EINVAL,
56} VarlinkFieldFlags;
57
58typedef struct VarlinkField VarlinkField;
59typedef struct VarlinkSymbol VarlinkSymbol;
60typedef struct VarlinkInterface VarlinkInterface;
61
62/* Fields are the components making up symbols */
63struct VarlinkField {
64 const char *name;
65 VarlinkFieldType field_type;
66 VarlinkFieldFlags field_flags;
67 VarlinkFieldDirection field_direction; /* in case of method call fields: whether input or output argument */
68 const VarlinkSymbol *symbol; /* VARLINK_STRUCT, VARLINK_ENUM: anonymous symbol that carries the definitions, VARLINK_NAMED_TYPE: resolved symbol */
69 const char *named_type; /* VARLINK_NAMED_TYPE */
70};
71
72/* Symbols are primary named concepts in an interface, and are methods, errors or named types (either enum or struct). */
73struct VarlinkSymbol {
74 const char *name; /* most symbols have a name, but sometimes they are created on-the-fly for fields, in which case they are anonymous */
75 VarlinkSymbolType symbol_type;
76 VarlinkField fields[];
77};
78
79/* An interface definition has a name and consist of symbols */
80struct VarlinkInterface {
81 const char *name;
82 const VarlinkSymbol *symbols[];
83};
84
85#define VARLINK_DEFINE_FIELD(_name, _field_type, _field_flags) \
86 { .name = #_name, .field_type = (_field_type), .field_flags = (_field_flags) }
87
88#define VARLINK_DEFINE_FIELD_BY_TYPE(_name, _named_type, _field_flags) \
89 { .name = #_name, .field_type = VARLINK_NAMED_TYPE, .named_type = #_named_type, .symbol = &vl_type_ ## _named_type, .field_flags = (_field_flags) }
90
91#define VARLINK_DEFINE_INPUT(_name, _field_type, _field_flags) \
92 { .name = #_name, .field_type = (_field_type), .field_flags = (_field_flags), .field_direction = VARLINK_INPUT }
93
94#define VARLINK_DEFINE_INPUT_BY_TYPE(_name, _named_type, _field_flags) \
95 { .name = #_name, .field_type = VARLINK_NAMED_TYPE, .named_type = #_named_type, .symbol = &vl_type_ ## _named_type, .field_flags = (_field_flags), .field_direction = VARLINK_INPUT }
96
97#define VARLINK_DEFINE_OUTPUT(_name, _field_type, _field_flags) \
98 { .name = #_name, .field_type = (_field_type), .field_flags = (_field_flags), .field_direction = VARLINK_OUTPUT }
99
100#define VARLINK_DEFINE_OUTPUT_BY_TYPE(_name, _named_type, _field_flags) \
101 { .name = #_name, .field_type = VARLINK_NAMED_TYPE, .named_type = #_named_type, .symbol = &vl_type_ ## _named_type, .field_flags = (_field_flags), .field_direction = VARLINK_OUTPUT }
102
103#define VARLINK_DEFINE_ENUM_VALUE(_name) \
104 { .name = #_name, .field_type = VARLINK_ENUM_VALUE }
105
106#define VARLINK_DEFINE_METHOD(_name, ...) \
107 const VarlinkSymbol vl_method_ ## _name = { \
108 .name = #_name, \
109 .symbol_type = VARLINK_METHOD, \
110 .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \
111 }
112
113#define VARLINK_DEFINE_ERROR(_name, ...) \
114 const VarlinkSymbol vl_error_ ## _name = { \
115 .name = #_name, \
116 .symbol_type = VARLINK_ERROR, \
117 .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \
118 }
119
120#define VARLINK_DEFINE_STRUCT_TYPE(_name, ...) \
121 const VarlinkSymbol vl_type_ ## _name = { \
122 .name = #_name, \
123 .symbol_type = VARLINK_STRUCT_TYPE, \
124 .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \
125 }
126
127#define VARLINK_DEFINE_ENUM_TYPE(_name, ...) \
128 const VarlinkSymbol vl_type_ ## _name = { \
129 .name = #_name, \
130 .symbol_type = VARLINK_ENUM_TYPE, \
131 .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \
132 }
133
134#define VARLINK_DEFINE_INTERFACE(_name, _full_name, ...) \
135 const VarlinkInterface vl_interface_ ## _name = { \
136 .name = (_full_name), \
137 .symbols = { __VA_ARGS__ __VA_OPT__(,) NULL}, \
138 }
139
140int varlink_idl_dump(FILE *f, int use_colors, const VarlinkInterface *interface);
141int varlink_idl_format(const VarlinkInterface *interface, char **ret);
142
143int varlink_idl_parse(const char *text, unsigned *ret_line, unsigned *ret_column, VarlinkInterface **ret);
144VarlinkInterface* varlink_interface_free(VarlinkInterface *interface);
145DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkInterface*, varlink_interface_free);
146
147bool varlink_idl_field_name_is_valid(const char *name);
148bool varlink_idl_symbol_name_is_valid(const char *name);
149bool varlink_idl_interface_name_is_valid(const char *name);
150
a972870e 151int varlink_idl_consistent(const VarlinkInterface *interface, int level);
e50b2a93
LP
152
153const VarlinkSymbol* varlink_idl_find_symbol(const VarlinkInterface *interface, VarlinkSymbolType type, const char *name);
154const VarlinkField* varlink_idl_find_field(const VarlinkSymbol *symbol, const char *name);
155
156int varlink_idl_validate_method_call(const VarlinkSymbol *method, JsonVariant *v, const char **bad_field);
157int varlink_idl_validate_method_reply(const VarlinkSymbol *method, JsonVariant *v, const char **bad_field);
158int varlink_idl_validate_error(const VarlinkSymbol *error, JsonVariant *v, const char **bad_field);