#ifndef _H_SHELL_LEX_ #define _H_SHELL_LEX_ #include 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_