mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
sh: also auto-complete built-ins
Reported in a comment in PR 261728. Reported by: Oleg Reviewed by: jilles (previous version), bapt Differential Revision: https://reviews.freebsd.org/D39839
This commit is contained in:
parent
7a91ccd2fb
commit
14dd001235
|
@ -594,6 +594,20 @@ comparator(const void *a, const void *b, void *thunk)
|
||||||
*(char *const *)b + curpos));
|
*(char *const *)b + curpos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char
|
||||||
|
**add_match(char **matches, size_t i, size_t *size, char *match_copy)
|
||||||
|
{
|
||||||
|
if (match_copy == NULL)
|
||||||
|
return (NULL);
|
||||||
|
matches[i] = match_copy;
|
||||||
|
if (i >= *size - 1) {
|
||||||
|
*size *= 2;
|
||||||
|
matches = reallocarray(matches, *size, sizeof(matches[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (matches);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is passed to libedit's fn_complete2(). The library will use
|
* This function is passed to libedit's fn_complete2(). The library will use
|
||||||
* it instead of its standard function that finds matching files in current
|
* it instead of its standard function that finds matching files in current
|
||||||
|
@ -605,7 +619,7 @@ static char
|
||||||
{
|
{
|
||||||
char *free_path = NULL, *path;
|
char *free_path = NULL, *path;
|
||||||
const char *dirname;
|
const char *dirname;
|
||||||
char **matches = NULL;
|
char **matches = NULL, **rmatches;
|
||||||
size_t i = 0, size = 16, uniq;
|
size_t i = 0, size = 16, uniq;
|
||||||
size_t curpos = end - start, lcstring = -1;
|
size_t curpos = end - start, lcstring = -1;
|
||||||
|
|
||||||
|
@ -631,7 +645,6 @@ static char
|
||||||
}
|
}
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
char **rmatches;
|
|
||||||
|
|
||||||
if (strncmp(entry->d_name, text, curpos) != 0)
|
if (strncmp(entry->d_name, text, curpos) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -642,11 +655,8 @@ static char
|
||||||
continue;
|
continue;
|
||||||
} else if (entry->d_type != DT_REG)
|
} else if (entry->d_type != DT_REG)
|
||||||
continue;
|
continue;
|
||||||
matches[++i] = strdup(entry->d_name);
|
rmatches = add_match(matches, ++i, &size,
|
||||||
if (i < size - 1)
|
strdup(entry->d_name));
|
||||||
continue;
|
|
||||||
size *= 2;
|
|
||||||
rmatches = reallocarray(matches, size, sizeof(matches[0]));
|
|
||||||
if (rmatches == NULL) {
|
if (rmatches == NULL) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -655,6 +665,14 @@ static char
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
for (const unsigned char *bp = builtincmd; *bp != 0; bp += 2 + bp[0]) {
|
||||||
|
if (curpos > bp[0] || memcmp(bp + 2, text, curpos) != 0)
|
||||||
|
continue;
|
||||||
|
rmatches = add_match(matches, ++i, &size, strndup(bp + 2, bp[0]));
|
||||||
|
if (rmatches == NULL)
|
||||||
|
goto out;
|
||||||
|
matches = rmatches;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
free(free_path);
|
free(free_path);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
|
Loading…
Reference in a new issue