Dynamic types
[libside.git] / include / side / trace.h
index b8399790102420e414d23e1c4dda636fe706c193..b1cfc17719b481524892cbe97521cc0975bc6f29 100644 (file)
 
 struct side_arg_vec;
 struct side_type_description;
+struct side_dynamic_type_description;
 struct side_event_field;
+struct side_tracer_visitor_ctx;
+struct side_tracer_dynamic_map_visitor_ctx;
+struct side_tracer_dynamic_vla_visitor_ctx;
 
 enum side_type {
        SIDE_TYPE_U8,
@@ -27,15 +31,51 @@ enum side_type {
        SIDE_TYPE_S16,
        SIDE_TYPE_S32,
        SIDE_TYPE_S64,
+
        SIDE_TYPE_STRING,
-       SIDE_TYPE_DYNAMIC,
+
        SIDE_TYPE_STRUCT,
        SIDE_TYPE_ARRAY,
        SIDE_TYPE_VLA,
        SIDE_TYPE_VLA_VISITOR,
-       //TODO:
-       //specialized array and vla for fixed-size integers (optimization)
-       //variants (discriminated unions)
+
+       SIDE_TYPE_ARRAY_U8,
+       SIDE_TYPE_ARRAY_U16,
+       SIDE_TYPE_ARRAY_U32,
+       SIDE_TYPE_ARRAY_U64,
+       SIDE_TYPE_ARRAY_S8,
+       SIDE_TYPE_ARRAY_S16,
+       SIDE_TYPE_ARRAY_S32,
+       SIDE_TYPE_ARRAY_S64,
+
+       SIDE_TYPE_VLA_U8,
+       SIDE_TYPE_VLA_U16,
+       SIDE_TYPE_VLA_U32,
+       SIDE_TYPE_VLA_U64,
+       SIDE_TYPE_VLA_S8,
+       SIDE_TYPE_VLA_S16,
+       SIDE_TYPE_VLA_S32,
+       SIDE_TYPE_VLA_S64,
+
+       SIDE_TYPE_DYNAMIC,
+};
+
+enum side_dynamic_type {
+       SIDE_DYNAMIC_TYPE_NULL,
+
+       SIDE_DYNAMIC_TYPE_U8,
+       SIDE_DYNAMIC_TYPE_U16,
+       SIDE_DYNAMIC_TYPE_U32,
+       SIDE_DYNAMIC_TYPE_U64,
+       SIDE_DYNAMIC_TYPE_S8,
+       SIDE_DYNAMIC_TYPE_S16,
+       SIDE_DYNAMIC_TYPE_S32,
+       SIDE_DYNAMIC_TYPE_S64,
+
+       SIDE_DYNAMIC_TYPE_STRING,
+
+       SIDE_DYNAMIC_TYPE_MAP_VISITOR,
+       SIDE_DYNAMIC_TYPE_VLA_VISITOR,
 };
 
 enum side_loglevel {
@@ -55,12 +95,16 @@ enum side_visitor_status {
        SIDE_VISITOR_STATUS_END = 1,
 };
 
-typedef enum side_visitor_status (*side_visitor_begin)(void *ctx);
-typedef enum side_visitor_status (*side_visitor_end)(void *ctx);
-typedef enum side_visitor_status (*side_visitor_get_next)(void *ctx, struct side_arg_vec *sav_elem);
+typedef enum side_visitor_status (*side_visitor)(const struct side_tracer_visitor_ctx *tracer_ctx,
+                                               void *app_ctx);
+typedef enum side_visitor_status (*side_dynamic_map_visitor)(const struct side_tracer_dynamic_map_visitor_ctx *tracer_ctx,
+                                               void *app_ctx);
+typedef enum side_visitor_status (*side_dynamic_vla_visitor)(const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
+                                               void *app_ctx);
 
 struct side_type_description {
        enum side_type type;
+       //TODO: we should add something like a list of user attributes (namespaced strings)
        union {
                struct {
                        uint32_t nr_fields;
@@ -75,9 +119,7 @@ struct side_type_description {
                } side_vla;
                struct {
                        const struct side_type_description *elem_type;
-                       side_visitor_begin begin;
-                       side_visitor_end end;
-                       side_visitor_get_next get_next;
+                       side_visitor visitor;
                } side_vla_visitor;
        } u;
 };
@@ -97,6 +139,31 @@ struct side_event_description {
        const struct side_event_field *fields;
 };
 
+struct side_arg_dynamic_vec {
+       uint32_t type;  /* enum side_dynamic_type */
+       union {
+               uint8_t side_u8;
+               uint16_t side_u16;
+               uint32_t side_u32;
+               uint64_t side_u64;
+               int8_t side_s8;
+               int16_t side_s16;
+               int32_t side_s32;
+               int64_t side_s64;
+
+               const char *string;
+
+               struct {
+                       void *app_dynamic_visitor_ctx;
+                       side_dynamic_map_visitor visitor;
+               } side_dynamic_map_visitor;
+               struct {
+                       void *app_dynamic_visitor_ctx;
+                       side_dynamic_vla_visitor visitor;
+               } side_dynamic_vla_visitor;
+       } u;
+};
+
 struct side_arg_vec {
        uint32_t type;  /* enum side_type */
        union {
@@ -108,11 +175,20 @@ struct side_arg_vec {
                int16_t side_s16;
                int32_t side_s32;
                int64_t side_s64;
+
                const char *string;
                const struct side_arg_vec_description *side_struct;
                const struct side_arg_vec_description *side_array;
                const struct side_arg_vec_description *side_vla;
-               void *side_vla_visitor_ctx;
+               void *side_vla_app_visitor_ctx;
+
+               void *side_array_fixint;
+               struct {
+                       void *p;
+                       uint32_t length;
+               } side_vla_fixint;
+
+               struct side_arg_dynamic_vec dynamic;
        } u;
 };
 
@@ -121,6 +197,31 @@ struct side_arg_vec_description {
        uint32_t len;
 };
 
+struct side_dynamic_event_field {
+       const char *field_name;
+       const struct side_arg_dynamic_vec *elem;
+       //TODO: we should add something like a list of user attributes (namespaced strings)
+};
+
+/* The visitor pattern is a double-dispatch visitor. */
+struct side_tracer_visitor_ctx {
+       enum side_visitor_status (*write_elem)(const struct side_tracer_visitor_ctx *tracer_ctx,
+                                       const struct side_arg_vec *elem);
+       void *priv;             /* Private tracer context. */
+};
+
+struct side_tracer_dynamic_map_visitor_ctx {
+       enum side_visitor_status (*write_field)(const struct side_tracer_dynamic_map_visitor_ctx *tracer_ctx,
+                                       const struct side_dynamic_event_field *field);
+       void *priv;             /* Private tracer context. */
+};
+
+struct side_tracer_dynamic_vla_visitor_ctx {
+       enum side_visitor_status (*write_elem)(const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
+                                       const struct side_arg_dynamic_vec *elem);
+       void *priv;             /* Private tracer context. */
+};
+
 #define side_type_decl(_type)                  { .type = _type }
 #define side_field(_type, _name)               { .field_name = _name, .side_type = side_type_decl(_type) }
 
@@ -171,26 +272,27 @@ struct side_arg_vec_description {
                .side_type = side_type_vla_decl(_elem_type), \
        }
 
-#define side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next) \
+#define side_type_vla_visitor_decl(_elem_type, _visitor) \
        { \
                .type = SIDE_TYPE_VLA_VISITOR, \
                .u = { \
                        .side_vla_visitor = { \
-                               .elem_type = _elem_type, \
-                               .begin = _begin, \
-                               .end = _end, \
-                               .get_next = _get_next, \
+                               .elem_type = SIDE_PARAM(_elem_type), \
+                               .visitor = _visitor, \
                        }, \
                }, \
        }
-#define side_field_vla_visitor(_name, _elem_type, _begin, _end, _get_next) \
+#define side_field_vla_visitor(_name, _elem_type, _visitor) \
        { \
                .field_name = _name, \
-               .side_type = side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next), \
+               .side_type = side_type_vla_visitor_decl(SIDE_PARAM(_elem_type), _visitor), \
        }
 
 #define side_elem(...) \
-       SIDE_COMPOUND_LITERAL(const struct side_type_description, side_type_decl(__VA_ARGS__))
+       SIDE_COMPOUND_LITERAL(const struct side_type_description, __VA_ARGS__)
+
+#define side_elem_type(...) \
+       side_elem(side_type_decl(__VA_ARGS__))
 
 #define side_field_list(...) \
        SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
@@ -207,7 +309,63 @@ struct side_arg_vec_description {
 #define side_arg_struct(_side_type)    { .type = SIDE_TYPE_STRUCT, .u = { .side_struct = (_side_type) } }
 #define side_arg_array(_side_type)     { .type = SIDE_TYPE_ARRAY, .u = { .side_array = (_side_type) } }
 #define side_arg_vla(_side_type)       { .type = SIDE_TYPE_VLA, .u = { .side_vla = (_side_type) } }
-#define side_arg_vla_visitor(_ctx)     { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_vla_visitor_ctx = (_ctx) } }
+#define side_arg_vla_visitor(_ctx)     { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_vla_app_visitor_ctx = (_ctx) } }
+
+#define side_arg_array_u8(_ptr)                { .type = SIDE_TYPE_ARRAY_U8, .u = { .side_array_fixint = (_ptr) } }
+#define side_arg_array_u16(_ptr)       { .type = SIDE_TYPE_ARRAY_U16, .u = { .side_array_fixint = (_ptr) } }
+#define side_arg_array_u32(_ptr)       { .type = SIDE_TYPE_ARRAY_U32, .u = { .side_array_fixint = (_ptr) } }
+#define side_arg_array_u64(_ptr)       { .type = SIDE_TYPE_ARRAY_U64, .u = { .side_array_fixint = (_ptr) } }
+#define side_arg_array_s8(_ptr)                { .type = SIDE_TYPE_ARRAY_S8, .u = { .side_array_fixint = (_ptr) } }
+#define side_arg_array_s16(_ptr)       { .type = SIDE_TYPE_ARRAY_S16, .u = { .side_array_fixint  = (_ptr) } }
+#define side_arg_array_s32(_ptr)       { .type = SIDE_TYPE_ARRAY_S32, .u = { .side_array_fixint = (_ptr) } }
+#define side_arg_array_s64(_ptr)       { .type = SIDE_TYPE_ARRAY_S64, .u = { .side_array_fixint = (_ptr) } }
+
+#define side_arg_vla_u8(_ptr, _length) { .type = SIDE_TYPE_VLA_U8, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } }
+#define side_arg_vla_u16(_ptr, _length)        { .type = SIDE_TYPE_VLA_U16, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
+#define side_arg_vla_u32(_ptr, _length)        { .type = SIDE_TYPE_VLA_U32, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
+#define side_arg_vla_u64(_ptr, _length)        { .type = SIDE_TYPE_VLA_U64, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
+#define side_arg_vla_s8(_ptr, _length) { .type = SIDE_TYPE_VLA_S8, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
+#define side_arg_vla_s16(_ptr, _length)        { .type = SIDE_TYPE_VLA_S16, .u = { .side_vla_fixint  = { .p = (_ptr), .length = (_length) } } }
+#define side_arg_vla_s32(_ptr, _length)        { .type = SIDE_TYPE_VLA_S32, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
+#define side_arg_vla_s64(_ptr, _length)        { .type = SIDE_TYPE_VLA_S64, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
+
+#define side_arg_dynamic(dynamic_arg_type) \
+       { \
+               .type = SIDE_TYPE_DYNAMIC, \
+               .u = { \
+                       .dynamic = dynamic_arg_type, \
+               }, \
+       }
+
+#define side_arg_dynamic_null(val)     { .type = SIDE_DYNAMIC_TYPE_NULL }
+
+#define side_arg_dynamic_u8(val)       { .type = SIDE_DYNAMIC_TYPE_U8, .u = { .side_u8 = (val) } }
+#define side_arg_dynamic_u16(val)      { .type = SIDE_DYNAMIC_TYPE_U16, .u = { .side_u16 = (val) } }
+#define side_arg_dynamic_u32(val)      { .type = SIDE_DYNAMIC_TYPE_U32, .u = { .side_u32 = (val) } }
+#define side_arg_dynamic_u64(val)      { .type = SIDE_DYNAMIC_TYPE_U64, .u = { .side_u64 = (val) } }
+#define side_arg_dynamic_s8(val)       { .type = SIDE_DYNAMIC_TYPE_S8, .u = { .side_s8 = (val) } }
+#define side_arg_dynamic_s16(val)      { .type = SIDE_DYNAMIC_TYPE_S16, .u = { .side_s16 = (val) } }
+#define side_arg_dynamic_s32(val)      { .type = SIDE_DYNAMIC_TYPE_S32, .u = { .side_s32 = (val) } }
+#define side_arg_dynamic_s64(val)      { .type = SIDE_DYNAMIC_TYPE_S64, .u = { .side_s64 = (val) } }
+#define side_arg_dynamic_string(val)   { .type = SIDE_DYNAMIC_TYPE_STRING, .u = { .string = (val) } }
+
+#define side_arg_dynamic_vla_visitor(_dynamic_vla_visitor, _ctx) \
+       { \
+               .type = SIDE_DYNAMIC_TYPE_VLA_VISITOR, \
+               .app_dynamic_visitor_ctx = _ctx, \
+               .u = { \
+                       .vla_visitor = _dynamic_vla_visitor, \
+               }, \
+       }
+
+#define side_arg_dynamic_map_visitor(_dynamic_map_visitor, _ctx) \
+       { \
+               .type = SIDE_DYNAMIC_TYPE_MAP_VISITOR, \
+               .app_dynamic_visitor_ctx = _ctx, \
+               .u = { \
+                       .map_visitor = _dynamic_map_visitor, \
+               }, \
+       }
 
 #define side_arg_define_vec(_identifier, _sav) \
        const struct side_arg_vec _identifier##_vec[] = { _sav }; \
This page took 0.026831 seconds and 4 git commands to generate.