+- if (pclen == (size_t)-1 || pclen == (size_t)-2)
+- return (RANGE_NOMATCH);
+- pattern += pclen;
++ else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) {
++ cp = (pattern += 2);
++ while(cp = strchr(cp, special)) {
++ if (*(cp + 1) == ']')
++ break;
++ cp++;
++ }
++ if (!cp)
++ return (RANGE_ERROR);
++ if (special == '.') {
++treat_like_collating_symbol:
++ len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc);
++ if (len == (size_t)-1 || len == 0)
++ return (RANGE_ERROR);
++ pattern = cp + 2;
++ if (len > 1) {
++ wchar_t *wp, sc;
++ /* no multi-character collation symbols as start of range */
++ if (*(cp + 2) == '-' && *(cp + 3) != EOS
++ && *(cp + 3) != ']')
++ return (RANGE_ERROR);
++ wp = buf;
++ if (test != *wp++)
++ continue;
++ if (len == 1) {
++ ok = 1;
++ break;
++ }
++ memcpy(&save, strmbs, sizeof(save));
++ savestring = string;
++ while (--len > 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;
++ memset(&strmbs, 0, sizeof(strmbs));
++ }
++ if (sc != *wp++) {
++ memcpy(strmbs, &save, sizeof(save));
++ string = savestring;
++ break;
++ }
++ string += sclen;
++ }
++ if (len == 0) {
++ ok = 1;
++ break;
++ }
++ continue; /* no match */
++ }
++ c = *buf;
++ } else if (special == '=') {
++ int ec;
++ memcpy(&save, patmbs, sizeof(save));
++ ec = __collate_equiv_class(pattern, cp - pattern, patmbs, loc);
++ if (ec < 0)
++ return (RANGE_ERROR);
++ if (ec == 0) {
++ memcpy(patmbs, &save, sizeof(save));
++ goto treat_like_collating_symbol;
++ }
++ pattern = cp + 2;
++ /* no equivalence classes as start of range */
++ if (*(cp + 2) == '-' && *(cp + 3) != EOS &&
++ *(cp + 3) != ']')
++ return (RANGE_ERROR);
++ len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc);
++ if (len < 0)
++ return (RANGE_ERROR);
++ if (len > 0) {
++ ok = 1;
++ string += sclen;
++ break;
++ }
++ continue;
++ } else { /* special == ':' */
++ wctype_t charclass;
++ char name[CHARCLASS_NAME_MAX + 1];
++ /* no character classes as start of range */
++ if (*(cp + 2) == '-' && *(cp + 3) != EOS &&
++ *(cp + 3) != ']')
++ return (RANGE_ERROR);
++ /* assume character class names are ascii */
++ if (cp - pattern > CHARCLASS_NAME_MAX)
++ return (RANGE_ERROR);
++ strlcpy(name, pattern, cp - pattern + 1);
++ pattern = cp + 2;
++ if ((charclass = wctype(name)) == 0)
++ return (RANGE_ERROR);
++ if (iswctype_l(test, charclass, loc)) {
++ ok = 1;
++ break;
++ }
++ continue;
++ }
++ }
++ if (!c) {
++ pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc);
++ if (pclen == (size_t)-1 || pclen == (size_t)-2)
++ return (RANGE_ERROR);
++ pattern += pclen;
++ }