diff options
author | Barton E. Schaefer <schaefer@zsh.org> | 2015-10-04 14:01:08 -0700 |
---|---|---|
committer | Barton E. Schaefer <schaefer@zsh.org> | 2015-10-04 14:01:08 -0700 |
commit | 3f9606333578384221948e285ed896738071b253 (patch) | |
tree | 17fc54b3992a66560bee4a2b8bfb4dc813e7d012 /Src | |
parent | cb26e11c70f95c72e300e1f4f16b33e4e5f54d21 (diff) | |
download | zsh-3f9606333578384221948e285ed896738071b253.tar.gz zsh-3f9606333578384221948e285ed896738071b253.tar.xz zsh-3f9606333578384221948e285ed896738071b253.zip |
36773: limit CORRECT / CORRECT_ALL to directory names in cases where it is obvious that a directory is expected
Diffstat (limited to 'Src')
-rw-r--r-- | Src/utils.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/Src/utils.c b/Src/utils.c index ab3b0c274..61cbe84aa 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2812,7 +2812,7 @@ spckword(char **s, int hist, int cmd, int ask) * as used in spscan(), so that an autocd is chosen * * only when it is better than anything so far, and * * so we prefer directories earlier in the cdpath. */ - if ((thisdist = mindist(*pp, *s, bestcd)) < d) { + if ((thisdist = mindist(*pp, *s, bestcd, 1)) < d) { best = dupstring(bestcd); d = thisdist; } @@ -4057,7 +4057,8 @@ spname(char *oldname) thresh = 3; else if (thresh > 100) thresh = 100; - if ((thisdist = mindist(newname, spnameguess, spnamebest)) >= thresh) { + thisdist = mindist(newname, spnameguess, spnamebest, *old == '/'); + if (thisdist >= thresh) { /* The next test is always true, except for the first path * * component. We could initialize bestdist to some large * * constant instead, and then compare to that constant here, * @@ -4082,42 +4083,52 @@ spname(char *oldname) /**/ static int -mindist(char *dir, char *mindistguess, char *mindistbest) +mindist(char *dir, char *mindistguess, char *mindistbest, int wantdir) { int mindistd, nd; DIR *dd; char *fn; char *buf; + struct stat st; + size_t dirlen; if (dir[0] == '\0') dir = "."; mindistd = 100; - buf = zalloc(strlen(dir) + strlen(mindistguess) + 2); + if (!(buf = zalloc((dirlen = strlen(dir)) + strlen(mindistguess) + 2))) + return 0; sprintf(buf, "%s/%s", dir, mindistguess); - if (access(unmeta(buf), F_OK) == 0) { + if (stat(unmeta(buf), &st) == 0 && (!wantdir || S_ISDIR(st.st_mode))) { strcpy(mindistbest, mindistguess); free(buf); return 0; } - free(buf); - if (!(dd = opendir(unmeta(dir)))) - return mindistd; - while ((fn = zreaddir(dd, 0))) { - if (spnamepat && pattry(spnamepat, fn)) - continue; - nd = spdist(fn, mindistguess, - (int)strlen(mindistguess) / 4 + 1); - if (nd <= mindistd) { - strcpy(mindistbest, fn); - mindistd = nd; - if (mindistd == 0) - break; + if ((dd = opendir(unmeta(dir)))) { + while ((fn = zreaddir(dd, 0))) { + if (spnamepat && pattry(spnamepat, fn)) + continue; + nd = spdist(fn, mindistguess, + (int)strlen(mindistguess) / 4 + 1); + if (nd <= mindistd) { + if (wantdir) { + if (!(buf = zrealloc(buf, dirlen + strlen(fn) + 2))) + continue; + sprintf(buf, "%s/%s", dir, fn); + if (stat(unmeta(buf), &st) != 0 || !S_ISDIR(st.st_mode)) + continue; + } + strcpy(mindistbest, fn); + mindistd = nd; + if (mindistd == 0) + break; + } } + closedir(dd); } - closedir(dd); + free(buf); return mindistd; } |