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 <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2023-02-15 22:34:46 +01:00
parent 20162667de
commit 1df19b3cae
1 changed files with 31 additions and 11 deletions

View File

@ -158,6 +158,7 @@ typedef char Char;
#define M_RNG META('-') #define M_RNG META('-')
#define M_SET META('[') #define M_SET META('[')
#define M_NAMED META(':') #define M_NAMED META(':')
#define M_EQUIV META('=')
#define ismeta(c) (((c)&M_QUOTE) != 0) #define ismeta(c) (((c)&M_QUOTE) != 0)
static int compare(const void *, const void *); 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 /* Return value is either EOS, COLON, DOT, EQUALS, or LBRACKET if no class
expression found. */ expression found. */
static inline Char 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) size_t classbufsize = 0)
{ {
const Char *ctype = NULL; const Char *ctype = NULL;
@ -206,7 +207,7 @@ check_classes_expr(const Char *&cptr, char *classbuf = NULL,
if (clen < classbufsize) { if (clen < classbufsize) {
for (idx = 0; idx < clen; ++idx) for (idx = 0; idx < clen; ++idx)
classbuf[idx] = class_p[idx]; classbuf[idx] = CHAR(class_p[idx]);
classbuf[idx] = '\0'; classbuf[idx] = '\0';
} else } else
ctype = NULL; ctype = NULL;
@ -480,6 +481,11 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
return patbuf; return patbuf;
} }
static void
wcitoascii(char *dst, wint_t *src)
{
while ((*dst++ = *src++));
}
/* /*
* The main glob() routine: compiles the pattern (optionally processing * 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; *bufnext++ = M_NOT;
c = *qpatnext; c = *qpatnext;
do { do {
char cclass[64]; wint_t wclass[64];
wctype_t type;
Char ctype; Char ctype;
ctype = check_classes_expr(qpatnext, cclass, ctype = check_classes_expr(qpatnext, wclass,
sizeof cclass); 64);
if (ctype) { if (ctype) {
if (ctype == COLON && wctype_t type;
(type = wctype (cclass))) {
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++ = M_NAMED;
*bufnext++ = CHAR (type); *bufnext++ = CHAR (type);
} }
/* TODO: [. and [= are ignored yet */ } else if (ctype == EQUALS &&
wclass[0] && !wclass[1]) {
*bufnext++ = M_EQUIV;
*bufnext++ = CHAR (wclass[0]);
}
/* TODO: [. is ignored yet */
qpatnext++; qpatnext++;
continue; continue;
} }
@ -858,6 +875,9 @@ match(Char *name, Char *pat, Char *patend)
if ((c & M_MASK) == M_NAMED) { if ((c & M_MASK) == M_NAMED) {
if (iswctype (k, *pat++)) if (iswctype (k, *pat++))
ok = 1; ok = 1;
} else if ((c & M_MASK) == M_EQUIV) {
if (is_unicode_equiv (k, *pat++))
ok = 1;
} else if ((*pat & M_MASK) == M_RNG) { } else if ((*pat & M_MASK) == M_RNG) {
if (__collate_load_error ? if (__collate_load_error ?
CCHAR(c) <= CCHAR(k) && CCHAR(k) <= CCHAR(pat[1]) : CCHAR(c) <= CCHAR(k) && CCHAR(k) <= CCHAR(pat[1]) :