enum parse_next_item_status status;
status = parse_next_item(argpar_iter, &argpar_item,
- argc_offset, *argv, false, NULL);
- if (status == PARSE_NEXT_ITEM_STATUS_ERROR) {
+ argc_offset, *argv, false, NULL, NULL);
+ if (status == PARSE_NEXT_ITEM_STATUS_ERROR ||
+ status == PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY) {
goto error;
} else if (status == PARSE_NEXT_ITEM_STATUS_END) {
break;
{ "event-rule-matches", handle_condition_event },
};
+static
+void print_valid_condition_names(void)
+{
+ unsigned int i;
+
+ ERR("Valid condition names are:");
+
+ for (i = 0; i < ARRAY_SIZE(condition_descrs); ++i) {
+ ERR(" %s", condition_descrs[i].name);
+ }
+}
+
static
struct lttng_condition *parse_condition(const char *condition_name, int *argc,
const char ***argv, int argc_offset, int orig_arg_index,
if (!descr) {
ERR(WHILE_PARSING_ARG_N_ARG_FMT "Unknown condition name '%s'",
orig_arg_index + 1, orig_arg, condition_name);
+ print_valid_condition_names();
goto error;
}
enum parse_next_item_status status;
status = parse_next_item(argpar_iter, &argpar_item,
- argc_offset, *argv, false,
+ argc_offset, *argv, false, NULL,
"While parsing `notify` action:");
- if (status == PARSE_NEXT_ITEM_STATUS_ERROR) {
+ if (status == PARSE_NEXT_ITEM_STATUS_ERROR ||
+ status == PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY) {
goto error;
} else if (status == PARSE_NEXT_ITEM_STATUS_END) {
break;
enum parse_next_item_status status;
status = parse_next_item(argpar_iter, &argpar_item, argc_offset,
- *argv, false,
+ *argv, false, NULL,
"While parsing `%s` action:", action_name);
- if (status == PARSE_NEXT_ITEM_STATUS_ERROR) {
+ if (status == PARSE_NEXT_ITEM_STATUS_ERROR ||
+ status == PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY) {
goto error;
} else if (status == PARSE_NEXT_ITEM_STATUS_END) {
break;
enum parse_next_item_status status;
status = parse_next_item(argpar_iter, &argpar_item, argc_offset,
- *argv, false, "While parsing `snapshot` action:");
- if (status == PARSE_NEXT_ITEM_STATUS_ERROR) {
+ *argv, false, NULL, "While parsing `snapshot` action:");
+ if (status == PARSE_NEXT_ITEM_STATUS_ERROR ||
+ status == PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY) {
goto error;
} else if (status == PARSE_NEXT_ITEM_STATUS_END) {
break;
{ "snapshot-session", handle_action_snapshot_session },
};
+static
+void print_valid_action_names(void)
+{
+ unsigned int i;
+
+ ERR("Valid action names are:");
+
+ for (i = 0; i < ARRAY_SIZE(condition_descrs); ++i) {
+ ERR(" %s", action_descrs[i].name);
+ }
+}
+
static
struct lttng_action *parse_action(const char *action_name, int *argc,
const char ***argv, int argc_offset, int orig_arg_index,
}
if (!descr) {
- ERR(WHILE_PARSING_ARG_N_ARG_FMT "Unknown action name: %s",
+ ERR(WHILE_PARSING_ARG_N_ARG_FMT "Unknown action name '%s'",
orig_arg_index + 1, orig_arg, action_name);
+ print_valid_action_names();
goto error;
}
struct lttng_dynamic_pointer_array actions;
struct argpar_iter *argpar_iter = NULL;
const struct argpar_item *argpar_item = NULL;
+ const struct argpar_error *argpar_error = NULL;
struct lttng_action *action_list = NULL;
struct lttng_action *action = NULL;
struct lttng_trigger *trigger = NULL;
}
status = parse_next_item(argpar_iter, &argpar_item,
- argc - my_argc, my_argv, true, NULL);
+ argc - my_argc, my_argv, true, &argpar_error, NULL);
if (status == PARSE_NEXT_ITEM_STATUS_ERROR) {
+
+ if (argpar_error_type(argpar_error) ==
+ ARGPAR_ERROR_TYPE_MISSING_OPT_ARG) {
+ int opt_id = argpar_error_opt_descr(argpar_error, NULL)->id;
+
+ if (opt_id == OPT_CONDITION) {
+ print_valid_condition_names();
+ } else if (opt_id == OPT_ACTION) {
+ print_valid_action_names();
+ }
+ }
+
+ goto error;
+ } else if (status == PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY) {
goto error;
} else if (status == PARSE_NEXT_ITEM_STATUS_END) {
break;
}
cleanup:
+ argpar_error_destroy(argpar_error);
argpar_iter_destroy(argpar_iter);
argpar_item_destroy(argpar_item);
lttng_dynamic_pointer_array_reset(&actions);
PARSE_NEXT_ITEM_STATUS_OK = 0,
PARSE_NEXT_ITEM_STATUS_END = 1,
PARSE_NEXT_ITEM_STATUS_ERROR = -1,
+ PARSE_NEXT_ITEM_STATUS_ERROR_MEMORY = -2,
};
/*
*
* If `unknown_opt_is_error` is true, an unknown option is considered an error.
* Otherwise, it is considered as the end of the argument list.
+ *
+ * If `error_out` is given and PARSE_NEXT_ITEM_STATUS_ERROR is returned, set
+ * `*error_out` to the argpar_error object corresponding to the error. The
+ * caller must free the object with `argpar_error_destroy`.
*/
-ATTR_FORMAT_PRINTF(6, 7)
+ATTR_FORMAT_PRINTF(7, 8)
enum parse_next_item_status parse_next_item(struct argpar_iter *iter,
const struct argpar_item **item, int argc_offset,
const char **argv, bool unknown_opt_is_error,
+ const struct argpar_error **error_out,
const char *context_fmt, ...);
#ifdef __cplusplus
# shellcheck source=../../../utils/utils.sh
source "$TESTDIR/utils/utils.sh"
-plan_tests 289
+plan_tests 295
FULL_LTTNG_BIN="${TESTDIR}/../src/bin/lttng/${LTTNG_BIN}"
# `--condition` failures
test_failure "missing args after --condition" \
- "Error: While parsing argument #2 (\`--condition\`): Missing required argument for option \`--condition\`" \
+ "Error: While parsing argument #2 (\`--condition\`): Missing required argument for option \`--condition\`
+Error: Valid condition names are:
+Error: event-rule-matches" \
--condition
test_failure "unknown --condition" \
- "Error: While parsing argument #2 (\`--condition\`): Unknown condition name 'zoofest'" \
+ "Error: While parsing argument #2 (\`--condition\`): Unknown condition name 'zoofest'
+Error: Valid condition names are:
+Error: event-rule-matches" \
--condition zoofest
test_failure "unknown --condition=" \
- "Error: While parsing argument #2 (\`--condition=zoofest\`): Unknown condition name 'zoofest'" \
+ "Error: While parsing argument #2 (\`--condition=zoofest\`): Unknown condition name 'zoofest'
+Error: Valid condition names are:
+Error: event-rule-matches" \
--condition=zoofest
# `--condition event-rule-matches` failures
# `--action` failures
test_failure "missing args after --action" \
- "Error: While parsing argument #5 (\`--action\`): Missing required argument for option \`--action\`" \
+ "Error: While parsing argument #5 (\`--action\`): Missing required argument for option \`--action\`
+Error: Valid action names are:
+Error: notify" \
--condition event-rule-matches --type=user \
--action
+test_failure "unknown --action" \
+ "Error: While parsing argument #5 (\`--action\`): Unknown action name 'zoofest'
+Error: Valid action names are:
+Error: notify" \
+ --condition event-rule-matches --type=user \
+ --action zoofest
+
+test_failure "unknown --action=" \
+ "Error: While parsing argument #5 (\`--action=zoofest\`): Unknown action name 'zoofest'
+Error: Valid action names are:
+Error: notify" \
+ --condition event-rule-matches --type=user \
+ --action=zoofest
+
# `--action notify` failures
test_failure "extra arg after --action notify" \
"Error: Unexpected argument \`bob\`." \