https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1df19b3caeaee95388a3c4d78559389bbcfc9ad5

commit 1df19b3caeaee95388a3c4d78559389bbcfc9ad5
Author:     Corinna Vinschen <[email protected]>
AuthorDate: Wed Feb 15 22:34:46 2023 +0100
Commit:     Corinna Vinschen <[email protected]>
CommitDate: Wed Feb 15 22:34:46 2023 +0100

    Cygwin: glob: handle equivalence class expressions
    
    Handle [=x=] expressions in range brackets.  Use the new
    is_unicode_equiv() function to perform the check.
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/cygwin/glob.cc | 42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/winsup/cygwin/glob.cc b/winsup/cygwin/glob.cc
index 1e8eda903e70..c882cd59d2e2 100644
--- a/winsup/cygwin/glob.cc
+++ b/winsup/cygwin/glob.cc
@@ -158,6 +158,7 @@ typedef char Char;
 #define        M_RNG           META('-')
 #define        M_SET           META('[')
 #define        M_NAMED         META(':')
+#define        M_EQUIV         META('=')
 #define        ismeta(c)       (((c)&M_QUOTE) != 0)
 
 static int      compare(const void *, const void *);
@@ -186,7 +187,7 @@ static void  qprintf(const char *, Char *);
 /* 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 = NULL,
+check_classes_expr(const Char *&cptr, wint_t *classbuf = NULL,
                   size_t classbufsize = 0)
 {
        const Char *ctype = NULL;
@@ -206,7 +207,7 @@ check_classes_expr(const Char *&cptr, char *classbuf = NULL,
 
                        if (clen < classbufsize) {
                                for (idx = 0; idx < clen; ++idx)
-                                   classbuf[idx] = class_p[idx];
+                                   classbuf[idx] = CHAR(class_p[idx]);
                                classbuf[idx] = '\0';
                        } else
                                ctype = NULL;
@@ -480,6 +481,11 @@ globtilde(const Char *pattern, Char *patbuf, size_t 
patbuf_len, glob_t *pglob)
        return patbuf;
 }
 
+static void
+wcitoascii(char *dst, wint_t *src)
+{
+       while ((*dst++ = *src++));
+}
 
 /*
  * The main glob() routine: compiles the pattern (optionally processing
@@ -523,19 +529,30 @@ glob0(const Char *pattern, glob_t *pglob, size_t *limit)
                                *bufnext++ = M_NOT;
                        c = *qpatnext;
                        do {
-                               char cclass[64];
-                               wctype_t type;
+                               wint_t wclass[64];
                                Char ctype;
 
-                               ctype = check_classes_expr(qpatnext, cclass,
-                                                          sizeof cclass);
+                               ctype = check_classes_expr(qpatnext, wclass,
+                                                          64);
                                if (ctype) {
-                                       if (ctype == COLON &&
-                                           (type = wctype (cclass))) {
-                                           *bufnext++ = M_NAMED;
-                                           *bufnext++ = CHAR (type);
+                                       wctype_t type;
+
+                                       if (ctype == COLON) {
+                                           char cclass[64];
+
+                                           /* No worries, char classes are
+                                              ASCII-only anyway */
+                                           wcitoascii (cclass, wclass);
+                                           if ((type = wctype (cclass))) {
+                                               *bufnext++ = M_NAMED;
+                                               *bufnext++ = CHAR (type);
+                                           }
+                                       } else if (ctype == EQUALS &&
+                                                  wclass[0] && !wclass[1]) {
+                                           *bufnext++ = M_EQUIV;
+                                           *bufnext++ = CHAR (wclass[0]);
                                        }
-                                       /* TODO: [. and [= are ignored yet */
+                                       /* TODO: [. is ignored yet */
                                        qpatnext++;
                                        continue;
                                }
@@ -858,6 +875,9 @@ match(Char *name, Char *pat, Char *patend)
                                if ((c & M_MASK) == M_NAMED) {
                                        if (iswctype (k, *pat++))
                                                ok = 1;
+                               } else if ((c & M_MASK) == M_EQUIV) {
+                                       if (is_unicode_equiv (k, *pat++))
+                                               ok = 1;
                                } else if ((*pat & M_MASK) == M_RNG) {
                                        if (__collate_load_error ?
                                            CCHAR(c) <= CCHAR(k) && CCHAR(k) <= 
CCHAR(pat[1]) :

Reply via email to