script_debug(interp, c->name, argc, argv);
- words = malloc(sizeof(char *) * (argc + 1));
- words[0] = c->name;
+ words = malloc(argc * sizeof(char *));
for (i = 0; i < argc; i++)
{
int len;
/* hit an end of line comment */
break;
}
- words[i + 1] = strdup(w);
- if (words[i + 1] == NULL)
+ words[i] = strdup(w);
+ if (words[i] == NULL)
{
int j;
for (j = 0; j < i; j++)
- free(words[j + 1]);
+ free(words[j]);
free(words);
return JIM_ERR;
}
log_add_callback(tcl_output, tclOutput);
// turn words[0] into CMD_ARGV[-1] with this cast
- retval = run_command(context, c, (const char **)words + 1, nwords);
+ retval = run_command(context, c, (const char **)words, nwords);
log_remove_callback(tcl_output, tclOutput);
Jim_DecrRefCount(interp, tclOutput);
for (i = 0; i < nwords; i++)
- free(words[i + 1]);
+ free(words[i]);
free(words);
int *return_retval = Jim_GetAssocData(interp, "retval");
static int run_command(struct command_context *context,
struct command *c, const char *words[], unsigned num_words)
{
- int start_word = 0;
if (!((context->mode == COMMAND_CONFIG) || (c->mode == COMMAND_ANY) || (c->mode == context->mode)))
{
/* Config commands can not run after the config stage */
return ERROR_FAIL;
}
- unsigned argc = num_words - start_word - 1;
- const char **args = words + start_word + 1;
- int retval = c->handler(context, args, argc);
+ struct command_invocation cmd = {
+ .ctx = context,
+ .name = c->name,
+ .argc = num_words - 1,
+ .argv = words + 1,
+ };
+ int retval = c->handler(&cmd);
if (retval == ERROR_COMMAND_SYNTAX_ERROR)
{
/* Print help for command */
}
-struct command_context* command_init()
+struct command_context* command_init(const char *startup_tcl)
{
struct command_context* context = malloc(sizeof(struct command_context));
- extern const char startup_tcl[];
const char *HostOs;
context->mode = COMMAND_EXEC;
DEFINE_PARSE_LONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)
DEFINE_PARSE_LONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)
DEFINE_PARSE_LONG(_s8, int8_t, n < INT8_MIN, INT8_MAX)
+
+static int command_parse_bool(const char *in, bool *out,
+ const char *on, const char *off)
+{
+ if (strcasecmp(in, on) == 0)
+ *out = true;
+ else if (strcasecmp(in, off) == 0)
+ *out = false;
+ else
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ return ERROR_OK;
+}
+
+int command_parse_bool_arg(const char *in, bool *out)
+{
+ if (command_parse_bool(in, out, "on", "off") == ERROR_OK)
+ return ERROR_OK;
+ if (command_parse_bool(in, out, "enable", "disable") == ERROR_OK)
+ return ERROR_OK;
+ if (command_parse_bool(in, out, "true", "false") == ERROR_OK)
+ return ERROR_OK;
+ if (command_parse_bool(in, out, "yes", "no") == ERROR_OK)
+ return ERROR_OK;
+ if (command_parse_bool(in, out, "1", "0") == ERROR_OK)
+ return ERROR_OK;
+ return ERROR_INVALID_ARGUMENTS;
+}
+
+COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)
+{
+ switch (CMD_ARGC) {
+ case 1: {
+ const char *in = CMD_ARGV[0];
+ if (command_parse_bool_arg(in, out) != ERROR_OK)
+ {
+ LOG_ERROR("%s: argument '%s' is not valid", CMD_NAME, in);
+ return ERROR_INVALID_ARGUMENTS;
+ }
+ // fall through
+ }
+ case 0:
+ LOG_INFO("%s is %s", label, *out ? "enabled" : "disabled");
+ break;
+ default:
+ return ERROR_INVALID_ARGUMENTS;
+ }
+ return ERROR_OK;
+}
+
+