apps/dtm: Port to parse_arg module

Make use of common argument parsing code.
This commit is contained in:
Szymon Janc
2023-09-25 11:08:37 +02:00
parent a161f0abcd
commit 61e724ab23
5 changed files with 9 additions and 598 deletions
-3
View File
@@ -24,9 +24,6 @@
#include "host/ble_uuid.h"
#include <parse_arg/parse_arg.h>
//int parse_arg_mac(char *name, uint8_t *dst);
//int parse_arg_addr(char *name, ble_addr_t *addr);
//int parse_arg_uuid(char *name, ble_uuid_any_t *uuid);
int parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body,
uint8_t *out_body_len, uint8_t *out_suffix);
+1
View File
@@ -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"
+8 -8
View File
@@ -19,7 +19,7 @@
#include "os/mynewt.h"
#include <console/console.h>
#include <parse.h>
#include <parse_arg/parse_arg.h>
#include <shell/shell.h>
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
@@ -28,14 +28,14 @@
#include <img_mgmt/img_mgmt.h>
#include <bootutil/image.h>
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;
}
-529
View File
@@ -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 <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#include <parse.h>
#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;
}
-58
View File
@@ -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 <inttypes.h>
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