Skip to content

Commit 2d630e3

Browse files
authored
【msh】新增msh自动补全子选项特性 (#8086)
1 parent d8a2084 commit 2d630e3

File tree

6 files changed

+363
-48
lines changed

6 files changed

+363
-48
lines changed

components/finsh/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,8 @@ if RT_USING_MSH
7676
int "The number of arguments for a shell command"
7777
default 10
7878

79+
config FINSH_USING_OPTION_COMPLETION
80+
bool "command option completion enable"
81+
default y
82+
7983
endif

components/finsh/cmd.c

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#ifdef RT_USING_FINSH
4040
#include <finsh.h>
4141

42+
#define LIST_DFS_OPT_ID 0x100
4243
#define LIST_FIND_OBJ_NR 8
4344

4445
static long clear(void)
@@ -903,6 +904,7 @@ long list_device(void)
903904
}
904905
#endif /* RT_USING_DEVICE */
905906

907+
#ifndef FINSH_USING_OPTION_COMPLETION
906908
int cmd_list(int argc, char **argv)
907909
{
908910
if(argc == 2)
@@ -1013,6 +1015,95 @@ int cmd_list(int argc, char **argv)
10131015

10141016
return 0;
10151017
}
1016-
MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects);
1018+
1019+
#else
1020+
CMD_OPTIONS_STATEMENT(cmd_list)
1021+
int cmd_list(int argc, char **argv)
1022+
{
1023+
if (argc == 2)
1024+
{
1025+
switch (MSH_OPT_ID_GET(cmd_list))
1026+
{
1027+
case RT_Object_Class_Thread: list_thread(); break;
1028+
case RT_Object_Class_Timer: list_timer(); break;
1029+
#ifdef RT_USING_SEMAPHORE
1030+
case RT_Object_Class_Semaphore: list_sem(); break;
1031+
#endif /* RT_USING_SEMAPHORE */
1032+
#ifdef RT_USING_EVENT
1033+
case RT_Object_Class_Event: list_event(); break;
1034+
#endif /* RT_USING_EVENT */
1035+
#ifdef RT_USING_MUTEX
1036+
case RT_Object_Class_Mutex: list_mutex(); break;
1037+
#endif /* RT_USING_MUTEX */
1038+
#ifdef RT_USING_MAILBOX
1039+
case RT_Object_Class_MailBox: list_mailbox(); break;
1040+
#endif /* RT_USING_MAILBOX */
1041+
#ifdef RT_USING_MESSAGEQUEUE
1042+
case RT_Object_Class_MessageQueue: list_msgqueue(); break;
1043+
#endif /* RT_USING_MESSAGEQUEUE */
1044+
#ifdef RT_USING_MEMHEAP
1045+
case RT_Object_Class_MemHeap: list_memheap(); break;
1046+
#endif /* RT_USING_MEMHEAP */
1047+
#ifdef RT_USING_MEMPOOL
1048+
case RT_Object_Class_MemPool: list_mempool(); break;
1049+
#endif /* RT_USING_MEMPOOL */
1050+
#ifdef RT_USING_DEVICE
1051+
case RT_Object_Class_Device: list_device(); break;
1052+
#endif /* RT_USING_DEVICE */
1053+
#ifdef RT_USING_DFS
1054+
case LIST_DFS_OPT_ID:
1055+
{
1056+
extern int list_fd(void);
1057+
list_fd();
1058+
break;
1059+
}
1060+
#endif /* RT_USING_DFS */
1061+
default:
1062+
goto _usage;
1063+
break;
1064+
};
1065+
1066+
return 0;
1067+
}
1068+
1069+
_usage:
1070+
rt_kprintf("Usage: list [options]\n");
1071+
rt_kprintf("[options]:\n");
1072+
MSH_OPT_DUMP(cmd_list);
1073+
return 0;
1074+
}
1075+
CMD_OPTIONS_NODE_START(cmd_list)
1076+
CMD_OPTIONS_NODE(RT_Object_Class_Thread, thread, list threads)
1077+
CMD_OPTIONS_NODE(RT_Object_Class_Timer, timer, list timers)
1078+
#ifdef RT_USING_SEMAPHORE
1079+
CMD_OPTIONS_NODE(RT_Object_Class_Semaphore, sem, list semaphores)
1080+
#endif /* RT_USING_SEMAPHORE */
1081+
#ifdef RT_USING_EVENT
1082+
CMD_OPTIONS_NODE(RT_Object_Class_Event, event, list events)
1083+
#endif /* RT_USING_EVENT */
1084+
#ifdef RT_USING_MUTEX
1085+
CMD_OPTIONS_NODE(RT_Object_Class_Mutex, mutex, list mutexs)
1086+
#endif /* RT_USING_MUTEX */
1087+
#ifdef RT_USING_MAILBOX
1088+
CMD_OPTIONS_NODE(RT_Object_Class_MailBox, mailbox, list mailboxs)
1089+
#endif /* RT_USING_MAILBOX */
1090+
#ifdef RT_USING_MESSAGEQUEUE
1091+
CMD_OPTIONS_NODE(RT_Object_Class_MessageQueue, msgqueue, list message queues)
1092+
#endif /* RT_USING_MESSAGEQUEUE */
1093+
#ifdef RT_USING_MEMHEAP
1094+
CMD_OPTIONS_NODE(RT_Object_Class_MemHeap, memheap, list memory heaps)
1095+
#endif /* RT_USING_MEMHEAP */
1096+
#ifdef RT_USING_MEMPOOL
1097+
CMD_OPTIONS_NODE(RT_Object_Class_MemPool, mempool, list memory pools)
1098+
#endif /* RT_USING_MEMPOOL */
1099+
#ifdef RT_USING_DEVICE
1100+
CMD_OPTIONS_NODE(RT_Object_Class_Device, device, list devices)
1101+
#endif /* RT_USING_DEVICE */
1102+
#ifdef RT_USING_DFS
1103+
CMD_OPTIONS_NODE(LIST_DFS_OPT_ID, fd, list file descriptors)
1104+
#endif /* RT_USING_DFS */
1105+
CMD_OPTIONS_NODE_END
1106+
#endif /* FINSH_USING_OPTION_COMPLETION */
1107+
MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects, optenable);
10171108

10181109
#endif /* RT_USING_FINSH */

components/finsh/finsh.h

Lines changed: 101 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,35 @@
1616
#pragma section("FSymTab$f",read)
1717
#endif /* _MSC_VER */
1818

19+
#ifdef FINSH_USING_OPTION_COMPLETION
20+
#define FINSH_COND(opt) opt,
21+
#else
22+
#define FINSH_COND(opt)
23+
#endif
24+
25+
#ifdef FINSH_USING_DESCRIPTION
26+
#define FINSH_DESC(cmd, desc) __fsym_##cmd##_desc,
27+
#else
28+
#define FINSH_DESC(cmd, desc)
29+
#endif
30+
1931
typedef long (*syscall_func)(void);
2032
#ifdef FINSH_USING_SYMTAB
33+
2134
#ifdef __TI_COMPILER_VERSION__
2235
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
2336
#endif /* __TI_COMPILER_VERSION__ */
24-
#ifdef FINSH_USING_DESCRIPTION
37+
2538
#ifdef _MSC_VER
26-
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
39+
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
2740
const char __fsym_##cmd##_name[] = #cmd; \
2841
const char __fsym_##cmd##_desc[] = #desc; \
2942
__declspec(allocate("FSymTab$f")) \
3043
const struct finsh_syscall __fsym_##cmd = \
3144
{ \
3245
__fsym_##cmd##_name, \
33-
__fsym_##cmd##_desc, \
46+
FINSH_DESC(cmd, desc) \
47+
FINSH_COND(opt) \
3448
(syscall_func)&name \
3549
};
3650
#pragma comment(linker, "/merge:FSymTab=mytext")
@@ -41,62 +55,54 @@ typedef long (*syscall_func)(void);
4155
#else
4256
#define RT_NOBLOCKED
4357
#endif
44-
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
45-
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
46-
const char __fsym_##cmd##_name[] = #cmd; \
47-
const char __fsym_##cmd##_desc[] = #desc; \
48-
rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \
58+
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
59+
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
60+
const char __fsym_##cmd##_name[] = #cmd; \
61+
const char __fsym_##cmd##_desc[] = #desc; \
62+
rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \
4963
{ \
5064
__fsym_##cmd##_name, \
51-
__fsym_##cmd##_desc, \
65+
FINSH_DESC(cmd, desc) \
66+
FINSH_COND(opt) \
5267
(syscall_func)&name \
5368
};
69+
5470
#else
55-
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
71+
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
5672
const char __fsym_##cmd##_name[] rt_section(".rodata.name") = #cmd; \
5773
const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc; \
5874
rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
5975
{ \
6076
__fsym_##cmd##_name, \
61-
__fsym_##cmd##_desc, \
77+
FINSH_DESC(cmd, desc) \
78+
FINSH_COND(opt) \
6279
(syscall_func)&name \
6380
};
6481

65-
#endif
66-
#else
67-
#ifdef _MSC_VER
68-
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
69-
const char __fsym_##cmd##_name[] = #cmd; \
70-
__declspec(allocate("FSymTab$f")) \
71-
const struct finsh_syscall __fsym_##cmd = \
72-
{ \
73-
__fsym_##cmd##_name, \
74-
(syscall_func)&name \
75-
};
76-
#pragma comment(linker, "/merge:FSymTab=mytext")
82+
#endif /* _MSC_VER */
83+
#endif /* end of FINSH_USING_SYMTAB */
7784

78-
#elif defined(__TI_COMPILER_VERSION__)
79-
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
80-
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
81-
const char __fsym_##cmd##_name[] = #cmd; \
82-
const struct finsh_syscall __fsym_##cmd = \
83-
{ \
84-
__fsym_##cmd##_name, \
85-
(syscall_func)&name \
86-
};
8785

88-
#else
89-
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
90-
const char __fsym_##cmd##_name[] = #cmd; \
91-
rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
92-
{ \
93-
__fsym_##cmd##_name, \
94-
(syscall_func)&name \
95-
};
86+
#define __MSH_GET_MACRO(_1, _2, _3, _FUN, ...) _FUN
87+
#define __MSH_GET_EXPORT_MACRO(_1, _2, _3, _4, _FUN, ...) _FUN
9688

97-
#endif
98-
#endif /* end of FINSH_USING_DESCRIPTION */
99-
#endif /* end of FINSH_USING_SYMTAB */
89+
#define _MSH_FUNCTION_CMD2(a0, a1) \
90+
MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0)
91+
92+
#define _MSH_FUNCTION_CMD3_OPT(a0, a1, a2) \
93+
MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, a0##_msh_options)
94+
95+
#define _MSH_FUNCTION_CMD3_NO_OPT(a0, a1, a2) \
96+
MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0)
97+
98+
#define _MSH_FUNCTION_EXPORT_CMD3(a0, a1, a2) \
99+
MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0)
100+
101+
#define _MSH_FUNCTION_EXPORT_CMD4_OPT(a0, a1, a2, a3) \
102+
MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, a0##_msh_options)
103+
104+
#define _MSH_FUNCTION_EXPORT_CMD4_NO_OPT(a0, a1, a2, a3) \
105+
MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0)
100106

101107
/**
102108
* @ingroup finsh
@@ -126,9 +132,18 @@ typedef long (*syscall_func)(void);
126132
*
127133
* @param command is the name of the command.
128134
* @param desc is the description of the command, which will show in help list.
135+
* @param opt This is an option, enter any content to enable option completion
129136
*/
130-
#define MSH_CMD_EXPORT(command, desc) \
131-
MSH_FUNCTION_EXPORT_CMD(command, command, desc)
137+
/* MSH_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */
138+
#ifdef FINSH_USING_OPTION_COMPLETION
139+
#define MSH_CMD_EXPORT(...) \
140+
__MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3_OPT, \
141+
_MSH_FUNCTION_CMD2)(__VA_ARGS__)
142+
#else
143+
#define MSH_CMD_EXPORT(...) \
144+
__MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3_NO_OPT, \
145+
_MSH_FUNCTION_CMD2)(__VA_ARGS__)
146+
#endif /* FINSH_USING_OPTION_COMPLETION */
132147

133148
/**
134149
* @ingroup msh
@@ -138,9 +153,19 @@ typedef long (*syscall_func)(void);
138153
* @param command is the name of the command.
139154
* @param alias is the alias of the command.
140155
* @param desc is the description of the command, which will show in help list.
156+
* @param opt This is an option, enter any content to enable option completion
141157
*/
142-
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
143-
MSH_FUNCTION_EXPORT_CMD(command, alias, desc)
158+
/* #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) or
159+
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) */
160+
#ifdef FINSH_USING_OPTION_COMPLETION
161+
#define MSH_CMD_EXPORT_ALIAS(...) \
162+
__MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4_OPT, \
163+
_MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__)
164+
#else
165+
#define MSH_CMD_EXPORT_ALIAS(...) \
166+
__MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4_NO_OPT, \
167+
_MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__)
168+
#endif /* FINSH_USING_OPTION_COMPLETION */
144169

145170
/* system call table */
146171
struct finsh_syscall
@@ -149,6 +174,10 @@ struct finsh_syscall
149174
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
150175
const char *desc; /* description of system call */
151176
#endif
177+
178+
#ifdef FINSH_USING_OPTION_COMPLETION
179+
struct msh_cmd_opt *opt;
180+
#endif
152181
syscall_func func; /* the function address of system call */
153182
};
154183

@@ -159,6 +188,31 @@ struct finsh_syscall_item
159188
struct finsh_syscall syscall; /* syscall */
160189
};
161190

191+
#ifdef FINSH_USING_OPTION_COMPLETION
192+
typedef struct msh_cmd_opt
193+
{
194+
rt_uint32_t id;
195+
const char *name;
196+
const char *des;
197+
} msh_cmd_opt_t;
198+
199+
#define CMD_OPTIONS_STATEMENT(command) static struct msh_cmd_opt command##_msh_options[];
200+
#define CMD_OPTIONS_NODE_START(command) static struct msh_cmd_opt command##_msh_options[] = {
201+
#define CMD_OPTIONS_NODE(_id, _name, _des) {.id = _id, .name = #_name, .des = #_des},
202+
#define CMD_OPTIONS_NODE_END {0},};
203+
204+
void msh_opt_list_dump(void *options);
205+
int msh_cmd_opt_id_get(int argc, char *argv[], void *options);
206+
#define MSH_OPT_ID_GET(fun) msh_cmd_opt_id_get(argc, argv, (void*) fun##_msh_options)
207+
#define MSH_OPT_DUMP(fun) msh_opt_list_dump((void*) fun##_msh_options)
208+
209+
#else
210+
#define CMD_OPTIONS_STATEMENT(command)
211+
#define CMD_OPTIONS_NODE_START(command)
212+
#define CMD_OPTIONS_NODE(_id, _name, _des)
213+
#define CMD_OPTIONS_NODE_END
214+
#endif
215+
162216
extern struct finsh_syscall_item *global_syscall_list;
163217
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
164218

0 commit comments

Comments
 (0)