From 8631a84333c4bba47ab21490405f4398b8f04ee7 Mon Sep 17 00:00:00 2001 From: coffee Date: Wed, 4 Jun 2025 15:50:21 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=9B=B4=E6=96=B0=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=A1=8C=202.=20=E6=9B=B4=E6=96=B0=E9=A1=B5=E9=9D=A2=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HShellLex.h | 50 ++++- include/HUIPageManage.h | 23 +- src/HShellLex.c | 474 ++++++++++++++++++++++++++++------------ src/HUIPageManage.c | 28 +-- 4 files changed, 412 insertions(+), 163 deletions(-) diff --git a/include/HShellLex.h b/include/HShellLex.h index df6ed37..19420ac 100644 --- a/include/HShellLex.h +++ b/include/HShellLex.h @@ -10,6 +10,9 @@ typedef uint8_t HShellLenType; #define HSHELL_ERROR_INDEX (0xff) +// 是否使用密码 +#define HSHELL_USE_PASSWORD + ///< 可配置最多可注册回调多少个 #ifndef HSHELL_CALL_MAX #define HSHELL_CALL_MAX 5 @@ -22,12 +25,24 @@ typedef uint8_t HShellLenType; ///< 解析token参数的最大个数 #ifndef HSHELL_CMD_TOKEN_MAX -#define HSHELL_CMD_TOKEN_MAX 5 +#define HSHELL_CMD_TOKEN_MAX 3 +#endif + +///< 打印帮助命令行长度多少换行 +#ifndef HSHELL_CMD_LINE_NUM +#define HSHELL_CMD_LINE_NUM 80 #endif ///< 使用专门接口避免日志系统关闭日志打印导致命令不输出的问题 -#define HSHELL_PRINTF(format, ...) printf(format, ##__VA_ARGS__) +#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 @@ -76,6 +91,27 @@ uint8_t HShellLex(const uint8_t *str, int strLen, HShellCmdToken *tokens, int to **/ 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 匹配映射表 @@ -93,11 +129,17 @@ int16_t HSHellRegister(const HShellMatch *matches, int matchLen, shellCall call, void HSHellUnregister(int16_t index); /** - * @brief 添加命令行数据, 直到换行'\n'才处理 + * @brief 添加命令行数据, 直到直到换行将停止添加, 到HShellRun处理后恢复继续添加 * @param str 命令行数据 * @param strLen 命令行数据长度 **/ void HShellAddCmdData(uint8_t data); -void HSHellAddCmdDatas(uint8_t *data, int len); +void HSHellAddCmdDatas(const uint8_t *data, int len); + +/** + * @brief 处理命令行数据, 因添加数据在中断, 执行需在非中断执行 + **/ +void HShellRun(); + #endif // _H_SHELL_LEX_ diff --git a/include/HUIPageManage.h b/include/HUIPageManage.h index df69fb0..2cca266 100644 --- a/include/HUIPageManage.h +++ b/include/HUIPageManage.h @@ -48,9 +48,10 @@ #define UIPAGE_SHOW_HIDE_FUNC(show, hide) UIPAGE_SHOW_FUNC(show); UIPAGE_HIDE_FUNC(hide) // 对应事件的data转换具体类型宏 -#define UI_CALL_INDEX_TYPE(value) ((enum eUIPage *)value) +#define UI_CALL_INDEX_TYPE(value) ((HUiPageIndex_t *)value) /** ================================================================= */ +typedef uint8_t HUiPageIndex_t; // hide -> free -> update Page -> init -> show // 或者非返回时如下, 此时的hide和index事件都可存储该页面索引: @@ -62,7 +63,7 @@ enum eCallCmd kCallShowPage, ///< 显示页面 kCallHidePage, ///< 退出页面, 此事件如果是返回触发的可以存储索引数据 kCallSwitchPage, ///< 切换页面, 对应页面返回false时则不切换, 所有切换都会触发这个事件 - kCallIndexSave, ///< 存储当前索引事件, 通知此事件说明当前不是返回事件(cmd, enum eUIPage *nextPage, 1); + kCallIndexSave, ///< 存储当前索引事件, 通知此事件说明当前不是返回事件(cmd, HUiPageIndex_t *nextPage, 1); }; @@ -70,7 +71,7 @@ enum eCallCmd typedef enum eUIPage { - kUIPageMax, ///< ui最大个数, 不超过254个页面, 如超过则需要修改字节栈类型 + kUIPageMax = 4, ///< ui最大个数, 不超过254个页面, 如超过则需要修改字节栈类型 } eUIPage; ///< cmd命令, data数据, len数据长度 @@ -81,11 +82,11 @@ typedef void (*initPageType_t)(pageCallType_t *call); void HUIPageInit(initPageType_t initPage); // 设置主页, 切换到主页清空返回栈, 如果返回栈为空时, 当前页面不是主页, 则切换到主页 -void HUIPageSetHome(enum eUIPage page); +void HUIPageSetHome(HUiPageIndex_t page); // 切换页面, 当前页面入栈, 相同页面不操作, 需要检查栈, 栈存在就回栈清空之后的, 不存在就压栈 // 因为有些页面可能不用HUIPageBack来返回, 所以需要兼容这种情况 -void HUIPageSwitch(enum eUIPage page); +void HUIPageSwitch(HUiPageIndex_t page); // 切换到主页 void HUIPageSwitchHome(); @@ -119,13 +120,13 @@ void HUIPageResetCurrFree(); uint8_t HUIPageGetCurrNotFree(); // 设置指定页面不释放内存 -void HUIPageSetNotFree(enum eUIPage page); +void HUIPageSetNotFree(HUiPageIndex_t page); // 恢复指定页面默认释放内存 -void HUIPageResetFree(enum eUIPage page); +void HUIPageResetFree(HUiPageIndex_t page); // 获取指定页面是否不释放, 是返回1, 否则返回0 -uint8_t HUIPageGetNotFree(enum eUIPage page); +uint8_t HUIPageGetNotFree(HUiPageIndex_t page); // 设置用户数据, 在 kCallShowPage 和 kCallHidePage 都可调用, 但每次切换这些事件后都会重置数据为0 void HUIPageSetUserData(long userData); @@ -140,10 +141,10 @@ uint8_t HUIPageSaveIndex(uint8_t value); uint8_t HUIPageGetIndex(); // 获取当前页面 -enum eUIPage HUIPageGetCurrPage(); +HUiPageIndex_t HUIPageGetCurrPage(); // 获取上一个页面 -enum eUIPage HUIPageGetPrevPage(); +HUiPageIndex_t HUIPageGetPrevPage(); // 获取返回栈使用长度 uint8_t HUIPageGetStackLen(); @@ -155,7 +156,7 @@ uint8_t HUIPageGetIndexStackLen(); uint8_t HUIPageIsBack(); // 检查该页面是否在返回栈, 是返回1, 否则返回0 -uint8_t HUIPageFindStack(enum eUIPage page); +uint8_t HUIPageFindStack(HUiPageIndex_t page); #endif //__H_UI_PAGE_MANAGE_H__ diff --git a/src/HShellLex.c b/src/HShellLex.c index 67f962f..6f76597 100644 --- a/src/HShellLex.c +++ b/src/HShellLex.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -10,7 +11,7 @@ #ifndef LogD #if 0 #include -#define LogD(format, ...) printf("[%s:%s:%d]" format "\r\n", __FILE_NAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define LogD(format, ...) printf("[%s:%s:%d]" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define LogD(...) #endif @@ -20,23 +21,267 @@ #define CTRL_KEY(k) ((k) & 0x1f) -struct __attribute__((packed)) HShellCmd { +typedef struct __attribute__((packed)) ShellCmd { const HShellMatch *match; ///< 匹配表 shellCall call; ///< 回调 - uint8_t matchLen; ///< 匹配表长度 - uint8_t ignoreCase : 1; ///< 忽略大小写 + uint8_t matchLen : 7; ///< 匹配表长度 + uint8_t ignoreCase : 1; ///< 忽略大小写 +} ShellCmd; + +struct __attribute__((packed)) ShellInfo { + ShellCmd shellCmd[HSHELL_CALL_MAX]; ///< 回调注册表 + HShellCmdToken cmdTokens[HSHELL_CMD_TOKEN_MAX]; ///< 解析参数 + uint8_t cursorPos; ///< 光标位置 + uint8_t escStatus : 3; ///< ESC转义状态, 最多7状态 + uint8_t run : 1; ///< 可执行, 当前不能继续加入缓存区 + uint8_t needPrint : 1; ///< 需要重绘当前行 + uint8_t password : 1; ///< 密码模式 + uint8_t userName : 1; ///< 用户名是否正确 }; -// 回调注册 -static struct HShellCmd shellCmd_[HSHELL_CALL_MAX]; -// 命令行数据 +// 命令行缓存数据 static HVECTOR_DEFINE(cmdBuffer_, HSHELL_CMD_LINE_BUFFER); -// 解析参数 -static HShellCmdToken cmdTokens_[HSHELL_CMD_TOKEN_MAX]; -// 光标位置 -static uint8_t cursorPos; +static struct ShellInfo shellInfo_; +static void PrintAllCmd() { + uint16_t len = 0; + for (int i = 0; i < HSHELL_CALL_MAX; ++i) { + if (shellInfo_.shellCmd[i].match == NULL) { + continue; + } + + for (int j = 0; j < shellInfo_.shellCmd[i].matchLen; ++j) { + if (shellInfo_.shellCmd[i].matchLen <= 0) { + continue; + } + + HSHELL_PRINTF("%s\t", (const char *)shellInfo_.shellCmd[i].match[j].match); + len += shellInfo_.shellCmd[i].match[j].matchLen; + if (len >= HSHELL_CMD_LINE_NUM) { + HSHELL_PRINTF("\r\n"); + len = 0; + } + } + } + + if (len > 0) { + HSHELL_PRINTF("\r\n"); + } +} + +static void ShellParse() +{ + if (HVectorEmpty(cmdBuffer_)) { + return ; + } + + uint8_t len = HShellLex((const uint8_t *)HVectorGetByteDataPtr(cmdBuffer_, 0), HVectorGetUseByteLen(cmdBuffer_), shellInfo_.cmdTokens, HSHELL_CMD_TOKEN_MAX); + if (len <= 0) { + LogD("lex parse len[%d] empty", len); + return ; + } + +#ifdef HSHELL_USE_PASSWORD + if (shellInfo_.password == 0 || shellInfo_.userName == 0) { + shellInfo_.needPrint = 1; + + // 这个状态下说明用户名输入错误, 无论输入什么都是失败 + if (shellInfo_.password == 1 && shellInfo_.userName == 0) { + shellInfo_.password = 0; + return ; + } + + // 输入用户名 + if (shellInfo_.userName == 0) { + if (HShellDiffString(shellInfo_.cmdTokens, len, 0, "hdroot", 6, 0) == 0) { + // 用户名错误, 给输入假的密码机会 + shellInfo_.password = 1; + return ; + } + + shellInfo_.userName = 1; + return ; + } + + if (shellInfo_.password == 0) { + if (HShellDiffString(shellInfo_.cmdTokens, len, 0, "hd123", 5, 0) == 0) { + shellInfo_.userName = 0; + return ; + } + + shellInfo_.password = 1; + return ; + } + } +#endif + + if (shellInfo_.cmdTokens[0].len == 1 && shellInfo_.cmdTokens[0].str[0] == '?') { + PrintAllCmd(); + return ; + } + + for (int i = 0; i < HSHELL_CALL_MAX; ++i) { + if (shellInfo_.shellCmd[i].match == NULL) { + continue; + } + + HShellLenType key = HShellMatchToken(shellInfo_.cmdTokens, shellInfo_.shellCmd[i].match, shellInfo_.shellCmd[i].matchLen, shellInfo_.shellCmd[i].ignoreCase); + if (key != HSHELL_ERROR_INDEX) { + shellInfo_.shellCmd[i].call(key, shellInfo_.cmdTokens, len); + return ; + } + } +} + +static void PrintCmdLine() { + HVectorLenType len = HVectorGetUseLen(cmdBuffer_); + HVectorSetData(cmdBuffer_, len, '\0'); + HSHELL_PRINTF("\r\033[K\033[1;32m > "); +#ifdef HSHELL_USE_PASSWORD + if (shellInfo_.password == 0 || shellInfo_.userName == 0) { + // 用户已经输入 + if (shellInfo_.password == 1 && shellInfo_.userName == 0) { + HSHELL_PRINTF("password: \033[0m"); + fflush(stdout); + return ; + } + + // 输入用户名 + if (shellInfo_.userName == 0) { + HSHELL_PRINTF("username: %s\033[0m", (const char *)HVectorGetByteDataPtr(cmdBuffer_, 0)); + if (shellInfo_.cursorPos < len) { + HSHELL_PRINTF("\033[%dD", len - shellInfo_.cursorPos); + } + } else if (shellInfo_.password == 0) { + HSHELL_PRINTF("password: \033[0m"); + } + + fflush(stdout); + return ; + } +#endif + + HSHELL_PRINTF("%s\033[0m", (const char *)HVectorGetByteDataPtr(cmdBuffer_, 0)); + if (shellInfo_.cursorPos < len) { + HSHELL_PRINTF("\033[%dD", len - shellInfo_.cursorPos); + } + + fflush(stdout); +} + +static void DeleteBeginByte() { + if (shellInfo_.cursorPos <= 0) { + return ; + } + + HVectorRemoveData(cmdBuffer_, shellInfo_.cursorPos - 1, 1); + --shellInfo_.cursorPos; + shellInfo_.needPrint = 1; +} + +static void DeleteAfterByte() { + if (shellInfo_.cursorPos <= 0) { + return ; + } + + if (shellInfo_.cursorPos >= HVectorGetUseLen(cmdBuffer_)) { + return ; + } + + HVectorRemoveData(cmdBuffer_, shellInfo_.cursorPos, 1); + shellInfo_.needPrint = 1; +} + + +static void AddCmdData(uint8_t data) { + enum eEscStaus { + kEscNone, + kEsc, + kEscCsi, + kEscCsiDel, + }; + + if (shellInfo_.run) { + return ; + } + + switch (shellInfo_.escStatus) { + case kEsc: { + if (data == '[') { + shellInfo_.escStatus = kEscCsi; + return ; + } + } break; + case kEscCsi: { + switch (data) { + case 'D': { + // 左键 + if (shellInfo_.cursorPos > 0) { + --shellInfo_.cursorPos; + } + + shellInfo_.needPrint = 1; + shellInfo_.escStatus = kEscNone; + } return ; + case 'C': { + // 右键 + if (shellInfo_.cursorPos < HVectorGetUseLen(cmdBuffer_)) { + ++shellInfo_.cursorPos; + } + + shellInfo_.needPrint = 1; + shellInfo_.escStatus = kEscNone; + } return ; + case 'A': // 上键 + case 'B': // 下键 + shellInfo_.escStatus = kEscNone; + return ; + case '3': { + shellInfo_.escStatus = kEscCsiDel; + } return ; + default: break; + } + } break; + case kEscCsiDel: { + shellInfo_.escStatus = kEscNone; + if (data == '~') { + DeleteAfterByte(); + return ; + } + } break; + default: break; + } + + shellInfo_.escStatus = kEscNone; + switch (data) { + case 0x1b: shellInfo_.escStatus = kEsc; return ; + case '\t': return ; + case '\r': + case '\n': { + shellInfo_.run = 1; + } return ; + case '\b': + case 0x7f: { + DeleteBeginByte(); + } return ; + default: break; + } + + if (isprint(data) == 0) { + LogD("not print char[%x]", data); + return ; + } + + if (HVectorInsertData(cmdBuffer_, shellInfo_.cursorPos, data) == 0) { + LogD("buffer is full"); + return ; + } + + shellInfo_.cursorPos++; + shellInfo_.needPrint = 1; +} + uint8_t HShellLex(const uint8_t *str, int strLen, HShellCmdToken *tokens, int tokensLen) { if (str == NULL || tokens == NULL || tokensLen <= 0) { LogD("str[%p] is nullptr or Tokens[%p] is nullptr or len[%d]", str, tokens, tokensLen); @@ -91,6 +336,51 @@ HShellLenType HShellMatchToken(const HShellCmdToken *token, const HShellMatch *m return HSHELL_ERROR_INDEX; } +uint8_t HShellDiffString(const HShellCmdToken *token, uint8_t tokenLen, uint8_t index, const char *str, uint8_t strLen, uint8_t ignoreCase) { + if (token == NULL || tokenLen <= 0 || index >= tokenLen || str == NULL || strLen <= 0) { + LogD("token[%p] or tokenLen[%d] or index[%d] or str[%p] or strLen[%d] is nullptr", token, tokenLen, index, str, strLen); + return 0; + } + + if (token[index].str == NULL || token[index].len == 0) { + LogD("token[%d] is empty or str[%p] is nullptr", index, token[index].str); + return 0; + } + + if (token[index].len != strLen) { + return 0; + } + + int (*cmpFunc)(const char *, const char *, size_t) = ignoreCase ? strncasecmp : strncmp; + return cmpFunc((const char *)token[index].str, str, strLen) == 0 ? 1 : 0; +} + +uint8_t HSHellToUint32(const HShellCmdToken *token, uint8_t tokenLen, uint8_t index, uint32_t *value) { + if (token == NULL || tokenLen <= 0 || value == NULL) { + LogD("token[%p] or tokenLen[%d] or value[%p] is nullptr", token, tokenLen, value); + return 0; + } + + if (index >= tokenLen) { + LogD("index[%d] is out of range", index); + return 0; + } + + if (token[index].str == NULL || token[index].len == 0) { + LogD("token[%d] is empty or str[%p] is nullptr", index, token[index].str); + return 0; + } + + char *endPtr = NULL; + *value = strtol((const char *)token[index].str, &endPtr, 0); + if (endPtr == (const char *)token[index].str || *endPtr != '\0') { + LogD("token[%d] is not uint32", index); + return 0; + } + + return 1; +} + int16_t HSHellRegister(const HShellMatch *matches, int matchLen, shellCall call, uint8_t ignoreCase) { if (matches == NULL || matchLen <= 0 || call == NULL) { LogD("matches[%p] or matchLen[%d] or call[%p] is nullptr", matches, matchLen, call); @@ -98,19 +388,19 @@ int16_t HSHellRegister(const HShellMatch *matches, int matchLen, shellCall call, } for (int i = 0; i < HSHELL_CALL_MAX; ++i) { - if (shellCmd_[i].match == matches) { + if (shellInfo_.shellCmd[i].match == matches) { LogD("call[%p] is exist, override write index[%d]", call, i); - shellCmd_[i].call = call; - shellCmd_[i].matchLen = matchLen; - shellCmd_[i].ignoreCase = ignoreCase ? 1 : 0; + shellInfo_.shellCmd[i].call = call; + shellInfo_.shellCmd[i].matchLen = matchLen; + shellInfo_.shellCmd[i].ignoreCase = ignoreCase ? 1 : 0; return i; } - if (shellCmd_[i].match == NULL) { - shellCmd_[i].match = matches; - shellCmd_[i].call = call; - shellCmd_[i].matchLen = matchLen; - shellCmd_[i].ignoreCase = ignoreCase ? 1 : 0; + if (shellInfo_.shellCmd[i].match == NULL) { + shellInfo_.shellCmd[i].match = matches; + shellInfo_.shellCmd[i].call = call; + shellInfo_.shellCmd[i].matchLen = matchLen; + shellInfo_.shellCmd[i].ignoreCase = ignoreCase ? 1 : 0; return i; } } @@ -125,125 +415,41 @@ void HSHellUnregister(int16_t index) { return; } - shellCmd_[index].match = NULL; - shellCmd_[index].call = NULL; - shellCmd_[index].matchLen = 0; -} - -static void ShellParse() -{ - if (HVectorEmpty(cmdBuffer_)) { - return ; - } - - uint8_t len = HShellLex((const uint8_t *)HVectorGetByteDataPtr(cmdBuffer_, 0), HVectorGetUseByteLen(cmdBuffer_), cmdTokens_, HSHELL_CMD_TOKEN_MAX); - LogD("lex parse len[%d], dataLen[%d]", len, HVectorGetUseByteLen(cmdBuffer_)); - if (len <= 0) { - LogD("lex parse len[%d] empty", len); - return ; - } - - for (int i = 0; i < HSHELL_CALL_MAX; ++i) { - if (shellCmd_[i].match == NULL) { - continue; - } - - HShellLenType key = HShellMatchToken(cmdTokens_, shellCmd_[i].match, shellCmd_[i].matchLen, shellCmd_[i].ignoreCase); - if (key != HSHELL_ERROR_INDEX) { - shellCmd_[i].call(key, cmdTokens_, len); - return ; - } - } -} - -static void PrintCmdData() { - if (HVectorEmpty(cmdBuffer_)) { - return ; - } - - HVectorSetData(cmdBuffer_, HVectorGetUseLen(cmdBuffer_), '\0'); - HSHELL_PRINTF("\r\x1b[K%s", (const char *)HVectorGetByteDataPtr(cmdBuffer_, 0)); -} - -///< 返回1需要打印数据 -static uint8_t AddCmdData(uint8_t data) { - enum eEscStaus { - kEscNone, - kEsc, - kEscCsi, - }; - - static uint8_t escStatus = kEscNone; - switch (escStatus) { - case kEsc: { - if (data == '[') { - escStatus = kEscCsi; - return 0; - } - } break; - case kEscCsi: { - if (data == 'D') { - // 左键 - if (cursorPos > 0) { - --cursorPos; - } - return 0; - } else if (data == 'C') { - // 右键 - if (cursorPos < HVectorGetUseLen(cmdBuffer_)) { - ++cursorPos; - } - return 0; - } - } break; - } - - escStatus = kEscNone; - switch (data) { - case 0x1b: escStatus = kEsc; return 0; - case '\t': - case '\r': return 0; - case '\n': { - cursorPos = 0; - ShellParse(); - HVectorClear(cmdBuffer_); - } return 0; - case '\b': { - if (cursorPos > 0) { - HVectorRemoveData(cmdBuffer_, cursorPos - 1, 1); - cursorPos--; - } - } return 1; - default: break; - } - - if (isprint(data) == 0) { - LogD("not print char[%x]", data); - return 0; - } - - if (HVectorInsertData(cmdBuffer_, cursorPos, data) == 0) { - LogD("buffer is full"); - return 0; - } - - cursorPos++; - return 1; + shellInfo_.shellCmd[index].match = NULL; + shellInfo_.shellCmd[index].call = NULL; + shellInfo_.shellCmd[index].matchLen = 0; } void HShellAddCmdData(uint8_t data) { - if (AddCmdData(data)) { - PrintCmdData(); - } + AddCmdData(data); } -void HSHellAddCmdDatas(uint8_t *data, int len) { - uint8_t needPrint = 0; +void HSHellAddCmdDatas(const uint8_t *data, int len) { + if (shellInfo_.run) { + return ; + } + for (int i = 0; i < len; ++i) { - needPrint |= AddCmdData(data[i]); - } - - if (HVectorGetUseLen(cmdBuffer_) > 0 && needPrint) { - PrintCmdData(); + AddCmdData(data[i]); } } + +void HShellRun() { + if (shellInfo_.needPrint) { + PrintCmdLine(); + shellInfo_.needPrint = 0; + } + + if (shellInfo_.run == 0) { + return ; + } + + HSHELL_PRINTFL(""); + ShellParse(); + HVectorClear(cmdBuffer_); + HVectorSetData(cmdBuffer_, 0, '\0'); + PrintCmdLine(); + + shellInfo_.cursorPos = 0; + shellInfo_.run = 0; +} diff --git a/src/HUIPageManage.c b/src/HUIPageManage.c index 685519f..2f60512 100644 --- a/src/HUIPageManage.c +++ b/src/HUIPageManage.c @@ -60,7 +60,7 @@ static void InitPage() { /** =================================================== */ -static void UpdateIndexEvent(uint8_t currPage, uint8_t isHideEvent, enum eUIPage nextPage) { +static void UpdateIndexEvent(uint8_t currPage, uint8_t isHideEvent, HUiPageIndex_t nextPage) { // 非回退情况下, 保存索引 pageManage.saveIndex = pageManage.isBack == 0; if (isHideEvent) { @@ -76,7 +76,7 @@ static void UpdateIndexEvent(uint8_t currPage, uint8_t isHideEvent, enum eUIPage pageManage.saveIndex = 0; } -static uint8_t CheckPageIsNull(enum eUIPage page) { +static uint8_t CheckPageIsNull(HUiPageIndex_t page) { if (pageManage.pageCall[page] == NULL) { LogD("Page[%d] is nullptr", page); return 0; @@ -99,7 +99,7 @@ static uint8_t CheckSwitchPage() { return 1; } -static void HideFreePage(enum eUIPage currPage, enum eUIPage nextPage) { +static void HideFreePage(HUiPageIndex_t currPage, HUiPageIndex_t nextPage) { if (pageManage.isInit == 1) { // hide -> free -> update Page -> init -> show UpdateIndexEvent(currPage, 1, nextPage); @@ -127,7 +127,7 @@ static void RecoveryUserDataFlag() { pageManage.modifyUserData = 0; } -static void SwitchPage(enum eUIPage page) { +static void SwitchPage(HUiPageIndex_t page) { if (CheckPageIsNull(page) == 0) { LogD("Switch Page[%d] is nullptr", page); return ; @@ -171,13 +171,13 @@ void HUIPageInit(initPageType_t initPage) { //SwitchPage(pageManage.homePage); } -void HUIPageSetHome(enum eUIPage page) { +void HUIPageSetHome(HUiPageIndex_t page) { pageManage.homePage = page; } // 切换页面, 当前页面入栈, 相同页面不操作, 需要检查栈, 栈存在就回栈清空之后的, 不存在就压栈 // 因为有些页面可能不用HUIPageBack来返回, 所以需要兼容这种情况 -void HUIPageSwitch(enum eUIPage page) { +void HUIPageSwitch(HUiPageIndex_t page) { if (page < 0 || page >= kUIPageMax) { LogD("page[%d] out of range", page); return ; @@ -304,7 +304,7 @@ void _HUIPageAddStack(int len, ...) { va_list args; va_start(args, len); - enum eUIPage curr = va_arg(args, enum eUIPage); + HUiPageIndex_t curr = va_arg(args, int); HByteLenType findPos = HByteStackFind(pageStack, curr); if (findPos != HBYTE_STACK_ERROR) { HByteStackSetUseLen(pageStack, findPos); @@ -320,7 +320,7 @@ void _HUIPageAddStack(int len, ...) { findPos = HByteStackGetUseLen(pageStack); HByteStackPush(pageStack, curr); for (int i = 1; i < len; ++i) { - curr = va_arg(args, enum eUIPage); + curr = va_arg(args, int); if (curr < 0 || curr >= kUIPageMax) { LogD("page[%d] out of range", curr); continue; @@ -373,17 +373,17 @@ uint8_t HUIPageGetCurrNotFree() { } // 设置指定页面不释放内存 -void HUIPageSetNotFree(enum eUIPage page) { +void HUIPageSetNotFree(HUiPageIndex_t page) { HBitSet(notFreeBit, page, 1); } // 恢复指定页面默认释放内存 -void HUIPageResetFree(enum eUIPage page) { +void HUIPageResetFree(HUiPageIndex_t page) { HBitSet(notFreeBit, page, 0); } // 获取指定页面是否不释放 -uint8_t HUIPageGetNotFree(enum eUIPage page) { +uint8_t HUIPageGetNotFree(HUiPageIndex_t page) { return HBitGet(notFreeBit, page); } @@ -430,12 +430,12 @@ uint8_t HUIPageGetIndex() { } // 获取当前页面 -enum eUIPage HUIPageGetCurrPage() { +HUiPageIndex_t HUIPageGetCurrPage() { return pageManage.currPage; } // 获取上一个页面 -enum eUIPage HUIPageGetPrevPage() { +HUiPageIndex_t HUIPageGetPrevPage() { return pageManage.prevPage; } @@ -455,7 +455,7 @@ uint8_t HUIPageIsBack() { } // 检查该页面是否在返回栈, 是返回1, 否则返回0 -uint8_t HUIPageFindStack(enum eUIPage page) { +uint8_t HUIPageFindStack(HUiPageIndex_t page) { return HByteStackFind(pageStack, page) != HBYTE_STACK_ERROR; }