Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>

*** 29,38 **** --- 29,39 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* + * Copyright 2013 Garrett D'Amore <garrett@damore.org> * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Use is subject to license terms. */ /*
*** 54,102 **** #include "lint.h" #include <fnmatch.h> #include <limits.h> #include <string.h> #include <wchar.h> #include <wctype.h> ! #include "collate.h" #define EOS '\0' #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) ! static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, ! mbstate_t); int fnmatch(pattern, string, flags) const char *pattern, *string; int flags; { static const mbstate_t initial = { 0 }; ! return (fnmatch1(pattern, string, string, flags, initial, initial)); } static int fnmatch1(const char *pattern, const char *string, const char *stringstart, ! int flags, mbstate_t patmbs, mbstate_t strmbs) { char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; for (;;) { ! pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); pattern += pclen; ! sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; (void) memset(&strmbs, 0, sizeof (strmbs)); } --- 55,107 ---- #include "lint.h" #include <fnmatch.h> #include <limits.h> #include <string.h> #include <wchar.h> + #include <xlocale.h> #include <wctype.h> ! #include "localeimpl.h" #include "collate.h" #define EOS '\0' #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) ! static int rangematch(const char *, wchar_t, int, char **, mbstate_t *, ! locale_t); static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, ! mbstate_t, locale_t); int fnmatch(pattern, string, flags) const char *pattern, *string; int flags; { + locale_t loc = uselocale(NULL); static const mbstate_t initial = { 0 }; ! return (fnmatch1(pattern, string, string, flags, initial, initial, ! loc)); } static int fnmatch1(const char *pattern, const char *string, const char *stringstart, ! int flags, mbstate_t patmbs, mbstate_t strmbs, locale_t loc) { char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; for (;;) { ! pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, &patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); pattern += pclen; ! sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, &strmbs, loc); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; (void) memset(&strmbs, 0, sizeof (strmbs)); }
*** 143,156 **** } /* General case, use recursion. */ while (sc != EOS) { if (!fnmatch1(pattern, string, stringstart, ! flags, patmbs, strmbs)) return (0); ! sclen = mbrtowc(&sc, string, MB_LEN_MAX, ! &strmbs); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; (void) memset(&strmbs, 0, --- 148,161 ---- } /* General case, use recursion. */ while (sc != EOS) { if (!fnmatch1(pattern, string, stringstart, ! flags, patmbs, strmbs, loc)) return (0); ! sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, ! &strmbs, loc); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; (void) memset(&strmbs, 0,
*** 170,180 **** (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) return (FNM_NOMATCH); switch (rangematch(pattern, sc, flags, &newp, ! &patmbs)) { case RANGE_ERROR: goto norm; case RANGE_MATCH: pattern = newp; break; --- 175,185 ---- (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) return (FNM_NOMATCH); switch (rangematch(pattern, sc, flags, &newp, ! &patmbs, loc)) { case RANGE_ERROR: goto norm; case RANGE_MATCH: pattern = newp; break;
*** 183,194 **** } string += sclen; break; case '\\': if (!(flags & FNM_NOESCAPE)) { ! pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, ! &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); if (pclen == 0) pc = '\\'; pattern += pclen; --- 188,199 ---- } string += sclen; break; case '\\': if (!(flags & FNM_NOESCAPE)) { ! pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, ! &patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); if (pclen == 0) pc = '\\'; pattern += pclen;
*** 198,208 **** norm: if (pc == sc) string += sclen; else if ((flags & FNM_IGNORECASE) && ! (towlower(pc) == towlower(sc))) string += sclen; else return (FNM_NOMATCH); break; --- 203,213 ---- norm: if (pc == sc) string += sclen; else if ((flags & FNM_IGNORECASE) && ! (towlower_l(pc, loc) == towlower_l(sc, loc))) string += sclen; else return (FNM_NOMATCH); break;
*** 210,225 **** } /* NOTREACHED */ } static int ! rangematch(pattern, test, flags, newp, patmbs) ! const char *pattern; ! wchar_t test; ! int flags; ! char **newp; ! mbstate_t *patmbs; { int negate, ok; wchar_t c, c2; size_t pclen; const char *origpat; --- 215,226 ---- } /* NOTREACHED */ } static int ! rangematch(const char *pattern, wchar_t test, int flags, char **newp, ! mbstate_t *patmbs, locale_t loc) { int negate, ok; wchar_t c, c2; size_t pclen; const char *origpat;
*** 233,243 **** */ if ((negate = (*pattern == '!' || *pattern == '^')) != 0) ++pattern; if (flags & FNM_IGNORECASE) ! test = towlower(test); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2 --- 234,244 ---- */ if ((negate = (*pattern == '!' || *pattern == '^')) != 0) ++pattern; if (flags & FNM_IGNORECASE) ! test = towlower_l(test, loc); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2
*** 252,288 **** return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; ! pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (flags & FNM_IGNORECASE) ! c = towlower(c); if (*pattern == '-' && *(pattern + 1) != EOS && *(pattern + 1) != ']') { if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) if (*pattern != EOS) pattern++; ! pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_IGNORECASE) ! c2 = towlower(c2); ! if (_collate_load_error ? c <= test && test <= c2 : ! _collate_range_cmp(c, test) <= 0 && ! _collate_range_cmp(test, c2) <= 0) ok = 1; } else if (c == test) ok = 1; } --- 253,290 ---- return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; ! pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (flags & FNM_IGNORECASE) ! c = towlower_l(c, loc); if (*pattern == '-' && *(pattern + 1) != EOS && *(pattern + 1) != ']') { if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) if (*pattern != EOS) pattern++; ! pclen = mbrtowc_l(&c2, pattern, MB_LEN_MAX, patmbs, ! loc); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_IGNORECASE) ! c2 = towlower_l(c2, loc); ! if (loc->collate->lc_is_posix ? c <= test && test <= c2 : ! _collate_range_cmp(c, test, loc) <= 0 && ! _collate_range_cmp(test, c2, loc) <= 0) ok = 1; } else if (c == test) ok = 1; }