112 lines
2.3 KiB
C
112 lines
2.3 KiB
C
/**
|
|
* @file cmd.c
|
|
* @author xxx
|
|
* @date 2023-06-25 13:07:02
|
|
* @brief 命令解析器
|
|
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
|
|
*/
|
|
|
|
#include "cmd.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
static cmd_t *_cmd_begin, *_cmd_end;
|
|
|
|
static int _cmd_to_lower(int c)
|
|
{
|
|
if ((c >= 'A') && (c <= 'Z'))
|
|
return c + ('a' - 'A');
|
|
return c;
|
|
}
|
|
|
|
static unsigned int _cmd_hash(const char *str)
|
|
{
|
|
int tmp, c = *str;
|
|
unsigned int seed = CMD_HASH; /* 'jiejie' string hash */
|
|
unsigned int hash = 0;
|
|
|
|
while (*str)
|
|
{
|
|
tmp = _cmd_to_lower(c);
|
|
hash = (hash ^ seed) + tmp;
|
|
str++;
|
|
c = *str;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
static void _cmd_init(const void *begin, const void *end)
|
|
{
|
|
_cmd_begin = (cmd_t *)begin;
|
|
_cmd_end = (cmd_t *)end;
|
|
}
|
|
|
|
static cmd_t *_get_next_cmd(cmd_t *cmd)
|
|
{
|
|
unsigned int *ptr;
|
|
ptr = (unsigned int *)(cmd + 1);
|
|
while ((*ptr == 0) && ((unsigned int *)ptr < (unsigned int *)_cmd_end))
|
|
ptr++;
|
|
|
|
return (cmd_t *)ptr;
|
|
}
|
|
|
|
static int _cmd_match(const char *str, const char *cmd)
|
|
{
|
|
int c1, c2;
|
|
|
|
do
|
|
{
|
|
c1 = _cmd_to_lower(*str++);
|
|
c2 = _cmd_to_lower(*cmd++);
|
|
} while ((c1 == c2) && c1);
|
|
|
|
return c1 - c2;
|
|
}
|
|
|
|
static void _list(void)
|
|
{
|
|
cmd_t *index;
|
|
for (index = _cmd_begin; index < _cmd_end; index = _get_next_cmd(index))
|
|
{
|
|
// printf("%s -->%s\n", index->cmd, index->cmd_mess);
|
|
}
|
|
}
|
|
REGISTER_CMD(_list, _list, list all command);
|
|
|
|
void cmd_init(void)
|
|
{
|
|
cmd_t *index;
|
|
|
|
#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM C Compiler */
|
|
extern const int CMDS$$Base;
|
|
extern const int CMDS$$Limit;
|
|
_cmd_init(&CMDS$$Base, &CMDS$$Limit);
|
|
#elif defined(__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
|
|
_cmd_init(__section_begin("CMDS"), __section_end("CMDS"));
|
|
#endif
|
|
|
|
for (index = _cmd_begin; index < _cmd_end; index = _get_next_cmd(index))
|
|
{
|
|
index->hash = _cmd_hash(index->cmd);
|
|
}
|
|
}
|
|
|
|
void cmd_parsing(char *str)
|
|
{
|
|
cmd_t *index;
|
|
unsigned int hash = _cmd_hash(str);
|
|
|
|
for (index = _cmd_begin; index < _cmd_end; index = _get_next_cmd(index))
|
|
{
|
|
if (hash == index->hash)
|
|
{
|
|
if (_cmd_match(str, index->cmd) == 0)
|
|
{
|
|
index->handler();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|