babeltrace(1): escape '.' in PLUGIN.COMPCLS arguments
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 22 Feb 2017 18:08:12 +0000 (13:08 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:38 +0000 (12:57 -0400)
Now you can have dots in your plugin or component class names:

    babeltrace --source 'hello\.world.my\.component\.class'

Also, escape `\` with `\\`.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
converter/babeltrace-cfg.c
converter/babeltrace.c

index e005df2c528c28b9b1b84a887bf3d27a06f92464..4053357164429d1dc28eab1bf9319dc39dfce145 100644 (file)
@@ -642,42 +642,74 @@ static
 void plugin_component_names_from_arg(const char *arg, char **plugin,
                char **component)
 {
-       const char *dot;
-       const char *end;
-       size_t plugin_len;
-       size_t component_len;
+       const char *arg_ch = arg;
+       char *ch;
+       bool in_component = false;
 
-       /* Initialize both return values to NULL: not found */
-       *plugin = NULL;
-       *component = NULL;
-
-       dot = strchr(arg, '.');
-       if (!dot) {
-               /* No dot */
-               goto end;
-       }
-
-       end = arg + strlen(arg);
-       plugin_len = dot - arg;
-       component_len = end - dot - 1;
-       if (plugin_len == 0 || component_len == 0) {
-               goto end;
-       }
-
-       *plugin = g_malloc0(plugin_len + 1);
+       /* Initialize both return values */
+       *plugin = g_malloc0(strlen(arg) + 1);
+       ch = *plugin;
        if (!*plugin) {
                print_err_oom();
-               goto end;
+               goto error;
        }
 
-       g_strlcpy(*plugin, arg, plugin_len + 1);
-       *component = g_malloc0(component_len + 1);
+       *component = g_malloc0(strlen(arg) + 1);
        if (!*component) {
                print_err_oom();
-               goto end;
+               goto error;
        }
 
-       g_strlcpy(*component, dot + 1, component_len + 1);
+       while (*arg_ch != '\0') {
+               switch (*arg_ch) {
+               case '\\':
+                       if (arg_ch[1] == '\0') {
+                               /* `\` at the end of the string */
+                               *ch = *arg_ch;
+                               ch++;
+                               arg_ch++;
+                       } else if (arg_ch[1] == '\\' || arg_ch[1] == '.') {
+                               /* Escaped `\` or `.` */
+                               *ch = arg_ch[1];
+                               ch++;
+                               arg_ch += 2;
+                       } else {
+                               /* Unknown escaped character (write `\` too) */
+                               ch[0] = arg_ch[0];
+                               ch[1] = arg_ch[1];
+                               ch += 2;
+                               arg_ch += 2;
+
+                       }
+                       continue;
+               case '.':
+                       if (in_component) {
+                               goto error;
+                       }
+
+                       in_component = true;
+                       ch = *component;
+                       arg_ch++;
+                       break;
+               default:
+                       *ch = *arg_ch;
+                       ch++;
+                       arg_ch++;
+                       break;
+               }
+       }
+
+       if (strlen(*plugin) == 0 || strlen(*component) == 0) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       g_free(*plugin);
+       *plugin = NULL;
+       g_free(*component);
+       *component = NULL;
 
 end:
        return;
index aa985a34d7175c2c705c566f96b261dab15aa3f8..1abda5c31550fffde5f91a335d13dfc9222325a5 100644 (file)
@@ -112,6 +112,94 @@ void print_indent(size_t indent)
        }
 }
 
+static char *escape_name_for_shell(const char *input)
+{
+       char *output = g_malloc0(strlen(input) * 5 + 1);
+       const char *in;
+       char *out = output;
+
+       if (!output) {
+               goto end;
+       }
+
+       for (in = input; *in != '\0'; in++) {
+               switch (*in) {
+               case '\\':
+                       *out++ = '\\';
+                       *out++ = '\\';
+                       break;
+               case '\'':
+                       *out++ = '\'';
+                       *out++ = '"';
+                       *out++ = '\'';
+                       *out++ = '"';
+                       *out++ = '\'';
+                       break;
+               case '.':
+                       *out++ = '\\';
+                       *out++ = '.';
+                       break;
+               default:
+                       *out++ = *in;
+                       break;
+               }
+       }
+
+end:
+       return output;
+}
+
+static
+const char *component_type_str(enum bt_component_class_type type)
+{
+       switch (type) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+               return "source";
+       case BT_COMPONENT_CLASS_TYPE_SINK:
+               return "sink";
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+               return "filter";
+       case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
+       default:
+               return "unknown";
+       }
+}
+
+static void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name,
+               const char *comp_cls_name, enum bt_component_class_type type)
+{
+       char *shell_plugin_name = NULL;
+       char *shell_comp_cls_name = NULL;
+
+       shell_plugin_name = escape_name_for_shell(plugin_name);
+       if (!shell_plugin_name) {
+               goto end;
+       }
+
+       shell_comp_cls_name = escape_name_for_shell(comp_cls_name);
+       if (!shell_comp_cls_name) {
+               goto end;
+       }
+
+       fprintf(fh, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'",
+               bt_common_color_bold(),
+               bt_common_color_fg_cyan(),
+               component_type_str(type),
+               bt_common_color_reset(),
+               bt_common_color_fg_default(),
+               bt_common_color_bold(),
+               bt_common_color_fg_blue(),
+               shell_plugin_name,
+               bt_common_color_fg_default(),
+               bt_common_color_fg_yellow(),
+               shell_comp_cls_name,
+               bt_common_color_reset());
+
+end:
+       g_free(shell_plugin_name);
+       g_free(shell_comp_cls_name);
+}
+
 static
 void print_value(struct bt_value *, size_t);
 
@@ -256,8 +344,11 @@ void print_value(struct bt_value *value, size_t indent)
 static
 void print_bt_config_component(struct bt_config_component *bt_config_component)
 {
-       printf("    %s.%s:\n", bt_config_component->plugin_name->str,
-               bt_config_component->component_name->str);
+       printf("    ");
+       print_plugin_comp_cls_opt(stdout, bt_config_component->plugin_name->str,
+               bt_config_component->component_name->str,
+               bt_config_component->type);
+       printf(":\n");
 
        if (bt_config_component->instance_name->len > 0) {
                printf("      Name: %s\n",
@@ -600,22 +691,6 @@ end:
        return ret;
 }
 
-static
-const char *component_type_str(enum bt_component_class_type type)
-{
-       switch (type) {
-       case BT_COMPONENT_CLASS_TYPE_SOURCE:
-               return "source";
-       case BT_COMPONENT_CLASS_TYPE_SINK:
-               return "sink";
-       case BT_COMPONENT_CLASS_TYPE_FILTER:
-               return "filter";
-       case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
-       default:
-               return "unknown";
-       }
-}
-
 static int load_all_plugins(struct bt_value *plugin_paths)
 {
        int ret = 0;
@@ -682,22 +757,6 @@ static void print_plugin_info(struct bt_plugin *plugin)
                license ? license : "(Unknown)");
 }
 
-static void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name,
-               const char *comp_cls_name, enum bt_component_class_type type)
-{
-       fprintf(fh, "%s%s--%s%s %s%s%s.%s%s%s",
-               bt_common_color_bold(),
-               bt_common_color_fg_cyan(),
-               component_type_str(type),
-               bt_common_color_fg_default(),
-               bt_common_color_fg_blue(),
-               plugin_name,
-               bt_common_color_fg_default(),
-               bt_common_color_fg_yellow(),
-               comp_cls_name,
-               bt_common_color_reset());
-}
-
 static int cmd_query(struct bt_config *cfg)
 {
        int ret;
@@ -1058,9 +1117,10 @@ static int cmd_convert(struct bt_config *cfg)
                        source_cfg->component_name->str,
                        BT_COMPONENT_CLASS_TYPE_SOURCE);
        if (!source_class) {
-               fprintf(stderr, "Could not find %s.%s source component class. Aborting...\n",
-                               source_cfg->plugin_name->str,
-                               source_cfg->component_name->str);
+               fprintf(stderr, "Could not find ");
+               print_plugin_comp_cls_opt(stderr, source_cfg->plugin_name->str,
+                       source_cfg->component_name->str, BT_COMPONENT_CLASS_TYPE_SOURCE);
+               fprintf(stderr, ". Aborting...\n");
                ret = -1;
                goto end;
        }
@@ -1071,9 +1131,10 @@ static int cmd_convert(struct bt_config *cfg)
                        sink_cfg->component_name->str,
                        BT_COMPONENT_CLASS_TYPE_SINK);
        if (!sink_class) {
-               fprintf(stderr, "Could not find %s.%s output component class. Aborting...\n",
-                               sink_cfg->plugin_name->str,
-                               sink_cfg->component_name->str);
+               fprintf(stderr, "Could not find ");
+               print_plugin_comp_cls_opt(stderr, sink_cfg->plugin_name->str,
+                       sink_cfg->component_name->str, BT_COMPONENT_CLASS_TYPE_SINK);
+               fprintf(stderr, ". Aborting...\n");
                ret = -1;
                goto end;
        }
This page took 0.030003 seconds and 4 git commands to generate.