Commit 560d424b6d7cd4205b062ad95f1b104bd4f8bcc3

Authored by Mike Frysinger
Committed by Wolfgang Denk
1 parent 42df1e1618

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>

Showing 6 changed files with 50 additions and 27 deletions Side-by-side Diff

... ... @@ -162,7 +162,6 @@
162 162  
163 163 int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[])
164 164 {
165   -#if 0 /* need to reimplement */
166 165 static char tmp_buf[512];
167 166 int space;
168 167  
... ... @@ -173,7 +172,7 @@
173 172  
174 173 if (!space && argc == 2)
175 174 return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf);
176   -#endif
  175 +
177 176 return 0;
178 177 }
179 178  
... ... @@ -246,42 +246,32 @@
246 246 }
247 247 }
248 248  
249   -#if 0 /* need to reimplement - def CONFIG_AUTO_COMPLETE */
  249 +#ifdef CONFIG_AUTO_COMPLETE
250 250 int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
251 251 {
252   - int i, nxt, len, vallen, found;
253   - const char *lval, *rval;
  252 + ENTRY *match;
  253 + int found, idx;
254 254  
  255 + idx = 0;
255 256 found = 0;
256 257 cmdv[0] = NULL;
257 258  
258   - len = strlen(var);
259   - /* now iterate over the variables and select those that match */
260   - for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
  259 + while ((idx = hmatch_r(var, idx, &match, &env_htab))) {
  260 + int vallen = strlen(match->key) + 1;
261 261  
262   - for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
263   - ;
264   -
265   - lval = (char *)env_get_addr(i);
266   - rval = strchr(lval, '=');
267   - if (rval != NULL) {
268   - vallen = rval - lval;
269   - rval++;
270   - } else
271   - vallen = strlen(lval);
272   -
273   - if (len > 0 && (vallen < len || memcmp(lval, var, len) != 0))
274   - continue;
275   -
276   - if (found >= maxv - 2 || bufsz < vallen + 1) {
277   - cmdv[found++] = "...";
  262 + if (found >= maxv - 2 || bufsz < vallen)
278 263 break;
279   - }
  264 +
280 265 cmdv[found++] = buf;
281   - memcpy(buf, lval, vallen); buf += vallen; bufsz -= vallen;
282   - *buf++ = '\0'; bufsz--;
  266 + memcpy(buf, match->key, vallen);
  267 + buf += vallen;
  268 + bufsz -= vallen;
283 269 }
284 270  
  271 + qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar);
  272 +
  273 + if (idx)
  274 + cmdv[found++] = "...";
285 275 cmdv[found] = NULL;
286 276 return found;
287 277 }
... ... @@ -632,6 +632,7 @@
632 632 /* lib/qsort.c */
633 633 void qsort(void *base, size_t nmemb, size_t size,
634 634 int(*compar)(const void *, const void *));
  635 +int strcmp_compar(const void *, const void *);
635 636  
636 637 /* lib/time.c */
637 638 void udelay (unsigned long);
... ... @@ -74,6 +74,13 @@
74 74 extern int hsearch_r(ENTRY __item, ACTION __action, ENTRY ** __retval,
75 75 struct hsearch_data *__htab);
76 76  
  77 +/*
  78 + * Search for an entry matching `MATCH'. Otherwise, Same semantics
  79 + * as hsearch_r().
  80 + */
  81 +extern int hmatch_r(const char *__match, int __last_idx, ENTRY ** __retval,
  82 + struct hsearch_data *__htab);
  83 +
77 84 /* Search and delete entry matching ITEM.key in internal hash table. */
78 85 extern int hdelete_r(const char *__key, struct hsearch_data *__htab);
79 86  
... ... @@ -202,6 +202,26 @@
202 202 * example for functions like hdelete().
203 203 */
204 204  
  205 +int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
  206 + struct hsearch_data *htab)
  207 +{
  208 + unsigned int idx;
  209 + size_t key_len = strlen(match);
  210 +
  211 + for (idx = last_idx + 1; idx < htab->size; ++idx) {
  212 + if (!htab->table[idx].used)
  213 + continue;
  214 + if (!strncmp(match, htab->table[idx].entry.key, key_len)) {
  215 + *retval = &htab->table[idx].entry;
  216 + return idx;
  217 + }
  218 + }
  219 +
  220 + __set_errno(ESRCH);
  221 + *retval = NULL;
  222 + return 0;
  223 +}
  224 +
205 225 int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
206 226 struct hsearch_data *htab)
207 227 {
... ... @@ -16,6 +16,7 @@
16 16 * bcc and gcc. */
17 17  
18 18 #include <linux/types.h>
  19 +#include <exports.h>
19 20 #if 0
20 21 #include <assert.h>
21 22 #else
... ... @@ -66,5 +67,10 @@
66 67 wgap = (wgap - width)/3;
67 68 } while (wgap);
68 69 }
  70 +}
  71 +
  72 +int strcmp_compar(const void *p1, const void *p2)
  73 +{
  74 + return strcmp(*(const char **)p1, *(const char **)p2);
69 75 }