~ubuntu-branches/debian/experimental/lftp/experimental

« back to all changes in this revision

Viewing changes to lib/fnmatch_loop.c

  • Committer: Package Import Robot
  • Author(s): Noël Köthe
  • Date: 2015-08-21 16:06:22 UTC
  • mfrom: (1.1.20) (24.1.38 sid)
  • Revision ID: package-import@ubuntu.com-20150821160622-lckdmbiqx16wefgy
Tags: 4.6.4-1
new upstream release 2015-08-21

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
2
 
   Free Software Foundation, Inc.
 
1
/* Copyright (C) 1991-1993, 1996-2006, 2009-2015 Free Software Foundation, Inc.
3
2
   This file is part of the GNU C Library.
4
3
 
5
4
   This program is free software; you can redistribute it and/or modify
13
12
   GNU General Public License for more details.
14
13
 
15
14
   You should have received a copy of the GNU General Public License
16
 
   along with this program; if not, write to the Free Software Foundation,
17
 
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
15
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
18
16
 
19
17
/* Match STRING against the file name pattern PATTERN, returning zero if
20
18
   it matches, nonzero if not.  */
21
19
static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
22
 
                const CHAR *string_end, bool no_leading_period, int flags)
 
20
                const CHAR *string_end, bool no_leading_period, int flags)
23
21
     internal_function;
24
22
static const CHAR *END (const CHAR *patternp) internal_function;
25
23
 
46
44
      c = FOLD (c);
47
45
 
48
46
      switch (c)
49
 
        {
50
 
        case L_('?'):
51
 
          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
52
 
            {
53
 
              int res;
54
 
 
55
 
              res = EXT (c, p, n, string_end, no_leading_period,
56
 
                         flags);
57
 
              if (res != -1)
58
 
                return res;
59
 
            }
60
 
 
61
 
          if (n == string_end)
62
 
            return FNM_NOMATCH;
63
 
          else if (*n == L_('/') && (flags & FNM_FILE_NAME))
64
 
            return FNM_NOMATCH;
65
 
          else if (*n == L_('.') && no_leading_period)
66
 
            return FNM_NOMATCH;
67
 
          break;
68
 
 
69
 
        case L_('\\'):
70
 
          if (!(flags & FNM_NOESCAPE))
71
 
            {
72
 
              c = *p++;
73
 
              if (c == L_('\0'))
74
 
                /* Trailing \ loses.  */
75
 
                return FNM_NOMATCH;
76
 
              c = FOLD (c);
77
 
            }
78
 
          if (n == string_end || FOLD ((UCHAR) *n) != c)
79
 
            return FNM_NOMATCH;
80
 
          break;
81
 
 
82
 
        case L_('*'):
83
 
          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
84
 
            {
85
 
              int res;
86
 
 
87
 
              res = EXT (c, p, n, string_end, no_leading_period,
88
 
                         flags);
89
 
              if (res != -1)
90
 
                return res;
91
 
            }
92
 
 
93
 
          if (n != string_end && *n == L_('.') && no_leading_period)
94
 
            return FNM_NOMATCH;
95
 
 
96
 
          for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
97
 
            {
98
 
              if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
99
 
                {
100
 
                  const CHAR *endp = END (p);
101
 
                  if (endp != p)
102
 
                    {
103
 
                      /* This is a pattern.  Skip over it.  */
104
 
                      p = endp;
105
 
                      continue;
106
 
                    }
107
 
                }
108
 
 
109
 
              if (c == L_('?'))
110
 
                {
111
 
                  /* A ? needs to match one character.  */
112
 
                  if (n == string_end)
113
 
                    /* There isn't another character; no match.  */
114
 
                    return FNM_NOMATCH;
115
 
                  else if (*n == L_('/')
116
 
                           && __builtin_expect (flags & FNM_FILE_NAME, 0))
117
 
                    /* A slash does not match a wildcard under
118
 
                       FNM_FILE_NAME.  */
119
 
                    return FNM_NOMATCH;
120
 
                  else
121
 
                    /* One character of the string is consumed in matching
122
 
                       this ? wildcard, so *??? won't match if there are
123
 
                       less than three characters.  */
124
 
                    ++n;
125
 
                }
126
 
            }
127
 
 
128
 
          if (c == L_('\0'))
129
 
            /* The wildcard(s) is/are the last element of the pattern.
130
 
               If the name is a file name and contains another slash
131
 
               this means it cannot match, unless the FNM_LEADING_DIR
132
 
               flag is set.  */
133
 
            {
134
 
              int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
135
 
 
136
 
              if (flags & FNM_FILE_NAME)
137
 
                {
138
 
                  if (flags & FNM_LEADING_DIR)
139
 
                    result = 0;
140
 
                  else
141
 
                    {
142
 
                      if (MEMCHR (n, L_('/'), string_end - n) == NULL)
143
 
                        result = 0;
144
 
                    }
145
 
                }
146
 
 
147
 
              return result;
148
 
            }
149
 
          else
150
 
            {
151
 
              const CHAR *endp;
152
 
 
153
 
              endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
154
 
                             string_end - n);
155
 
              if (endp == NULL)
156
 
                endp = string_end;
157
 
 
158
 
              if (c == L_('[')
159
 
                  || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
160
 
                      && (c == L_('@') || c == L_('+') || c == L_('!'))
161
 
                      && *p == L_('(')))
162
 
                {
163
 
                  int flags2 = ((flags & FNM_FILE_NAME)
164
 
                                ? flags : (flags & ~FNM_PERIOD));
165
 
                  bool no_leading_period2 = no_leading_period;
166
 
 
167
 
                  for (--p; n < endp; ++n, no_leading_period2 = false)
168
 
                    if (FCT (p, n, string_end, no_leading_period2, flags2)
169
 
                        == 0)
170
 
                      return 0;
171
 
                }
172
 
              else if (c == L_('/') && (flags & FNM_FILE_NAME))
173
 
                {
174
 
                  while (n < string_end && *n != L_('/'))
175
 
                    ++n;
176
 
                  if (n < string_end && *n == L_('/')
177
 
                      && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
178
 
                          == 0))
179
 
                    return 0;
180
 
                }
181
 
              else
182
 
                {
183
 
                  int flags2 = ((flags & FNM_FILE_NAME)
184
 
                                ? flags : (flags & ~FNM_PERIOD));
185
 
                  int no_leading_period2 = no_leading_period;
186
 
 
187
 
                  if (c == L_('\\') && !(flags & FNM_NOESCAPE))
188
 
                    c = *p;
189
 
                  c = FOLD (c);
190
 
                  for (--p; n < endp; ++n, no_leading_period2 = false)
191
 
                    if (FOLD ((UCHAR) *n) == c
192
 
                        && (FCT (p, n, string_end, no_leading_period2, flags2)
193
 
                            == 0))
194
 
                      return 0;
195
 
                }
196
 
            }
197
 
 
198
 
          /* If we come here no match is possible with the wildcard.  */
199
 
          return FNM_NOMATCH;
200
 
 
201
 
        case L_('['):
202
 
          {
203
 
            /* Nonzero if the sense of the character class is inverted.  */
204
 
            register bool not;
205
 
            CHAR cold;
206
 
            UCHAR fn;
207
 
 
208
 
            if (posixly_correct == 0)
209
 
              posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
210
 
 
211
 
            if (n == string_end)
212
 
              return FNM_NOMATCH;
213
 
 
214
 
            if (*n == L_('.') && no_leading_period)
215
 
              return FNM_NOMATCH;
216
 
 
217
 
            if (*n == L_('/') && (flags & FNM_FILE_NAME))
218
 
              /* `/' cannot be matched.  */
219
 
              return FNM_NOMATCH;
220
 
 
221
 
            not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
222
 
            if (not)
223
 
              ++p;
224
 
 
225
 
            fn = FOLD ((UCHAR) *n);
226
 
 
227
 
            c = *p++;
228
 
            for (;;)
229
 
              {
230
 
                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
231
 
                  {
232
 
                    if (*p == L_('\0'))
233
 
                      return FNM_NOMATCH;
234
 
                    c = FOLD ((UCHAR) *p);
235
 
                    ++p;
236
 
 
237
 
                    goto normal_bracket;
238
 
                  }
239
 
                else if (c == L_('[') && *p == L_(':'))
240
 
                  {
241
 
                    /* Leave room for the null.  */
242
 
                    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
243
 
                    size_t c1 = 0;
 
47
        {
 
48
        case L_('?'):
 
49
          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
 
50
            {
 
51
              int res;
 
52
 
 
53
              res = EXT (c, p, n, string_end, no_leading_period,
 
54
                         flags);
 
55
              if (res != -1)
 
56
                return res;
 
57
            }
 
58
 
 
59
          if (n == string_end)
 
60
            return FNM_NOMATCH;
 
61
          else if (*n == L_('/') && (flags & FNM_FILE_NAME))
 
62
            return FNM_NOMATCH;
 
63
          else if (*n == L_('.') && no_leading_period)
 
64
            return FNM_NOMATCH;
 
65
          break;
 
66
 
 
67
        case L_('\\'):
 
68
          if (!(flags & FNM_NOESCAPE))
 
69
            {
 
70
              c = *p++;
 
71
              if (c == L_('\0'))
 
72
                /* Trailing \ loses.  */
 
73
                return FNM_NOMATCH;
 
74
              c = FOLD (c);
 
75
            }
 
76
          if (n == string_end || FOLD ((UCHAR) *n) != c)
 
77
            return FNM_NOMATCH;
 
78
          break;
 
79
 
 
80
        case L_('*'):
 
81
          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
 
82
            {
 
83
              int res;
 
84
 
 
85
              res = EXT (c, p, n, string_end, no_leading_period,
 
86
                         flags);
 
87
              if (res != -1)
 
88
                return res;
 
89
            }
 
90
 
 
91
          if (n != string_end && *n == L_('.') && no_leading_period)
 
92
            return FNM_NOMATCH;
 
93
 
 
94
          for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
 
95
            {
 
96
              if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
 
97
                {
 
98
                  const CHAR *endp = END (p);
 
99
                  if (endp != p)
 
100
                    {
 
101
                      /* This is a pattern.  Skip over it.  */
 
102
                      p = endp;
 
103
                      continue;
 
104
                    }
 
105
                }
 
106
 
 
107
              if (c == L_('?'))
 
108
                {
 
109
                  /* A ? needs to match one character.  */
 
110
                  if (n == string_end)
 
111
                    /* There isn't another character; no match.  */
 
112
                    return FNM_NOMATCH;
 
113
                  else if (*n == L_('/')
 
114
                           && __builtin_expect (flags & FNM_FILE_NAME, 0))
 
115
                    /* A slash does not match a wildcard under
 
116
                       FNM_FILE_NAME.  */
 
117
                    return FNM_NOMATCH;
 
118
                  else
 
119
                    /* One character of the string is consumed in matching
 
120
                       this ? wildcard, so *??? won't match if there are
 
121
                       less than three characters.  */
 
122
                    ++n;
 
123
                }
 
124
            }
 
125
 
 
126
          if (c == L_('\0'))
 
127
            /* The wildcard(s) is/are the last element of the pattern.
 
128
               If the name is a file name and contains another slash
 
129
               this means it cannot match, unless the FNM_LEADING_DIR
 
130
               flag is set.  */
 
131
            {
 
132
              int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
 
133
 
 
134
              if (flags & FNM_FILE_NAME)
 
135
                {
 
136
                  if (flags & FNM_LEADING_DIR)
 
137
                    result = 0;
 
138
                  else
 
139
                    {
 
140
                      if (MEMCHR (n, L_('/'), string_end - n) == NULL)
 
141
                        result = 0;
 
142
                    }
 
143
                }
 
144
 
 
145
              return result;
 
146
            }
 
147
          else
 
148
            {
 
149
              const CHAR *endp;
 
150
 
 
151
              endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
 
152
                             string_end - n);
 
153
              if (endp == NULL)
 
154
                endp = string_end;
 
155
 
 
156
              if (c == L_('[')
 
157
                  || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
 
158
                      && (c == L_('@') || c == L_('+') || c == L_('!'))
 
159
                      && *p == L_('(')))
 
160
                {
 
161
                  int flags2 = ((flags & FNM_FILE_NAME)
 
162
                                ? flags : (flags & ~FNM_PERIOD));
 
163
                  bool no_leading_period2 = no_leading_period;
 
164
 
 
165
                  for (--p; n < endp; ++n, no_leading_period2 = false)
 
166
                    if (FCT (p, n, string_end, no_leading_period2, flags2)
 
167
                        == 0)
 
168
                      return 0;
 
169
                }
 
170
              else if (c == L_('/') && (flags & FNM_FILE_NAME))
 
171
                {
 
172
                  while (n < string_end && *n != L_('/'))
 
173
                    ++n;
 
174
                  if (n < string_end && *n == L_('/')
 
175
                      && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
 
176
                          == 0))
 
177
                    return 0;
 
178
                }
 
179
              else
 
180
                {
 
181
                  int flags2 = ((flags & FNM_FILE_NAME)
 
182
                                ? flags : (flags & ~FNM_PERIOD));
 
183
                  int no_leading_period2 = no_leading_period;
 
184
 
 
185
                  if (c == L_('\\') && !(flags & FNM_NOESCAPE))
 
186
                    c = *p;
 
187
                  c = FOLD (c);
 
188
                  for (--p; n < endp; ++n, no_leading_period2 = false)
 
189
                    if (FOLD ((UCHAR) *n) == c
 
190
                        && (FCT (p, n, string_end, no_leading_period2, flags2)
 
191
                            == 0))
 
192
                      return 0;
 
193
                }
 
194
            }
 
195
 
 
196
          /* If we come here no match is possible with the wildcard.  */
 
197
          return FNM_NOMATCH;
 
198
 
 
199
        case L_('['):
 
200
          {
 
201
            /* Nonzero if the sense of the character class is inverted.  */
 
202
            const CHAR *p_init = p;
 
203
            const CHAR *n_init = n;
 
204
            register bool not;
 
205
            CHAR cold;
 
206
            UCHAR fn;
 
207
 
 
208
            if (posixly_correct == 0)
 
209
              posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
 
210
 
 
211
            if (n == string_end)
 
212
              return FNM_NOMATCH;
 
213
 
 
214
            if (*n == L_('.') && no_leading_period)
 
215
              return FNM_NOMATCH;
 
216
 
 
217
            if (*n == L_('/') && (flags & FNM_FILE_NAME))
 
218
              /* '/' cannot be matched.  */
 
219
              return FNM_NOMATCH;
 
220
 
 
221
            not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
 
222
            if (not)
 
223
              ++p;
 
224
 
 
225
            fn = FOLD ((UCHAR) *n);
 
226
 
 
227
            c = *p++;
 
228
            for (;;)
 
229
              {
 
230
                bool is_range = false;
 
231
 
 
232
                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
 
233
                  {
 
234
                    if (*p == L_('\0'))
 
235
                      return FNM_NOMATCH;
 
236
                    c = FOLD ((UCHAR) *p);
 
237
                    ++p;
 
238
 
 
239
                    goto normal_bracket;
 
240
                  }
 
241
                else if (c == L_('[') && *p == L_(':'))
 
242
                  {
 
243
                    /* Leave room for the null.  */
 
244
                    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
 
245
                    size_t c1 = 0;
244
246
#if defined _LIBC || WIDE_CHAR_SUPPORT
245
 
                    wctype_t wt;
 
247
                    wctype_t wt;
246
248
#endif
247
 
                    const CHAR *startp = p;
248
 
 
249
 
                    for (;;)
250
 
                      {
251
 
                        if (c1 == CHAR_CLASS_MAX_LENGTH)
252
 
                          /* The name is too long and therefore the pattern
253
 
                             is ill-formed.  */
254
 
                          return FNM_NOMATCH;
255
 
 
256
 
                        c = *++p;
257
 
                        if (c == L_(':') && p[1] == L_(']'))
258
 
                          {
259
 
                            p += 2;
260
 
                            break;
261
 
                          }
262
 
                        if (c < L_('a') || c >= L_('z'))
263
 
                          {
264
 
                            /* This cannot possibly be a character class name.
265
 
                               Match it as a normal range.  */
266
 
                            p = startp;
267
 
                            c = L_('[');
268
 
                            goto normal_bracket;
269
 
                          }
270
 
                        str[c1++] = c;
271
 
                      }
272
 
                    str[c1] = L_('\0');
 
249
                    const CHAR *startp = p;
 
250
 
 
251
                    for (;;)
 
252
                      {
 
253
                        if (c1 == CHAR_CLASS_MAX_LENGTH)
 
254
                          /* The name is too long and therefore the pattern
 
255
                             is ill-formed.  */
 
256
                          return FNM_NOMATCH;
 
257
 
 
258
                        c = *++p;
 
259
                        if (c == L_(':') && p[1] == L_(']'))
 
260
                          {
 
261
                            p += 2;
 
262
                            break;
 
263
                          }
 
264
                        if (c < L_('a') || c >= L_('z'))
 
265
                          {
 
266
                            /* This cannot possibly be a character class name.
 
267
                               Match it as a normal range.  */
 
268
                            p = startp;
 
269
                            c = L_('[');
 
270
                            goto normal_bracket;
 
271
                          }
 
272
                        str[c1++] = c;
 
273
                      }
 
274
                    str[c1] = L_('\0');
273
275
 
274
276
#if defined _LIBC || WIDE_CHAR_SUPPORT
275
 
                    wt = IS_CHAR_CLASS (str);
276
 
                    if (wt == 0)
277
 
                      /* Invalid character class name.  */
278
 
                      return FNM_NOMATCH;
 
277
                    wt = IS_CHAR_CLASS (str);
 
278
                    if (wt == 0)
 
279
                      /* Invalid character class name.  */
 
280
                      return FNM_NOMATCH;
279
281
 
280
282
# if defined _LIBC && ! WIDE_CHAR_VERSION
281
 
                    /* The following code is glibc specific but does
282
 
                       there a good job in speeding up the code since
283
 
                       we can avoid the btowc() call.  */
284
 
                    if (_ISCTYPE ((UCHAR) *n, wt))
285
 
                      goto matched;
 
283
                    /* The following code is glibc specific but does
 
284
                       there a good job in speeding up the code since
 
285
                       we can avoid the btowc() call.  */
 
286
                    if (_ISCTYPE ((UCHAR) *n, wt))
 
287
                      goto matched;
286
288
# else
287
 
                    if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
288
 
                      goto matched;
 
289
                    if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
 
290
                      goto matched;
289
291
# endif
290
292
#else
291
 
                    if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n))
292
 
                        || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n))
293
 
                        || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n))
294
 
                        || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n))
295
 
                        || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n))
296
 
                        || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n))
297
 
                        || (STREQ (str, L_("lower")) && islower ((UCHAR) *n))
298
 
                        || (STREQ (str, L_("print")) && isprint ((UCHAR) *n))
299
 
                        || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n))
300
 
                        || (STREQ (str, L_("space")) && isspace ((UCHAR) *n))
301
 
                        || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n))
302
 
                        || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n)))
303
 
                      goto matched;
 
293
                    if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n))
 
294
                        || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n))
 
295
                        || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n))
 
296
                        || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n))
 
297
                        || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n))
 
298
                        || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n))
 
299
                        || (STREQ (str, L_("lower")) && islower ((UCHAR) *n))
 
300
                        || (STREQ (str, L_("print")) && isprint ((UCHAR) *n))
 
301
                        || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n))
 
302
                        || (STREQ (str, L_("space")) && isspace ((UCHAR) *n))
 
303
                        || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n))
 
304
                        || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n)))
 
305
                      goto matched;
304
306
#endif
305
 
                    c = *p++;
306
 
                  }
 
307
                    c = *p++;
 
308
                  }
307
309
#ifdef _LIBC
308
 
                else if (c == L_('[') && *p == L_('='))
309
 
                  {
310
 
                    UCHAR str[1];
311
 
                    uint32_t nrules =
312
 
                      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
313
 
                    const CHAR *startp = p;
314
 
 
315
 
                    c = *++p;
316
 
                    if (c == L_('\0'))
317
 
                      {
318
 
                        p = startp;
319
 
                        c = L_('[');
320
 
                        goto normal_bracket;
321
 
                      }
322
 
                    str[0] = c;
323
 
 
324
 
                    c = *++p;
325
 
                    if (c != L_('=') || p[1] != L_(']'))
326
 
                      {
327
 
                        p = startp;
328
 
                        c = L_('[');
329
 
                        goto normal_bracket;
330
 
                      }
331
 
                    p += 2;
332
 
 
333
 
                    if (nrules == 0)
334
 
                      {
335
 
                        if ((UCHAR) *n == str[0])
336
 
                          goto matched;
337
 
                      }
338
 
                    else
339
 
                      {
340
 
                        const int32_t *table;
 
310
                else if (c == L_('[') && *p == L_('='))
 
311
                  {
 
312
                    UCHAR str[1];
 
313
                    uint32_t nrules =
 
314
                      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
 
315
                    const CHAR *startp = p;
 
316
 
 
317
                    c = *++p;
 
318
                    if (c == L_('\0'))
 
319
                      {
 
320
                        p = startp;
 
321
                        c = L_('[');
 
322
                        goto normal_bracket;
 
323
                      }
 
324
                    str[0] = c;
 
325
 
 
326
                    c = *++p;
 
327
                    if (c != L_('=') || p[1] != L_(']'))
 
328
                      {
 
329
                        p = startp;
 
330
                        c = L_('[');
 
331
                        goto normal_bracket;
 
332
                      }
 
333
                    p += 2;
 
334
 
 
335
                    if (nrules == 0)
 
336
                      {
 
337
                        if ((UCHAR) *n == str[0])
 
338
                          goto matched;
 
339
                      }
 
340
                    else
 
341
                      {
 
342
                        const int32_t *table;
341
343
# if WIDE_CHAR_VERSION
342
 
                        const int32_t *weights;
343
 
                        const int32_t *extra;
 
344
                        const int32_t *weights;
 
345
                        const int32_t *extra;
344
346
# else
345
 
                        const unsigned char *weights;
346
 
                        const unsigned char *extra;
 
347
                        const unsigned char *weights;
 
348
                        const unsigned char *extra;
347
349
# endif
348
 
                        const int32_t *indirect;
349
 
                        int32_t idx;
350
 
                        const UCHAR *cp = (const UCHAR *) str;
 
350
                        const int32_t *indirect;
 
351
                        int32_t idx;
 
352
                        const UCHAR *cp = (const UCHAR *) str;
351
353
 
352
 
                        /* This #include defines a local function!  */
 
354
                        /* This #include defines a local function!  */
353
355
# if WIDE_CHAR_VERSION
354
356
#  include <locale/weightwc.h>
355
357
# else
357
359
# endif
358
360
 
359
361
# if WIDE_CHAR_VERSION
360
 
                        table = (const int32_t *)
361
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
362
 
                        weights = (const int32_t *)
363
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
364
 
                        extra = (const int32_t *)
365
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
366
 
                        indirect = (const int32_t *)
367
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
 
362
                        table = (const int32_t *)
 
363
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
 
364
                        weights = (const int32_t *)
 
365
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
 
366
                        extra = (const int32_t *)
 
367
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
 
368
                        indirect = (const int32_t *)
 
369
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
368
370
# else
369
 
                        table = (const int32_t *)
370
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
371
 
                        weights = (const unsigned char *)
372
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
373
 
                        extra = (const unsigned char *)
374
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
375
 
                        indirect = (const int32_t *)
376
 
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
 
371
                        table = (const int32_t *)
 
372
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
 
373
                        weights = (const unsigned char *)
 
374
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
 
375
                        extra = (const unsigned char *)
 
376
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
 
377
                        indirect = (const int32_t *)
 
378
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
377
379
# endif
378
380
 
379
 
                        idx = findidx (&cp);
380
 
                        if (idx != 0)
381
 
                          {
382
 
                            /* We found a table entry.  Now see whether the
383
 
                               character we are currently at has the same
384
 
                               equivalance class value.  */
385
 
                            int len = weights[idx];
386
 
                            int32_t idx2;
387
 
                            const UCHAR *np = (const UCHAR *) n;
388
 
 
389
 
                            idx2 = findidx (&np);
390
 
                            if (idx2 != 0 && len == weights[idx2])
391
 
                              {
392
 
                                int cnt = 0;
393
 
 
394
 
                                while (cnt < len
395
 
                                       && (weights[idx + 1 + cnt]
396
 
                                           == weights[idx2 + 1 + cnt]))
397
 
                                  ++cnt;
398
 
 
399
 
                                if (cnt == len)
400
 
                                  goto matched;
401
 
                              }
402
 
                          }
403
 
                      }
404
 
 
405
 
                    c = *p++;
406
 
                  }
 
381
                        idx = findidx (&cp);
 
382
                        if (idx != 0)
 
383
                          {
 
384
                            /* We found a table entry.  Now see whether the
 
385
                               character we are currently at has the same
 
386
                               equivalence class value.  */
 
387
                            int len = weights[idx & 0xffffff];
 
388
                            int32_t idx2;
 
389
                            const UCHAR *np = (const UCHAR *) n;
 
390
 
 
391
                            idx2 = findidx (&np);
 
392
                            if (idx2 != 0
 
393
                                && (idx >> 24) == (idx2 >> 24)
 
394
                                && len == weights[idx2 & 0xffffff])
 
395
                              {
 
396
                                int cnt = 0;
 
397
 
 
398
                                idx &= 0xffffff;
 
399
                                idx2 &= 0xffffff;
 
400
 
 
401
                                while (cnt < len
 
402
                                       && (weights[idx + 1 + cnt]
 
403
                                           == weights[idx2 + 1 + cnt]))
 
404
                                  ++cnt;
 
405
 
 
406
                                if (cnt == len)
 
407
                                  goto matched;
 
408
                              }
 
409
                          }
 
410
                      }
 
411
 
 
412
                    c = *p++;
 
413
                  }
407
414
#endif
408
 
                else if (c == L_('\0'))
409
 
                  /* [ (unterminated) loses.  */
410
 
                  return FNM_NOMATCH;
411
 
                else
412
 
                  {
413
 
                    bool is_range = false;
414
 
 
 
415
                else if (c == L_('\0'))
 
416
                  {
 
417
                    /* [ unterminated, treat as normal character.  */
 
418
                    p = p_init;
 
419
                    n = n_init;
 
420
                    c = L_('[');
 
421
                    goto normal_match;
 
422
                  }
 
423
                else
 
424
                  {
415
425
#ifdef _LIBC
416
 
                    bool is_seqval = false;
417
 
 
418
 
                    if (c == L_('[') && *p == L_('.'))
419
 
                      {
420
 
                        uint32_t nrules =
421
 
                          _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
422
 
                        const CHAR *startp = p;
423
 
                        size_t c1 = 0;
424
 
 
425
 
                        while (1)
426
 
                          {
427
 
                            c = *++p;
428
 
                            if (c == L_('.') && p[1] == L_(']'))
429
 
                              {
430
 
                                p += 2;
431
 
                                break;
432
 
                              }
433
 
                            if (c == '\0')
434
 
                              return FNM_NOMATCH;
435
 
                            ++c1;
436
 
                          }
437
 
 
438
 
                        /* We have to handling the symbols differently in
439
 
                           ranges since then the collation sequence is
440
 
                           important.  */
441
 
                        is_range = *p == L_('-') && p[1] != L_('\0');
442
 
 
443
 
                        if (nrules == 0)
444
 
                          {
445
 
                            /* There are no names defined in the collation
446
 
                               data.  Therefore we only accept the trivial
447
 
                               names consisting of the character itself.  */
448
 
                            if (c1 != 1)
449
 
                              return FNM_NOMATCH;
450
 
 
451
 
                            if (!is_range && *n == startp[1])
452
 
                              goto matched;
453
 
 
454
 
                            cold = startp[1];
455
 
                            c = *p++;
456
 
                          }
457
 
                        else
458
 
                          {
459
 
                            int32_t table_size;
460
 
                            const int32_t *symb_table;
 
426
                    bool is_seqval = false;
 
427
 
 
428
                    if (c == L_('[') && *p == L_('.'))
 
429
                      {
 
430
                        uint32_t nrules =
 
431
                          _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
 
432
                        const CHAR *startp = p;
 
433
                        size_t c1 = 0;
 
434
 
 
435
                        while (1)
 
436
                          {
 
437
                            c = *++p;
 
438
                            if (c == L_('.') && p[1] == L_(']'))
 
439
                              {
 
440
                                p += 2;
 
441
                                break;
 
442
                              }
 
443
                            if (c == '\0')
 
444
                              return FNM_NOMATCH;
 
445
                            ++c1;
 
446
                          }
 
447
 
 
448
                        /* We have to handling the symbols differently in
 
449
                           ranges since then the collation sequence is
 
450
                           important.  */
 
451
                        is_range = *p == L_('-') && p[1] != L_('\0');
 
452
 
 
453
                        if (nrules == 0)
 
454
                          {
 
455
                            /* There are no names defined in the collation
 
456
                               data.  Therefore we only accept the trivial
 
457
                               names consisting of the character itself.  */
 
458
                            if (c1 != 1)
 
459
                              return FNM_NOMATCH;
 
460
 
 
461
                            if (!is_range && *n == startp[1])
 
462
                              goto matched;
 
463
 
 
464
                            cold = startp[1];
 
465
                            c = *p++;
 
466
                          }
 
467
                        else
 
468
                          {
 
469
                            int32_t table_size;
 
470
                            const int32_t *symb_table;
461
471
# ifdef WIDE_CHAR_VERSION
462
 
                            char str[c1];
463
 
                            size_t strcnt;
 
472
                            char str[c1];
 
473
                            size_t strcnt;
464
474
# else
465
475
#  define str (startp + 1)
466
476
# endif
467
 
                            const unsigned char *extra;
468
 
                            int32_t idx;
469
 
                            int32_t elem;
470
 
                            int32_t second;
471
 
                            int32_t hash;
472
 
 
473
 
# ifdef WIDE_CHAR_VERSION
474
 
                            /* We have to convert the name to a single-byte
475
 
                               string.  This is possible since the names
476
 
                               consist of ASCII characters and the internal
477
 
                               representation is UCS4.  */
478
 
                            for (strcnt = 0; strcnt < c1; ++strcnt)
479
 
                              str[strcnt] = startp[1 + strcnt];
480
 
# endif
481
 
 
482
 
                            table_size =
483
 
                              _NL_CURRENT_WORD (LC_COLLATE,
484
 
                                                _NL_COLLATE_SYMB_HASH_SIZEMB);
485
 
                            symb_table = (const int32_t *)
486
 
                              _NL_CURRENT (LC_COLLATE,
487
 
                                           _NL_COLLATE_SYMB_TABLEMB);
488
 
                            extra = (const unsigned char *)
489
 
                              _NL_CURRENT (LC_COLLATE,
490
 
                                           _NL_COLLATE_SYMB_EXTRAMB);
491
 
 
492
 
                            /* Locate the character in the hashing table.  */
493
 
                            hash = elem_hash (str, c1);
494
 
 
495
 
                            idx = 0;
496
 
                            elem = hash % table_size;
497
 
                            if (symb_table[2 * elem] != 0)
498
 
                              {
499
 
                                second = hash % (table_size - 2) + 1;
500
 
 
501
 
                                do
502
 
                                  {
503
 
                                    /* First compare the hashing value.  */
504
 
                                    if (symb_table[2 * elem] == hash
505
 
                                        && (c1
506
 
                                            == extra[symb_table[2 * elem + 1]])
507
 
                                        && memcmp (str,
508
 
                                                   &extra[symb_table[2 * elem
509
 
                                                                     + 1]
510
 
                                                          + 1], c1) == 0)
511
 
                                      {
512
 
                                        /* Yep, this is the entry.  */
513
 
                                        idx = symb_table[2 * elem + 1];
514
 
                                        idx += 1 + extra[idx];
515
 
                                        break;
516
 
                                      }
517
 
 
518
 
                                    /* Next entry.  */
519
 
                                    elem += second;
520
 
                                  }
521
 
                                while (symb_table[2 * elem] != 0);
522
 
                              }
523
 
 
524
 
                            if (symb_table[2 * elem] != 0)
525
 
                              {
526
 
                                /* Compare the byte sequence but only if
527
 
                                   this is not part of a range.  */
528
 
# ifdef WIDE_CHAR_VERSION
529
 
                                int32_t *wextra;
530
 
 
531
 
                                idx += 1 + extra[idx];
532
 
                                /* Adjust for the alignment.  */
533
 
                                idx = (idx + 3) & ~3;
534
 
 
535
 
                                wextra = (int32_t *) &extra[idx + 4];
536
 
# endif
537
 
 
538
 
                                if (! is_range)
539
 
                                  {
540
 
# ifdef WIDE_CHAR_VERSION
541
 
                                    for (c1 = 0;
542
 
                                         (int32_t) c1 < wextra[idx];
543
 
                                         ++c1)
544
 
                                      if (n[c1] != wextra[1 + c1])
545
 
                                        break;
546
 
 
547
 
                                    if ((int32_t) c1 == wextra[idx])
548
 
                                      goto matched;
549
 
# else
550
 
                                    for (c1 = 0; c1 < extra[idx]; ++c1)
551
 
                                      if (n[c1] != extra[1 + c1])
552
 
                                        break;
553
 
 
554
 
                                    if (c1 == extra[idx])
555
 
                                      goto matched;
556
 
# endif
557
 
                                  }
558
 
 
559
 
                                /* Get the collation sequence value.  */
560
 
                                is_seqval = true;
561
 
# ifdef WIDE_CHAR_VERSION
562
 
                                cold = wextra[1 + wextra[idx]];
563
 
# else
564
 
                                /* Adjust for the alignment.  */
565
 
                                idx += 1 + extra[idx];
566
 
                                idx = (idx + 3) & ~4;
567
 
                                cold = *((int32_t *) &extra[idx]);
568
 
# endif
569
 
 
570
 
                                c = *p++;
571
 
                              }
572
 
                            else if (c1 == 1)
573
 
                              {
574
 
                                /* No valid character.  Match it as a
575
 
                                   single byte.  */
576
 
                                if (!is_range && *n == str[0])
577
 
                                  goto matched;
578
 
 
579
 
                                cold = str[0];
580
 
                                c = *p++;
581
 
                              }
582
 
                            else
583
 
                              return FNM_NOMATCH;
584
 
                          }
585
 
                      }
586
 
                    else
 
477
                            const unsigned char *extra;
 
478
                            int32_t idx;
 
479
                            int32_t elem;
 
480
                            int32_t second;
 
481
                            int32_t hash;
 
482
 
 
483
# ifdef WIDE_CHAR_VERSION
 
484
                            /* We have to convert the name to a single-byte
 
485
                               string.  This is possible since the names
 
486
                               consist of ASCII characters and the internal
 
487
                               representation is UCS4.  */
 
488
                            for (strcnt = 0; strcnt < c1; ++strcnt)
 
489
                              str[strcnt] = startp[1 + strcnt];
 
490
# endif
 
491
 
 
492
                            table_size =
 
493
                              _NL_CURRENT_WORD (LC_COLLATE,
 
494
                                                _NL_COLLATE_SYMB_HASH_SIZEMB);
 
495
                            symb_table = (const int32_t *)
 
496
                              _NL_CURRENT (LC_COLLATE,
 
497
                                           _NL_COLLATE_SYMB_TABLEMB);
 
498
                            extra = (const unsigned char *)
 
499
                              _NL_CURRENT (LC_COLLATE,
 
500
                                           _NL_COLLATE_SYMB_EXTRAMB);
 
501
 
 
502
                            /* Locate the character in the hashing table.  */
 
503
                            hash = elem_hash (str, c1);
 
504
 
 
505
                            idx = 0;
 
506
                            elem = hash % table_size;
 
507
                            if (symb_table[2 * elem] != 0)
 
508
                              {
 
509
                                second = hash % (table_size - 2) + 1;
 
510
 
 
511
                                do
 
512
                                  {
 
513
                                    /* First compare the hashing value.  */
 
514
                                    if (symb_table[2 * elem] == hash
 
515
                                        && (c1
 
516
                                            == extra[symb_table[2 * elem + 1]])
 
517
                                        && memcmp (str,
 
518
                                                   &extra[symb_table[2 * elem
 
519
                                                                     + 1]
 
520
                                                          + 1], c1) == 0)
 
521
                                      {
 
522
                                        /* Yep, this is the entry.  */
 
523
                                        idx = symb_table[2 * elem + 1];
 
524
                                        idx += 1 + extra[idx];
 
525
                                        break;
 
526
                                      }
 
527
 
 
528
                                    /* Next entry.  */
 
529
                                    elem += second;
 
530
                                  }
 
531
                                while (symb_table[2 * elem] != 0);
 
532
                              }
 
533
 
 
534
                            if (symb_table[2 * elem] != 0)
 
535
                              {
 
536
                                /* Compare the byte sequence but only if
 
537
                                   this is not part of a range.  */
 
538
# ifdef WIDE_CHAR_VERSION
 
539
                                int32_t *wextra;
 
540
 
 
541
                                idx += 1 + extra[idx];
 
542
                                /* Adjust for the alignment.  */
 
543
                                idx = (idx + 3) & ~3;
 
544
 
 
545
                                wextra = (int32_t *) &extra[idx + 4];
 
546
# endif
 
547
 
 
548
                                if (! is_range)
 
549
                                  {
 
550
# ifdef WIDE_CHAR_VERSION
 
551
                                    for (c1 = 0;
 
552
                                         (int32_t) c1 < wextra[idx];
 
553
                                         ++c1)
 
554
                                      if (n[c1] != wextra[1 + c1])
 
555
                                        break;
 
556
 
 
557
                                    if ((int32_t) c1 == wextra[idx])
 
558
                                      goto matched;
 
559
# else
 
560
                                    for (c1 = 0; c1 < extra[idx]; ++c1)
 
561
                                      if (n[c1] != extra[1 + c1])
 
562
                                        break;
 
563
 
 
564
                                    if (c1 == extra[idx])
 
565
                                      goto matched;
 
566
# endif
 
567
                                  }
 
568
 
 
569
                                /* Get the collation sequence value.  */
 
570
                                is_seqval = true;
 
571
# ifdef WIDE_CHAR_VERSION
 
572
                                cold = wextra[1 + wextra[idx]];
 
573
# else
 
574
                                /* Adjust for the alignment.  */
 
575
                                idx += 1 + extra[idx];
 
576
                                idx = (idx + 3) & ~4;
 
577
                                cold = *((int32_t *) &extra[idx]);
 
578
# endif
 
579
 
 
580
                                c = *p++;
 
581
                              }
 
582
                            else if (c1 == 1)
 
583
                              {
 
584
                                /* No valid character.  Match it as a
 
585
                                   single byte.  */
 
586
                                if (!is_range && *n == str[0])
 
587
                                  goto matched;
 
588
 
 
589
                                cold = str[0];
 
590
                                c = *p++;
 
591
                              }
 
592
                            else
 
593
                              return FNM_NOMATCH;
 
594
                          }
 
595
                      }
 
596
                    else
587
597
# undef str
588
598
#endif
589
 
                      {
590
 
                        c = FOLD (c);
591
 
                      normal_bracket:
592
 
 
593
 
                        /* We have to handling the symbols differently in
594
 
                           ranges since then the collation sequence is
595
 
                           important.  */
596
 
                        is_range = (*p == L_('-') && p[1] != L_('\0')
597
 
                                    && p[1] != L_(']'));
598
 
 
599
 
                        if (!is_range && c == fn)
600
 
                          goto matched;
 
599
                      {
 
600
                        c = FOLD (c);
 
601
                      normal_bracket:
 
602
 
 
603
                        /* We have to handling the symbols differently in
 
604
                           ranges since then the collation sequence is
 
605
                           important.  */
 
606
                        is_range = (*p == L_('-') && p[1] != L_('\0')
 
607
                                    && p[1] != L_(']'));
 
608
 
 
609
                        if (!is_range && c == fn)
 
610
                          goto matched;
601
611
 
602
612
#if _LIBC
603
 
                        /* This is needed if we goto normal_bracket; from
604
 
                           outside of is_seqval's scope.  */
605
 
                        is_seqval = false;
 
613
                        /* This is needed if we goto normal_bracket; from
 
614
                           outside of is_seqval's scope.  */
 
615
                        is_seqval = false;
606
616
#endif
607
617
 
608
 
                        cold = c;
609
 
                        c = *p++;
610
 
                      }
 
618
                        cold = c;
 
619
                        c = *p++;
 
620
                      }
611
621
 
612
 
                    if (c == L_('-') && *p != L_(']'))
613
 
                      {
 
622
                    if (c == L_('-') && *p != L_(']'))
 
623
                      {
614
624
#if _LIBC
615
 
                        /* We have to find the collation sequence
616
 
                           value for C.  Collation sequence is nothing
617
 
                           we can regularly access.  The sequence
618
 
                           value is defined by the order in which the
619
 
                           definitions of the collation values for the
620
 
                           various characters appear in the source
621
 
                           file.  A strange concept, nowhere
622
 
                           documented.  */
623
 
                        uint32_t fcollseq;
624
 
                        uint32_t lcollseq;
625
 
                        UCHAR cend = *p++;
 
625
                        /* We have to find the collation sequence
 
626
                           value for C.  Collation sequence is nothing
 
627
                           we can regularly access.  The sequence
 
628
                           value is defined by the order in which the
 
629
                           definitions of the collation values for the
 
630
                           various characters appear in the source
 
631
                           file.  A strange concept, nowhere
 
632
                           documented.  */
 
633
                        uint32_t fcollseq;
 
634
                        uint32_t lcollseq;
 
635
                        UCHAR cend = *p++;
626
636
 
627
637
# ifdef WIDE_CHAR_VERSION
628
 
                        /* Search in the `names' array for the characters.  */
629
 
                        fcollseq = __collseq_table_lookup (collseq, fn);
630
 
                        if (fcollseq == ~((uint32_t) 0))
631
 
                          /* XXX We don't know anything about the character
632
 
                             we are supposed to match.  This means we are
633
 
                             failing.  */
634
 
                          goto range_not_matched;
 
638
                        /* Search in the 'names' array for the characters.  */
 
639
                        fcollseq = __collseq_table_lookup (collseq, fn);
 
640
                        if (fcollseq == ~((uint32_t) 0))
 
641
                          /* XXX We don't know anything about the character
 
642
                             we are supposed to match.  This means we are
 
643
                             failing.  */
 
644
                          goto range_not_matched;
635
645
 
636
 
                        if (is_seqval)
637
 
                          lcollseq = cold;
638
 
                        else
639
 
                          lcollseq = __collseq_table_lookup (collseq, cold);
 
646
                        if (is_seqval)
 
647
                          lcollseq = cold;
 
648
                        else
 
649
                          lcollseq = __collseq_table_lookup (collseq, cold);
640
650
# else
641
 
                        fcollseq = collseq[fn];
642
 
                        lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
 
651
                        fcollseq = collseq[fn];
 
652
                        lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
643
653
# endif
644
654
 
645
 
                        is_seqval = false;
646
 
                        if (cend == L_('[') && *p == L_('.'))
647
 
                          {
648
 
                            uint32_t nrules =
649
 
                              _NL_CURRENT_WORD (LC_COLLATE,
650
 
                                                _NL_COLLATE_NRULES);
651
 
                            const CHAR *startp = p;
652
 
                            size_t c1 = 0;
653
 
 
654
 
                            while (1)
655
 
                              {
656
 
                                c = *++p;
657
 
                                if (c == L_('.') && p[1] == L_(']'))
658
 
                                  {
659
 
                                    p += 2;
660
 
                                    break;
661
 
                                  }
662
 
                                if (c == '\0')
663
 
                                  return FNM_NOMATCH;
664
 
                                ++c1;
665
 
                              }
666
 
 
667
 
                            if (nrules == 0)
668
 
                              {
669
 
                                /* There are no names defined in the
670
 
                                   collation data.  Therefore we only
671
 
                                   accept the trivial names consisting
672
 
                                   of the character itself.  */
673
 
                                if (c1 != 1)
674
 
                                  return FNM_NOMATCH;
675
 
 
676
 
                                cend = startp[1];
677
 
                              }
678
 
                            else
679
 
                              {
680
 
                                int32_t table_size;
681
 
                                const int32_t *symb_table;
 
655
                        is_seqval = false;
 
656
                        if (cend == L_('[') && *p == L_('.'))
 
657
                          {
 
658
                            uint32_t nrules =
 
659
                              _NL_CURRENT_WORD (LC_COLLATE,
 
660
                                                _NL_COLLATE_NRULES);
 
661
                            const CHAR *startp = p;
 
662
                            size_t c1 = 0;
 
663
 
 
664
                            while (1)
 
665
                              {
 
666
                                c = *++p;
 
667
                                if (c == L_('.') && p[1] == L_(']'))
 
668
                                  {
 
669
                                    p += 2;
 
670
                                    break;
 
671
                                  }
 
672
                                if (c == '\0')
 
673
                                  return FNM_NOMATCH;
 
674
                                ++c1;
 
675
                              }
 
676
 
 
677
                            if (nrules == 0)
 
678
                              {
 
679
                                /* There are no names defined in the
 
680
                                   collation data.  Therefore we only
 
681
                                   accept the trivial names consisting
 
682
                                   of the character itself.  */
 
683
                                if (c1 != 1)
 
684
                                  return FNM_NOMATCH;
 
685
 
 
686
                                cend = startp[1];
 
687
                              }
 
688
                            else
 
689
                              {
 
690
                                int32_t table_size;
 
691
                                const int32_t *symb_table;
682
692
# ifdef WIDE_CHAR_VERSION
683
 
                                char str[c1];
684
 
                                size_t strcnt;
 
693
                                char str[c1];
 
694
                                size_t strcnt;
685
695
# else
686
696
#  define str (startp + 1)
687
697
# endif
688
 
                                const unsigned char *extra;
689
 
                                int32_t idx;
690
 
                                int32_t elem;
691
 
                                int32_t second;
692
 
                                int32_t hash;
 
698
                                const unsigned char *extra;
 
699
                                int32_t idx;
 
700
                                int32_t elem;
 
701
                                int32_t second;
 
702
                                int32_t hash;
693
703
 
694
704
# ifdef WIDE_CHAR_VERSION
695
 
                                /* We have to convert the name to a single-byte
696
 
                                   string.  This is possible since the names
697
 
                                   consist of ASCII characters and the internal
698
 
                                   representation is UCS4.  */
699
 
                                for (strcnt = 0; strcnt < c1; ++strcnt)
700
 
                                  str[strcnt] = startp[1 + strcnt];
 
705
                                /* We have to convert the name to a single-byte
 
706
                                   string.  This is possible since the names
 
707
                                   consist of ASCII characters and the internal
 
708
                                   representation is UCS4.  */
 
709
                                for (strcnt = 0; strcnt < c1; ++strcnt)
 
710
                                  str[strcnt] = startp[1 + strcnt];
701
711
# endif
702
712
 
703
 
                                table_size =
704
 
                                  _NL_CURRENT_WORD (LC_COLLATE,
705
 
                                                    _NL_COLLATE_SYMB_HASH_SIZEMB);
706
 
                                symb_table = (const int32_t *)
707
 
                                  _NL_CURRENT (LC_COLLATE,
708
 
                                               _NL_COLLATE_SYMB_TABLEMB);
709
 
                                extra = (const unsigned char *)
710
 
                                  _NL_CURRENT (LC_COLLATE,
711
 
                                               _NL_COLLATE_SYMB_EXTRAMB);
 
713
                                table_size =
 
714
                                  _NL_CURRENT_WORD (LC_COLLATE,
 
715
                                                    _NL_COLLATE_SYMB_HASH_SIZEMB);
 
716
                                symb_table = (const int32_t *)
 
717
                                  _NL_CURRENT (LC_COLLATE,
 
718
                                               _NL_COLLATE_SYMB_TABLEMB);
 
719
                                extra = (const unsigned char *)
 
720
                                  _NL_CURRENT (LC_COLLATE,
 
721
                                               _NL_COLLATE_SYMB_EXTRAMB);
712
722
 
713
 
                                /* Locate the character in the hashing
 
723
                                /* Locate the character in the hashing
714
724
                                   table.  */
715
 
                                hash = elem_hash (str, c1);
716
 
 
717
 
                                idx = 0;
718
 
                                elem = hash % table_size;
719
 
                                if (symb_table[2 * elem] != 0)
720
 
                                  {
721
 
                                    second = hash % (table_size - 2) + 1;
722
 
 
723
 
                                    do
724
 
                                      {
725
 
                                        /* First compare the hashing value.  */
726
 
                                        if (symb_table[2 * elem] == hash
727
 
                                            && (c1
728
 
                                                == extra[symb_table[2 * elem + 1]])
729
 
                                            && memcmp (str,
730
 
                                                       &extra[symb_table[2 * elem + 1]
731
 
                                                              + 1], c1) == 0)
732
 
                                          {
733
 
                                            /* Yep, this is the entry.  */
734
 
                                            idx = symb_table[2 * elem + 1];
735
 
                                            idx += 1 + extra[idx];
736
 
                                            break;
737
 
                                          }
738
 
 
739
 
                                        /* Next entry.  */
740
 
                                        elem += second;
741
 
                                      }
742
 
                                    while (symb_table[2 * elem] != 0);
743
 
                                  }
744
 
 
745
 
                                if (symb_table[2 * elem] != 0)
746
 
                                  {
747
 
                                    /* Compare the byte sequence but only if
748
 
                                       this is not part of a range.  */
 
725
                                hash = elem_hash (str, c1);
 
726
 
 
727
                                idx = 0;
 
728
                                elem = hash % table_size;
 
729
                                if (symb_table[2 * elem] != 0)
 
730
                                  {
 
731
                                    second = hash % (table_size - 2) + 1;
 
732
 
 
733
                                    do
 
734
                                      {
 
735
                                        /* First compare the hashing value.  */
 
736
                                        if (symb_table[2 * elem] == hash
 
737
                                            && (c1
 
738
                                                == extra[symb_table[2 * elem + 1]])
 
739
                                            && memcmp (str,
 
740
                                                       &extra[symb_table[2 * elem + 1]
 
741
                                                              + 1], c1) == 0)
 
742
                                          {
 
743
                                            /* Yep, this is the entry.  */
 
744
                                            idx = symb_table[2 * elem + 1];
 
745
                                            idx += 1 + extra[idx];
 
746
                                            break;
 
747
                                          }
 
748
 
 
749
                                        /* Next entry.  */
 
750
                                        elem += second;
 
751
                                      }
 
752
                                    while (symb_table[2 * elem] != 0);
 
753
                                  }
 
754
 
 
755
                                if (symb_table[2 * elem] != 0)
 
756
                                  {
 
757
                                    /* Compare the byte sequence but only if
 
758
                                       this is not part of a range.  */
749
759
# ifdef WIDE_CHAR_VERSION
750
 
                                    int32_t *wextra;
751
 
 
752
 
                                    idx += 1 + extra[idx];
753
 
                                    /* Adjust for the alignment.  */
754
 
                                    idx = (idx + 3) & ~4;
755
 
 
756
 
                                    wextra = (int32_t *) &extra[idx + 4];
 
760
                                    int32_t *wextra;
 
761
 
 
762
                                    idx += 1 + extra[idx];
 
763
                                    /* Adjust for the alignment.  */
 
764
                                    idx = (idx + 3) & ~4;
 
765
 
 
766
                                    wextra = (int32_t *) &extra[idx + 4];
757
767
# endif
758
 
                                    /* Get the collation sequence value.  */
759
 
                                    is_seqval = true;
 
768
                                    /* Get the collation sequence value.  */
 
769
                                    is_seqval = true;
760
770
# ifdef WIDE_CHAR_VERSION
761
 
                                    cend = wextra[1 + wextra[idx]];
 
771
                                    cend = wextra[1 + wextra[idx]];
762
772
# else
763
 
                                    /* Adjust for the alignment.  */
764
 
                                    idx += 1 + extra[idx];
765
 
                                    idx = (idx + 3) & ~4;
766
 
                                    cend = *((int32_t *) &extra[idx]);
 
773
                                    /* Adjust for the alignment.  */
 
774
                                    idx += 1 + extra[idx];
 
775
                                    idx = (idx + 3) & ~4;
 
776
                                    cend = *((int32_t *) &extra[idx]);
767
777
# endif
768
 
                                  }
769
 
                                else if (symb_table[2 * elem] != 0 && c1 == 1)
770
 
                                  {
771
 
                                    cend = str[0];
772
 
                                    c = *p++;
773
 
                                  }
774
 
                                else
775
 
                                  return FNM_NOMATCH;
776
 
                              }
 
778
                                  }
 
779
                                else if (symb_table[2 * elem] != 0 && c1 == 1)
 
780
                                  {
 
781
                                    cend = str[0];
 
782
                                    c = *p++;
 
783
                                  }
 
784
                                else
 
785
                                  return FNM_NOMATCH;
 
786
                              }
777
787
# undef str
778
 
                          }
779
 
                        else
780
 
                          {
781
 
                            if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
782
 
                              cend = *p++;
783
 
                            if (cend == L_('\0'))
784
 
                              return FNM_NOMATCH;
785
 
                            cend = FOLD (cend);
786
 
                          }
 
788
                          }
 
789
                        else
 
790
                          {
 
791
                            if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
 
792
                              cend = *p++;
 
793
                            if (cend == L_('\0'))
 
794
                              return FNM_NOMATCH;
 
795
                            cend = FOLD (cend);
 
796
                          }
787
797
 
788
 
                        /* XXX It is not entirely clear to me how to handle
789
 
                           characters which are not mentioned in the
790
 
                           collation specification.  */
791
 
                        if (
 
798
                        /* XXX It is not entirely clear to me how to handle
 
799
                           characters which are not mentioned in the
 
800
                           collation specification.  */
 
801
                        if (
792
802
# ifdef WIDE_CHAR_VERSION
793
 
                            lcollseq == 0xffffffff ||
 
803
                            lcollseq == 0xffffffff ||
794
804
# endif
795
 
                            lcollseq <= fcollseq)
796
 
                          {
797
 
                            /* We have to look at the upper bound.  */
798
 
                            uint32_t hcollseq;
 
805
                            lcollseq <= fcollseq)
 
806
                          {
 
807
                            /* We have to look at the upper bound.  */
 
808
                            uint32_t hcollseq;
799
809
 
800
 
                            if (is_seqval)
801
 
                              hcollseq = cend;
802
 
                            else
803
 
                              {
 
810
                            if (is_seqval)
 
811
                              hcollseq = cend;
 
812
                            else
 
813
                              {
804
814
# ifdef WIDE_CHAR_VERSION
805
 
                                hcollseq =
806
 
                                  __collseq_table_lookup (collseq, cend);
807
 
                                if (hcollseq == ~((uint32_t) 0))
808
 
                                  {
809
 
                                    /* Hum, no information about the upper
810
 
                                       bound.  The matching succeeds if the
811
 
                                       lower bound is matched exactly.  */
812
 
                                    if (lcollseq != fcollseq)
813
 
                                      goto range_not_matched;
 
815
                                hcollseq =
 
816
                                  __collseq_table_lookup (collseq, cend);
 
817
                                if (hcollseq == ~((uint32_t) 0))
 
818
                                  {
 
819
                                    /* Hum, no information about the upper
 
820
                                       bound.  The matching succeeds if the
 
821
                                       lower bound is matched exactly.  */
 
822
                                    if (lcollseq != fcollseq)
 
823
                                      goto range_not_matched;
814
824
 
815
 
                                    goto matched;
816
 
                                  }
 
825
                                    goto matched;
 
826
                                  }
817
827
# else
818
 
                                hcollseq = collseq[cend];
 
828
                                hcollseq = collseq[cend];
819
829
# endif
820
 
                              }
 
830
                              }
821
831
 
822
 
                            if (lcollseq <= hcollseq && fcollseq <= hcollseq)
823
 
                              goto matched;
824
 
                          }
 
832
                            if (lcollseq <= hcollseq && fcollseq <= hcollseq)
 
833
                              goto matched;
 
834
                          }
825
835
# ifdef WIDE_CHAR_VERSION
826
 
                      range_not_matched:
 
836
                      range_not_matched:
827
837
# endif
828
838
#else
829
 
                        /* We use a boring value comparison of the character
830
 
                           values.  This is better than comparing using
831
 
                           `strcoll' since the latter would have surprising
832
 
                           and sometimes fatal consequences.  */
833
 
                        UCHAR cend = *p++;
834
 
 
835
 
                        if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
836
 
                          cend = *p++;
837
 
                        if (cend == L_('\0'))
838
 
                          return FNM_NOMATCH;
839
 
 
840
 
                        /* It is a range.  */
841
 
                        if (cold <= fn && fn <= cend)
842
 
                          goto matched;
 
839
                        /* We use a boring value comparison of the character
 
840
                           values.  This is better than comparing using
 
841
                           'strcoll' since the latter would have surprising
 
842
                           and sometimes fatal consequences.  */
 
843
                        UCHAR cend = *p++;
 
844
 
 
845
                        if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
 
846
                          cend = *p++;
 
847
                        if (cend == L_('\0'))
 
848
                          return FNM_NOMATCH;
 
849
 
 
850
                        /* It is a range.  */
 
851
                        if (cold <= fn && fn <= cend)
 
852
                          goto matched;
843
853
#endif
844
854
 
845
 
                        c = *p++;
846
 
                      }
847
 
                  }
848
 
 
849
 
                if (c == L_(']'))
850
 
                  break;
851
 
              }
852
 
 
853
 
            if (!not)
854
 
              return FNM_NOMATCH;
855
 
            break;
856
 
 
857
 
          matched:
858
 
            /* Skip the rest of the [...] that already matched.  */
859
 
            do
860
 
              {
861
 
              ignore_next:
862
 
                c = *p++;
863
 
 
864
 
                if (c == L_('\0'))
865
 
                  /* [... (unterminated) loses.  */
866
 
                  return FNM_NOMATCH;
867
 
 
868
 
                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
869
 
                  {
870
 
                    if (*p == L_('\0'))
871
 
                      return FNM_NOMATCH;
872
 
                    /* XXX 1003.2d11 is unclear if this is right.  */
873
 
                    ++p;
874
 
                  }
875
 
                else if (c == L_('[') && *p == L_(':'))
876
 
                  {
877
 
                    int c1 = 0;
878
 
                    const CHAR *startp = p;
879
 
 
880
 
                    while (1)
881
 
                      {
882
 
                        c = *++p;
883
 
                        if (++c1 == CHAR_CLASS_MAX_LENGTH)
884
 
                          return FNM_NOMATCH;
885
 
 
886
 
                        if (*p == L_(':') && p[1] == L_(']'))
887
 
                          break;
888
 
 
889
 
                        if (c < L_('a') || c >= L_('z'))
890
 
                          {
891
 
                            p = startp;
892
 
                            goto ignore_next;
893
 
                          }
894
 
                      }
895
 
                    p += 2;
896
 
                    c = *p++;
897
 
                  }
898
 
                else if (c == L_('[') && *p == L_('='))
899
 
                  {
900
 
                    c = *++p;
901
 
                    if (c == L_('\0'))
902
 
                      return FNM_NOMATCH;
903
 
                    c = *++p;
904
 
                    if (c != L_('=') || p[1] != L_(']'))
905
 
                      return FNM_NOMATCH;
906
 
                    p += 2;
907
 
                    c = *p++;
908
 
                  }
909
 
                else if (c == L_('[') && *p == L_('.'))
910
 
                  {
911
 
                    ++p;
912
 
                    while (1)
913
 
                      {
914
 
                        c = *++p;
915
 
                        if (c == '\0')
916
 
                          return FNM_NOMATCH;
917
 
 
918
 
                        if (*p == L_('.') && p[1] == L_(']'))
919
 
                          break;
920
 
                      }
921
 
                    p += 2;
922
 
                    c = *p++;
923
 
                  }
924
 
              }
925
 
            while (c != L_(']'));
926
 
            if (not)
927
 
              return FNM_NOMATCH;
928
 
          }
929
 
          break;
930
 
 
931
 
        case L_('+'):
932
 
        case L_('@'):
933
 
        case L_('!'):
934
 
          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
935
 
            {
936
 
              int res;
937
 
 
938
 
              res = EXT (c, p, n, string_end, no_leading_period, flags);
939
 
              if (res != -1)
940
 
                return res;
941
 
            }
942
 
          goto normal_match;
943
 
 
944
 
        case L_('/'):
945
 
          if (NO_LEADING_PERIOD (flags))
946
 
            {
947
 
              if (n == string_end || c != (UCHAR) *n)
948
 
                return FNM_NOMATCH;
949
 
 
950
 
              new_no_leading_period = true;
951
 
              break;
952
 
            }
953
 
          /* FALLTHROUGH */
954
 
        default:
955
 
        normal_match:
956
 
          if (n == string_end || c != FOLD ((UCHAR) *n))
957
 
            return FNM_NOMATCH;
958
 
        }
 
855
                        c = *p++;
 
856
                      }
 
857
                  }
 
858
 
 
859
                if (c == L_(']'))
 
860
                  break;
 
861
              }
 
862
 
 
863
            if (!not)
 
864
              return FNM_NOMATCH;
 
865
            break;
 
866
 
 
867
          matched:
 
868
            /* Skip the rest of the [...] that already matched.  */
 
869
            do
 
870
              {
 
871
              ignore_next:
 
872
                c = *p++;
 
873
 
 
874
                if (c == L_('\0'))
 
875
                  /* [... (unterminated) loses.  */
 
876
                  return FNM_NOMATCH;
 
877
 
 
878
                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
 
879
                  {
 
880
                    if (*p == L_('\0'))
 
881
                      return FNM_NOMATCH;
 
882
                    /* XXX 1003.2d11 is unclear if this is right.  */
 
883
                    ++p;
 
884
                  }
 
885
                else if (c == L_('[') && *p == L_(':'))
 
886
                  {
 
887
                    int c1 = 0;
 
888
                    const CHAR *startp = p;
 
889
 
 
890
                    while (1)
 
891
                      {
 
892
                        c = *++p;
 
893
                        if (++c1 == CHAR_CLASS_MAX_LENGTH)
 
894
                          return FNM_NOMATCH;
 
895
 
 
896
                        if (*p == L_(':') && p[1] == L_(']'))
 
897
                          break;
 
898
 
 
899
                        if (c < L_('a') || c >= L_('z'))
 
900
                          {
 
901
                            p = startp;
 
902
                            goto ignore_next;
 
903
                          }
 
904
                      }
 
905
                    p += 2;
 
906
                    c = *p++;
 
907
                  }
 
908
                else if (c == L_('[') && *p == L_('='))
 
909
                  {
 
910
                    c = *++p;
 
911
                    if (c == L_('\0'))
 
912
                      return FNM_NOMATCH;
 
913
                    c = *++p;
 
914
                    if (c != L_('=') || p[1] != L_(']'))
 
915
                      return FNM_NOMATCH;
 
916
                    p += 2;
 
917
                    c = *p++;
 
918
                  }
 
919
                else if (c == L_('[') && *p == L_('.'))
 
920
                  {
 
921
                    ++p;
 
922
                    while (1)
 
923
                      {
 
924
                        c = *++p;
 
925
                        if (c == '\0')
 
926
                          return FNM_NOMATCH;
 
927
 
 
928
                        if (*p == L_('.') && p[1] == L_(']'))
 
929
                          break;
 
930
                      }
 
931
                    p += 2;
 
932
                    c = *p++;
 
933
                  }
 
934
              }
 
935
            while (c != L_(']'));
 
936
            if (not)
 
937
              return FNM_NOMATCH;
 
938
          }
 
939
          break;
 
940
 
 
941
        case L_('+'):
 
942
        case L_('@'):
 
943
        case L_('!'):
 
944
          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
 
945
            {
 
946
              int res;
 
947
 
 
948
              res = EXT (c, p, n, string_end, no_leading_period, flags);
 
949
              if (res != -1)
 
950
                return res;
 
951
            }
 
952
          goto normal_match;
 
953
 
 
954
        case L_('/'):
 
955
          if (NO_LEADING_PERIOD (flags))
 
956
            {
 
957
              if (n == string_end || c != (UCHAR) *n)
 
958
                return FNM_NOMATCH;
 
959
 
 
960
              new_no_leading_period = true;
 
961
              break;
 
962
            }
 
963
          /* FALLTHROUGH */
 
964
        default:
 
965
        normal_match:
 
966
          if (n == string_end || c != FOLD ((UCHAR) *n))
 
967
            return FNM_NOMATCH;
 
968
        }
959
969
 
960
970
      no_leading_period = new_no_leading_period;
961
971
      ++n;
984
994
      return pattern;
985
995
    else if (*p == L_('['))
986
996
      {
987
 
        /* Handle brackets special.  */
988
 
        if (posixly_correct == 0)
989
 
          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
 
997
        /* Handle brackets special.  */
 
998
        if (posixly_correct == 0)
 
999
          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
990
1000
 
991
 
        /* Skip the not sign.  We have to recognize it because of a possibly
992
 
           following ']'.  */
993
 
        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
994
 
          ++p;
995
 
        /* A leading ']' is recognized as such.  */
996
 
        if (*p == L_(']'))
997
 
          ++p;
998
 
        /* Skip over all characters of the list.  */
999
 
        while (*p != L_(']'))
1000
 
          if (*p++ == L_('\0'))
1001
 
            /* This is no valid pattern.  */
1002
 
            return pattern;
 
1001
        /* Skip the not sign.  We have to recognize it because of a possibly
 
1002
           following ']'.  */
 
1003
        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
 
1004
          ++p;
 
1005
        /* A leading ']' is recognized as such.  */
 
1006
        if (*p == L_(']'))
 
1007
          ++p;
 
1008
        /* Skip over all characters of the list.  */
 
1009
        while (*p != L_(']'))
 
1010
          if (*p++ == L_('\0'))
 
1011
            /* This is no valid pattern.  */
 
1012
            return pattern;
1003
1013
      }
1004
1014
    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1005
 
              || *p == L_('!')) && p[1] == L_('('))
 
1015
              || *p == L_('!')) && p[1] == L_('('))
1006
1016
      p = END (p + 1);
1007
1017
    else if (*p == L_(')'))
1008
1018
      break;
1037
1047
      return -1;
1038
1048
    else if (*p == L_('['))
1039
1049
      {
1040
 
        /* Handle brackets special.  */
1041
 
        if (posixly_correct == 0)
1042
 
          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
 
1050
        /* Handle brackets special.  */
 
1051
        if (posixly_correct == 0)
 
1052
          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1043
1053
 
1044
 
        /* Skip the not sign.  We have to recognize it because of a possibly
1045
 
           following ']'.  */
1046
 
        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
1047
 
          ++p;
1048
 
        /* A leading ']' is recognized as such.  */
1049
 
        if (*p == L_(']'))
1050
 
          ++p;
1051
 
        /* Skip over all characters of the list.  */
1052
 
        while (*p != L_(']'))
1053
 
          if (*p++ == L_('\0'))
1054
 
            /* This is no valid pattern.  */
1055
 
            return -1;
 
1054
        /* Skip the not sign.  We have to recognize it because of a possibly
 
1055
           following ']'.  */
 
1056
        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
 
1057
          ++p;
 
1058
        /* A leading ']' is recognized as such.  */
 
1059
        if (*p == L_(']'))
 
1060
          ++p;
 
1061
        /* Skip over all characters of the list.  */
 
1062
        while (*p != L_(']'))
 
1063
          if (*p++ == L_('\0'))
 
1064
            /* This is no valid pattern.  */
 
1065
            return -1;
1056
1066
      }
1057
1067
    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1058
 
              || *p == L_('!')) && p[1] == L_('('))
 
1068
              || *p == L_('!')) && p[1] == L_('('))
1059
1069
      /* Remember the nesting level.  */
1060
1070
      ++level;
1061
1071
    else if (*p == L_(')'))
1062
1072
      {
1063
 
        if (level-- == 0)
1064
 
          {
1065
 
            /* This means we found the end of the pattern.  */
 
1073
        if (level-- == 0)
 
1074
          {
 
1075
            /* This means we found the end of the pattern.  */
1066
1076
#define NEW_PATTERN \
1067
 
            struct patternlist *newp;                                         \
1068
 
            size_t plen;                                                      \
1069
 
            size_t plensize;                                                  \
1070
 
            size_t newpsize;                                                  \
1071
 
                                                                              \
1072
 
            plen = (opt == L_('?') || opt == L_('@')                          \
1073
 
                    ? pattern_len                                             \
1074
 
                    : p - startp + 1);                                        \
1075
 
            plensize = plen * sizeof (CHAR);                                  \
1076
 
            newpsize = offsetof (struct patternlist, str) + plensize;         \
1077
 
            if ((size_t) -1 / sizeof (CHAR) < plen                            \
1078
 
                || newpsize < offsetof (struct patternlist, str)              \
1079
 
                || ALLOCA_LIMIT <= newpsize)                                  \
1080
 
              return -1;                                                      \
1081
 
            newp = (struct patternlist *) alloca (newpsize);                  \
1082
 
            *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0');    \
1083
 
            newp->next = NULL;                                                \
1084
 
            *lastp = newp;                                                    \
1085
 
            lastp = &newp->next
1086
 
            NEW_PATTERN;
1087
 
            break;
1088
 
          }
 
1077
            struct patternlist *newp;                                         \
 
1078
            size_t plen;                                                      \
 
1079
            size_t plensize;                                                  \
 
1080
            size_t newpsize;                                                  \
 
1081
                                                                              \
 
1082
            plen = (opt == L_('?') || opt == L_('@')                          \
 
1083
                    ? pattern_len                                             \
 
1084
                    : p - startp + 1UL);                                      \
 
1085
            plensize = plen * sizeof (CHAR);                                  \
 
1086
            newpsize = offsetof (struct patternlist, str) + plensize;         \
 
1087
            if ((size_t) -1 / sizeof (CHAR) < plen                            \
 
1088
                || newpsize < offsetof (struct patternlist, str)              \
 
1089
                || ALLOCA_LIMIT <= newpsize)                                  \
 
1090
              return -1;                                                      \
 
1091
            newp = (struct patternlist *) alloca (newpsize);                  \
 
1092
            *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0');    \
 
1093
            newp->next = NULL;                                                \
 
1094
            *lastp = newp;                                                    \
 
1095
            lastp = &newp->next
 
1096
            NEW_PATTERN;
 
1097
            break;
 
1098
          }
1089
1099
      }
1090
1100
    else if (*p == L_('|'))
1091
1101
      {
1092
 
        if (level == 0)
1093
 
          {
1094
 
            NEW_PATTERN;
1095
 
            startp = p + 1;
1096
 
          }
 
1102
        if (level == 0)
 
1103
          {
 
1104
            NEW_PATTERN;
 
1105
            startp = p + 1;
 
1106
          }
1097
1107
      }
1098
1108
  assert (list != NULL);
1099
1109
  assert (p[-1] == L_(')'));
1103
1113
    {
1104
1114
    case L_('*'):
1105
1115
      if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1106
 
        return 0;
 
1116
        return 0;
1107
1117
      /* FALLTHROUGH */
1108
1118
 
1109
1119
    case L_('+'):
1110
1120
      do
1111
 
        {
1112
 
          for (rs = string; rs <= string_end; ++rs)
1113
 
            /* First match the prefix with the current pattern with the
1114
 
               current pattern.  */
1115
 
            if (FCT (list->str, string, rs, no_leading_period,
1116
 
                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
1117
 
                /* This was successful.  Now match the rest with the rest
1118
 
                   of the pattern.  */
1119
 
                && (FCT (p, rs, string_end,
1120
 
                         rs == string
1121
 
                         ? no_leading_period
1122
 
                         : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1123
 
                         flags & FNM_FILE_NAME
1124
 
                         ? flags : flags & ~FNM_PERIOD) == 0
1125
 
                    /* This didn't work.  Try the whole pattern.  */
1126
 
                    || (rs != string
1127
 
                        && FCT (pattern - 1, rs, string_end,
1128
 
                                rs == string
1129
 
                                ? no_leading_period
1130
 
                                : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1131
 
                                flags & FNM_FILE_NAME
1132
 
                                ? flags : flags & ~FNM_PERIOD) == 0)))
1133
 
              /* It worked.  Signal success.  */
1134
 
              return 0;
1135
 
        }
 
1121
        {
 
1122
          for (rs = string; rs <= string_end; ++rs)
 
1123
            /* First match the prefix with the current pattern with the
 
1124
               current pattern.  */
 
1125
            if (FCT (list->str, string, rs, no_leading_period,
 
1126
                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
 
1127
                /* This was successful.  Now match the rest with the rest
 
1128
                   of the pattern.  */
 
1129
                && (FCT (p, rs, string_end,
 
1130
                         rs == string
 
1131
                         ? no_leading_period
 
1132
                         : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
 
1133
                         flags & FNM_FILE_NAME
 
1134
                         ? flags : flags & ~FNM_PERIOD) == 0
 
1135
                    /* This didn't work.  Try the whole pattern.  */
 
1136
                    || (rs != string
 
1137
                        && FCT (pattern - 1, rs, string_end,
 
1138
                                rs == string
 
1139
                                ? no_leading_period
 
1140
                                : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
 
1141
                                flags & FNM_FILE_NAME
 
1142
                                ? flags : flags & ~FNM_PERIOD) == 0)))
 
1143
              /* It worked.  Signal success.  */
 
1144
              return 0;
 
1145
        }
1136
1146
      while ((list = list->next) != NULL);
1137
1147
 
1138
1148
      /* None of the patterns lead to a match.  */
1140
1150
 
1141
1151
    case L_('?'):
1142
1152
      if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1143
 
        return 0;
 
1153
        return 0;
1144
1154
      /* FALLTHROUGH */
1145
1155
 
1146
1156
    case L_('@'):
1147
1157
      do
1148
 
        /* I cannot believe it but `strcat' is actually acceptable
1149
 
           here.  Match the entire string with the prefix from the
1150
 
           pattern list and the rest of the pattern following the
1151
 
           pattern list.  */
1152
 
        if (FCT (STRCAT (list->str, p), string, string_end,
1153
 
                 no_leading_period,
1154
 
                 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1155
 
          /* It worked.  Signal success.  */
1156
 
          return 0;
 
1158
        /* I cannot believe it but 'strcat' is actually acceptable
 
1159
           here.  Match the entire string with the prefix from the
 
1160
           pattern list and the rest of the pattern following the
 
1161
           pattern list.  */
 
1162
        if (FCT (STRCAT (list->str, p), string, string_end,
 
1163
                 no_leading_period,
 
1164
                 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
 
1165
          /* It worked.  Signal success.  */
 
1166
          return 0;
1157
1167
      while ((list = list->next) != NULL);
1158
1168
 
1159
1169
      /* None of the patterns lead to a match.  */
1161
1171
 
1162
1172
    case L_('!'):
1163
1173
      for (rs = string; rs <= string_end; ++rs)
1164
 
        {
1165
 
          struct patternlist *runp;
1166
 
 
1167
 
          for (runp = list; runp != NULL; runp = runp->next)
1168
 
            if (FCT (runp->str, string, rs,  no_leading_period,
1169
 
                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1170
 
              break;
1171
 
 
1172
 
          /* If none of the patterns matched see whether the rest does.  */
1173
 
          if (runp == NULL
1174
 
              && (FCT (p, rs, string_end,
1175
 
                       rs == string
1176
 
                       ? no_leading_period
1177
 
                       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1178
 
                       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
1179
 
                  == 0))
1180
 
            /* This is successful.  */
1181
 
            return 0;
1182
 
        }
 
1174
        {
 
1175
          struct patternlist *runp;
 
1176
 
 
1177
          for (runp = list; runp != NULL; runp = runp->next)
 
1178
            if (FCT (runp->str, string, rs,  no_leading_period,
 
1179
                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
 
1180
              break;
 
1181
 
 
1182
          /* If none of the patterns matched see whether the rest does.  */
 
1183
          if (runp == NULL
 
1184
              && (FCT (p, rs, string_end,
 
1185
                       rs == string
 
1186
                       ? no_leading_period
 
1187
                       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
 
1188
                       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
 
1189
                  == 0))
 
1190
            /* This is successful.  */
 
1191
            return 0;
 
1192
        }
1183
1193
 
1184
1194
      /* None of the patterns together with the rest of the pattern
1185
 
         lead to a match.  */
 
1195
         lead to a match.  */
1186
1196
      return FNM_NOMATCH;
1187
1197
 
1188
1198
    default:
1203
1213
#undef END
1204
1214
#undef MEMPCPY
1205
1215
#undef MEMCHR
1206
 
#undef STRCOLL
1207
1216
#undef STRLEN
1208
1217
#undef STRCAT
1209
1218
#undef L_