【msh】新增msh自动补全子选项特性 (#8086)
This commit is contained in:
parent
d8a2084c05
commit
2d630e38d7
|
@ -76,4 +76,8 @@ if RT_USING_MSH
|
||||||
int "The number of arguments for a shell command"
|
int "The number of arguments for a shell command"
|
||||||
default 10
|
default 10
|
||||||
|
|
||||||
|
config FINSH_USING_OPTION_COMPLETION
|
||||||
|
bool "command option completion enable"
|
||||||
|
default y
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#ifdef RT_USING_FINSH
|
#ifdef RT_USING_FINSH
|
||||||
#include <finsh.h>
|
#include <finsh.h>
|
||||||
|
|
||||||
|
#define LIST_DFS_OPT_ID 0x100
|
||||||
#define LIST_FIND_OBJ_NR 8
|
#define LIST_FIND_OBJ_NR 8
|
||||||
|
|
||||||
static long clear(void)
|
static long clear(void)
|
||||||
|
@ -903,6 +904,7 @@ long list_device(void)
|
||||||
}
|
}
|
||||||
#endif /* RT_USING_DEVICE */
|
#endif /* RT_USING_DEVICE */
|
||||||
|
|
||||||
|
#ifndef FINSH_USING_OPTION_COMPLETION
|
||||||
int cmd_list(int argc, char **argv)
|
int cmd_list(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if(argc == 2)
|
if(argc == 2)
|
||||||
|
@ -1013,6 +1015,95 @@ _usage:
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
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 LIST_DFS_OPT_ID:
|
||||||
|
{
|
||||||
|
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(LIST_DFS_OPT_ID, fd, list file descriptors)
|
||||||
|
#endif /* RT_USING_DFS */
|
||||||
|
CMD_OPTIONS_NODE_END
|
||||||
|
#endif /* FINSH_USING_OPTION_COMPLETION */
|
||||||
|
MSH_CMD_EXPORT_ALIAS(cmd_list, list, list objects, optenable);
|
||||||
|
|
||||||
#endif /* RT_USING_FINSH */
|
#endif /* RT_USING_FINSH */
|
||||||
|
|
|
@ -16,21 +16,35 @@
|
||||||
#pragma section("FSymTab$f",read)
|
#pragma section("FSymTab$f",read)
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
#define FINSH_COND(opt) opt,
|
||||||
|
#else
|
||||||
|
#define FINSH_COND(opt)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_DESCRIPTION
|
||||||
|
#define FINSH_DESC(cmd, desc) __fsym_##cmd##_desc,
|
||||||
|
#else
|
||||||
|
#define FINSH_DESC(cmd, desc)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef long (*syscall_func)(void);
|
typedef long (*syscall_func)(void);
|
||||||
#ifdef FINSH_USING_SYMTAB
|
#ifdef FINSH_USING_SYMTAB
|
||||||
|
|
||||||
#ifdef __TI_COMPILER_VERSION__
|
#ifdef __TI_COMPILER_VERSION__
|
||||||
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
|
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
|
||||||
#endif /* __TI_COMPILER_VERSION__ */
|
#endif /* __TI_COMPILER_VERSION__ */
|
||||||
#ifdef FINSH_USING_DESCRIPTION
|
|
||||||
#ifdef _MSC_VER
|
#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##_name[] = #cmd; \
|
||||||
const char __fsym_##cmd##_desc[] = #desc; \
|
const char __fsym_##cmd##_desc[] = #desc; \
|
||||||
__declspec(allocate("FSymTab$f")) \
|
__declspec(allocate("FSymTab$f")) \
|
||||||
const struct finsh_syscall __fsym_##cmd = \
|
const struct finsh_syscall __fsym_##cmd = \
|
||||||
{ \
|
{ \
|
||||||
__fsym_##cmd##_name, \
|
__fsym_##cmd##_name, \
|
||||||
__fsym_##cmd##_desc, \
|
FINSH_DESC(cmd, desc) \
|
||||||
|
FINSH_COND(opt) \
|
||||||
(syscall_func)&name \
|
(syscall_func)&name \
|
||||||
};
|
};
|
||||||
#pragma comment(linker, "/merge:FSymTab=mytext")
|
#pragma comment(linker, "/merge:FSymTab=mytext")
|
||||||
|
@ -41,63 +55,55 @@ typedef long (*syscall_func)(void);
|
||||||
#else
|
#else
|
||||||
#define RT_NOBLOCKED
|
#define RT_NOBLOCKED
|
||||||
#endif
|
#endif
|
||||||
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
|
||||||
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
|
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
|
||||||
const char __fsym_##cmd##_name[] = #cmd; \
|
const char __fsym_##cmd##_name[] = #cmd; \
|
||||||
const char __fsym_##cmd##_desc[] = #desc; \
|
const char __fsym_##cmd##_desc[] = #desc; \
|
||||||
rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \
|
rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \
|
||||||
{ \
|
{ \
|
||||||
__fsym_##cmd##_name, \
|
__fsym_##cmd##_name, \
|
||||||
__fsym_##cmd##_desc, \
|
FINSH_DESC(cmd, desc) \
|
||||||
|
FINSH_COND(opt) \
|
||||||
(syscall_func)&name \
|
(syscall_func)&name \
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#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##_name[] rt_section(".rodata.name") = #cmd; \
|
||||||
const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc; \
|
const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc; \
|
||||||
rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
|
rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
|
||||||
{ \
|
{ \
|
||||||
__fsym_##cmd##_name, \
|
__fsym_##cmd##_name, \
|
||||||
__fsym_##cmd##_desc, \
|
FINSH_DESC(cmd, desc) \
|
||||||
|
FINSH_COND(opt) \
|
||||||
(syscall_func)&name \
|
(syscall_func)&name \
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif /* _MSC_VER */
|
||||||
#else
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
|
||||||
const char __fsym_##cmd##_name[] = #cmd; \
|
|
||||||
__declspec(allocate("FSymTab$f")) \
|
|
||||||
const struct finsh_syscall __fsym_##cmd = \
|
|
||||||
{ \
|
|
||||||
__fsym_##cmd##_name, \
|
|
||||||
(syscall_func)&name \
|
|
||||||
};
|
|
||||||
#pragma comment(linker, "/merge:FSymTab=mytext")
|
|
||||||
|
|
||||||
#elif defined(__TI_COMPILER_VERSION__)
|
|
||||||
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
|
||||||
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
|
|
||||||
const char __fsym_##cmd##_name[] = #cmd; \
|
|
||||||
const struct finsh_syscall __fsym_##cmd = \
|
|
||||||
{ \
|
|
||||||
__fsym_##cmd##_name, \
|
|
||||||
(syscall_func)&name \
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
|
|
||||||
const char __fsym_##cmd##_name[] = #cmd; \
|
|
||||||
rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
|
|
||||||
{ \
|
|
||||||
__fsym_##cmd##_name, \
|
|
||||||
(syscall_func)&name \
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif /* end of FINSH_USING_DESCRIPTION */
|
|
||||||
#endif /* end of FINSH_USING_SYMTAB */
|
#endif /* end of FINSH_USING_SYMTAB */
|
||||||
|
|
||||||
|
|
||||||
|
#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_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_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
|
* @ingroup finsh
|
||||||
*
|
*
|
||||||
|
@ -126,9 +132,18 @@ typedef long (*syscall_func)(void);
|
||||||
*
|
*
|
||||||
* @param command is the name of the command.
|
* @param command is the name of the command.
|
||||||
* @param desc is the description of the command, which will show in help list.
|
* @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_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */
|
||||||
MSH_FUNCTION_EXPORT_CMD(command, command, desc)
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
#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_USING_OPTION_COMPLETION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup msh
|
* @ingroup msh
|
||||||
|
@ -138,9 +153,19 @@ typedef long (*syscall_func)(void);
|
||||||
* @param command is the name of the command.
|
* @param command is the name of the command.
|
||||||
* @param alias is the alias 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 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) \
|
/* #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) or
|
||||||
MSH_FUNCTION_EXPORT_CMD(command, alias, desc)
|
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) */
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
#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_USING_OPTION_COMPLETION */
|
||||||
|
|
||||||
/* system call table */
|
/* system call table */
|
||||||
struct finsh_syscall
|
struct finsh_syscall
|
||||||
|
@ -149,6 +174,10 @@ struct finsh_syscall
|
||||||
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
|
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
|
||||||
const char *desc; /* description of system call */
|
const char *desc; /* description of system call */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
struct msh_cmd_opt *opt;
|
||||||
|
#endif
|
||||||
syscall_func func; /* the function address of system call */
|
syscall_func func; /* the function address of system call */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +188,31 @@ struct finsh_syscall_item
|
||||||
struct finsh_syscall syscall; /* syscall */
|
struct finsh_syscall syscall; /* syscall */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
typedef struct msh_cmd_opt
|
||||||
|
{
|
||||||
|
rt_uint32_t id;
|
||||||
|
const char *name;
|
||||||
|
const char *des;
|
||||||
|
} msh_cmd_opt_t;
|
||||||
|
|
||||||
|
#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},};
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
#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_item *global_syscall_list;
|
||||||
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
|
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
|
||||||
|
|
||||||
|
|
|
@ -789,4 +789,162 @@ void msh_auto_complete(char *prefix)
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
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;
|
||||||
|
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 /* FINSH_USING_OPTION_COMPLETION */
|
||||||
#endif /* RT_USING_FINSH */
|
#endif /* RT_USING_FINSH */
|
||||||
|
|
|
@ -19,4 +19,8 @@ void msh_auto_complete(char *prefix);
|
||||||
int msh_exec_module(const char *cmd_line, int size);
|
int msh_exec_module(const char *cmd_line, int size);
|
||||||
int msh_exec_script(const char *cmd_line, int size);
|
int msh_exec_script(const char *cmd_line, int size);
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
void msh_opt_auto_complete(char *prefix);
|
||||||
|
|
||||||
|
#endif /* FINSH_USING_OPTION_COMPLETION */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -381,6 +381,10 @@ static void shell_auto_complete(char *prefix)
|
||||||
rt_kprintf("\n");
|
rt_kprintf("\n");
|
||||||
msh_auto_complete(prefix);
|
msh_auto_complete(prefix);
|
||||||
|
|
||||||
|
#ifdef FINSH_USING_OPTION_COMPLETION
|
||||||
|
msh_opt_auto_complete(prefix);
|
||||||
|
#endif
|
||||||
|
|
||||||
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
|
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue