Commit 560d424b6d7cd4205b062ad95f1b104bd4f8bcc3
Committed by
Wolfgang Denk
1 parent
42df1e1618
Exists in
master
and in
54 other branches
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
common/command.c
... | ... | @@ -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 |
common/env_common.c
... | ... | @@ -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 | } |
include/common.h
include/search.h
... | ... | @@ -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 |
lib/hashtable.c
... | ... | @@ -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 | { |
lib/qsort.c
... | ... | @@ -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 | } |