mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
common: command: Add support for $ auto-completion
Add the dollar_complete() function to auto-complete arguments starting with a '$' and use it in the cmd_auto_complete() path such that all args starting with a $ can be auto-completed based on the available env vars. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> [trini: Fix some linking problems] Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
parent
31a2cf1ca4
commit
03dcf17dba
4 changed files with 77 additions and 13 deletions
|
@ -142,23 +142,38 @@ int cmd_usage(const cmd_tbl_t *cmdtp)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_AUTO_COMPLETE
|
||||
static char env_complete_buf[512];
|
||||
|
||||
int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[])
|
||||
{
|
||||
static char tmp_buf[512];
|
||||
int space;
|
||||
|
||||
space = last_char == '\0' || isblank(last_char);
|
||||
|
||||
if (space && argc == 1)
|
||||
return env_complete("", maxv, cmdv, sizeof(tmp_buf), tmp_buf);
|
||||
return env_complete("", maxv, cmdv, sizeof(env_complete_buf),
|
||||
env_complete_buf, false);
|
||||
|
||||
if (!space && argc == 2)
|
||||
return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf);
|
||||
return env_complete(argv[1], maxv, cmdv,
|
||||
sizeof(env_complete_buf),
|
||||
env_complete_buf, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dollar_complete(int argc, char * const argv[], char last_char,
|
||||
int maxv, char *cmdv[])
|
||||
{
|
||||
/* Make sure the last argument starts with a $. */
|
||||
if (argc < 1 || argv[argc - 1][0] != '$' ||
|
||||
last_char == '\0' || isblank(last_char))
|
||||
return 0;
|
||||
|
||||
return env_complete(argv[argc - 1], maxv, cmdv, sizeof(env_complete_buf),
|
||||
env_complete_buf, true);
|
||||
}
|
||||
|
||||
/*************************************************************************************/
|
||||
|
||||
int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc,
|
||||
|
@ -357,9 +372,14 @@ int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
|
|||
/* separate into argv */
|
||||
argc = make_argv(tmp_buf, sizeof(argv)/sizeof(argv[0]), argv);
|
||||
|
||||
/* do the completion and return the possible completions */
|
||||
i = complete_cmdv(argc, argv, last_char,
|
||||
sizeof(cmdv) / sizeof(cmdv[0]), cmdv);
|
||||
/* first try a $ completion */
|
||||
i = dollar_complete(argc, argv, last_char,
|
||||
sizeof(cmdv) / sizeof(cmdv[0]), cmdv);
|
||||
if (!i) {
|
||||
/* do the completion and return the possible completions */
|
||||
i = complete_cmdv(argc, argv, last_char,
|
||||
sizeof(cmdv) / sizeof(cmdv[0]), cmdv);
|
||||
}
|
||||
|
||||
/* no match; bell and out */
|
||||
if (i == 0) {
|
||||
|
|
52
env/common.c
vendored
52
env/common.c
vendored
|
@ -240,32 +240,76 @@ void env_relocate(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_AUTO_COMPLETE) && !defined(CONFIG_SPL_BUILD)
|
||||
int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
|
||||
#ifdef CONFIG_AUTO_COMPLETE
|
||||
int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf,
|
||||
bool dollar_comp)
|
||||
{
|
||||
ENTRY *match;
|
||||
int found, idx;
|
||||
|
||||
if (dollar_comp) {
|
||||
/*
|
||||
* When doing $ completion, the first character should
|
||||
* obviously be a '$'.
|
||||
*/
|
||||
if (var[0] != '$')
|
||||
return 0;
|
||||
|
||||
var++;
|
||||
|
||||
/*
|
||||
* The second one, if present, should be a '{', as some
|
||||
* configuration of the u-boot shell expand ${var} but not
|
||||
* $var.
|
||||
*/
|
||||
if (var[0] == '{')
|
||||
var++;
|
||||
else if (var[0] != '\0')
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
found = 0;
|
||||
cmdv[0] = NULL;
|
||||
|
||||
|
||||
while ((idx = hmatch_r(var, idx, &match, &env_htab))) {
|
||||
int vallen = strlen(match->key) + 1;
|
||||
|
||||
if (found >= maxv - 2 || bufsz < vallen)
|
||||
if (found >= maxv - 2 ||
|
||||
bufsz < vallen + (dollar_comp ? 3 : 0))
|
||||
break;
|
||||
|
||||
cmdv[found++] = buf;
|
||||
|
||||
/* Add the '${' prefix to each var when doing $ completion. */
|
||||
if (dollar_comp) {
|
||||
strcpy(buf, "${");
|
||||
buf += 2;
|
||||
bufsz -= 3;
|
||||
}
|
||||
|
||||
memcpy(buf, match->key, vallen);
|
||||
buf += vallen;
|
||||
bufsz -= vallen;
|
||||
|
||||
if (dollar_comp) {
|
||||
/*
|
||||
* This one is a bit odd: vallen already contains the
|
||||
* '\0' character but we need to add the '}' suffix,
|
||||
* hence the buf - 1 here. strcpy() will add the '\0'
|
||||
* character just after '}'. buf is then incremented
|
||||
* to account for the extra '}' we just added.
|
||||
*/
|
||||
strcpy(buf - 1, "}");
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar);
|
||||
|
||||
if (idx)
|
||||
cmdv[found++] = "...";
|
||||
cmdv[found++] = dollar_comp ? "${...}" : "...";
|
||||
|
||||
cmdv[found] = NULL;
|
||||
return found;
|
||||
|
|
|
@ -248,7 +248,8 @@ static inline int env_set_addr(const char *varname, const void *addr)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_AUTO_COMPLETE
|
||||
int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf);
|
||||
int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf,
|
||||
bool dollar_comp);
|
||||
#endif
|
||||
int get_env_id (void);
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ obj-y += ldiv.o
|
|||
obj-$(CONFIG_MD5) += md5.o
|
||||
obj-y += net_utils.o
|
||||
obj-$(CONFIG_PHYSMEM) += physmem.o
|
||||
obj-y += qsort.o
|
||||
obj-y += rc4.o
|
||||
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
|
||||
obj-$(CONFIG_RBTREE) += rbtree.o
|
||||
|
@ -67,7 +66,6 @@ obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o
|
|||
|
||||
obj-$(CONFIG_LIBAVB) += libavb/
|
||||
|
||||
obj-$(CONFIG_$(SPL_TPL_)SAVEENV) += qsort.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += libfdt/
|
||||
ifneq ($(CONFIG_$(SPL_TPL_)BUILD)$(CONFIG_$(SPL_TPL_)OF_PLATDATA),yy)
|
||||
obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += fdtdec_common.o
|
||||
|
@ -80,6 +78,7 @@ obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
|
|||
obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
|
||||
endif
|
||||
obj-$(CONFIG_ADDR_MAP) += addr_map.o
|
||||
obj-y += qsort.o
|
||||
obj-y += hashtable.o
|
||||
obj-y += errno.o
|
||||
obj-y += display_options.o
|
||||
|
|
Loading…
Reference in a new issue