4 * Babeltrace Trace Converter
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/babeltrace.h>
30 #include <babeltrace/plugin/component-factory.h>
31 #include <babeltrace/plugin/plugin.h>
32 #include <babeltrace/plugin/component-class.h>
33 #include <babeltrace/plugin/notification/iterator.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/values.h>
37 #include <babeltrace/ctf-ir/metadata.h> /* for clocks */
43 static char *opt_plugin_path
;
44 static char *opt_input_path
;
56 * We are _not_ using POPT_ARG_STRING's ability to store directly into
57 * variables, because we want to cast the return to non-const, which is
58 * not possible without using poptGetOptArg explicitly. This helps us
59 * controlling memory allocation correctly without making assumptions
60 * about undocumented behaviors. poptGetOptArg is documented as
61 * requiring the returned const char * to be freed by the caller.
63 static struct poptOption long_options
[] = {
64 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
65 { "plugin-path", 0, POPT_ARG_STRING
, NULL
, OPT_PLUGIN_PATH
, NULL
, NULL
},
66 { "input-path", 0, POPT_ARG_STRING
, NULL
, OPT_INPUT_PATH
, NULL
, NULL
},
67 { "verbose", 'v', POPT_ARG_NONE
, NULL
, OPT_VERBOSE
, NULL
, NULL
},
68 { "debug", 'd', POPT_ARG_NONE
, NULL
, OPT_DEBUG
, NULL
, NULL
},
69 { NULL
, 0, 0, NULL
, 0, NULL
, NULL
},
73 * Return 0 if caller should continue, < 0 if caller should return
74 * error, > 0 if caller should exit without reporting error.
76 static int parse_options(int argc
, char **argv
)
82 return 1; /* exit cleanly */
85 pc
= poptGetContext(NULL
, argc
, (const char **) argv
, long_options
, 0);
86 poptReadDefaultConfig(pc
, 0);
89 opt_context_field_names
= 1;
90 opt_payload_field_names
= 1;
92 while ((opt
= poptGetNextOpt(pc
)) != -1) {
95 ret
= 1; /* exit cleanly */
98 opt_plugin_path
= (char *) poptGetOptArg(pc
);
99 if (!opt_plugin_path
) {
105 babeltrace_verbose
= 1;
108 babeltrace_debug
= 1;
111 opt_input_path
= (char *) poptGetOptArg(pc
);
112 if (!opt_input_path
) {
131 const char *component_type_str(enum bt_component_type type
)
134 case BT_COMPONENT_TYPE_SOURCE
:
136 case BT_COMPONENT_TYPE_SINK
:
138 case BT_COMPONENT_TYPE_FILTER
:
140 case BT_COMPONENT_TYPE_UNKNOWN
:
147 void print_found_component_classes(struct bt_component_factory
*factory
)
151 if (!babeltrace_verbose
) {
155 count
= bt_component_factory_get_component_class_count(factory
);
157 fprintf(stderr
, "No component classes found. Please make sure your plug-in search path is set correctly.");
161 printf_verbose("Found %d component classes.\n", count
);
162 for (i
= 0; i
< count
; i
++) {
163 struct bt_component_class
*component_class
=
164 bt_component_factory_get_component_class_index(
166 struct bt_plugin
*plugin
= bt_component_class_get_plugin(
168 const char *plugin_name
= bt_plugin_get_name(plugin
);
169 const char *component_name
= bt_component_class_get_name(
171 const char *path
= bt_plugin_get_path(plugin
);
172 const char *author
= bt_plugin_get_author(plugin
);
173 const char *license
= bt_plugin_get_license(plugin
);
174 const char *plugin_description
= bt_plugin_get_description(
176 const char *component_description
=
177 bt_component_class_get_description(
179 enum bt_component_type type
= bt_component_class_get_type(
182 printf_verbose("[%s - %s (%s)]\n", plugin_name
, component_name
,
183 component_type_str(type
));
184 printf_verbose("\tpath: %s\n", path
);
185 printf_verbose("\tauthor: %s\n", author
);
186 printf_verbose("\tlicense: %s\n", license
);
187 printf_verbose("\tplugin description: %s\n",
188 plugin_description
? plugin_description
: "None");
189 printf_verbose("\tcomponent description: %s\n",
190 component_description
? component_description
: "None");
193 bt_put(component_class
);
197 int main(int argc
, char **argv
)
200 enum bt_value_status value_status
;
201 struct bt_component_factory
*component_factory
= NULL
;
202 struct bt_component_class
*source_class
= NULL
, *sink_class
= NULL
;
203 struct bt_component
*source
= NULL
, *sink
= NULL
;
204 struct bt_value
*source_params
= NULL
, *sink_params
= NULL
;
205 struct bt_notification_iterator
*it
= NULL
;
207 ret
= parse_options(argc
, argv
);
209 fprintf(stderr
, "Error parsing options.\n\n");
211 } else if (ret
> 0) {
215 source_params
= bt_value_map_create();
216 if (!source_params
) {
217 fprintf(stderr
, "Failed to create source parameters map, aborting...\n");
222 value_status
= bt_value_map_insert_string(source_params
, "path",
224 if (value_status
!= BT_VALUE_STATUS_OK
) {
229 printf_verbose("Verbose mode active.\n");
230 printf_debug("Debug mode active.\n");
232 if (!opt_plugin_path
) {
233 fprintf(stderr
, "No plugin path specified, aborting...\n");
237 printf_verbose("Looking-up plugins at %s\n",
238 opt_plugin_path
? opt_plugin_path
: "Invalid");
239 component_factory
= bt_component_factory_create();
240 if (!component_factory
) {
241 fprintf(stderr
, "Failed to create component factory.\n");
246 ret
= bt_component_factory_load_recursive(component_factory
, opt_plugin_path
);
248 fprintf(stderr
, "Failed to load plugins.\n");
252 print_found_component_classes(component_factory
);
254 source_class
= bt_component_factory_get_component_class(
255 component_factory
, "ctf", BT_COMPONENT_TYPE_SOURCE
,
258 fprintf(stderr
, "Could not find ctf-fs source component class. Aborting...\n");
263 sink_class
= bt_component_factory_get_component_class(component_factory
,
264 "text", BT_COMPONENT_TYPE_SINK
, "text");
266 fprintf(stderr
, "Could not find text sink component class. Aborting...\n");
271 source
= bt_component_create(source_class
, "ctf-fs", source_params
);
273 fprintf(stderr
, "Failed to instantiate source component. Aborting...\n");
278 sink
= bt_component_create(sink_class
, "bt_text_output", sink_params
);
280 fprintf(stderr
, "Failed to instantiate output component. Aborting...\n");
285 it
= bt_component_source_create_iterator(source
);
287 fprintf(stderr
, "Failed to instantiate source iterator. Aborting...\n");
293 enum bt_component_status sink_status
;
294 struct bt_notification
*notification
=
295 bt_notification_iterator_get_notification(it
);
299 * Should never happen in final code except after next
300 * has returned BT_NOTIFICATION_ITERATOR_STATUS_END.
302 * Right now it happens at the first event since the
303 * iterator is not completely initialized and we don't
304 * have a notification "heap" in place.
309 sink_status
= bt_component_sink_handle_notification(sink
,
311 BT_PUT(notification
);
312 if (sink_status
!= BT_COMPONENT_STATUS_OK
) {
313 fprintf(stderr
, "Sink component returned an error, aborting...\n");
316 } while (bt_notification_iterator_next(it
) ==
317 BT_NOTIFICATION_ITERATOR_STATUS_OK
);
318 /* teardown and exit */
320 BT_PUT(component_factory
);
322 BT_PUT(source_class
);
325 BT_PUT(source_params
);