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+
1931typedef 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 */
146171struct 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+
162216extern struct finsh_syscall_item * global_syscall_list ;
163217extern struct finsh_syscall * _syscall_table_begin , * _syscall_table_end ;
164218
0 commit comments