From 365f3580e735a187b2e68d537dc4d7d26d112a58 Mon Sep 17 00:00:00 2001 From: hqm <13720409820@163.com> Date: Sun, 12 Sep 2021 18:01:02 +0800 Subject: [PATCH] New feature is ok --- .gitignore | 2 +- .vscode/c_cpp_properties.json | 21 ++ .vscode/launch.json | 8 +- .vscode/settings.json | 23 ++ .vscode/tasks.json | 27 -- Makefile | 22 -- example/Makefile | 1 - example/linux/Makefile | 21 ++ example/{ => linux}/linux_main.c | 37 ++- example/{ => linux}/test_cmds.c | 30 +- xcmd.c | 527 ------------------------------- xcmd.h | 80 ----- xcmd/xcmd.c | 527 +++++++++++++++++++++++++++++++ xcmd/xcmd.h | 150 +++++++++ xcmd/xcmd_default_cmds.c | 48 +++ xcmd/xcmd_default_cmds.h | 7 + xcmd/xcmd_default_keys.c | 99 ++++++ xcmd/xcmd_default_keys.h | 19 ++ xcmder | Bin 18728 -> 0 bytes 19 files changed, 957 insertions(+), 692 deletions(-) mode change 100644 => 100755 .gitignore create mode 100755 .vscode/c_cpp_properties.json mode change 100644 => 100755 .vscode/launch.json create mode 100755 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 Makefile delete mode 100644 example/Makefile create mode 100755 example/linux/Makefile rename example/{ => linux}/linux_main.c (61%) mode change 100644 => 100755 rename example/{ => linux}/test_cmds.c (75%) delete mode 100755 xcmd.c delete mode 100755 xcmd.h create mode 100755 xcmd/xcmd.c create mode 100755 xcmd/xcmd.h create mode 100755 xcmd/xcmd_default_cmds.c create mode 100755 xcmd/xcmd_default_cmds.h create mode 100755 xcmd/xcmd_default_keys.c create mode 100755 xcmd/xcmd_default_keys.h delete mode 100755 xcmder 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 296c1c78d54d156c1ff0581b810cf2b2e527c523..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18728 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