New feature is ok
This commit is contained in:
parent
0c458efba4
commit
365f3580e7
|
@ -1 +1 @@
|
||||||
/build
|
*/build
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "linux-gcc-x64",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "${default}",
|
||||||
|
"cppStandard": "${default}",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64",
|
||||||
|
"compilerArgs": [
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wpedantic"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
|
@ -5,10 +5,10 @@
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "gcc - 生成和调试活动文件",
|
"name": "(gdb) 启动",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${fileDirname}/../xcmder",
|
"program": "${workspaceFolder}/example/linux/xcmder",
|
||||||
"args": [],
|
"args": [],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${fileDirname}",
|
"cwd": "${fileDirname}",
|
||||||
|
@ -21,9 +21,7 @@
|
||||||
"text": "-enable-pretty-printing",
|
"text": "-enable-pretty-printing",
|
||||||
"ignoreFailures": true
|
"ignoreFailures": true
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"preLaunchTask": "",
|
|
||||||
"miDebuggerPath": "/usr/bin/gdb"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"C_Cpp_Runner.cCompilerPath": "/usr/bin/gcc",
|
||||||
|
"C_Cpp_Runner.cppCompilerPath": "/usr/bin/g++",
|
||||||
|
"C_Cpp_Runner.debuggerPath": "/usr/bin/gdb",
|
||||||
|
"C_Cpp_Runner.makePath": "/usr/bin/make",
|
||||||
|
"C_Cpp_Runner.warnings": [
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wpedantic"
|
||||||
|
],
|
||||||
|
"C_Cpp_Runner.compilerArgs": [],
|
||||||
|
"C_Cpp_Runner.includePaths": [],
|
||||||
|
"C_Cpp_Runner.linkerArgs": [],
|
||||||
|
"C_Cpp_Runner.cStandard": "",
|
||||||
|
"C_Cpp_Runner.cppStandard": "",
|
||||||
|
"C_Cpp_Runner.excludeSearch": [],
|
||||||
|
"C_Cpp_Runner.enableWarnings": true,
|
||||||
|
"C_Cpp_Runner.warningsAsError": false,
|
||||||
|
"files.associations": {
|
||||||
|
"cmath": "c",
|
||||||
|
"complex": "c"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"type": "cppbuild",
|
|
||||||
"label": "C/C++: gcc 生成活动文件",
|
|
||||||
"command": "/usr/bin/gcc",
|
|
||||||
"args": [
|
|
||||||
"-g",
|
|
||||||
"${file}",
|
|
||||||
"-o",
|
|
||||||
"${fileDirname}/${fileBasenameNoExtension}"
|
|
||||||
],
|
|
||||||
"options": {
|
|
||||||
"cwd": "${fileDirname}"
|
|
||||||
},
|
|
||||||
"problemMatcher": [
|
|
||||||
"$gcc"
|
|
||||||
],
|
|
||||||
"group": {
|
|
||||||
"kind": "build",
|
|
||||||
"isDefault": true
|
|
||||||
},
|
|
||||||
"detail": "调试器生成的任务。"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"version": "2.0.0"
|
|
||||||
}
|
|
22
Makefile
22
Makefile
|
@ -1,22 +0,0 @@
|
||||||
include example/Makefile
|
|
||||||
INC += ./
|
|
||||||
OBJ += xcmd.o
|
|
||||||
BIN = xcmder
|
|
||||||
VPATH := example
|
|
||||||
OBJ_WITH_BUILD_DIR:=$(addprefix build/,$(OBJ))
|
|
||||||
|
|
||||||
all: mkbuilddir $(OBJ_WITH_BUILD_DIR)
|
|
||||||
gcc $(OBJ_WITH_BUILD_DIR) -o $(BIN)
|
|
||||||
|
|
||||||
build/%.o:%.c
|
|
||||||
gcc -c -I$(INC) -o $@ $<
|
|
||||||
|
|
||||||
.PHONY:mkbuilddir
|
|
||||||
mkbuilddir:
|
|
||||||
mkdir -p build
|
|
||||||
|
|
||||||
.PHONY:clean
|
|
||||||
clean:
|
|
||||||
rm -rf build
|
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
OBJ += test_cmds.o linux_main.o
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
OBJ += xcmd.o xcmd_default_keys.o xcmd_default_cmds.o test_cmds.o linux_main.o
|
||||||
|
BIN = xcmder
|
||||||
|
VPATH := ../../xcmd
|
||||||
|
INC += ../../xcmd
|
||||||
|
OBJ_WITH_BUILD_DIR:=$(addprefix build/,$(OBJ))
|
||||||
|
|
||||||
|
all: mkbuilddir $(OBJ_WITH_BUILD_DIR)
|
||||||
|
gcc -g $(OBJ_WITH_BUILD_DIR) -o $(BIN)
|
||||||
|
|
||||||
|
build/%.o:%.c
|
||||||
|
gcc -g -c -I$(INC) -o $@ $<
|
||||||
|
|
||||||
|
.PHONY:mkbuilddir
|
||||||
|
mkbuilddir:
|
||||||
|
mkdir -p build
|
||||||
|
|
||||||
|
.PHONY:clean
|
||||||
|
clean:
|
||||||
|
rm -rf build xcmder
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "xcmd.h"
|
#include "xcmd.h"
|
||||||
|
#include "xcmd_default_keys.h"
|
||||||
|
#include "xcmd_default_cmds.h"
|
||||||
#include<errno.h>
|
#include<errno.h>
|
||||||
#include<sys/types.h>
|
#include<sys/types.h>
|
||||||
#include<sys/socket.h>
|
#include<sys/socket.h>
|
||||||
|
@ -23,6 +27,7 @@ int getch(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = getchar();
|
ch = getchar();
|
||||||
|
// printf("%d\n", ch);
|
||||||
if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
|
if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -30,27 +35,49 @@ int getch(void)
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_get_char(char *ch)
|
int cmd_get_char(uint8_t *ch)
|
||||||
{
|
{
|
||||||
*ch = getch();
|
*ch = getch();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_put_char(char ch)
|
int cmd_put_char(uint8_t ch)
|
||||||
{
|
{
|
||||||
putchar(ch);
|
putchar(ch);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmd_ctr_a(void* pv)
|
||||||
|
{
|
||||||
|
printf("this is ctr+a\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_ctr_c(void* pv)
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static xcmd_key_t user_keys[] =
|
||||||
|
{
|
||||||
|
{CTR_A, cmd_ctr_a, NULL},
|
||||||
|
{CTR_C, cmd_ctr_c, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
void user_keys_init(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
xcmd_key_register(cmder, user_keys, sizeof(user_keys)/sizeof(xcmd_key_t));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
printf("hello\n");
|
|
||||||
|
|
||||||
xcmder_t* cmder = xcmd_create_default(cmd_get_char, cmd_put_char);
|
xcmder_t* cmder = xcmd_create_default(cmd_get_char, cmd_put_char);
|
||||||
if(cmder)
|
if(cmder)
|
||||||
{
|
{
|
||||||
test_cmd_init(cmder);
|
test_cmd_init(cmder);
|
||||||
xcmd_exec(cmder, "help");
|
user_keys_init(cmder);
|
||||||
|
default_keys_init(cmder);
|
||||||
|
default_cmds_init(cmder);
|
||||||
|
xcmd_exec(cmder, "logo");
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
xcmd_task(cmder);
|
xcmd_task(cmder);
|
|
@ -3,7 +3,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
xcmder_t *g_cmder = NULL;
|
static xcmder_t *g_cmder = NULL;
|
||||||
|
|
||||||
#define EXIT_MESSAGE() printf("press \"q\" or \"Q\" to exit!\r\n")
|
#define EXIT_MESSAGE() printf("press \"q\" or \"Q\" to exit!\r\n")
|
||||||
#define EXIT_CHECK() \
|
#define EXIT_CHECK() \
|
||||||
|
@ -22,7 +22,7 @@ xcmder_t *g_cmder = NULL;
|
||||||
} \
|
} \
|
||||||
while (0);
|
while (0);
|
||||||
|
|
||||||
uint8_t param_check(int need, int argc, char*argv[])
|
static uint8_t param_check(int need, int argc, char*argv[])
|
||||||
{
|
{
|
||||||
uint8_t i,ret = 0;
|
uint8_t i,ret = 0;
|
||||||
if(need<(argc))
|
if(need<(argc))
|
||||||
|
@ -46,12 +46,7 @@ uint8_t param_check(int need, int argc, char*argv[])
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_clear(int argc, char* argv[])
|
static void cmd_echo(int argc, char* argv[])
|
||||||
{
|
|
||||||
printf("\033c");
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmd_echo(int argc, char* argv[])
|
|
||||||
{
|
{
|
||||||
if(param_check(1, argc, argv))
|
if(param_check(1, argc, argv))
|
||||||
{
|
{
|
||||||
|
@ -59,7 +54,7 @@ void cmd_echo(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_example(int argc, char* argv[])
|
static void cmd_example(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
if(param_check(1, argc, argv))
|
if(param_check(1, argc, argv))
|
||||||
|
@ -88,27 +83,14 @@ void cmd_example(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_help(int argc, char* argv[])
|
static xcmd_t cmds[] =
|
||||||
{
|
{
|
||||||
xcmd_print_list(g_cmder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmd_exit(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd_t cmds[] =
|
|
||||||
{
|
|
||||||
{"clear", cmd_clear, "clear screen", NULL},
|
|
||||||
{"echo", cmd_echo, "echo anything", NULL},
|
{"echo", cmd_echo, "echo anything", NULL},
|
||||||
{"example", cmd_example, "example [-f|-i|-s] [val]", NULL},
|
{"example", cmd_example, "example [-f|-i|-s] [val]", NULL},
|
||||||
{"help", cmd_help, "show this list", NULL},
|
|
||||||
{"exit", cmd_exit, "exit xcmder", NULL},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_cmd_init(xcmder_t *cmder)
|
void test_cmd_init(xcmder_t *cmder)
|
||||||
{
|
{
|
||||||
xcmd_register(cmder, cmds, sizeof(cmds)/sizeof(cmd_t));
|
xcmd_register(cmder, cmds, sizeof(cmds)/sizeof(xcmd_t));
|
||||||
g_cmder = cmder;
|
g_cmder = cmder;
|
||||||
}
|
}
|
527
xcmd.c
527
xcmd.c
|
@ -1,527 +0,0 @@
|
||||||
#include "xcmd.h"
|
|
||||||
#include "malloc.h"
|
|
||||||
|
|
||||||
#define CMD_COMBINE_NONE (0xFF)
|
|
||||||
#define CMD_COMBINE_CHAR_UP (0xF1)
|
|
||||||
#define CMD_COMBINE_CHAR_DW (0xF2)
|
|
||||||
#define CMD_COMBINE_CHAR_RIGHT (0xF3)
|
|
||||||
#define CMD_COMBINE_CHAR_LEFT (0xF4)
|
|
||||||
|
|
||||||
#define CMD_IS_UP(c) (c == CMD_COMBINE_CHAR_UP)
|
|
||||||
#define CMD_IS_DOWN(c) (c == CMD_COMBINE_CHAR_DW)
|
|
||||||
#define CMD_IS_RIGHT(c) (c == CMD_COMBINE_CHAR_RIGHT)
|
|
||||||
#define CMD_IS_LEFT(c) (c == CMD_COMBINE_CHAR_LEFT)
|
|
||||||
|
|
||||||
#define CMD_IS_DELETE(c) ((c == 0x08) || (c == 0x7F))
|
|
||||||
#define CMD_IS_ENDLINE(c) ((c == '\n') || (c == '\r'))
|
|
||||||
#define CMD_IS_PRINT(c) ((c >= 32) && (c <= 126))
|
|
||||||
|
|
||||||
int xcmd_get_param(char* msg, char*delim, char* get[], int maxNum)
|
|
||||||
{
|
|
||||||
int i,ret;
|
|
||||||
char *ptr = NULL;
|
|
||||||
ptr = strtok(msg, delim);
|
|
||||||
for(i=0; ptr!=NULL &&i<maxNum; i++)
|
|
||||||
{
|
|
||||||
get[i] = ptr;
|
|
||||||
ptr = strtok(NULL, delim);
|
|
||||||
}
|
|
||||||
ret = i;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xcmd_param_analysis(char* msg, char delim, char* get[], int maxNum)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
get[ret] = msg;
|
|
||||||
uint8_t flag = 0;
|
|
||||||
while(*msg)
|
|
||||||
{
|
|
||||||
if(*msg == delim)
|
|
||||||
{
|
|
||||||
while(*msg && (*msg != delim))
|
|
||||||
{
|
|
||||||
*msg = '\0';
|
|
||||||
msg++;
|
|
||||||
}
|
|
||||||
get[ret] = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*msg == '"') //start "
|
|
||||||
{
|
|
||||||
while(*msg && (*msg != '"')) //ignore """"
|
|
||||||
{
|
|
||||||
*msg = '\0';
|
|
||||||
msg++;
|
|
||||||
}
|
|
||||||
get[ret] = msg;
|
|
||||||
|
|
||||||
while(*msg && (*msg != '"'))
|
|
||||||
{
|
|
||||||
msg++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(*msg && (*msg != '"'))
|
|
||||||
{
|
|
||||||
*msg = '\0';
|
|
||||||
msg++;
|
|
||||||
}
|
|
||||||
get[ret] = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ret >= maxNum)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
msg++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_print_str(xcmder_t * cmder, char* str)
|
|
||||||
{
|
|
||||||
while(*str)
|
|
||||||
{
|
|
||||||
cmder->io.put_c(*str++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t xcmd_bytes_encode(xcmder_t * cmder, uint8_t byte)
|
|
||||||
{
|
|
||||||
uint16_t ret = byte;
|
|
||||||
|
|
||||||
switch(cmder->encodeCaseStu)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if(byte==0x1B) //1~2
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 1;
|
|
||||||
ret = CMD_COMBINE_NONE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if(byte==0x5B)
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu++;
|
|
||||||
ret = CMD_COMBINE_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if(byte == 0x41)
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
ret = CMD_COMBINE_CHAR_UP;
|
|
||||||
}
|
|
||||||
else if(byte == 0x42)
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
ret = CMD_COMBINE_CHAR_DW;
|
|
||||||
}
|
|
||||||
else if(byte == 0x43)
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
ret = CMD_COMBINE_CHAR_RIGHT;
|
|
||||||
}
|
|
||||||
else if(byte == 0x44)
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
ret = CMD_COMBINE_CHAR_LEFT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
ret = CMD_COMBINE_NONE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_del_line(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
char (*buf)[cmder->parser.historyLen] = (char (*)[cmder->parser.historyLen])cmder->parser.buf;
|
|
||||||
uint16_t len = strlen(buf[cmder->parser.historyCursor]);
|
|
||||||
if(len)
|
|
||||||
{
|
|
||||||
xcmd_print_str(cmder, "\r->");
|
|
||||||
for(uint16_t i=0; i<len; i++)
|
|
||||||
{
|
|
||||||
cmder->io.put_c(' ');
|
|
||||||
}
|
|
||||||
xcmd_print_str(cmder, "\r->");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_insert_char(xcmder_t *cmder, char c)
|
|
||||||
{
|
|
||||||
char (*buf)[cmder->parser.historyLen] = (char (*)[cmder->parser.historyLen])cmder->parser.buf;
|
|
||||||
char *line = buf[cmder->parser.historyCursor];
|
|
||||||
if(cmder->parser.bytesNum < cmder->parser.bufLen-1)
|
|
||||||
{
|
|
||||||
for(uint16_t i = cmder->parser.bytesNum; i>cmder->parser.cursor;i--)
|
|
||||||
{
|
|
||||||
line[i] = line[i-1];
|
|
||||||
}
|
|
||||||
cmder->parser.bytesNum++;
|
|
||||||
line[cmder->parser.bytesNum] = '\0';
|
|
||||||
line[cmder->parser.cursor++] = c;
|
|
||||||
|
|
||||||
xcmd_print_str(cmder, "\r->");
|
|
||||||
xcmd_print_str(cmder, line);
|
|
||||||
xcmd_print_str(cmder, "\r->");
|
|
||||||
|
|
||||||
/* move cursor */
|
|
||||||
for(uint16_t i = 0; i<cmder->parser.cursor; i++)
|
|
||||||
{
|
|
||||||
xcmd_print_str(cmder, "\x1B\x5B\x43");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_del_char(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
char (*buf)[cmder->parser.historyLen] = (char (*)[cmder->parser.historyLen])cmder->parser.buf;
|
|
||||||
char *line = buf[cmder->parser.historyCursor];
|
|
||||||
if(cmder->parser.cursor > 0)
|
|
||||||
{
|
|
||||||
for(uint16_t i = cmder->parser.cursor-1; i<cmder->parser.bytesNum-1; i++)
|
|
||||||
{
|
|
||||||
line[i] = line[i+1];
|
|
||||||
}
|
|
||||||
cmder->parser.bytesNum--;
|
|
||||||
cmder->parser.cursor--;
|
|
||||||
line[cmder->parser.bytesNum] = ' ';
|
|
||||||
xcmd_print_str(cmder, "\r->");
|
|
||||||
xcmd_print_str(cmder, line);
|
|
||||||
xcmd_print_str(cmder, "\r->");
|
|
||||||
|
|
||||||
/* move cursor */
|
|
||||||
for(uint16_t i = 0; i<cmder->parser.cursor; i++)
|
|
||||||
{
|
|
||||||
xcmd_print_str(cmder, "\x1B\x5B\x43");
|
|
||||||
}
|
|
||||||
|
|
||||||
line[cmder->parser.bytesNum] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_cursor_left(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
if(cmder->parser.cursor > 0)
|
|
||||||
{
|
|
||||||
cmder->parser.cursor--;
|
|
||||||
xcmd_print_str(cmder, "\x1B\x5B\x44");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_cursor_right(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
if(cmder->parser.cursor < cmder->parser.bytesNum)
|
|
||||||
{
|
|
||||||
cmder->parser.cursor++;
|
|
||||||
xcmd_print_str(cmder, "\x1B\x5B\x43");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_history_dw(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
char(*buf)[cmder->parser.historyLen] = (char(*)[cmder->parser.historyLen])cmder->parser.buf;
|
|
||||||
while(cmder->parser.historyNum)
|
|
||||||
{
|
|
||||||
xcmd_del_line(cmder);
|
|
||||||
cmder->parser.historyCursor++;
|
|
||||||
if(cmder->parser.historyCursor>=cmder->parser.historyLen)
|
|
||||||
{
|
|
||||||
cmder->parser.historyCursor = 0;
|
|
||||||
}
|
|
||||||
uint16_t len = strlen(buf[cmder->parser.historyCursor]);
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
xcmd_print_str(cmder, buf[cmder->parser.historyCursor]);
|
|
||||||
cmder->parser.bytesNum = len;
|
|
||||||
cmder->parser.cursor = len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_history_up(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
char(*buf)[cmder->parser.historyLen] = (char(*)[cmder->parser.historyLen])cmder->parser.buf;
|
|
||||||
while(cmder->parser.historyNum)
|
|
||||||
{
|
|
||||||
xcmd_del_line(cmder);
|
|
||||||
if (cmder->parser.historyCursor)
|
|
||||||
{
|
|
||||||
cmder->parser.historyCursor--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmder->parser.historyCursor = cmder->parser.historyLen;
|
|
||||||
}
|
|
||||||
uint16_t len = strlen(buf[cmder->parser.historyCursor]);
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
xcmd_print_str(cmder, buf[cmder->parser.historyCursor]);
|
|
||||||
cmder->parser.bytesNum = len;
|
|
||||||
cmder->parser.cursor = len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* xcmd_line_end(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
char (*buf)[cmder->parser.historyLen] = (char (*)[cmder->parser.historyLen])cmder->parser.buf;
|
|
||||||
char* ret = NULL;
|
|
||||||
if(cmder->parser.bytesNum)
|
|
||||||
{
|
|
||||||
ret = buf[cmder->parser.historyCursor];
|
|
||||||
|
|
||||||
uint16_t temp = cmder->parser.historyCursor;
|
|
||||||
if(temp)
|
|
||||||
{
|
|
||||||
temp--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
temp = cmder->parser.historyLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strcmp(buf[temp], ret) != 0)
|
|
||||||
{
|
|
||||||
if(cmder->parser.historyNum < cmder->parser.historyLen)
|
|
||||||
{
|
|
||||||
cmder->parser.historyNum++;
|
|
||||||
}
|
|
||||||
cmder->parser.historyCursor++;
|
|
||||||
if(cmder->parser.historyCursor>=cmder->parser.historyLen)
|
|
||||||
{
|
|
||||||
cmder->parser.historyCursor = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmder->parser.bytesNum = 0;
|
|
||||||
cmder->parser.cursor = 0;
|
|
||||||
xcmd_print_str(cmder, "\r\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xcmd_print_str(cmder, "\r\n->");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* xcmd_parser(xcmder_t * cmder, uint8_t byte)
|
|
||||||
{
|
|
||||||
char* ret = NULL;
|
|
||||||
uint16_t c = 0;
|
|
||||||
|
|
||||||
c = xcmd_bytes_encode(cmder, byte);
|
|
||||||
|
|
||||||
if(CMD_IS_DELETE(c))
|
|
||||||
{
|
|
||||||
xcmd_del_char(cmder);
|
|
||||||
}
|
|
||||||
else if(CMD_IS_PRINT(c))
|
|
||||||
{
|
|
||||||
xcmd_insert_char(cmder, c);
|
|
||||||
}
|
|
||||||
else if(CMD_IS_UP(c))
|
|
||||||
{
|
|
||||||
xcmd_history_up(cmder);
|
|
||||||
}
|
|
||||||
else if(CMD_IS_DOWN(c))
|
|
||||||
{
|
|
||||||
xcmd_history_dw(cmder);
|
|
||||||
}
|
|
||||||
else if(CMD_IS_RIGHT(c))
|
|
||||||
{
|
|
||||||
xcmd_cursor_right(cmder);
|
|
||||||
}
|
|
||||||
else if(CMD_IS_LEFT(c))
|
|
||||||
{
|
|
||||||
xcmd_cursor_left(cmder);
|
|
||||||
}
|
|
||||||
else if(CMD_IS_ENDLINE(c))
|
|
||||||
{
|
|
||||||
ret = xcmd_line_end(cmder);
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t xcmd_exec(xcmder_t *cmder, char* str)
|
|
||||||
{
|
|
||||||
int param_num = 0;
|
|
||||||
char *cmd_param_buff[cmder->parser.paramLen];
|
|
||||||
char temp[cmder->parser.bufLen];
|
|
||||||
strncpy(temp, str, cmder->parser.bufLen);
|
|
||||||
param_num = xcmd_get_param(temp, "., ", cmd_param_buff, cmder->parser.paramLen);
|
|
||||||
if(param_num >0)
|
|
||||||
{
|
|
||||||
xcmd_match(cmder, param_num, cmd_param_buff);
|
|
||||||
}
|
|
||||||
return param_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xcmd_register(xcmder_t *cmder, xcmd_t *cmds, uint16_t number)
|
|
||||||
{
|
|
||||||
uint16_t i=0;
|
|
||||||
if(cmder->cmd_list.len == 0)
|
|
||||||
{
|
|
||||||
cmder->cmd_list.next = &cmds[i++];
|
|
||||||
cmder->cmd_list.next->next = NULL;
|
|
||||||
++cmder->cmd_list.len;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(i<number)
|
|
||||||
{
|
|
||||||
xcmd_t *p = cmder->cmd_list.next;
|
|
||||||
cmder->cmd_list.next = &cmds[i];
|
|
||||||
cmds[i].next = p;
|
|
||||||
++cmder->cmd_list.len;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return cmder->cmd_list.len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_print_list(xcmder_t *cmder)
|
|
||||||
{
|
|
||||||
xcmd_t *p = cmder->cmd_list.next;
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
printf("%-20s %s\r\n",p->name, p->help);
|
|
||||||
p = p->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_match(xcmder_t *cmder, int argc, char*argv[])
|
|
||||||
{
|
|
||||||
xcmd_t *p = cmder->cmd_list.next;
|
|
||||||
uint8_t flag = 0;
|
|
||||||
while(p)
|
|
||||||
{
|
|
||||||
if(strcmp(p->name, argv[0]) == 0)
|
|
||||||
{
|
|
||||||
flag = 1;
|
|
||||||
if(argc>1)
|
|
||||||
{
|
|
||||||
if((strcmp(argv[1],"?") == 0) ||
|
|
||||||
(strcmp(argv[1],"-h") == 0))
|
|
||||||
{
|
|
||||||
printf("%s\r\n", p->help);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p->func(argc, argv);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = p->next;
|
|
||||||
}
|
|
||||||
if(flag)
|
|
||||||
{
|
|
||||||
printf("\r\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("cmd \"%s\" does not exist\r\n", argv[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xcmder_t *xcmd_create( int (*get_c)(uint8_t*), int (*put_c)(uint8_t), uint16_t cmdLen, uint16_t historyLen, uint16_t paramLen)
|
|
||||||
{
|
|
||||||
xcmder_t* cmder = (xcmder_t*)malloc(sizeof(xcmder_t));
|
|
||||||
if(cmder == NULL)
|
|
||||||
{
|
|
||||||
goto create_cmder_failure;
|
|
||||||
}
|
|
||||||
if(get_c && put_c)
|
|
||||||
{
|
|
||||||
cmder->parser.buf = (char*)malloc(cmdLen*historyLen);
|
|
||||||
cmder->parser.historyLen = historyLen;
|
|
||||||
cmder->parser.bufLen = cmdLen*historyLen;
|
|
||||||
if(cmder->parser.buf == NULL)
|
|
||||||
{
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmder->parser.paramLen = paramLen;
|
|
||||||
|
|
||||||
cmder->parser.bytesNum = 0;
|
|
||||||
cmder->parser.historyNum = 0;
|
|
||||||
cmder->parser.cursor = 0;
|
|
||||||
cmder->parser.historyCursor = 0;
|
|
||||||
cmder->parser.ishistory = 0;
|
|
||||||
|
|
||||||
cmder->encodeCaseStu = 0;
|
|
||||||
cmder->io.get_c = get_c;
|
|
||||||
cmder->io.put_c = put_c;
|
|
||||||
cmder->_initOK = 1;
|
|
||||||
|
|
||||||
cmder->cmd_list.len = 0;
|
|
||||||
cmder->cmd_list.next = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
return cmder;
|
|
||||||
|
|
||||||
failure:
|
|
||||||
if(cmder->parser.buf)
|
|
||||||
{
|
|
||||||
free(cmder->parser.buf);
|
|
||||||
cmder->parser.buf = NULL;
|
|
||||||
}
|
|
||||||
create_cmder_failure:
|
|
||||||
if(cmder)
|
|
||||||
{
|
|
||||||
free(cmder);
|
|
||||||
cmder = NULL;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_destory(xcmder_t* cmder)
|
|
||||||
{
|
|
||||||
if(cmder)
|
|
||||||
{
|
|
||||||
if(cmder->parser.buf)
|
|
||||||
{
|
|
||||||
free(cmder->parser.buf);
|
|
||||||
cmder->parser.buf = NULL;
|
|
||||||
}
|
|
||||||
free(cmder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xcmd_task(xcmder_t* cmder)
|
|
||||||
{
|
|
||||||
uint8_t c;
|
|
||||||
char *str = NULL;
|
|
||||||
if(cmder && cmder->_initOK)
|
|
||||||
{
|
|
||||||
if(cmder->io.get_c(&c))
|
|
||||||
{
|
|
||||||
str = xcmd_parser(cmder, c);
|
|
||||||
if(str)
|
|
||||||
{
|
|
||||||
xcmd_exec(cmder, str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
80
xcmd.h
80
xcmd.h
|
@ -1,80 +0,0 @@
|
||||||
#ifndef XCMD_H
|
|
||||||
#define XCMD_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
typedef void(*cmd_func_t)(int argv, char* argc[]);
|
|
||||||
typedef int (*xcmd_get_char_func_t)(uint8_t *);
|
|
||||||
typedef int (*xcmd_put_char_func_t)(uint8_t ch);
|
|
||||||
|
|
||||||
typedef struct __cmd
|
|
||||||
{
|
|
||||||
char* name;
|
|
||||||
cmd_func_t func;
|
|
||||||
char* help;
|
|
||||||
struct __cmd *next;
|
|
||||||
}xcmd_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int (*get_c)(uint8_t*);
|
|
||||||
int (*put_c)(uint8_t);
|
|
||||||
}io;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t index; /* 在pool的第几行 */
|
|
||||||
uint16_t cur_len; /* 当前行的字符长度 */
|
|
||||||
uint16_t cursor; /* 光标所在位置 */
|
|
||||||
}display;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
uint16_t line_len; /* 每一行的最大长度 */
|
|
||||||
uint16_t line_num; /* 一共有多少行 */
|
|
||||||
}pool;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
uint16_t paramLen;
|
|
||||||
uint16_t historyLen;
|
|
||||||
uint16_t bufLen;
|
|
||||||
|
|
||||||
uint16_t historyNum;
|
|
||||||
uint16_t bytesNum;
|
|
||||||
|
|
||||||
uint16_t historyCursor;
|
|
||||||
uint16_t cursor;
|
|
||||||
uint8_t ishistory;
|
|
||||||
} parser;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t len;
|
|
||||||
xcmd_t *next;
|
|
||||||
xcmd_t *tail;
|
|
||||||
}cmd_list;
|
|
||||||
|
|
||||||
uint8_t encodeCaseStu;
|
|
||||||
uint8_t _initOK;
|
|
||||||
} xcmder_t;
|
|
||||||
|
|
||||||
int xcmd_register(xcmder_t *cmder, xcmd_t *cmds, uint16_t number);
|
|
||||||
void xcmd_match(xcmder_t *cmder, int argc, char*argv[]);
|
|
||||||
void xcmd_print_list(xcmder_t *cmder);
|
|
||||||
uint8_t xcmd_exec(xcmder_t *cmder, char *str);
|
|
||||||
void xcmd_destory(xcmder_t* cmder);
|
|
||||||
xcmder_t *xcmd_create( int (*get_c)(uint8_t*), int (*put_c)(uint8_t), uint16_t cmdLen, uint16_t historyLen, uint16_t paramLen);
|
|
||||||
#define xcmd_create_default(getchar, putchar) xcmd_create(getchar, putchar, 64, 10, 16);
|
|
||||||
void xcmd_task(xcmder_t *cmder);
|
|
||||||
|
|
||||||
#endif /*XCMD_H*/
|
|
|
@ -0,0 +1,527 @@
|
||||||
|
#include "xcmd.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
|
||||||
|
#define CMD_IS_ENDLINE(c) ((c == '\n') || (c == '\r'))
|
||||||
|
#define CMD_IS_PRINT(c) ((c >= 32) && (c <= 126))
|
||||||
|
|
||||||
|
static int xcmd_get_param(char* msg, char*delim, char* get[], int max_num)
|
||||||
|
{
|
||||||
|
int i,ret;
|
||||||
|
char *ptr = NULL;
|
||||||
|
ptr = strtok(msg, delim);
|
||||||
|
for(i=0; ptr!=NULL &&i<max_num; i++)
|
||||||
|
{
|
||||||
|
get[i] = ptr;
|
||||||
|
ptr = strtok(NULL, delim);
|
||||||
|
}
|
||||||
|
ret = i;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xcmd_match(xcmder_t *cmder, int argc, char*argv[])
|
||||||
|
{
|
||||||
|
xcmd_t *p = cmder->cmd_list.next;
|
||||||
|
uint8_t flag = 0;
|
||||||
|
while(p)
|
||||||
|
{
|
||||||
|
if(strcmp(p->name, argv[0]) == 0)
|
||||||
|
{
|
||||||
|
flag = 1;
|
||||||
|
if(argc>1)
|
||||||
|
{
|
||||||
|
if((strcmp(argv[1],"?") == 0) ||
|
||||||
|
(strcmp(argv[1],"-h") == 0))
|
||||||
|
{
|
||||||
|
printf("%s\r\n", p->help);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->func(argc, argv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
if(flag)
|
||||||
|
{
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("cmd \"%s\" does not exist\r\n", argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xcmd_key_match(xcmder_t *cmder, XCMD_KEY_T key)
|
||||||
|
{
|
||||||
|
xcmd_key_t *p = cmder->key_list.next;
|
||||||
|
uint8_t flag = 0;
|
||||||
|
while(p)
|
||||||
|
{
|
||||||
|
if(p->key == key)
|
||||||
|
{
|
||||||
|
p->func(cmder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t xcmd_bytes_encode(xcmder_t * cmder, uint8_t byte)
|
||||||
|
{
|
||||||
|
uint32_t ret = byte;
|
||||||
|
|
||||||
|
switch(cmder->parser.encode_case_stu)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if(byte==0x1B) //1~2
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu = 1;
|
||||||
|
cmder->parser.key_val = byte;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(byte==0x5B)
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu++;
|
||||||
|
cmder->parser.key_val |= (uint32_t)byte<<8;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(byte >= 0x41)
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu = 0;
|
||||||
|
cmder->parser.key_val |= (uint32_t)byte<<16;
|
||||||
|
ret = cmder->parser.key_val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu++;
|
||||||
|
cmder->parser.key_val |= (uint32_t)byte<<16;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(byte == 0x7E)
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu = 0;
|
||||||
|
cmder->parser.key_val |= (uint32_t)byte<<24;
|
||||||
|
ret = cmder->parser.key_val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmder->parser.encode_case_stu = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xcmd_display_update(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = xcmd_display_get(cmder);
|
||||||
|
xcmd_print_str(cmder, "\r->");
|
||||||
|
xcmd_print_str(cmder, line);
|
||||||
|
xcmd_print_str(cmder, "\r->");
|
||||||
|
/* move cursor */
|
||||||
|
for(uint16_t i = 0; i<cmder->parser.cursor; i++)
|
||||||
|
{
|
||||||
|
xcmd_print_str(cmder, "\x1B\x5B\x43");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* xcmd_line_end(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char* ret = cmder->parser.display_line;
|
||||||
|
if(cmder->parser.byte_num)
|
||||||
|
{
|
||||||
|
if(cmder->parser.history_list.next == NULL)
|
||||||
|
{
|
||||||
|
xcmd_history_insert(cmder, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *head_line = cmder->parser.history_list.next->line;
|
||||||
|
if(strcmp(head_line, ret) != 0)
|
||||||
|
{
|
||||||
|
xcmd_history_insert(cmder, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmder->parser.byte_num = 0;
|
||||||
|
cmder->parser.cursor = 0;
|
||||||
|
xcmd_print_str(cmder, "\r\n");
|
||||||
|
xcmd_history_reset(cmder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xcmd_print_str(cmder, "\r\n->");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* xcmd_parser(xcmder_t * cmder, uint8_t byte)
|
||||||
|
{
|
||||||
|
char* ret = NULL;
|
||||||
|
uint32_t c = 0;
|
||||||
|
|
||||||
|
c = xcmd_bytes_encode(cmder, byte);
|
||||||
|
|
||||||
|
if(CMD_IS_PRINT(c))
|
||||||
|
{
|
||||||
|
xcmd_display_insert_char(cmder, c);
|
||||||
|
}
|
||||||
|
else if(CMD_IS_ENDLINE(c))
|
||||||
|
{
|
||||||
|
ret = xcmd_line_end(cmder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xcmd_key_match(cmder, c);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_print_str(xcmder_t * cmder, char* str)
|
||||||
|
{
|
||||||
|
while(*str)
|
||||||
|
{
|
||||||
|
cmder->io.put_c(*str++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* xcmd_display_get(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = cmder->parser.display_line;
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_display_clear(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = xcmd_display_get(cmder);
|
||||||
|
uint16_t len = strlen(line);
|
||||||
|
if(len)
|
||||||
|
{
|
||||||
|
xcmd_print_str(cmder, "\r->");
|
||||||
|
for(uint16_t i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
cmder->io.put_c(' ');
|
||||||
|
}
|
||||||
|
xcmd_print_str(cmder, "\r->");
|
||||||
|
cmder->parser.byte_num = 0;
|
||||||
|
cmder->parser.cursor = 0;
|
||||||
|
line[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_display_insert_char(xcmder_t *cmder, char c)
|
||||||
|
{
|
||||||
|
char *line = xcmd_display_get(cmder);
|
||||||
|
if(cmder->parser.byte_num < cmder->parser.line_len-1)
|
||||||
|
{
|
||||||
|
for(uint16_t i=cmder->parser.byte_num; i>cmder->parser.cursor; i--)
|
||||||
|
{
|
||||||
|
line[i] = line[i-1];
|
||||||
|
}
|
||||||
|
cmder->parser.byte_num++;
|
||||||
|
line[cmder->parser.byte_num] = '\0';
|
||||||
|
line[cmder->parser.cursor++] = c;
|
||||||
|
xcmd_display_update(cmder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_display_delete_char(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = xcmd_display_get(cmder);
|
||||||
|
if(cmder->parser.cursor > 0)
|
||||||
|
{
|
||||||
|
for(uint16_t i = cmder->parser.cursor-1; i<cmder->parser.byte_num-1; i++)
|
||||||
|
{
|
||||||
|
line[i] = line[i+1];
|
||||||
|
}
|
||||||
|
cmder->parser.byte_num--;
|
||||||
|
cmder->parser.cursor--;
|
||||||
|
line[cmder->parser.byte_num] = ' ';
|
||||||
|
xcmd_display_update(cmder);
|
||||||
|
line[cmder->parser.byte_num] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_history_insert(xcmder_t *cmder, char* str)
|
||||||
|
{
|
||||||
|
if(cmder->parser.history_list.len < cmder->parser.line_totle)
|
||||||
|
{
|
||||||
|
xcmd_history_t *next_p = cmder->parser.history_list.next;
|
||||||
|
xcmd_history_t *prev_p = cmder->parser.history_list.next;
|
||||||
|
xcmd_history_t *new_p = (xcmd_history_t*)malloc(sizeof(xcmd_history_t));
|
||||||
|
if(cmder->parser.history_list.len == 0)
|
||||||
|
{
|
||||||
|
if(new_p)
|
||||||
|
{
|
||||||
|
char * new_line = (char*)malloc(cmder->parser.line_len);
|
||||||
|
if(new_line)
|
||||||
|
{
|
||||||
|
cmder->parser.history_list.next = new_p;
|
||||||
|
cmder->parser.history_list.next->next = NULL;
|
||||||
|
cmder->parser.history_list.next->prev = new_p;
|
||||||
|
|
||||||
|
cmder->parser.history_list.next->line = new_line;
|
||||||
|
strncpy(cmder->parser.history_list.next->line, str, cmder->parser.line_len);
|
||||||
|
cmder->parser.history_list.len++;
|
||||||
|
cmder->parser.history_list.handle = cmder->parser.history_list.next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(new_p);
|
||||||
|
new_p = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(new_p)
|
||||||
|
{
|
||||||
|
char * new_line = (char*)malloc(cmder->parser.line_len);
|
||||||
|
if(cmder->parser.history_list.next->line)
|
||||||
|
{
|
||||||
|
cmder->parser.history_list.next = new_p;
|
||||||
|
cmder->parser.history_list.next->next = next_p;
|
||||||
|
cmder->parser.history_list.next->prev = new_p;
|
||||||
|
next_p->prev = cmder->parser.history_list.next;
|
||||||
|
|
||||||
|
cmder->parser.history_list.next->line = new_line;
|
||||||
|
strncpy(cmder->parser.history_list.next->line, str, cmder->parser.line_len);
|
||||||
|
cmder->parser.history_list.len++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(new_p);
|
||||||
|
new_p = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 获取到倒数第二个节点 */
|
||||||
|
xcmd_history_t *next_p = cmder->parser.history_list.next;
|
||||||
|
while(next_p->next->next)
|
||||||
|
{
|
||||||
|
next_p = next_p->next;
|
||||||
|
}
|
||||||
|
xcmd_history_t *last = next_p->next;
|
||||||
|
next_p->next = NULL;
|
||||||
|
xcmd_history_t *first = cmder->parser.history_list.next;
|
||||||
|
strncpy(last->line, str, cmder->parser.line_len);
|
||||||
|
cmder->parser.history_list.next = last;
|
||||||
|
last->next = first;
|
||||||
|
last->prev = last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *xcmd_history_next(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = NULL;
|
||||||
|
if(cmder->parser.history_list.handle)
|
||||||
|
{
|
||||||
|
line = cmder->parser.history_list.handle->line;
|
||||||
|
if(cmder->parser.history_list.handle->next)
|
||||||
|
{
|
||||||
|
cmder->parser.history_list.handle = cmder->parser.history_list.handle->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *xcmd_history_prev(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = NULL;
|
||||||
|
if(cmder->parser.history_list.handle)
|
||||||
|
{
|
||||||
|
if(cmder->parser.history_list.handle != cmder->parser.history_list.next)
|
||||||
|
{
|
||||||
|
cmder->parser.history_list.handle = cmder->parser.history_list.handle->prev;
|
||||||
|
line = cmder->parser.history_list.handle->line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *xcmd_history_current(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
char *line = NULL;
|
||||||
|
if(cmder->parser.history_list.handle)
|
||||||
|
{
|
||||||
|
line = cmder->parser.history_list.handle->line;
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t xcmd_history_len(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
return cmder->parser.history_list.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_history_reset(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
cmder->parser.history_list.handle = cmder->parser.history_list.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t xcmd_exec(xcmder_t *cmder, char* str)
|
||||||
|
{
|
||||||
|
int param_num = 0;
|
||||||
|
char *cmd_param_buff[cmder->parser.param_len];
|
||||||
|
char temp[cmder->parser.line_len];
|
||||||
|
strncpy(temp, str, cmder->parser.line_len);
|
||||||
|
param_num = xcmd_get_param(temp, "., ", cmd_param_buff, cmder->parser.param_len);
|
||||||
|
if(param_num >0)
|
||||||
|
{
|
||||||
|
xcmd_match(cmder, param_num, cmd_param_buff);
|
||||||
|
}
|
||||||
|
return param_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xcmd_key_register(xcmder_t *cmder, xcmd_key_t *keys, uint16_t number)
|
||||||
|
{
|
||||||
|
uint16_t i=0;
|
||||||
|
if(cmder->key_list.len == 0)
|
||||||
|
{
|
||||||
|
cmder->key_list.next = &keys[i++];
|
||||||
|
cmder->key_list.next->next = NULL;
|
||||||
|
++cmder->key_list.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(i<number)
|
||||||
|
{
|
||||||
|
xcmd_key_t *p = cmder->key_list.next;
|
||||||
|
cmder->key_list.next = &keys[i];
|
||||||
|
keys[i].next = p;
|
||||||
|
++cmder->key_list.len;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return cmder->key_list.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xcmd_register(xcmder_t *cmder, xcmd_t *cmds, uint16_t number)
|
||||||
|
{
|
||||||
|
uint16_t i=0;
|
||||||
|
if(cmder->cmd_list.len == 0)
|
||||||
|
{
|
||||||
|
cmder->cmd_list.next = &cmds[i++];
|
||||||
|
cmder->cmd_list.next->next = NULL;
|
||||||
|
++cmder->cmd_list.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(i<number)
|
||||||
|
{
|
||||||
|
xcmd_t *p = cmder->cmd_list.next;
|
||||||
|
cmder->cmd_list.next = &cmds[i];
|
||||||
|
cmds[i].next = p;
|
||||||
|
++cmder->cmd_list.len;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return cmder->cmd_list.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcmder_t *xcmd_create( int (*get_c)(uint8_t*), int (*put_c)(uint8_t), uint16_t cmd_len, uint16_t history_len, uint16_t param_len)
|
||||||
|
{
|
||||||
|
xcmder_t* cmder = (xcmder_t*)calloc(1, sizeof(xcmder_t));
|
||||||
|
if(cmder == NULL)
|
||||||
|
{
|
||||||
|
goto create_cmder_failure;
|
||||||
|
}
|
||||||
|
if(get_c && put_c)
|
||||||
|
{
|
||||||
|
cmder->parser.display_line = (char*)calloc(cmd_len, sizeof(char));
|
||||||
|
cmder->parser.line_len = cmd_len;
|
||||||
|
cmder->parser.line_totle = history_len;
|
||||||
|
if(cmder->parser.display_line == NULL)
|
||||||
|
{
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmder->parser.param_len = param_len;
|
||||||
|
|
||||||
|
cmder->parser.byte_num = 0;
|
||||||
|
cmder->parser.cursor = 0;
|
||||||
|
cmder->parser.encode_case_stu = 0;
|
||||||
|
|
||||||
|
cmder->io.get_c = get_c;
|
||||||
|
cmder->io.put_c = put_c;
|
||||||
|
cmder->_initOK = 1;
|
||||||
|
|
||||||
|
cmder->cmd_list.len = 0;
|
||||||
|
cmder->cmd_list.next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
return cmder;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
if(cmder->parser.display_line)
|
||||||
|
{
|
||||||
|
free(cmder->parser.display_line);
|
||||||
|
cmder->parser.display_line = NULL;
|
||||||
|
}
|
||||||
|
create_cmder_failure:
|
||||||
|
if(cmder)
|
||||||
|
{
|
||||||
|
free(cmder);
|
||||||
|
cmder = NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_destory(xcmder_t* cmder)
|
||||||
|
{
|
||||||
|
if(cmder)
|
||||||
|
{
|
||||||
|
if(cmder->parser.display_line)
|
||||||
|
{
|
||||||
|
free(cmder->parser.display_line);
|
||||||
|
cmder->parser.display_line = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcmd_history_t *history_p = cmder->parser.history_list.next;
|
||||||
|
while(history_p)
|
||||||
|
{
|
||||||
|
xcmd_history_t * free_p = history_p;
|
||||||
|
history_p = history_p->next;
|
||||||
|
free(free_p);
|
||||||
|
}
|
||||||
|
free(cmder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xcmd_task(xcmder_t* cmder)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
char *str = NULL;
|
||||||
|
if(cmder && cmder->_initOK)
|
||||||
|
{
|
||||||
|
if(cmder->io.get_c(&c))
|
||||||
|
{
|
||||||
|
str = xcmd_parser(cmder, c);
|
||||||
|
if(str)
|
||||||
|
{
|
||||||
|
xcmd_exec(cmder, str);
|
||||||
|
str[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
#ifndef XCMD_H
|
||||||
|
#define XCMD_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
typedef void(*cmd_func_t)(int argv, char* argc[]);
|
||||||
|
typedef int(*cmd_key_func_t)(void *data);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CTR_A = 1,
|
||||||
|
CTR_B = 2,
|
||||||
|
CTR_C = 3,
|
||||||
|
CTR_D = 4,
|
||||||
|
CTR_E = 5,
|
||||||
|
CTR_F = 6,
|
||||||
|
CTR_G = 7,
|
||||||
|
CTR_H = 8,
|
||||||
|
BACKSPACE = 8,
|
||||||
|
CTR_I = 9,
|
||||||
|
LF = 9,
|
||||||
|
TAB = 9,
|
||||||
|
CTR_J = 10,
|
||||||
|
CTR_K = 11,
|
||||||
|
CTR_L = 12,
|
||||||
|
CTR_M = 13,
|
||||||
|
CR = 13,
|
||||||
|
CTR_N = 14,
|
||||||
|
CTR_O = 15,
|
||||||
|
CTR_P = 16,
|
||||||
|
CTR_Q = 17,
|
||||||
|
CTR_R = 18,
|
||||||
|
CTR_S = 19,
|
||||||
|
CTR_T = 20,
|
||||||
|
CTR_U = 21,
|
||||||
|
CTR_V = 22,
|
||||||
|
CTR_W = 23,
|
||||||
|
CTR_X = 24,
|
||||||
|
CTR_Y = 25,
|
||||||
|
CTR_Z = 26,
|
||||||
|
ESC = 27,
|
||||||
|
FS = 28,
|
||||||
|
GS = 29,
|
||||||
|
RS = 30,
|
||||||
|
US = 31,
|
||||||
|
L_DELETE = 127,
|
||||||
|
UP = 0x00415B1B,
|
||||||
|
DW = 0x00425B1B,
|
||||||
|
RIGHT = 0x00435B1B,
|
||||||
|
LEFT = 0x00445B1B,
|
||||||
|
END = 0x00465B1B,
|
||||||
|
HOME = 0x00485B1B,
|
||||||
|
INSERT = 0x7E325B1B,
|
||||||
|
R_DELETE = 0x7E335B1B,
|
||||||
|
PGUP = 0x7E355B1B,
|
||||||
|
PGDW = 0x7E365B1B,
|
||||||
|
}XCMD_KEY_T;
|
||||||
|
|
||||||
|
typedef struct __cmd
|
||||||
|
{
|
||||||
|
char* name;
|
||||||
|
cmd_func_t func;
|
||||||
|
char* help;
|
||||||
|
struct __cmd *next;
|
||||||
|
}xcmd_t;
|
||||||
|
|
||||||
|
typedef struct __key
|
||||||
|
{
|
||||||
|
XCMD_KEY_T key;
|
||||||
|
cmd_key_func_t func;
|
||||||
|
struct __key *next;
|
||||||
|
}xcmd_key_t;
|
||||||
|
|
||||||
|
typedef struct __history
|
||||||
|
{
|
||||||
|
char *line;
|
||||||
|
struct __history *next;
|
||||||
|
struct __history *prev;
|
||||||
|
}xcmd_history_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int (*get_c)(uint8_t*);
|
||||||
|
int (*put_c)(uint8_t);
|
||||||
|
}io;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t len;
|
||||||
|
xcmd_t *next;
|
||||||
|
xcmd_t *tail;
|
||||||
|
}cmd_list;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t len;
|
||||||
|
xcmd_key_t *next;
|
||||||
|
|
||||||
|
}key_list;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t len;
|
||||||
|
xcmd_history_t *next;
|
||||||
|
xcmd_history_t *handle;
|
||||||
|
}history_list;
|
||||||
|
char *display_line; /* 显示区的缓存 */
|
||||||
|
uint16_t line_totle; /* 一共有多少行 */
|
||||||
|
uint16_t line_len; /* 每一行的最大长度 */
|
||||||
|
uint16_t byte_num; /* 当前行的字符个数 */
|
||||||
|
uint16_t cursor; /* 光标所在位置 */
|
||||||
|
uint8_t encode_case_stu;
|
||||||
|
uint32_t key_val;
|
||||||
|
uint16_t param_len;
|
||||||
|
}parser;
|
||||||
|
uint8_t _initOK;
|
||||||
|
} xcmder_t;
|
||||||
|
|
||||||
|
#define xcmd_create_default(getchar, putchar) xcmd_create(getchar, putchar, 64, 10, 16);
|
||||||
|
xcmder_t *xcmd_create( int (*get_c)(uint8_t*), int (*put_c)(uint8_t), uint16_t cmd_len, uint16_t history_len, uint16_t param_len);
|
||||||
|
void xcmd_destory(xcmder_t* cmder);
|
||||||
|
void xcmd_task(xcmder_t *cmder);
|
||||||
|
|
||||||
|
int xcmd_register(xcmder_t *cmder, xcmd_t *cmds, uint16_t number);
|
||||||
|
int xcmd_key_register(xcmder_t *cmder, xcmd_key_t *keys, uint16_t number);
|
||||||
|
|
||||||
|
uint8_t xcmd_exec(xcmder_t *cmder, char *str);
|
||||||
|
void xcmd_print_str(xcmder_t * cmder, char* str);
|
||||||
|
|
||||||
|
void xcmd_display_insert_char(xcmder_t *cmder, char c);
|
||||||
|
void xcmd_display_delete_char(xcmder_t *cmder);
|
||||||
|
void xcmd_display_clear(xcmder_t *cmder);
|
||||||
|
char*xcmd_display_get(xcmder_t *cmder);
|
||||||
|
|
||||||
|
uint16_t xcmd_history_len(xcmder_t *cmder);
|
||||||
|
void xcmd_history_insert(xcmder_t *cmder, char* str);
|
||||||
|
char *xcmd_history_next(xcmder_t *cmder);
|
||||||
|
char *xcmd_history_prev(xcmder_t *cmder);
|
||||||
|
char *xcmd_history_current(xcmder_t *cmder);
|
||||||
|
void xcmd_history_reset(xcmder_t *cmder);
|
||||||
|
#endif /*XCMD_H*/
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "xcmd_default_cmds.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static xcmder_t *g_cmder = NULL;
|
||||||
|
|
||||||
|
static void cmd_clear(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
printf("\033c");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_help(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
xcmd_t *p = g_cmder->cmd_list.next;
|
||||||
|
while(p)
|
||||||
|
{
|
||||||
|
printf("%-20s %s\r\n",p->name, p->help);
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_exit(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_logo(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
char *log = "\
|
||||||
|
_ _ ___ __ __ ____ \n\
|
||||||
|
( \\/ )/ __)( \\/ )( _ \\ \n\
|
||||||
|
) (( (__ ) ( )(_) )\n\
|
||||||
|
(_/\\_)\\___)(_/\\/\\_)(____/\n ";
|
||||||
|
printf("%s", log);
|
||||||
|
}
|
||||||
|
|
||||||
|
static xcmd_t cmds[] =
|
||||||
|
{
|
||||||
|
{"clear", cmd_clear, "clear screen", NULL},
|
||||||
|
{"help", cmd_help, "show this list", NULL},
|
||||||
|
{"exit", cmd_exit, "exit xcmder", NULL},
|
||||||
|
{"logo", cmd_logo, "show logo", NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
void default_cmds_init(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
xcmd_register(cmder, cmds, sizeof(cmds)/sizeof(xcmd_t));
|
||||||
|
g_cmder = cmder;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef XCMMD_DEFAULT_CMDS_H
|
||||||
|
#define XCMMD_DEFAULT_CMDS_H
|
||||||
|
|
||||||
|
#include "xcmd.h"
|
||||||
|
void default_cmds_init(xcmder_t *cmder);
|
||||||
|
|
||||||
|
#endif /*XCMMD_DEFAULT_CMDS_H*/
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "xcmd_default_keys.h"
|
||||||
|
|
||||||
|
#define STR_UP "\x1B\x5B\x41"
|
||||||
|
#define STR_DW "\x1B\x5B\x42"
|
||||||
|
#define STR_RIGHT "\x1B\x5B\x43"
|
||||||
|
#define STR_LEFT "\x1B\x5B\x44"
|
||||||
|
#define STR_END "\x1B\x5B\x46"
|
||||||
|
#define STR_HOME "\x1B\x5B\x48"
|
||||||
|
#define STR_INSERT "\x1B\x5B\x32\x7E"
|
||||||
|
#define STR_DELETE "\x1B\x5B\x33\x7E"
|
||||||
|
#define STR_PGUP "\x1B\x5B\x35\x7E"
|
||||||
|
#define STR_PGDW "\x1B\x5B\x36\x7E"
|
||||||
|
|
||||||
|
static int xcmd_del_char(void *pv)
|
||||||
|
{
|
||||||
|
xcmder_t *cmder = (xcmder_t*)pv;
|
||||||
|
xcmd_display_delete_char(cmder);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xcmd_cursor_left(void *pv)
|
||||||
|
{
|
||||||
|
xcmder_t *cmder = (xcmder_t*)pv;
|
||||||
|
if(cmder->parser.cursor > 0)
|
||||||
|
{
|
||||||
|
cmder->parser.cursor--;
|
||||||
|
xcmd_print_str(cmder, STR_LEFT);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xcmd_cursor_right(void *pv)
|
||||||
|
{
|
||||||
|
xcmder_t *cmder = (xcmder_t*)pv;
|
||||||
|
if(cmder->parser.cursor < cmder->parser.byte_num)
|
||||||
|
{
|
||||||
|
cmder->parser.cursor++;
|
||||||
|
xcmd_print_str(cmder, STR_RIGHT);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xcmd_history_dw(void *pv)
|
||||||
|
{
|
||||||
|
xcmder_t *cmder = (xcmder_t*)pv;
|
||||||
|
char *line = xcmd_history_prev(cmder);
|
||||||
|
char *display_line = xcmd_display_get(cmder);
|
||||||
|
if(line)
|
||||||
|
{
|
||||||
|
xcmd_display_clear(cmder);
|
||||||
|
uint16_t len = strlen(line);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
strncpy(display_line, line, cmder->parser.line_len);
|
||||||
|
xcmd_print_str(cmder, line);
|
||||||
|
cmder->parser.byte_num = len;
|
||||||
|
cmder->parser.cursor = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xcmd_display_clear(cmder);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xcmd_history_up(void *pv)
|
||||||
|
{
|
||||||
|
xcmder_t *cmder = (xcmder_t*)pv;
|
||||||
|
char *line = xcmd_history_next(cmder);
|
||||||
|
char *display_line = xcmd_display_get(cmder);
|
||||||
|
if(line)
|
||||||
|
{
|
||||||
|
xcmd_display_clear(cmder);
|
||||||
|
uint16_t len = strlen(line);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
strncpy(display_line, line, cmder->parser.line_len);
|
||||||
|
xcmd_print_str(cmder, line);
|
||||||
|
cmder->parser.byte_num = len;
|
||||||
|
cmder->parser.cursor = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static xcmd_key_t default_keys[] =
|
||||||
|
{
|
||||||
|
{L_DELETE, xcmd_del_char, NULL},
|
||||||
|
{LEFT, xcmd_cursor_left, NULL},
|
||||||
|
{RIGHT, xcmd_cursor_right, NULL},
|
||||||
|
{DW, xcmd_history_dw, NULL},
|
||||||
|
{UP, xcmd_history_up, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
void default_keys_init(xcmder_t *cmder)
|
||||||
|
{
|
||||||
|
xcmd_key_register(cmder, default_keys, sizeof(default_keys)/sizeof(xcmd_key_t));
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef XCMD_DEFAULT_KEYS_H
|
||||||
|
#define XCMD_DEFAULT_KEYS_H
|
||||||
|
|
||||||
|
#include "xcmd.h"
|
||||||
|
|
||||||
|
#define STR_UP "\x1B\x5B\x41"
|
||||||
|
#define STR_DW "\x1B\x5B\x42"
|
||||||
|
#define STR_RIGHT "\x1B\x5B\x43"
|
||||||
|
#define STR_LEFT "\x1B\x5B\x44"
|
||||||
|
#define STR_END "\x1B\x5B\x46"
|
||||||
|
#define STR_HOME "\x1B\x5B\x48"
|
||||||
|
#define STR_INSERT "\x1B\x5B\x32\x7E"
|
||||||
|
#define STR_DELETE "\x1B\x5B\x33\x7E"
|
||||||
|
#define STR_PGUP "\x1B\x5B\x35\x7E"
|
||||||
|
#define STR_PGDW "\x1B\x5B\x36\x7E"
|
||||||
|
|
||||||
|
void default_keys_init(xcmder_t *cmder);
|
||||||
|
|
||||||
|
#endif /* XCMD_DEFAULT_KEYS_H */
|
Loading…
Reference in New Issue