goto end;
}
- components = bt_component_factory_get_components(component_factory);
- if (!components || bt_value_array_is_empty(components)) {
- printf_error("No plugins found, exiting.");
- ret = -1;
+ ret = bt_component_factory_get_component_class_count(component_factory);
+ if (ret <= 0) {
goto end;
}
enum bt_component_type type;
GString *name;
struct bt_plugin *plugin;
+ bt_component_init_cb init;
};
BT_HIDDEN
const char *name);
BT_HIDDEN
-int bt_component_class_set_plugin(struct bt_component_class *class,
+struct bt_component_class *bt_component_class_create(
+ enum bt_component_type type, const char *name,
struct bt_plugin *plugin);
#endif /* BABELTRACE_PLUGIN_COMPONENT_CLASS_INTERNAL_H */
BT_COMPONENT_TYPE_FILTER = 2,
};
+struct bt_plugin;
struct bt_component_class;
-const char *bt_component_class_get_name(
+
+/**
+ * Get a component class' name.
+ *
+ * @param component_class Component class of which to get the name
+ * @returns Name of the component class
+ */
+extern const char *bt_component_class_get_name(
+ struct bt_component_class *component_class);
+
+/**
+ * Get a component class' type.
+ *
+ * @param component_class Component class of which to get the type
+ * @returns One of #bt_component_type
+ */
+extern enum bt_component_type bt_component_class_get_type(
struct bt_component_class *component_class);
-enum bt_component_type bt_component_class_get_type(
+/**
+ * Get a component class' plug-in.
+ *
+ * @param component_class Component class of which to get the plug-in
+ * @returns The plug-in which registered the component class
+ */
+extern struct bt_plugin *bt_component_class_get_plugin(
struct bt_component_class *component_class);
#endif /* BABELTRACE_PLUGIN_COMPONENT_CLASS_H */
struct bt_component_factory {
struct bt_object base;
- /** Array of pointers to struct bt_plugin */
- GPtrArray *plugins;
/** Array of pointers to struct bt_component_class */
GPtrArray *component_classes;
+ /* Plug-in currently registering component classes. Weak ref. */
+ struct bt_plugin *current_plugin;
};
#endif /* BABELTRACE_PLUGIN_COMPONENT_FACTORY_INTERNAL_H */
extern struct bt_component_factory *bt_component_factory_create(void);
/**
- * Get the list of components registered to this factory.
+ * Get the number of component classes registered to the component factory.
*
- * @param factory Component factory
+ * @param factory A component factory instance
+ * @returns The number of component classes registered to the
+ * component factory, or a negative value on error.
*/
-extern struct bt_value *bt_component_factory_get_components(
+extern int bt_component_factory_get_component_class_count(
struct bt_component_factory *factory);
/**
- * .
+ * Get component class at index.
+ *
+ * @param factory A component factory instance
+ * @param index Index of the component class to return
+ * @returns A component class instance, NULL on error.
*/
-extern struct bt_value *bt_component_factory_create_component(
- struct bt_component_factory *factory);
+extern struct bt_component_class *bt_component_factory_get_component_class_index(
+ struct bt_component_factory *factory, int index);
+
+/**
+ * Look-up component class.
+ *
+ * @param factory A component factory instance
+ * @param plugin_name Name of the plug-in which registered the
+ * component class
+ * @param type Component type (@see #bt_component_type)
+ * @param component_name Component name
+ * @returns A component class instance, NULL on error.
+ */
+extern struct bt_component_class *bt_component_factory_get_component_class(
+ struct bt_component_factory *factory,
+ const char *plugin_name, enum bt_component_type type,
+ const char *component_name);
/**
* Recursively load and register Babeltrace plugins under a given path.
extern enum bt_component_factory_status
bt_component_factory_register_source_component_class(
struct bt_component_factory *factory, const char *name,
- bt_component_source_init_cb init);
+ bt_component_init_cb init);
extern enum bt_component_factory_status
bt_component_factory_register_sink_component_class(
struct bt_component_factory *factory, const char *name,
- bt_component_sink_init_cb init);
+ bt_component_init_cb init);
#ifdef __cplusplus
}
struct bt_component_class *class, const char *name,
bt_component_destroy_cb destroy);
+BT_HIDDEN
+enum bt_component_type bt_component_get_type(struct bt_component *component);
+
#endif /* BABELTRACE_PLUGIN_COMPONENT_INTERNAL_H */
struct bt_component;
+
+/**
+ * Create an instance of a component from a component class.
+ *
+ * @param component_class Component class of which to create an instance
+ * @param name Name of the new component instance, optional
+ * @returns Returns a pointer to a new component instance
+ */
+extern struct bt_component *bt_component_create(
+ struct bt_component_class *component_class, const char *name);
+
/**
* Get component's name.
*
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/ref-internal.h>
#include <babeltrace/plugin/component.h>
-#include <babeltrace/plugin/plugin.h>
+#include <babeltrace/plugin/plugin-system.h>
#include <babeltrace/object-internal.h>
#include <gmodule.h>
--- /dev/null
+#ifndef BABELTRACE_PLUGIN_H
+#define BABELTRACE_PLUGIN_H
+
+/*
+ * BabelTrace - Babeltrace Plug-in Helper Macros
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/plugin/component-factory.h>
+#include <babeltrace/plugin/component.h>
+
+/* A plugin must define the __bt_plugin_init symbol */
+#define BT_PLUGIN_NAME(_x) const char __bt_plugin_name[] = (_x)
+#define BT_PLUGIN_AUTHOR(_x) const char __bt_plugin_author[] = (_x)
+#define BT_PLUGIN_LICENSE(_x) const char __bt_plugin_license[] = (_x)
+#define BT_PLUGIN_INIT(_x) bt_plugin_init_func __bt_plugin_init = (_x)
+#define BT_PLUGIN_EXIT(_x) bt_plugin_exit_func __bt_plugin_exit = (_x)
+
+#define BT_PLUGIN_COMPONENT_CLASSES_BEGIN \
+ enum bt_component_status __bt_plugin_register_component_classes(\
+ struct bt_component_factory *factory)\
+ {
+
+#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_ENTRY(_name, _init) \
+ bt_component_factory_register_source_component_class(factory, \
+ _name, _init);
+
+#define BT_PLUGIN_SINK_COMPONENT_CLASS_ENTRY(_name, _init) \
+ bt_component_factory_register_sink_component_class(factory, \
+ _name, _init);
+
+#define BT_PLUGIN_COMPONENT_CLASSES_END\
+ \
+ return BT_COMPONENT_STATUS_OK;\
+}\
+ \
+ BT_PLUGIN_INIT(__bt_plugin_register_component_classes);\
+
+#endif /* BABELTRACE_PLUGIN_MACROS_H */
struct bt_notification;
struct bt_notification_iterator;
struct bt_component;
+struct bt_component_factory;
+
+typedef enum bt_component_status (*bt_plugin_init_func)(
+ struct bt_component_factory *factory);
+typedef void (*bt_plugin_exit_func)(void);
/**
* Component private data deallocation function type.
typedef void (*bt_component_destroy_cb)(struct bt_component *component);
/**
- * Source component initialization function type.
- *
- * A source component's iterator initialization callback, private data and
- * deinitialization callback must be set by this function.
- *
- * @param component Component instance
- * @returns One of #bt_component_status values
- */
-typedef enum bt_component_status (*bt_component_source_init_cb)(
- struct bt_component *component);
-
-/**
- * Sink component initialization function type.
+ * Component initialization function type.
*
- * A sink component's notification handling callback, private data and
- * deinitialization callback must be set by this function.
+ * A component's private data and required callbacks must be set by this
+ * function.
*
* @param component Component instance
* @returns One of #bt_component_status values
*/
-typedef enum bt_component_status (*bt_component_sink_init_cb)(
+typedef enum bt_component_status (*bt_component_init_cb)(
struct bt_component *component);
-/**
- * Iterator initialization function type.
- *
- * @param component Component instance
- * @param iterator Iterator instance
- */
-typedef enum bt_component_status (*bt_component_source_iterator_init_cb)(
- struct bt_component *component,
- struct bt_notification_iterator *iterator);
-
/**
* Get a component's private data.
*
/*
* BabelTrace - Babeltrace Plug-in Interface
*
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2015 Philippe Proulx <pproulx@efficios.com>
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SOFTWARE.
*/
-#include <babeltrace/plugin/component-factory.h>
-#include <babeltrace/plugin/component.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
-typedef enum bt_component_status (*bt_plugin_init_func)(
- struct bt_component_factory *factory);
-typedef void (*bt_plugin_exit_func)(void);
+struct bt_plugin;
-/* A plugin must define the __bt_plugin_init symbol */
-#define BT_PLUGIN_NAME(_x) const char __bt_plugin_name[] = (_x)
-#define BT_PLUGIN_AUTHOR(_x) const char __bt_plugin_author[] = (_x)
-#define BT_PLUGIN_LICENSE(_x) const char __bt_plugin_license[] = (_x)
-#define BT_PLUGIN_INIT(_x) bt_plugin_init_func __bt_plugin_init = (_x)
-#define BT_PLUGIN_EXIT(_x) bt_plugin_exit_func __bt_plugin_exit = (_x)
-
-#define BT_PLUGIN_COMPONENT_CLASSES_BEGIN \
- enum bt_component_status __bt_plugin_register_component_classes(\
- struct bt_component_factory *factory)\
- {
+/**
+ * Get the name of a plug-in.
+ *
+ * @param plugin An instance of a plug-in
+ * @returns Plug-in name or NULL on error
+ */
+extern const char *bt_plugin_get_name(struct bt_plugin *plugin);
-#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_ENTRY(_name, _init) \
- bt_component_factory_register_source_component_class(factory, \
- _name, _init);
+/**
+ * Get the name of a plug-in's author.
+ *
+ * @param plugin An instance of a plug-in
+ * @returns Plug-in author or NULL on error
+ */
+extern const char *bt_plugin_get_author(struct bt_plugin *plugin);
-#define BT_PLUGIN_SINK_COMPONENT_CLASS_ENTRY(_name, _init) \
- bt_component_factory_register_sink_component_class(factory, \
- _name, _init);
+/**
+ * Get the license of a plug-in.
+ *
+ * @param plugin An instance of a plug-in
+ * @returns Plug-in license or NULL on error
+ */
+extern const char *bt_plugin_get_license(struct bt_plugin *plugin);
-#define BT_PLUGIN_COMPONENT_CLASSES_END\
- \
- return BT_COMPONENT_STATUS_OK;\
-}\
- \
- BT_PLUGIN_INIT(__bt_plugin_register_component_classes);\
+#ifdef __cplusplus
+}
+#endif
#endif /* BABELTRACE_PLUGIN_H */
struct bt_component_sink_class {
struct bt_component_class parent;
- bt_component_sink_init_cb init;
};
struct bt_component_sink {
struct bt_component_source_class {
struct bt_component_class parent;
- bt_component_source_init_cb init;
};
struct bt_component_source {
goto end;
}
- bt_get(plugin);
- class->plugin = plugin;
+ class->plugin = bt_get(plugin);
end:
return class;
}
+
+const char *bt_component_class_get_name(
+ struct bt_component_class *component_class)
+{
+ return component_class ? component_class->name->str : NULL;
+}
+
+enum bt_component_type bt_component_class_get_type(
+ struct bt_component_class *component_class)
+{
+ return component_class ? component_class->type :
+ BT_COMPONENT_TYPE_UNKNOWN;
+}
+
+struct bt_plugin *bt_component_class_get_plugin(
+ struct bt_component_class *component_class)
+{
+ return component_class ? bt_get(component_class->plugin) :
+ NULL;
+}
#include <babeltrace/plugin/component-factory.h>
#include <babeltrace/plugin/component-factory-internal.h>
+#include <babeltrace/plugin/component-class-internal.h>
#include <babeltrace/plugin/source-internal.h>
#include <babeltrace/plugin/sink-internal.h>
#include <babeltrace/babeltrace-internal.h>
goto end;
}
+ factory->current_plugin = plugin;
component_status = bt_plugin_register_component_classes(plugin,
factory);
+ factory->current_plugin = NULL;
if (component_status != BT_COMPONENT_STATUS_OK) {
switch (component_status) {
case BT_COMPONENT_STATUS_NOMEM:
BT_PUT(plugin);
goto end;
}
- g_ptr_array_add(factory->plugins, plugin);
end:
return ret;
}
assert(obj);
factory = container_of(obj, struct bt_component_factory, base);
- if (factory->plugins) {
- g_ptr_array_free(factory->plugins, TRUE);
- }
if (factory->component_classes) {
g_ptr_array_free(factory->component_classes, TRUE);
}
}
bt_object_init(factory, bt_component_factory_destroy);
- factory->plugins = g_ptr_array_new_with_free_func(
- (GDestroyNotify) bt_put);
- if (!factory->plugins) {
- goto error;
- }
factory->component_classes = g_ptr_array_new_with_free_func(
(GDestroyNotify) bt_put);
if (!factory->component_classes) {
return factory;
}
-struct bt_value *bt_component_factory_get_components(
+int bt_component_factory_get_component_class_count(
struct bt_component_factory *factory)
{
- assert(0);
+ return factory ? factory->component_classes->len : -1;
+}
+
+struct bt_component_class *bt_component_factory_get_component_class_index(
+ struct bt_component_factory *factory, int index)
+{
+ struct bt_component_class *component_class = NULL;
+
+ if (!factory || index < 0 || index >= factory->component_classes->len) {
+ goto end;
+ }
+
+ component_class = bt_get(g_ptr_array_index(
+ factory->component_classes, index));
+end:
+ return component_class;
+}
+
+struct bt_component_class *bt_component_factory_get_component_class(
+ struct bt_component_factory *factory,
+ const char *plugin_name, enum bt_component_type type,
+ const char *component_name)
+{
+ size_t i;
+ struct bt_component_class *component_class = NULL;
+
+ if (!factory || (!plugin_name && !component_name &&
+ type == BT_COMPONENT_TYPE_UNKNOWN)) {
+ /* At least one criterion must be provided. */
+ goto no_match;
+ }
+
+ for (i = 0; i < factory->component_classes->len; i++) {
+ struct bt_plugin *plugin = NULL;
+
+ component_class = g_ptr_array_index(factory->component_classes,
+ i);
+ plugin = bt_component_class_get_plugin(component_class);
+ assert(plugin);
+
+ if (type != BT_COMPONENT_TYPE_UNKNOWN) {
+ if (type != bt_component_class_get_type(
+ component_class)) {
+ continue;
+ }
+ }
+
+ if (plugin_name) {
+ const char *cur_plugin_name = bt_plugin_get_name(
+ plugin);
+
+ assert(cur_plugin_name);
+ if (strcmp(plugin_name, cur_plugin_name)) {
+ continue;
+ }
+ }
+
+ if (component_name) {
+ const char *cur_cc_name = bt_component_class_get_name(
+ component_class);
+
+ assert(cur_cc_name);
+ if (strcmp(component_name, cur_cc_name)) {
+ continue;
+ }
+ }
+
+ /* All criteria met. */
+ goto match;
+ }
+
+no_match:
return NULL;
+match:
+ return bt_get(component_class);
}
enum bt_component_factory_status bt_component_factory_load(
return ret;
}
+static
enum bt_component_factory_status
-bt_component_factory_register_source_component_class(
- struct bt_component_factory *factory, const char *name,
- bt_component_source_init_cb init)
-{
- assert(0);
- return BT_COMPONENT_FACTORY_STATUS_ERROR;
-}
-
-enum bt_component_factory_status
-bt_component_factory_register_sink_component_class(
- struct bt_component_factory *factory, const char *name,
- bt_component_sink_init_cb init)
+add_component_class(struct bt_component_factory *factory, const char *name,
+ bt_component_init_cb init, enum bt_component_type type)
{
struct bt_component_class *class;
enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK;
goto end;
}
+ class = bt_component_class_create(type, name,
+ factory->current_plugin);
+ g_ptr_array_add(factory->component_classes, class);
end:
return ret;
}
+
+enum bt_component_factory_status
+bt_component_factory_register_source_component_class(
+ struct bt_component_factory *factory, const char *name,
+ bt_component_init_cb init)
+{
+ return add_component_class(factory, name, init,
+ BT_COMPONENT_TYPE_SOURCE);
+}
+
+enum bt_component_factory_status
+bt_component_factory_register_sink_component_class(
+ struct bt_component_factory *factory, const char *name,
+ bt_component_init_cb init)
+{
+ return add_component_class(factory, name, init,
+ BT_COMPONENT_TYPE_SINK);
+}
#include <babeltrace/plugin/component.h>
#include <babeltrace/plugin/component-internal.h>
+#include <babeltrace/plugin/source-internal.h>
+#include <babeltrace/plugin/sink-internal.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/compiler.h>
#include <babeltrace/ref.h>
{
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+ bt_object_init(component, bt_component_destroy);
if (!component || !class || !name || name[0] == '\0' || !destroy) {
ret = BT_COMPONENT_STATUS_INVAL;
goto end;
}
- bt_object_init(component, bt_component_destroy);
component->class = bt_get(class);
component->name = g_string_new(name);
if (!component->name) {
return ret;
}
+BT_HIDDEN
+enum bt_component_type bt_component_get_type(struct bt_component *component)
+{
+ return component ? component->class->type : BT_COMPONENT_TYPE_UNKNOWN;
+}
+
+struct bt_component *bt_component_create(
+ struct bt_component_class *component_class, const char *name)
+{
+ struct bt_component *component = NULL;
+
+ if (!component_class) {
+ goto end;
+ }
+
+ switch (bt_component_class_get_type(component_class))
+ {
+ case BT_COMPONENT_TYPE_SOURCE:
+ component = bt_component_source_create(component_class, name);
+ break;
+ case BT_COMPONENT_TYPE_SINK:
+ component = bt_component_sink_create(component_class, name);
+ break;
+ default:
+ goto end;
+ }
+end:
+ return component;
+}
+
const char *bt_component_get_name(struct bt_component *component)
{
const char *ret = NULL;
return ret;
}
-enum bt_component_type bt_component_get_type(struct bt_component *component)
+struct bt_component_class *bt_component_get_class(
+ struct bt_component *component)
{
- enum bt_component_type type = BT_COMPONENT_TYPE_UNKNOWN;
-
- if (!component) {
- goto end;
- }
-
- type = component->class->type;
-end:
- return type;
+ return component ? bt_get(component->class) : NULL;
}
enum bt_component_status bt_component_set_error_stream(
void *bt_component_get_private_data(struct bt_component *component)
{
- void *ret = NULL;
-
- if (!component) {
- goto end;
- }
-
- ret = component->user_data;
-end:
- return ret;
+ return component ? component->user_data : NULL;
}
enum bt_component_status
* SOFTWARE.
*/
-#include <babeltrace/plugin/plugin.h>
+#include <babeltrace/plugin/plugin-macros.h>
#include <babeltrace/plugin/component.h>
#include <babeltrace/plugin/sink.h>
#include <babeltrace/plugin/notification/notification.h>
assert(plugin && factory);
return plugin->init(factory);
}
+
+const char *bt_plugin_get_name(struct bt_plugin *plugin)
+{
+ return plugin ? plugin->name : NULL;
+}
+
+const char *bt_plugin_get_author(struct bt_plugin *plugin)
+{
+ return plugin ? plugin->author : NULL;
+}
+
+const char *bt_plugin_get_license(struct bt_plugin *plugin)
+{
+ return plugin ? plugin->license : NULL;
+}
ret = bt_component_init(&sink->parent, class, name,
bt_component_sink_destroy);
if (ret != BT_COMPONENT_STATUS_OK) {
- g_free(sink);
- sink = NULL;
+ BT_PUT(sink);
goto end;
}
end:
{
struct bt_component_source *source = NULL;
enum bt_component_status ret;
+
source = g_new0(struct bt_component_source, 1);
if (!source) {
goto end;
ret = bt_component_init(&source->parent, class, name,
bt_component_source_destroy);
if (ret != BT_COMPONENT_STATUS_OK) {
- g_free(source);
- source = NULL;
+ BT_PUT(source);
goto end;
}
end:
return source ? &source->parent : NULL;
}
-struct bt_notification_iterator *bt_plugin_source_create_iterator(
+struct bt_notification_iterator *bt_component_source_create_iterator(
struct bt_component *component)
{
enum bt_component_status ret_component;