1 Star 0 Fork 1

uuaa/cmd_lib_v2

forked from 赵章博/cmd_lib_v2 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
cmd.c 8.41 KB
一键复制 编辑 原始数据 按行查看 历史
赵章博 提交于 2024-09-18 11:24 . init
/******************************************************************************
* @brief 命令管理器
* Change Logs:
* Date Author Email Notes
* 2024-09-18 子恒 3393018959@qq.com Initial version
******************************************************************************/
#include "cmd.h"
static b_cmd_mgr_t b_cmd_mgr;
static ring_buf_t cmds_ring = {NULL,0,0,0};
static unsigned char cmd_ring_buf[B_CMD_RING_MAX];
static uint8_t cb_cmd_help(char *argv[],uint8_t argc);
static const b_cmd_t cmds_help = {.cmd_str = "HELP",.cb = cb_cmd_help};
static unsigned char string_split(char *buf, char **argv,unsigned char * argc);
static unsigned char parse_str(char *str,char ch);
static unsigned char char_in_string(char *str, char ch);
static unsigned int str_hash(char *str);
static unsigned char str_match(const char *str1, char **argv, unsigned char argc);
static void cmd_put_char(const char ch);
static void cmd_print_var_cb(char *argv[],uint8_t argc);
unsigned char cmd_ring_puts(unsigned char *pch,unsigned int len)
{
if(ring_buf_put(&cmds_ring, pch, len) == len) return B_CMD_RET_PASS;
return B_CMD_RET_FAIL;
}
void cmd_mgr_init(b_cmd_t *cmds,unsigned char cmds_len, b_cmd_out_char_cb_t * putc_cb)
{
unsigned short i,j;
ring_buf_init(&cmds_ring, cmd_ring_buf, B_CMD_RING_MAX);
b_cmd_mgr.pf_outchar = putc_cb;
b_cmd_mgr.cmds = cmds;
b_cmd_mgr.info.cmds_len = cmds_len;
memset(b_cmd_mgr.line, 0, sizeof(b_cmd_mgr.line));
for(i = 0; i < b_cmd_mgr.info.cmds_len; i++)
{
const char *pstr = b_cmd_mgr.cmds[i].cmd_str;
unsigned int hash = 0;
unsigned char argc_mask = 0x80;
j = 0;
while(*pstr)
{
if(char_in_string(B_CMD_SPLIT_STR,*pstr) != B_CMD_RET_PASS)
{
hash += (*pstr) << j;
j++;
if(argc_mask & 0x80){
argc_mask &= ~0x80;
argc_mask++;
}
}
else
{
j = 0;
argc_mask |= 0x80;
}
pstr++;
}
argc_mask &= 0x7f;
b_cmd_mgr.cmds[i].hash = hash;
b_cmd_mgr.cmds[i].hash_argc = argc_mask;
}
}
void b_cmd_parse(void)
{
static uint16_t index = 0;
uint8_t argc = 0,ch,i,j;
char * argv[B_CMD_ARGS_NUM_MAX + 1] = {0};
unsigned short hash_map[B_CMD_ARGS_NUM_MAX + 1];
unsigned char ret = B_CMD_RET_FAIL;
uint8_t len = ring_buf_get(&cmds_ring, &ch, 1);
if(len != 1) return;
b_cmd_mgr.line[index++] = ch;
if(index >= B_CMD_LINE_CHAR_MAX)
{
index = 0;
b_cmd_put_str("[Command buffer exceeded!!]\r\n");
}
if(parse_str(B_CMD_END_STR,ch) == B_CMD_RET_PASS)
{
b_cmd_mgr.line[index - strlen(B_CMD_END_STR)] = '\0';
index = 0;
string_split(b_cmd_mgr.line,argv,&argc);
hash_map[0] = str_hash(argv[0]);
for(i = 1; i < argc; i++)
{
hash_map[i] = hash_map[i-1] + str_hash(argv[i]);
}
for(i = 0; i < b_cmd_mgr.info.cmds_len; i++){
unsigned int hash = 0;
if(b_cmd_mgr.cmds[i].hash == hash_map[b_cmd_mgr.cmds[i].hash_argc - 1])
{
ret = str_match(b_cmd_mgr.cmds[i].cmd_str,argv,b_cmd_mgr.cmds[i].hash_argc);
if(ret == B_CMD_RET_PASS)
{
ret = b_cmd_mgr.cmds[i].cb(argv,argc);
break;
}
}
}
if((ret != B_CMD_RET_PASS) && (argc == 1))
{
if(!strcmp(cmds_help.cmd_str,argv[0]))
{
ret = cmds_help.cb(argv,argc);
}
}
if(ret == B_CMD_RET_PASS){
b_cmd_put_str(B_CMD_EXE_SUCESS_STR);
}else{
b_cmd_put_str(B_CMD_EXE_FAIL_STR);
}
cmd_print_var_cb(argv,argc);
}
}
void b_cmd_put_str(const char *const str)
{
const char *ptemp = str;
if (b_cmd_mgr.pf_outchar != NULL)
{
while (*ptemp)
{
b_cmd_mgr.pf_outchar(*ptemp);
ptemp++;
}
}
}
//检测ch是否按字符串str的顺序逐个写入
static unsigned char parse_str(char *str,char ch)
{
static unsigned int pt = 0;
if(str[pt] == ch) pt++;
if(str[pt] == '\0')
{
pt = 0;
return B_CMD_RET_PASS;
}
return B_CMD_RET_FAIL;
}
//检测ch是否在字符串str中存在
static unsigned char char_in_string(char *str, char ch)
{
while (*str)
{
if (*str == ch)
return B_CMD_RET_PASS;
str++;
}
return B_CMD_RET_FAIL;
}
//获取字符串哈希和
static unsigned int str_hash(char *str)
{
unsigned int hash = 0;
unsigned char i = 0;
while(*str)
{
hash += (*str) << i;
i++;
str++;
}
return hash;
}
//从母串中匹配子串,忽略分隔符
static unsigned char str_match(const char *str1, char **argv, unsigned char argc)
{
unsigned char flg = 0,i = 0;
const char *p1 = str1;
char *p2 = argv[i];
for(i = 0; i < argc; )
{
if (char_in_string(B_CMD_SPLIT_STR, *p1) == B_CMD_RET_PASS)
{
p1++;
if(flg == 1)
{
flg = 0;
}
}
else
{
if(flg == 0)
{
flg = 1;
p2 = argv[i];
i++;
}
while(*p2)
{
if(!(*p2 == *p1))
{
return B_CMD_RET_FAIL;
}
p1++;
p2++;
}
}
}
return B_CMD_RET_PASS;
}
//按B_CMD_SPLIT_STR字符串中字符,将buf分割成子字符串并将其首地址储存在argv[]中,argc为分割的子字符串数量
//忽略首分割字符、连续多个分割字符。
static unsigned char string_split(char *buf, char **argv,unsigned char * argc)
{
unsigned char i = 0;
if(argv == NULL) return B_CMD_RET_FAIL;
do{
if (char_in_string(B_CMD_SPLIT_STR, buf[i]) != B_CMD_RET_PASS){
break;
}
i++;
}while(1);
argv[(*argc)++] = &buf[i];
for (; buf[i] != '\0'; i++)
{
if (char_in_string(B_CMD_SPLIT_STR, buf[i]) == B_CMD_RET_PASS)
{
buf[i] = '\0';
if (char_in_string(B_CMD_SPLIT_STR, buf[i + 1]) == B_CMD_RET_FAIL)
{
if (buf[i + 1] != '\0')
{
argv[(*argc)++] = &buf[i + 1];
}
}
}
if (*argc > B_CMD_ARGS_NUM_MAX)
{
break;
}
}
return B_CMD_RET_PASS;
}
static uint8_t cb_cmd_help(char *argv[],uint8_t argc)
{
unsigned char i;
const char *tab="0123456789ABCDEF";
b_cmd_put_str("CMD LIST\r\n");
b_cmd_put_str("----------------------------------------------------\r\n");
for(i = 0; i < b_cmd_mgr.info.cmds_len; i++){
b_cmd_put_str(b_cmd_mgr.cmds[i].cmd_str);
b_cmd_put_str("\t0x");
cmd_put_char(tab[(((b_cmd_mgr.cmds[i].hash) & 0xF000) >> 12)]);
cmd_put_char(tab[(((b_cmd_mgr.cmds[i].hash) & 0x0F00) >> 8)]);
cmd_put_char(tab[(((b_cmd_mgr.cmds[i].hash) & 0x00F0) >> 4)]);
cmd_put_char(tab[(((b_cmd_mgr.cmds[i].hash) & 0x000F) >> 0)]);
b_cmd_put_str("\t");
if(b_cmd_mgr.cmds[i].cmd_help != NULL)b_cmd_put_str(b_cmd_mgr.cmds[i].cmd_help);
b_cmd_put_str("\r\n");
}
b_cmd_put_str("----------------------------------------------------\r\n");
return B_CMD_RET_PASS;
}
static void cmd_print_var_cb(char *argv[],uint8_t argc)
{
#if B_CMD_VAR_PRINT_EN == 1
uint8_t i = 0;
const char *tab="0123456789ABCDEF";
for (i = 0; i < argc; i++)
{
b_cmd_put_str("argv[");
cmd_put_char(tab[((i & 0xf0) >> 4)]);
cmd_put_char(tab[((i & 0x0f) >> 0)]);
b_cmd_put_str("] = ");
b_cmd_put_str(argv[i]);
b_cmd_put_str("\r\n");
}
#endif
}
static void cmd_put_char(const char ch)
{
if (b_cmd_mgr.pf_outchar != NULL)
{
b_cmd_mgr.pf_outchar(ch);
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/uuaa_aa/cmd_lib_v2.git
git@gitee.com:uuaa_aa/cmd_lib_v2.git
uuaa_aa
cmd_lib_v2
cmd_lib_v2
master

搜索帮助