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

235 lines
15 KiB
C
Raw Normal View History

2024-03-28 12:19:52 +08:00
/**
* @file sh_vset.h
* @author LokLiang
* @brief shell
* @version 0.1
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*
*
*
* -
* -
* -
* - 38
*
* 使
* 1. 使 vset_init() sh
* 2. 使
* - @b SET_VAR
* - @b SET_ENUM SET_VAR
* - @b SET_CP_ENUM SET_ENUM
* 3. ?
* 4.
* - @b PSET_FN const sh_vset_param_t*
* - @b PSET_CP const sh_vset_param_t*
*
* 1: SH_SETUP_CMD FUNC sh_vset_param_t::set_func
2025-02-13 17:17:07 +08:00
* static int _value_set_u8(const char *argv[]) { return SET_VAR(&var_u8, 1, 200); }
* static int _value_set_s16(const char *argv[]) { return SET_VAR(&var_s16, -1000, 1000); }
* static int _value_set_float(const char *argv[]) { return SET_VAR(&var_float, -1000, var_u8); }
* static int _value_set_str(const char *argv[]) { return SET_VAR(&var_str, 0, 0); }
* static int _value_set_enum(const char *argv[]) { return SET_ENUM(&var_s32, "enable=1,disable=0"); }
2024-03-28 12:19:52 +08:00
*
* 2: +
* static sh_vset_param_t const s_param_template[] = {
* {"--u8", "该选项的帮助信息", value_set_u8, NULL},
* {"--s16", "该选项的帮助信息", value_set_s16, NULL},
* {"--float", "该选项的帮助信息", value_set_float, NULL},
* {"--str", "该选项的帮助信息", value_set_str, NULL},
* {"--enum", "该选项的帮助信息", value_set_enum, "enable=1,disable=0"},
* static int _value_set(sh_t *sh_hdl, int argc, const char *argv[]) { PSET_FN(s_param_template); } // 这个函数可作为 SH_SETUP_CMD 中定义的 FUNC
* static void _value_cp(sh_t *sh_hdl, int argc, const char *argv[], bool flag) { PSET_CP(s_param_template); } // 这个函数可作为 SH_SETUP_CMD 中定义的 SUB
*
*/
#ifndef __SH_VSET_H__
#define __SH_VSET_H__
#include "sys_types.h"
#include "sh.h"
/* 描述支待的待设置变量的具体类型 */
typedef enum
{
__TYPE_ATTR_CHR,
__TYPE_ATTR_BOOL,
__TYPE_ATTR_U8,
__TYPE_ATTR_S8,
__TYPE_ATTR_U16,
__TYPE_ATTR_S16,
__TYPE_ATTR_U32,
__TYPE_ATTR_S32,
__TYPE_ATTR_U64,
__TYPE_ATTR_S64,
__TYPE_ATTR_FLOAT,
__TYPE_ATTR_DOUBLE,
__TYPE_ATTR_STR,
__TYPE_ATTR_OTHER,
} __type_attr_t;
/**
* @brief vset_cb
* 退
* @param new_value sh_vset __typeof()
*/
typedef void (*vset_cb)(sh_t *sh_hdl, void *new_value);
#define __GENERIC_ATTR(VAR) (__builtin_types_compatible_p(__typeof(VAR), char) ? __TYPE_ATTR_CHR \
: __builtin_types_compatible_p(__typeof(VAR), volatile char) ? __TYPE_ATTR_CHR \
: __builtin_types_compatible_p(__typeof(VAR), bool) ? __TYPE_ATTR_BOOL \
: __builtin_types_compatible_p(__typeof(VAR), volatile bool) ? __TYPE_ATTR_BOOL \
: __builtin_types_compatible_p(__typeof(VAR), uint8_t) ? __TYPE_ATTR_U8 \
: __builtin_types_compatible_p(__typeof(VAR), volatile uint8_t) ? __TYPE_ATTR_U8 \
: __builtin_types_compatible_p(__typeof(VAR), int8_t) ? __TYPE_ATTR_S8 \
: __builtin_types_compatible_p(__typeof(VAR), volatile int8_t) ? __TYPE_ATTR_S8 \
: __builtin_types_compatible_p(__typeof(VAR), uint16_t) ? __TYPE_ATTR_U16 \
: __builtin_types_compatible_p(__typeof(VAR), volatile uint16_t) ? __TYPE_ATTR_U16 \
: __builtin_types_compatible_p(__typeof(VAR), int16_t) ? __TYPE_ATTR_S16 \
: __builtin_types_compatible_p(__typeof(VAR), volatile int16_t) ? __TYPE_ATTR_S16 \
: __builtin_types_compatible_p(__typeof(VAR), uint32_t) ? __TYPE_ATTR_U32 \
: __builtin_types_compatible_p(__typeof(VAR), volatile uint32_t) ? __TYPE_ATTR_U32 \
: __builtin_types_compatible_p(__typeof(VAR), int32_t) ? __TYPE_ATTR_S32 \
: __builtin_types_compatible_p(__typeof(VAR), volatile int32_t) ? __TYPE_ATTR_S32 \
: __builtin_types_compatible_p(__typeof(VAR), uint64_t) ? __TYPE_ATTR_U64 \
: __builtin_types_compatible_p(__typeof(VAR), volatile uint64_t) ? __TYPE_ATTR_U64 \
: __builtin_types_compatible_p(__typeof(VAR), int64_t) ? __TYPE_ATTR_S64 \
: __builtin_types_compatible_p(__typeof(VAR), volatile int64_t) ? __TYPE_ATTR_S64 \
: __builtin_types_compatible_p(__typeof(VAR), float) ? __TYPE_ATTR_FLOAT \
: __builtin_types_compatible_p(__typeof(VAR), volatile float) ? __TYPE_ATTR_FLOAT \
: __builtin_types_compatible_p(__typeof(VAR), double) ? __TYPE_ATTR_DOUBLE \
: __builtin_types_compatible_p(__typeof(VAR), volatile double) ? __TYPE_ATTR_DOUBLE \
: __builtin_types_compatible_p(__typeof(VAR), char[]) ? __TYPE_ATTR_STR \
: __TYPE_ATTR_OTHER)
typedef int (*vset_var_fn)(const char *argv[]);
typedef struct // 用于长选项设置的描述结构
{
const char *option; // 选项,如 "--value"
const char *help; // 对该选项的描述
vset_var_fn set_func; // 与 option 对应的,使用宏 SET_VAR() 或 SET_ENUM() 设置变量的函数。如果值为 NULL 表示该选项无参数,同时对应的输入参数被保留
const char *enum_str; // 仅在类型为 vset_enum_fn 时有效,为对应的选项提供可选的补全参数选项,值为 NULL 或 "" 时默认候选参数为 '?'
} sh_vset_param_t;
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);
int vset_integer(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], signed int low, signed int high);
int vset_float(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], float low, float high);
int vset_str(void *dest, __type_attr_t attr, vset_cb cb, const char *argv[], unsigned bufsize);
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
void vset_cp_enum(int argc, bool flag, const char *enum_str);
int vset_option_set(sh_t *sh_hdl, int *argc, const char *argv[], const sh_vset_param_t *p, unsigned size);
bool vset_option_cp(sh_t *sh_hdl, int argc, const char *argv[], bool flag, const sh_vset_param_t *p, unsigned size);
/* 自动分析并设置变量的值,带设置回调 */
2025-02-13 17:17:07 +08:00
#define SET_VAR_CB(NAME, LOW, HIGH, CB) \
((__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_U8 || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_U16 || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_U32 || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_U64) \
? vset_unsigned(NAME, __GENERIC_ATTR(*(NAME)), CB, argv, LOW, HIGH) \
: ((__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_CHR || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_BOOL || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_S8 || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_S16 || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_S32 || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_S64) \
? vset_integer(NAME, __GENERIC_ATTR(*(NAME)), CB, argv, LOW, HIGH) \
: ((__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_FLOAT || \
__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_DOUBLE) \
? vset_float(NAME, __GENERIC_ATTR(*(NAME)), CB, argv, LOW, HIGH) \
: ((__GENERIC_ATTR(*(NAME)) == __TYPE_ATTR_STR) \
? vset_str(NAME, __GENERIC_ATTR(*(NAME)), CB, argv, sizeof(*(NAME))) \
: -1))))
2024-03-28 12:19:52 +08:00
/* 设置数据类型为 枚举型 的变量,带设置回调 */
#define SET_ENUM_CB(NAME, ENUM_STR, CB) \
2025-02-13 17:17:07 +08:00
(vset_enum(NAME, __GENERIC_ATTR(*(NAME)), CB, \
argv, ENUM_STR))
2024-03-28 12:19:52 +08:00
/* 自动分析并设置变量的值 */
#define SET_VAR(NAME, LOW, HIGH) SET_VAR_CB(NAME, LOW, HIGH, NULL)
/* 设置数据类型为 枚举型 的变量 */
#define SET_ENUM(NAME, ENUM_STR) SET_ENUM_CB(NAME, ENUM_STR, NULL)
/* 对应 SET_ENUM 所设置的变量的可用自动补全函数 */
#define SET_CP_ENUM(ENUM_STR) \
do \
{ \
vset_cp_enum(argc, flag, ENUM_STR); \
} while (0)
#define PSET_FN(OPT) vset_option_set(sh_hdl, &argc, argv, OPT, sizeof(OPT)) /* 作为 SH_CMD_FN() 的实际执行函数 */
#define PSET_CP(OPT) vset_option_cp(sh_hdl, argc, argv, flag, OPT, sizeof(OPT)) /* 作为 SH_CMD_CP_FN() 的实际执行函数 */
typedef void (*vset_global_cb)(sh_t *sh_hdl);
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
void vset_force_cb(void);
2025-02-13 17:17:07 +08:00
/**
* @note
*
* sh
*
*
* SET_VAR() SET_ENUM()
* 使
* - @b SET_VAR()
* - @b SET_ENUM()
* - @b SET_CP_ENUM()
* - @b PSET_FN()
* - @b PSET_CP()
*
* 使
* sh 使 SH_SETUP_CMD()
* -
* - bash Tab
* 使 SET_VAR() SET_ENUM()
* 使 SET_CP_ENUM()
*
*
* SET_VAR() SET_ENUM() SET_VAR()
* SET_VAR()
* SET_ENUM()
*
* SET_CP_ENUM()
* SET_ENUM()
*
* sh_hdl
* sh
*
*
* - SET_VAR() SET_ENUM()
* - SET_CP_ENUM()
* - 使
*
* 使 SET_VAR() SET_ENUM()
* sh_vset_param_t
*
* PSET_FN() PSET_CP()
* sh_vset_param_t
*
* - "--value"
* -
* - option 使 SET_VAR() SET_ENUM() NULL
* - vset_enum_fn NULL "" '?'
* 便: <> [ <>] [ <>] ...
*
*
* - 便使
*
*
* SET_VAR(), SET_ENUM() SET_CP_ENUM() 使 sh_vset_param_t 使
* PSET_FN() PSET_CP()
* sh_vset_param_t
*
*/
2024-03-28 12:19:52 +08:00
#endif