From 5a389db1c1b88f8dbab7324606c6f8335865ba41 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Feb 2012 22:21:09 +0100 Subject: [PATCH] uart_cmd: introduce argument array parsing --- firmware/include/uart_cmd.h | 3 ++- firmware/sdr-test-project/main.c | 22 +++++++++++++--------- firmware/src/uart_cmd.c | 23 ++++++++++++++++------- firmware/tests/cmd-test.c | 14 +++++++------- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/firmware/include/uart_cmd.h b/firmware/include/uart_cmd.h index 4ede795..829cc0c 100644 --- a/firmware/include/uart_cmd.h +++ b/firmware/include/uart_cmd.h @@ -53,7 +53,8 @@ int uart_cmd_reset(struct cmd_state *cs); struct cmd { const char *cmd; uint32_t ops; - int (*cb)(struct cmd_state *cs, enum cmd_op op, const char *cmd, const char *arg); + int (*cb)(struct cmd_state *cs, enum cmd_op op, const char *cmd, + int argc, char **argv); const char *help; /* put list at the end for simpler initialization */ struct llist_head list; diff --git a/firmware/sdr-test-project/main.c b/firmware/sdr-test-project/main.c index 7f4104f..425f453 100644 --- a/firmware/sdr-test-project/main.c +++ b/firmware/sdr-test-project/main.c @@ -201,20 +201,22 @@ static int freq = 800; static struct cmd_state cmd_state; static int cmd_tuner_init(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *argv) + const char *cmd, int argc, char **argv) { e4k_init(&e4k); return 0; } static int cmd_rf_freq(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *arg) + const char *cmd, int argc, char **argv) { uint32_t freq; switch (op) { case CMD_OP_SET: - freq = strtoul(arg, NULL, 10); + if (argc < 1) + return -EINVAL; + freq = strtoul(argv[0], NULL, 10); e4k_tune_freq(&e4k, freq); break; case CMD_OP_GET: @@ -229,13 +231,15 @@ static int cmd_rf_freq(struct cmd_state *cs, enum cmd_op op, } static int cmd_si570_freq(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *arg) + const char *cmd, int argc, char **argv) { uint32_t freq; switch (op) { case CMD_OP_SET: - freq = strtoul(arg, NULL, 10); + if (argc < 1) + return -EINVAL; + freq = strtoul(argv[0], NULL, 10); set_si570_freq(freq); break; default: @@ -245,14 +249,14 @@ static int cmd_si570_freq(struct cmd_state *cs, enum cmd_op op, } static int cmd_si570_dump(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *arg) + const char *cmd, int argc, char **argv) { si570_regdump(&si570); return 0; } static int cmd_fpga_dump(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *arg) + const char *cmd, int argc, char **argv) { uart_cmd_out(cs, "FPGA ID REG: 0x%08x\n\r", osdr_fpga_reg_read(OSDR_FPGA_REG_ID)); @@ -264,7 +268,7 @@ static int cmd_fpga_dump(struct cmd_state *cs, enum cmd_op op, } static int cmd_ssc_start(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *arg) + const char *cmd, int argc, char **argv) { switch (op) { case CMD_OP_EXEC: @@ -278,7 +282,7 @@ static int cmd_ssc_start(struct cmd_state *cs, enum cmd_op op, } static int cmd_ssc_stats(struct cmd_state *cs, enum cmd_op op, - const char *cmd, const char *arg) + const char *cmd, int argc, char **argv) { ssc_stats(); } diff --git a/firmware/src/uart_cmd.c b/firmware/src/uart_cmd.c index 93e0fda..2e58b94 100644 --- a/firmware/src/uart_cmd.c +++ b/firmware/src/uart_cmd.c @@ -57,15 +57,24 @@ void uart_cmds_register(struct cmd *c, unsigned int num) uart_cmd_register(&c[i]); } +#define CMD_MAX_ARGS 10 + static int handle_cb(struct cmd_state *cs, int op, char *cmd, char *arg) { struct cmd *c; int rc; + char *argv[CMD_MAX_ARGS]; + int argc = 0; - if (!arg) - arg = ""; - - //printf("handle_cb(%s, %s)\n", cmd, arg); + if (arg) { + char *tok; + /* tokenize the argument portion into individual arguments */ + for (tok = strtok(arg, ","); tok; tok = strtok(NULL, ",")) { + if (argc >= CMD_MAX_ARGS) + break; + argv[argc++] = tok; + } + } llist_for_each_entry(c, &cmd_list, list) { if (!strcmp(c->cmd, cmd)) { @@ -75,7 +84,7 @@ static int handle_cb(struct cmd_state *cs, int op, char *cmd, char *arg) return -EINVAL; } - rc = c->cb(cs, op, cmd, arg); + rc = c->cb(cs, op, cmd, argc, argv); if (rc < 0) uart_cmd_out(cs, "Error executing command\n\r"); return rc; @@ -128,10 +137,10 @@ int uart_cmd_char(struct cmd_state *cs, uint8_t ch) uart_cmd_reset(cs); break; case ' ': - case '\n': case '\t': /* ignore any whitespace */ break; + case '\n': case '\r': /* new line always resets buffer */ uart_cmd_reset(cs); @@ -143,12 +152,12 @@ int uart_cmd_char(struct cmd_state *cs, uint8_t ch) break; case ST_IN_ARG: switch (ch) { + case '\n': case '\r': rc = handle_cb(cs, CMD_OP_SET, cs->cmd.buf, cs->arg.buf); uart_cmd_reset(cs); break; case ' ': - case '\n': case '\t': /* ignore any whitespace */ break; diff --git a/firmware/tests/cmd-test.c b/firmware/tests/cmd-test.c index b3e4611..6af916f 100644 --- a/firmware/tests/cmd-test.c +++ b/firmware/tests/cmd-test.c @@ -12,15 +12,15 @@ static void my_out(const char *format, va_list ap) vprintf(format, ap); } -static int my_cb(struct cmd_state *cs, enum cmd_op op, const char *cmd, const char *arg) +static int my_cb(struct cmd_state *cs, enum cmd_op op, const char *cmd, + int argc, char **argv) { - printf("my_%s `%s', `%s'\n", op == CMD_OP_SET ? "set" : "get", cmd, arg); + int i; - if (!strcmp(cmd, "bar") && op == CMD_OP_SET) - return -EINVAL; - - else if (!strcmp(cmd, "baz") && op == CMD_OP_GET) - return -EINVAL; + printf("my_cb(%u,%s,%u,[", op, cmd, argc); + for (i = 0; i < argc; i++) + printf("%s,", argv[i]); + printf("])\n"); return 0; }