lineedit: use strncmp instead of is_prefixed_with (we know the length)

Also: add comments, rename some variables

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2020-12-16 10:59:20 +01:00
parent eaced1ec85
commit 1d180cd749

View File

@ -736,9 +736,9 @@ enum {
FIND_FILE_ONLY = 2, FIND_FILE_ONLY = 2,
}; };
static int path_parse(char ***p) static unsigned path_parse(char ***p)
{ {
int npth; unsigned npth;
const char *pth; const char *pth;
char *tmp; char *tmp;
char **res; char **res;
@ -755,7 +755,7 @@ static int path_parse(char ***p)
return 1; return 1;
tmp = (char*)pth; tmp = (char*)pth;
npth = 2; /* path component count */ npth = 1; /* path component count */
while (1) { while (1) {
tmp = strchr(tmp, ':'); tmp = strchr(tmp, ':');
if (!tmp) if (!tmp)
@ -766,7 +766,7 @@ static int path_parse(char ***p)
npth++; npth++;
} }
*p = res = xmalloc(npth * sizeof(res[0])); *p = res = xzalloc((npth + 1) * sizeof(res[0]));
res[0] = tmp = xstrdup(pth); res[0] = tmp = xstrdup(pth);
npth = 1; npth = 1;
while (1) { while (1) {
@ -778,8 +778,8 @@ static int path_parse(char ***p)
break; /* :<empty> */ break; /* :<empty> */
res[npth++] = tmp; res[npth++] = tmp;
} }
/* special case: match subdirectories of the current directory */ /* special case: "match subdirectories of the current directory" */
res[npth++] = NULL; /*res[npth++] = NULL; - filled by xzalloc() */
return npth; return npth;
} }
@ -790,38 +790,38 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
{ {
char *path1[1]; char *path1[1];
char **paths = path1; char **paths = path1;
int npaths; unsigned npaths;
int i; unsigned i;
unsigned pf_len; unsigned baselen;
const char *pfind; const char *basecmd;
char *dirbuf = NULL; char *dirbuf = NULL;
npaths = 1; npaths = 1;
path1[0] = (char*)"."; path1[0] = (char*)".";
pfind = strrchr(command, '/'); basecmd = strrchr(command, '/');
if (!pfind) { if (!basecmd) {
if (type == FIND_EXE_ONLY) if (type == FIND_EXE_ONLY)
npaths = path_parse(&paths); npaths = path_parse(&paths);
pfind = command; basecmd = command;
} else { } else {
/* point to 'l' in "..../last_component" */ /* point to 'l' in "..../last_component" */
pfind++; basecmd++;
/* dirbuf = ".../.../.../" */ /* dirbuf = ".../.../.../" */
dirbuf = xstrndup(command, pfind - command); dirbuf = xstrndup(command, basecmd - command);
# if ENABLE_FEATURE_USERNAME_COMPLETION # if ENABLE_FEATURE_USERNAME_COMPLETION
if (dirbuf[0] == '~') /* ~/... or ~user/... */ if (dirbuf[0] == '~') /* ~/... or ~user/... */
dirbuf = username_path_completion(dirbuf); dirbuf = username_path_completion(dirbuf);
# endif # endif
path1[0] = dirbuf; path1[0] = dirbuf;
} }
pf_len = strlen(pfind); baselen = strlen(basecmd);
if (type == FIND_EXE_ONLY && !dirbuf) { if (type == FIND_EXE_ONLY && !dirbuf) {
# if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 # if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
const char *p = applet_names; const char *p = applet_names;
while (*p) { while (*p) {
if (strncmp(pfind, p, pf_len) == 0) if (strncmp(basecmd, p, baselen) == 0)
add_match(xstrdup(p)); add_match(xstrdup(p));
while (*p++ != '\0') while (*p++ != '\0')
continue; continue;
@ -834,7 +834,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
const char *b = state->get_exe_name(i++); const char *b = state->get_exe_name(i++);
if (!b) if (!b)
break; break;
if (strncmp(pfind, b, pf_len) == 0) if (strncmp(basecmd, b, baselen) == 0)
add_match(xstrdup(b)); add_match(xstrdup(b));
} }
} }
@ -847,7 +847,10 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
struct stat st; struct stat st;
char *found; char *found;
if (paths[i] == NULL) { if (paths[i] == NULL) { /* path_parse()'s last component? */
/* in PATH completion, current dir's subdir names
* can be completions (but only subdirs, not files).
*/
type = FIND_DIR_ONLY; type = FIND_DIR_ONLY;
paths[i] = (char *)"."; paths[i] = (char *)".";
} }
@ -861,10 +864,10 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
const char *name_found = next->d_name; const char *name_found = next->d_name;
/* .../<tab>: bash 3.2.0 shows dotfiles, but not . and .. */ /* .../<tab>: bash 3.2.0 shows dotfiles, but not . and .. */
if (!pfind[0] && DOT_OR_DOTDOT(name_found)) if (!basecmd[0] && DOT_OR_DOTDOT(name_found))
continue; continue;
/* match? */ /* match? */
if (!is_prefixed_with(name_found, pfind)) if (strncmp(basecmd, name_found, baselen) != 0)
continue; /* no */ continue; /* no */
found = concat_path_file(paths[i], name_found); found = concat_path_file(paths[i], name_found);
@ -906,7 +909,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
} }
free(dirbuf); free(dirbuf);
return pf_len; return baselen;
} }
/* build_match_prefix: /* build_match_prefix: