diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2022-04-11 00:17:48 +0200 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2022-04-11 00:17:48 +0200 |
commit | b09f4483416c54c1782824633dfabaf2ec0265b6 (patch) | |
tree | 304bc82642862525ae680c7fbaa249663b10ad57 /Src/glob.c | |
parent | 12eb3e5356f2fc3351eed58ef1cef1b8fb83b504 (diff) | |
parent | 6e55c920503071e917619b8cb1a188cd35d772db (diff) | |
download | zsh-b09f4483416c54c1782824633dfabaf2ec0265b6.tar.gz zsh-b09f4483416c54c1782824633dfabaf2ec0265b6.zip |
New upstream version 5.8.1.2-test
Diffstat (limited to 'Src/glob.c')
-rw-r--r-- | Src/glob.c | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/Src/glob.c b/Src/glob.c index f67a376b9..400be12d5 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -279,11 +279,11 @@ addpath(char *s, int l) * foo/ can be used to reference a non-directory foo. Returns nonzero if * * the file does not exists. */ -/**/ static int statfullpath(const char *s, struct stat *st, int l) { char buf[PATH_MAX+1]; + int check_for_being_a_directory = 0; DPUTS(strlen(s) + !*s + pathpos - pathbufcwd >= PATH_MAX, "BUG: statfullpath(): pathname too long"); @@ -294,16 +294,44 @@ statfullpath(const char *s, struct stat *st, int l) * Don't add the '.' if the path so far is empty, since * then we get bogus empty strings inserted as files. */ - buf[pathpos - pathbufcwd] = '.'; - buf[pathpos - pathbufcwd + 1] = '\0'; - l = 0; + if (st) { + buf[pathpos - pathbufcwd] = '.'; + buf[pathpos - pathbufcwd + 1] = '\0'; + l = 0; + } + else { + check_for_being_a_directory = 1; + } } unmetafy(buf, NULL); - if (!st) { + if (st) { + return l ? lstat(buf, st) : stat(buf, st); + } + else if (check_for_being_a_directory) { + struct stat tmp; + if (stat(buf, &tmp)) + return -1; + + return S_ISDIR(tmp.st_mode) ? 0 : -1; + } + else { char lbuf[1]; - return access(buf, F_OK) && (!l || readlink(buf, lbuf, 1) < 0); + + /* If it exists, signal success. */ + if (access(buf, F_OK) == 0) + return 0; + + /* Would a dangling symlink be good enough? */ + if (l == 0) + return -1; + + /* Is it a dangling symlink? */ + if (readlink(buf, lbuf, 1) >= 0) + return 0; + + /* Guess it doesn't exist, then. */ + return -1; } - return l ? lstat(buf, st) : stat(buf, st); } /* This may be set by qualifier functions to an array of strings to insert @@ -327,11 +355,13 @@ insert(char *s, int checked) if (gf_listtypes || gf_markdirs) { /* Add the type marker to the end of the filename */ mode_t mode; - checked = statted = 1; if (statfullpath(s, &buf, 1)) { unqueue_signals(); return; } + else { + checked = statted = 1; + } mode = buf.st_mode; if (gf_follow) { if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0)) @@ -387,11 +417,10 @@ insert(char *s, int checked) qn = qn->next; } } else if (!checked) { - if (statfullpath(s, &buf, 1)) { + if (statfullpath(s, NULL, 1)) { unqueue_signals(); return; } - statted = 1; news = dyncat(pathbuf, news); } else news = dyncat(pathbuf, news); @@ -2191,7 +2220,7 @@ bracechardots(char *str, convchar_t *c1p, convchar_t *c2p) #ifdef MULTIBYTE_SUPPORT cstart == WEOF || #else - !cstart || + !*pconv || #endif pnext[0] != '.' || pnext[1] != '.') return 0; @@ -2212,7 +2241,7 @@ bracechardots(char *str, convchar_t *c1p, convchar_t *c2p) #ifdef MULTIBYTE_SUPPORT cend == WEOF || #else - !cend || + !*pconv || #endif *pnext != Outbrace) return 0; @@ -2276,22 +2305,19 @@ xpandbraces(LinkList list, LinkNode *np) strp = str - str3; lenalloc = strp + strlen(str2+1) + 1; do { -#ifdef MULTIBYTE_SUPPORT char *ncptr; int nclen; +#ifdef MULTIBYTE_SUPPORT mb_charinit(); ncptr = wcs_nicechar(cend, NULL, NULL); +#else + ncptr = nicechar(cend); +#endif nclen = strlen(ncptr); p = zhalloc(lenalloc + nclen); memcpy(p, str3, strp); memcpy(p + strp, ncptr, nclen); strcpy(p + strp + nclen, str2 + 1); -#else - p = zhalloc(lenalloc + 1); - memcpy(p, str3, strp); - sprintf(p + strp, "%c", cend); - strcat(p + strp, str2 + 1); -#endif insertlinknode(list, last, p); if (rev) /* decreasing: add in reverse order. */ last = nextnode(last); @@ -2539,7 +2565,8 @@ get_match_ret(Imatchdata imd, int b, int e) addlinknode(imd->repllist, rd); return imd->mstr; } - ll += strlen(replstr); + if (replstr) + ll += strlen(replstr); } if (fl & SUB_MATCH) /* matched portion */ ll += 1 + (e - b); @@ -2565,6 +2592,9 @@ get_match_ret(Imatchdata imd, int b, int e) if (bl) buf[bl - 1] = '\0'; + if (ll == 0) + return NULL; + rr = r = (char *) hcalloc(ll); if (fl & SUB_MATCH) { @@ -3253,6 +3283,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, return 1; } if (matched) { + /* Default is to match at the start; see comment in MULTIBYTE above */ switch (fl & (SUB_END|SUB_LONG|SUB_SUBSTR)) { case 0: case SUB_LONG: @@ -3300,7 +3331,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, /* Largest possible match at tail of string: * * move forward along string until we get a match. * * Again there's no optimisation. */ - for (ioff = 0, t = s, umlen = uml; t < send; + for (ioff = 0, t = s, umlen = uml; t <= send; ioff++, t++, umlen--) { set_pat_start(p, t-s); if (pattrylen(p, t, send - t, umlen, &patstralloc, ioff)) { @@ -3322,7 +3353,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, /* longest or smallest at start with substrings */ t = s; if (fl & SUB_GLOBAL) { - imd.repllist = newlinklist(); + imd.repllist = (fl & SUB_LIST) ? znewlinklist() : newlinklist(); if (repllistp) *repllistp = imd.repllist; } @@ -3331,7 +3362,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, do { /* loop over all matches for global substitution */ matched = 0; - for (; t < send; t++, ioff++, umlen--) { + for (; t <= send; t++, ioff++, umlen--) { /* Find the longest match from this position. */ set_pat_start(p, t-s); if (pattrylen(p, t, send - t, umlen, &patstralloc, ioff)) { @@ -3372,6 +3403,8 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, * which is already marked for replacement. */ matched = 1; + if (t == send) + break; while (t < mpos) { ioff++; umlen--; @@ -3379,8 +3412,10 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, } break; } + if (t == send) + break; } - } while (matched); + } while (matched && t < send); /* * check if we can match a blank string, if so do it * at the start. Goodness knows if this is a good idea @@ -3452,6 +3487,8 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, * Results from get_match_ret in repllist are all metafied. */ s = *sp; + if (fl & SUB_LIST) + return 1; i = 0; /* start of last chunk we got from *sp */ for (nd = firstnode(imd.repllist); nd; incnode(nd)) { rd = (Repldata) getdata(nd); @@ -3481,7 +3518,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr, imd.replstr = NULL; imd.repllist = NULL; *sp = get_match_ret(&imd, 0, 0); - return 1; + return (fl & SUB_RETFAIL) ? 0 : 1; } /**/ |