From 4807e7aa0c092812bc12be1768638b8504494a0d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Jul 2023 15:28:16 +0200 Subject: [PATCH] apps/dtm: Port to parse_arg module Make use of common argument parsing code. --- apps/dtm/pkg.yml | 1 + apps/dtm/src/main.c | 16 +- apps/dtm/src/parse.c | 529 ------------------------------------------- apps/dtm/src/parse.h | 58 ----- 4 files changed, 9 insertions(+), 595 deletions(-) delete mode 100644 apps/dtm/src/parse.c delete mode 100644 apps/dtm/src/parse.h diff --git a/apps/dtm/pkg.yml b/apps/dtm/pkg.yml index 2204befc41..bf1ced3640 100644 --- a/apps/dtm/pkg.yml +++ b/apps/dtm/pkg.yml @@ -28,6 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/shell" - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/util/parse_arg" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-mcumgr/cmd/img_mgmt" - "@mcuboot/boot/bootutil" diff --git a/apps/dtm/src/main.c b/apps/dtm/src/main.c index 11f41160b4..3b1716180e 100644 --- a/apps/dtm/src/main.c +++ b/apps/dtm/src/main.c @@ -19,7 +19,7 @@ #include "os/mynewt.h" #include -#include +#include #include #include "nimble/ble.h" #include "nimble/nimble_opt.h" @@ -28,14 +28,14 @@ #include #include -static const struct kv_pair phy_opts[] = { +static const struct parse_arg_kv_pair phy_opts[] = { { "1M", 0x01 }, { "2M", 0x02 }, { "coded", 0x03 }, { NULL } }; -static const struct kv_pair modulation_index_opts[] = { +static const struct parse_arg_kv_pair modulation_index_opts[] = { { "standard", 0x00 }, { "stable", 0x01 }, { NULL } @@ -47,7 +47,7 @@ cmd_rx_test(int argc, char **argv) struct ble_dtm_rx_params params; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -87,7 +87,7 @@ cmd_tx_test(int argc, char **argv) struct ble_dtm_tx_params params; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -132,7 +132,7 @@ cmd_stop_test(int argc, char **argv) uint16_t num_packets; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -154,7 +154,7 @@ cmd_tx_power(int argc, char **argv) struct ble_hci_vs_set_tx_pwr_rp rsp; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -183,7 +183,7 @@ cmd_set_antenna(int argc, char **argv) struct ble_hci_vs_set_antenna_cp cmd; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } diff --git a/apps/dtm/src/parse.c b/apps/dtm/src/parse.c deleted file mode 100644 index ed79d74042..0000000000 --- a/apps/dtm/src/parse.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "console/console.h" - -#define CMD_MAX_ARGS 16 - -static char *cmd_args[CMD_MAX_ARGS][2]; -static int cmd_num_args; - -int -parse_arg_find_idx(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - return i; - } - } - - return -1; -} - -char * -parse_arg_peek(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - return cmd_args[i][1]; - } - } - - return NULL; -} - -char * -parse_arg_extract(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - /* Erase parameter. */ - cmd_args[i][0][0] = '\0'; - - return cmd_args[i][1]; - } - } - - return NULL; -} - -/** - * Determines which number base to use when parsing the specified numeric - * string. This just avoids base '0' so that numbers don't get interpreted as - * octal. - */ -static int -parse_arg_long_base(char *sval) -{ - if (sval[0] == '0' && sval[1] == 'x') { - return 0; - } else { - return 10; - } -} - -long -parse_long_bounds(char *sval, long min, long max, int *out_status) -{ - char *endptr; - long lval; - - lval = strtol(sval, &endptr, parse_arg_long_base(sval)); - if (sval[0] != '\0' && *endptr == '\0' && - lval >= min && lval <= max) { - - *out_status = 0; - return lval; - } - - *out_status = EINVAL; - return 0; -} - -long -parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status) -{ - char *sval; - - sval = parse_arg_peek(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - return parse_long_bounds(sval, min, max, out_status); -} - -long -parse_arg_long_bounds(char *name, long min, long max, int *out_status) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - return parse_long_bounds(sval, min, max, out_status); -} - -long -parse_arg_long_bounds_dflt(char *name, long min, long max, - long dflt, int *out_status) -{ - long val; - int rc; - - val = parse_arg_long_bounds(name, min, max, &rc); - if (rc == ENOENT) { - rc = 0; - val = dflt; - } - - *out_status = rc; - - return val; -} - -uint64_t -parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status) -{ - char *endptr; - char *sval; - uint64_t lval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - - lval = strtoull(sval, &endptr, parse_arg_long_base(sval)); - if (sval[0] != '\0' && *endptr == '\0' && - lval >= min && lval <= max) { - - *out_status = 0; - return lval; - } - - *out_status = EINVAL; - return 0; -} - -long -parse_arg_long(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status); -} - -uint8_t -parse_arg_bool(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, 1, out_status); -} - -uint8_t -parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status) -{ - return parse_arg_long_bounds_dflt(name, 0, 1, dflt, out_status); -} - -uint8_t -parse_arg_uint8(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status); -} - -uint16_t -parse_arg_uint16(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status); -} - -uint16_t -parse_arg_uint16_peek(char *name, int *out_status) -{ - return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status); -} - -uint32_t -parse_arg_uint32(char *name, int *out_status) -{ - return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status); -} - -uint64_t -parse_arg_uint64(char *name, int *out_status) -{ - return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status); -} - -uint8_t -parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status) -{ - uint8_t val; - int rc; - - val = parse_arg_uint8(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -uint16_t -parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status) -{ - uint16_t val; - int rc; - - val = parse_arg_uint16(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -uint32_t -parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status) -{ - uint32_t val; - int rc; - - val = parse_arg_uint32(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -static uint32_t -parse_time_unit_mult(const char *str) -{ - if (!strcasecmp(str, "us")) { - return 1; - } else if (!strcasecmp(str, "ms")) { - return 1000; - } else if (!strcasecmp(str, "s")) { - return 1000000; - } - - return 0; -} - -static uint32_t -parse_time_us(const char *str, int *out_status) -{ - uint32_t val = 0; - uint32_t val_div = 1; - uint32_t val_mult = 1; - uint32_t val_us; - - while (isdigit((unsigned char)*str)) { - val *= 10; - val += *str - '0'; - str++; - } - - if (*str == '.') { - str++; - while (isdigit((unsigned char)*str)) { - val *= 10; - val += *str - '0'; - val_div *= 10; - str++; - } - } - - val_mult = parse_time_unit_mult(str); - if (val_mult == 0) { - *out_status = EINVAL; - return 0; - } - - if (val_mult > val_div) { - val_us = val * (val_mult / val_div); - } else { - val_us = val * (val_div / val_mult); - } - - *out_status = 0; - - return val_us; -} - -uint32_t -parse_arg_time_dflt(char *name, int step_us, uint32_t dflt, int *out_status) -{ - const char *arg; - uint32_t val; - int rc; - - arg = parse_arg_peek(name); - if (!arg) { - *out_status = 0; - return dflt; - } - - val = parse_time_us(arg, &rc); - if (rc) { - val = parse_arg_uint32(name, &rc); - if (rc == ENOENT) { - *out_status = 0; - return dflt; - } - } else { - val /= step_us; - parse_arg_extract(name); - } - - *out_status = rc; - return val; -} - -const struct kv_pair * -parse_kv_find(const struct kv_pair *kvs, char *name) -{ - const struct kv_pair *kv; - int i; - - for (i = 0; kvs[i].key != NULL; i++) { - kv = kvs + i; - if (strcmp(name, kv->key) == 0) { - return kv; - } - } - - return NULL; -} - -int -parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status) -{ - const struct kv_pair *kv; - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return -1; - } - - kv = parse_kv_find(kvs, sval); - if (kv == NULL) { - *out_status = EINVAL; - return -1; - } - - *out_status = 0; - return kv->val; -} - -int -parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, - int *out_status) -{ - int val; - int rc; - - val = parse_arg_kv(name, kvs, &rc); - if (rc == ENOENT) { - rc = 0; - val = def_val; - } - - *out_status = rc; - - return val; -} - - -static int -parse_arg_byte_stream_delim(char *sval, char *delims, int max_len, - uint8_t *dst, int *out_len) -{ - unsigned long ul; - char *endptr; - char *token; - int i; - char *tok_ptr; - - i = 0; - for (token = strtok_r(sval, delims, &tok_ptr); - token != NULL; - token = strtok_r(NULL, delims, &tok_ptr)) { - - if (i >= max_len) { - return EINVAL; - } - - ul = strtoul(token, &endptr, 16); - if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) { - return -1; - } - - dst[i] = ul; - i++; - } - - *out_len = i; - - return 0; -} - -int -parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - return ENOENT; - } - - return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len); -} - -int -parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, - uint8_t *dst, int *out_len) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - return ENOENT; - } - - return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len); -} - -int -parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len) -{ - int actual_len; - int rc; - - rc = parse_arg_byte_stream(name, len, dst, &actual_len); - if (rc != 0) { - return rc; - } - - if (actual_len != len) { - return EINVAL; - } - - return 0; -} - -int -parse_arg_all(int argc, char **argv) -{ - char *key; - char *val; - int i; - char *tok_ptr; - - cmd_num_args = 0; - - for (i = 0; i < argc; i++) { - key = strtok_r(argv[i], "=", &tok_ptr); - val = strtok_r(NULL, "=", &tok_ptr); - - if (key != NULL && val != NULL) { - if (strlen(key) == 0) { - console_printf("Error: invalid argument: %s\n", argv[i]); - return -1; - } - - if (cmd_num_args >= CMD_MAX_ARGS) { - console_printf("Error: too many arguments"); - return -1; - } - - cmd_args[cmd_num_args][0] = key; - cmd_args[cmd_num_args][1] = val; - cmd_num_args++; - } - } - - return 0; -} diff --git a/apps/dtm/src/parse.h b/apps/dtm/src/parse.h deleted file mode 100644 index a0255d368f..0000000000 --- a/apps/dtm/src/parse.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef PARSE_H -#define PARSE_H - -#include - -struct kv_pair { - char *key; - int val; -}; - -uint32_t parse_arg_time_dflt(char *name, int step, uint32_t dflt, int *out_status); -const struct kv_pair *parse_kv_find(const struct kv_pair *kvs, char *name); -int parse_arg_find_idx(const char *key); -char *parse_arg_extract(const char *key); -long parse_arg_long_bounds(char *name, long min, long max, int *out_status); -long parse_arg_long_bounds_dflt(char *name, long min, long max, - long dflt, int *out_status); -uint64_t parse_arg_uint64_bounds(char *name, uint64_t min, - uint64_t max, int *out_status); -long parse_arg_long(char *name, int *staus); -uint8_t parse_arg_bool(char *name, int *status); -uint8_t parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status); -uint8_t parse_arg_uint8(char *name, int *status); -uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status); -uint16_t parse_arg_uint16(char *name, int *status); -uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status); -uint32_t parse_arg_uint32(char *name, int *out_status); -uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status); -uint64_t parse_arg_uint64(char *name, int *out_status); -int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status); -int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, - int *out_status); -int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len); -int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, - uint8_t *dst, int *out_len); -int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len); -int parse_arg_all(int argc, char **argv); - -#endif