From 74e14f3bacb2f7fa6093983674f2560d71bc61bf Mon Sep 17 00:00:00 2001 From: wangqinglin <53550140+HelloByeAll@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:49:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=96=B0=E5=A2=9E:MSH=E5=91=BD=E4=BB=A4=20?= =?UTF-8?q?options=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/stm32/stm32f103-dofly-lyc8/.config | 8 +- bsp/stm32/stm32f103-dofly-lyc8/rtconfig.h | 5 +- components/finsh/Kconfig | 4 + components/finsh/cmd.c | 116 ++++++++++++++-- components/finsh/finsh.h | 79 +++++++++-- components/finsh/msh.c | 158 +++++++++++++++++++++- components/finsh/msh.h | 6 + components/finsh/shell.c | 2 + 8 files changed, 348 insertions(+), 30 deletions(-) diff --git a/bsp/stm32/stm32f103-dofly-lyc8/.config b/bsp/stm32/stm32f103-dofly-lyc8/.config index 9be46937191..48e52ea3349 100644 --- a/bsp/stm32/stm32f103-dofly-lyc8/.config +++ b/bsp/stm32/stm32f103-dofly-lyc8/.config @@ -81,7 +81,7 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -CONFIG_RT_VER_NUM=0x50000 +CONFIG_RT_VER_NUM=0x50001 # CONFIG_RT_USING_STDC_ATOMIC is not set # CONFIG_RT_USING_CACHE is not set CONFIG_RT_USING_HW_ATOMIC=y @@ -115,6 +115,11 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 +# CONFIG_FINSH_OPTION_COMPLETION_ENABLED is not set + +# +# DFS: device virtual file system +# # CONFIG_RT_USING_DFS is not set # CONFIG_RT_USING_FAL is not set @@ -661,7 +666,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_MISAKA_AT24CXX is not set # CONFIG_PKG_USING_MISAKA_RGB_BLING is not set # CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set -# CONFIG_PKG_USING_BL_MCU_SDK is not set # CONFIG_PKG_USING_SOFT_SERIAL is not set # CONFIG_PKG_USING_MB85RS16 is not set # CONFIG_PKG_USING_RFM300 is not set diff --git a/bsp/stm32/stm32f103-dofly-lyc8/rtconfig.h b/bsp/stm32/stm32f103-dofly-lyc8/rtconfig.h index 50c86ba3a2e..9876672cbbe 100644 --- a/bsp/stm32/stm32f103-dofly-lyc8/rtconfig.h +++ b/bsp/stm32/stm32f103-dofly-lyc8/rtconfig.h @@ -45,7 +45,7 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart1" -#define RT_VER_NUM 0x50000 +#define RT_VER_NUM 0x50001 #define RT_USING_HW_ATOMIC #define RT_USING_CPU_FFS #define ARCH_ARM @@ -72,6 +72,9 @@ #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 +/* DFS: device virtual file system */ + + /* Device Drivers */ #define RT_USING_DEVICE_IPC diff --git a/components/finsh/Kconfig b/components/finsh/Kconfig index 2d9d768e239..4a805a3922d 100644 --- a/components/finsh/Kconfig +++ b/components/finsh/Kconfig @@ -76,4 +76,8 @@ if RT_USING_MSH int "The number of arguments for a shell command" default 10 + config FINSH_OPTION_COMPLETION_ENABLED + bool "command option completion enable" + default y + endif diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index a9a673101ec..8ea5e9d8595 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -38,6 +38,7 @@ #ifdef RT_USING_FINSH #include +#include "msh.h" #define LIST_FIND_OBJ_NR 8 @@ -894,68 +895,69 @@ long list_device(void) } #endif /* RT_USING_DEVICE */ +#ifndef FINSH_OPTION_COMPLETION_ENABLED int cmd_list(int argc, char **argv) { - if(argc == 2) + if (argc == 2) { - if(strcmp(argv[1], "thread") == 0) + if (strcmp(argv[1], "thread") == 0) { list_thread(); } - else if(strcmp(argv[1], "timer") == 0) + else if (strcmp(argv[1], "timer") == 0) { list_timer(); } #ifdef RT_USING_SEMAPHORE - else if(strcmp(argv[1], "sem") == 0) + else if (strcmp(argv[1], "sem") == 0) { list_sem(); } #endif /* RT_USING_SEMAPHORE */ #ifdef RT_USING_EVENT - else if(strcmp(argv[1], "event") == 0) + else if (strcmp(argv[1], "event") == 0) { list_event(); } #endif /* RT_USING_EVENT */ #ifdef RT_USING_MUTEX - else if(strcmp(argv[1], "mutex") == 0) + else if (strcmp(argv[1], "mutex") == 0) { list_mutex(); } #endif /* RT_USING_MUTEX */ #ifdef RT_USING_MAILBOX - else if(strcmp(argv[1], "mailbox") == 0) + else if (strcmp(argv[1], "mailbox") == 0) { list_mailbox(); } #endif /* RT_USING_MAILBOX */ #ifdef RT_USING_MESSAGEQUEUE - else if(strcmp(argv[1], "msgqueue") == 0) + else if (strcmp(argv[1], "msgqueue") == 0) { list_msgqueue(); } #endif /* RT_USING_MESSAGEQUEUE */ #ifdef RT_USING_MEMHEAP - else if(strcmp(argv[1], "memheap") == 0) + else if (strcmp(argv[1], "memheap") == 0) { list_memheap(); } #endif /* RT_USING_MEMHEAP */ #ifdef RT_USING_MEMPOOL - else if(strcmp(argv[1], "mempool") == 0) + else if (strcmp(argv[1], "mempool") == 0) { list_mempool(); } #endif /* RT_USING_MEMPOOL */ #ifdef RT_USING_DEVICE - else if(strcmp(argv[1], "device") == 0) + else if (strcmp(argv[1], "device") == 0) { list_device(); } #endif /* RT_USING_DEVICE */ #ifdef RT_USING_DFS - else if(strcmp(argv[1], "fd") == 0) + else if (strcmp(argv[1], "fd") == 0) { extern int list_fd(void); list_fd(); @@ -1006,4 +1008,94 @@ int cmd_list(int argc, char **argv) } MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects); +#else +CMD_OPTIONS_STATEMENT(cmd_list) +int cmd_list(int argc, char **argv) +{ + if (argc == 2) + { + switch (MSH_OPT_ID_GET(cmd_list)) + { + case RT_Object_Class_Thread: list_thread(); break; + case RT_Object_Class_Timer: list_timer(); break; +#ifdef RT_USING_SEMAPHORE + case RT_Object_Class_Semaphore: list_sem(); break; +#endif /* RT_USING_SEMAPHORE */ +#ifdef RT_USING_EVENT + case RT_Object_Class_Event: list_event(); break; +#endif /* RT_USING_EVENT */ +#ifdef RT_USING_MUTEX + case RT_Object_Class_Mutex: list_mutex(); break; +#endif /* RT_USING_MUTEX */ +#ifdef RT_USING_MAILBOX + case RT_Object_Class_MailBox: list_mailbox(); break; +#endif /* RT_USING_MAILBOX */ +#ifdef RT_USING_MESSAGEQUEUE + case RT_Object_Class_MessageQueue: list_msgqueue(); break; +#endif /* RT_USING_MESSAGEQUEUE */ +#ifdef RT_USING_MEMHEAP + case RT_Object_Class_MemHeap: list_memheap(); break; +#endif /* RT_USING_MEMHEAP */ +#ifdef RT_USING_MEMPOOL + case RT_Object_Class_MemPool: list_mempool(); break; +#endif /* RT_USING_MEMPOOL */ +#ifdef RT_USING_DEVICE + case RT_Object_Class_Device: list_device(); break; +#endif /* RT_USING_DEVICE */ +#ifdef RT_USING_DFS + case 0x100: + { + extern int list_fd(void); + list_fd(); + break; + } +#endif /* RT_USING_DFS */ + default: + goto _usage; + break; + }; + + return 0; + } + +_usage: + rt_kprintf("Usage: list [options]\n"); + rt_kprintf("[options]:\n"); + MSH_OPT_DUMP(cmd_list); + return 0; +} +CMD_OPTIONS_NODE_START(cmd_list) +CMD_OPTIONS_NODE(RT_Object_Class_Thread, thread, list threads) +CMD_OPTIONS_NODE(RT_Object_Class_Timer, timer, list timers) +#ifdef RT_USING_SEMAPHORE +CMD_OPTIONS_NODE(RT_Object_Class_Semaphore, sem, list semaphores) +#endif /* RT_USING_SEMAPHORE */ +#ifdef RT_USING_EVENT +CMD_OPTIONS_NODE(RT_Object_Class_Event, event, list events) +#endif /* RT_USING_EVENT */ +#ifdef RT_USING_MUTEX +CMD_OPTIONS_NODE(RT_Object_Class_Mutex, mutex, list mutexs) +#endif /* RT_USING_MUTEX */ +#ifdef RT_USING_MAILBOX +CMD_OPTIONS_NODE(RT_Object_Class_MailBox, mailbox, list mailboxs) +#endif /* RT_USING_MAILBOX */ +#ifdef RT_USING_MESSAGEQUEUE +CMD_OPTIONS_NODE(RT_Object_Class_MessageQueue, msgqueue, list message queues) +#endif /* RT_USING_MESSAGEQUEUE */ +#ifdef RT_USING_MEMHEAP +CMD_OPTIONS_NODE(RT_Object_Class_MemHeap, memheap, list memory heaps) +#endif /* RT_USING_MEMHEAP */ +#ifdef RT_USING_MEMPOOL +CMD_OPTIONS_NODE(RT_Object_Class_MemPool, mempool, list memory pools) +#endif /* RT_USING_MEMPOOL */ +#ifdef RT_USING_DEVICE +CMD_OPTIONS_NODE(RT_Object_Class_Device, device, list devices) +#endif /* RT_USING_DEVICE */ +#ifdef RT_USING_DFS +CMD_OPTIONS_NODE(0x100, fd, list file descriptors) +#endif /* RT_USING_DFS */ +CMD_OPTIONS_NODE_END +MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects, optenable); +#endif /* FINSH_OPTION_COMPLETION_ENABLED */ + #endif /* RT_USING_FINSH */ diff --git a/components/finsh/finsh.h b/components/finsh/finsh.h index cf13b761d5e..e0b816f7759 100644 --- a/components/finsh/finsh.h +++ b/components/finsh/finsh.h @@ -23,7 +23,7 @@ typedef long (*syscall_func)(void); #endif /* __TI_COMPILER_VERSION__ */ #ifdef FINSH_USING_DESCRIPTION #ifdef _MSC_VER -#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \ +#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \ const char __fsym_##cmd##_name[] = #cmd; \ const char __fsym_##cmd##_desc[] = #desc; \ __declspec(allocate("FSymTab$f")) \ @@ -31,6 +31,7 @@ typedef long (*syscall_func)(void); { \ __fsym_##cmd##_name, \ __fsym_##cmd##_desc, \ + opt, \ (syscall_func)&name \ }; #pragma comment(linker, "/merge:FSymTab=mytext") @@ -41,56 +42,61 @@ typedef long (*syscall_func)(void); #else #define RT_NOBLOCKED #endif -#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \ - __TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \ - const char __fsym_##cmd##_name[] = #cmd; \ - const char __fsym_##cmd##_desc[] = #desc; \ - rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \ +#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \ + __TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \ + const char __fsym_##cmd##_name[] = #cmd; \ + const char __fsym_##cmd##_desc[] = #desc; \ + rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \ { \ __fsym_##cmd##_name, \ __fsym_##cmd##_desc, \ + opt, \ (syscall_func)&name \ }; #else -#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \ +#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \ const char __fsym_##cmd##_name[] rt_section(".rodata.name") = #cmd; \ const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc; \ rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \ { \ __fsym_##cmd##_name, \ __fsym_##cmd##_desc, \ + opt, \ (syscall_func)&name \ }; #endif #else #ifdef _MSC_VER -#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \ +#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \ const char __fsym_##cmd##_name[] = #cmd; \ __declspec(allocate("FSymTab$f")) \ const struct finsh_syscall __fsym_##cmd = \ { \ __fsym_##cmd##_name, \ + opt, \ (syscall_func)&name \ }; #pragma comment(linker, "/merge:FSymTab=mytext") #elif defined(__TI_COMPILER_VERSION__) -#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \ +#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \ __TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \ const char __fsym_##cmd##_name[] = #cmd; \ const struct finsh_syscall __fsym_##cmd = \ { \ __fsym_##cmd##_name, \ + opt, \ (syscall_func)&name \ }; #else -#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \ +#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \ const char __fsym_##cmd##_name[] = #cmd; \ rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \ { \ __fsym_##cmd##_name, \ + opt, \ (syscall_func)&name \ }; @@ -98,6 +104,24 @@ typedef long (*syscall_func)(void); #endif /* end of FINSH_USING_DESCRIPTION */ #endif /* end of FINSH_USING_SYMTAB */ +#define GET_MACRO(_1, _2, _3, _FUN, ...) _FUN +#define GET_EXPORT_MACRO(_1, _2, _3, _4, _FUN, ...) _FUN + +#define GET_MSH_OPT1(cmd) cmd##msh_options +#define GET_MSH_OPT(cmd) GET_MSH_OPT1(cmd) + +#define _MSH_FUNCTION_CMD2(a0, a1) \ + MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0) + +#define _MSH_FUNCTION_CMD3(a0, a1, a2) \ + MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, a0##_msh_options) + +#define _MSH_FUNCTION_EXPORT_CMD3(a0, a1, a2) \ + MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0) + +#define _MSH_FUNCTION_EXPORT_CMD4(a0, a1, a2, a3) \ + MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, a0##_msh_options) + /** * @ingroup finsh * @@ -126,9 +150,12 @@ typedef long (*syscall_func)(void); * * @param command is the name of the command. * @param desc is the description of the command, which will show in help list. + * @param opt This is an option, enter any content to enable option completion */ -#define MSH_CMD_EXPORT(command, desc) \ - MSH_FUNCTION_EXPORT_CMD(command, command, desc) +/* MSH_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */ +#define MSH_CMD_EXPORT(...) \ + GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3, \ + _MSH_FUNCTION_CMD2)(__VA_ARGS__) /** * @ingroup msh @@ -138,9 +165,13 @@ typedef long (*syscall_func)(void); * @param command is the name of the command. * @param alias is the alias of the command. * @param desc is the description of the command, which will show in help list. + * @param opt This is an option, enter any content to enable option completion */ -#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \ - MSH_FUNCTION_EXPORT_CMD(command, alias, desc) +/* #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) or + #define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) */ +#define MSH_CMD_EXPORT_ALIAS(...) \ + GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4, \ + _MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__) /* system call table */ struct finsh_syscall @@ -149,6 +180,7 @@ struct finsh_syscall #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB) const char *desc; /* description of system call */ #endif + struct msh_cmd_opt *opt; syscall_func func; /* the function address of system call */ }; @@ -159,6 +191,25 @@ struct finsh_syscall_item struct finsh_syscall syscall; /* syscall */ }; +typedef struct msh_cmd_opt +{ + rt_uint32_t id; + const char *name; + const char *des; +} msh_cmd_opt_t; + +#ifdef FINSH_OPTION_COMPLETION_ENABLED +#define CMD_OPTIONS_STATEMENT(command) static struct msh_cmd_opt command##_msh_options[]; +#define CMD_OPTIONS_NODE_START(command) static struct msh_cmd_opt command##_msh_options[] = { +#define CMD_OPTIONS_NODE(_id, _name, _des) {.id = _id, .name = #_name, .des = #_des}, +#define CMD_OPTIONS_NODE_END {0},}; +#else +#define CMD_OPTIONS_STATEMENT(command) +#define CMD_OPTIONS_NODE_START(command) +#define CMD_OPTIONS_NODE(_id, _name, _des) +#define CMD_OPTIONS_NODE_END +#endif + extern struct finsh_syscall_item *global_syscall_list; extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end; diff --git a/components/finsh/msh.c b/components/finsh/msh.c index a63e34ddfe0..fee152c8b23 100644 --- a/components/finsh/msh.c +++ b/components/finsh/msh.c @@ -170,6 +170,36 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX]) return argc; } +static msh_cmd_opt_t *msh_get_cmd_opt(char *opt_str) +{ + struct finsh_syscall *index; + msh_cmd_opt_t *opt = RT_NULL; + char *ptr; + int len; + + if ((ptr = strchr(opt_str, ' '))) + { + len = ptr - opt_str; + } + else + { + len = strlen(opt_str); + } + + for (index = _syscall_table_begin; + index < _syscall_table_end; + FINSH_NEXT_SYSCALL(index)) + { + if (strncmp(index->name, opt_str, len) == 0 && index->name[len] == '\0') + { + opt = index->opt; + break; + } + } + + return opt; +} + static cmd_function_t msh_get_cmd(char *cmd, int size) { struct finsh_syscall *index; @@ -764,6 +794,132 @@ void msh_auto_complete(char *prefix) rt_strncpy(prefix, name_ptr, min_length); } - return ; + return; +} + +static int msh_get_argc(char *prefix, char **last_argv) +{ + int argc = 0; + char *ch = prefix; + + while (*ch) + { + if ((*ch == ' ') && *(ch + 1) && (*(ch + 1) != ' ')) + { + *last_argv = ch + 1; + argc++; + } + ch++; + } + + return argc; +} + +static void msh_opt_complete(char *opts_str, struct msh_cmd_opt *cmd_opt) +{ + struct msh_cmd_opt *opt = cmd_opt; + const char *name_ptr = RT_NULL; + int min_length = 0, length, opts_str_len; + + opts_str_len = strlen(opts_str); + + for (opt = cmd_opt; opt->id; opt++) + { + if (!strncmp(opt->name, opts_str, opts_str_len)) + { + if (min_length == 0) + { + /* set name_ptr */ + name_ptr = opt->name; + /* set initial length */ + min_length = strlen(name_ptr); + } + + length = str_common(name_ptr, opt->name); + if (length < min_length) + { + min_length = length; + } + + rt_kprintf("%s\n", opt->name); + } + } + rt_kprintf("\n"); + + if (name_ptr != NULL) + { + strncpy(opts_str, name_ptr, min_length); + } +} + +static void msh_opt_help(msh_cmd_opt_t *cmd_opt) +{ + msh_cmd_opt_t *opt = cmd_opt; + + for (; opt->id; opt++) + { + rt_kprintf("%-16s - %s\n", opt->name, opt->des); + } + rt_kprintf("\n"); +} + +void msh_opt_auto_complete(char *prefix) +{ + int argc; + char *opt_str = RT_NULL; + msh_cmd_opt_t *opt = RT_NULL; + + if ((argc = msh_get_argc(prefix, &opt_str))) + { + opt = msh_get_cmd_opt(prefix); + } + else if (!msh_get_cmd(prefix, strlen(prefix)) && (' ' == prefix[strlen(prefix) - 1])) + { + opt = msh_get_cmd_opt(prefix); + } + + if (opt && opt->id) + { + switch (argc) + { + case 0: + msh_opt_help(opt); + break; + + case 1: + msh_opt_complete(opt_str, opt); + break; + + default: + break; + } + } +} + +int msh_cmd_opt_id_get(int argc, char *argv[], void *options) +{ + msh_cmd_opt_t *opt = (msh_cmd_opt_t *) options; + int opt_id; + + for (opt_id = 0; (argc >= 2) && opt && opt->id; opt++) + { + if (!strcmp(opt->name, argv[1])) + { + opt_id = opt->id; + break; + } + } + + return opt_id; +} + +void msh_opt_list_dump(void *options) +{ + msh_cmd_opt_t *opt = (msh_cmd_opt_t *) options; + + for (; opt && opt->id; opt++) + { + rt_kprintf(" %-16s - %s\n", opt->name, opt->des); + } } #endif /* RT_USING_FINSH */ diff --git a/components/finsh/msh.h b/components/finsh/msh.h index b9b037586e6..20030a97ceb 100644 --- a/components/finsh/msh.h +++ b/components/finsh/msh.h @@ -15,8 +15,14 @@ int msh_exec(char *cmd, rt_size_t length); void msh_auto_complete(char *prefix); +void msh_opt_auto_complete(char *prefix); int msh_exec_module(const char *cmd_line, int size); int msh_exec_script(const char *cmd_line, int size); +void msh_opt_list_dump(void *options); +int msh_cmd_opt_id_get(int argc, char *argv[], void *options); + +#define MSH_OPT_ID_GET(fun) msh_cmd_opt_id_get(argc, argv, (void*) fun##_msh_options) +#define MSH_OPT_DUMP(fun) msh_opt_list_dump((void*) fun##_msh_options) #endif diff --git a/components/finsh/shell.c b/components/finsh/shell.c index b55eb32316b..95f8502de27 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -381,6 +381,8 @@ static void shell_auto_complete(char *prefix) rt_kprintf("\n"); msh_auto_complete(prefix); + msh_opt_auto_complete(prefix); + rt_kprintf("%s%s", FINSH_PROMPT, prefix); } From 1cecd45d289098f83895b58375d7bdde85771d9f Mon Sep 17 00:00:00 2001 From: wangqinglin <53550140+HelloByeAll@users.noreply.github.com> Date: Wed, 19 Apr 2023 09:59:22 +0800 Subject: [PATCH 2/2] =?UTF-8?q?msh=20=E9=80=89=E9=A1=B9=E8=A1=A5=E5=85=A8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BA=B3=E5=85=A5=E5=AE=8F=E7=AE=A1=E7=90=86?= =?UTF-8?q?=20FINSH=5FOPTION=5FCOMPLETION=5FENABLED?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/finsh/finsh.h | 37 +++++++++++++++++------- components/finsh/msh.c | 62 +++++++++++++++++++++------------------- components/finsh/shell.c | 2 ++ 3 files changed, 60 insertions(+), 41 deletions(-) diff --git a/components/finsh/finsh.h b/components/finsh/finsh.h index e0b816f7759..31e340ae439 100644 --- a/components/finsh/finsh.h +++ b/components/finsh/finsh.h @@ -104,24 +104,27 @@ typedef long (*syscall_func)(void); #endif /* end of FINSH_USING_DESCRIPTION */ #endif /* end of FINSH_USING_SYMTAB */ -#define GET_MACRO(_1, _2, _3, _FUN, ...) _FUN -#define GET_EXPORT_MACRO(_1, _2, _3, _4, _FUN, ...) _FUN - -#define GET_MSH_OPT1(cmd) cmd##msh_options -#define GET_MSH_OPT(cmd) GET_MSH_OPT1(cmd) +#define __MSH_GET_MACRO(_1, _2, _3, _FUN, ...) _FUN +#define __MSH_GET_EXPORT_MACRO(_1, _2, _3, _4, _FUN, ...) _FUN #define _MSH_FUNCTION_CMD2(a0, a1) \ MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0) -#define _MSH_FUNCTION_CMD3(a0, a1, a2) \ +#define _MSH_FUNCTION_CMD3_OPT(a0, a1, a2) \ MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, a0##_msh_options) +#define _MSH_FUNCTION_CMD3_NO_OPT(a0, a1, a2) \ + MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0) + #define _MSH_FUNCTION_EXPORT_CMD3(a0, a1, a2) \ MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0) -#define _MSH_FUNCTION_EXPORT_CMD4(a0, a1, a2, a3) \ +#define _MSH_FUNCTION_EXPORT_CMD4_OPT(a0, a1, a2, a3) \ MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, a0##_msh_options) +#define _MSH_FUNCTION_EXPORT_CMD4_NO_OPT(a0, a1, a2, a3) \ + MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0) + /** * @ingroup finsh * @@ -153,9 +156,15 @@ typedef long (*syscall_func)(void); * @param opt This is an option, enter any content to enable option completion */ /* MSH_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */ -#define MSH_CMD_EXPORT(...) \ - GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3, \ +#ifdef FINSH_OPTION_COMPLETION_ENABLED +#define MSH_CMD_EXPORT(...) \ + __MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3_OPT, \ _MSH_FUNCTION_CMD2)(__VA_ARGS__) +#else +#define MSH_CMD_EXPORT(...) \ + __MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3_NO_OPT, \ + _MSH_FUNCTION_CMD2)(__VA_ARGS__) +#endif /* FINSH_OPTION_COMPLETION_ENABLED */ /** * @ingroup msh @@ -169,9 +178,15 @@ typedef long (*syscall_func)(void); */ /* #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) or #define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) */ -#define MSH_CMD_EXPORT_ALIAS(...) \ - GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4, \ +#ifdef FINSH_OPTION_COMPLETION_ENABLED +#define MSH_CMD_EXPORT_ALIAS(...) \ + __MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4_OPT, \ + _MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__) +#else +#define MSH_CMD_EXPORT_ALIAS(...) \ + __MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4_NO_OPT, \ _MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__) +#endif /* FINSH_OPTION_COMPLETION_ENABLED */ /* system call table */ struct finsh_syscall diff --git a/components/finsh/msh.c b/components/finsh/msh.c index fee152c8b23..349393683a5 100644 --- a/components/finsh/msh.c +++ b/components/finsh/msh.c @@ -170,36 +170,6 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX]) return argc; } -static msh_cmd_opt_t *msh_get_cmd_opt(char *opt_str) -{ - struct finsh_syscall *index; - msh_cmd_opt_t *opt = RT_NULL; - char *ptr; - int len; - - if ((ptr = strchr(opt_str, ' '))) - { - len = ptr - opt_str; - } - else - { - len = strlen(opt_str); - } - - for (index = _syscall_table_begin; - index < _syscall_table_end; - FINSH_NEXT_SYSCALL(index)) - { - if (strncmp(index->name, opt_str, len) == 0 && index->name[len] == '\0') - { - opt = index->opt; - break; - } - } - - return opt; -} - static cmd_function_t msh_get_cmd(char *cmd, int size) { struct finsh_syscall *index; @@ -797,6 +767,37 @@ void msh_auto_complete(char *prefix) return; } +#ifdef FINSH_OPTION_COMPLETION_ENABLED +static msh_cmd_opt_t *msh_get_cmd_opt(char *opt_str) +{ + struct finsh_syscall *index; + msh_cmd_opt_t *opt = RT_NULL; + char *ptr; + int len; + + if ((ptr = strchr(opt_str, ' '))) + { + len = ptr - opt_str; + } + else + { + len = strlen(opt_str); + } + + for (index = _syscall_table_begin; + index < _syscall_table_end; + FINSH_NEXT_SYSCALL(index)) + { + if (strncmp(index->name, opt_str, len) == 0 && index->name[len] == '\0') + { + opt = index->opt; + break; + } + } + + return opt; +} + static int msh_get_argc(char *prefix, char **last_argv) { int argc = 0; @@ -895,6 +896,7 @@ void msh_opt_auto_complete(char *prefix) } } } +#endif /* FINSH_OPTION_COMPLETION_ENABLED */ int msh_cmd_opt_id_get(int argc, char *argv[], void *options) { diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 95f8502de27..7512b233444 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -381,7 +381,9 @@ static void shell_auto_complete(char *prefix) rt_kprintf("\n"); msh_auto_complete(prefix); +#ifdef FINSH_OPTION_COMPLETION_ENABLED msh_opt_auto_complete(prefix); +#endif rt_kprintf("%s%s", FINSH_PROMPT, prefix); }