diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 42afabf..45ed3d7 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/build \ No newline at end of file +*/build \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100755 index 0000000..e3d2bc6 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -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 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json old mode 100644 new mode 100755 index 77fa569..140e1f9 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,10 +5,10 @@ "version": "0.2.0", "configurations": [ { - "name": "gcc - 生成和调试活动文件", + "name": "(gdb) 启动", "type": "cppdbg", "request": "launch", - "program": "${fileDirname}/../xcmder", + "program": "${workspaceFolder}/example/linux/xcmder", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", @@ -21,9 +21,7 @@ "text": "-enable-pretty-printing", "ignoreFailures": true } - ], - "preLaunchTask": "", - "miDebuggerPath": "/usr/bin/gdb" + ] } ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100755 index 0000000..8944576 --- /dev/null +++ b/.vscode/settings.json @@ -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" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index a5ef78d..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index 0e2aa9b..0000000 --- a/Makefile +++ /dev/null @@ -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 - - diff --git a/example/Makefile b/example/Makefile deleted file mode 100644 index f6e12e9..0000000 --- a/example/Makefile +++ /dev/null @@ -1 +0,0 @@ -OBJ += test_cmds.o linux_main.o \ No newline at end of file diff --git a/example/linux/Makefile b/example/linux/Makefile new file mode 100755 index 0000000..cb5da2a --- /dev/null +++ b/example/linux/Makefile @@ -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 + + diff --git a/example/linux_main.c b/example/linux/linux_main.c old mode 100644 new mode 100755 similarity index 61% rename from example/linux_main.c rename to example/linux/linux_main.c index 7b72ef4..24daf6b --- a/example/linux_main.c +++ b/example/linux/linux_main.c @@ -1,5 +1,9 @@ #include +#include +#include #include "xcmd.h" +#include "xcmd_default_keys.h" +#include "xcmd_default_cmds.h" #include #include #include @@ -23,6 +27,7 @@ int getch(void) } ch = getchar(); + // printf("%d\n", ch); if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子 return -1; } @@ -30,27 +35,49 @@ int getch(void) return ch; } -int cmd_get_char(char *ch) +int cmd_get_char(uint8_t *ch) { *ch = getch(); return 1; } -int cmd_put_char(char ch) +int cmd_put_char(uint8_t ch) { putchar(ch); 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) { - printf("hello\n"); - xcmder_t* cmder = xcmd_create_default(cmd_get_char, cmd_put_char); if(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) { xcmd_task(cmder); diff --git a/example/test_cmds.c b/example/linux/test_cmds.c similarity index 75% rename from example/test_cmds.c rename to example/linux/test_cmds.c index c54eac7..d25a02a 100755 --- a/example/test_cmds.c +++ b/example/linux/test_cmds.c @@ -3,7 +3,7 @@ #include #include -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_CHECK() \ @@ -22,7 +22,7 @@ xcmder_t *g_cmder = NULL; } \ 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; if(need<(argc)) @@ -46,12 +46,7 @@ uint8_t param_check(int need, int argc, char*argv[]) return ret; } -void cmd_clear(int argc, char* argv[]) -{ - printf("\033c"); -} - -void cmd_echo(int argc, char* argv[]) +static void cmd_echo(int argc, char* 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; 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}, {"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) { - xcmd_register(cmder, cmds, sizeof(cmds)/sizeof(cmd_t)); + xcmd_register(cmder, cmds, sizeof(cmds)/sizeof(xcmd_t)); g_cmder = cmder; } diff --git a/xcmd.c b/xcmd.c deleted file mode 100755 index 7ad9310..0000000 --- a/xcmd.c +++ /dev/null @@ -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) - { - 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; iio.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; iparser.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; iparser.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; iparser.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(icmd_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); - } - } - } -} - - - - - diff --git a/xcmd.h b/xcmd.h deleted file mode 100755 index bd6d262..0000000 --- a/xcmd.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef XCMD_H -#define XCMD_H - -#include -#include -#include -#include -#include -#include - -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*/ diff --git a/xcmd/xcmd.c b/xcmd/xcmd.c new file mode 100755 index 0000000..6d2a551 --- /dev/null +++ b/xcmd/xcmd.c @@ -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 &&icmd_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; iparser.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; iio.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; iparser.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(ikey_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(icmd_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'; + } + } + } +} + + + + + diff --git a/xcmd/xcmd.h b/xcmd/xcmd.h new file mode 100755 index 0000000..7816200 --- /dev/null +++ b/xcmd/xcmd.h @@ -0,0 +1,150 @@ +#ifndef XCMD_H +#define XCMD_H + +#include +#include +#include +#include +#include +#include + +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*/ diff --git a/xcmd/xcmd_default_cmds.c b/xcmd/xcmd_default_cmds.c new file mode 100755 index 0000000..bc209c2 --- /dev/null +++ b/xcmd/xcmd_default_cmds.c @@ -0,0 +1,48 @@ +#include "xcmd_default_cmds.h" +#include + +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; +} diff --git a/xcmd/xcmd_default_cmds.h b/xcmd/xcmd_default_cmds.h new file mode 100755 index 0000000..2bfc19f --- /dev/null +++ b/xcmd/xcmd_default_cmds.h @@ -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*/ \ No newline at end of file diff --git a/xcmd/xcmd_default_keys.c b/xcmd/xcmd_default_keys.c new file mode 100755 index 0000000..23d54c1 --- /dev/null +++ b/xcmd/xcmd_default_keys.c @@ -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)); +} \ No newline at end of file diff --git a/xcmd/xcmd_default_keys.h b/xcmd/xcmd_default_keys.h new file mode 100755 index 0000000..85d4100 --- /dev/null +++ b/xcmd/xcmd_default_keys.h @@ -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 */ \ No newline at end of file diff --git a/xcmder b/xcmder deleted file mode 100755 index 296c1c7..0000000 Binary files a/xcmder and /dev/null differ