/* Stack-copy compound types */
side_ptr_t(const struct side_arg_vec) side_struct;
side_ptr_t(const struct side_arg_variant) side_variant;
+ side_ptr_t(const struct side_arg_optional) side_optional;
side_ptr_t(const struct side_arg_vec) side_array;
side_ptr_t(const struct side_arg_vec) side_vla;
/* Pointer to non-const structure. Content modified by libside. */
} SIDE_PACKED;
side_check_size(struct side_arg_variant, 128);
+struct side_arg_optional {
+ struct side_arg side_static;
+ uint8_t selector;
+} SIDE_PACKED;
+side_check_size(struct side_arg_optional, 65);
+
struct side_arg_vec {
side_ptr_t(const struct side_arg) sav;
uint32_t len;
/* Stack-copy compound types */
SIDE_TYPE_STRUCT,
SIDE_TYPE_VARIANT,
+ SIDE_TYPE_OPTIONAL,
SIDE_TYPE_ARRAY,
SIDE_TYPE_VLA,
SIDE_TYPE_VLA_VISITOR,
side_ptr_t(const struct side_type_vla_visitor) side_vla_visitor;
side_ptr_t(const struct side_type_struct) side_struct;
side_ptr_t(const struct side_type_variant) side_variant;
+ side_ptr_t(const struct side_type) side_optional;
/* Stack-copy enumeration types */
struct side_type_enum side_enum;
const struct side_type_variant _identifier = \
_side_type_variant_define(SIDE_PARAM(_selector), SIDE_PARAM(_options), SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
-#define side_variant_literal(_selector, _options, _attr...) \
- SIDE_COMPOUND_LITERAL(const struct side_type_variant, \
- _side_type_variant_define(SIDE_PARAM(_selector), SIDE_PARAM(_options), SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())))
+enum {
+ SIDE_OPTIONAL_DISABLED = 0,
+ SIDE_OPTIONAL_ENABLED = 1,
+};
+
+#define side_type_optional(_type) \
+ { \
+ .type = SIDE_ENUM_INIT(SIDE_TYPE_OPTIONAL), \
+ .u = { \
+ .side_optional = SIDE_PTR_INIT(_type), \
+ }, \
+ }
+
+#define side_define_optional(_identifier, _type) \
+ const struct side_type _identifier = side_type_optional(SIDE_PARAM(_type))
+
+#define side_field_optional(_name, _identifier) \
+ _side_field(_name, side_type_optional(_identifier))
+
+#define side_field_optional_literal(_name, _type) \
+ _side_field(_name, side_type_optional(SIDE_PARAM(_type)))
#define side_type_array(_elem_type, _length, _attr...) \
{ \
}, \
}
+
+#define side_arg_define_optional(_identifier, _value, _selector) \
+ const struct side_arg_optional _identifier = { \
+ .side_static = _value, \
+ .selector = _selector, \
+ }
+
+#define side_arg_optional(_identifier) \
+ { \
+ .type = SIDE_ENUM_INIT(SIDE_TYPE_OPTIONAL), \
+ .flags = 0, \
+ .u = { \
+ .side_static = { \
+ .side_optional = SIDE_PTR_INIT(_identifier) \
+ }, \
+ }, \
+ }
+
#define side_arg_array(_side_type) { .type = SIDE_ENUM_INIT(SIDE_TYPE_ARRAY), .flags = 0, .u = { .side_static = { .side_array = SIDE_PTR_INIT(_side_type) } } }
#define side_arg_vla(_side_type) { .type = SIDE_ENUM_INIT(SIDE_TYPE_VLA), .flags = 0, .u = { .side_static = { .side_vla = SIDE_PTR_INIT(_side_type) } } }
#define side_arg_vla_visitor(_side_vla_visitor) \
printf(" } }");
}
+static
+void before_print_description_optional(const struct side_type *optional __attribute__((unused)),
+ void *priv __attribute__((unused)))
+{
+ struct print_ctx *ctx = (struct print_ctx *) priv;
+
+ printf("type: optional {");
+ push_nesting(ctx);
+}
+
+static
+void after_print_description_optional(const struct side_type *optional __attribute__((unused)), void *priv)
+{
+ struct print_ctx *ctx = (struct print_ctx *) priv;
+
+ pop_nesting(ctx);
+ printf(" } }");
+}
+
static
void before_print_description_array(const struct side_type_array *side_array, void *priv)
{
.before_vla_visitor_type_func = before_print_description_vla_visitor,
.after_length_vla_visitor_type_func = after_length_print_description_vla_visitor,
.after_element_vla_visitor_type_func = after_element_print_description_vla_visitor,
+ .before_optional_type_func = before_print_description_optional,
+ .after_optional_type_func = after_print_description_optional,
/* Stack-copy enumeration types. */
.before_enum_type_func = before_print_description_enum,
CONTEXT_FIELD,
CONTEXT_ARRAY,
CONTEXT_STRUCT,
+ CONTEXT_OPTIONAL,
};
struct visit_context {
abort();
}
+static
+void type_visitor_optional(const struct side_type_visitor *type_visitor, const struct visit_context *ctx,
+ const struct side_type *type_desc, const struct side_arg_optional *side_arg_optional, void *priv)
+{
+ const struct side_type *type;
+ const struct side_arg *arg;
+ struct visit_context new_ctx = {
+ .type = CONTEXT_OPTIONAL,
+ .parent = ctx,
+ };
+
+ if (side_arg_optional->selector == SIDE_OPTIONAL_DISABLED)
+ return;
+
+ type = side_ptr_get(type_desc->u.side_optional);
+ arg = &side_arg_optional->side_static;
+
+ side_visit_type(type_visitor, &new_ctx, type, arg, priv);
+}
+
static
void type_visitor_array(const struct side_type_visitor *type_visitor, const struct visit_context *ctx,
const struct side_type *type_desc, const struct side_arg_vec *side_arg_vec, void *priv)
case CONTEXT_ARRAY:
fprintf(stderr, "index: %zu", ctx->array_index);
break;
+ case CONTEXT_OPTIONAL:
+ fprintf(stderr, "optional");
+ break;
case CONTEXT_NAMESPACE: /* Fallthrough */
default:
abort();
visit_dynamic_type(type_visitor, item, priv);
break;
+ case SIDE_TYPE_OPTIONAL:
+ type_visitor_optional(type_visitor, ctx, type_desc,
+ side_ptr_get(item->u.side_static.side_optional),
+ priv);
+ break;
+
default:
fprintf(stderr, "<UNKNOWN TYPE>\n");
abort();
description_visitor->after_variant_type_func(side_type_variant, priv);
}
+static
+void description_visitor_optional(const struct side_description_visitor *description_visitor,
+ const struct side_type *type_desc, void *priv)
+{
+ const struct side_type *optional = side_ptr_get(type_desc->u.side_optional);
+
+ if (description_visitor->before_optional_type_func)
+ description_visitor->before_optional_type_func(optional, priv);
+ side_visit_type(description_visitor, optional, priv);
+ if (description_visitor->after_optional_type_func)
+ description_visitor->after_optional_type_func(optional, priv);
+}
+
static
void description_visitor_array(const struct side_description_visitor *description_visitor, const struct side_type *type_desc, void *priv)
{
description_visitor->dynamic_type_func(type_desc, priv);
break;
+ case SIDE_TYPE_OPTIONAL:
+ description_visitor_optional(description_visitor, type_desc, priv);
+ break;
+
default:
fprintf(stderr, "<UNKNOWN TYPE>\n");
abort();
void (*before_vla_visitor_type_func)(const struct side_type_vla_visitor *side_vla_visitor, void *priv);
void (*after_length_vla_visitor_type_func)(const struct side_type_vla_visitor *side_vla_visitor, void *priv);
void (*after_element_vla_visitor_type_func)(const struct side_type_vla_visitor *side_vla_visitor, void *priv);
+ void (*before_optional_type_func)(const struct side_type *optional, void *priv);
+ void (*after_optional_type_func)(const struct side_type *optional, void *priv);
/* Stack-copy enumeration types. */
void (*before_enum_type_func)(const struct side_type *type_desc, void *priv);
#undef X
}
+static side_define_optional(my_optional, side_elem(side_type_string()));
+
+side_static_event(my_provider_event_optional, "myprovider", "myeventoptional", SIDE_LOGLEVEL_DEBUG,
+ side_field_list(
+ side_field_optional("a", &my_optional),
+ side_field_optional_literal("b", side_elem(side_type_string())),
+ )
+);
+
+
+static
+void test_optional(void)
+{
+ if (side_event_enabled(my_provider_event_optional)) {
+ side_arg_define_optional(present, side_arg_string("present"), SIDE_OPTIONAL_ENABLED);
+ side_arg_define_optional(absent, side_arg_string("absent"), SIDE_OPTIONAL_DISABLED);
+
+ side_event_call(my_provider_event_optional,
+ side_arg_list(
+ side_arg_optional(&present),
+ side_arg_optional(&absent),
+ )
+ );
+ }
+}
int main()
{
test_variant();
test_integer128();
test_c_native_types();
+ test_optional();
return 0;
}