diff options
| author | Mike Frysinger <vapier@gentoo.org> | 2010-12-17 16:51:59 -0500 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2011-01-09 17:57:37 +0100 | 
| commit | 560d424b6d7cd4205b062ad95f1b104bd4f8bcc3 (patch) | |
| tree | 5a429e36ad18a8fa2e0b026d143c38d7f3d493af | |
| parent | 42df1e1618f2bcae308ad193a136b72b82103bea (diff) | |
| download | olio-uboot-2014.01-560d424b6d7cd4205b062ad95f1b104bd4f8bcc3.tar.xz olio-uboot-2014.01-560d424b6d7cd4205b062ad95f1b104bd4f8bcc3.zip | |
env: re-add support for auto-completion
Currently, only basic completion is supported (no globs), but this is
what we had previously.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
| -rw-r--r-- | common/command.c | 3 | ||||
| -rw-r--r-- | common/env_common.c | 40 | ||||
| -rw-r--r-- | include/common.h | 1 | ||||
| -rw-r--r-- | include/search.h | 7 | ||||
| -rw-r--r-- | lib/hashtable.c | 20 | ||||
| -rw-r--r-- | lib/qsort.c | 6 | 
6 files changed, 50 insertions, 27 deletions
| diff --git a/common/command.c b/common/command.c index ef4a08110..b3ec510a2 100644 --- a/common/command.c +++ b/common/command.c @@ -162,7 +162,6 @@ int cmd_usage(cmd_tbl_t *cmdtp)  int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[])  { -#if 0 /* need to reimplement */  	static char tmp_buf[512];  	int space; @@ -173,7 +172,7 @@ int var_complete(int argc, char * const argv[], char last_char, int maxv, char *  	if (!space && argc == 2)  		return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf); -#endif +  	return 0;  } diff --git a/common/env_common.c b/common/env_common.c index ae710e5e6..c3e6388ac 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -246,42 +246,32 @@ void env_relocate (void)  	}  } -#if 0 /* need to reimplement - def CONFIG_AUTO_COMPLETE */ +#ifdef CONFIG_AUTO_COMPLETE  int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)  { -	int i, nxt, len, vallen, found; -	const char *lval, *rval; +	ENTRY *match; +	int found, idx; +	idx = 0;  	found = 0;  	cmdv[0] = NULL; -	len = strlen(var); -	/* now iterate over the variables and select those that match */ -	for (i=0; env_get_char(i) != '\0'; i=nxt+1) { +	while ((idx = hmatch_r(var, idx, &match, &env_htab))) { +		int vallen = strlen(match->key) + 1; -		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) -			; - -		lval = (char *)env_get_addr(i); -		rval = strchr(lval, '='); -		if (rval != NULL) { -			vallen = rval - lval; -			rval++; -		} else -			vallen = strlen(lval); - -		if (len > 0 && (vallen < len || memcmp(lval, var, len) != 0)) -			continue; - -		if (found >= maxv - 2 || bufsz < vallen + 1) { -			cmdv[found++] = "..."; +		if (found >= maxv - 2 || bufsz < vallen)  			break; -		} +  		cmdv[found++] = buf; -		memcpy(buf, lval, vallen); buf += vallen; bufsz -= vallen; -		*buf++ = '\0'; bufsz--; +		memcpy(buf, match->key, vallen); +		buf += vallen; +		bufsz -= vallen;  	} +	qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar); + +	if (idx) +		cmdv[found++] = "...";  	cmdv[found] = NULL;  	return found;  } diff --git a/include/common.h b/include/common.h index 0d1c8724a..d8c912d09 100644 --- a/include/common.h +++ b/include/common.h @@ -632,6 +632,7 @@ static inline IPaddr_t getenv_IPaddr (char *var)  /* lib/qsort.c */  void qsort(void *base, size_t nmemb, size_t size,  	   int(*compar)(const void *, const void *)); +int strcmp_compar(const void *, const void *);  /* lib/time.c */  void	udelay        (unsigned long); diff --git a/include/search.h b/include/search.h index 81ced7f48..a7c129377 100644 --- a/include/search.h +++ b/include/search.h @@ -74,6 +74,13 @@ extern void hdestroy_r(struct hsearch_data *__htab);  extern int hsearch_r(ENTRY __item, ACTION __action, ENTRY ** __retval,  		     struct hsearch_data *__htab); +/* + * Search for an entry matching `MATCH'.  Otherwise, Same semantics + * as hsearch_r(). + */ +extern int hmatch_r(const char *__match, int __last_idx, ENTRY ** __retval, +		    struct hsearch_data *__htab); +  /* Search and delete entry matching ITEM.key in internal hash table. */  extern int hdelete_r(const char *__key, struct hsearch_data *__htab); diff --git a/lib/hashtable.c b/lib/hashtable.c index b47f3b69b..9f069c076 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -202,6 +202,26 @@ void hdestroy_r(struct hsearch_data *htab)   *   example for functions like hdelete().   */ +int hmatch_r(const char *match, int last_idx, ENTRY ** retval, +	     struct hsearch_data *htab) +{ +	unsigned int idx; +	size_t key_len = strlen(match); + +	for (idx = last_idx + 1; idx < htab->size; ++idx) { +		if (!htab->table[idx].used) +			continue; +		if (!strncmp(match, htab->table[idx].entry.key, key_len)) { +			*retval = &htab->table[idx].entry; +			return idx; +		} +	} + +	__set_errno(ESRCH); +	*retval = NULL; +	return 0; +} +  int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,  	      struct hsearch_data *htab)  { diff --git a/lib/qsort.c b/lib/qsort.c index e771dcfcf..1cc0d31c9 100644 --- a/lib/qsort.c +++ b/lib/qsort.c @@ -16,6 +16,7 @@   * bcc and gcc. */  #include <linux/types.h> +#include <exports.h>  #if 0  #include <assert.h>  #else @@ -67,3 +68,8 @@ void qsort(void  *base,  		} while (wgap);  	}  } + +int strcmp_compar(const void *p1, const void *p2) +{ +	return strcmp(*(const char **)p1, *(const char **)p2); +} |