From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id B640A3858C60; Wed, 15 Feb 2023 13:12:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B640A3858C60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1676466731; bh=/6dCVJAiQrIPHhchkjuRl+8JyEe7MpV/B3Ze+m+qM8o=; h=From:To:Subject:Date:From; b=ljQJnmQUNH0PX9BtetXjUmWN3AFDvAlYJKWAAiVkisNTdRoopu8hUW/4G6Vax/Iuy 6Le+xms+WuyjJvySuWVDLwVfiO0hS56NPnObHWMY9DOdZwAG9ZVG6Y8ntccP3zzNvX XWBb1fXZgo6EWyCPG5hUPpao0lUY/B3/R6GQaEPw= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/main] Cygwin: glob: handle named character classes X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/main X-Git-Oldrev: 7faa6465531637d76e3c0733a4d2608bf7b3a54a X-Git-Newrev: d6d4436145b823ac28e19fb2257aaca4d94a725b Message-Id: <20230215131211.B640A3858C60@sourceware.org> Date: Wed, 15 Feb 2023 13:12:11 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dd6d4436145b= 823ac28e19fb2257aaca4d94a725b commit d6d4436145b823ac28e19fb2257aaca4d94a725b Author: Corinna Vinschen AuthorDate: Wed Feb 15 14:11:45 2023 +0100 Commit: Corinna Vinschen CommitDate: Wed Feb 15 14:11:45 2023 +0100 Cygwin: glob: handle named character classes =20 Handle [::] expressions in range brackets. =20 TODO: Collating symbols [.'.] and Equivalence class expressions [=3D=3D] are recognized but skipped as if they are not present at all. =20 Signed-off-by: Corinna Vinschen Diff: --- winsup/cygwin/glob.cc | 83 ++++++++++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/glob.cc b/winsup/cygwin/glob.cc index 61fa610d60a0..1e8eda903e70 100644 --- a/winsup/cygwin/glob.cc +++ b/winsup/cygwin/glob.cc @@ -110,6 +110,8 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.28 2010= /05/12 17:44:00 gordon Ex =20 #define DOLLAR '$' #define DOT '.' +#define COLON ':' +#define EQUALS '=3D' #define EOS '\0' #define LBRACKET '[' #define NOT '!' @@ -155,9 +157,9 @@ typedef char Char; #define M_ONE META('?') #define M_RNG META('-') #define M_SET META('[') +#define M_NAMED META(':') #define ismeta(c) (((c)&M_QUOTE) !=3D 0) =20 - static int compare(const void *, const void *); static int g_Ctoc(const Char *, char *, size_t); static int g_lstat(Char *, struct stat *, glob_t *); @@ -181,6 +183,39 @@ static int match(Char *, Char *, Char *); static void qprintf(const char *, Char *); #endif =20 +/* Return value is either EOS, COLON, DOT, EQUALS, or LBRACKET if no class + expression found. */ +static inline Char +check_classes_expr(const Char *&cptr, char *classbuf =3D NULL, + size_t classbufsize =3D 0) +{ + const Char *ctype =3D NULL; + + if (*cptr =3D=3D LBRACKET && + (cptr[1] =3D=3D COLON || cptr[1] =3D=3D DOT || cptr[1] =3D=3D EQUALS)= ) { + ctype =3D ++cptr; + while (*++cptr !=3D EOS && + (*cptr !=3D *ctype || cptr[1] !=3D RBRACKET)) + ; + if (*cptr =3D=3D EOS) + return EOS; + if (classbuf) { + const Char *class_p =3D ctype + 1; + size_t clen =3D cptr - class_p; + size_t idx; + + if (clen < classbufsize) { + for (idx =3D 0; idx < clen; ++idx) + classbuf[idx] =3D class_p[idx]; + classbuf[idx] =3D '\0'; + } else + ctype =3D NULL; + } + cptr++; /* Advance cptr to closing RBRACKET of class expr */ + } + return ctype ? *ctype : LBRACKET; +} + int glob(const char *__restrict pattern, int flags, int (*errfunc)(const char = *, int), glob_t *__restrict pglob) { @@ -296,8 +331,10 @@ globexp2(const Char *ptr, const Char *pattern, glob_t = *pglob, int *rv, size_t *l for (i =3D 0, pe =3D ++ptr; *pe; pe++) if (*pe =3D=3D LBRACKET) { /* Ignore everything between [] */ - for (pm =3D pe++; *pe !=3D RBRACKET && *pe !=3D EOS; pe++) - continue; + for (pm =3D pe++; *pe !=3D RBRACKET && *pe !=3D EOS; pe++) { + if (check_classes_expr (pe) =3D=3D EOS) + break; + } if (*pe =3D=3D EOS) { /* * We could not find a matching RBRACKET. @@ -324,8 +361,10 @@ globexp2(const Char *ptr, const Char *pattern, glob_t = *pglob, int *rv, size_t *l switch (*pm) { case LBRACKET: /* Ignore everything between [] */ - for (pm1 =3D pm++; *pm !=3D RBRACKET && *pm !=3D EOS; pm++) - continue; + for (pm1 =3D pm++; *pm !=3D RBRACKET && *pm !=3D EOS; pm++) { + if (check_classes_expr (pm) =3D=3D EOS) + break; + } if (*pm =3D=3D EOS) { /* * We could not find a matching RBRACKET. @@ -451,7 +490,7 @@ globtilde(const Char *pattern, Char *patbuf, size_t pat= buf_len, glob_t *pglob) static int glob0(const Char *pattern, glob_t *pglob, size_t *limit) { - const Char *qpatnext; + const Char *qpatnext, *qpatrbsrch; int err; size_t oldpathc; Char *bufnext, c, patbuf[MAXPATHLEN]; @@ -467,8 +506,13 @@ glob0(const Char *pattern, glob_t *pglob, size_t *limi= t) c =3D *qpatnext; if (c =3D=3D NOT) ++qpatnext; - if (*qpatnext =3D=3D EOS || - g_strchr(qpatnext+1, RBRACKET) =3D=3D NULL) { + for (qpatrbsrch =3D qpatnext; + *qpatrbsrch !=3D RBRACKET && *qpatrbsrch !=3D EOS; + ++qpatrbsrch) { + if (check_classes_expr (qpatrbsrch) =3D=3D EOS) + break; + } + if (*qpatrbsrch =3D=3D EOS) { *bufnext++ =3D LBRACKET; if (c =3D=3D NOT) --qpatnext; @@ -477,8 +521,24 @@ glob0(const Char *pattern, glob_t *pglob, size_t *limi= t) *bufnext++ =3D M_SET; if (c =3D=3D NOT) *bufnext++ =3D M_NOT; - c =3D *qpatnext++; + c =3D *qpatnext; do { + char cclass[64]; + wctype_t type; + Char ctype; + + ctype =3D check_classes_expr(qpatnext, cclass, + sizeof cclass); + if (ctype) { + if (ctype =3D=3D COLON && + (type =3D wctype (cclass))) { + *bufnext++ =3D M_NAMED; + *bufnext++ =3D CHAR (type); + } + /* TODO: [. and [=3D are ignored yet */ + qpatnext++; + continue; + } *bufnext++ =3D CHAR(c); if (*qpatnext =3D=3D RANGE && (c =3D qpatnext[1]) !=3D RBRACKET) { @@ -795,7 +855,10 @@ match(Char *name, Char *pat, Char *patend) if ((negate_range =3D ((*pat & M_MASK) =3D=3D M_NOT)) !=3D EOS) ++pat; while (((c =3D *pat++) & M_MASK) !=3D M_END) - if ((*pat & M_MASK) =3D=3D M_RNG) { + if ((c & M_MASK) =3D=3D M_NAMED) { + if (iswctype (k, *pat++)) + ok =3D 1; + } else if ((*pat & M_MASK) =3D=3D M_RNG) { if (__collate_load_error ? CCHAR(c) <=3D CCHAR(k) && CCHAR(k) <=3D CCHAR(pat[1]) : __collate_range_cmp(CCHAR(c), CCHAR(k)) <=3D 0