修改配置文件,支持历史记录和变量为0

This commit is contained in:
hqm 2023-06-27 22:49:22 +08:00
parent 42af1b6e78
commit a586080941
30 changed files with 138 additions and 2385 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
*DebugConfig/
*Listings/
*OBJ/
*example/arduino/src
example/stm32/qemu/qemu_stm32

View File

@ -38,7 +38,8 @@
"stdio.h": "c",
"xnr_line.h": "c",
"errno.h": "c",
"stdint.h": "c"
"stdint.h": "c",
"*.xcmd_confg": "c"
},
"cmake.sourceDirectory": "/home/hqm/project/xcmd/example/esp_idf",
"MicroPython.executeButton": [

0
README.en.md Executable file
View File

View File

@ -1,5 +1,5 @@
# xcmd
[English Version](./README.en.md)s
#### 效果展示
![输入图片说明](https://images.gitee.com/uploads/images/2021/0922/220957_66faa768_1680380.gif "演示1.gif")
@ -16,13 +16,11 @@ xcmd是一款单片机命令行工具移植十分方便并且对flash与ra
6. **支持 `xcmd_cmd_register()/xcmd_key_register`方法注册命令或按键**
7. **支持 `XCMD_EXPORT_CMD()/XCMD_EXPORT_KEY()`方法直接导出命令或按键,不需要额外运行注册函数**
#### 支持的平台
#### 支持的平台示例
1. linux
2. arduino
3. stm32
4. esp32
5. qemu-stm32
3. esp32
#### 测试过的串口软件
@ -50,34 +48,38 @@ xcmd是一款单片机命令行工具移植十分方便并且对flash与ra
```C
/* 例如移植到Arduino平台 */
int cmd_get_char(uint8_t *ch)
#include "src/xcmd.h"
#include "arduino_xcmd.h"
#include <Arduino.h>
xcmder_t xcmder;
static int io_write(int fd, const char *buf, size_t len)
{
if(Serial.available())
{
*ch = Serial.read();
return 1;
}
else
{
return 0;
}
Serial.write(buf, len);
return len;
}
int cmd_put_char(uint8_t ch)
static int io_read(int fd, char *buf, size_t len)
{
Serial.write(ch);
return 1;
int i=0;
while (Serial.available() > 0)
{
buf[i++] = (char)Serial.read();
}
return i;
}
void setup() {
Serial.begin(115200);
xcmd_init(cmd_get_char, cmd_put_char);
xcmd_init(&xcmder, io_write, io_read);
}
void loop() {
xcmd_task();
xcmd_task(&xcmder);
}
```
#### 配置
@ -87,12 +89,50 @@ void loop() {
**注意** 如果不知道如何修改连接脚本建议不要使能ENABLE_XCMD_EXPORT。不使能ENABLE_XCMD_EXPORT的情况下有更好的兼容性移植更加简单
```C
#define XCMD_LINE_MAX_LENGTH (128) /* 命令行支持的最大字符数 */
#define XCMD_HISTORY_MAX_NUM (16) /* 支持的历史记录个数, 这个参数对内存的影响很大建议arduino设置为00为不支持 */
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
// #define XCMD_DEFAULT_PROMPT "->" /* 提示符 */
// #define XCMD_DEFAULT_PROMPT_CLOLR TX_GREEN /* 提示符颜色 */
// #define ENABLE_XCMD_EXPORT /* 需要修改lds启用后支持XCMD_EXPORT_CMD和XCMD_EXPORT_KEY方法导出命令 */
#ifndef XCMD_LINE_MAX_LENGTH
#define XCMD_LINE_MAX_LENGTH (32) /* 命令行支持的最大字符数 */
#endif
#ifndef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (64) /* xcmd_print缓存 */
#endif
#ifndef XCMD_HISTORY_BUF_SZIE
#define XCMD_HISTORY_BUF_SZIE (64) /* 支持的历史记录个数, 这个参数对内存的影响很大建议arduino设置为00为不支持 */
#endif
#ifndef XCMD_PARAM_MAX_NUM
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
#endif
#if XCMD_PRINT_BUF_MAX_LENGTH < (XCMD_LINE_MAX_LENGTH+32)
#undef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#endif
#ifndef XCMD_DEFAULT_PROMPT
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#endif
#ifndef XCMD_DEFAULT_PROMPT_CLOLR
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#endif
#ifndef XCMD_VAR_NUM
#define XCMD_VAR_NUM (4)
#endif
#ifndef XCMD_VAR_NAME_BUF_SZIE
#define XCMD_VAR_NAME_BUF_SZIE (32)
#endif
#ifndef XCMD_VAR_VAR_SZIE
#define XCMD_VAR_VAR_SZIE (32)
#endif
#ifndef ENABLE_XCMD_EXPORT
//#define ENABLE_XCMD_EXPORT /*使能XCMD_EXPORT_CMD和XCMD_EXPORT_KEY*/
#endif
```
#### 使用说明

View File

@ -5,50 +5,28 @@
extern "C" {
#endif
#ifndef XCMD_LINE_MAX_LENGTH
#define XCMD_LINE_MAX_LENGTH (32) /* 命令行支持的最大字符数 */
#endif
#define XCMD_LINE_MAX_LENGTH (32) /* 命令行支持的最大字符数 */
#ifndef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (64) /* xcmd_print缓存 */
#endif
#define XCMD_PRINT_BUF_MAX_LENGTH (64) /* xcmd_print缓存 */
#ifndef XCMD_HISTORY_BUF_SZIE
#define XCMD_HISTORY_BUF_SZIE (64) /* 支持的历史记录个数, 这个参数对内存的影响很大建议arduino设置为00为不支持 */
#endif
#define XCMD_HISTORY_BUF_SZIE (128) /* 支持的历史记录缓存大小实际历史记录个数取决于记录的命令长度建议内存较小的单片机设置为0 */
#ifndef XCMD_PARAM_MAX_NUM
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
#endif
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
#if XCMD_PRINT_BUF_MAX_LENGTH < (XCMD_LINE_MAX_LENGTH+32)
#undef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#endif
#ifndef XCMD_DEFAULT_PROMPT
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#endif
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#ifndef XCMD_DEFAULT_PROMPT_CLOLR
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#endif
#ifndef XCMD_VAR_NUM
#define XCMD_VAR_NUM (4)
#endif
#define XCMD_VAR_NUM (0) /* 支持的变量的个数可以为0 */
#define XCMD_VAR_NAME_BUF_SZIE (0) /* 变量名最大长度可以为0 */
#define XCMD_VAR_VAR_SZIE (0) /* 变量最大长度可以为0 */
#ifndef XCMD_VAR_NAME_BUF_SZIE
#define XCMD_VAR_NAME_BUF_SZIE (32)
#endif
#ifndef XCMD_VAR_VAR_SZIE
#define XCMD_VAR_VAR_SZIE (32)
#endif
#ifndef ENABLE_XCMD_EXPORT
//#define ENABLE_XCMD_EXPORT /*使能XCMD_EXPORT_CMD和XCMD_EXPORT_KEY*/
#endif
#ifdef __cplusplus
}

View File

@ -1,372 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include "xcmd.h"
#include "xcmd_cmds.h"
#include "xcmd_keys.h"
static struct
{
xcmd_t head;
} g_cmd_list;
static struct
{
xcmd_key_t head;
} g_key_list;
int xcmd_key_register(xcmd_key_t *keys, uint16_t number)
{
#ifndef ENABLE_XCMD_EXPORT
uint16_t i = 0;
xcmd_key_t *temp;
while (i < number)
{
temp = g_key_list.head.next;
g_key_list.head.next = &keys[i];
keys[i].next = temp;
++i;
}
#endif
return 0;
}
int xcmd_cmd_register(xcmd_t *cmds, uint16_t number)
{
#ifndef ENABLE_XCMD_EXPORT
xcmd_t *temp;
uint16_t i = 0;
while (i < number)
{
temp = g_cmd_list.head.next;
g_cmd_list.head.next = &cmds[i];
cmds[i].next = temp;
++i;
}
#endif
return 0;
}
int xcmd_unregister_key(char *key)
{
#ifndef ENABLE_XCMD_EXPORT
xcmd_key_t *bk = &g_key_list.head;
xcmd_key_t *p = NULL;
XCMD_KEY_FOR_EACH(p)
{
if (strcmp(key, p->name) == 0)
{
bk->next = p->next;
return 0;
}
bk = p;
}
#endif
return -1;
}
int xcmd_unregister_cmd(char *cmd)
{
#ifndef ENABLE_XCMD_EXPORT
xcmd_t *bk = &g_cmd_list.head;
xcmd_t *p = NULL;
XCMD_CMD_FOR_EACH(p)
{
if (strcmp(cmd, p->name) == 0)
{
bk->next = p->next;
return 0;
}
bk = p;
}
#endif
return -1;
}
xcmd_key_t *xcmd_keylist_get(void)
{
#ifndef ENABLE_XCMD_EXPORT
return g_key_list.head.next;
#else
return &_xcmd_key_list_start;
#endif
}
xcmd_t *xcmd_cmdlist_get(void)
{
#ifndef ENABLE_XCMD_EXPORT
return g_cmd_list.head.next;
#else
return &_xcmd_cmd_list_start;
#endif
}
static void xcmd_key_match(xcmder_t *xcmder, char *key)
{
xcmd_key_t *p = NULL;
XCMD_KEY_FOR_EACH(p)
{
if (strcmp(key, p->name) == 0)
{
if (p->func(0, (char **)&xcmder) == 0)
{
break;
}
}
}
}
static int xcmd_cmd_match(xcmder_t *xcmder, int argc, char *argv[])
{
uint8_t flag = 0;
int ret = -1;
xcmd_t *p = NULL;
XCMD_CMD_FOR_EACH(p)
{
if (strcmp(p->name, argv[0]) == 0)
{
flag = 1;
if (argc > 1)
{
if (p->help && ((strcmp(argv[1], "?") == 0) || (strcmp(argv[1], "-h") == 0)))
{
xcmd_print(xcmder, "%s\r\n", p->help);
break;
}
}
if (xcmder->pre_cmd_cbk)
{
argc = xcmder->pre_cmd_cbk(argc, argv);
argv[argc] = (char *)xcmder;
}
ret = p->func(argc, argv);
if (xcmder->after_cmd_cbk)
argc = xcmder->after_cmd_cbk(argc, argv);
break;
}
}
if (0 == flag)
{
if (NULL == xcmder->unknow_cmd_cbk)
xcmd_print(xcmder, "cmd \"%s\" does not exist\r\n", argv[0]);
else
xcmder->unknow_cmd_cbk(argc, argv);
}
return ret;
}
int xcmd_exec(xcmder_t *xcmder, char *str)
{
int param_num = 0;
int ret = -1;
char *cmd_param_buff[XCMD_PARAM_MAX_NUM + 1];
char temp[XNR_LINE_MAX_LENGTH];
strncpy(temp, str, XNR_LINE_MAX_LENGTH);
param_num = xnr_line_tok(temp, " ", cmd_param_buff, XCMD_PARAM_MAX_NUM);
if (param_num > 0)
{
cmd_param_buff[param_num] = (char *)xcmder;
ret = xcmd_cmd_match(xcmder, param_num, cmd_param_buff);
}
xnr_line_clear(&xcmder->line);
return ret;
}
static void xcmd_key_exec(xcmder_t *xcmder, char *key)
{
xcmd_key_match(xcmder, key);
}
void xcmd_task(xcmder_t *xcmder)
{
int c;
if (xcmder->_initOK)
{
c = xnr_io_getc(&xcmder->io);
if (xnr_key_encode(&xcmder->key, c))
{
char *key_val = xnr_key_val(&xcmder->key);
if (isprint((int)key_val[0u])) // 可显示字符
{
xnr_line_insert(&xcmder->line, c); // 向行中插入可显示字符
}
else // 不可显示字符,即快捷键
{
xcmd_key_exec(xcmder, key_val);
}
}
}
}
void xcmd_reg_unknow_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk)
{
xcmder->unknow_cmd_cbk = cbk;
}
void xcmd_reg_pre_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk)
{
xcmder->pre_cmd_cbk = cbk;
}
void xcmd_reg_after_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk)
{
xcmder->after_cmd_cbk = cbk;
}
int xcmd_getopt(xcmder_t *xcmder, int argc, char *const argv[], const char *optstring)
{
static char *nextc = NULL; // 字符串中下一个选项字符位置
char *c = NULL; // 选项字符
int has_arg = 0; // 选项是否有参数
int is_long_opt = 0; // 是否是长选项
int opt_long_index = -1; // 如果是长选项,存储它的下标
xcmder->optarg = 0;
if (nextc == NULL || *nextc == '\0')
{
if (xcmder->optind >= argc || argv[xcmder->optind][0] != '-' || argv[xcmder->optind][1] == '\0')
{
return -1;
}
nextc = argv[xcmder->optind] + 1;
if (*nextc == '-')
{
is_long_opt = 1;
nextc++;
}
xcmder->optind++;
}
if (is_long_opt)
{
// 如果是长选项,查找选项字符串和操作数
char buf[XCMD_PARAM_MAX_NUM + 1];
char *p = strchr(nextc, '=');
if (p != NULL)
{
// 选项字符串和操作数之间有等号
int len = p - nextc;
if (len > XCMD_PARAM_MAX_NUM)
{
return '?';
}
strncpy(buf, nextc, len);
buf[len] = '\0';
nextc = p + 1;
xcmder->optarg = nextc;
nextc = NULL; // xcmder->optarg 后面不会再有操作数
}
else
{
// 选项字符串后没有等号
int len = strlen(nextc);
if (len > XCMD_PARAM_MAX_NUM)
{
return '?';
}
strncpy(buf, nextc, XCMD_PARAM_MAX_NUM);
nextc = NULL;
}
// 在 optstring 中查找长选项
int i;
for (i = 0; optstring[i] != '\0'; i += 2)
{
if (optstring[i] == ':' || optstring[i + 1] == ':')
{
// 忽略有错误格式的选项(参见实例代码,有两个冒号的应该可以解析出错)
continue;
}
if (strcmp(buf, optstring + i) == 0)
{
opt_long_index = i / 2;
break;
}
}
}
else
{
c = nextc++;
has_arg = 0;
if (*nextc == ':')
{
has_arg = 1;
nextc++;
}
if (*c == ':' || strchr(optstring, *c) == NULL)
{
return '?';
}
}
if (opt_long_index >= 0 || has_arg)
{
if (nextc != NULL)
{
xcmder->optarg = nextc;
nextc = NULL;
}
else if (xcmder->optind < argc)
{
xcmder->optarg = argv[xcmder->optind];
xcmder->optind++;
}
else
{
return ':';
}
}
if (opt_long_index >= 0)
{
return optstring[opt_long_index * 2];
}
else
{
return *c;
}
}
void xcmd_init(xcmder_t *xcmder, io_write_t write, io_read_t read)
{
if (write && read && xcmder && 0 == xcmder->_initOK)
{
xcmder->unknow_cmd_cbk = NULL;
xcmder->pre_cmd_cbk = NULL;
xcmder->after_cmd_cbk = NULL;
xcmder->user_data = NULL;
xcmder->optarg = NULL;
xcmder->optind = 1;
#ifndef ENABLE_XCMD_EXPORT
g_cmd_list.head.next = NULL;
#endif
xnr_var_init(&xcmder->var_tab, xcmder->var_buf, XCMD_VAR_NUM);
xnr_io_init(&xcmder->io, write, read);
xnr_key_init(&xcmder->key);
xnr_line_init(&xcmder->line, &xcmder->io);
xnr_history_init(&xcmder->history, &xcmder->io);
default_cmds_init();
default_keys_init();
xcmd_exec(xcmder, "logo");
xcmd_unregister_cmd("logo");
xnr_var_set(&xcmder->var_tab, "prompt", ANSI_COLOR_TXT(XCMD_DEFAULT_PROMPT_CLOLR, XCMD_DEFAULT_PROMPT));
char *var_val = xnr_var_value(&xcmder->var_tab, "prompt");
xnr_line_bind_prompt(&xcmder->line, var_val);
xnr_line_clear(&xcmder->line);
xcmder->_initOK = 1;
}
}

View File

@ -1,139 +0,0 @@
#ifndef XCMD_H
#define XCMD_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "xnr_line.h"
#include "xnr_history.h"
#include "xnr_io.h"
#include "xnr_key.h"
#include "xnr_var.h"
#include "xcmd_confg.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef int (*cmd_func_t)(int, char **);
typedef struct cmd
{
const char *name;
cmd_func_t func;
const char *help;
#ifndef ENABLE_XCMD_EXPORT
struct cmd *next;
#endif
} xcmd_t;
typedef xcmd_t xcmd_key_t;
#ifndef XCMD_PARAM_MAX_NUM
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
#endif
#define XCMD_CURRENT() ((xcmder_t *)(argv[argc]))
#ifndef XCMD_SECTION
#if defined(__CC_ARM) || defined(__CLANG_ARM)
#define XCMD_SECTION(x) __attribute__((section(x)))
#elif defined(__IAR_SYSTEMS_ICC__)
#define XCMD_SECTION(x) @x
#elif defined(__GNUC__)
#define XCMD_SECTION(x) __attribute__((section(x)))
#else
#define XCMD_SECTION(x)
#endif
#endif
#ifndef XCMD_USED
#if defined(__CC_ARM) || defined(__CLANG_ARM)
#define XCMD_USED __attribute__((used))
#elif defined(__IAR_SYSTEMS_ICC__)
#define XCMD_USED __root
#elif defined(__GNUC__)
#define XCMD_USED __attribute__((used))
#else
#define XCMD_USED
#endif
#endif
#ifdef ENABLE_XCMD_EXPORT
#define XCMD_EXPORT_CMD(_name, _func, _help) XCMD_USED const xcmd_t XCMD_SECTION("_xcmd_cmd_list") \
xcmd_cmd_##_name = { \
.name = #_name, \
.func = _func, \
.help = _help};
#define XCMD_EXPORT_KEY(_key, _func, _help) XCMD_USED const xcmd_key_t XCMD_SECTION("_xcmd_key_list") \
xcmd_key_##_key = { \
.key = _key, \
.func = _func, \
.help = _help};
extern xcmd_t _xcmd_cmd_list_start;
extern xcmd_t _xcmd_cmd_list_end;
extern xcmd_key_t _xcmd_key_list_start;
extern xcmd_key_t _xcmd_key_list_end;
#define XCMD_CMD_FOR_EACH(pos) for ((pos) = &_xcmd_cmd_list_start; (pos) < &_xcmd_cmd_list_end; ++(pos))
#define XCMD_KEY_FOR_EACH(pos) for ((pos) = &_xcmd_key_list_start; (pos) < &_xcmd_key_list_end; ++(pos))
#else
/**
* @description: next指针可以遍历所有指令
* @param {*}
* @param {}
* @return {xcmd_t *}
*/
xcmd_t *xcmd_cmdlist_get(void);
/**
* @description: next指针可以遍历所有按键
* @param {*}
* @param {}
* @return {xcmd_key_t *}
*/
xcmd_key_t *xcmd_keylist_get(void);
#define XCMD_EXPORT_CMD(name, func, help)
#define XCMD_EXPORT_KEY(key, func, help)
#define XCMD_CMD_FOR_EACH(pos) for ((pos) = xcmd_cmdlist_get(); (pos); (pos) = (pos)->next)
#define XCMD_KEY_FOR_EACH(pos) for ((pos) = xcmd_keylist_get(); (pos); (pos) = (pos)->next)
#endif
#define xcmd_print(xcmder, fmt, args...) xnr_io_printf(&(xcmder)->io, fmt, ##args)
#define xcmd_puts(xcmder, str) xnr_io_puts(&(xcmder)->io, str)
#define xcmd_putc(xcmder, c) xnr_io_putc(&(xcmder)->io, c)
#define xcmd_getc(xcmder) xnr_io_getc(&(xcmder)->io)
typedef struct xcmd
{
xnr_io_t io;
xnr_key_t key;
xnr_var_tab_t var_tab;
xnr_var_t var_buf[XCMD_VAR_NUM];
xnr_history_t history;
xnr_line_t line;
cmd_func_t unknow_cmd_cbk; // 输入为命令序列,输出未处理
cmd_func_t pre_cmd_cbk; // 输入为命令序列输出重新赋值给argc
cmd_func_t after_cmd_cbk; // 输入为命令序列,输出未处理
void *user_data; // 用户数据
int optind; // 选项在参数列表中的位置
char *optarg; // 选项参数的值
bool _initOK;
} xcmder_t;
void xcmd_init(xcmder_t *xcmder, io_write_t write, io_read_t read);
void xcmd_task(xcmder_t *xcmder);
void xcmd_reg_unknow_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk);
void xcmd_reg_pre_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk);
void xcmd_reg_after_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk);
int xcmd_exec(xcmder_t *xcmder, char *str);
int xcmd_getopt(xcmder_t *xcmder, int argc, char * const argv[], const char *optstring);
int xcmd_key_register(xcmd_key_t *keys, uint16_t number);
int xcmd_unregister_key(char *key);
int xcmd_cmd_register(xcmd_t *cmds, uint16_t number);
int xcmd_unregister_cmd(char *cmd);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,100 +0,0 @@
#include "xcmd_confg.h"
#include "xcmd_cmds.h"
#include "xcmd.h"
#include <stdlib.h>
#define VERSION "2.0 .0"
static int cmd_clear(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xcmd_print(xcmder, "\033c");
return 0;
}
static int cmd_help(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xcmd_t *p = NULL;
XCMD_CMD_FOR_EACH(p)
{
xcmd_print(xcmder, "%-20s %s\r\n",p->name, p->help);
}
return 0;
}
static int cmd_keys(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xcmd_key_t *p = NULL;
XCMD_KEY_FOR_EACH(p)
{
xcmd_print(xcmder, "0x%08X\t", p->name);
xcmd_print(xcmder, "%s\r\n",p->help);
}
return 0;
}
static int cmd_logo(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
char *log = "\
_ _ ___ __ __ ____ \r\n\
( \\/ )/ __)( \\/ )( _ \\ \r\n\
) (( (__ ) ( )(_) )\r\n\
(_/\\_)\\___)(_/\\/\\_)(____/\r\n ";
xcmd_puts(xcmder, log);
xcmd_print(xcmder, "\r\n%-10s %s %s\r\n","Build" ,__DATE__, __TIME__);
xcmd_print(xcmder, "%-10s %s\r\n","Version", VERSION);
return 0;
}
static int cmd_set(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
if(argc >= 3)
{
xnr_var_set(&xcmder->var_tab, argv[1], argv[2]);
}
return 0;
}
static int cmd_var(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
int id = 0;
xnr_var_t *var;
while(1)
{
var = xnr_var(&xcmder->var_tab, id++);
if(NULL == var)
break;
if(var->name[0] != '\0')
xcmd_print(xcmder, "%-15s:%s\n", var->name, var->value);
}
return 0;
}
XCMD_EXPORT_CMD(clear, cmd_clear, "clear screen")
XCMD_EXPORT_CMD(help, cmd_help, "show this list")
XCMD_EXPORT_CMD(keys, cmd_keys, "show keys")
XCMD_EXPORT_CMD(logo, cmd_logo, "show logo")
XCMD_EXPORT_CMD(setvar, cmd_set, "set var")
XCMD_EXPORT_CMD(var, cmd_var, "get all var")
static xcmd_t cmds[] =
{
#ifndef ENABLE_XCMD_EXPORT
{"clear", cmd_clear, "clear screen", NULL},
{"help", cmd_help, "show this list", NULL},
{"keys", cmd_keys, "show keys", NULL},
{"logo", cmd_logo, "show logo", NULL},
{"setvar", cmd_set, "set var", NULL},
{"var", cmd_var, "get all var", NULL},
#endif
};
void default_cmds_init(void)
{
xcmd_cmd_register(cmds, sizeof(cmds)/sizeof(xcmd_t));
}

View File

@ -1,15 +0,0 @@
#ifndef XCMMD_DEFAULT_CMDS_H
#define XCMMD_DEFAULT_CMDS_H
#ifdef __cplusplus
extern "C" {
#endif
void default_cmds_init(void);
#ifdef __cplusplus
}
#endif
#endif /*XCMMD_DEFAULT_CMDS_H*/

View File

@ -1,57 +0,0 @@
#ifndef xcmd_confg_H
#define xcmd_confg_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XCMD_LINE_MAX_LENGTH
#define XCMD_LINE_MAX_LENGTH (32) /* 命令行支持的最大字符数 */
#endif
#ifndef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (64) /* xcmd_print缓存 */
#endif
#ifndef XCMD_HISTORY_BUF_SZIE
#define XCMD_HISTORY_BUF_SZIE (64) /* 支持的历史记录个数, 这个参数对内存的影响很大建议arduino设置为00为不支持 */
#endif
#ifndef XCMD_PARAM_MAX_NUM
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
#endif
#if XCMD_PRINT_BUF_MAX_LENGTH < (XCMD_LINE_MAX_LENGTH+32)
#undef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#endif
#ifndef XCMD_DEFAULT_PROMPT
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#endif
#ifndef XCMD_DEFAULT_PROMPT_CLOLR
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#endif
#ifndef XCMD_VAR_NUM
#define XCMD_VAR_NUM (4)
#endif
#ifndef XCMD_VAR_NAME_BUF_SZIE
#define XCMD_VAR_NAME_BUF_SZIE (32)
#endif
#ifndef XCMD_VAR_VAR_SZIE
#define XCMD_VAR_VAR_SZIE (32)
#endif
#ifndef ENABLE_XCMD_EXPORT
//#define ENABLE_XCMD_EXPORT /*使能XCMD_EXPORT_CMD和XCMD_EXPORT_KEY*/
#endif
#ifdef __cplusplus
}
#endif
#endif /* xcmd_confg_H */

View File

@ -1,166 +0,0 @@
#include "xcmd_confg.h"
#include "xcmd.h"
#include "xcmd_keys.h"
static int xcmd_str_match(const char *str1, const char *str2)
{
int i = 0;
for (i = 0; str1[i] && str2[i]; i++)
{
if (str1[i] != str2[i])
{
break;
}
}
return i;
}
static int xcmd_del_char(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xnr_line_delete(&xcmder->line);
return 0;
}
XCMD_EXPORT_KEY(KEY_CTR_H, xcmd_del_char, "backspace")
XCMD_EXPORT_KEY(KEY_BACKSPACE, xcmd_del_char, "delete")
static int xcmd_enter(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
char out_line[XNR_LINE_MAX_LENGTH] = {0};
xcmd_print(xcmder, "\n\r");
char *line = xnr_line_line(&xcmder->line);
xnr_history_append(&xcmder->history, line);
xnr_var_repalce(&xcmder->var_tab, line, out_line, XNR_LINE_MAX_LENGTH);
if (out_line[0])
{
xcmd_exec(xcmder, out_line);
}
else
{
xnr_line_clear(&xcmder->line);
}
return 0;
}
XCMD_EXPORT_KEY(KEY_CTR_M, xcmd_enter, "enter")
XCMD_EXPORT_KEY(KEY_CTR_J, xcmd_enter, "enter")
static int xcmd_cursor_left(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xnr_line_cursor_left(&xcmder->line);
return 0;
}
XCMD_EXPORT_KEY(KEY_LEFT, xcmd_cursor_left, "left")
static int xcmd_cursor_right(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xnr_line_cursor_right(&xcmder->line);
return 0;
}
XCMD_EXPORT_KEY(KEY_RIGHT, xcmd_cursor_right, "right")
static int xcmd_history_dw(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
char out_line[XNR_LINE_MAX_LENGTH] = {0};
if (xnr_history_dw(&xcmder->history, out_line, XNR_LINE_MAX_LENGTH) > 0)
{
xnr_line_clear(&xcmder->line);
xnr_line_puts(&xcmder->line, out_line);
}
else
{
xnr_line_clear(&xcmder->line);
}
return 0;
}
XCMD_EXPORT_KEY(KEY_DW, xcmd_history_dw, "down")
static int xcmd_history_up(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
char out_line[XNR_LINE_MAX_LENGTH] = {0};
if (xnr_history_up(&xcmder->history, out_line, XNR_LINE_MAX_LENGTH) > 0)
{
xnr_line_clear(&xcmder->line);
xnr_line_puts(&xcmder->line, out_line);
}
return 0;
}
XCMD_EXPORT_KEY(KEY_UP, xcmd_history_up, "up")
static int xcmd_auto_completion(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
xcmd_t *match_cmd_first = NULL;
uint16_t match_num = 0;
uint16_t match_subscript_min = 0;
char *display_line = xnr_line_line(&xcmder->line);
uint16_t cursor_pos = xnr_line_cursor(&xcmder->line);
xcmd_t *p = NULL;
XCMD_CMD_FOR_EACH(p)
{
if (strncmp(display_line, p->name, cursor_pos) == 0)
{
if (match_num == 0)
{
match_cmd_first = p;
match_subscript_min = strlen(p->name);
}
else if (match_num == 1)
{
xcmd_print(xcmder, "\r\n%-15s%-15s", match_cmd_first->name, p->name);
}
else
{
xcmd_print(xcmder, "%-15s", p->name);
if ((match_num % 4) == 0)
{
xcmd_print(xcmder, "\r\n");
}
}
uint16_t subscript = xcmd_str_match(match_cmd_first->name, p->name);
if (subscript < match_subscript_min)
{
match_subscript_min = subscript;
}
match_num++;
}
}
if (match_num == 1)
{
xnr_line_clear(&xcmder->line);
xnr_line_puts(&xcmder->line, match_cmd_first->name);
}
else if (match_num > 1)
{
xcmd_print(xcmder, "\r\n");
xnr_line_clear(&xcmder->line);
xnr_line_write(&xcmder->line, match_cmd_first->name, match_subscript_min);
}
return 0;
}
XCMD_EXPORT_KEY(KEY_TAB, xcmd_auto_completion, "tab")
static xcmd_key_t default_keys[] =
{
#ifndef ENABLE_XCMD_EXPORT
{KEY_CTR_M, xcmd_enter, "enter", NULL},
{KEY_CTR_J, xcmd_enter, "enter", NULL},
{KEY_CTR_H, xcmd_del_char, "backspace", NULL},
{KEY_BACKSPACE, xcmd_del_char, "delete", NULL},
{KEY_LEFT, xcmd_cursor_left, "left", NULL},
{KEY_RIGHT, xcmd_cursor_right, "right", NULL},
{KEY_TAB, xcmd_auto_completion, "tab", NULL},
{KEY_DW, xcmd_history_dw, "down", NULL},
{KEY_UP, xcmd_history_up, "up", NULL},
#endif
};
void default_keys_init(void)
{
xcmd_key_register(default_keys, sizeof(default_keys) / sizeof(xcmd_key_t));
}

View File

@ -1,14 +0,0 @@
#ifndef xcmd_keys_H
#define xcmd_keys_H
#ifdef __cplusplus
extern "C" {
#endif
void default_keys_init(void);
#ifdef __cplusplus
}
#endif
#endif /* xcmd_keys_H */

View File

@ -1,31 +0,0 @@
#ifndef XNR_CONF_H
#define XNR_CONF_H
#include "xcmd_confg.h"
//行缓存长度
#ifndef XNR_LINE_MAX_LENGTH
#define XNR_LINE_MAX_LENGTH (XCMD_LINE_MAX_LENGTH)
#endif
//历史记录缓存长度
#ifndef XNR_HISTORY_BUF_SZIE
#define XNR_HISTORY_BUF_SZIE (XCMD_HISTORY_BUF_SZIE)
#endif
//变量名长度
#ifndef XNR_VAR_NAME_LEN
#define XNR_VAR_NAME_LEN (XCMD_VAR_NAME_BUF_SZIE)
#endif
//变量值长度
#ifndef XNR_VAR_VAR_LEN
#define XNR_VAR_VAR_LEN (XCMD_VAR_VAR_SZIE)
#endif
//IO print缓存大小
#ifndef XNR_PRINT_BUF_MAX_LENGTH
#define XNR_PRINT_BUF_MAX_LENGTH (XCMD_PRINT_BUF_MAX_LENGTH)
#endif
#endif

View File

@ -1,191 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "xnr_history.h"
int xnr_history_init(xnr_history_t *history, xnr_io_t *io)
{
if (NULL == history || NULL == io)
return -1;
history->head = 0;
history->tail = 0;
history->length = 0;
history->id = 0;
history->io = io;
memset(history->buffer, 0, XNR_HISTORY_BUF_SZIE);
return 0;
}
int xnr_history_clear(xnr_history_t *history)
{
return xnr_history_init(history, history->io);
}
int xnr_history_length(xnr_history_t *history)
{
return history->length;
}
int xnr_history_append(xnr_history_t *history, char *cmd)
{
if ((history == NULL) || (cmd == NULL))
return -1;
int len = strlen(cmd) + 1; // 包括'\0'
if (len == 1 || len > (XNR_HISTORY_BUF_SZIE - 1))
return -1;
if (xnr_history_cmp(history, -1, cmd) != 0) // 最近的一次历史记录不同
{
for (int i = 0; i < len; i++)
{
history->buffer[history->head++] = cmd[i];
history->head %= XNR_HISTORY_BUF_SZIE;
if (history->head == history->tail) // 缓存空间不足
{
while (1)
{
history->buffer[history->tail++] = '\0';
history->tail %= XNR_HISTORY_BUF_SZIE;
if (history->buffer[history->tail] == '\0')
{
++history->tail;
history->tail %= XNR_HISTORY_BUF_SZIE;
break;
}
}
--history->length;
}
}
++history->length;
}
history->id = 0;
return 0;
}
int xnr_history_pos(xnr_history_t *history, int id)
{
if ((history == NULL))
return -1;
if (history->head == history->tail)
return -1; // buffer中没有缓存历史命令
int pos = history->tail;
if (id < 0)
{
id = -id;
if (id > (history->length)) // 负id从1开始
{
return -1; // id超限
}
pos = history->head - 1;
pos = pos < 0 ? (XNR_HISTORY_BUF_SZIE - 1) : pos;
for (int i = 0; i < id; i++)
{
while (1)
{
--pos;
pos = pos < 0 ? (XNR_HISTORY_BUF_SZIE - 1) : pos;
if (history->buffer[pos] == '\0')
{
break;
}
}
}
++pos;
pos %= XNR_HISTORY_BUF_SZIE;
}
else
{
if (id > (history->length - 1)) // 正id从0开始
{
return -1; // id超限
}
for (int i = 0; i < id; i++)
{
while (1)
{
++pos;
pos %= XNR_HISTORY_BUF_SZIE;
if (history->buffer[pos] == '\0')
{
++pos;
pos %= XNR_HISTORY_BUF_SZIE;
break;
}
}
}
}
return pos;
}
int xnr_history_get(xnr_history_t *history, int id, char *buf, int buf_len)
{
if ((history == NULL) || (buf == NULL) || (buf_len == 0))
return 0;
int pos = xnr_history_pos(history, id);
if (pos < 0)
return 0; // id超限
for (int i = 0; i < buf_len; i++)
{
buf[i] = history->buffer[pos++];
pos %= XNR_HISTORY_BUF_SZIE;
if (buf[i] == '\0')
{
return i; // 返回字符串的长度
}
}
buf[buf_len - 1] = '\0';
return -(buf_len - 1); // 由于buf的size小于历史命令返回字符串的长度
}
int xnr_history_cmp(xnr_history_t *history, int id, char *cmd)
{
if ((history == NULL) || (cmd == NULL))
return -1;
int pos = xnr_history_pos(history, id);
if (pos < 0)
return -1; // id超限
char c;
while (1)
{
c = history->buffer[pos++];
pos %= XNR_HISTORY_BUF_SZIE;
if (c && *cmd && (c == *cmd))
{
++cmd;
}
else
{
break;
}
}
return *cmd - c;
}
int xnr_history_up(xnr_history_t *history, char *buf, int buf_len)
{
int id = history->id;
int ret = 0;
ret = xnr_history_get(history, --id, buf, buf_len);
if (ret > 0)
{
history->id = id;
}
return ret;
}
int xnr_history_dw(xnr_history_t *history, char *buf, int buf_len)
{
int id = history->id;
int ret = 0;
if (id >= -1)
{
history->id = 0;
return ret;
}
ret = xnr_history_get(history, ++id, buf, buf_len);
if (ret > 0)
{
history->id = id;
}
return ret;
}

View File

@ -1,92 +0,0 @@
#ifndef XNR_HISTORY_H
#define XNR_HISTORY_H
#include "xnr_conf.h"
#include "xnr_io.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XNR_HISTORY_BUF_SZIE
#define XNR_HISTORY_BUF_SZIE (256)
#endif
typedef struct xnr_history //doc/history.drawio
{
char buffer[XNR_HISTORY_BUF_SZIE];
int length;
int head;
int tail;
int id;
xnr_io_t *io;
}xnr_history_t;
/**
* @description:
* @param historyxnr_history实例ioxnr_io实例
* @return -10
*/
int xnr_history_init(xnr_history_t *history, xnr_io_t *io);
/**
* @description:
* @param historyxnr_history实例
* @return -10
*/
int xnr_history_clear(xnr_history_t *history);
/**
* @description:
* @param historyxnr_history实例
* @return
*/
int xnr_history_length(xnr_history_t *history);
/**
* @description:
* @param historyxnr_history实例cmd
* @return -10
*/
int xnr_history_append(xnr_history_t *history, char* cmd);
/**
* @description: ringbuffer对应的起始位置
* @param historyxnr_history实例
* @return -1ringbuffer对应的起始位置
*/
int xnr_history_pos(xnr_history_t *history, int id);
/**
* @description:
* @param historyxnr_history实例idcmd
* @return 0
*/
int xnr_history_cmp(xnr_history_t *history, int id, char *cmd);
/**
* @description:
* @param historyxnr_history实例idbufbufbuf_len
* @return -1
*/
int xnr_history_get(xnr_history_t *history, int id, char *buf, int buf_len);
/**
* @description:
* @param historyxnr_history实例bufbufbuf_len
* @return -1
*/
int xnr_history_up(xnr_history_t *history, char *buf, int buf_len);
/**
* @description:
* @param historyxnr_history实例bufbufbuf_len
* @return -1
*/
int xnr_history_dw(xnr_history_t *history, char *buf, int buf_len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,82 +0,0 @@
#include <stdarg.h>
#include <string.h>
#include "xnr_io.h"
int xnr_io_init(xnr_io_t *io,
io_write_t write,
io_read_t read)
{
if(NULL == io)
return -1;
io->in_fd = STDIN_FILENO;
io->out_fd = STDOUT_FILENO;
io->read = read;
io->write = write;
return 0;
}
int xnr_io_puts(xnr_io_t *io, const char *str)
{
if(NULL == io || NULL == str)
return -1;
return io->write(io->out_fd, str, strlen(str));
}
int xnr_io_putc(xnr_io_t *io, char c)
{
if(NULL == io)
return -1;
return io->write(io->out_fd, &c, 1);
}
int xnr_io_printf(xnr_io_t *io, const char *fmt, ...)
{
if(NULL == io || NULL == fmt)
return -1;
char ucstring[XNR_PRINT_BUF_MAX_LENGTH] = {0};
va_list arg;
va_start(arg, fmt);
int len = vsnprintf(ucstring, XNR_PRINT_BUF_MAX_LENGTH, fmt, arg);
va_end(arg);
return io->write(io->out_fd, ucstring, len);
}
void xnr_io_set_in_fd(xnr_io_t *io, int in_fd)
{
if(NULL == io)
return;
io->in_fd = in_fd;
}
void xnr_io_set_out_fd(xnr_io_t *io, int out_fd)
{
if(NULL == io)
return;
io->out_fd = out_fd;
}
int xnr_io_in_fd(xnr_io_t *io)
{
if(NULL == io)
return -1;
return io->in_fd;
}
int xnr_io_out_fd(xnr_io_t *io)
{
if(NULL == io)
return -1;
return io->out_fd;
}
int xnr_io_getc(xnr_io_t *io)
{
if(NULL == io)
return -1;
char c;
if (io->read(io->in_fd, &c, 1))
{
return c;
}
return -1;
}

View File

@ -1,90 +0,0 @@
#ifndef XNR_IO_H
#define XNR_IO_H
#include <stdio.h>
#include <stddef.h>
#include "xnr_conf.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XNR_PRINT_BUF_MAX_LENGTH
#define XNR_PRINT_BUF_MAX_LENGTH (128)
#endif
/* 标准文件描述符. */
#ifndef STDIN_FILENO
#define STDIN_FILENO 0 /* 标准输入. */
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1 /* 标准输出. */
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2 /* 标准错误. */
#endif
typedef int (*io_write_t)(int fd, const char *buf, size_t len);
typedef int (*io_read_t)(int fd, char *buf, size_t len);
typedef struct xnr_io
{
int in_fd;
int out_fd;
io_write_t write;
io_read_t read;
} xnr_io_t;
/**
* @description:
* @param ioxnr_io实例writereadin_fdfd out_fdfd
*
* @return -10
*/
int xnr_io_init(xnr_io_t *io,
io_write_t write,
io_read_t read);
/**
* @description: fd
* @param ioxnr_io实例in_fd out_fd
* @return
*/
void xnr_io_set_in_fd(xnr_io_t *io, int in_fd);
void xnr_io_set_out_fd(xnr_io_t *io, int out_fd);
int xnr_io_in_fd(xnr_io_t *io);
int xnr_io_out_fd(xnr_io_t *io);
/**
* @description:
* @param ioxnr_io实例fmt...
* @return -1
*/
int xnr_io_printf(xnr_io_t *io, const char *fmt, ...);
/**
* @description:
* @param ioxnr_io实例str
* @return -1
*/
int xnr_io_puts(xnr_io_t *io, const char *str);
/**
* @description:
* @param ioxnr_io实例c
* @return -1
*/
int xnr_io_putc(xnr_io_t *io, char c);
/**
* @description:
* @param ioxnr_io实例
* @return -1
*/
int xnr_io_getc(xnr_io_t *io);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,70 +0,0 @@
#include "xnr_key.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define _IS_END_KEY(c) ((((c) >= 'A') && ((c) <= 'D')) || (((c) >= 'P') && ((c) <= 'S')) || \
((c) == '~') || ((c) == 'H') || ((c) == 'F'))
char *xnr_key_val(xnr_key_t *key)
{
if(NULL == key)
return NULL;
return key->encode_buf;
}
int xnr_key_encode(xnr_key_t *key, int ch)
{
if((NULL == key) || (-1 == ch))
return 0;
int ret = 0;
switch (key->case_stu)
{
case 0: //开始状态
key->encode_cnt = 0;
if (ch == 0x1B) //输入的字符是 ESC
{
key->encode_buf[key->encode_cnt++] = ch;
key->case_stu = 1;
}
else
{
key->encode_buf[key->encode_cnt++] = ch;
key->encode_buf[key->encode_cnt] = '\0';
key->encode_cnt = 0;
ret = 1;
}
break;
case 1:
if (_IS_END_KEY(ch))
{
key->encode_buf[key->encode_cnt++] = ch;
key->encode_buf[key->encode_cnt] = '\0';
ret = key->encode_cnt;
key->case_stu = 0;
}
else
{
key->encode_buf[key->encode_cnt++] = ch;
if (key->encode_cnt >= 6)
{
key->case_stu = 0;
ret = 0;
}
}
break;
default:
break;
}
return ret;
}
int xnr_key_init(xnr_key_t *key)
{
if (NULL == key)
return -1;
key->case_stu = 0;
key->encode_cnt = 0;
return 0;
}

View File

@ -1,98 +0,0 @@
#ifndef XNR_KEY_H
#define XNR_KEY_H
#ifdef __cplusplus
extern "C" {
#endif
#define KEY_CTR_A "\x01"
#define KEY_CTR_B "\x02"
#define KEY_CTR_C "\x03"
#define KEY_CTR_D "\x04"
#define KEY_CTR_E "\x05"
#define KEY_CTR_F "\x06"
#define KEY_CTR_G "\x07"
#define KEY_CTR_H "\x08"
#define KEY_CTR_I "\x09"
#define KEY_TAB "\x09"
#define KEY_CTR_J "\x0A"
#define KEY_CTR_K "\x0B"
#define KEY_CTR_L "\x0C"
#define KEY_CTR_M "\x0D"
#define KEY_ENTER "\n"
#define KEY_CTR_N "\x0E"
#define KEY_CTR_O "\x0F"
#define KEY_CTR_P "\x10"
#define KEY_CTR_Q "\x11"
#define KEY_CTR_R "\x12"
#define KEY_CTR_S "\x13"
#define KEY_CTR_T "\x14"
#define KEY_CTR_U "\x15"
#define KEY_CTR_V "\x16"
#define KEY_CTR_W "\x17"
#define KEY_CTR_X "\x18"
#define KEY_CTR_Y "\x19"
#define KEY_CTR_Z "\x1A"
#define KEY_PAUSE "\x1A"
#define KEY_ESC "\x1B"
#define KEY_BACKSPACE "\x7F"
#define KEY_UP "\x1B[A"
#define KEY_DW "\x1B[B"
#define KEY_RIGHT "\x1B[C"
#define KEY_LEFT "\x1B[D"
#define KEY_HOME "\x1B[H"
#define KEY_EMD "\x1B[F"
#define KEY_CTR_UP "\x1B[1;5A"
#define KEY_CTR_DW "\x1B[1;5B"
#define KEY_CTR_RIGHT "\x1B[1;5C"
#define KEY_CTR_LEFT "\x1B[1;5D"
#define KEY_INSERT "\x1B[2~"
#define KEY_DELETE "\x1B[3~"
#define KEY_PAGE_UP "\x1B[5~"
#define KEY_PAGE_DOWN "\x1B[6~"
#define KEY_F1 "\x1BOP"
#define KEY_F2 "\x1BOQ"
#define KEY_F3 "\x1BOR"
#define KEY_F4 "\x1BOS"
#define KEY_F5 "\x1B[15~"
#define KEY_F6 "\x1B[17~"
#define KEY_F7 "\x1B[18~"
#define KEY_F8 "\x1B[19~"
#define KEY_F9 "\x1B[20~"
#define KEY_F10 "\x1B[21~"
#define KEY_F11 "\x1B[23~"
#define KEY_F12 "\x1B[24~"
typedef struct xnr_key
{
char encode_buf[8];
int encode_cnt;
int case_stu;
} xnr_key_t;
/**
* @description:
* @param key
* @return -10
*/
int xnr_key_init(xnr_key_t *key);
/**
* @description:
* @param keych
* @return 01
*/
int xnr_key_encode(xnr_key_t *key, int ch);
/**
* @description:
* @param key
* @return NULL
*/
char *xnr_key_val(xnr_key_t *key);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,304 +0,0 @@
#include "xnr_line.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
/**
* s中查找任意一个属于字符串delim中的字符
* s中的位置
*
*/
static char *_strpbrk(char *s, const char *delim) // 返回s1中第一个满足条件的字符的指针, 并且保留""号内的源格式
{
char flag = 0; // 用来标记是否在双引号内部0表示否1表示是
for (int i = 0; s[i]; i++)
{
if (s[i] == '\"')
{ // 如果当前位置为双引号
// 从字符串中去掉双引号
for (int k = i; s[k]; k++)
{
s[k] = s[k + 1];
}
// 改变flag的值
flag = !flag;
}
else if (flag == 0)
{
// 只有不在双引号内部才查找delim中的字符
for (int j = 0; delim[j]; j++)
{
if (s[i] == delim[j])
{
return &s[i]; // 找到了,返回字符位置
}
}
}
}
return NULL; // 没找到返回NULL
}
/**
* s中查找由字符串delim中的字符分隔出来的下一个子串
* save_ptr的值
*
*/
char *_strtok(char *s, const char *delim, char **save_ptr)
{
// 如果s为NULL则从上一次保存的位置开始切割
if (s == NULL)
{
s = *save_ptr;
}
// 跳过连续的分隔符
s += strspn(s, delim);
if (*s == '\0')
{
// 字符串已经结束
return NULL;
}
// 找到本次切割的子串
char *token = s;
s = _strpbrk(token, delim);
if (s == NULL)
{
// 没有找到分隔符,返回剩余的字符串
*save_ptr = strchr(token, '\0');
}
else
{
// 找到分隔符,替换为'\0'并更新save_ptr的值
*s = '\0';
*save_ptr = s + 1;
}
return token;
}
static int strlen_without_ansi(const char *str)
{
int len = 0;
int i = 0;
while (str[i] != '\0')
{
if (str[i] == '\x1b')
{
// skip ANSI escape sequence
while (str[i] != 'm' && str[i] != '\0')
{
++i;
}
if (str[i] == '\0')
{
break;
}
}
else
{
++len;
}
++i;
}
return len;
}
int xnr_line_init(xnr_line_t *le, xnr_io_t *io)
{
if (NULL == le || NULL == io)
return -1;
le->length = 0;
le->cursor = 0;
le->prompt = ANSI_COLOR_TXT(ANSI_BLUE, "->");
le->line[0] = '\0';
le->io = io;
return 0;
}
int xnr_line_bind_prompt(xnr_line_t *le, const char *prompt)
{
if (NULL == le || NULL == prompt)
return -1;
le->prompt = prompt;
return 0;
}
const char *xnr_line_prompt(xnr_line_t *le)
{
if (NULL == le)
return NULL;
return le->prompt;
}
int xnr_line_insert(xnr_line_t *le, char c)
{
if (NULL == le)
return -1;
if (le->length < XNR_LINE_MAX_LENGTH - 1) // 需要保留一个位置存放'\0'
{
for (int i = le->length; i > le->cursor; i--)
{
le->line[i] = le->line[i - 1];
}
++le->length;
le->line[le->length] = '\0';
le->line[le->cursor++] = c;
xnr_io_printf(le->io, ICH(1)); // 在当前光标位置插入空格
xnr_io_printf(le->io, "%c", c); // 将空格替换成字符
return 0;
}
return -1;
}
int xnr_line_delete(xnr_line_t *le)
{
if (NULL == le)
return -1;
if (le->cursor > 0)
{
for (int i = le->cursor - 1; i < le->length - 1; i++)
{
le->line[i] = le->line[i + 1];
}
--le->length;
--le->cursor;
le->line[le->length] = '\0';
xnr_io_printf(le->io, CUB(1));
xnr_io_printf(le->io, DCH(1));
return 0;
}
return -1;
}
char *xnr_line_line(xnr_line_t *le)
{
if (NULL == le)
return NULL;
return le->line;
}
int xnr_line_cursor(xnr_line_t *le)
{
if (NULL == le)
return 0;
return le->cursor;
}
int xnr_line_length(xnr_line_t *le) // 不包含'\0'
{
if (NULL == le)
return 0;
return le->length;
}
int xnr_line_cursor_left(xnr_line_t *le)
{
if (NULL == le)
return 0;
int pos = xnr_line_cursor(le);
if (pos > 0)
xnr_line_cursor_set(le, --pos);
return pos;
}
int xnr_line_cursor_right(xnr_line_t *le)
{
if (NULL == le)
return 0;
int pos = xnr_line_cursor(le);
if (pos < xnr_line_length(le))
xnr_line_cursor_set(le, ++pos);
return pos;
}
int xnr_line_cursor_set(xnr_line_t *le, int pos)
{
if (NULL == le)
return 0;
if (pos > le->length)
{
pos = le->length;
}
le->cursor = pos;
pos = le->cursor + strlen_without_ansi(le->prompt) + 1;
xnr_io_printf(le->io, CHA(pos));
return pos;
}
void xnr_line_cls(xnr_line_t *le) // 仅清除屏幕显示clear时也会显示prompt
{
if (NULL == le)
return;
xnr_io_printf(le->io, DL(0));
xnr_io_printf(le->io, "%s", le->prompt);
le->length = 0;
le->cursor = 0;
}
void xnr_line_clear(xnr_line_t *le) // 仅清除屏幕显示和le buffer clear时也会显示prompt所以建议新行后都调用此函数
{
if (NULL == le)
return;
xnr_line_cls(le);
le->line[0] = '\0';
}
char xnr_line_current_char(xnr_line_t *le)
{
if (NULL == le)
return '\0';
if (le->cursor < le->length)
{
return le->line[le->cursor];
}
return '\0';
}
void xnr_line_write(xnr_line_t *le, const char *buf, int len)
{
if (NULL == le)
return;
if (len > XNR_LINE_MAX_LENGTH - 1)
{
len = XNR_LINE_MAX_LENGTH - 1;
}
for (int i = 0; i < len; i++)
{
xnr_line_insert(le, buf[i]);
}
}
void xnr_line_puts(xnr_line_t *le, const char *str)
{
if (NULL == le)
return;
xnr_line_write(le, str, strlen(str));
}
void xnr_line_print(xnr_line_t *le, const char *fmt, ...)
{
if (NULL == le)
return;
char ucstring[XNR_LINE_MAX_LENGTH] = {0};
va_list arg;
va_start(arg, fmt);
vsnprintf(ucstring, XNR_LINE_MAX_LENGTH, fmt, arg);
va_end(arg);
xnr_line_write(le, ucstring, strlen(ucstring));
}
int xnr_line_tok(char *msg, char *delim, char *get[], int max_num)
{
int i, ret;
char *ptr = NULL;
char *sp = NULL;
ptr = _strtok(msg, delim, &sp);
for (i = 0; ptr != NULL && i < max_num; i++)
{
get[i] = ptr;
ptr = _strtok(NULL, delim, &sp);
}
ret = i;
return ret;
}

View File

@ -1,219 +0,0 @@
#ifndef XNR_LINE_H
#define XNR_LINE_H
#include "xnr_conf.h"
#include "xnr_io.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*光标操作符其中0x1B是ESC只适用于xnr_print函数*/
#define CUU(n) "\x1B[%dA", n /* 光标向上 光标向上 <n> 行 */
#define CUD(n) "\x1B[%dB", n /* 光标向下 光标向下 <n> 行 */
#define CUF(n) "\x1B[%dC", n /* 光标向前 光标向前(右)<n> 行 */
#define CUB(n) "\x1B[%dD", n /* 光标向后 光标向后(左)<n> 行 */
#define CNL(n) "\x1B[%dE", n /* 光标下一行 光标从当前位置向下 <n> 行 */
#define CPL(n) "\x1B[%dF", n /* 光标当前行 光标从当前位置向上 <n> 行 */
#define CHA(n) "\x1B[%dG", n /* 绝对光标水平 光标在当前行中水平移动到第 <n> 个位置 */
#define VPA(n) "\x1B[%dd", n /* 绝对垂直行位置 光标在当前列中垂直移动到第 <n> 个位置 */
#define CUP(y, x) "\x1B[%d;%dH", y, x /* 光标位置 *光标移动到视区中的 <x>; <y> 坐标,其中 <x> 是 <y> 行的列 */
#define HVP(y, x) "\x1B[%d;%df", y, x /* 水平垂直位置 *光标移动到视区中的 <x>; <y> 坐标,其中 <x> 是 <y> 行的列 */
/*光标可见性*/
#define CU_START_BL "\x1B[?12h" /* ATT160 文本光标启用闪烁 开始光标闪烁 */
#define CU_STOP_BL "\x1B[?12l" /* ATT160 文本光标禁用闪烁 停止闪烁光标 */
#define CU_SHOW "\x1B[?25h" /* DECTCEM 文本光标启用模式显示 显示光标 */
#define CU_HIDE "\x1B[?25l" /* DECTCEM 文本光标启用模式隐藏 隐藏光标 */
/* 字符操作 */
#define ICH(n) "\x1B[%d@", n /* 插入字符 在当前光标位置插入 <n> 个空格,这会将所有现有文本移到右侧。 向右溢出屏幕的文本会被删除。*/
#define DCH(n) "\x1B[%dP", n /* 删除字符 删除当前光标位置的 <n> 个字符,这会从屏幕右边缘以空格字符移动。*/
#define ECH(n) "\x1B[%dX", n /* 擦除字符 擦除当前光标位置的 <n> 个字符,方法是使用空格字符覆盖它们。*/
#define IL(n) "\x1B[%dL", n /* 插入行 将 <n> 行插入光标位置的缓冲区。 光标所在的行及其下方的行将向下移动。*/
#define DL(n) "\x1B[%dM\r", n /* 删除行 从缓冲区中删除 <n> 行,从光标所在的行开始。*/
/* 打印字体样式 */
#define ANSI_COLOR(fg, bg, style) "\x1b[" style ";" fg ";" bg "m"
#define ANSI_TXT(fg, bg, style, txt) ANSI_COLOR(fg, bg, style) txt ANSI_COLOR(ANSI_DEFAULT, ANSI_BG_DEFAULT, ANSI_RESET)
#define ANSI_COLOR_TXT(fg, txt) "\x1b[" fg "m" txt "\x1b[39m"
#define ANSI_BG_TXT(bg, txt) "\x1b[" bg "m" txt "\x1b[49m"
#define ANSI_STYLE_TXT(style, txt) "\x1b[" style "m" txt "\x1b[0m"
// 前景色
#define ANSI_BLACK "30"
#define ANSI_RED "31"
#define ANSI_GREEN "32"
#define ANSI_YELLOW "33"
#define ANSI_BLUE "34"
#define ANSI_MAGENTA "35"
#define ANSI_CYAN "36"
#define ANSI_WHITE "37"
#define ANSI_DEFAULT "39"
// 背景色
#define ANSI_BG_BLACK "40"
#define ANSI_BG_RED "41"
#define ANSI_BG_GREEN "42"
#define ANSI_BG_YELLOW "43"
#define ANSI_BG_BLUE "44"
#define ANSI_BG_MAGENTA "45"
#define ANSI_BG_CYAN "46"
#define ANSI_BG_WHITE "47"
#define ANSI_BG_DEFAULT "49"
// 样式
#define ANSI_RESET "0"
#define ANSI_BOLD "1"
#define ANSI_DIM "2"
#define ANSI_ITALIC "3"
#define ANSI_UNDERLINED "4"
#define ANSI_BLINK "5"
#define ANSI_REVERSE "7"
#define ANSI_HIDDEN "8"
#ifndef XNR_LINE_MAX_LENGTH
#define XNR_LINE_MAX_LENGTH (64)
#endif
typedef struct xnr_line
{
char line[XNR_LINE_MAX_LENGTH];
const char *prompt;
int length;
int cursor;
xnr_io_t *io;
} xnr_line_t;
/**
* @description:
* @param lexnr_line实例ioxnr_io实例
* @return -10
*/
int xnr_line_init(xnr_line_t *le, xnr_io_t *io);
/**
* @description:
* @param lexnr_line实例c
* @return -10
*/
int xnr_line_insert(xnr_line_t *le, char c);
/**
* @description:
* @param lexnr_line实例
* @return -10
*/
int xnr_line_delete(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例
* @return NULL
*/
char *xnr_line_line(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例
* @return '\0'
*/
int xnr_line_length(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例
* @return
*/
int xnr_line_cursor(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例pos
* @return
*/
int xnr_line_cursor_set(xnr_line_t *le, int pos);
/**
* @description:
* @param lexnr_line实例
* @return
*/
int xnr_line_cursor_left(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例
* @return
*/
int xnr_line_cursor_right(xnr_line_t *le);
/**
* @description: cls时也会显示prompt
* @param lexnr_line实例
* @return
*/
void xnr_line_cls(xnr_line_t *le);
/**
* @description: line buffer clear时也会显示prompt
* @param lexnr_line实例
* @return
*/
void xnr_line_clear(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例
* @return
*/
char xnr_line_current_char(xnr_line_t *le);
/**
* @description:
* @param lexnr_line实例buflen
* @return
*/
void xnr_line_write(xnr_line_t *le, const char *buf, int len);
/**
* @description:
* @param lexnr_line实例fmt...
* @return
*/
void xnr_line_print(xnr_line_t *le, const char *fmt, ...);
/**
* @description:
* @param lexnr_line实例str
* @return
*/
void xnr_line_puts(xnr_line_t *le, const char *str);
/**
* @description: strtok
* @param msgdelimget max_numbuf大小
* @return
*/
int xnr_line_tok(char *msg, char *delim, char *get[], int max_num);
/**
* @description: ANSI颜色控制
* @param lexnr_line实例prompt
* @return -10
*/
int xnr_line_bind_prompt(xnr_line_t *le, const char *prompt);
/**
* @description: ANSI颜色控制
* @param lexnr_line实例
* @return NULL
*/
const char *xnr_line_prompt(xnr_line_t *le);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,142 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "xnr_var.h"
int xnr_var_init(xnr_var_tab_t *tab, xnr_var_t *var_buf, int num)
{
if (NULL == tab || NULL == var_buf || 0 == num)
return -1;
tab->capacity = num;
tab->var_buf = var_buf;
memset(var_buf, 0, sizeof(xnr_var_t) * num);
return 0;
}
int xnr_var_set(xnr_var_tab_t *tab, char *name, char *value)
{
if (NULL == tab ||
NULL == name ||
NULL == value ||
strlen(name) == 0 || strlen(name) >= XNR_VAR_NAME_LEN ||
strlen(value) == 0 || strlen(value) >= XNR_VAR_VAR_LEN)
return -1;
int var_id = -1; // 保存需要设置的槽位
int var_empty_id = -1; // 保存空闲槽位
for (int i = 0; i < tab->capacity; i++) // 查找name是否存在
{
if ((-1 == var_empty_id) && (tab->var_buf[i].name[0] == '\0'))
{
var_empty_id = i;
}
else
{
if (strcmp(tab->var_buf[i].name, name) == 0)
{
var_id = i;
break;
}
}
}
if (-1 == var_id) // 获取一个空闲的var槽位
var_id = var_empty_id;
if (-1 == var_id) // 没有空余槽位
return -1;
if (strcmp(value, "nil") == 0) // 删除变量
{
tab->var_buf[var_id].name[0] = '\0';
return 0;
}
else
{
strncpy(tab->var_buf[var_id].value, value, XNR_VAR_VAR_LEN);
strncpy(tab->var_buf[var_id].name, name, XNR_VAR_NAME_LEN);
tab->var_buf[var_id].value[XNR_VAR_VAR_LEN - 1] = '\0';
tab->var_buf[var_id].name[XNR_VAR_NAME_LEN - 1] = '\0';
}
return var_id;
}
char *xnr_var_value(xnr_var_tab_t *tab, char *name)
{
if (NULL == tab || NULL == name)
return "nil";
xnr_var_t *var = NULL;
for (int i = 0; i < tab->capacity; i++) // 查找name是否存在
{
if (strcmp(tab->var_buf[i].name, name) == 0)
{
var = &tab->var_buf[i];
}
}
if (NULL == var)
return "nil";
else
return var->value;
}
xnr_var_t *xnr_var(xnr_var_tab_t *tab, int id)
{
if (NULL == tab || (id >= tab->capacity))
return NULL;
return &tab->var_buf[id];
}
int xnr_var_repalce(xnr_var_tab_t *tab, char *in, char *out, int out_len)
{
if (NULL == tab || NULL == in || out == NULL || 0 == out_len)
return -1;
int len = strlen(in);
char name[XNR_VAR_NAME_LEN] = {0};
int out_i = 0;
for (unsigned int i = 0; (i < len) && (out_i < (out_len - 1)); i++)
{
if (in[i] == '$')
{
int k = 0;
char end = ' ';
unsigned int j = i + 1;
if (in[j] == '{')
{
end = '}';
j++;
}
while (isprint((int)in[j]) && // 可显示字符
in[j] != end // 变量结尾
)
{
if (k < (XNR_VAR_NAME_LEN - 1))
{
name[k++] = in[j++];
}
else
{
return -1; // name长度超限
}
}
name[k] = '\0';
char *value = xnr_var_value(tab, name); // 获取变量的值
if (value != NULL)
{
int val_len = strlen(value);
for (k = 0; (k < val_len) && (out_i < (out_len - 1)); k++)
{
out[out_i++] = value[k];
}
}
if (end == '}')
i = j;
else
i = j - 1;
}
else
{
out[out_i++] = in[i];
}
}
out[out_i] = '\0';
return out_i;
}

View File

@ -1,69 +0,0 @@
#ifndef XNR_ENV_H
#define XNR_ENV_H
#include "xnr_conf.h"
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef XNR_VAR_NAME_LEN
#define XNR_VAR_NAME_LEN (32)
#endif
#ifndef XNR_VAR_VAR_LEN
#define XNR_VAR_VAR_LEN (64)
#endif
typedef struct xnr_var
{
char name[XNR_VAR_NAME_LEN];
char value[XNR_VAR_VAR_LEN];
} xnr_var_t;
typedef struct xnr_var_tab
{
int capacity;
xnr_var_t *var_buf;
} xnr_var_tab_t;
/**
* @description:
* @param tabvar_bufnum
* @return -10
*/
int xnr_var_init(xnr_var_tab_t *tab, xnr_var_t *var_buf, int num);
/**
* @description:
* @param tabnamevalue
* @return -1var_id
*/
int xnr_var_set(xnr_var_tab_t *tab, char *name, char *value);
/**
* @description:
* @param tabname
* @return "nil"
*/
char *xnr_var_value(xnr_var_tab_t *tab, char *name);
/**
* @description:
* @param tabidid
* @return NULL
*/
xnr_var_t *xnr_var(xnr_var_tab_t *tab, int id);
/**
* @description: ${name}$name
* @param tabinoutout_len
* @return -1
*/
int xnr_var_repalce(xnr_var_tab_t *tab, char *in, char *out, int out_len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -5,50 +5,28 @@
extern "C" {
#endif
#ifndef XCMD_LINE_MAX_LENGTH
#define XCMD_LINE_MAX_LENGTH (128) /* 命令行支持的最大字符数 */
#endif
#define XCMD_LINE_MAX_LENGTH (128) /* 命令行支持的最大字符数 */
#ifndef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (512) /* xcmd_print缓存 */
#endif
#define XCMD_PRINT_BUF_MAX_LENGTH (128) /* xcmd_print缓存 */
#ifndef XCMD_HISTORY_BUF_SZIE
#define XCMD_HISTORY_BUF_SZIE (512) /* 支持的历史记录个数, 这个参数对内存的影响很大建议arduino设置为00为不支持 */
#endif
#define XCMD_HISTORY_BUF_SZIE (256) /* 支持的历史记录缓存大小实际历史记录个数取决于记录的命令长度建议内存较小的单片机设置为0 */
#ifndef XCMD_PARAM_MAX_NUM
#define XCMD_PARAM_MAX_NUM (16) /* 支持输入的参数个数 */
#endif
#define XCMD_PARAM_MAX_NUM (10) /* 支持输入的参数个数 */
#if XCMD_PRINT_BUF_MAX_LENGTH < (XCMD_LINE_MAX_LENGTH+32)
#undef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#endif
#ifndef XCMD_DEFAULT_PROMPT
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#endif
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#ifndef XCMD_DEFAULT_PROMPT_CLOLR
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#endif
#ifndef XCMD_VAR_NUM
#define XCMD_VAR_NUM (32)
#endif
#define XCMD_VAR_NUM (16) /* 支持的变量的个数可以为0 */
#define XCMD_VAR_NAME_BUF_SZIE (32) /* 变量名最大长度可以为0 */
#define XCMD_VAR_VAR_SZIE (64) /* 变量最大长度可以为0 */
#ifndef XCMD_VAR_NAME_BUF_SZIE
#define XCMD_VAR_NAME_BUF_SZIE (32)
#endif
#ifndef XCMD_VAR_VAR_SZIE
#define XCMD_VAR_VAR_SZIE (64)
#endif
#ifndef ENABLE_XCMD_EXPORT
//#define ENABLE_XCMD_EXPORT /*使能XCMD_EXPORT_CMD和XCMD_EXPORT_KEY*/
#endif
#ifdef __cplusplus
}

View File

@ -5,50 +5,28 @@
extern "C" {
#endif
#ifndef XCMD_LINE_MAX_LENGTH
#define XCMD_LINE_MAX_LENGTH (64) /* 命令行支持的最大字符数 */
#endif
#define XCMD_LINE_MAX_LENGTH (256) /* 命令行支持的最大字符数 */
#ifndef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (128) /* xcmd_print缓存 */
#endif
#define XCMD_PRINT_BUF_MAX_LENGTH (4096) /* xcmd_print缓存 */
#ifndef XCMD_HISTORY_BUF_SZIE
#define XCMD_HISTORY_BUF_SZIE (256) /* 支持的历史记录个数, 这个参数对内存的影响很大建议arduino设置为00为不支持 */
#endif
#define XCMD_HISTORY_BUF_SZIE (4096) /* 支持的历史记录缓存大小实际历史记录个数取决于记录的命令长度建议内存较小的单片机设置为0 */
#ifndef XCMD_PARAM_MAX_NUM
#define XCMD_PARAM_MAX_NUM (8) /* 支持输入的参数个数 */
#endif
#define XCMD_PARAM_MAX_NUM (32) /* 支持输入的参数个数 */
#if XCMD_PRINT_BUF_MAX_LENGTH < (XCMD_LINE_MAX_LENGTH+32)
#undef XCMD_PRINT_BUF_MAX_LENGTH
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#define XCMD_PRINT_BUF_MAX_LENGTH (XCMD_LINE_MAX_LENGTH+32) /* xcmd_print缓存 */
#endif
#ifndef XCMD_DEFAULT_PROMPT
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#endif
#define XCMD_DEFAULT_PROMPT "$ " /*提示符*/
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#ifndef XCMD_DEFAULT_PROMPT_CLOLR
#define XCMD_DEFAULT_PROMPT_CLOLR ANSI_BLUE /*提示符颜色*/
#endif
#ifndef XCMD_VAR_NUM
#define XCMD_VAR_NUM (8)
#endif
#define XCMD_VAR_NUM (512) /* 支持的变量的个数可以为0 */
#define XCMD_VAR_NAME_BUF_SZIE (64) /* 变量名最大长度可以为0 */
#define XCMD_VAR_VAR_SZIE (128) /* 变量最大长度可以为0 */
#ifndef XCMD_VAR_NAME_BUF_SZIE
#define XCMD_VAR_NAME_BUF_SZIE (32)
#endif
#ifndef XCMD_VAR_VAR_SZIE
#define XCMD_VAR_VAR_SZIE (64)
#endif
#ifndef ENABLE_XCMD_EXPORT
//#define ENABLE_XCMD_EXPORT /*使能XCMD_EXPORT_CMD和XCMD_EXPORT_KEY*/
#endif
#ifdef __cplusplus
}

View File

@ -354,18 +354,26 @@ void xcmd_init(xcmder_t *xcmder, io_write_t write, io_read_t read)
#ifndef ENABLE_XCMD_EXPORT
g_cmd_list.head.next = NULL;
#endif
xnr_var_init(&xcmder->var_tab, xcmder->var_buf, XCMD_VAR_NUM);
xnr_io_init(&xcmder->io, write, read);
xnr_key_init(&xcmder->key);
xnr_line_init(&xcmder->line, &xcmder->io);
#if XCMD_HISTORY_BUF_SZIE != 0
xnr_history_init(&xcmder->history, &xcmder->io);
#endif
#if XCMD_VAR_NUM!=0
xnr_var_init(&xcmder->var_tab, xcmder->var_buf, XCMD_VAR_NUM);
#endif
#if XCMD_VAR_NUM==0
char *var_val = ANSI_COLOR_TXT(XCMD_DEFAULT_PROMPT_CLOLR, XCMD_DEFAULT_PROMPT);
#else
xnr_var_set(&xcmder->var_tab, "prompt", ANSI_COLOR_TXT(XCMD_DEFAULT_PROMPT_CLOLR, XCMD_DEFAULT_PROMPT));
char *var_val = xnr_var_value(&xcmder->var_tab, "prompt");
#endif
xnr_line_bind_prompt(&xcmder->line, var_val);
default_cmds_init();
default_keys_init();
xcmd_exec(xcmder, "logo");
xcmd_unregister_cmd("logo");
xnr_var_set(&xcmder->var_tab, "prompt", ANSI_COLOR_TXT(XCMD_DEFAULT_PROMPT_CLOLR, XCMD_DEFAULT_PROMPT));
char *var_val = xnr_var_value(&xcmder->var_tab, "prompt");
xnr_line_bind_prompt(&xcmder->line, var_val);
xnr_line_clear(&xcmder->line);
xcmder->_initOK = 1;
}

View File

@ -105,9 +105,13 @@ typedef struct xcmd
{
xnr_io_t io;
xnr_key_t key;
#if XCMD_VAR_NUM!=0
xnr_var_tab_t var_tab;
xnr_var_t var_buf[XCMD_VAR_NUM];
#endif
#if XCMD_HISTORY_BUF_SZIE != 0
xnr_history_t history;
#endif
xnr_line_t line;
cmd_func_t unknow_cmd_cbk; // 输入为命令序列,输出未处理
cmd_func_t pre_cmd_cbk; // 输入为命令序列输出重新赋值给argc

View File

@ -11,6 +11,7 @@ static int cmd_clear(int argc, char* argv[])
xcmd_print(xcmder, "\033c");
return 0;
}
XCMD_EXPORT_CMD(clear, cmd_clear, "clear screen")
static int cmd_help(int argc, char* argv[])
{
@ -22,6 +23,7 @@ static int cmd_help(int argc, char* argv[])
}
return 0;
}
XCMD_EXPORT_CMD(help, cmd_help, "show this list")
static int cmd_keys(int argc, char* argv[])
{
@ -34,6 +36,7 @@ static int cmd_keys(int argc, char* argv[])
}
return 0;
}
XCMD_EXPORT_CMD(keys, cmd_keys, "show keys")
static int cmd_logo(int argc, char* argv[])
{
@ -48,7 +51,9 @@ static int cmd_logo(int argc, char* argv[])
xcmd_print(xcmder, "%-10s %s\r\n","Version", VERSION);
return 0;
}
XCMD_EXPORT_CMD(logo, cmd_logo, "show logo")
#if XCMD_VAR_NUM!=0
static int cmd_set(int argc, char* argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
@ -58,6 +63,7 @@ static int cmd_set(int argc, char* argv[])
}
return 0;
}
XCMD_EXPORT_CMD(setvar, cmd_set, "set var")
static int cmd_var(int argc, char* argv[])
{
@ -74,13 +80,8 @@ static int cmd_var(int argc, char* argv[])
}
return 0;
}
XCMD_EXPORT_CMD(clear, cmd_clear, "clear screen")
XCMD_EXPORT_CMD(help, cmd_help, "show this list")
XCMD_EXPORT_CMD(keys, cmd_keys, "show keys")
XCMD_EXPORT_CMD(logo, cmd_logo, "show logo")
XCMD_EXPORT_CMD(setvar, cmd_set, "set var")
XCMD_EXPORT_CMD(var, cmd_var, "get all var")
#endif
static xcmd_t cmds[] =
{
@ -89,9 +90,11 @@ static xcmd_t cmds[] =
{"help", cmd_help, "show this list", NULL},
{"keys", cmd_keys, "show keys", NULL},
{"logo", cmd_logo, "show logo", NULL},
#if XCMD_VAR_NUM!=0
{"setvar", cmd_set, "set var", NULL},
{"var", cmd_var, "get all var", NULL},
#endif
#endif
};
void default_cmds_init(void)

View File

@ -30,8 +30,15 @@ static int xcmd_enter(int argc, char *argv[])
char out_line[XNR_LINE_MAX_LENGTH] = {0};
xcmd_print(xcmder, "\n\r");
char *line = xnr_line_line(&xcmder->line);
#if XCMD_HISTORY_BUF_SZIE != 0
xnr_history_append(&xcmder->history, line);
#endif
#if XCMD_VAR_NUM!=0
xnr_var_repalce(&xcmder->var_tab, line, out_line, XNR_LINE_MAX_LENGTH);
#else
strncpy(out_line, line, XNR_LINE_MAX_LENGTH);
#endif
if (out_line[0])
{
xcmd_exec(xcmder, out_line);
@ -61,6 +68,7 @@ static int xcmd_cursor_right(int argc, char *argv[])
}
XCMD_EXPORT_KEY(KEY_RIGHT, xcmd_cursor_right, "right")
#if XCMD_HISTORY_BUF_SZIE != 0
static int xcmd_history_dw(int argc, char *argv[])
{
xcmder_t *xcmder = XCMD_CURRENT();
@ -90,6 +98,7 @@ static int xcmd_history_up(int argc, char *argv[])
return 0;
}
XCMD_EXPORT_KEY(KEY_UP, xcmd_history_up, "up")
#endif
static int xcmd_auto_completion(int argc, char *argv[])
{
@ -155,9 +164,11 @@ static xcmd_key_t default_keys[] =
{KEY_LEFT, xcmd_cursor_left, "left", NULL},
{KEY_RIGHT, xcmd_cursor_right, "right", NULL},
{KEY_TAB, xcmd_auto_completion, "tab", NULL},
#if XCMD_HISTORY_BUF_SZIE != 0
{KEY_DW, xcmd_history_dw, "down", NULL},
{KEY_UP, xcmd_history_up, "up", NULL},
#endif
#endif
};
void default_keys_init(void)

View File

@ -3,6 +3,8 @@
#include "xcmd_confg.h"
/* 注意请勿修改此处代码 */
//行缓存长度
#ifndef XNR_LINE_MAX_LENGTH
#define XNR_LINE_MAX_LENGTH (XCMD_LINE_MAX_LENGTH)