Files
ESPC3-wireless/components/system/source/shell/sh_vset.c

1515 lines
47 KiB
C
Raw Normal View History

2024-03-28 12:19:52 +08:00
/**
* @file sh_vset.h.c
* @author LokLiang
* @brief sh_vset.h
* @version 0.1
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#include "sh_vset.h"
#include <string.h>
#undef CONFIG_SYS_LOG_LEVEL
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
#define SYS_LOG_DOMAIN "VSET"
#define CONS_ABORT()
#include "sys_log.h"
#define __ARR_SIZE(ARR) (sizeof(ARR) / sizeof((ARR)[0]))
#define _TYPE_FLAG_UNSIGNED (1 << 0)
#define _TYPE_FLAG_INTEGER (1 << 1)
#define _TYPE_FLAG_FLOAT (1 << 2)
#define _TYPE_FLAG_STRING (1 << 3)
2025-02-13 17:17:07 +08:00
#define _PARAM_CB() \
do \
{ \
if (cb) \
cb(s_sh_hdl, &value); \
2024-03-28 12:19:52 +08:00
} while (0)
static sh_t *s_sh_hdl;
static vset_global_cb s_global_cb;
static bool _is_in_option(const char *input, const sh_vset_param_t *p, unsigned size);
static const sh_vset_param_t *_find_option(const char *input, const sh_vset_param_t *p, unsigned size);
static bool _do_completing_option(sh_t *sh_hdl, int argc, const char *argv[], const sh_vset_param_t *p, unsigned size);
static bool _do_completing_enum(const char *option, const sh_vset_param_t *p, unsigned size);
2025-02-13 17:17:07 +08:00
static int _set_dest_unsigned(void *dest, __type_attr_t attr, vset_cb cb, unsigned int value, unsigned int low, unsigned int high);
static int _set_dest_integer(void *dest, __type_attr_t attr, vset_cb cb, signed int value, signed int low, signed int high);
static int _set_dest_float(void *dest, __type_attr_t attr, vset_cb cb, float value, float low, float high);
static int _set_dest_string(void *dest, __type_attr_t attr, vset_cb cb, const char *str, unsigned bufsize);
static int _set_dest_enum(void *dest, __type_attr_t attr, vset_cb cb, const char *value, int type_flag);
2024-03-28 12:19:52 +08:00
2025-02-13 17:17:07 +08:00
static unsigned int _get_unsigned(void *dest, __type_attr_t attr);
static signed int _get_integer(void *dest, __type_attr_t attr);
static float _get_float(void *dest, __type_attr_t attr);
static char *_get_string(void *dest, __type_attr_t attr);
2024-03-28 12:19:52 +08:00
static int _enum_format(char *enum_buf, int buf_len, const char *enum_str);
static int _get_enum_by_key(const char *key, char **match_value, char *enum_buf);
2025-02-13 17:17:07 +08:00
static int _get_enum_by_param(void *dest, __type_attr_t attr, char **match_key, char **match_value, char *enum_buf, bool print_list, bool print_cp);
2024-03-28 12:19:52 +08:00
/**
* @brief s_attr_to_type_tbl
*
*/
static int const s_attr_to_type_tbl[] = {
[__TYPE_ATTR_CHR] = _PARSE_TYPE_INTEGER,
[__TYPE_ATTR_BOOL] = _PARSE_TYPE_INTEGER,
[__TYPE_ATTR_U8] = _PARSE_TYPE_UNSIGNED,
[__TYPE_ATTR_S8] = _PARSE_TYPE_INTEGER,
[__TYPE_ATTR_U16] = _PARSE_TYPE_UNSIGNED,
[__TYPE_ATTR_S16] = _PARSE_TYPE_INTEGER,
[__TYPE_ATTR_U32] = _PARSE_TYPE_UNSIGNED,
[__TYPE_ATTR_S32] = _PARSE_TYPE_INTEGER,
[__TYPE_ATTR_U64] = _PARSE_TYPE_UNSIGNED,
[__TYPE_ATTR_S64] = _PARSE_TYPE_INTEGER,
[__TYPE_ATTR_FLOAT] = _PARSE_TYPE_FLOAT,
[__TYPE_ATTR_DOUBLE] = _PARSE_TYPE_FLOAT,
[__TYPE_ATTR_STR] = _PARSE_TYPE_STRING,
};
/**
* @brief
*
* @param sh_hdl shell
2025-02-13 17:17:07 +08:00
* @param global_cb NULL
2024-03-28 12:19:52 +08:00
*/
2025-02-13 17:17:07 +08:00
void vset_init(sh_t *sh_hdl, vset_global_cb global_cb)
2024-03-28 12:19:52 +08:00
{
s_sh_hdl = sh_hdl;
2025-02-13 17:17:07 +08:00
s_global_cb = global_cb;
2024-03-28 12:19:52 +08:00
}
/**
* @brief vset_init()
*
*/
void vset_force_cb(void)
{
2025-02-13 17:17:07 +08:00
vset_global_cb global_cb = s_global_cb;
if (global_cb)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
global_cb(s_sh_hdl);
2024-03-28 12:19:52 +08:00
}
}
/**
* @brief p argv,
* argc argv
*
* @details
* p argc argv
* argv
*
* @param sh_hdl
* @param argc[i/o]
* @param argv[i/o]
* @param p
* @param size
* @retval 0 sh_vset_param_t::option
* @retval != 0 sh_vset_param_t::option
*/
int vset_option_set(sh_t *sh_hdl, int *argc, const char *argv[], const sh_vset_param_t *p, unsigned size)
{
int argc_old = *argc;
const char *err_option = NULL;
/* 遍历输入参数 argv 在 p 中找到匹配的 p[i].option 对应的 p[i].set_func 并执行 */
for (int i = 0; i < argc_old; i++)
{
for (int j = 0; j < size / sizeof(*p); j++)
{
const sh_vset_param_t *pset = &p[j];
if (strcmp(argv[i], pset->option) == 0) // 匹配到选项
{
if (pset->set_func) // 该选有对应的设置函数
{
bool flag = false;
argv[i] = NULL;
const char *str[] = {
"",
"",
};
if (i + 1 < argc_old)
{
++i;
str[0] = argv[i];
argv[i] = NULL;
if (strcmp("?", str[0]) == 0)
{
flag = true;
sh_echo(s_sh_hdl, "选项: %s\r\n", pset->option);
2025-02-13 17:17:07 +08:00
if (pset->help)
{
sh_echo(s_sh_hdl, "说明: %s\r\n", pset->help);
}
2024-03-28 12:19:52 +08:00
}
}
int ret = pset->set_func(str);
if (flag)
{
sh_echo(s_sh_hdl, "========\r\n");
}
if (ret != 0)
{
if (err_option == NULL)
{
err_option = pset->option;
}
sh_echo(s_sh_hdl, "( 选项 %s )\r\n", pset->option);
sh_echo(s_sh_hdl, "========\r\n");
}
}
break;
}
}
}
/* 更新已被处理的输入参数 argc 和 argv */
int argc_new = 0;
for (int i = 0; i < argc_old; i++)
{
if (argv[i] && *argv[i] != '\0')
{
argv[argc_new++] = argv[i]; // 更新 argv
}
}
*argc = argc_new; // 更新 argc
while (argc_new < argc_old)
{
argv[argc_new++] = NULL;
}
return (int)err_option;
}
/**
* @brief cp_fn set_func
*
* @param sh_hdl
* @param argc
* @param argv
* @param flag
* @param p
* @param size
* @retval true cp_fn
* @retval false cp_fn
*/
bool vset_option_cp(sh_t *sh_hdl, int argc, const char *argv[], bool flag, const sh_vset_param_t *p, unsigned size)
{
if (flag == false) // 一个参数正在输入
{
if (argc > 0 && _is_in_option(argv[argc - 1], p, size)) // 前正在输入的参数有对应存在的候选选项
{
_do_completing_option(sh_hdl, argc, argv, p, size); // 执行对选项的补全
return true;
}
else if (argc > 1)
{
return _do_completing_enum(argv[argc - 2], p, size); // 执行对 SET_ENUM 中的 ENUM_STR 的补全
}
else
{
return false;
}
}
else // 当前参数未有任何输入
{
const sh_vset_param_t *pset;
if (argc > 0 && (pset = _find_option(argv[argc - 1], p, size)) != NULL) // 找到上一个输入的参数的对应选项
{
vset_cp_enum(1, false, pset->enum_str);
return true;
}
else
{
_do_completing_option(sh_hdl, argc, argv, p, size); // 执行对选项的补全
return true;
}
}
}
2025-02-13 17:17:07 +08:00
int vset_unsigned(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], unsigned int low, unsigned int high)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_UNSIGNED, "待设置的参数类型不是正整数");
2024-03-28 12:19:52 +08:00
if (s_sh_hdl == NULL)
{
return -1;
}
2025-02-13 17:17:07 +08:00
if (attr >= __ARR_SIZE(s_attr_to_type_tbl))
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
2025-02-13 17:17:07 +08:00
if (s_attr_to_type_tbl[attr] != _PARSE_TYPE_UNSIGNED)
2024-03-28 12:19:52 +08:00
{
sh_echo(s_sh_hdl, "待设置的参数类型不是正整数\r\n");
return -1;
}
if (argv[0] == NULL || *argv[0] == '\0')
{
sh_echo(s_sh_hdl, "缺少参数\r\n");
return -1;
}
if (strcmp(argv[0], "?") == 0)
{
if (high < low)
{
low ^= high;
high ^= low;
low ^= high;
}
sh_echo(s_sh_hdl, "有效范围: %d .. %d\r\n", low, high);
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "当前值: %u\r\n", _get_unsigned(dest, attr));
2024-03-28 12:19:52 +08:00
return 0;
}
sh_parse_t pv = sh_parse_value(argv[0]);
switch (pv.type)
{
case _PARSE_TYPE_UNSIGNED: // 解析出的参数格式是无符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_unsigned(dest, attr, cb, pv.value.val_unsigned, low, high);
2024-03-28 12:19:52 +08:00
default:
sh_echo(s_sh_hdl, "参数 '%s' 格式错误, 请输入正整数\r\n", argv[0]);
return -1;
}
}
2025-02-13 17:17:07 +08:00
int vset_integer(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], signed int low, signed int high)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_INTEGER, "待设置的参数类型不是带符号整数");
2024-03-28 12:19:52 +08:00
if (s_sh_hdl == NULL)
{
return -1;
}
2025-02-13 17:17:07 +08:00
if (attr >= __ARR_SIZE(s_attr_to_type_tbl))
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
2025-02-13 17:17:07 +08:00
if (s_attr_to_type_tbl[attr] != _PARSE_TYPE_INTEGER)
2024-03-28 12:19:52 +08:00
{
sh_echo(s_sh_hdl, "待设置的参数类型不是带符号整数\r\n");
return -1;
}
if (argv[0] == NULL || *argv[0] == '\0')
{
sh_echo(s_sh_hdl, "缺少参数\r\n");
return -1;
}
if (strcmp(argv[0], "?") == 0)
{
if (high < low)
{
low ^= high;
high ^= low;
low ^= high;
}
sh_echo(s_sh_hdl, "有效范围: %d .. %d\r\n", low, high);
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "当前值: %d\r\n", _get_integer(dest, attr));
2024-03-28 12:19:52 +08:00
return 0;
}
sh_parse_t pv = sh_parse_value(argv[0]);
switch (pv.type)
{
case _PARSE_TYPE_INTEGER: // 解析出的参数格式是带符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_integer(dest, attr, cb, pv.value.val_integer, low, high);
2024-03-28 12:19:52 +08:00
case _PARSE_TYPE_UNSIGNED: // 解析出的参数格式是无符号整型
if (pv.value.val_unsigned > (1u << (sizeof(pv.value.val_unsigned) * 8 - 1)) - 1)
{
sh_echo(s_sh_hdl, "参数 %u 溢出\r\n", pv.value.val_unsigned);
return -1;
}
2025-02-13 17:17:07 +08:00
return _set_dest_integer(dest, attr, cb, pv.value.val_unsigned, low, high);
2024-03-28 12:19:52 +08:00
default:
sh_echo(s_sh_hdl, "参数 '%s' 格式错误, 请输入整数\r\n", argv[0]);
return -1;
}
}
2025-02-13 17:17:07 +08:00
int vset_float(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], float low, float high)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_FLOAT, "待设置的参数类型不是浮点数");
2024-03-28 12:19:52 +08:00
if (s_sh_hdl == NULL)
{
return -1;
}
2025-02-13 17:17:07 +08:00
if (attr >= __ARR_SIZE(s_attr_to_type_tbl))
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
2025-02-13 17:17:07 +08:00
if (s_attr_to_type_tbl[attr] != _PARSE_TYPE_FLOAT)
2024-03-28 12:19:52 +08:00
{
sh_echo(s_sh_hdl, "待设置的参数类型不是浮点数\r\n");
return -1;
}
if (argv[0] == NULL || *argv[0] == '\0')
{
sh_echo(s_sh_hdl, "缺少参数\r\n");
return -1;
}
if (strcmp(argv[0], "?") == 0)
{
if (high < low)
{
float tmp = low;
low = high;
high = tmp;
}
sh_echo(s_sh_hdl, "有效范围: %f .. %f\r\n", low, high);
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "当前值: %f\r\n", _get_float(dest, attr));
2024-03-28 12:19:52 +08:00
return 0;
}
sh_parse_t pv = sh_parse_value(argv[0]);
switch (pv.type)
{
case _PARSE_TYPE_INTEGER: // 解析出的参数格式是带符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_float(dest, attr, cb, pv.value.val_integer, low, high);
2024-03-28 12:19:52 +08:00
case _PARSE_TYPE_UNSIGNED: // 解析出的参数格式是无符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_float(dest, attr, cb, pv.value.val_unsigned, low, high);
2024-03-28 12:19:52 +08:00
case _PARSE_TYPE_FLOAT: // 解析出的参数格式是浮点数
2025-02-13 17:17:07 +08:00
return _set_dest_float(dest, attr, cb, pv.value.val_float, low, high);
2024-03-28 12:19:52 +08:00
default:
sh_echo(s_sh_hdl, "参数 '%s' 格式错误, 请输入数值\r\n", argv[0]);
return -1;
}
}
2025-02-13 17:17:07 +08:00
int vset_str(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], unsigned bufsize)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_STRING, "待设置的参数类型不是字符串");
2024-03-28 12:19:52 +08:00
if (s_sh_hdl == NULL)
{
return -1;
}
2025-02-13 17:17:07 +08:00
if (attr >= __ARR_SIZE(s_attr_to_type_tbl))
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
2025-02-13 17:17:07 +08:00
if (s_attr_to_type_tbl[attr] != _PARSE_TYPE_STRING)
2024-03-28 12:19:52 +08:00
{
sh_echo(s_sh_hdl, "待设置的参数类型不是字符串\r\n");
return -1;
}
if (argv[0] == NULL || *argv[0] == '\0')
{
sh_echo(s_sh_hdl, "缺少参数\r\n");
return -1;
}
if (strcmp(argv[0], "?") == 0)
{
sh_echo(s_sh_hdl, "最大长度: %d\r\n", bufsize - 1);
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "当前值: %s\r\n", _get_string(dest, attr));
2024-03-28 12:19:52 +08:00
return 0;
}
if (argv[1] && *argv[1] != '\0')
{
sh_echo(s_sh_hdl, "参数中有空格。如果目标设备名中包含空格,请使用引号表示\r\n");
return -1;
}
2025-02-13 17:17:07 +08:00
return _set_dest_string(dest, attr, cb, argv[0], bufsize);
2024-03-28 12:19:52 +08:00
}
2025-02-13 17:17:07 +08:00
int vset_enum(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], const char *enum_str)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
2024-03-28 12:19:52 +08:00
if (s_sh_hdl == NULL)
{
return -1;
}
2025-02-13 17:17:07 +08:00
if (attr >= __ARR_SIZE(s_attr_to_type_tbl))
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
if (argv[0] == NULL || *argv[0] == '\0')
{
sh_echo(s_sh_hdl, "缺少参数\r\n");
return -1;
}
/* 格式化 enum_str 到 enum_buf */
char enum_buf[CONFIG_SH_MAX_LINE_LEN];
int enum_len = _enum_format(enum_buf, __ARR_SIZE(enum_buf), enum_str);
if (enum_len < 0)
{
return -1;
}
char *match_key = NULL;
char *match_value = NULL;
int type_flag = 0;
if (strcmp(argv[0], "?") == 0)
{
sh_echo(s_sh_hdl, "可选值:\r\n");
2025-02-13 17:17:07 +08:00
_get_enum_by_param(dest, attr, &match_key, &match_value, enum_buf, true, false);
2024-03-28 12:19:52 +08:00
if (match_value)
{
sh_echo(s_sh_hdl, "当前值:\t%s\r\n", match_key);
}
return 0;
}
type_flag = _get_enum_by_key(argv[0], &match_value, enum_buf);
if (type_flag == 0)
{
sh_echo(s_sh_hdl, "选项为空\r\n");
return -1;
}
if (match_value == NULL)
{
sh_echo(s_sh_hdl, "'%s': 非法的取值\r\n", argv[0]);
return -1;
}
2025-02-13 17:17:07 +08:00
return _set_dest_enum(dest, attr, cb, match_value, type_flag);
2024-03-28 12:19:52 +08:00
}
void vset_cp_enum(int argc, bool flag, const char *enum_str)
{
if (argc + flag == 1)
{
if (enum_str != NULL)
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
if (s_sh_hdl == NULL)
{
return;
}
/* 格式化 enum_str 到 enum_buf */
char enum_buf[CONFIG_SH_MAX_LINE_LEN];
int enum_len = _enum_format(enum_buf, __ARR_SIZE(enum_buf), enum_str);
if (enum_len < 0)
{
return;
}
/* 分割字符串 str_buf 并穷举匹配到的值,输出 match_key, match_value, type_flag */
char *match_key = NULL;
char *match_value = NULL;
2025-02-13 17:17:07 +08:00
_get_enum_by_param(enum_buf, __GENERIC_ATTR(enum_buf), &match_key, &match_value, enum_buf, false, true);
2024-03-28 12:19:52 +08:00
}
else
{
sh_completion_resource(s_sh_hdl, NULL, "? ", NULL);
}
}
}
/**
* @brief vset_option_cp()
*
* @param input
* @param p
* @param size
* @retval true
* @retval false
*/
static bool _is_in_option(const char *input, const sh_vset_param_t *p, unsigned size)
{
int len = strlen(input);
for (int i = 0; i < size / sizeof(*p); i++)
{
if (strncmp(input, p[i].option, len) == 0)
{
return true;
}
}
return false;
}
/**
* @brief vset_option_cp()
* @brief
*
* @param input
* @param p
* @param size
* @return const sh_vset_param_t*
*/
static const sh_vset_param_t *_find_option(const char *input, const sh_vset_param_t *p, unsigned size)
{
for (int i = 0; i < size / sizeof(*p); i++)
{
if (strcmp(input, p[i].option) == 0)
{
return &p[i];
}
}
return NULL;
}
/**
* @brief vset_option_cp()
*
* @param sh_hdl
* @param argc
* @param argv
* @param p
* @param size
* @retval true
*/
static bool _do_completing_option(sh_t *sh_hdl, int argc, const char *argv[], const sh_vset_param_t *p, unsigned size)
{
bool ret = false;
for (int i = 0; i < size / sizeof(*p); i++) // 遍历 p[i].option 分析
{
/* 遍历已输入的参数确认当前的 p[i].option 未曾出现过 */
bool repeat_flag = false;
for (int j = 0; j < argc - 1; j++)
{
if (strcmp(p[i].option, argv[j]) == 0)
{
repeat_flag = true;
break;
}
}
if (repeat_flag == false)
{
/* 执行 sh_completion_resource() */
char option_cpy[0x100];
int len = 0;
for (len = 0; len < sizeof(option_cpy) - 2; len++)
{
option_cpy[len] = p[i].option[len];
if (option_cpy[len] == '\0')
{
break;
}
}
option_cpy[len++] = ' ';
option_cpy[len] = '\0';
sh_completion_resource(sh_hdl, NULL, option_cpy, p[i].help);
ret = true;
}
}
return ret;
}
/**
* @brief vset_option_cp() SET_ENUM ENUM_STR
*
* @param option
* @param p
* @param size
*/
static bool _do_completing_enum(const char *option, const sh_vset_param_t *p, unsigned size)
{
/* 根据上一个参数,遍历 p 找到对应的成员 */
if (option)
{
for (int i = 0; i < size / sizeof(*p); i++)
{
if (strcmp(option, p[i].option) == 0)
{
if (p[i].set_func)
{
vset_cp_enum(1, false, p[i].enum_str);
}
return true;
}
}
}
return false;
}
2025-02-13 17:17:07 +08:00
static int _set_dest_unsigned(void *dest, __type_attr_t attr, vset_cb cb, unsigned int value, unsigned int low, unsigned int high)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
vset_global_cb global_cb = NULL;
2024-03-28 12:19:52 +08:00
int ret = -1;
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_UNSIGNED, "待设置的参数类型不是正整数");
if (value < low)
{
sh_echo(s_sh_hdl, "设置失败: %d < %d(min)\r\n", value, low);
return -1;
}
if (value > high)
{
sh_echo(s_sh_hdl, "设置失败: %d > %d(max)\r\n", value, high);
return -1;
}
switch (attr)
{
case __TYPE_ATTR_U8:
{
SYS_ASSERT((low & (~0u << 8)) == 0 && (high & (~0u << 8)) == 0, "范围值溢出");
if ((low & (~0u << 8)) || (high & (~0u << 8)))
{
sh_echo(s_sh_hdl, "设置失败: 设置值溢出\r\n");
return -1;
}
if (*((uint8_t *)dest) != value)
{
_PARAM_CB();
*((uint8_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_U16:
{
SYS_ASSERT((low & (~0u << 16)) == 0 && (high & (~0u << 16)) == 0, "范围值溢出");
if ((low & (~0u << 16)) || (high & (~0u << 16)))
{
sh_echo(s_sh_hdl, "设置失败: 设置值溢出\r\n");
return -1;
}
if (*((uint16_t *)dest) != value)
{
_PARAM_CB();
*((uint16_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_U32:
{
if (*((uint32_t *)dest) != value)
{
_PARAM_CB();
*((uint32_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_U64:
{
if (*((uint64_t *)dest) != value)
{
_PARAM_CB();
*((uint64_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
default:
return -1;
}
2025-02-13 17:17:07 +08:00
if (global_cb)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
global_cb(s_sh_hdl);
2024-03-28 12:19:52 +08:00
}
return ret;
}
2025-02-13 17:17:07 +08:00
static int _set_dest_integer(void *dest, __type_attr_t attr, vset_cb cb, signed int value, signed int low, signed int high)
2024-03-28 12:19:52 +08:00
{
#define _MAX_S8 127
#define _MIN_S8 -128
#define _MAX_S16 32767
#define _MIN_S16 -32768
2025-02-13 17:17:07 +08:00
vset_global_cb global_cb = NULL;
2024-03-28 12:19:52 +08:00
int ret = -1;
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_INTEGER, "待设置的参数类型不是带符号整数");
if (value < low)
{
sh_echo(s_sh_hdl, "设置失败: %d < %d(min)\r\n", value, low);
return -1;
}
if (value > high)
{
sh_echo(s_sh_hdl, "设置失败: %d > %d(max)\r\n", value, high);
return -1;
}
switch (attr)
{
case __TYPE_ATTR_CHR:
{
char data = value;
if (data != value)
{
sh_echo(s_sh_hdl, "设置失败: 设置值溢出\r\n");
return -1;
}
if (*((char *)dest) != data)
{
_PARAM_CB();
*((char *)dest) = data;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_BOOL:
{
bool data = value;
if (data != value)
{
sh_echo(s_sh_hdl, "设置失败: 设置值溢出\r\n");
return -1;
}
if (*((bool *)dest) != data)
{
_PARAM_CB();
*((bool *)dest) = data;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_S8:
{
SYS_ASSERT(low >= _MIN_S8 && low <= _MAX_S8, "范围值溢出");
SYS_ASSERT(high >= _MIN_S8 && high <= _MAX_S8, "范围值溢出");
if (low < _MIN_S8 || low > _MAX_S8 ||
high < _MIN_S8 || high > _MAX_S8)
{
sh_echo(s_sh_hdl, "设置失败: 设置值溢出\r\n");
return -1;
}
if (*((int8_t *)dest) != value)
{
_PARAM_CB();
*((int8_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_S16:
{
SYS_ASSERT(low >= _MIN_S16 && low <= _MAX_S16, "范围值溢出");
SYS_ASSERT(high >= _MIN_S16 && high <= _MAX_S16, "范围值溢出");
if (low < _MIN_S16 || low > _MAX_S16 ||
high < _MIN_S16 || high > _MAX_S16)
{
sh_echo(s_sh_hdl, "设置失败: 设置值溢出\r\n");
return -1;
}
if (*((int16_t *)dest) != value)
{
_PARAM_CB();
*((int16_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_S32:
{
if (*((int32_t *)dest) != value)
{
_PARAM_CB();
*((int32_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_S64:
{
if (*((int64_t *)dest) != value)
{
_PARAM_CB();
*((int64_t *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
default:
return -1;
}
2025-02-13 17:17:07 +08:00
if (global_cb)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
global_cb(s_sh_hdl);
2024-03-28 12:19:52 +08:00
}
return ret;
}
2025-02-13 17:17:07 +08:00
static int _set_dest_float(void *dest, __type_attr_t attr, vset_cb cb, float value, float low, float high)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
vset_global_cb global_cb = NULL;
2024-03-28 12:19:52 +08:00
int ret = -1;
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_FLOAT, "待设置的参数类型不是浮点数");
if (value < low)
{
sh_echo(s_sh_hdl, "设置失败: %f < %f(min)\r\n", value, low);
return -1;
}
if (value > high)
{
sh_echo(s_sh_hdl, "设置失败: %f > %f(max)\r\n", value, high);
return -1;
}
switch (attr)
{
case __TYPE_ATTR_FLOAT:
{
if (*((float *)dest) != value)
{
_PARAM_CB();
*((float *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
case __TYPE_ATTR_DOUBLE:
{
if (*((double *)dest) != value)
{
_PARAM_CB();
*((double *)dest) = value;
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
}
default:
return -1;
}
2025-02-13 17:17:07 +08:00
if (global_cb)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
global_cb(s_sh_hdl);
2024-03-28 12:19:52 +08:00
}
return ret;
}
2025-02-13 17:17:07 +08:00
static int _set_dest_string(void *dest, __type_attr_t attr, vset_cb cb, const char *str, unsigned bufsize)
2024-03-28 12:19:52 +08:00
{
int str_size = strlen(str) + 1;
2025-02-13 17:17:07 +08:00
vset_global_cb global_cb = NULL;
2024-03-28 12:19:52 +08:00
int ret = -1;
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_STRING, "待设置的参数类型不是字符串");
if (str_size > bufsize)
{
sh_echo(s_sh_hdl, "注意: '%s' 大于最大长度 %d\r\n", str, bufsize - 1);
2025-02-13 17:17:07 +08:00
str_size = bufsize;
2024-03-28 12:19:52 +08:00
}
switch (attr)
{
case __TYPE_ATTR_STR:
memset(dest, 0, bufsize);
if (memcmp(dest, str, str_size))
{
2025-02-13 17:17:07 +08:00
if (cb)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
char value[str_size + 1];
memset(value, 0, str_size + 1);
memcpy(value, str, str_size);
2024-03-28 12:19:52 +08:00
_PARAM_CB();
}
memcpy(dest, str, str_size);
2025-02-13 17:17:07 +08:00
global_cb = s_global_cb;
2024-03-28 12:19:52 +08:00
}
ret = 0;
break;
default:
return -1;
}
2025-02-13 17:17:07 +08:00
if (global_cb)
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
global_cb(s_sh_hdl);
2024-03-28 12:19:52 +08:00
}
return ret;
}
2025-02-13 17:17:07 +08:00
static int _set_dest_enum(void *dest, __type_attr_t attr, vset_cb cb, const char *value, int type_flag)
2024-03-28 12:19:52 +08:00
{
sh_parse_t pv = sh_parse_value(value);
2025-02-13 17:17:07 +08:00
switch (s_attr_to_type_tbl[attr])
2024-03-28 12:19:52 +08:00
{
case _PARSE_TYPE_UNSIGNED: // 待设置的参数格式是无符号整型
{
if (type_flag & (_TYPE_FLAG_INTEGER | _TYPE_FLAG_FLOAT | _TYPE_FLAG_STRING))
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 包含非法的 value 类型\r\n");
return -1;
}
switch (pv.type)
{
case _PARSE_TYPE_UNSIGNED: // 当前匹配的参数格式是无符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_unsigned(dest, attr, cb, pv.value.val_unsigned, pv.value.val_unsigned, pv.value.val_unsigned);
2024-03-28 12:19:52 +08:00
default:
return -1;
}
}
break;
case _PARSE_TYPE_INTEGER: // 待设置的参数格式是带符号整型
{
if (type_flag & (_TYPE_FLAG_FLOAT | _TYPE_FLAG_STRING))
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 包含非法的 value 类型\r\n");
return -1;
}
switch (pv.type)
{
case _PARSE_TYPE_INTEGER: // 当前匹配的参数格式是带符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_integer(dest, attr, cb, pv.value.val_integer, pv.value.val_integer, pv.value.val_integer);
2024-03-28 12:19:52 +08:00
case _PARSE_TYPE_UNSIGNED: // 当前匹配的参数格式是无符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_integer(dest, attr, cb, pv.value.val_unsigned, pv.value.val_unsigned, pv.value.val_unsigned);
2024-03-28 12:19:52 +08:00
default:
return -1;
}
}
break;
case _PARSE_TYPE_FLOAT: // 待设置的参数格式是浮点数
{
if (type_flag & (_TYPE_FLAG_STRING))
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 包含非法的 value 类型\r\n");
return -1;
}
switch (pv.type)
{
case _PARSE_TYPE_INTEGER: // 当前匹配的参数格式是带符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_float(dest, attr, cb, pv.value.val_integer, pv.value.val_integer, pv.value.val_integer);
2024-03-28 12:19:52 +08:00
case _PARSE_TYPE_UNSIGNED: // 当前匹配的参数格式是无符号整型
2025-02-13 17:17:07 +08:00
return _set_dest_float(dest, attr, cb, pv.value.val_unsigned, pv.value.val_unsigned, pv.value.val_unsigned);
2024-03-28 12:19:52 +08:00
case _PARSE_TYPE_FLOAT: // 当前匹配的参数格式是浮点数
2025-02-13 17:17:07 +08:00
return _set_dest_float(dest, attr, cb, pv.value.val_float, pv.value.val_float, pv.value.val_float);
2024-03-28 12:19:52 +08:00
default:
return -1;
}
}
break;
case _PARSE_TYPE_STRING: // 待设置的参数格式是字符串
{
2025-02-13 17:17:07 +08:00
return _set_dest_string(dest, attr, cb, value, strlen(value) + 1);
2024-03-28 12:19:52 +08:00
}
break;
default:
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
return -1;
}
2025-02-13 17:17:07 +08:00
static signed int _get_integer(void *dest, __type_attr_t attr)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_INTEGER, "待设置的参数类型不是带符号整数");
2024-03-28 12:19:52 +08:00
2025-02-13 17:17:07 +08:00
switch (attr)
2024-03-28 12:19:52 +08:00
{
case __TYPE_ATTR_CHR:
2025-02-13 17:17:07 +08:00
return *((char *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_BOOL:
2025-02-13 17:17:07 +08:00
return *((bool *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_S8:
2025-02-13 17:17:07 +08:00
return *((int8_t *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_S16:
2025-02-13 17:17:07 +08:00
return *((int16_t *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_S32:
2025-02-13 17:17:07 +08:00
return *((int32_t *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_S64:
2025-02-13 17:17:07 +08:00
return *((int64_t *)dest);
2024-03-28 12:19:52 +08:00
default:
return -1;
}
}
2025-02-13 17:17:07 +08:00
static float _get_float(void *dest, __type_attr_t attr)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_FLOAT, "待设置的参数类型不是浮点数");
2024-03-28 12:19:52 +08:00
2025-02-13 17:17:07 +08:00
switch (attr)
2024-03-28 12:19:52 +08:00
{
case __TYPE_ATTR_FLOAT:
2025-02-13 17:17:07 +08:00
return *((float *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_DOUBLE:
2025-02-13 17:17:07 +08:00
return *((double *)dest);
2024-03-28 12:19:52 +08:00
default:
return -1;
}
}
2025-02-13 17:17:07 +08:00
static char *_get_string(void *dest, __type_attr_t attr)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_STRING, "待设置的参数类型不是字符串");
2024-03-28 12:19:52 +08:00
2025-02-13 17:17:07 +08:00
return dest;
2024-03-28 12:19:52 +08:00
}
2025-02-13 17:17:07 +08:00
static unsigned int _get_unsigned(void *dest, __type_attr_t attr)
2024-03-28 12:19:52 +08:00
{
SYS_ASSERT(s_sh_hdl, "未使用 vset_init() 初始化");
2025-02-13 17:17:07 +08:00
SYS_ASSERT(attr < __ARR_SIZE(s_attr_to_type_tbl), "attr 的值不在 __type_attr_t 所定义的范围");
SYS_ASSERT(s_attr_to_type_tbl[attr] == _PARSE_TYPE_UNSIGNED, "待设置的参数类型不是正整数");
2024-03-28 12:19:52 +08:00
2025-02-13 17:17:07 +08:00
switch (attr)
2024-03-28 12:19:52 +08:00
{
case __TYPE_ATTR_U8:
2025-02-13 17:17:07 +08:00
return *((uint8_t *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_U16:
2025-02-13 17:17:07 +08:00
return *((uint16_t *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_U32:
2025-02-13 17:17:07 +08:00
return *((uint32_t *)dest);
2024-03-28 12:19:52 +08:00
case __TYPE_ATTR_U64:
2025-02-13 17:17:07 +08:00
return *((uint64_t *)dest);
2024-03-28 12:19:52 +08:00
default:
return -1;
}
}
/**
* @brief enum_str enum_buf
*
* @param enum_buf[out] enum_str
* @param buf_len enum_buf
* @param enum_str
* @retval < 0 enum_str ()
* @retval >= 0 enum_buf '\0'
*/
static int _enum_format(char *enum_buf, int buf_len, const char *enum_str)
{
/* 复制 enum_str 到 str_buf 并移除空格 */
if (strlen(enum_str) >= buf_len)
{
sh_echo(s_sh_hdl, "注意: str_buff 长度不足\r\n");
}
strncpy(enum_buf, enum_str, buf_len - 1);
enum_buf[buf_len - 1] = '\0';
/* 去除可能的多余空格 */
buf_len = strlen(enum_buf);
int cid = 0;
int flag1 = 0;
int flag2 = 1;
for (int i = 0; i < buf_len; i++)
{
if (enum_buf[i] > ' ')
{
enum_buf[cid] = enum_str[i];
cid++;
if (enum_buf[i] != ',' && enum_buf[i] != '=')
{
flag1 += flag2;
flag1 += !flag1;
if (flag1 > 1)
{
break;
}
}
else
{
flag1 = 0;
}
flag2 = 0;
}
else
{
flag2 = 1;
}
}
if (flag1 > 1)
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 键值或数值不能包含空格\r\n");
return -1;
}
enum_buf[cid] = '\0';
return cid; // 返回字符串长度(不包含结束符)
}
/**
* @brief key enum_buf value
*
* @param key key
* @param match_value[out] key value enum_buf NULL enum_buf param
* @param enum_buf _enum_format()
* @retval int enum_buf value
* _TYPE_FLAG_UNSIGNED enum_buf
* _TYPE_FLAG_INTEGER enum_buf
* _TYPE_FLAG_FLOAT enum_buf
* _TYPE_FLAG_STRING enum_buf
*/
static int _get_enum_by_key(const char *key, char **match_value, char *enum_buf)
{
int type_flag = 0; // 在 match_value 中出现过的数据类型
/* 分割字符串 enum_buf 并穷举匹配到的值 */
*match_value = NULL;
char *save_token;
char *token = strtok_r(enum_buf, ",", &save_token);
while (token)
{
char *enum_value;
char *enum_key = strtok_r(token, "=", &enum_value);
if (enum_key == NULL || *enum_key == '\0' || *enum_value == '\0')
{
sh_echo(s_sh_hdl, "'%s' 的格式错误, 请使用如下格式表示: 'key1=value,key2=value,...'\r\n", token);
return 0;
}
sh_parse_t pv = sh_parse_value(enum_value);
switch (pv.type)
{
case _PARSE_TYPE_INTEGER: // 解析出的参数格式是带符号整型
type_flag |= _TYPE_FLAG_INTEGER;
break;
case _PARSE_TYPE_UNSIGNED: // 解析出的参数格式是无符号整型
type_flag |= _TYPE_FLAG_UNSIGNED;
break;
case _PARSE_TYPE_FLOAT: // 解析出的参数格式是浮点数
type_flag |= _TYPE_FLAG_FLOAT;
break;
case _PARSE_TYPE_STRING: // 解析出的参数格式是字符串
type_flag |= _TYPE_FLAG_STRING;
break;
default:
break;
}
if (*match_value == NULL)
{
if (strcmp(enum_key, key) == 0)
{
*match_value = enum_value;
}
}
token = strtok_r(NULL, ",", &save_token);
}
return type_flag;
}
/**
* @brief param enum_buf key value
* 1. enum_buf value
* 2. param key value *match_key *match_value
* 2. enum_buf key value
*
* @param param
* @param match_key[out] param key enum_buf NULL enum_buf param
* @param match_value[out] param value enum_buf NULL enum_buf param
* @param enum_buf _enum_format()
* @param print_list enum_buf
* @param print_cp
* @retval int enum_buf value
* _TYPE_FLAG_UNSIGNED enum_buf
* _TYPE_FLAG_INTEGER enum_buf
* _TYPE_FLAG_FLOAT enum_buf
* _TYPE_FLAG_STRING enum_buf
*/
2025-02-13 17:17:07 +08:00
static int _get_enum_by_param(void *dest, __type_attr_t attr, char **match_key, char **match_value, char *enum_buf, bool print_list, bool print_cp)
2024-03-28 12:19:52 +08:00
{
char param_value_str[0x100];
int type_flag = 0; // 在 match_value 中出现过的数据类型
2025-02-13 17:17:07 +08:00
if (attr >= __ARR_SIZE(s_attr_to_type_tbl))
2024-03-28 12:19:52 +08:00
{
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
2025-02-13 17:17:07 +08:00
switch (s_attr_to_type_tbl[attr])
2024-03-28 12:19:52 +08:00
{
case _PARSE_TYPE_INTEGER: // 待设置的参数格式是带符号整型
2025-02-13 17:17:07 +08:00
SYS_SNPRINT(param_value_str, sizeof(param_value_str), "%d", _get_integer(dest, attr));
2024-03-28 12:19:52 +08:00
break;
case _PARSE_TYPE_UNSIGNED: // 待设置的参数格式是无符号整型
2025-02-13 17:17:07 +08:00
SYS_SNPRINT(param_value_str, sizeof(param_value_str), "%u", _get_unsigned(dest, attr));
2024-03-28 12:19:52 +08:00
break;
case _PARSE_TYPE_FLOAT: // 待设置的参数格式是浮点数
2025-02-13 17:17:07 +08:00
SYS_SNPRINT(param_value_str, sizeof(param_value_str), "%f", _get_float(dest, attr));
2024-03-28 12:19:52 +08:00
break;
case _PARSE_TYPE_STRING: // 待设置的参数格式是字符串
2025-02-13 17:17:07 +08:00
SYS_SNPRINT(param_value_str, sizeof(param_value_str), "%s", _get_string(dest, attr));
2024-03-28 12:19:52 +08:00
break;
default:
2025-02-13 17:17:07 +08:00
sh_echo(s_sh_hdl, "attr 的值不在 __type_attr_t 所定义的范围\r\n");
2024-03-28 12:19:52 +08:00
return -1;
}
param_value_str[__ARR_SIZE(param_value_str) - 1] = '\0';
/* 分割字符串 enum_buf 并穷举匹配到的值 */
*match_key = NULL;
*match_value = NULL;
char *save_token;
char *token = strtok_r(enum_buf, ",", &save_token);
while (token)
{
char *enum_value;
char *enum_key = strtok_r(token, "=", &enum_value);
char key_value_str[__ARR_SIZE(param_value_str)];
if (*enum_key == '\0' || *enum_value == '\0')
{
sh_echo(s_sh_hdl, "'%s' 的格式错误, 请使用如下格式表示: 'key1=value,key2=value,...'\r\n", enum_key);
return 0;
}
key_value_str[0] = '\0';
sh_parse_t pv = sh_parse_value(enum_value);
switch (pv.type)
{
case _PARSE_TYPE_UNSIGNED: // 解析出的参数格式是无符号整型
type_flag |= _TYPE_FLAG_UNSIGNED;
if (*match_key == NULL)
{
2025-02-13 17:17:07 +08:00
switch (s_attr_to_type_tbl[attr])
2024-03-28 12:19:52 +08:00
{
case _PARSE_TYPE_UNSIGNED: // 待设置的参数格式是无符号整型
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%u", pv.value.val_unsigned);
break;
case _PARSE_TYPE_INTEGER: // 待设置的参数格式是带符号整型
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%d", pv.value.val_unsigned);
break;
case _PARSE_TYPE_FLOAT: // 待设置的参数格式是浮点数
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%f", (float)pv.value.val_unsigned);
break;
case _PARSE_TYPE_STRING: // 待设置的参数格式是字符串
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%s", enum_value);
break;
default:
break;
}
}
break;
case _PARSE_TYPE_INTEGER: // 解析出的参数格式是带符号整型
type_flag |= _TYPE_FLAG_INTEGER;
if (*match_key == NULL)
{
2025-02-13 17:17:07 +08:00
switch (s_attr_to_type_tbl[attr])
2024-03-28 12:19:52 +08:00
{
case _PARSE_TYPE_INTEGER: // 待设置的参数格式是带符号整型
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%d", pv.value.val_integer);
break;
case _PARSE_TYPE_FLOAT: // 待设置的参数格式是浮点数
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%f", (float)pv.value.val_integer);
break;
case _PARSE_TYPE_STRING: // 待设置的参数格式是字符串
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%s", enum_value);
break;
default:
break;
}
}
break;
case _PARSE_TYPE_FLOAT: // 解析出的参数格式是浮点数
type_flag |= _TYPE_FLAG_FLOAT;
if (*match_key == NULL)
{
2025-02-13 17:17:07 +08:00
switch (s_attr_to_type_tbl[attr])
2024-03-28 12:19:52 +08:00
{
case _PARSE_TYPE_FLOAT: // 待设置的参数格式是浮点数
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%f", (float)pv.value.val_float);
break;
case _PARSE_TYPE_STRING: // 待设置的参数格式是字符串
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%s", enum_value);
break;
default:
break;
}
}
break;
case _PARSE_TYPE_STRING: // 解析出的参数格式是字符串
type_flag |= _TYPE_FLAG_STRING;
if (*match_key == NULL)
SYS_SNPRINT(key_value_str, sizeof(key_value_str), "%s", enum_value);
break;
default:
break;
}
if (*match_key == NULL)
{
if (strcmp(key_value_str, param_value_str) == 0)
{
*match_key = enum_key;
*match_value = enum_value;
}
}
if (print_list)
{
sh_echo(s_sh_hdl, "\t%s (%s)\r\n", enum_key, enum_value);
}
if (print_cp)
{
char key_cpy[0x100];
int len = 0;
for (len = 0; len < sizeof(key_cpy) - 2; len++)
{
key_cpy[len] = enum_key[len];
if (key_cpy[len] == '\0')
{
break;
}
}
key_cpy[len++] = ' ';
key_cpy[len] = '\0';
sh_completion_resource(s_sh_hdl, NULL, key_cpy, NULL);
}
token = strtok_r(NULL, ",", &save_token);
}
2025-02-13 17:17:07 +08:00
switch (s_attr_to_type_tbl[attr])
2024-03-28 12:19:52 +08:00
{
case _PARSE_TYPE_UNSIGNED: // 待设置的参数格式是无符号整型
{
if (type_flag & (_TYPE_FLAG_INTEGER | _TYPE_FLAG_FLOAT | _TYPE_FLAG_STRING))
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 包含非法的 value 类型\r\n");
return -1;
}
}
break;
case _PARSE_TYPE_INTEGER: // 待设置的参数格式是带符号整型
{
if (type_flag & (_TYPE_FLAG_FLOAT | _TYPE_FLAG_STRING))
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 包含非法的 value 类型\r\n");
return -1;
}
}
break;
case _PARSE_TYPE_FLOAT: // 待设置的参数格式是浮点数
{
if (type_flag & (_TYPE_FLAG_STRING))
{
sh_echo(s_sh_hdl, "ENUM_STR 格式错误, 包含非法的 value 类型\r\n");
return -1;
}
}
break;
default:
break;
}
return type_flag;
}