2 * SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
11 #include <babeltrace2/babeltrace.h>
14 #include "common/assert.h"
17 typedef void (* run_in_comp_cls_init_func
)(
18 bt_self_component
*self_comp
, void *user_data
);
20 struct comp_cls_init_method_data
{
21 run_in_comp_cls_init_func func
;
26 bt_component_class_initialize_method_status
comp_cls_init(
27 bt_self_component_source
*self_comp
,
28 bt_self_component_source_configuration
*conf
,
29 const bt_value
*params
, void *init_method_data
)
31 comp_cls_init_method_data
*data
=
32 static_cast<comp_cls_init_method_data
*>(init_method_data
);
34 /* Call user function which is expected to abort */
35 data
->func(bt_self_component_source_as_self_component(self_comp
),
39 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR
;
43 bt_message_iterator_class_next_method_status
msg_iter_cls_next(
44 bt_self_message_iterator
*self_msg_iter
,
45 bt_message_array_const msgs
, uint64_t capacity
,
49 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR
;
53 void run_in_comp_cls_init(run_in_comp_cls_init_func func
,
56 bt_message_iterator_class
*msg_iter_cls
;
57 bt_component_class_source
*comp_cls
;
58 bt_component_class_set_method_status set_method_status
;
60 struct comp_cls_init_method_data init_method_data
= {
62 .user_data
= user_data
,
65 /* Create component class */
66 msg_iter_cls
= bt_message_iterator_class_create(msg_iter_cls_next
);
67 BT_ASSERT(msg_iter_cls
);
68 comp_cls
= bt_component_class_source_create("yo", msg_iter_cls
);
70 set_method_status
= bt_component_class_source_set_initialize_method(
71 comp_cls
, comp_cls_init
);
72 BT_ASSERT(set_method_status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
75 graph
= bt_graph_create(0);
79 * Add source component: this calls the initialization method,
82 (void) bt_graph_add_source_component_with_initialize_method_data(graph
,
83 comp_cls
, "whatever", NULL
, &init_method_data
,
84 BT_LOGGING_LEVEL_NONE
, NULL
);
87 * This point is not expected to be reached as func() is
93 void run_in_comp_cls_init_defer(bt_self_component
*self_comp
,
96 cond_trigger_run_in_comp_cls_init_func user_func
=
97 reinterpret_cast<cond_trigger_run_in_comp_cls_init_func
>(user_data
);
103 void run_trigger(const struct cond_trigger
*trigger
)
105 switch (trigger
->func_type
) {
106 case COND_TRIGGER_FUNC_TYPE_BASIC
:
107 trigger
->func
.basic();
109 case COND_TRIGGER_FUNC_TYPE_RUN_IN_COMP_CLS_INIT
:
110 run_in_comp_cls_init(run_in_comp_cls_init_defer
,
111 reinterpret_cast<void *>(trigger
->func
.run_in_comp_cls_init
));
119 void escape_json_string(const char *str
, GString
*escaped_str
)
121 g_string_assign(escaped_str
, "");
123 for (const char *ch
= str
; *ch
; ch
++) {
124 if (*ch
== '\\' || *ch
== '"') {
125 g_string_append_c(escaped_str
, '\\');
128 g_string_append_c(escaped_str
, *ch
);
133 void list_triggers(const struct cond_trigger triggers
[], size_t trigger_count
)
135 GString
*escaped_str
= g_string_new(NULL
);
138 BT_ASSERT(escaped_str
);
141 for (i
= 0; i
< trigger_count
; i
++) {
142 const struct cond_trigger
*trigger
= &triggers
[i
];
145 escape_json_string(trigger
->cond_id
, escaped_str
);
146 printf("{\"cond-id\":\"%s\",", escaped_str
->str
);
148 /* Name starts with condition ID */
149 printf("\"name\":\"%s", escaped_str
->str
);
151 if (trigger
->suffix
) {
152 escape_json_string(trigger
->suffix
, escaped_str
);
153 printf("-%s", escaped_str
->str
);
158 if (i
< trigger_count
- 1) {
159 /* Comma between objects */
165 g_string_free(escaped_str
, TRUE
);
169 void cond_main(int argc
, const char *argv
[],
170 const struct cond_trigger triggers
[], size_t trigger_count
)
172 BT_ASSERT(argc
>= 2);
174 if (strcmp(argv
[1], "list") == 0) {
175 list_triggers(triggers
, trigger_count
);
176 } else if (strcmp(argv
[1], "run") == 0) {
179 BT_ASSERT(argc
>= 3);
180 index
= atoi(argv
[2]);
181 BT_ASSERT(index
>= 0 && index
< trigger_count
);
182 run_trigger(&triggers
[index
]);