HCoreBase/include/HShellLex.h

153 lines
4.9 KiB
C

#ifndef _H_SHELL_LEX_
#define _H_SHELL_LEX_
#include <stdint.h>
typedef uint8_t HShellLenType;
#define HSHELL_ERROR_INDEX (0xff)
// 是否使用密码
#define HSHELL_USE_PASSWORD
#define HSHELL_USER "hdroot"
#define HSHELL_PASSWORD "hd456321;"
// 是否使用上一次缓存
#define HSHELL_USE_BACK_BUFFER
#ifdef HSHELL_USE_BACK_BUFFER
#endif
///< 可配置最多可注册回调多少个
#ifndef HSHELL_CALL_MAX
#define HSHELL_CALL_MAX 5
#endif
///< 命令行缓存长度
#ifndef HSHELL_CMD_LINE_BUFFER
#define HSHELL_CMD_LINE_BUFFER 32
#endif
///< 解析token参数的最大个数
#ifndef HSHELL_CMD_TOKEN_MAX
#define HSHELL_CMD_TOKEN_MAX 4
#endif
///< 打印帮助命令行长度多少换行
#ifndef HSHELL_CMD_LINE_NUM
#define HSHELL_CMD_LINE_NUM 80
#endif
///< 使用专门接口避免日志系统关闭日志打印导致命令不输出的问题
#define HSHELL_PRINTFL(format, ...) printf(format "\r\n", ##__VA_ARGS__)
#define HSHELL_PRINTF(format, ...) printf(format, ##__VA_ARGS__)
///< 回调参数固定格式
#define HSHELL_FUNC_ARGS HShellLenType key, const HShellCmdToken *tokens, int tokensLen
///< 命令行参数, 需要使用上面的宏的同名参数
#define HSHELL_ARGS_GET_UINT(index, result) \
if (HSHellToUint32(tokens, tokensLen, index, &result) == 0) { HSHELL_PRINTFL("args error, index[%d], len[%d]", index, tokensLen); return ; }
///< 处理命令行token
typedef struct __attribute__ ((__packed__)) HShellCmdToken
{
const uint8_t* str; ///< 指向每项数据开头, 如 echo 123 会有2个token, 一个str指向echo, 一个str指向123
uint8_t len; ///< 数据长度
} HShellCmdToken;
// 匹配映射表初始化每项的辅助宏
#define HSHELL_MATCH_ITEM(token, str) {token, sizeof(str) - 1, (const uint8_t *)str}
///< 匹配映射表
typedef struct __attribute__ ((__packed__)) HShellMatch
{
HShellLenType token; ///< 匹配后对应的映射值
uint8_t matchLen; ///< 需要匹配的字符串长度
const uint8_t *match; ///< 需要匹配的字符串
} HShellMatch;
/**
* @brief 命令行解析回调
* @param key 命令行解析的首个token
* @param tokens 原始token, 可自行处理后续命令的所需的参数
* @param tokensLen 原始token个数
**/
typedef void (*shellCall)(HShellLenType key, const HShellCmdToken *tokens, int tokensLen);
/**
* @brief 解析命令行数据, 将解析后的数据写入tokens, 内存还是str, tokens是指向tokens的指针
* @brief str 命令行数据
* @brief strLen 命令行数据长度
* @brief tokens 命令行解析后写入的token
* @brief tokensLen toknes长度
* @return 返回token个数
**/
uint8_t HShellLex(const uint8_t *str, int strLen, HShellCmdToken *tokens, int tokensLen);
/**
* @brief 查找token匹配对应token枚举值, 判断是否忽略大小写
* @param token 命令行解析的token
* @param matches 匹配映射表
* @param matchLen 匹配映射表个数
* @param ignoreCase 是否忽略大小写
* @return 返回对应token映射值, 如果不存在返回 HSHELL_ERROR_INDEX
**/
HShellLenType HShellMatchToken(const HShellCmdToken *token, const HShellMatch *matches, int matchLen, uint8_t ignoreCase);
/**
* @brief 查找token匹配字符串, 判断是否忽略大小写
* @param token 命令行解析的token
* @param tokenLen 命令行解析的token个数
* @param index 命令行解析的token索引
* @param str 需要匹配的字符串
* @param strLen 需要匹配的字符串长度
* @param ignoreCase 是否忽略大小写
* @return 返回是否匹配成功, 1成功, 0失败
**/
uint8_t HShellDiffString(const HShellCmdToken *token, uint8_t tokenLen, uint8_t index, const char *str, uint8_t strLen, uint8_t ignoreCase);
/**
* @brief 将参数转换为uint32
* @param token 命令行解析的token
* @param index 命令行解析的token索引
* @param value 转换后的uint32值
* @return 返回是否转换成功, 1成功, 0失败
**/
uint8_t HSHellToUint32(const HShellCmdToken *token, uint8_t tokenLen, uint8_t index, uint32_t *value);
/**
* @brief 注册命令行解析回调, 如果存在匹配映射表则覆盖原有映射
* @param matches 匹配映射表
* @param matchLen 匹配映射表个数
* @param call 命令行解析回调
* @param ignoreCase 是否忽略大小写
* @return 返回注册的索引, 错误返回 -1
**/
int16_t HSHellRegister(const HShellMatch *matches, int matchLen, shellCall call, uint8_t ignoreCase);
/**
* @brief 注销命令行解析回调
* @param index 注销的索引
**/
void HSHellUnregister(int16_t index);
/**
* @brief 添加命令行数据, 直到直到换行将停止添加, 到HShellRun处理后恢复继续添加
* @param str 命令行数据
* @param strLen 命令行数据长度
**/
void HShellAddCmdData(uint8_t data);
void HSHellAddCmdDatas(const uint8_t *data, int len);
/**
* @brief 处理命令行数据, 因添加数据在中断, 执行需在非中断执行
**/
void HShellRun();
#endif // _H_SHELL_LEX_