Skip to content

add gcc support #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 48 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

cmd-parser 遵循 [Apache License v2.0](https://github.com/jiejieTop/mqttclient/blob/master/LICENSE) 开源协议。鼓励代码共享和尊重原作者的著作权,可以自由的使用、修改源代码,也可以将修改后的代码作为开源或闭源软件发布,**但必须保留原作者版权声明**。

## 使用方法
## MDK和IAR编译器使用方法

1. 注册命令

Expand All @@ -40,18 +40,60 @@ cmd_init();
cmd_parsing("test1");
```

## GCC编译器使用方法

GCC工程需要在工程的ld文件中找到非零变量的初始化链接代码,将下面的代码粘贴到最后面即可

```c
. = ALIGN(4);
PROVIDE( CMDS_Base = . );
KEEP(*(CMDS))
PROVIDE( CMDS_Limit = . );
. = ALIGN(4);
```

例如:

```c
.data :
{
. = ALIGN(4);
PROVIDE(_data_vma = .);
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);

/* this section is for cmd parser */
PROVIDE( CMDS_Base = . );
KEEP(*(CMDS))
PROVIDE( CMDS_Limit = . );
. = ALIGN(4);

PROVIDE( _edata = .);
} >RAM AT>FLASH

```

剩余步骤和上一节**MDK和IAR编译器使用方法**一致。

## 特色

- 用户无需关心命令的存储区域与大小,由编译器静态分配。
- 加入哈希算法超快速匹配命令,时间复杂度从O(n*m)变为O(n)。
- 命令支持忽略大小写。
- 非常易用与非常简洁的代码(不足150行)。

## 注意事项

- 本代码目前只支持`MDK`与`IAR`的编译器,对于`gcc`尚未移植,欢迎参与贡献


## test.c
```c
#include "cmd.h"
Expand Down
69 changes: 44 additions & 25 deletions cmd.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
/*
* @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.
* Copyright (c) 2019, jiejie <https://github.com/jiejieTop>
* Copyright (c) 2020, hong54321 <https://github.com/hong54321>
* Copyright (c) 2022, smartmx <smartmx@qq.com>
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-13 jiejie the first version
* 2020-03-06 jiejie fix the hash algorithm bug
* 2020-03-29 hong54321 update
* 2022-04-01 smartmx add gcc support
*
*/
#include "cmd.h"
#include <stdio.h>
Expand All @@ -17,13 +25,14 @@ static int _cmd_to_lower(int c)
return c;
}

static unsigned int _cmd_hash(const char* str)
static unsigned int _cmd_hash(const char *str)
{
int tmp, c = *str;
unsigned int seed = CMD_HASH; /* 'jiejie' string hash */
unsigned int seed = CMD_HASH; /* 'jiejie' string hash */
unsigned int hash = 0;

while(*str) {

while (*str)
{
tmp = _cmd_to_lower(c);
hash = (hash ^ seed) + tmp;
str++;
Expand All @@ -34,40 +43,43 @@ static unsigned int _cmd_hash(const char* str)

static void _cmd_init(const void *begin, const void *end)
{
_cmd_begin = (cmd_t*) begin;
_cmd_end = (cmd_t*) end;
_cmd_begin = (cmd_t *) begin;
_cmd_end = (cmd_t *) end;
}

static cmd_t* _get_next_cmd(cmd_t *cmd)
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 = (unsigned int *)(cmd + 1);
while ((*ptr == 0) && ((unsigned int *)ptr < (unsigned int *) _cmd_end))
ptr ++;

return (cmd_t*) ptr;
return (cmd_t *) ptr;
}

static int _cmd_match(const char *str, const char *cmd)
{
int c1, c2;

do {
do
{
c1 = _cmd_to_lower(*str++);
c2 = _cmd_to_lower(*cmd++);
} while((c1 == c2) && c1);
}
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);
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);
REGISTER_CMD(_list, _list, list all command);

void cmd_init(void)
{
Expand All @@ -79,9 +91,14 @@ void cmd_init(void)
_cmd_init(&CMDS$$Base, &CMDS$$Limit);
#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
_cmd_init(__section_begin("CMDS"), __section_end("CMDS"));
#elif defined (__GNUC__)
extern const int CMDS_Base;
extern const int CMDS_Limit;
_cmd_init(&CMDS_Base, &CMDS_Limit);
#endif

for (index = _cmd_begin; index < _cmd_end; index = _get_next_cmd(index)) {
for (index = _cmd_begin; index < _cmd_end; index = _get_next_cmd(index))
{
index->hash = _cmd_hash(index->cmd);
}

Expand All @@ -91,10 +108,12 @@ 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) {
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;
}
Expand Down
28 changes: 20 additions & 8 deletions cmd.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
/*
* @Author: jiejie
* @Github: https://github.com/jiejieTop
* @Date: 2019-12-13 10:48:52
* @LastEditTime: 2019-12-16 21:26:56
* @Description: the code belongs to jiejie, please keep the author information and source code according to the license.
* Copyright (c) 2019, jiejie <https://github.com/jiejieTop>
* Copyright (c) 2020, hong54321 <https://github.com/hong54321>
* Copyright (c) 2022, smartmx <smartmx@qq.com>
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-13 jiejie the first version
* 2020-03-06 jiejie fix the hash algorithm bug
* 2020-03-29 hong54321 update
* 2022-04-01 smartmx add gcc support
*
*/
#ifndef _CMD_H_
#define _CMD_H_
Expand All @@ -17,16 +25,20 @@
#elif defined (__IAR_SYSTEMS_ICC__) /* IAR Compiler */
#define SECTION(x) @ x
#define CMD_USED __root
#elif defined (__GNUC__)
#define SECTION(x) __attribute__((section(x)))
#define CMD_USED __attribute__((used))
#else
#error "not supported tool chain..."
#endif


typedef void (*cmd_handler)(void);

typedef struct cmd {
const char* cmd;
const char* cmd_mess;
typedef struct cmd
{
const char *cmd;
const char *cmd_mess;
unsigned int hash;
cmd_handler handler;
} cmd_t;
Expand Down