2021-01-09 17:52:11 +08:00
|
|
|
/**
|
|
|
|
* @file shell_cpp.h
|
|
|
|
* @author Letter (nevermindzzt@gmail.com)
|
|
|
|
* @brief shell cpp support
|
|
|
|
* @version 1.0.0
|
|
|
|
* @date 2021-01-09
|
|
|
|
*
|
|
|
|
* @copyright (c) 2021 Letter
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#ifndef __SHELL_CPP_H__
|
|
|
|
#define __SHELL_CPP_H__
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
#include "shell.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief shell command cpp 支持 cmd 定义
|
|
|
|
*/
|
|
|
|
typedef struct shell_command_cpp_cmd
|
|
|
|
{
|
|
|
|
int attr; /**< 属性 */
|
|
|
|
const char *name; /**< 命令名 */
|
|
|
|
int (*function)(); /**< 命令执行函数 */
|
|
|
|
const char *desc; /**< 命令描述 */
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
#if SHELL_USING_FUNC_SIGNATURE == 1
|
|
|
|
const char *signature; /**< 函数签名 */
|
|
|
|
#endif
|
2021-01-09 17:52:11 +08:00
|
|
|
} ShellCommandCppCmd;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief shell command cpp 支持 var 定义
|
|
|
|
*/
|
|
|
|
typedef struct shell_command_cpp_var
|
|
|
|
{
|
|
|
|
int attr; /**< 属性 */
|
|
|
|
const char *name; /**< 变量名 */
|
|
|
|
void *value; /**< 变量值 */
|
|
|
|
const char *desc; /**< 变量描述 */
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
#if SHELL_USING_FUNC_SIGNATURE == 1
|
|
|
|
void *unused; /**< 未使用成员,需要保持和 ShellCommandCppCmd 大小一致 */
|
|
|
|
#endif
|
2021-01-09 17:52:11 +08:00
|
|
|
} ShellCommandCppVar;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief shell command cpp 支持 user 定义
|
|
|
|
*/
|
|
|
|
typedef struct shell_command_cpp_user
|
|
|
|
{
|
|
|
|
int attr; /**< 属性 */
|
|
|
|
const char *name; /**< 用户名 */
|
|
|
|
const char *password; /**< 用户密码 */
|
|
|
|
const char *desc; /**< 用户描述 */
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
#if SHELL_USING_FUNC_SIGNATURE == 1
|
|
|
|
void *unused; /**< 未使用成员,需要保持和 ShellCommandCppCmd 大小一致 */
|
|
|
|
#endif
|
2021-01-09 17:52:11 +08:00
|
|
|
} ShellCommandCppUser;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief shell command cpp 支持 key 定义
|
|
|
|
*/
|
|
|
|
typedef struct shell_command_cpp_key
|
|
|
|
{
|
|
|
|
int attr; /**< 属性 */
|
|
|
|
int value; /**< 按键键值 */
|
|
|
|
void (*function)(Shell *); /**< 按键执行函数 */
|
|
|
|
const char *desc; /**< 按键描述 */
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
#if SHELL_USING_FUNC_SIGNATURE == 1
|
|
|
|
void *unused; /**< 未使用成员,需要保持和 ShellCommandCppCmd 大小一致 */
|
|
|
|
#endif
|
2021-01-09 17:52:11 +08:00
|
|
|
} ShellCommandCppKey;
|
|
|
|
|
2023-04-16 17:18:38 +08:00
|
|
|
#if SHELL_USING_FUNC_SIGNATURE == 1
|
|
|
|
typedef struct shell_command_cpp_param_parser
|
|
|
|
{
|
|
|
|
int attr; /**< 属性 */
|
|
|
|
const char *type; /**< 参数类型 */
|
2023-04-22 07:50:25 +00:00
|
|
|
int (*parser)(char *, void **);; /**< 解析函数 */
|
|
|
|
int (*cleaner)(void *); /**< 清理函数 */
|
|
|
|
void *unsed; /**< 未使用成员,需要保持和 ShellCommandCppCmd 大小一致 */
|
2023-04-16 17:18:38 +08:00
|
|
|
} ShellCommandCppParamParser;
|
|
|
|
#endif
|
|
|
|
|
2021-01-09 17:52:11 +08:00
|
|
|
#if SHELL_USING_CMD_EXPORT == 1
|
|
|
|
|
|
|
|
#undef SHELL_EXPORT_CMD
|
|
|
|
/**
|
|
|
|
* @brief shell 命令定义
|
|
|
|
*
|
|
|
|
* @param _attr 命令属性
|
|
|
|
* @param _name 命令名
|
|
|
|
* @param _func 命令函数
|
|
|
|
* @param _desc 命令描述
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
* @param ... 其他参数
|
2021-01-09 17:52:11 +08:00
|
|
|
*/
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc, ...) \
|
2021-01-09 17:52:11 +08:00
|
|
|
const char shellCmd##_name[] = #_name; \
|
|
|
|
const char shellDesc##_name[] = #_desc; \
|
2021-05-09 13:43:59 +08:00
|
|
|
extern "C" SHELL_USED const ShellCommandCppCmd \
|
|
|
|
shellCommand##_name SHELL_SECTION("shellCommand") = \
|
2021-01-09 17:52:11 +08:00
|
|
|
{ \
|
|
|
|
_attr, \
|
|
|
|
shellCmd##_name, \
|
|
|
|
(int (*)())_func, \
|
新增 函数签名
## 函数签名
之前的版本里,如果声明的命令是 `SHELL_TYPE_CMD_FUNC`,shell 会自动进行参数的转换,但是参数转换后的类型是猜出来的,无法保证转换后的数据类型是正确的,一旦猜错了,就容易导致程序挂掉
由此,借鉴 Java 等语言的函数签名,新版也引入了函数签名的概念,在声明命令时,可以给定最终执行命令的函数的签名,shell 根据这个签名进行参数转换,使用此功能时,需要打开宏 `SHELL_USING_FUNC_SIGNATURE`
函数签名是一个字符串,通过这个字符串声明表达函数的参数类型,返回值不声明,比如一个函数`int func(int a, char *b, char c)`,它的函数签名就是 `ics`
基本类型的参数签名定义如下:
| 类型 | 签名 |
| -------------------- | ---- |
| char(字符) | c |
| int/short/char(数字) | i |
| char * (字符串) | s |
| pointer | p |
声明命令时,在最后添加一个参数 `.data.cmd.signature = "ics"` 即可,比如:
```c
void shellFuncSignatureTest(int a, char *b, char c)
{
printf("a = %d, b = %s, c = %c\r\n", a, b, c);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
funcSignatureTest, shellFuncSignatureTest, test function signature, .data.cmd.signature = "isc");
```
2023-04-15 16:30:44 +08:00
|
|
|
shellDesc##_name, \
|
|
|
|
##__VA_ARGS__ \
|
2021-01-09 17:52:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#undef SHELL_EXPORT_VAR
|
|
|
|
/**
|
|
|
|
* @brief shell 变量定义
|
|
|
|
*
|
|
|
|
* @param _attr 变量属性
|
|
|
|
* @param _name 变量名
|
|
|
|
* @param _value 变量值
|
|
|
|
* @param _desc 变量描述
|
|
|
|
*/
|
|
|
|
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
|
|
|
|
const char shellCmd##_name[] = #_name; \
|
|
|
|
const char shellDesc##_name[] = #_desc; \
|
2021-05-09 13:43:59 +08:00
|
|
|
extern "C" SHELL_USED const ShellCommandCppVar \
|
|
|
|
shellVar##_name SHELL_SECTION("shellCommand") = \
|
2021-01-09 17:52:11 +08:00
|
|
|
{ \
|
|
|
|
_attr, \
|
|
|
|
shellCmd##_name, \
|
|
|
|
(void *)_value, \
|
|
|
|
shellDesc##_name \
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef SHELL_EXPORT_USER
|
|
|
|
/**
|
|
|
|
* @brief shell 用户定义
|
|
|
|
*
|
|
|
|
* @param _attr 用户属性
|
|
|
|
* @param _name 用户名
|
|
|
|
* @param _password 用户密码
|
|
|
|
* @param _desc 用户描述
|
|
|
|
*/
|
|
|
|
#define SHELL_EXPORT_USER(_attr, _name, _password, _desc) \
|
|
|
|
const char shellCmd##_name[] = #_name; \
|
|
|
|
const char shellPassword##_name[] = #_password; \
|
|
|
|
const char shellDesc##_name[] = #_desc; \
|
2021-05-09 13:43:59 +08:00
|
|
|
extern "C" SHELL_USED const ShellCommandCppUser \
|
|
|
|
shellUser##_name SHELL_SECTION("shellCommand") = \
|
2021-01-09 17:52:11 +08:00
|
|
|
{ \
|
|
|
|
_attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
|
|
|
shellCmd##_name, \
|
|
|
|
shellPassword##_name, \
|
|
|
|
shellDesc##_name \
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef SHELL_EXPORT_KEY
|
|
|
|
/**
|
|
|
|
* @brief shell 按键定义
|
|
|
|
*
|
|
|
|
* @param _attr 按键属性
|
|
|
|
* @param _value 按键键值
|
|
|
|
* @param _func 按键函数
|
|
|
|
* @param _desc 按键描述
|
|
|
|
*/
|
|
|
|
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
|
|
|
|
const char shellDesc##_value[] = #_desc; \
|
2021-05-09 13:43:59 +08:00
|
|
|
extern "C" SHELL_USED const ShellCommandCppKey \
|
|
|
|
shellKey##_value SHELL_SECTION("shellCommand") = \
|
2021-05-24 15:51:59 +08:00
|
|
|
{ \
|
2021-01-09 17:52:11 +08:00
|
|
|
_attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
|
|
|
_value, \
|
|
|
|
(void (*)(Shell *))_func, \
|
|
|
|
shellDesc##_value \
|
|
|
|
}
|
2023-04-16 17:18:38 +08:00
|
|
|
|
|
|
|
#if SHELL_USING_FUNC_SIGNATURE == 1
|
2023-04-22 07:50:25 +00:00
|
|
|
#undef SHELL_EXPORT_PARAM_PARSER
|
2023-04-16 17:18:38 +08:00
|
|
|
/**
|
|
|
|
* @brief shell 参数解析器定义
|
|
|
|
*
|
|
|
|
* @param _attr 参数解析器属性
|
|
|
|
* @param _type 参数解析器类型
|
2023-04-22 07:50:25 +00:00
|
|
|
* @param _parser 参数解析器函数
|
|
|
|
* @param _cleaner 参数清理函数
|
2023-04-16 17:18:38 +08:00
|
|
|
*/
|
2023-04-22 07:50:25 +00:00
|
|
|
#define SHELL_EXPORT_PARAM_PARSER(_attr, _type, _parser, _cleaner) \
|
|
|
|
const char shellDesc##_parser[] = #_type; \
|
2023-04-16 17:18:38 +08:00
|
|
|
extern "C" SHELL_USED const ShellCommandCppParamParser \
|
2023-04-22 07:50:25 +00:00
|
|
|
shellCommand##_parser SHELL_SECTION("shellCommand") = \
|
2023-04-16 17:18:38 +08:00
|
|
|
{ \
|
|
|
|
_attr|SHELL_CMD_TYPE(SHELL_TYPE_PARAM_PARSER), \
|
2023-04-22 07:50:25 +00:00
|
|
|
shellDesc##_parser, \
|
|
|
|
(int (*)(char *, void **))_parser, \
|
|
|
|
(int (*)(void *))_cleaner \
|
2023-04-16 17:18:38 +08:00
|
|
|
}
|
|
|
|
#endif
|
2021-01-09 17:52:11 +08:00
|
|
|
#endif /** SHELL_USING_CMD_EXPORT == 1 */
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif /**< defined __cplusplus */
|
|
|
|
|
|
|
|
#endif /**< __SHELL_CPP_H__ */
|