From 9f9a69a100d61f66f7c5a0a901ff8b48be7cc5cc Mon Sep 17 00:00:00 2001 From: hqm <13720409820@163.com> Date: Sun, 11 Jun 2023 23:19:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/c_cpp_properties.json | 17 - .vscode/settings.json | 30 +- doc/历史记录链表模型.drawio | 81 --- example/linux/Makefile | 59 +- example/linux/linux_main.c | 165 +++-- example/linux/xcmd_confg.h | 2 - extensions/ex_cmds/ex_cmds.c | 3 +- extensions/ex_keys/ex_keys.c | 53 +- extensions/ex_list/ex_list.c | 6 + extensions/fs_cmds/fs_cmds.c | 45 +- extensions/test/test.c | 60 +- inc/xcmd.h | 335 +++------- inc/xcmd_default_confg.h | 4 + inc/xcmd_define.h | 120 ---- src/xcmd.c | 987 +++++++++------------------- src/xcmd_default_cmds.c | 56 +- src/xcmd_default_keys.c | 97 ++- 17 files changed, 759 insertions(+), 1361 deletions(-) delete mode 100755 .vscode/c_cpp_properties.json delete mode 100755 doc/历史记录链表模型.drawio mode change 100755 => 100644 inc/xcmd.h delete mode 100644 inc/xcmd_define.h mode change 100755 => 100644 src/xcmd.c diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100755 index a0a1f34..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/opt/gcc-arm-none-eabi-9-2020-q2-update/bin/arm-none-eabi-gcc", - "cStandard": "gnu17", - "cppStandard": "gnu++14", - "intelliSenseMode": "linux-gcc-arm", - "configurationProvider": "ms-vscode.makefile-tools" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index e64aa1e..d301b25 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,6 +29,32 @@ "ex_keys.h": "c", "ex_cmds.h": "c", "test.h": "c", - "ctype.h": "c" - } + "ctype.h": "c", + "string.h": "c", + "stdarg.h": "c", + "stddef.h": "c", + "unistd.h": "c", + "stdlib.h": "c", + "stdio.h": "c", + "xnr_line.h": "c" + }, + "cmake.sourceDirectory": "/home/hqm/project/xcmd/example/esp_idf", + "MicroPython.executeButton": [ + { + "text": "▶", + "tooltip": "运行", + "alignment": "left", + "command": "extension.executeFile", + "priority": 3.5 + } + ], + "MicroPython.syncButton": [ + { + "text": "$(sync)", + "tooltip": "同步", + "alignment": "left", + "command": "extension.execute", + "priority": 4 + } + ] } \ No newline at end of file diff --git a/doc/历史记录链表模型.drawio b/doc/历史记录链表模型.drawio deleted file mode 100755 index d338c6a..0000000 --- a/doc/历史记录链表模型.drawio +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/example/linux/Makefile b/example/linux/Makefile index 77a19c4..b482baa 100755 --- a/example/linux/Makefile +++ b/example/linux/Makefile @@ -4,37 +4,44 @@ OBJ += xcmd.o \ xcmd_default_keys.o \ xcmd_default_cmds.o \ linux_main.o \ - test.o \ - ex_keys.o \ - ex_list.o \ - ex_cmds.o \ - socket_cmds.o \ - diskio.o \ - ff.o \ - ffunicode.o \ - fatfs_port.o \ - fs_cmds.o\ - fatfs_disk_mmc.o\ - fatfs_disk_ram.o + xnr_io.o \ + xnr_line.o \ + xnr_history.o \ + xnr_key.o \ + xnr_var.o \ + # test.o \ + # ex_keys.o \ + # ex_list.o \ + # ex_cmds.o \ + # socket_cmds.o \ + # diskio.o \ + # ff.o \ + # ffunicode.o \ + # fatfs_port.o \ + # fs_cmds.o\ + # fatfs_disk_mmc.o\ + # fatfs_disk_ram.o VPATH := ../../src \ - ../../extensions/test \ - ../../extensions/ex_keys \ - ../../extensions/ex_list \ - ../../extensions/ex_cmds \ - ../../extensions/net_cmds \ - ../../extensions/fs_cmds \ - ../../extensions/fs_cmds/FatFs/source \ + ../../third_party/XNanoReadLine \ + # ../../extensions/test \ + # ../../extensions/ex_keys \ + # ../../extensions/ex_list \ + # ../../extensions/ex_cmds \ + # ../../extensions/net_cmds \ + # ../../extensions/fs_cmds \ + # ../../extensions/fs_cmds/FatFs/source \ INC += -I./ \ -I../../inc \ - -I../../extensions/test \ - -I../../extensions/ex_keys \ - -I../../extensions/ex_list \ - -I../../extensions/ex_cmds \ - -I../../extensions/net_cmds \ - -I../../extensions/fs_cmds/FatFs/source \ - -I../../extensions/fs_cmds \ + -I../../third_party/XNanoReadLine \ + # -I../../extensions/test \ + # -I../../extensions/ex_keys \ + # -I../../extensions/ex_list \ + # -I../../extensions/ex_cmds \ + # -I../../extensions/net_cmds \ + # -I../../extensions/fs_cmds/FatFs/source \ + # -I../../extensions/fs_cmds \ OBJ_WITH_BUILD_DIR:=$(addprefix build/,$(OBJ)) diff --git a/example/linux/linux_main.c b/example/linux/linux_main.c index cbd1190..e587d85 100755 --- a/example/linux/linux_main.c +++ b/example/linux/linux_main.c @@ -6,22 +6,25 @@ * @Description: In User Settings Edit * @FilePath: /xcmd/example/linux/linux_main.c */ +#include +#include +#include #include #include #include #include "xcmd_platform.h" #include "xcmd.h" -#include "test.h" -#include "ex_keys.h" -#include "ex_cmds.h" -#include "ex_list.h" -#include "fs_cmds.h" -#include "socket_cmds.h" -#include "ff.h" -#include "fatfs_disk_mmc.h" -#include "fatfs_disk_ram.h" +// #include "test.h" +// #include "ex_keys.h" +// #include "ex_cmds.h" +// #include "ex_list.h" +// #include "fs_cmds.h" +// #include "socket_cmds.h" +// #include "ff.h" +// #include "fatfs_disk_mmc.h" +// #include "fatfs_disk_ram.h" -FIL g_fp; +// FIL g_fp; int getch(void) { @@ -49,25 +52,49 @@ int getch(void) return ch; } -int cmd_get_char(uint8_t *ch) + +int io_write_t(int fd, const char *buf, size_t len) { - *ch = getch(); - return 1; + return write(fd, buf, len); } -int cmd_put_char(uint8_t ch) +int io_read_t(int fd, char *buf, size_t len) { - putchar(ch); - return 1; + for (int i = 0; i < len; i++) + { + buf[i] = getch(); + } + return len; } -static int key_ctr_c(void *pv) +static int cmd_ls(int argc, char* argv[]) +{ + xcmder_t *xcmder = XCMD_CURRENT(); + int fd = xnr_io_out_fd(&xcmder->io); + if(fd != STDOUT_FILENO) + { + // 保存原始的标准输出文件描述符 + int stdout_backup = dup(STDOUT_FILENO); + dup2(fd, STDOUT_FILENO); + close(fd); + system("ls"); + // 恢复标准输出为终端 + dup2(stdout_backup, STDOUT_FILENO); + } + else + { + system("ls"); + } + return 0; +} + +static int key_ctr_c(int argc, char* argv[]) { exit(0); } static xcmd_key_t keys[] = - { +{ {KEY_CTR_C, key_ctr_c, "ctr+c", NULL}, }; @@ -76,41 +103,91 @@ void user_keys_init(void) xcmd_key_register(keys, sizeof(keys) / sizeof(xcmd_key_t)); } -void fatfs_test(char* path) +// void fatfs_test(char* path) +// { +// FRESULT res; +// res = f_open(&g_fp, path, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); +// if(res == FR_OK) +// { +// char buf[128]; +// strcpy(buf, "hello world"); +// int len = strlen(buf); +// UINT bw; +// UINT br; +// res = f_write(&g_fp, buf, len, &bw); +// memset(buf, 0, len); +// f_lseek(&g_fp,0); +// res = f_read(&g_fp, buf, len, &br); +// printf("test file:%s\r\n", buf); +// f_close(&g_fp); +// } +// } + +static int pre_cmd(int argc, char* argv[]) { - FRESULT res; - res = f_open(&g_fp, path, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); - if(res == FR_OK) + xcmder_t *xcmder = XCMD_CURRENT(); + for(int i=0; i< argc; i++) { - char buf[128]; - strcpy(buf, "hello world"); - int len = strlen(buf); - UINT bw; - UINT br; - res = f_write(&g_fp, buf, len, &bw); - memset(buf, 0, len); - f_lseek(&g_fp,0); - res = f_read(&g_fp, buf, len, &br); - printf("test file:%s\r\n", buf); - f_close(&g_fp); + if(strcmp(argv[i], ">") == 0) + { + if(i < argc-1) + { + int fd = open(argv[i+1], O_WRONLY | O_TRUNC | O_CREAT, 0644); + xnr_io_set_out_fd(&xcmder->io, fd); + } + return i; + } } + return argc; +} + +static int after_cmd(int argc, char* argv[]) +{ + xcmder_t *xcmder = XCMD_CURRENT(); + int fd = xnr_io_out_fd(&xcmder->io); + if(STDOUT_FILENO != fd) + { + close(fd); + xnr_io_set_out_fd(&xcmder->io, STDOUT_FILENO); + } + return argc; +} + +#define HELP_LS ("like linux \"ls\"") + +XCMD_EXPORT_CMD(ls, cmd_ls, HELP_LS) + +static xcmd_t cmds[] = +{ +#ifndef ENABLE_XCMD_EXPORT + {"ls", cmd_ls, HELP_LS, NULL}, +#endif +}; + +void linux_cmds_init(void) +{ + xcmd_cmd_register(cmds, sizeof(cmds)/sizeof(xcmd_t)); } int main(void) { - xcmd_init(cmd_get_char, cmd_put_char); - ram_disk_init(); - mmc_disk_init(); - test_cmd_init(); - test_keys_init(); + xcmder_t xcmder; + xcmd_init(&xcmder, io_write_t, io_read_t); + xcmd_reg_pre_cmd_cbk(&xcmder, pre_cmd); + xcmd_reg_after_cmd_cbk(&xcmder, after_cmd); user_keys_init(); - ex_keys_init(); - ex_cmds_init(); - socket_cmds_init(); - fs_cmds_init(); - ex_list_init(); + linux_cmds_init(); + // ram_disk_init(); + // mmc_disk_init(); + // test_cmd_init(); + // test_keys_init(); + // ex_keys_init(); + // ex_cmds_init(); + // socket_cmds_init(); + // fs_cmds_init(); + // ex_list_init(); while (1) { - xcmd_task(); + xcmd_task(&xcmder); } } \ No newline at end of file diff --git a/example/linux/xcmd_confg.h b/example/linux/xcmd_confg.h index dfed81d..9c2092b 100755 --- a/example/linux/xcmd_confg.h +++ b/example/linux/xcmd_confg.h @@ -13,8 +13,6 @@ extern "C" { #endif -#include "xcmd_define.h" - #define XCMD_LINE_MAX_LENGTH (128) /* 命令行支持的最大字符数 */ #define XCMD_HISTORY_MAX_NUM (16) /* 支持的历史记录个数, 这个参数对内存的影响很大,建议arduino设置为0,0为不支持 */ #define XCMD_PARAM_MAX_NUM (64) /* 支持输入的参数个数 */ diff --git a/extensions/ex_cmds/ex_cmds.c b/extensions/ex_cmds/ex_cmds.c index 6e4d8a6..8af11e7 100644 --- a/extensions/ex_cmds/ex_cmds.c +++ b/extensions/ex_cmds/ex_cmds.c @@ -13,13 +13,14 @@ static int cmd_run(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); if(argc >= 2) { xcmd_exec(argv[1]); } else { - xcmd_print("%s\r\n", HELP_RUN); + xcmd_print(xcmder, "%s\r\n", HELP_RUN); } return 0; } diff --git a/extensions/ex_keys/ex_keys.c b/extensions/ex_keys/ex_keys.c index a5f9a5f..700bd3a 100644 --- a/extensions/ex_keys/ex_keys.c +++ b/extensions/ex_keys/ex_keys.c @@ -4,59 +4,65 @@ #define IS_ALPHA(c) ( (c>='A' && c<='Z') || (c>='a' && c<='z') ) #define IS_NUMBER(c) (c>='0' && c<='9') -static int xcmd_ctr_a(void *pv) +static int xcmd_ctr_a(int argc, char* argv[]) { /* 移动光标到头 */ - xcmd_display_cursor_set(0); + xcmder_t *xcmder = XCMD_CURRENT(); + xnr_line_cursor_set(&xcmder->line, 0); return 0; } -static int xcmd_ctr_e(void *pv) +static int xcmd_ctr_e(int argc, char* argv[]) { /* 移动光标到尾 */ - xcmd_display_cursor_set(-1); + xcmder_t *xcmder = XCMD_CURRENT(); + xnr_line_cursor_set(&xcmder->line, XCMD_LINE_MAX_LENGTH); return 0; } -static int xcmd_ctr_u(void *pv) +static int xcmd_ctr_u(int argc, char* argv[]) { /* 删除光标左边的所有字符 */ - uint16_t pos = xcmd_display_cursor_get(); - for(uint16_t i=0; iline); + for(int i=0; iline); } return 0; } -static int xcmd_ctr_k(void *pv) +static int xcmd_ctr_k(int argc, char* argv[]) { /* 删除光标右边的所有字符 */ - uint16_t pos = xcmd_display_cursor_get(); - xcmd_display_cursor_set(-1); + xcmder_t *xcmder = XCMD_CURRENT(); + int pos = xnr_line_cursor(&xcmder->line); + xnr_line_cursor_set(&xcmder->line, XCMD_LINE_MAX_LENGTH); while(1) { - if(xcmd_display_cursor_get() == pos) + if(xnr_line_cursor(&xcmder->line) == pos) { break; } - xcmd_display_delete_char(); + xnr_line_delete(&xcmder->line); } return 0; } -static int xcmd_ctr_l(void *pv) +static int xcmd_ctr_l(int argc, char* argv[]) { - xcmd_exec("clear"); + xcmder_t *xcmder = XCMD_CURRENT(); + xcmd_exec(xcmder, "clear"); return 0; } -static int xcmd_ctr_left(void *pv) +static int xcmd_ctr_left(int argc, char* argv[]) { - char *line = xcmd_display_get(); - uint16_t pos = xcmd_display_cursor_get(); + xcmder_t *xcmder = XCMD_CURRENT(); + char *line = xnr_line_line(&xcmder->line); + uint16_t pos = xnr_line_cursor(&xcmder->line); while(pos) { pos--; @@ -74,15 +80,16 @@ static int xcmd_ctr_left(void *pv) } pos--; } - xcmd_display_cursor_set(pos); + xnr_line_cursor_set(&xcmder->line, pos); return 0; } -static int xcmd_ctr_right(void *pv) +static int xcmd_ctr_right(int argc, char* argv[]) { - char *line = xcmd_display_get(); - uint16_t pos = xcmd_display_cursor_get(); + xcmder_t *xcmder = XCMD_CURRENT(); + char *line = xnr_line_line(&xcmder->line); + uint16_t pos = xnr_line_cursor(&xcmder->line); while(line[pos++]) { if(IS_ALPHA(line[pos]) || IS_NUMBER(line[pos])) @@ -98,7 +105,7 @@ static int xcmd_ctr_right(void *pv) break; } } - xcmd_display_cursor_set(pos); + xnr_line_cursor_set(&xcmder->line, pos); return 0; } diff --git a/extensions/ex_list/ex_list.c b/extensions/ex_list/ex_list.c index c098dbe..75da31e 100644 --- a/extensions/ex_list/ex_list.c +++ b/extensions/ex_list/ex_list.c @@ -12,6 +12,7 @@ struct student static int list_test(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); struct student *p; struct student stu1; struct student stu2; @@ -55,6 +56,7 @@ static int list_test(int argc, char* argv[]) static int list_note_del(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); struct student *p; struct student stu1; struct student stu2; @@ -99,6 +101,7 @@ static int list_note_del(int argc, char* argv[]) static int list_note_rep(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); struct student *p; struct student stu1; struct student stu2; @@ -142,6 +145,7 @@ static int list_note_rep(int argc, char* argv[]) static int list_note_del_insert(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); struct student *p; struct student stu1; struct student stu2; @@ -183,6 +187,7 @@ static int list_note_del_insert(int argc, char* argv[]) static int List_to_merge(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); struct student *p; struct student *q; struct student stu1; @@ -235,6 +240,7 @@ static int List_to_merge(int argc, char* argv[]) static int List_traverse(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); struct student *p; struct student stu1; struct student stu2; diff --git a/extensions/fs_cmds/fs_cmds.c b/extensions/fs_cmds/fs_cmds.c index d8745f5..f32766a 100644 --- a/extensions/fs_cmds/fs_cmds.c +++ b/extensions/fs_cmds/fs_cmds.c @@ -69,7 +69,7 @@ static FRESULT scan_files( break; /* Break on error or end of dir */ if (fno.fattrib & AM_DIR) { /* It is a directory */ - xcmd_print("\x1B[34m" + xcmd_print(xcmder, "\x1B[34m" "%s" "\x1B[0m" " ", @@ -77,7 +77,7 @@ static FRESULT scan_files( } else { /* It is a file. */ - xcmd_print("%s ", fno.fname); + xcmd_print(xcmder, "%s ", fno.fname); } } f_closedir(&dir); @@ -85,7 +85,7 @@ static FRESULT scan_files( } else { - xcmd_print("%s ", fno.fname); + xcmd_print(xcmder, "%s ", fno.fname); } return res; } @@ -163,6 +163,7 @@ static FRESULT df(char* path, DWORD* totle_byte, DWORD* free_byte) static int cmd_df(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); FRESULT res; DWORD fre_bytes, tot_bytes; char * disk_path; @@ -174,11 +175,11 @@ static int cmd_df(int argc, char* argv[]) res = df(disk_path, &tot_bytes, &fre_bytes); if (res != FR_OK) { - xcmd_print("%s Failure:%s\r\n", disk_path, RESAULT_TO_STR(res)); + xcmd_print(xcmder, "%s Failure:%s\r\n", disk_path, RESAULT_TO_STR(res)); } else { - xcmd_print("%s %lu/%lu KiB.\r\n", disk_path, fre_bytes/1024, tot_bytes / 1024); + xcmd_print(xcmder, "%s %lu/%lu KiB.\r\n", disk_path, fre_bytes/1024, tot_bytes / 1024); } } } @@ -207,7 +208,7 @@ static int cmd_cd(int argc, char *argv[]) res = f_chdir(argv[1]); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); } else { @@ -218,7 +219,7 @@ static int cmd_cd(int argc, char *argv[]) } else { - xcmd_print("%s\r\n", HELP_CD); + xcmd_print(xcmder, "%s\r\n", HELP_CD); return -1; } return 0; @@ -243,7 +244,7 @@ static int cmd_rm(int argc, char *argv[]) res = rm_dir(argv[2]); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return -1; } } @@ -252,19 +253,19 @@ static int cmd_rm(int argc, char *argv[]) res = f_stat(argv[1], &fno); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return -1; } if (fno.fattrib & AM_DIR) { - xcmd_print("Failure:%s\r\n", "PATH is DIR"); + xcmd_print(xcmder, "Failure:%s\r\n", "PATH is DIR"); } else { res = f_unlink(argv[1]); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return -1; } } @@ -272,7 +273,7 @@ static int cmd_rm(int argc, char *argv[]) } else { - xcmd_print("%s\r\n", HELP_RM); + xcmd_print(xcmder, "%s\r\n", HELP_RM); return -1; } return 0; @@ -286,13 +287,13 @@ static int cmd_mv(int argc, char *argv[]) res = f_rename(argv[1], argv[2]); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return -1; } } else { - xcmd_print("%s\r\n", HELP_MV); + xcmd_print(xcmder, "%s\r\n", HELP_MV); return -1; } return 0; @@ -312,13 +313,13 @@ static int cmd_mkdir(int argc, char *argv[]) res = f_mkdir(argv[1]); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return 0; } } else { - xcmd_print("%s\r\n", HELP_MKDIR); + xcmd_print(xcmder, "%s\r\n", HELP_MKDIR); return -1; } return 0; @@ -332,14 +333,14 @@ static int cmd_touch(int argc, char *argv[]) res = f_open(&fp, argv[1], FA_CREATE_NEW); if ((res != FR_OK) && (res != FR_EXIST)) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return -1; } f_close(&fp); } else { - xcmd_print("%s\r\n", HELP_TOUCH); + xcmd_print(xcmder, "%s\r\n", HELP_TOUCH); return -1; } return 0; @@ -353,7 +354,7 @@ static int cmd_cat(int argc, char *argv[]) res = f_open(&fp, argv[1], FA_READ); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); return -1; } else @@ -365,7 +366,7 @@ static int cmd_cat(int argc, char *argv[]) res = f_read(&fp, buf, 128, &br); if (res != FR_OK) { - xcmd_print("Failure:%s\r\n", RESAULT_TO_STR(res)); + xcmd_print(xcmder, "Failure:%s\r\n", RESAULT_TO_STR(res)); f_close(&fp); return -1; } @@ -375,14 +376,14 @@ static int cmd_cat(int argc, char *argv[]) } for(UINT i=0; i -#include -#include -#include #include -#include -#include -#include "xcmd_define.h" +#include +#include +#include "xnr_line.h" +#include "xnr_history.h" +#include "xnr_io.h" +#include "xnr_key.h" +#include "xnr_var.h" #include "xcmd_default_confg.h" -#ifdef __cplusplus -extern "C" { -#endif - -typedef int(*cmd_func_t)(int, char**); -typedef int(*cmd_key_func_t)(void *); - -typedef struct __cmd +typedef int (*cmd_func_t)(int, char **); +typedef struct cmd { - const char* name; + const char *name; cmd_func_t func; - const char* help; + const char *help; #ifndef ENABLE_XCMD_EXPORT - struct __cmd *next; + struct cmd *next; #endif -}xcmd_t; +} xcmd_t; +typedef xcmd_t xcmd_key_t; -typedef struct __key -{ - const char* key; - cmd_key_func_t func; - const char* help; -#ifndef ENABLE_XCMD_EXPORT - struct __key *next; -#endif -}xcmd_key_t; - - -/** - * @description: 解释器初始化 - * @param {func*} get_c:获取一个字符的函数 - * @param {func*} put_c:发送一个字符的函数 - * @return {*} - */ -void xcmd_init( int (*get_c)(uint8_t*), int (*put_c)(uint8_t)); - -/** - * @description: 解释器的主任务 - * @param {*} - * @return {*} - */ -void xcmd_task(void); - -/** - * @description: 注册一组指令 - * @param {xcmd_t*} cmds:指令集 - * @param {uint16_t} number:指令个数 - * @return {int} 已经注册的指令的个数 - */ -int xcmd_cmd_register(xcmd_t* cmds, uint16_t number); - -/** - * @description: 注册一组按键 - * @param {xcmd_key_t*} keys:快捷键集 - * @param {uint16_t} number:快捷键的个数 - * @return {int}:已经注册的快捷键的个数 - */ -int xcmd_key_register(xcmd_key_t* keys, uint16_t number); - -/** - * @description: 删除已经注册的cmd - * @param {char*} cmd:cmd集 - * @return {int}:0:success; !0:failed - */ -int xcmd_unregister_cmd(char *cmd); - -/** - * @description:删除已经注册的key - * @param {char*} key:key集 - * @return {int}:0:success; !0:failed - */ -int xcmd_unregister_key(char *key); +#define XCMD_CURRENT() (xcmder_t *)(argv[argc]) #ifndef XCMD_SECTION - #if defined(__CC_ARM) || defined(__CLANG_ARM) - #define XCMD_SECTION(x) __attribute__((section(x))) - #elif defined (__IAR_SYSTEMS_ICC__) - #define XCMD_SECTION(x) @ x - #elif defined(__GNUC__) - #define XCMD_SECTION(x) __attribute__((section(x))) - #else - #define XCMD_SECTION(x) - #endif +#if defined(__CC_ARM) || defined(__CLANG_ARM) +#define XCMD_SECTION(x) __attribute__((section(x))) +#elif defined(__IAR_SYSTEMS_ICC__) +#define XCMD_SECTION(x) @x +#elif defined(__GNUC__) +#define XCMD_SECTION(x) __attribute__((section(x))) +#else +#define XCMD_SECTION(x) +#endif #endif #ifndef XCMD_USED - #if defined(__CC_ARM) || defined(__CLANG_ARM) - #define XCMD_USED __attribute__((used)) - #elif defined (__IAR_SYSTEMS_ICC__) - #define XCMD_USED __root - #elif defined(__GNUC__) - #define XCMD_USED __attribute__((used)) - #else - #define XCMD_USED - #endif +#if defined(__CC_ARM) || defined(__CLANG_ARM) +#define XCMD_USED __attribute__((used)) +#elif defined(__IAR_SYSTEMS_ICC__) +#define XCMD_USED __root +#elif defined(__GNUC__) +#define XCMD_USED __attribute__((used)) +#else +#define XCMD_USED +#endif #endif #ifdef ENABLE_XCMD_EXPORT -#define XCMD_EXPORT_CMD(_name, _func, _help) XCMD_USED const xcmd_t XCMD_SECTION("_xcmd_cmd_list") \ - xcmd_cmd_##_name={\ - .name=#_name, \ - .func=_func, \ - .help=_help\ - }; -#define XCMD_EXPORT_KEY(_key, _func, _help) XCMD_USED const xcmd_key_t XCMD_SECTION("_xcmd_key_list") \ - xcmd_key_##_key={\ - .key=_key, \ - .func=_func, \ - .help=_help\ - }; -extern xcmd_t _xcmd_cmd_list_start; -extern xcmd_t _xcmd_cmd_list_end; -extern xcmd_key_t _xcmd_key_list_start; -extern xcmd_key_t _xcmd_key_list_end; -#define XCMD_CMD_FOR_EACH(pos) for ((pos) = &_xcmd_cmd_list_start; (pos)<&_xcmd_cmd_list_end; ++(pos)) -#define XCMD_KEY_FOR_EACH(pos) for ((pos) = &_xcmd_key_list_start; (pos)<&_xcmd_key_list_end; ++(pos)) +#define XCMD_EXPORT_CMD(_name, _func, _help) XCMD_USED const xcmd_t XCMD_SECTION("_xcmd_cmd_list") \ + xcmd_cmd_##_name = { \ + .name = #_name, \ + .func = _func, \ + .help = _help}; +#define XCMD_EXPORT_KEY(_key, _func, _help) XCMD_USED const xcmd_key_t XCMD_SECTION("_xcmd_key_list") \ + xcmd_key_##_key = { \ + .key = _key, \ + .func = _func, \ + .help = _help}; +extern xcmd_t _xcmd_cmd_list_start; +extern xcmd_t _xcmd_cmd_list_end; +extern xcmd_key_t _xcmd_key_list_start; +extern xcmd_key_t _xcmd_key_list_end; +#define XCMD_CMD_FOR_EACH(pos) for ((pos) = &_xcmd_cmd_list_start; (pos) < &_xcmd_cmd_list_end; ++(pos)) +#define XCMD_KEY_FOR_EACH(pos) for ((pos) = &_xcmd_key_list_start; (pos) < &_xcmd_key_list_end; ++(pos)) #else /** * @description: 获取命令列表,可以通过next指针可以遍历所有指令 - * @param {*} - * @param {} + * @param {*} + * @param {} * @return {xcmd_t *}:指令链表表头 */ xcmd_t *xcmd_cmdlist_get(void); /** * @description: 获取按键列表,可以通过next指针可以遍历所有按键 - * @param {*} - * @param {} + * @param {*} + * @param {} * @return {xcmd_key_t *}:快捷键链表表头 */ xcmd_key_t *xcmd_keylist_get(void); #define XCMD_EXPORT_CMD(name, func, help) #define XCMD_EXPORT_KEY(key, func, help) -#define XCMD_CMD_FOR_EACH(pos) for ((pos) = xcmd_cmdlist_get(); (pos); (pos) = (pos)->next) -#define XCMD_KEY_FOR_EACH(pos) for ((pos) = xcmd_keylist_get(); (pos); (pos) = (pos)->next) +#define XCMD_CMD_FOR_EACH(pos) for ((pos) = xcmd_cmdlist_get(); (pos); (pos) = (pos)->next) +#define XCMD_KEY_FOR_EACH(pos) for ((pos) = xcmd_keylist_get(); (pos); (pos) = (pos)->next) #endif -/** - * @description: 手动执行命令 - * @param {char* } str:命令 - * @return {uint8_t} 返回执行结果 - */ -int xcmd_exec(char *str); +typedef struct xcmd +{ + xnr_io_t io; + xnr_key_t key; + xnr_var_tab_t var_tab; + xnr_history_t history; + xnr_line_t line; + cmd_func_t unknow_cmd_cbk; // 输入为命令序列,输出未处理 + cmd_func_t pre_cmd_cbk; // 输入为命令序列,输出重新赋值给argc + cmd_func_t after_cmd_cbk; // 输入为命令序列,输出未处理 + void *user_data; // 用户数据 + int optind; // 选项在参数列表中的位置 + char *optarg; // 选项参数的值 + bool _initOK; +} xcmder_t; -/** - * @description: 打印字符串 - */ -void xcmd_print(const char *fmt, ...); -void xcmd_put_str(const char *str); +void xcmd_init(xcmder_t *xcmder, _io_write_t write, _io_read_t read); +void xcmd_task(xcmder_t *xcmder); +int xcmd_exec(xcmder_t *xcmder, char *str); +int xcmd_getopt(xcmder_t *xcmder, int argc, char * const argv[], const char *optstring); +void xcmd_reg_unknow_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk); +void xcmd_reg_pre_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk); +void xcmd_reg_after_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk); -/** - * @description: 向显示器插入一个字符 - * @param {char} c - * @return 无 - */ -void xcmd_display_insert_char(char c); +int xcmd_print(xcmder_t *xcmder, const char *fmt, ...); +int xcmd_puts(xcmder_t *xcmder, const char *str); +int xcmd_putc(xcmder_t *xcmder, char c); +int xcmd_getc(xcmder_t *xcmder); -/** - * @description: 删除显示器的一个字符 - * @param {*} - * @return 无 - */ -void xcmd_display_delete_char(void); +int xcmd_key_register(xcmd_key_t *keys, uint16_t number); +int xcmd_unregister_key(char *key); +int xcmd_cmd_register(xcmd_t *cmds, uint16_t number); +int xcmd_unregister_cmd(char *cmd); -/** - * @description: 返回光标当前的字符 - * @param {char*}cha存储返回的字符 - * @return {uint8_t}0光标位置无字符,1有字符 - */ -uint8_t xcmd_display_current_char(char *cha); - -/** - * @description: 清除显示器 - * @param {*} - * @return 无 - */ -void xcmd_display_clear(void); - -/** - * @description: 获取显示器的内容 - * @param {*} - * @return {char*} *显示器的内容的指针 - */ -char* xcmd_display_get(void); - -/** - * @description: 设置显示器的内容 - * @param {char*} 要现实的内容 - * @return 无 - */ -void xcmd_display_print(const char *fmt, ...); -void xcmd_display_write(const char* buf, uint16_t len); - -/** - * @description: 光标操作函数 - * @param {*} - * @return {*} - */ -void xcmd_display_cursor_set(uint16_t pos); -uint16_t xcmd_display_cursor_get(void); - -/** - * @description: 设置命令行提示字符串,此函数并不拷贝字符串,只是记住了传入的指针 - * @param {char*} prompt - * @return {*} - */ -void xcmd_set_prompt(const char* prompt); -const char* xcmd_get_prompt(void); - -/** - * @description: 注册解释器接收函数的钩子函数 - * @param {func_p} 钩子函数,返回0则接收到的数据会返回给解释器,返回1则不会 - * @return {*} 无 - */ -void xcmd_register_rcv_hook_func(uint8_t(*func_p)(char*)); - -/** - * @description: 获取历史记录的个数 - * @param {*} - * @return {uint16_t} 已经记录的历史个数 - */ -uint16_t xcmd_history_len(void); - -/** - * @description: 插入一条历史记录 - * @param {char*} str - * @return 无 - */ -void xcmd_history_insert(char* str); - -/** - * @description: 获取下一条历史记录 - * @param {*} - * @return 历史命令 - */ -char *xcmd_history_next(void); - -/** - * @description: 获取上条历史记录 - * @param {*} - * @return 历史命令 - */ -char *xcmd_history_prev(void); - -/** - * @description: 获取当前历史记录 - * @param {*} - * @return 历史命令 - */ -char *xcmd_history_current(void); - -/** - * @description: 将历史记录指针指向头部 - * @param {*} - * @return 无 - */ -void xcmd_history_slider_reset(void); - -/** - * @description: 结束输入 - * @param {*} - * @return {*} - */ -char* xcmd_end_of_input(void); - - - - - -#ifdef __cplusplus - } -#endif - -#endif /*XCMD_H*/ +#endif \ No newline at end of file diff --git a/inc/xcmd_default_confg.h b/inc/xcmd_default_confg.h index b93535a..02988cc 100755 --- a/inc/xcmd_default_confg.h +++ b/inc/xcmd_default_confg.h @@ -46,6 +46,10 @@ extern "C" { #define XCMD_DEFAULT_PROMPT_CLOLR TX_GREEN /*提示符颜色*/ #endif +#ifndef XCMD_VAR_BUF_SZIE +#define XCMD_VAR_BUF_SZIE (32) +#endif + #ifndef ENABLE_XCMD_EXPORT //#define ENABLE_XCMD_EXPORT /*使能XCMD_EXPORT_CMD和XCMD_EXPORT_KEY*/ #endif diff --git a/inc/xcmd_define.h b/inc/xcmd_define.h deleted file mode 100644 index 966f2c2..0000000 --- a/inc/xcmd_define.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * @Author: your name - * @Date: 2021-09-20 19:59:05 - * @LastEditTime: 2022-02-17 22:41:13 - * @LastEditors: Please set LastEditors - * @Description: In User Settings Edit - * @FilePath: /xcmd/inc/xcmd_define.h - */ - -#ifndef XCMD_DEFINE_H -#define XCMD_DEFINE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define KEY_CTR_A "\x01" -#define KEY_CTR_B "\x02" -#define KEY_CTR_C "\x03" -#define KEY_CTR_D "\x04" -#define KEY_CTR_E "\x05" -#define KEY_CTR_F "\x06" -#define KEY_CTR_G "\x07" -#define KEY_CTR_H "\x08" -#define KEY_CTR_I "\x09" -#define KEY_TAB "\x09" -#define KEY_CTR_J "\x0A" -#define KEY_CTR_K "\x0B" -#define KEY_CTR_L "\x0C" -#define KEY_CTR_M "\x0D" -#define KEY_CTR_N "\x0E" -#define KEY_CTR_O "\x0F" -#define KEY_CTR_P "\x10" -#define KEY_CTR_Q "\x11" -#define KEY_CTR_R "\x12" -#define KEY_CTR_S "\x13" -#define KEY_CTR_T "\x14" -#define KEY_CTR_U "\x15" -#define KEY_CTR_V "\x16" -#define KEY_CTR_W "\x17" -#define KEY_CTR_X "\x18" -#define KEY_CTR_Y "\x19" -#define KEY_CTR_Z "\x1A" -#define KEY_PAUSE "\x1A" -#define KEY_ESC "\x1B" -#define KEY_BACKSPACE "\x7F" -#define KEY_UP "\x1B[A" -#define KEY_DW "\x1B[B" -#define KEY_RIGHT "\x1B[C" -#define KEY_LEFT "\x1B[D" -#define KEY_HOME "\x1B[H" -#define KEY_EMD "\x1B[F" -#define KEY_CTR_UP "\x1B[1;5A" -#define KEY_CTR_DW "\x1B[1;5B" -#define KEY_CTR_RIGHT "\x1B[1;5C" -#define KEY_CTR_LEFT "\x1B[1;5D" -#define KEY_INSERT "\x1B[2~" -#define KEY_DELETE "\x1B[3~" -#define KEY_PAGE_UP "\x1B[5~" -#define KEY_PAGE_DOWN "\x1B[6~" -#define KEY_F1 "\x1BOP" -#define KEY_F2 "\x1BOQ" -#define KEY_F3 "\x1BOR" -#define KEY_F4 "\x1BOS" -#define KEY_F5 "\x1B[15~" -#define KEY_F6 "\x1B[17~" -#define KEY_F7 "\x1B[18~" -#define KEY_F8 "\x1B[19~" -#define KEY_F9 "\x1B[20~" -#define KEY_F10 "\x1B[21~" -#define KEY_F11 "\x1B[23~" -#define KEY_F12 "\x1B[24~" - -/*光标操作符,其中0x1B是ESC,只适用于xcmd_print函数*/ -#define CUU(n) "\x1B[%dA",n /* 光标向上 光标向上 行 */ -#define CUD(n) "\x1B[%dB",n /* 光标向下 光标向下 行 */ -#define CUF(n) "\x1B[%dC",n /* 光标向前 光标向前(右) 行 */ -#define CUB(n) "\x1B[%dD",n /* 光标向后 光标向后(左) 行 */ -#define CNL(n) "\x1B[%dE",n /* 光标下一行 光标从当前位置向下 行 */ -#define CPL(n) "\x1B[%dF",n /* 光标当前行 光标从当前位置向上 行 */ -#define CHA(n) "\x1B[%dG",n /* 绝对光标水平 光标在当前行中水平移动到第 个位置 */ -#define VPA(n) "\x1B[%dd",n /* 绝对垂直行位置 光标在当前列中垂直移动到第 个位置 */ -#define CUP(y,x) "\x1B[%d;%dH",y,x /* 光标位置 *光标移动到视区中的 ; 坐标,其中 行的列 */ -#define HVP(y,x) "\x1B[%d;%df",y,x /* 水平垂直位置 *光标移动到视区中的 ; 坐标,其中 行的列 */ - -/*光标可见性*/ -#define CU_START_BL "\x1B[?12h" /* ATT160 文本光标启用闪烁 开始光标闪烁 */ -#define CU_STOP_BL "\x1B[?12l" /* ATT160 文本光标禁用闪烁 停止闪烁光标 */ -#define CU_SHOW "\x1B[?25h" /* DECTCEM 文本光标启用模式显示 显示光标 */ -#define CU_HIDE "\x1B[?25l" /* DECTCEM 文本光标启用模式隐藏 隐藏光标 */ - -/* 字符操作 */ -#define ICH(n) "\x1B[%d@",n /* 插入字符 在当前光标位置插入 个空格,这会将所有现有文本移到右侧。 向右溢出屏幕的文本会被删除。*/ -#define DCH(n) "\x1B[%dP",n /* 删除字符 删除当前光标位置的 个字符,这会从屏幕右边缘以空格字符移动。*/ -#define ECH(n) "\x1B[%dX",n /* 擦除字符 擦除当前光标位置的 个字符,方法是使用空格字符覆盖它们。*/ -#define IL(n) "\x1B[%dL",n /* 插入行 将 行插入光标位置的缓冲区。 光标所在的行及其下方的行将向下移动。*/ -#define DL(n) "\x1B[%dM\r",n /* 删除行 从缓冲区中删除 行,从光标所在的行开始。*/ - -/* 打印字体颜色设置 */ -#define TX_DEF "\x1b[0m" -#define TX_BLACK "\x1b[30m" -#define TX_RED "\x1b[31m" -#define TX_GREEN "\x1b[32m" -#define TX_YELLOW "\x1b[33m" -#define TX_BLUE "\x1b[34m" -#define TX_WHITE "\x1b[37m" - -/* 打印背景颜色设置 */ -#define BK_DEF "\x1b[0m" -#define BK_BLACK "\x1b[40m" -#define BK_RED "\x1b[41m" -#define BK_GREEN "\x1b[42m" -#define BK_YELLOW "\x1b[43m" -#define BK_BLUE "\x1b[44m" -#define BK_WHITE "\x1b[47m" - -#ifdef __cplusplus - } -#endif -#endif /*XCMD_DEFINE_H*/ diff --git a/src/xcmd.c b/src/xcmd.c old mode 100755 new mode 100644 index 65b9edc..1b155a9 --- a/src/xcmd.c +++ b/src/xcmd.c @@ -1,614 +1,33 @@ +#include +#include +#include +#include #include "xcmd.h" #include "xcmd_default_cmds.h" #include "xcmd_default_keys.h" -#include -#include -#include -#define CMD_IS_END_KEY(c) ( ((c >= 'A') && (c <= 'D')) || ((c >= 'P') && (c <= 'S')) || \ - (c == '~') || (c == 'H') || (c == 'F')) +static xnr_var_t g_var_buf[XCMD_VAR_BUF_SZIE]; -#define CMD_IS_PRINT(c) ((c >= 32) && (c <= 126)) - -typedef struct __history +static struct { - char line[XCMD_LINE_MAX_LENGTH]; - struct __history *next; - struct __history *prev; -}xcmd_history_t; + xcmd_t head; +} g_cmd_list; -struct +static struct { - struct - { - ssize_t write_fd; - ssize_t read_fd; - int (*get_c)(uint8_t*); - int (*put_c)(uint8_t); - }io; - - struct - { - xcmd_t head; - }cmd_list; - - struct - { - xcmd_key_t head; - }key_list; - - struct - { - #if XCMD_HISTORY_MAX_NUM - struct xcmd - { - xcmd_history_t pool[XCMD_HISTORY_MAX_NUM]; - uint16_t index; - }history_pool; - struct - { - uint16_t len; - xcmd_history_t *head; - xcmd_history_t *slider; - }history_list; - #endif - - char display_line[XCMD_LINE_MAX_LENGTH+1]; /* 显示区的缓存 */ - const char *prompt; /* 显示区的提示 */ - uint16_t byte_num; /* 当前行的字符个数 */ - uint16_t cursor; /* 光标所在位置 */ - uint8_t encode_case_stu; - char encode_buf[7]; - uint8_t encode_count; - uint32_t key_val; - uint16_t param_len; - uint8_t (*recv_hook_func)(char*); /* 解释器接收钩子函数,返回0则接收到的数据会返回给解释器,返回1则不会 */ - }parser; - uint8_t _initOK; -} g_xcmder = {0}; - -ssize_t file_open(char *name, int is_write, int is_append) __attribute__((weak)); -void file_close(ssize_t fd) __attribute__((weak)); -int file_write(ssize_t fd, const char *str) __attribute__((weak)); -int file_read(ssize_t fd, char *buf, int buflen) __attribute__((weak)); - -void file_close(ssize_t fd) -{ -} - -ssize_t file_open(char *name, int is_write, int is_append) -{ - return -1; -} - -int file_write(ssize_t fd, const char *str) -{ - return -1; -} - - -int file_read(ssize_t fd, char *buf, int buflen) -{ - return -1; -} - -static char *xcmd_strpbrk(char*s, const char *delim) //返回s1中第一个满足条件的字符的指针, 并且保留""号内的源格式 -{ - uint8_t flag = 0; - for(uint16_t i=0; s[i]; i++) - { - for(uint16_t j=0; delim[j]; j++) - { - if(0 == flag) - { - if(s[i] == '\"') - { - for(uint16_t k=i; s[k]; k++) - { - s[k] = s[k+1]; - } - flag = 1; - continue; - } - } - - if(flag) - { - if(s[i] == '\"') - { - for(uint16_t k=i; s[k]; k++) - { - s[k] = s[k+1]; - } - flag = 0; - } - else - { - continue; - } - } - - if(s[i] == delim[j]) - { - return &s[i]; - } - } - } - return NULL; -} - -/* 字符串切割函数,使用: - char s[] = "-abc-=-def"; - char *sp; - x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = strtok_r(NULL, "=", &sp); // x = NULL - // s = "abc/0-def/0" -*/ -static char *xcmd_strtok(char *s, const char *delim, char **save_ptr) -{ - char *token; - - if (s == NULL) s = *save_ptr; - - /* Scan leading delimiters. */ - s += strspn(s, delim); // 返回字符串中第一个不在指定字符串中出现的字符下标,去掉了以空字符开头的 - // 字串的情况 - if (*s == '\0') - return NULL; - - /* Find the end of the token. */ - token = s; - s = xcmd_strpbrk(token, delim); // 返回s1中第一个满足条件的字符的指针 - if (s == NULL) - /* This token finishes the string. */ - *save_ptr = strchr(token, '\0'); - else { - /* Terminate the token and make *SAVE_PTR point past it. */ - *s = '\0'; - *save_ptr = s + 1; - } - return token; -} - -static int xcmd_get_param(char* msg, char*delim, char* get[], int max_num) -{ - int i,ret; - char *ptr = NULL; - char *sp = NULL; - ptr = xcmd_strtok(msg, delim, &sp); - for(i=0; ptr!=NULL &&i') - { - argc = i; - if(argv[i][1] == '>') - { - g_xcmder.io.write_fd = file_open(argv[i+1], 1, 1); - } - else - { - g_xcmder.io.write_fd = file_open(argv[i+1], 1, 0); - } - break; - } - } - return argc; -} - -static int xcmd_cmd_match(int argc, char*argv[]) -{ - uint8_t flag = 0; - int ret = -1; - xcmd_t *p = NULL; - XCMD_CMD_FOR_EACH(p) - { - if(strcmp(p->name, argv[0]) == 0) - { - flag = 1; - if(argc>1) - { - if((strcmp(argv[1],"?") == 0) || - (strcmp(argv[1],"-h") == 0)) - { - xcmd_print("%s\r\n", p->help); - break; - } - } - argc = xcmd_redirected(argc, argv); - ret = p->func(argc, argv); - file_close(g_xcmder.io.write_fd); - g_xcmder.io.write_fd = -1; - break; - } - } - if(flag) - { - xcmd_print("\r\n"); - } - else - { - xcmd_print("cmd \"%s\" does not exist\r\n", argv[0]); - } - return ret; -} - -static void xcmd_key_match(char* key) -{ - xcmd_key_t *p = NULL; - XCMD_KEY_FOR_EACH(p) - { - if(strcmp(key, p->key) == 0) - { - if(p->func(&g_xcmder) == 0) - { - break; - } - } - } -} - -static void xcmd_key_exec(char* key) -{ - xcmd_key_match(key); -} - -static uint8_t xcmd_rcv_encode(uint8_t byte) -{ - uint8_t ret = 0; - - switch (g_xcmder.parser.encode_case_stu) - { - case 0: - g_xcmder.parser.encode_count = 0; - if (byte == 0x1B) //ESC - { - g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; - g_xcmder.parser.encode_case_stu = 1; - g_xcmder.parser.key_val = byte; - } - else - { - g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; - g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count] = '\0'; - g_xcmder.parser.encode_count = 0; - ret = 1; - } - break; - case 1: - if (CMD_IS_END_KEY(byte)) - { - g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; - g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count] = '\0'; - ret = g_xcmder.parser.encode_count; - g_xcmder.parser.encode_case_stu = 0; - } - else - { - g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; - if (g_xcmder.parser.encode_count >= 6) - { - g_xcmder.parser.encode_case_stu = 0; - ret = 0; - } - } - break; - default: - break; - } - return ret; -} - -char* xcmd_end_of_input(void) -{ - char* ret = g_xcmder.parser.display_line; - if(g_xcmder.parser.byte_num) - { -#if XCMD_HISTORY_MAX_NUM - if(g_xcmder.parser.history_list.head == NULL) - { - xcmd_history_insert(ret); - } - else - { - char *head_line = g_xcmder.parser.history_list.head->line; - if(strcmp(head_line, ret) != 0) - { - xcmd_history_insert(ret); - } - } -#endif - g_xcmder.parser.byte_num = 0; - g_xcmder.parser.cursor = 0; - xcmd_history_slider_reset(); - } - return ret; -} - -static void xcmd_parser(uint8_t byte) -{ - uint32_t num = 0; - - num = xcmd_rcv_encode(byte); - - if(num > 0) - { - if( !(g_xcmder.parser.recv_hook_func && !g_xcmder.parser.recv_hook_func(g_xcmder.parser.encode_buf)) ) - { - if(CMD_IS_PRINT(g_xcmder.parser.encode_buf[0])) - { - xcmd_display_insert_char(g_xcmder.parser.encode_buf[0]); - return; - } - else - { - xcmd_key_exec(g_xcmder.parser.encode_buf); - } - } - } -} - -void xcmd_put_str(const char *str) -{ - if(g_xcmder.io.write_fd != -1) - { - if(file_write(g_xcmder.io.write_fd, str) != -1) - { - return; - } - } - for(uint16_t i=0; str[i]; i++) - { - g_xcmder.io.put_c(str[i]); - }; -} - -void xcmd_print(const char *fmt, ...) -{ - char ucstring[XCMD_PRINT_BUF_MAX_LENGTH] = {0}; - va_list arg; - va_start(arg, fmt); - vsnprintf(ucstring, XCMD_PRINT_BUF_MAX_LENGTH, fmt, arg); - va_end(arg); - xcmd_put_str(ucstring); -} - -void xcmd_display_write(const char* buf, uint16_t len) -{ - if(len > XCMD_LINE_MAX_LENGTH) - { - len = XCMD_LINE_MAX_LENGTH; - } - for(uint16_t i=0; ig_xcmder.parser.cursor; i--) - { - line[i] = line[i-1]; - } - g_xcmder.parser.byte_num++; - line[g_xcmder.parser.byte_num] = '\0'; - line[g_xcmder.parser.cursor++] = c; - xcmd_print(ICH(1)); - xcmd_print("%c", c); - } -} - -void xcmd_display_delete_char(void) -{ - char *line = xcmd_display_get(); - if(g_xcmder.parser.cursor > 0) - { - for(uint16_t i = g_xcmder.parser.cursor-1; i g_xcmder.parser.byte_num) - { - pos = g_xcmder.parser.byte_num; - } - g_xcmder.parser.cursor = pos; - xcmd_print(CHA(g_xcmder.parser.cursor+strlen(g_xcmder.parser.prompt)+1)); -} - -uint16_t xcmd_display_cursor_get(void) -{ - return g_xcmder.parser.cursor; -} - -void xcmd_history_insert(char* str) -{ -#if XCMD_HISTORY_MAX_NUM - if(g_xcmder.parser.history_list.len < XCMD_HISTORY_MAX_NUM) - { - xcmd_history_t *new_p = &(g_xcmder.parser.history_pool.pool[g_xcmder.parser.history_pool.index++]); - if(g_xcmder.parser.history_list.len == 0) /* 头插 */ - { - strncpy(new_p->line, str, XCMD_LINE_MAX_LENGTH); - g_xcmder.parser.history_list.head = new_p; - g_xcmder.parser.history_list.head->next = new_p; - g_xcmder.parser.history_list.head->prev = new_p; - g_xcmder.parser.history_list.slider = new_p; - g_xcmder.parser.history_list.len++; - } - else - { - strncpy(new_p->line, str, XCMD_LINE_MAX_LENGTH); - xcmd_history_t *old_head = g_xcmder.parser.history_list.head; - g_xcmder.parser.history_list.head = new_p; - new_p->next = old_head; - new_p->prev = old_head->prev; - old_head->prev->next = new_p; - old_head->prev = new_p; - g_xcmder.parser.history_list.len++; - } - } - else - { - g_xcmder.parser.history_list.head = g_xcmder.parser.history_list.head->prev; - strncpy(g_xcmder.parser.history_list.head->line, str, XCMD_LINE_MAX_LENGTH); - } -#endif -} - -char *xcmd_history_next(void) -{ - char *line = NULL; -#if XCMD_HISTORY_MAX_NUM - if(g_xcmder.parser.history_list.len) - { - line = g_xcmder.parser.history_list.slider->line;; - if(g_xcmder.parser.history_list.slider->next != g_xcmder.parser.history_list.head) - { - g_xcmder.parser.history_list.slider = g_xcmder.parser.history_list.slider->next; - } - } -#endif - return line; -} - -char *xcmd_history_prev(void) -{ - char *line = NULL; -#if XCMD_HISTORY_MAX_NUM - if(g_xcmder.parser.history_list.len) - { - if(g_xcmder.parser.history_list.slider != g_xcmder.parser.history_list.head) - { - g_xcmder.parser.history_list.slider = g_xcmder.parser.history_list.slider->prev; - line = g_xcmder.parser.history_list.slider->line; - } - } -#endif - return line; -} - -char *xcmd_history_current(void) -{ - char *line = NULL; -#if XCMD_HISTORY_MAX_NUM - if(g_xcmder.parser.history_list.len) - { - if(g_xcmder.parser.history_list.slider) - { - line = g_xcmder.parser.history_list.slider->line; - } - } -#endif - return line; -} - -uint16_t xcmd_history_len(void) -{ -#if XCMD_HISTORY_MAX_NUM - return g_xcmder.parser.history_list.len; -#else - return 0; -#endif -} - -void xcmd_history_slider_reset(void) -{ -#if XCMD_HISTORY_MAX_NUM - g_xcmder.parser.history_list.slider = g_xcmder.parser.history_list.head; -#endif -} - -int xcmd_exec(char* str) -{ - int param_num = 0; - char *cmd_param_buff[XCMD_PARAM_MAX_NUM]; - char temp[XCMD_LINE_MAX_LENGTH]; - strncpy(temp, str, XCMD_LINE_MAX_LENGTH); - param_num = xcmd_get_param(temp, " ", cmd_param_buff, XCMD_PARAM_MAX_NUM); - if(param_num >0) - { - return xcmd_cmd_match(param_num, cmd_param_buff); - } - return -1; -} + xcmd_key_t head; +} g_key_list; int xcmd_key_register(xcmd_key_t *keys, uint16_t number) { #ifndef ENABLE_XCMD_EXPORT - uint16_t i=0; - xcmd_key_t * temp; + uint16_t i = 0; + xcmd_key_t *temp; - while(iname) == 0) + { + bk->next = p->next; + return 0; + } + bk = p; + } +#endif + return -1; +} + +int xcmd_unregister_cmd(char *cmd) +{ +#ifndef ENABLE_XCMD_EXPORT + xcmd_t *bk = &g_cmd_list.head; + xcmd_t *p = NULL; + XCMD_CMD_FOR_EACH(p) + { + if (strcmp(cmd, p->name) == 0) + { + bk->next = p->next; + return 0; + } + bk = p; + } +#endif + return -1; +} + xcmd_key_t *xcmd_keylist_get(void) { #ifndef ENABLE_XCMD_EXPORT - return g_xcmder.key_list.head.next; + return g_key_list.head.next; +#else + return &_xcmd_key_list_start; #endif } xcmd_t *xcmd_cmdlist_get(void) { #ifndef ENABLE_XCMD_EXPORT - return g_xcmder.cmd_list.head.next; + return g_cmd_list.head.next; +#else + return &_xcmd_cmd_list_start; #endif } -int xcmd_unregister_cmd(char *cmd) +static void xcmd_key_match(xcmder_t *xcmder, char *key) { -#ifndef ENABLE_XCMD_EXPORT - xcmd_t *bk = &g_xcmder.cmd_list.head; - xcmd_t *p = NULL; - XCMD_CMD_FOR_EACH(p) - { - if(strcmp(cmd, p->name) == 0) - { - bk->next = p->next; - return 0; - } - bk = p; - } -#endif - return -1; -} - -int xcmd_unregister_key(char *key) -{ -#ifndef ENABLE_XCMD_EXPORT - xcmd_key_t *bk = &g_xcmder.key_list.head; xcmd_key_t *p = NULL; XCMD_KEY_FOR_EACH(p) { - if(strcmp(key, p->key) == 0) + if (strcmp(key, p->name) == 0) { - bk->next = p->next; - return 0; + if (p->func(0, (char **)&xcmder) == 0) + { + break; + } } - bk = p; } -#endif +} + +static int xcmd_cmd_match(xcmder_t *xcmder, int argc, char *argv[]) +{ + uint8_t flag = 0; + int ret = -1; + xcmd_t *p = NULL; + XCMD_CMD_FOR_EACH(p) + { + if (strcmp(p->name, argv[0]) == 0) + { + flag = 1; + if (argc > 1) + { + if ((strcmp(argv[1], "?") == 0) || + (strcmp(argv[1], "-h") == 0)) + { + xcmd_print(xcmder, "%s\r\n", p->help); + break; + } + } + if (xcmder->pre_cmd_cbk) + { + argc = xcmder->pre_cmd_cbk(argc, argv); + argv[argc] = (char *)xcmder; + } + ret = p->func(argc, argv); + if (xcmder->after_cmd_cbk) + argc = xcmder->after_cmd_cbk(argc, argv); + break; + } + } + if (0 == flag) + { + if (NULL == xcmder->unknow_cmd_cbk) + xcmd_print(xcmder, "cmd \"%s\" does not exist\r\n", argv[0]); + else + xcmder->unknow_cmd_cbk(argc, argv); + } + return ret; +} + +int xcmd_print(xcmder_t *xcmder, const char *fmt, ...) +{ + if (NULL == xcmder || NULL == fmt) + return -1; + char ucstring[XCMD_PRINT_BUF_MAX_LENGTH] = {0}; + va_list arg; + va_start(arg, fmt); + int len = vsnprintf(ucstring, XCMD_PRINT_BUF_MAX_LENGTH, fmt, arg); + va_end(arg); + return xcmder->io.write(xcmder->io.out_fd, ucstring, len); +} + +int xcmd_puts(xcmder_t *xcmder, const char *str) +{ + return xnr_io_puts(&xcmder->io, str); +} + +int xcmd_putc(xcmder_t *xcmder, char c) +{ + return xnr_io_putc(&xcmder->io, c); +} + +int xcmd_getc(xcmder_t *xcmder) +{ + return xnr_io_getc(&xcmder->io); +} + +int xcmd_exec(xcmder_t *xcmder, char *str) +{ + int param_num = 0; + char *cmd_param_buff[XCMD_PARAM_MAX_NUM + 1]; + char temp[XCMD_LINE_MAX_LENGTH]; + strncpy(temp, str, XCMD_LINE_MAX_LENGTH); + param_num = xnr_line_tok(temp, " ", cmd_param_buff, XCMD_PARAM_MAX_NUM); + if (param_num > 0) + { + cmd_param_buff[param_num] = (char *)xcmder; + return xcmd_cmd_match(xcmder, param_num, cmd_param_buff); + } return -1; } -void xcmd_set_prompt(const char* prompt) +static void xcmd_key_exec(xcmder_t *xcmder, char *key) { - if(prompt) + xcmd_key_match(xcmder, key); +} + +void xcmd_init(xcmder_t *xcmder, _io_write_t write, _io_read_t read) +{ + if (write && read && xcmder && 0 == xcmder->_initOK) { - g_xcmder.parser.prompt = prompt; + xcmder->unknow_cmd_cbk = NULL; + xcmder->pre_cmd_cbk = NULL; + xcmder->after_cmd_cbk = NULL; + xcmder->user_data = NULL; + xcmder->optarg = 1; + xcmder->optind = NULL; +#ifndef ENABLE_XCMD_EXPORT + g_cmd_list.head.next = NULL; +#endif + xnr_var_init(&xcmder->var_tab, g_var_buf, XCMD_VAR_BUF_SZIE); + xnr_io_init(&xcmder->io, write, read); + xnr_key_init(&xcmder->key); + xnr_line_init(&xcmder->line, &xcmder->io); + xnr_history_init(&xcmder->history, &xcmder->io); + default_cmds_init(); + default_keys_init(); + xcmd_exec(xcmder, "logo"); + xcmd_unregister_cmd("logo"); + xnr_var_set(&xcmder->var_tab, "prompt", ANSI_COLOR_TXT(ANSI_YELLOW, "->")); + char *var_val = xnr_var_value(&xcmder->var_tab, "prompt"); + xnr_line_set_prompt(&xcmder->line, var_val); + xnr_line_clear(&xcmder->line); + xcmder->_initOK = 1; } } -const char* xcmd_get_prompt(void) -{ - return g_xcmder.parser.prompt; -} - -void xcmd_register_rcv_hook_func(uint8_t(*func_p)(char*)) -{ - g_xcmder.parser.recv_hook_func = func_p; -} - -void xcmd_init( int (*get_c)(uint8_t*), int (*put_c)(uint8_t)) -{ - if(get_c && put_c) - { - g_xcmder.io.get_c = get_c; - g_xcmder.io.put_c = put_c; - g_xcmder.io.read_fd = -1; - g_xcmder.io.write_fd = -1; - - g_xcmder.parser.prompt = XCMD_DEFAULT_PROMPT; - g_xcmder.parser.byte_num = 0; - g_xcmder.parser.cursor = 0; - g_xcmder.parser.encode_case_stu = 0; -#ifndef ENABLE_XCMD_EXPORT - g_xcmder.cmd_list.head.next = NULL; -#endif - - if(g_xcmder._initOK == 0) - { - default_cmds_init(); - default_keys_init(); - xcmd_exec("logo"); - xcmd_unregister_cmd("logo"); - } - g_xcmder._initOK = 1; - } -} - -void xcmd_task(void) +void xcmd_task(xcmder_t *xcmder) { uint8_t c; - if(g_xcmder._initOK) - { - if(g_xcmder.io.get_c(&c)) - { - xcmd_parser(c); - } - } + if (xcmder->_initOK) + { + c = xnr_io_getc(&xcmder->io); + if (xnr_key_encode(&xcmder->key, c)) + { + char *key_val = xnr_key_val(&xcmder->key); + if (isprint(key_val[0])) // 可显示字符 + { + xnr_line_insert(&xcmder->line, c); // 向行中插入可显示字符 + } + else // 不可显示字符,即快捷键 + { + xcmd_key_exec(xcmder, key_val); + } + } + } } +void xcmd_reg_unknow_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk) +{ + xcmder->unknow_cmd_cbk = cbk; +} +void xcmd_reg_pre_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk) +{ + xcmder->pre_cmd_cbk = cbk; +} +void xcmd_reg_after_cmd_cbk(xcmder_t *xcmder, cmd_func_t cbk) +{ + xcmder->after_cmd_cbk = cbk; +} +int xcmd_getopt(xcmder_t *xcmder, int argc, char * const argv[], const char *optstring) +{ + static char *nextc = NULL; // 字符串中下一个选项字符位置 + char *c; // 选项字符 + int has_arg; // 选项是否有参数 + int is_long_opt = 0; // 是否是长选项 + int opt_long_index = -1; // 如果是长选项,存储它的下标 + xcmder->optarg = 0; + + if (nextc == NULL || *nextc == '\0') { + if (xcmder->optind >= argc || argv[xcmder->optind][0] != '-' || argv[xcmder->optind][1] == '\0') { + return -1; + } + + nextc = argv[xcmder->optind] + 1; + + if (*nextc == '-') { + is_long_opt = 1; + nextc++; + } + + xcmder->optind++; + } + + if (is_long_opt) { + // 如果是长选项,查找选项字符串和操作数 + char buf[XCMD_PARAM_MAX_NUM + 1]; + char *p = strchr(nextc, '='); + + if (p != NULL) { + // 选项字符串和操作数之间有等号 + int len = p - nextc; + + if (len > XCMD_PARAM_MAX_NUM) { + return '?'; + } + + strncpy(buf, nextc, len); + buf[len] = '\0'; + nextc = p + 1; + xcmder->optarg = nextc; + nextc = NULL; // xcmder->optarg 后面不会再有操作数 + } else { + // 选项字符串后没有等号 + int len = strlen(nextc); + + if (len > XCMD_PARAM_MAX_NUM) { + return '?'; + } + + strncpy(buf, nextc, XCMD_PARAM_MAX_NUM); + nextc = NULL; + } + + // 在 optstring 中查找长选项 + int i; + for (i = 0; optstring[i] != '\0'; i += 2) { + if (optstring[i] == ':' || optstring[i + 1] == ':') { + // 忽略有错误格式的选项(参见实例代码,有两个冒号的应该可以解析出错) + continue; + } + + if (strcmp(buf, optstring + i) == 0) { + opt_long_index = i / 2; + break; + } + } + } else { + c = nextc++; + has_arg = 0; + + if (*nextc == ':') { + has_arg = 1; + nextc++; + } + + if (*c == ':' || strchr(optstring, *c) == NULL) { + return '?'; + } + } + + if (opt_long_index >= 0 || has_arg) { + if (nextc != NULL) { + xcmder->optarg = nextc; + nextc = NULL; + } + else if (xcmder->optind < argc) { + xcmder->optarg = argv[xcmder->optind]; + xcmder->optind++; + } + else { + return ':'; + } + } + + if (opt_long_index >= 0) { + return optstring[opt_long_index * 2]; + } else { + return *c; + } +} \ No newline at end of file diff --git a/src/xcmd_default_cmds.c b/src/xcmd_default_cmds.c index 08d7113..2d0043b 100755 --- a/src/xcmd_default_cmds.c +++ b/src/xcmd_default_cmds.c @@ -1,11 +1,3 @@ -/* - * @Author: your name - * @Date: 2021-09-15 00:11:50 - * @LastEditTime: 2021-10-11 21:37:09 - * @LastEditors: Please set LastEditors - * @Description: In User Settings Edit - * @FilePath: /xcmd/src/xcmd_default_cmds.c - */ #include "xcmd_default_confg.h" #include "xcmd_default_cmds.h" #include "xcmd.h" @@ -13,41 +5,71 @@ static int cmd_clear(int argc, char* argv[]) { - xcmd_print("\033c"); + xcmder_t *xcmder = XCMD_CURRENT(); + xcmd_print(xcmder, "\033c"); return 0; } static int cmd_help(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); xcmd_t *p = NULL; XCMD_CMD_FOR_EACH(p) { - xcmd_print("%-20s %s\r\n",p->name, p->help); + xcmd_print(xcmder, "%-20s %s\r\n",p->name, p->help); } return 0; } static int cmd_keys(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); xcmd_key_t *p = NULL; XCMD_KEY_FOR_EACH(p) { - xcmd_print("0x%08X\t", p->key); - xcmd_print("%s\r\n",p->help); + xcmd_print(xcmder, "0x%08X\t", p->name); + xcmd_print(xcmder, "%s\r\n",p->help); } return 0; } static int cmd_logo(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); char *log = "\ _ _ ___ __ __ ____ \r\n\ ( \\/ )/ __)( \\/ )( _ \\ \r\n\ ) (( (__ ) ( )(_) )\r\n\ (_/\\_)\\___)(_/\\/\\_)(____/\r\n "; - xcmd_print("%s", log); - xcmd_print("\r\n%-10s %s %s\r\n","Build" ,__DATE__, __TIME__); - xcmd_print("%-10s %s\r\n","Version", VERSION); + xcmd_print(xcmder, "%s", log); + xcmd_print(xcmder, "\r\n%-10s %s %s\r\n","Build" ,__DATE__, __TIME__); + xcmd_print(xcmder, "%-10s %s\r\n","Version", VERSION); + return 0; +} + +static int cmd_set(int argc, char* argv[]) +{ + xcmder_t *xcmder = XCMD_CURRENT(); + if(argc >= 3) + { + xnr_var_set(&xcmder->var_tab, argv[1], argv[2]); + } + return 0; +} + +static int cmd_var(int argc, char* argv[]) +{ + xcmder_t *xcmder = XCMD_CURRENT(); + int id = 0; + xnr_var_t *var; + while(1) + { + var = xnr_var(&xcmder->var_tab, id++); + if(NULL == var) + break; + if(var->name[0] != '\0') + xcmd_print(xcmder, "%-15s:%s\n", var->name, var->value); + } return 0; } @@ -55,6 +77,8 @@ XCMD_EXPORT_CMD(clear, cmd_clear, "clear screen") XCMD_EXPORT_CMD(help, cmd_help, "show this list") XCMD_EXPORT_CMD(keys, cmd_keys, "show keys") XCMD_EXPORT_CMD(logo, cmd_logo, "show logo") +XCMD_EXPORT_CMD(set, cmd_set, "set var") +XCMD_EXPORT_CMD(set, cmd_var, "get all var") static xcmd_t cmds[] = { @@ -63,6 +87,8 @@ static xcmd_t cmds[] = {"help", cmd_help, "show this list", NULL}, {"keys", cmd_keys, "show keys", NULL}, {"logo", cmd_logo, "show logo", NULL}, + {"set", cmd_set, "set var", NULL}, + {"var", cmd_var, "get all var", NULL}, #endif }; diff --git a/src/xcmd_default_keys.c b/src/xcmd_default_keys.c index 9e85f43..2fc2fa2 100755 --- a/src/xcmd_default_keys.c +++ b/src/xcmd_default_keys.c @@ -1,11 +1,3 @@ -/* - * @Author: your name - * @Date: 2021-09-15 00:11:50 - * @LastEditTime: 2021-10-27 09:16:27 - * @LastEditors: Please set LastEditors - * @Description: In User Settings Edit - * @FilePath: /xcmd/src/xcmd_default_keys.c - */ #include "xcmd_default_confg.h" #include "xcmd.h" #include "xcmd_default_keys.h" @@ -23,88 +15,85 @@ static int xcmd_str_match(const char* str1, const char* str2) return i; } - -static int xcmd_del_char(void *pv) +static int xcmd_del_char(int argc, char* argv[]) { - xcmd_display_delete_char(); + xcmder_t *xcmder = XCMD_CURRENT(); + xnr_line_delete(&xcmder->line); return 0; } XCMD_EXPORT_KEY(KEY_CTR_H, xcmd_del_char, "backspace") XCMD_EXPORT_KEY(KEY_BACKSPACE, xcmd_del_char, "delete") -static int xcmd_enter(void *pv) +static int xcmd_enter(int argc, char* argv[]) { - char *cmd = xcmd_end_of_input(); - xcmd_print("\n\r"); - if(cmd[0]) + xcmder_t *xcmder = XCMD_CURRENT(); + char out_line[XNR_LINE_MAX_LENGTH] = {0}; + xcmd_print(xcmder, "\n\r"); + char *line = xnr_line_line(&xcmder->line); + xnr_history_append(&xcmder->history, line); + xnr_var_repalce(&xcmder->var_tab, line, out_line, XNR_LINE_MAX_LENGTH); + if(out_line[0]) { - xcmd_exec(cmd); - cmd[0] = '\0'; + xcmd_exec(xcmder, out_line); } -#ifndef XCMD_DEFAULT_PROMPT_CLOLR - xcmd_print("%s", xcmd_get_prompt()); -#else - xcmd_print(XCMD_DEFAULT_PROMPT_CLOLR "%s" TX_DEF, xcmd_get_prompt()); -#endif + xnr_line_clear(&xcmder->line); return 0; } XCMD_EXPORT_KEY(KEY_CTR_M, xcmd_enter, "enter") XCMD_EXPORT_KEY(KEY_CTR_J, xcmd_enter, "enter") -static int xcmd_cursor_left(void *pv) +static int xcmd_cursor_left(int argc, char* argv[]) { - uint16_t pos = xcmd_display_cursor_get(); - if(pos > 0) - { - pos--; - xcmd_display_cursor_set(pos); - } + xcmder_t *xcmder = XCMD_CURRENT(); + xnr_line_cursor_left(&xcmder->line); return 0; } XCMD_EXPORT_KEY(KEY_LEFT, xcmd_cursor_left, "left") -static int xcmd_cursor_right(void *pv) +static int xcmd_cursor_right(int argc, char* argv[]) { - uint16_t pos = xcmd_display_cursor_get(); - pos++; - xcmd_display_cursor_set(pos); + xcmder_t *xcmder = XCMD_CURRENT(); + xnr_line_cursor_right(&xcmder->line); return 0; } XCMD_EXPORT_KEY(KEY_RIGHT, xcmd_cursor_right, "right") #if XCMD_HISTORY_MAX_NUM -static int xcmd_history_dw(void *pv) +static int xcmd_history_dw(int argc, char* argv[]) { - char *line = xcmd_history_prev(); - xcmd_display_clear(); - if(line) + xcmder_t *xcmder = XCMD_CURRENT(); + char out_line[XNR_LINE_MAX_LENGTH] = {0}; + if (xnr_history_dw(&xcmder->history, out_line, XNR_LINE_MAX_LENGTH) > 0) { - xcmd_display_print(line); + xnr_line_clear(&xcmder->line); + xnr_line_puts(&xcmder->line, out_line); } return 0; } XCMD_EXPORT_KEY(KEY_DW, xcmd_history_dw, "down") -static int xcmd_history_up(void *pv) +static int xcmd_history_up(int argc, char* argv[]) { - char *line = xcmd_history_next(); - if(line) + xcmder_t *xcmder = XCMD_CURRENT(); + char out_line[XNR_LINE_MAX_LENGTH] = {0}; + if (xnr_history_up(&xcmder->history, out_line, XNR_LINE_MAX_LENGTH) > 0) { - xcmd_display_clear(); - xcmd_display_print(line); + xnr_line_clear(&xcmder->line); + xnr_line_puts(&xcmder->line, out_line); } return 0; } XCMD_EXPORT_KEY(KEY_UP, xcmd_history_up, "up") #endif -static int xcmd_auto_completion(void *pv) +static int xcmd_auto_completion(int argc, char* argv[]) { + xcmder_t *xcmder = XCMD_CURRENT(); xcmd_t *match_cmd_first = NULL; uint16_t match_num = 0; uint16_t match_subscript_min = 0; - char *display_line = xcmd_display_get(); - uint16_t cursor_pos = xcmd_display_cursor_get(); + char *display_line = xnr_line_line(&xcmder->line); + uint16_t cursor_pos = xnr_line_cursor(&xcmder->line); xcmd_t *p = NULL; XCMD_CMD_FOR_EACH(p) { @@ -117,14 +106,14 @@ static int xcmd_auto_completion(void *pv) } else if(match_num == 1) { - xcmd_print("\r\n%-15s%-15s", match_cmd_first->name, p->name); + xcmd_print(xcmder,"\r\n%-15s%-15s", match_cmd_first->name, p->name); } else { - xcmd_print("%-15s", p->name); + xcmd_print(xcmder, "%-15s", p->name); if((match_num%4) == 0) { - xcmd_print("\r\n"); + xcmd_print(xcmder, "\r\n"); } } uint16_t subscript = xcmd_str_match(match_cmd_first->name, p->name); @@ -138,14 +127,14 @@ static int xcmd_auto_completion(void *pv) if(match_num == 1) { - xcmd_display_clear(); - xcmd_display_print("%s", match_cmd_first->name); + xnr_line_clear(&xcmder->line); + xnr_line_puts(&xcmder->line, match_cmd_first->name); } else if(match_num > 1) { - xcmd_print("\r\n"); - xcmd_display_clear(); - xcmd_display_write(match_cmd_first->name, match_subscript_min); + xcmd_print(xcmder, "\r\n"); + xnr_line_clear(&xcmder->line); + xnr_line_write(&xcmder->line, match_cmd_first->name, match_subscript_min); } return 0; }