Update Cygwin's fnmatch to latest from FreeBSD.
* collate.h (__collate_load_error): Convert to extern declaration. * globals.cc (__collate_load_error): Define and initialize here. * libc/fnmatch.c: Update to latest from FreeBSD. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
8cdd7bad21
commit
7da497499f
@ -1,6 +1,6 @@
|
|||||||
/* collate.h: Internal BSD libc header, used in glob and regcomp, for instance.
|
/* collate.h: Internal BSD libc header, used in glob and regcomp, for instance.
|
||||||
|
|
||||||
Copyright 2012 Red Hat, Inc.
|
Copyright 2012, 2015 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -13,10 +13,9 @@ details. */
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We never have a collate load error. */
|
extern const int __collate_load_error;
|
||||||
const int __collate_load_error = 0;
|
|
||||||
|
|
||||||
int __collate_range_cmp (int c1, int c2);
|
extern int __collate_range_cmp (int c1, int c2);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
|
@ -103,6 +103,9 @@ char NO_COPY almost_null[1];
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
/* We never have a collate load error. */
|
||||||
|
const int __collate_load_error = 0;
|
||||||
|
|
||||||
/* Heavily-used const UNICODE_STRINGs are defined here once. The idea is a
|
/* Heavily-used const UNICODE_STRINGs are defined here once. The idea is a
|
||||||
speed improvement by not having to initialize a UNICODE_STRING every time
|
speed improvement by not having to initialize a UNICODE_STRING every time
|
||||||
we make a string comparison. The _RDATA trick allows defining the strings
|
we make a string comparison. The _RDATA trick allows defining the strings
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
* This code is derived from software contributed to Berkeley by
|
* This code is derived from software contributed to Berkeley by
|
||||||
* Guido van Rossum.
|
* Guido van Rossum.
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2011 The FreeBSD Foundation
|
||||||
|
* All rights reserved.
|
||||||
|
* Portions of this software were developed by David Chisnall
|
||||||
|
* under sponsorship from the FreeBSD Foundation.
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@ -34,9 +39,7 @@
|
|||||||
static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
|
static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
|
||||||
#endif /* LIBC_SCCS and not lint */
|
#endif /* LIBC_SCCS and not lint */
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#if 0
|
__FBSDID("$FreeBSD: head/lib/libc/gen/fnmatch.c 288309 2015-09-27 12:52:18Z jilles $");
|
||||||
__FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.18 2007/01/09 00:27:53 imp Exp $");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
|
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
|
||||||
@ -60,7 +63,11 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.18 2007/01/09 00:27:53 imp Ex
|
|||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
|
||||||
#include "../posix/collate.h"
|
#ifdef __CYGWIN__
|
||||||
|
#include "../collate.h"
|
||||||
|
#else
|
||||||
|
#include "collate.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EOS '\0'
|
#define EOS '\0'
|
||||||
|
|
||||||
@ -69,31 +76,30 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.18 2007/01/09 00:27:53 imp Ex
|
|||||||
#define RANGE_ERROR (-1)
|
#define RANGE_ERROR (-1)
|
||||||
|
|
||||||
static int rangematch(const char *, wchar_t, int, char **, mbstate_t *);
|
static int rangematch(const char *, wchar_t, int, char **, mbstate_t *);
|
||||||
static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t);
|
static int fnmatch1(const char *, const char *, const char *, int, mbstate_t,
|
||||||
|
mbstate_t);
|
||||||
|
|
||||||
int
|
int
|
||||||
fnmatch(pattern, string, flags)
|
fnmatch(const char *pattern, const char *string, int flags)
|
||||||
const char *pattern, *string;
|
|
||||||
int flags;
|
|
||||||
{
|
{
|
||||||
static const mbstate_t initial;
|
static const mbstate_t initial;
|
||||||
|
|
||||||
return (fnmatch1(pattern, string, flags, initial, initial));
|
return (fnmatch1(pattern, string, string, flags, initial, initial));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fnmatch1(pattern, string, flags, patmbs, strmbs)
|
fnmatch1(const char *pattern, const char *string, const char *stringstart,
|
||||||
const char *pattern, *string;
|
int flags, mbstate_t patmbs, mbstate_t strmbs)
|
||||||
int flags;
|
|
||||||
mbstate_t patmbs, strmbs;
|
|
||||||
{
|
{
|
||||||
const char *stringstart;
|
const char *bt_pattern, *bt_string;
|
||||||
|
mbstate_t bt_patmbs, bt_strmbs;
|
||||||
char *newp;
|
char *newp;
|
||||||
char c;
|
char c;
|
||||||
wchar_t pc, sc;
|
wchar_t pc, sc;
|
||||||
size_t pclen, sclen;
|
size_t pclen, sclen;
|
||||||
|
|
||||||
for (stringstart = string;;) {
|
bt_pattern = bt_string = NULL;
|
||||||
|
for (;;) {
|
||||||
pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs);
|
pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs);
|
||||||
if (pclen == (size_t)-1 || pclen == (size_t)-2)
|
if (pclen == (size_t)-1 || pclen == (size_t)-2)
|
||||||
return (FNM_NOMATCH);
|
return (FNM_NOMATCH);
|
||||||
@ -108,16 +114,18 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
|
|||||||
case EOS:
|
case EOS:
|
||||||
if ((flags & FNM_LEADING_DIR) && sc == '/')
|
if ((flags & FNM_LEADING_DIR) && sc == '/')
|
||||||
return (0);
|
return (0);
|
||||||
return (sc == EOS ? 0 : FNM_NOMATCH);
|
if (sc == EOS)
|
||||||
|
return (0);
|
||||||
|
goto backtrack;
|
||||||
case '?':
|
case '?':
|
||||||
if (sc == EOS)
|
if (sc == EOS)
|
||||||
return (FNM_NOMATCH);
|
return (FNM_NOMATCH);
|
||||||
if (sc == '/' && (flags & FNM_PATHNAME))
|
if (sc == '/' && (flags & FNM_PATHNAME))
|
||||||
return (FNM_NOMATCH);
|
goto backtrack;
|
||||||
if (sc == '.' && (flags & FNM_PERIOD) &&
|
if (sc == '.' && (flags & FNM_PERIOD) &&
|
||||||
(string == stringstart ||
|
(string == stringstart ||
|
||||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||||
return (FNM_NOMATCH);
|
goto backtrack;
|
||||||
string += sclen;
|
string += sclen;
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
@ -129,7 +137,7 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
|
|||||||
if (sc == '.' && (flags & FNM_PERIOD) &&
|
if (sc == '.' && (flags & FNM_PERIOD) &&
|
||||||
(string == stringstart ||
|
(string == stringstart ||
|
||||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||||
return (FNM_NOMATCH);
|
goto backtrack;
|
||||||
|
|
||||||
/* Optimize for pattern with * at end or before /. */
|
/* Optimize for pattern with * at end or before /. */
|
||||||
if (c == EOS)
|
if (c == EOS)
|
||||||
@ -145,33 +153,24 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General case, use recursion. */
|
/*
|
||||||
while (sc != EOS) {
|
* First try the shortest match for the '*' that
|
||||||
if (!fnmatch1(pattern, string,
|
* could work. We can forget any earlier '*' since
|
||||||
flags & ~FNM_PERIOD, patmbs, strmbs))
|
* there is no way having it match more characters
|
||||||
return (0);
|
* can help us, given that we are already here.
|
||||||
sclen = mbrtowc(&sc, string, MB_LEN_MAX,
|
*/
|
||||||
&strmbs);
|
bt_pattern = pattern, bt_patmbs = patmbs;
|
||||||
if (sclen == (size_t)-1 ||
|
bt_string = string, bt_strmbs = strmbs;
|
||||||
sclen == (size_t)-2) {
|
|
||||||
sc = (unsigned char)*string;
|
|
||||||
sclen = 1;
|
|
||||||
memset(&strmbs, 0, sizeof(strmbs));
|
|
||||||
}
|
|
||||||
if (sc == '/' && flags & FNM_PATHNAME)
|
|
||||||
break;
|
break;
|
||||||
string += sclen;
|
|
||||||
}
|
|
||||||
return (FNM_NOMATCH);
|
|
||||||
case '[':
|
case '[':
|
||||||
if (sc == EOS)
|
if (sc == EOS)
|
||||||
return (FNM_NOMATCH);
|
return (FNM_NOMATCH);
|
||||||
if (sc == '/' && (flags & FNM_PATHNAME))
|
if (sc == '/' && (flags & FNM_PATHNAME))
|
||||||
return (FNM_NOMATCH);
|
goto backtrack;
|
||||||
if (sc == '.' && (flags & FNM_PERIOD) &&
|
if (sc == '.' && (flags & FNM_PERIOD) &&
|
||||||
(string == stringstart ||
|
(string == stringstart ||
|
||||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||||
return (FNM_NOMATCH);
|
goto backtrack;
|
||||||
|
|
||||||
switch (rangematch(pattern, sc, flags, &newp,
|
switch (rangematch(pattern, sc, flags, &newp,
|
||||||
&patmbs)) {
|
&patmbs)) {
|
||||||
@ -181,7 +180,7 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
|
|||||||
pattern = newp;
|
pattern = newp;
|
||||||
break;
|
break;
|
||||||
case RANGE_NOMATCH:
|
case RANGE_NOMATCH:
|
||||||
return (FNM_NOMATCH);
|
goto backtrack;
|
||||||
}
|
}
|
||||||
string += sclen;
|
string += sclen;
|
||||||
break;
|
break;
|
||||||
@ -191,21 +190,44 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
|
|||||||
&patmbs);
|
&patmbs);
|
||||||
if (pclen == (size_t)-1 || pclen == (size_t)-2)
|
if (pclen == (size_t)-1 || pclen == (size_t)-2)
|
||||||
return (FNM_NOMATCH);
|
return (FNM_NOMATCH);
|
||||||
if (pclen == 0)
|
|
||||||
pc = '\\';
|
|
||||||
pattern += pclen;
|
pattern += pclen;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
norm:
|
norm:
|
||||||
|
string += sclen;
|
||||||
if (pc == sc)
|
if (pc == sc)
|
||||||
;
|
;
|
||||||
else if ((flags & FNM_CASEFOLD) &&
|
else if ((flags & FNM_CASEFOLD) &&
|
||||||
(towlower(pc) == towlower(sc)))
|
(towlower(pc) == towlower(sc)))
|
||||||
;
|
;
|
||||||
else
|
else {
|
||||||
|
backtrack:
|
||||||
|
/*
|
||||||
|
* If we have a mismatch (other than hitting
|
||||||
|
* the end of the string), go back to the last
|
||||||
|
* '*' seen and have it match one additional
|
||||||
|
* character.
|
||||||
|
*/
|
||||||
|
if (bt_pattern == NULL)
|
||||||
return (FNM_NOMATCH);
|
return (FNM_NOMATCH);
|
||||||
string += sclen;
|
sclen = mbrtowc(&sc, bt_string, MB_LEN_MAX,
|
||||||
|
&bt_strmbs);
|
||||||
|
if (sclen == (size_t)-1 ||
|
||||||
|
sclen == (size_t)-2) {
|
||||||
|
sc = (unsigned char)*bt_string;
|
||||||
|
sclen = 1;
|
||||||
|
memset(&bt_strmbs, 0,
|
||||||
|
sizeof(bt_strmbs));
|
||||||
|
}
|
||||||
|
if (sc == EOS)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
if (sc == '/' && flags & FNM_PATHNAME)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
bt_string += sclen;
|
||||||
|
pattern = bt_pattern, patmbs = bt_patmbs;
|
||||||
|
string = bt_string, strmbs = bt_strmbs;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,17 +235,17 @@ fnmatch1(pattern, string, flags, patmbs, strmbs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rangematch(pattern, test, flags, newp, patmbs)
|
rangematch(const char *pattern, wchar_t test, int flags, char **newp,
|
||||||
const char *pattern;
|
mbstate_t *patmbs)
|
||||||
wchar_t test;
|
|
||||||
int flags;
|
|
||||||
char **newp;
|
|
||||||
mbstate_t *patmbs;
|
|
||||||
{
|
{
|
||||||
int negate, ok;
|
int negate, ok;
|
||||||
wchar_t c, c2;
|
wchar_t c, c2;
|
||||||
size_t pclen;
|
size_t pclen;
|
||||||
const char *origpat;
|
const char *origpat;
|
||||||
|
#ifndef __CYGWIN__
|
||||||
|
struct xlocale_collate *table =
|
||||||
|
(struct xlocale_collate*)__get_locale()->components[XLC_COLLATE];
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A bracket expression starting with an unquoted circumflex
|
* A bracket expression starting with an unquoted circumflex
|
||||||
@ -278,11 +300,19 @@ rangematch(pattern, test, flags, newp, patmbs)
|
|||||||
if (flags & FNM_CASEFOLD)
|
if (flags & FNM_CASEFOLD)
|
||||||
c2 = towlower(c2);
|
c2 = towlower(c2);
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
if (__collate_load_error ?
|
if (__collate_load_error ?
|
||||||
c <= test && test <= c2 :
|
c <= test && test <= c2 :
|
||||||
__collate_range_cmp(c, test) <= 0
|
__collate_range_cmp(c, test) <= 0
|
||||||
&& __collate_range_cmp(test, c2) <= 0
|
&& __collate_range_cmp(test, c2) <= 0
|
||||||
)
|
)
|
||||||
|
#else
|
||||||
|
if (table->__collate_load_error ?
|
||||||
|
c <= test && test <= c2 :
|
||||||
|
__collate_range_cmp(table, c, test) <= 0
|
||||||
|
&& __collate_range_cmp(table, test, c2) <= 0
|
||||||
|
)
|
||||||
|
#endif
|
||||||
ok = 1;
|
ok = 1;
|
||||||
} else if (c == test)
|
} else if (c == test)
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user