X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=cli%2Fbabeltrace-cfg-cli-args.c;h=05193d3bdf2c46c60758c8fdab1d78630a906f38;hb=fdd3a2da18afef5ca32ba181a8b6ebbff173df02;hp=542e136fff53829cbb487b8163c7721d27fc67f8;hpb=c7b0cd7839312f04d15f58c0b633f25c8b03139f;p=babeltrace.git diff --git a/cli/babeltrace-cfg-cli-args.c b/cli/babeltrace-cfg-cli-args.c index 542e136f..05193d3b 100644 --- a/cli/babeltrace-cfg-cli-args.c +++ b/cli/babeltrace-cfg-cli-args.c @@ -185,6 +185,26 @@ void ini_append_error_expecting(struct ini_parsing_state *state, g_string_append_printf(state->ini_error, "^\n\n"); } +/* Parse the next token as an unsigned integer. */ +static +bt_value *ini_parse_uint(struct ini_parsing_state *state) +{ + bt_value *value = NULL; + GTokenType token_type = g_scanner_get_next_token(state->scanner); + + if (token_type != G_TOKEN_INT) { + ini_append_error_expecting(state, state->scanner, + "integer value"); + goto end; + } + + value = bt_value_unsigned_integer_create_init( + state->scanner->value.v_int64); + +end: + return value; +} + /* Parse the next token as a number and return its negation. */ static bt_value *ini_parse_neg_number(struct ini_parsing_state *state) @@ -203,7 +223,8 @@ bt_value *ini_parse_neg_number(struct ini_parsing_state *state) "Integer value -%" PRIu64 " is outside the range of a 64-bit signed integer\n", int_val); } else { - value = bt_value_integer_create_init(-((int64_t) int_val)); + value = bt_value_signed_integer_create_init( + -((int64_t) int_val)); } break; @@ -306,6 +327,9 @@ bt_value *ini_parse_value(struct ini_parsing_state *state) if (state->scanner->value.v_char == '-') { /* Negative number */ value = ini_parse_neg_number(state); + } else if (state->scanner->value.v_char == '+') { + /* Unsigned integer */ + value = ini_parse_uint(state); } else if (state->scanner->value.v_char == '[') { /* Array */ value = ini_parse_array(state); @@ -315,7 +339,7 @@ bt_value *ini_parse_value(struct ini_parsing_state *state) break; case G_TOKEN_INT: { - /* Positive integer */ + /* Positive, signed integer */ uint64_t int_val = state->scanner->value.v_int64; if (int_val > INT64_MAX) { @@ -323,7 +347,8 @@ bt_value *ini_parse_value(struct ini_parsing_state *state) "Integer value %" PRIu64 " is outside the range of a 64-bit signed integer\n", int_val); } else { - value = bt_value_integer_create_init((int64_t)int_val); + value = bt_value_signed_integer_create_init( + (int64_t) int_val); } break; } @@ -1836,7 +1861,7 @@ void print_expected_params_format(FILE *fp) fprintf(fp, "* `true`, `TRUE`, `yes`, `YES`: true boolean value (no backticks).\n"); fprintf(fp, "* `false`, `FALSE`, `no`, `NO`: false boolean value (no backticks).\n"); fprintf(fp, "* Binary (`0b` prefix), octal (`0` prefix), decimal, or hexadecimal\n"); - fprintf(fp, " (`0x` prefix) signed 64-bit integer.\n"); + fprintf(fp, " (`0x` prefix) unsigned (with `+` prefix) or signed 64-bit integer.\n"); fprintf(fp, "* Double precision floating point number (scientific notation is accepted).\n"); fprintf(fp, "* Unquoted string with no special characters, and not matching any of\n"); fprintf(fp, " the null and boolean value symbols above.\n"); @@ -1849,7 +1874,7 @@ void print_expected_params_format(FILE *fp) fprintf(fp, "Example:\n"); fprintf(fp, "\n"); fprintf(fp, " many=null, fresh=yes, condition=false, squirrel=-782329,\n"); - fprintf(fp, " observe=3.14, simple=beef, needs-quotes=\"some string\",\n"); + fprintf(fp, " play=+23, observe=3.14, simple=beef, needs-quotes=\"some string\",\n"); fprintf(fp, " escape.chars-are:allowed=\"this is a \\\" double quote\",\n"); fprintf(fp, " things=[1, \"2\", 3]\n"); fprintf(fp, "\n"); @@ -3131,17 +3156,6 @@ void finalize_implicit_component_args(struct implicit_component_args *args) bt_value_put_ref(args->extra_params); } -static -void destroy_implicit_component_args(void *args) -{ - if (!args) { - return; - } - - finalize_implicit_component_args(args); - g_free(args); -} - static int init_implicit_component_args(struct implicit_component_args *args, const char *comp_arg, bool exists) @@ -3208,7 +3222,97 @@ end: } static -int append_parameter_to_args(bt_value *args, const char *key, const char *value) +int bt_value_to_cli_param_value_append(const bt_value *value, GString *buf) +{ + BT_ASSERT(buf); + + int ret = -1; + + switch (bt_value_get_type(value)) { + case BT_VALUE_TYPE_STRING: + { + const char *str_value = bt_value_string_get(value); + gchar *escaped_str_value; + + escaped_str_value = escape_string_value(str_value); + if (!escaped_str_value) { + goto end; + } + + g_string_append_printf(buf, "\"%s\"", escaped_str_value); + + g_free(escaped_str_value); + break; + } + case BT_VALUE_TYPE_ARRAY: { + g_string_append_c(buf, '['); + uint64_t sz = bt_value_array_get_size(value); + for (uint64_t i = 0; i < sz; i++) { + const bt_value *item; + int ret; + + if (i > 0) { + g_string_append(buf, ", "); + } + + item = bt_value_array_borrow_element_by_index_const( + value, i); + ret = bt_value_to_cli_param_value_append(item, buf); + + if (ret) { + goto end; + } + } + g_string_append_c(buf, ']'); + break; + } + default: + abort(); + } + + ret = 0; + +end: + return ret; +} + +/* + * Convert `value` to its equivalent representation as a command line parameter + * value. + */ + +static +gchar *bt_value_to_cli_param_value(bt_value *value) +{ + GString *buf; + gchar *result = NULL; + + buf = g_string_new(NULL); + if (!buf) { + print_err_oom(); + goto error; + } + + if (bt_value_to_cli_param_value_append(value, buf)) { + goto error; + } + + result = g_string_free(buf, FALSE); + buf = NULL; + + goto end; + +error: + if (buf) { + g_string_free(buf, TRUE); + } + +end: + return result; +} + +static +int append_parameter_to_args(bt_value *args, const char *key, bt_value *value) { BT_ASSERT(args); BT_ASSERT(bt_value_get_type(args) == BT_VALUE_TYPE_ARRAY); @@ -3216,7 +3320,7 @@ int append_parameter_to_args(bt_value *args, const char *key, const char *value) BT_ASSERT(value); int ret = 0; - gchar *escaped_value; + gchar *str_value = NULL; GString *parameter = NULL; if (bt_value_array_append_string_element(args, "--params")) { @@ -3225,8 +3329,8 @@ int append_parameter_to_args(bt_value *args, const char *key, const char *value) goto end; } - escaped_value = escape_string_value(value); - if (!escaped_value) { + str_value = bt_value_to_cli_param_value(value); + if (!str_value) { ret = -1; goto end; } @@ -3238,7 +3342,7 @@ int append_parameter_to_args(bt_value *args, const char *key, const char *value) goto end; } - g_string_printf(parameter, "%s=\"%s\"", key, escaped_value); + g_string_printf(parameter, "%s=%s", key, str_value); if (bt_value_array_append_string_element(args, parameter->str)) { print_err_oom(); @@ -3247,16 +3351,37 @@ int append_parameter_to_args(bt_value *args, const char *key, const char *value) } end: - if (escaped_value) { - g_free(escaped_value); - escaped_value = NULL; - } - if (parameter) { g_string_free(parameter, TRUE); parameter = NULL; } + if (str_value) { + g_free(str_value); + str_value = NULL; + } + + return ret; +} + +static +int append_string_parameter_to_args(bt_value *args, const char *key, const char *value) +{ + bt_value *str_value; + int ret; + + str_value = bt_value_string_create_init(value); + + if (!str_value) { + print_err_oom(); + ret = -1; + goto end; + } + + ret = append_parameter_to_args(args, key, str_value); + +end: + BT_VALUE_PUT_REF_AND_RESET(str_value); return ret; } @@ -3264,7 +3389,7 @@ static int append_implicit_component_extra_param(struct implicit_component_args *args, const char *key, const char *value) { - return append_parameter_to_args(args->extra_params, key, value); + return append_string_parameter_to_args(args->extra_params, key, value); } static @@ -3580,85 +3705,6 @@ end: return ret; } -static -struct implicit_component_args *create_implicit_component_args(void) -{ - struct implicit_component_args *impl_args = - g_new0(struct implicit_component_args, 1); - - if (!impl_args) { - goto end; - } - - if (init_implicit_component_args(impl_args, NULL, true)) { - destroy_implicit_component_args(impl_args); - impl_args = NULL; - goto end; - } - -end: - return impl_args; -} - -static -int fill_implicit_ctf_inputs_args(GPtrArray *implicit_ctf_inputs_args, - struct implicit_component_args *base_implicit_ctf_input_args, - GList *leftovers) -{ - int ret = 0; - GList *leftover; - bt_value_status status; - - for (leftover = leftovers; leftover != NULL; - leftover = g_list_next(leftover)) { - GString *gs_leftover = leftover->data; - struct implicit_component_args *impl_args = - create_implicit_component_args(); - - if (!impl_args) { - print_err_oom(); - goto error; - } - - impl_args->exists = true; - g_string_assign(impl_args->comp_arg, - base_implicit_ctf_input_args->comp_arg->str); - g_string_assign(impl_args->params_arg, - base_implicit_ctf_input_args->params_arg->str); - - /* - * We need our own copy of the extra parameters because - * this is where the unique path goes. - */ - BT_VALUE_PUT_REF_AND_RESET(impl_args->extra_params); - status = bt_value_copy(base_implicit_ctf_input_args->extra_params, - &impl_args->extra_params); - if (status != BT_VALUE_STATUS_OK) { - print_err_oom(); - destroy_implicit_component_args(impl_args); - goto error; - } - - /* Append unique path parameter */ - ret = append_implicit_component_extra_param(impl_args, - "path", gs_leftover->str); - if (ret) { - destroy_implicit_component_args(impl_args); - goto error; - } - - g_ptr_array_add(implicit_ctf_inputs_args, impl_args); - } - - goto end; - -error: - ret = -1; - -end: - return ret; -} - /* * Creates a Babeltrace config object from the arguments of a convert * command. @@ -3693,9 +3739,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], GList *source_names = NULL; GList *filter_names = NULL; GList *sink_names = NULL; - GList *leftovers = NULL; - GPtrArray *implicit_ctf_inputs_args = NULL; - struct implicit_component_args base_implicit_ctf_input_args = { 0 }; + bt_value *leftovers = NULL; + struct implicit_component_args implicit_ctf_input_args = { 0 }; struct implicit_component_args implicit_ctf_output_args = { 0 }; struct implicit_component_args implicit_lttng_live_args = { 0 }; struct implicit_component_args implicit_dummy_args = { 0 }; @@ -3719,7 +3764,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto end; } - if (init_implicit_component_args(&base_implicit_ctf_input_args, + if (init_implicit_component_args(&implicit_ctf_input_args, "source.ctf.fs", false)) { goto error; } @@ -3759,13 +3804,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - implicit_ctf_inputs_args = g_ptr_array_new_with_free_func( - (GDestroyNotify) destroy_implicit_component_args); - if (!implicit_ctf_inputs_args) { - print_err_oom(); - goto error; - } - all_names = bt_value_map_create(); if (!all_names) { print_err_oom(); @@ -3795,6 +3833,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } + leftovers = bt_value_array_create(); + if (!leftovers) { + print_err_oom(); + goto error; + } + /* * First pass: collect all arguments which need to be passed * as is to the run command. This pass can also add --name @@ -3916,7 +3960,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (append_parameter_to_args(run_args, "path", arg)) { + if (append_string_parameter_to_args(run_args, "path", arg)) { goto error; } break; @@ -3928,7 +3972,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } - if (append_parameter_to_args(run_args, "url", arg)) { + if (append_string_parameter_to_args(run_args, "url", arg)) { goto error; } break; @@ -4161,15 +4205,15 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], implicit_text_args.exists = true; break; case OPT_CLOCK_OFFSET: - base_implicit_ctf_input_args.exists = true; + implicit_ctf_input_args.exists = true; append_implicit_component_param( - &base_implicit_ctf_input_args, + &implicit_ctf_input_args, "clock-class-offset-s", arg); break; case OPT_CLOCK_OFFSET_NS: - base_implicit_ctf_input_args.exists = true; + implicit_ctf_input_args.exists = true; append_implicit_component_param( - &base_implicit_ctf_input_args, + &implicit_ctf_input_args, "clock-class-offset-ns", arg); break; case OPT_CLOCK_SECONDS: @@ -4260,7 +4304,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], got_input_format_opt = true; if (strcmp(arg, "ctf") == 0) { - base_implicit_ctf_input_args.exists = true; + implicit_ctf_input_args.exists = true; } else if (strcmp(arg, "lttng-live") == 0) { implicit_lttng_live_args.exists = true; } else { @@ -4369,16 +4413,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], /* Consume and keep leftover arguments */ while ((leftover = poptGetArg(pc))) { - GString *gs_leftover = g_string_new(leftover); - - if (!gs_leftover) { - print_err_oom(); - goto error; - } - - leftovers = g_list_append(leftovers, gs_leftover); - if (!leftovers) { - g_string_free(gs_leftover, TRUE); + bt_value_status status = bt_value_array_append_string_element(leftovers, leftover); + if (status != BT_VALUE_STATUS_OK) { print_err_oom(); goto error; } @@ -4386,14 +4422,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], /* Print CTF metadata or print LTTng live sessions */ if (print_ctf_metadata) { - GString *gs_leftover; + const bt_value *bt_val_leftover; - if (g_list_length(leftovers) == 0) { + if (bt_value_array_is_empty(leftovers)) { printf_err("--output-format=ctf-metadata specified without a path\n"); goto error; } - if (g_list_length(leftovers) > 1) { + if (bt_value_array_get_size(leftovers) > 1) { printf_err("Too many paths specified for --output-format=ctf-metadata\n"); goto error; } @@ -4403,9 +4439,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - gs_leftover = leftovers->data; + bt_val_leftover = bt_value_array_borrow_element_by_index_const(leftovers, 0); g_string_assign(cfg->cmd_data.print_ctf_metadata.path, - gs_leftover->str); + bt_value_string_get(bt_val_leftover)); if (output) { g_string_assign( @@ -4471,18 +4507,18 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } /* Decide where the leftover argument(s) go */ - if (g_list_length(leftovers) > 0) { + if (bt_value_array_get_size(leftovers) > 0) { if (implicit_lttng_live_args.exists) { - GString *gs_leftover; + const bt_value *bt_val_leftover; - if (g_list_length(leftovers) > 1) { + if (bt_value_array_get_size(leftovers) > 1) { printf_err("Too many URLs specified for --output-format=lttng-live\n"); goto error; } - gs_leftover = leftovers->data; + bt_val_leftover = bt_value_array_borrow_element_by_index_const(leftovers, 0); lttng_live_url_parts = - bt_common_parse_lttng_live_url(gs_leftover->str, + bt_common_parse_lttng_live_url(bt_value_string_get(bt_val_leftover), error_buf, sizeof(error_buf)); if (!lttng_live_url_parts.proto) { printf_err("Invalid LTTng live URL format: %s\n", @@ -4499,7 +4535,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url, - gs_leftover->str); + bt_value_string_get(bt_val_leftover)); if (output) { g_string_assign( @@ -4512,20 +4548,26 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], ret = append_implicit_component_extra_param( &implicit_lttng_live_args, "url", - gs_leftover->str); + bt_value_string_get(bt_val_leftover)); + if (ret) { + goto error; + } + + ret = append_implicit_component_extra_param( + &implicit_lttng_live_args, + "session-not-found-action", "end"); if (ret) { goto error; } } else { /* - * Append one implicit component argument set - * for each leftover (souce.ctf.fs paths). Copy - * the base implicit component arguments. - * Note that they still have to be named later. + * Create one source.ctf.fs component, pass it an array + * with the leftovers. + * Note that it still has to be named later. */ - ret = fill_implicit_ctf_inputs_args( - implicit_ctf_inputs_args, - &base_implicit_ctf_input_args, leftovers); + implicit_ctf_input_args.exists = true; + ret = append_parameter_to_args(implicit_ctf_input_args.extra_params, + "paths", leftovers); if (ret) { goto error; } @@ -4536,10 +4578,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * Ensure mutual exclusion between implicit `source.ctf.fs` and * `source.ctf.lttng-live` components. */ - if (base_implicit_ctf_input_args.exists && - implicit_lttng_live_args.exists) { + if (implicit_ctf_input_args.exists && implicit_lttng_live_args.exists) { printf_err("Cannot create both implicit `%s` and `%s` components\n", - base_implicit_ctf_input_args.comp_arg->str, + implicit_ctf_input_args.comp_arg->str, implicit_lttng_live_args.comp_arg->str); goto error; } @@ -4549,29 +4590,23 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * components exists, make sure there's at least one leftover * (which is the path or URL). */ - if (base_implicit_ctf_input_args.exists && - g_list_length(leftovers) == 0) { + if (implicit_ctf_input_args.exists && bt_value_array_is_empty(leftovers)) { printf_err("Missing path for implicit `%s` component\n", - base_implicit_ctf_input_args.comp_arg->str); + implicit_ctf_input_args.comp_arg->str); goto error; } - if (implicit_lttng_live_args.exists && g_list_length(leftovers) == 0) { + if (implicit_lttng_live_args.exists && bt_value_array_is_empty(leftovers)) { printf_err("Missing URL for implicit `%s` component\n", implicit_lttng_live_args.comp_arg->str); goto error; } /* Assign names to implicit components */ - for (i = 0; i < implicit_ctf_inputs_args->len; i++) { - struct implicit_component_args *impl_args = - g_ptr_array_index(implicit_ctf_inputs_args, i); - - ret = assign_name_to_implicit_component(impl_args, - "source-ctf-fs", all_names, &source_names, true); - if (ret) { - goto error; - } + ret = assign_name_to_implicit_component(&implicit_ctf_input_args, + "source-ctf-fs", all_names, &source_names, true); + if (ret) { + goto error; } ret = assign_name_to_implicit_component(&implicit_lttng_live_args, @@ -4657,15 +4692,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * Append the equivalent run arguments for the implicit * components. */ - for (i = 0; i < implicit_ctf_inputs_args->len; i++) { - struct implicit_component_args *impl_args = - g_ptr_array_index(implicit_ctf_inputs_args, i); - - ret = append_run_args_for_implicit_component(impl_args, - run_args); - if (ret) { - goto error; - } + ret = append_run_args_for_implicit_component(&implicit_ctf_input_args, run_args); + if (ret) { + goto error; } ret = append_run_args_for_implicit_component(&implicit_lttng_live_args, @@ -4802,17 +4831,13 @@ end: g_string_free(cur_name_prefix, TRUE); } - if (implicit_ctf_inputs_args) { - g_ptr_array_free(implicit_ctf_inputs_args, TRUE); - } - bt_value_put_ref(run_args); bt_value_put_ref(all_names); destroy_glist_of_gstring(source_names); destroy_glist_of_gstring(filter_names); destroy_glist_of_gstring(sink_names); - destroy_glist_of_gstring(leftovers); - finalize_implicit_component_args(&base_implicit_ctf_input_args); + bt_value_put_ref(leftovers); + finalize_implicit_component_args(&implicit_ctf_input_args); finalize_implicit_component_args(&implicit_ctf_output_args); finalize_implicit_component_args(&implicit_lttng_live_args); finalize_implicit_component_args(&implicit_dummy_args);