1. 更新命令行

2. 更新页面管理
This commit is contained in:
coffee 2025-06-04 15:50:21 +08:00
parent 0da93d100c
commit 8631a84333
4 changed files with 412 additions and 163 deletions

View File

@ -10,6 +10,9 @@
typedef uint8_t HShellLenType; typedef uint8_t HShellLenType;
#define HSHELL_ERROR_INDEX (0xff) #define HSHELL_ERROR_INDEX (0xff)
// 是否使用密码
#define HSHELL_USE_PASSWORD
///< 可配置最多可注册回调多少个 ///< 可配置最多可注册回调多少个
#ifndef HSHELL_CALL_MAX #ifndef HSHELL_CALL_MAX
#define HSHELL_CALL_MAX 5 #define HSHELL_CALL_MAX 5
@ -22,12 +25,24 @@ typedef uint8_t HShellLenType;
///< 解析token参数的最大个数 ///< 解析token参数的最大个数
#ifndef HSHELL_CMD_TOKEN_MAX #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 #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 ///< 处理命令行token
typedef struct __attribute__ ((__packed__)) HShellCmdToken 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); 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 , * @brief ,
* @param matches * @param matches
@ -93,11 +129,17 @@ int16_t HSHellRegister(const HShellMatch *matches, int matchLen, shellCall call,
void HSHellUnregister(int16_t index); void HSHellUnregister(int16_t index);
/** /**
* @brief , '\n' * @brief , , HShellRun处理后恢复继续添加
* @param str * @param str
* @param strLen * @param strLen
**/ **/
void HShellAddCmdData(uint8_t data); 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_ #endif // _H_SHELL_LEX_

View File

@ -48,9 +48,10 @@
#define UIPAGE_SHOW_HIDE_FUNC(show, hide) UIPAGE_SHOW_FUNC(show); UIPAGE_HIDE_FUNC(hide) #define UIPAGE_SHOW_HIDE_FUNC(show, hide) UIPAGE_SHOW_FUNC(show); UIPAGE_HIDE_FUNC(hide)
// 对应事件的data转换具体类型宏 // 对应事件的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 -> free -> update Page -> init -> show
// 或者非返回时如下, 此时的hide和index事件都可存储该页面索引: // 或者非返回时如下, 此时的hide和index事件都可存储该页面索引:
@ -62,7 +63,7 @@ enum eCallCmd
kCallShowPage, ///< 显示页面 kCallShowPage, ///< 显示页面
kCallHidePage, ///< 退出页面, 此事件如果是返回触发的可以存储索引数据 kCallHidePage, ///< 退出页面, 此事件如果是返回触发的可以存储索引数据
kCallSwitchPage, ///< 切换页面, 对应页面返回false时则不切换, 所有切换都会触发这个事件 kCallSwitchPage, ///< 切换页面, 对应页面返回false时则不切换, 所有切换都会触发这个事件
kCallIndexSave, ///< 存储当前索引事件, 通知此事件说明当前不是返回事件(cmd, enum eUIPage *nextPage, 1); kCallIndexSave, ///< 存储当前索引事件, 通知此事件说明当前不是返回事件(cmd, HUiPageIndex_t *nextPage, 1);
}; };
@ -70,7 +71,7 @@ enum eCallCmd
typedef enum eUIPage typedef enum eUIPage
{ {
kUIPageMax, ///< ui最大个数, 不超过254个页面, 如超过则需要修改字节栈类型 kUIPageMax = 4, ///< ui最大个数, 不超过254个页面, 如超过则需要修改字节栈类型
} eUIPage; } eUIPage;
///< cmd命令, data数据, len数据长度 ///< cmd命令, data数据, len数据长度
@ -81,11 +82,11 @@ typedef void (*initPageType_t)(pageCallType_t *call);
void HUIPageInit(initPageType_t initPage); void HUIPageInit(initPageType_t initPage);
// 设置主页, 切换到主页清空返回栈, 如果返回栈为空时, 当前页面不是主页, 则切换到主页 // 设置主页, 切换到主页清空返回栈, 如果返回栈为空时, 当前页面不是主页, 则切换到主页
void HUIPageSetHome(enum eUIPage page); void HUIPageSetHome(HUiPageIndex_t page);
// 切换页面, 当前页面入栈, 相同页面不操作, 需要检查栈, 栈存在就回栈清空之后的, 不存在就压栈 // 切换页面, 当前页面入栈, 相同页面不操作, 需要检查栈, 栈存在就回栈清空之后的, 不存在就压栈
// 因为有些页面可能不用HUIPageBack来返回, 所以需要兼容这种情况 // 因为有些页面可能不用HUIPageBack来返回, 所以需要兼容这种情况
void HUIPageSwitch(enum eUIPage page); void HUIPageSwitch(HUiPageIndex_t page);
// 切换到主页 // 切换到主页
void HUIPageSwitchHome(); void HUIPageSwitchHome();
@ -119,13 +120,13 @@ void HUIPageResetCurrFree();
uint8_t HUIPageGetCurrNotFree(); 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 // 获取指定页面是否不释放, 是返回1, 否则返回0
uint8_t HUIPageGetNotFree(enum eUIPage page); uint8_t HUIPageGetNotFree(HUiPageIndex_t page);
// 设置用户数据, 在 kCallShowPage 和 kCallHidePage 都可调用, 但每次切换这些事件后都会重置数据为0 // 设置用户数据, 在 kCallShowPage 和 kCallHidePage 都可调用, 但每次切换这些事件后都会重置数据为0
void HUIPageSetUserData(long userData); void HUIPageSetUserData(long userData);
@ -140,10 +141,10 @@ uint8_t HUIPageSaveIndex(uint8_t value);
uint8_t HUIPageGetIndex(); uint8_t HUIPageGetIndex();
// 获取当前页面 // 获取当前页面
enum eUIPage HUIPageGetCurrPage(); HUiPageIndex_t HUIPageGetCurrPage();
// 获取上一个页面 // 获取上一个页面
enum eUIPage HUIPageGetPrevPage(); HUiPageIndex_t HUIPageGetPrevPage();
// 获取返回栈使用长度 // 获取返回栈使用长度
uint8_t HUIPageGetStackLen(); uint8_t HUIPageGetStackLen();
@ -155,7 +156,7 @@ uint8_t HUIPageGetIndexStackLen();
uint8_t HUIPageIsBack(); uint8_t HUIPageIsBack();
// 检查该页面是否在返回栈, 是返回1, 否则返回0 // 检查该页面是否在返回栈, 是返回1, 否则返回0
uint8_t HUIPageFindStack(enum eUIPage page); uint8_t HUIPageFindStack(HUiPageIndex_t page);
#endif //__H_UI_PAGE_MANAGE_H__ #endif //__H_UI_PAGE_MANAGE_H__

View File

@ -3,6 +3,7 @@
#include <HShellLex.h> #include <HShellLex.h>
#include <HVector.h> #include <HVector.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -10,7 +11,7 @@
#ifndef LogD #ifndef LogD
#if 0 #if 0
#include <stdio.h> #include <stdio.h>
#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 #else
#define LogD(...) #define LogD(...)
#endif #endif
@ -20,23 +21,267 @@
#define CTRL_KEY(k) ((k) & 0x1f) #define CTRL_KEY(k) ((k) & 0x1f)
struct __attribute__((packed)) HShellCmd { typedef struct __attribute__((packed)) ShellCmd {
const HShellMatch *match; ///< 匹配表 const HShellMatch *match; ///< 匹配表
shellCall call; ///< 回调 shellCall call; ///< 回调
uint8_t matchLen; ///< 匹配表长度 uint8_t matchLen : 7; ///< 匹配表长度
uint8_t ignoreCase : 1; ///< 忽略大小写 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 HVECTOR_DEFINE(cmdBuffer_, HSHELL_CMD_LINE_BUFFER);
// 解析参数 static struct ShellInfo shellInfo_;
static HShellCmdToken cmdTokens_[HSHELL_CMD_TOKEN_MAX];
// 光标位置
static uint8_t cursorPos;
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) { uint8_t HShellLex(const uint8_t *str, int strLen, HShellCmdToken *tokens, int tokensLen) {
if (str == NULL || tokens == NULL || tokensLen <= 0) { if (str == NULL || tokens == NULL || tokensLen <= 0) {
LogD("str[%p] is nullptr or Tokens[%p] is nullptr or len[%d]", str, tokens, tokensLen); 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; 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) { int16_t HSHellRegister(const HShellMatch *matches, int matchLen, shellCall call, uint8_t ignoreCase) {
if (matches == NULL || matchLen <= 0 || call == NULL) { if (matches == NULL || matchLen <= 0 || call == NULL) {
LogD("matches[%p] or matchLen[%d] or call[%p] is nullptr", matches, matchLen, call); 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) { 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); LogD("call[%p] is exist, override write index[%d]", call, i);
shellCmd_[i].call = call; shellInfo_.shellCmd[i].call = call;
shellCmd_[i].matchLen = matchLen; shellInfo_.shellCmd[i].matchLen = matchLen;
shellCmd_[i].ignoreCase = ignoreCase ? 1 : 0; shellInfo_.shellCmd[i].ignoreCase = ignoreCase ? 1 : 0;
return i; return i;
} }
if (shellCmd_[i].match == NULL) { if (shellInfo_.shellCmd[i].match == NULL) {
shellCmd_[i].match = matches; shellInfo_.shellCmd[i].match = matches;
shellCmd_[i].call = call; shellInfo_.shellCmd[i].call = call;
shellCmd_[i].matchLen = matchLen; shellInfo_.shellCmd[i].matchLen = matchLen;
shellCmd_[i].ignoreCase = ignoreCase ? 1 : 0; shellInfo_.shellCmd[i].ignoreCase = ignoreCase ? 1 : 0;
return i; return i;
} }
} }
@ -125,125 +415,41 @@ void HSHellUnregister(int16_t index) {
return; return;
} }
shellCmd_[index].match = NULL; shellInfo_.shellCmd[index].match = NULL;
shellCmd_[index].call = NULL; shellInfo_.shellCmd[index].call = NULL;
shellCmd_[index].matchLen = 0; shellInfo_.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;
} }
void HShellAddCmdData(uint8_t data) { void HShellAddCmdData(uint8_t data) {
if (AddCmdData(data)) { AddCmdData(data);
PrintCmdData();
}
} }
void HSHellAddCmdDatas(uint8_t *data, int len) { void HSHellAddCmdDatas(const uint8_t *data, int len) {
uint8_t needPrint = 0; if (shellInfo_.run) {
return ;
}
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
needPrint |= AddCmdData(data[i]); AddCmdData(data[i]);
}
if (HVectorGetUseLen(cmdBuffer_) > 0 && needPrint) {
PrintCmdData();
} }
} }
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;
}

View File

@ -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; pageManage.saveIndex = pageManage.isBack == 0;
if (isHideEvent) { if (isHideEvent) {
@ -76,7 +76,7 @@ static void UpdateIndexEvent(uint8_t currPage, uint8_t isHideEvent, enum eUIPage
pageManage.saveIndex = 0; pageManage.saveIndex = 0;
} }
static uint8_t CheckPageIsNull(enum eUIPage page) { static uint8_t CheckPageIsNull(HUiPageIndex_t page) {
if (pageManage.pageCall[page] == NULL) { if (pageManage.pageCall[page] == NULL) {
LogD("Page[%d] is nullptr", page); LogD("Page[%d] is nullptr", page);
return 0; return 0;
@ -99,7 +99,7 @@ static uint8_t CheckSwitchPage() {
return 1; return 1;
} }
static void HideFreePage(enum eUIPage currPage, enum eUIPage nextPage) { static void HideFreePage(HUiPageIndex_t currPage, HUiPageIndex_t nextPage) {
if (pageManage.isInit == 1) { if (pageManage.isInit == 1) {
// hide -> free -> update Page -> init -> show // hide -> free -> update Page -> init -> show
UpdateIndexEvent(currPage, 1, nextPage); UpdateIndexEvent(currPage, 1, nextPage);
@ -127,7 +127,7 @@ static void RecoveryUserDataFlag() {
pageManage.modifyUserData = 0; pageManage.modifyUserData = 0;
} }
static void SwitchPage(enum eUIPage page) { static void SwitchPage(HUiPageIndex_t page) {
if (CheckPageIsNull(page) == 0) { if (CheckPageIsNull(page) == 0) {
LogD("Switch Page[%d] is nullptr", page); LogD("Switch Page[%d] is nullptr", page);
return ; return ;
@ -171,13 +171,13 @@ void HUIPageInit(initPageType_t initPage) {
//SwitchPage(pageManage.homePage); //SwitchPage(pageManage.homePage);
} }
void HUIPageSetHome(enum eUIPage page) { void HUIPageSetHome(HUiPageIndex_t page) {
pageManage.homePage = page; pageManage.homePage = page;
} }
// 切换页面, 当前页面入栈, 相同页面不操作, 需要检查栈, 栈存在就回栈清空之后的, 不存在就压栈 // 切换页面, 当前页面入栈, 相同页面不操作, 需要检查栈, 栈存在就回栈清空之后的, 不存在就压栈
// 因为有些页面可能不用HUIPageBack来返回, 所以需要兼容这种情况 // 因为有些页面可能不用HUIPageBack来返回, 所以需要兼容这种情况
void HUIPageSwitch(enum eUIPage page) { void HUIPageSwitch(HUiPageIndex_t page) {
if (page < 0 || page >= kUIPageMax) { if (page < 0 || page >= kUIPageMax) {
LogD("page[%d] out of range", page); LogD("page[%d] out of range", page);
return ; return ;
@ -304,7 +304,7 @@ void _HUIPageAddStack(int len, ...) {
va_list args; va_list args;
va_start(args, len); va_start(args, len);
enum eUIPage curr = va_arg(args, enum eUIPage); HUiPageIndex_t curr = va_arg(args, int);
HByteLenType findPos = HByteStackFind(pageStack, curr); HByteLenType findPos = HByteStackFind(pageStack, curr);
if (findPos != HBYTE_STACK_ERROR) { if (findPos != HBYTE_STACK_ERROR) {
HByteStackSetUseLen(pageStack, findPos); HByteStackSetUseLen(pageStack, findPos);
@ -320,7 +320,7 @@ void _HUIPageAddStack(int len, ...) {
findPos = HByteStackGetUseLen(pageStack); findPos = HByteStackGetUseLen(pageStack);
HByteStackPush(pageStack, curr); HByteStackPush(pageStack, curr);
for (int i = 1; i < len; ++i) { for (int i = 1; i < len; ++i) {
curr = va_arg(args, enum eUIPage); curr = va_arg(args, int);
if (curr < 0 || curr >= kUIPageMax) { if (curr < 0 || curr >= kUIPageMax) {
LogD("page[%d] out of range", curr); LogD("page[%d] out of range", curr);
continue; continue;
@ -373,17 +373,17 @@ uint8_t HUIPageGetCurrNotFree() {
} }
// 设置指定页面不释放内存 // 设置指定页面不释放内存
void HUIPageSetNotFree(enum eUIPage page) { void HUIPageSetNotFree(HUiPageIndex_t page) {
HBitSet(notFreeBit, page, 1); HBitSet(notFreeBit, page, 1);
} }
// 恢复指定页面默认释放内存 // 恢复指定页面默认释放内存
void HUIPageResetFree(enum eUIPage page) { void HUIPageResetFree(HUiPageIndex_t page) {
HBitSet(notFreeBit, page, 0); HBitSet(notFreeBit, page, 0);
} }
// 获取指定页面是否不释放 // 获取指定页面是否不释放
uint8_t HUIPageGetNotFree(enum eUIPage page) { uint8_t HUIPageGetNotFree(HUiPageIndex_t page) {
return HBitGet(notFreeBit, page); return HBitGet(notFreeBit, page);
} }
@ -430,12 +430,12 @@ uint8_t HUIPageGetIndex() {
} }
// 获取当前页面 // 获取当前页面
enum eUIPage HUIPageGetCurrPage() { HUiPageIndex_t HUIPageGetCurrPage() {
return pageManage.currPage; return pageManage.currPage;
} }
// 获取上一个页面 // 获取上一个页面
enum eUIPage HUIPageGetPrevPage() { HUiPageIndex_t HUIPageGetPrevPage() {
return pageManage.prevPage; return pageManage.prevPage;
} }
@ -455,7 +455,7 @@ uint8_t HUIPageIsBack() {
} }
// 检查该页面是否在返回栈, 是返回1, 否则返回0 // 检查该页面是否在返回栈, 是返回1, 否则返回0
uint8_t HUIPageFindStack(enum eUIPage page) { uint8_t HUIPageFindStack(HUiPageIndex_t page) {
return HByteStackFind(pageStack, page) != HBYTE_STACK_ERROR; return HByteStackFind(pageStack, page) != HBYTE_STACK_ERROR;
} }