-
Notifications
You must be signed in to change notification settings - Fork 120
/
cmd.c
103 lines (86 loc) · 2.35 KB
/
cmd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* @Author: jiejie
* @Github: https://github.com/jiejieTop
* @Date: 2019-12-13 10:47:30
* @LastEditTime: 2020-05-16 15:53:35
* @Description: the code belongs to jiejie, please keep the author information and source code according to the license.
*/
#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->desc);
}
}
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;
}
}
}
}