Make FNM_LEADING_DIR behave as GNU tar expects it.
[kopensolaris-gnu/glibc.git] / posix / fnmatch_loop.c
1 /* Copyright (C) 1991-1993, 1996-1999, 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with this library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 /* Match STRING against the filename pattern PATTERN, returning zero if
20    it matches, nonzero if not.  */
21 static int FCT (const CHAR *pattern, const CHAR *string,
22                 int no_leading_period, int flags) internal_function;
23
24 static int
25 internal_function
26 FCT (pattern, string, no_leading_period, flags)
27      const CHAR *pattern;
28      const CHAR *string;
29      int no_leading_period;
30      int flags;
31 {
32   register const CHAR *p = pattern, *n = string;
33   register UCHAR c;
34 #ifdef _LIBC
35 # if WIDE_CHAR_VERSION
36   const char *collseq = (const char *)
37     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
38 # else
39   const UCHAR *collseq = (const UCHAR *)
40     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
41 # endif
42 #endif
43
44   while ((c = *p++) != L('\0'))
45     {
46       c = FOLD (c);
47
48       switch (c)
49         {
50         case L('?'):
51           if (*n == L('\0'))
52             return FNM_NOMATCH;
53           else if (*n == L('/') && (flags & FNM_FILE_NAME))
54             return FNM_NOMATCH;
55           else if (*n == L('.') && no_leading_period
56                    && (n == string
57                        || (n[-1] == L('/') && (flags & FNM_FILE_NAME))))
58             return FNM_NOMATCH;
59           break;
60
61         case L('\\'):
62           if (!(flags & FNM_NOESCAPE))
63             {
64               c = *p++;
65               if (c == L('\0'))
66                 /* Trailing \ loses.  */
67                 return FNM_NOMATCH;
68               c = FOLD (c);
69             }
70           if (FOLD ((UCHAR) *n) != c)
71             return FNM_NOMATCH;
72           break;
73
74         case L('*'):
75           if (*n == L('.') && no_leading_period
76               && (n == string
77                   || (n[-1] == L('/') && (flags & FNM_FILE_NAME))))
78             return FNM_NOMATCH;
79
80           for (c = *p++; c == L('?') || c == L('*'); c = *p++)
81             {
82               if (*n == L('/') && (flags & FNM_FILE_NAME))
83                 /* A slash does not match a wildcard under FNM_FILE_NAME.  */
84                 return FNM_NOMATCH;
85               else if (c == L('?'))
86                 {
87                   /* A ? needs to match one character.  */
88                   if (*n == L('\0'))
89                     /* There isn't another character; no match.  */
90                     return FNM_NOMATCH;
91                   else
92                     /* One character of the string is consumed in matching
93                        this ? wildcard, so *??? won't match if there are
94                        less than three characters.  */
95                     ++n;
96                 }
97             }
98
99           if (c == L('\0'))
100             /* The wildcard(s) is/are the last element of the pattern.
101                If the name is a file name and contains another slash
102                this means it cannot match, unless the FNM_LEADING_DIR
103                flag is set.  */
104             {
105               int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
106
107               if (flags & FNM_FILE_NAME)
108                 {
109                   if (flags & FNM_LEADING_DIR)
110                     result = 0;
111                   else
112                     {
113                       if (STRCHR (n, L('/')) == NULL)
114                         result = 0;
115                     }
116                 }
117
118               return result;
119             }
120           else
121             {
122               const CHAR *endp;
123
124               endp = STRCHRNUL (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'));
125
126               if (c == L('['))
127                 {
128                   int flags2 = ((flags & FNM_FILE_NAME)
129                                 ? flags : (flags & ~FNM_PERIOD));
130
131                   for (--p; n < endp; ++n)
132                     if (FCT (p, n, (no_leading_period
133                                     && (n == string
134                                         || (n[-1] == L('/')
135                                             && (flags & FNM_FILE_NAME)))),
136                              flags2) == 0)
137                       return 0;
138                 }
139               else if (c == L('/') && (flags & FNM_FILE_NAME))
140                 {
141                   while (*n != L('\0') && *n != L('/'))
142                     ++n;
143                   if (*n == L('/')
144                       && (FCT (p, n + 1, flags & FNM_PERIOD, flags) == 0))
145                     return 0;
146                 }
147               else
148                 {
149                   int flags2 = ((flags & FNM_FILE_NAME)
150                                 ? flags : (flags & ~FNM_PERIOD));
151
152                   if (c == L('\\') && !(flags & FNM_NOESCAPE))
153                     c = *p;
154                   c = FOLD (c);
155                   for (--p; n < endp; ++n)
156                     if (FOLD ((UCHAR) *n) == c
157                         && (FCT (p, n, (no_leading_period
158                                         && (n == string
159                                             || (n[-1] == L('/')
160                                                 && (flags & FNM_FILE_NAME)))),
161                                  flags2) == 0))
162                       return 0;
163                 }
164             }
165
166           /* If we come here no match is possible with the wildcard.  */
167           return FNM_NOMATCH;
168
169         case L('['):
170           {
171             static int posixly_correct;
172             /* Nonzero if the sense of the character class is inverted.  */
173             register int not;
174             CHAR cold;
175
176             if (posixly_correct == 0)
177               posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
178
179             if (*n == L('\0'))
180               return FNM_NOMATCH;
181
182             if (*n == L('.') && no_leading_period
183                 && (n == string
184                     || (n[-1] == L('/') && (flags & FNM_FILE_NAME))))
185               return FNM_NOMATCH;
186
187             if (*n == L('/') && (flags & FNM_FILE_NAME))
188               /* `/' cannot be matched.  */
189               return FNM_NOMATCH;
190
191             not = (*p == L('!') || (posixly_correct < 0 && *p == L('^')));
192             if (not)
193               ++p;
194
195             c = *p++;
196             for (;;)
197               {
198                 UCHAR fn = FOLD ((UCHAR) *n);
199
200                 if (!(flags & FNM_NOESCAPE) && c == L('\\'))
201                   {
202                     if (*p == L('\0'))
203                       return FNM_NOMATCH;
204                     c = FOLD ((UCHAR) *p);
205                     ++p;
206
207                     if (c == fn)
208                       goto matched;
209                   }
210                 else if (c == L('[') && *p == L(':'))
211                   {
212                     /* Leave room for the null.  */
213                     CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
214                     size_t c1 = 0;
215 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
216                     wctype_t wt;
217 #endif
218                     const CHAR *startp = p;
219
220                     for (;;)
221                       {
222                         if (c1 == CHAR_CLASS_MAX_LENGTH)
223                           /* The name is too long and therefore the pattern
224                              is ill-formed.  */
225                           return FNM_NOMATCH;
226
227                         c = *++p;
228                         if (c == L(':') && p[1] == L(']'))
229                           {
230                             p += 2;
231                             break;
232                           }
233                         if (c < L('a') || c >= L('z'))
234                           {
235                             /* This cannot possibly be a character class name.
236                                Match it as a normal range.  */
237                             p = startp;
238                             c = L('[');
239                             goto normal_bracket;
240                           }
241                         str[c1++] = c;
242                       }
243                     str[c1] = L('\0');
244
245 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
246                     wt = IS_CHAR_CLASS (str);
247                     if (wt == 0)
248                       /* Invalid character class name.  */
249                       return FNM_NOMATCH;
250
251 # if defined _LIBC && ! WIDE_CHAR_VERSION
252                     /* The following code is glibc specific but does
253                        there a good job in speeding up the code since
254                        we can avoid the btowc() call.  */
255                     if (_ISCTYPE ((UCHAR) *n, wt))
256                       goto matched;
257 # else
258                     if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
259                       goto matched;
260 # endif
261 #else
262                     if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n))
263                         || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n))
264                         || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n))
265                         || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n))
266                         || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n))
267                         || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n))
268                         || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n))
269                         || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n))
270                         || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n))
271                         || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n))
272                         || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n))
273                         || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n)))
274                       goto matched;
275 #endif
276                     c = *p++;
277                   }
278 #ifdef _LIBC
279                 else if (c == L('[') && *p == L('='))
280                   {
281                     UCHAR str[1];
282                     uint32_t nrules =
283                       _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
284                     const CHAR *startp = p;
285
286                     c = *++p;
287                     if (c == L('\0'))
288                       {
289                         p = startp;
290                         c = L('[');
291                         goto normal_bracket;
292                       }
293                     str[0] = c;
294
295                     c = *++p;
296                     if (c != L('=') || p[1] != L(']'))
297                       {
298                         p = startp;
299                         c = L('[');
300                         goto normal_bracket;
301                       }
302                     p += 2;
303
304                     if (nrules == 0)
305                       {
306                         if ((UCHAR) *n == str[0])
307                           goto matched;
308                       }
309                     else
310                       {
311                         const int32_t *table;
312 # if WIDE_CHAR_VERSION
313                         const int32_t *weights;
314                         const int32_t *extra;
315 # else
316                         const unsigned char *weights;
317                         const unsigned char *extra;
318 # endif
319                         const int32_t *indirect;
320                         int32_t idx;
321                         const UCHAR *cp = (const UCHAR *) str;
322
323                         /* This #include defines a local function!  */
324 # if WIDE_CHAR_VERSION
325 #  include <locale/weightwc.h>
326 # else
327 #  include <locale/weight.h>
328 # endif
329
330 # if WIDE_CHAR_VERSION
331                         table = (const int32_t *)
332                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
333                         weights = (const int32_t *)
334                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
335                         extra = (const int32_t *)
336                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
337                         indirect = (const int32_t *)
338                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
339 # else
340                         table = (const int32_t *)
341                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
342                         weights = (const unsigned char *)
343                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
344                         extra = (const unsigned char *)
345                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
346                         indirect = (const int32_t *)
347                           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
348 # endif
349
350                         idx = findidx (&cp);
351                         if (idx != 0)
352                           {
353                             /* We found a table entry.  Now see whether the
354                                character we are currently at has the same
355                                equivalance class value.  */
356 # if !WIDE_CHAR_VERSION
357                             int len = weights[idx];
358 # endif
359                             int32_t idx2;
360                             const UCHAR *np = (const UCHAR *) n;
361
362                             idx2 = findidx (&np);
363 # if WIDE_CHAR_VERSION
364                             if (idx2 != 0 && weights[idx] == weights[idx2])
365                               goto matched;
366 # else
367                             if (idx2 != 0 && len == weights[idx2])
368                               {
369                                 int cnt = 0;
370
371                                 while (cnt < len
372                                        && (weights[idx + 1 + cnt]
373                                            == weights[idx2 + 1 + cnt]))
374                                   ++cnt;
375
376                                 if (cnt == len)
377                                   goto matched;
378                               }
379 # endif
380                           }
381                       }
382
383                     c = *p++;
384                   }
385 #endif
386                 else if (c == L('\0'))
387                   /* [ (unterminated) loses.  */
388                   return FNM_NOMATCH;
389                 else
390                   {
391                     int is_range = 0;
392
393 #ifdef _LIBC
394                     int is_seqval = 0;
395
396                     if (c == L('[') && *p == L('.'))
397                       {
398                         uint32_t nrules =
399                           _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
400                         const CHAR *startp = p;
401                         size_t c1 = 0;
402
403                         while (1)
404                           {
405                             c = *++p;
406                             if (c == L('.') && p[1] == L(']'))
407                               {
408                                 p += 2;
409                                 break;
410                               }
411                             if (c == '\0')
412                               return FNM_NOMATCH;
413                             ++c1;
414                           }
415
416                         /* We have to handling the symbols differently in
417                            ranges since then the collation sequence is
418                            important.  */
419                         is_range = *p == L('-') && p[1] != L('\0');
420
421                         if (nrules == 0)
422                           {
423                             /* There are no names defined in the collation
424                                data.  Therefore we only accept the trivial
425                                names consisting of the character itself.  */
426                             if (c1 != 1)
427                               return FNM_NOMATCH;
428
429                             if (!is_range && *n == startp[1])
430                               goto matched;
431
432                             cold = startp[1];
433                             c = *p++;
434                           }
435                         else
436                           {
437                             int32_t table_size;
438                             const int32_t *symb_table;
439 # ifdef WIDE_CHAR_VERSION
440                             char str[c1];
441                             int strcnt;
442 # else
443 #  define str (startp + 1)
444 # endif
445                             const unsigned char *extra;
446                             int32_t idx;
447                             int32_t elem;
448                             int32_t second;
449                             int32_t hash;
450
451 # ifdef WIDE_CHAR_VERSION
452                             /* We have to convert the name to a single-byte
453                                string.  This is possible since the names
454                                consist of ASCII characters and the internal
455                                representation is UCS4.  */
456                             for (strcnt = 0; strcnt < c1; ++strcnt)
457                               str[strcnt] = startp[1 + strcnt];
458 #endif
459
460                             table_size =
461                               _NL_CURRENT_WORD (LC_COLLATE,
462                                                 _NL_COLLATE_SYMB_HASH_SIZEMB);
463                             symb_table = (const int32_t *)
464                               _NL_CURRENT (LC_COLLATE,
465                                            _NL_COLLATE_SYMB_TABLEMB);
466                             extra = (const unsigned char *)
467                               _NL_CURRENT (LC_COLLATE,
468                                            _NL_COLLATE_SYMB_EXTRAMB);
469
470                             /* Locate the character in the hashing table.  */
471                             hash = elem_hash (str, c1);
472
473                             idx = 0;
474                             elem = hash % table_size;
475                             second = hash % (table_size - 2);
476                             while (symb_table[2 * elem] != 0)
477                               {
478                                 /* First compare the hashing value.  */
479                                 if (symb_table[2 * elem] == hash
480                                     && c1 == extra[symb_table[2 * elem + 1]]
481                                     && memcmp (str,
482                                                &extra[symb_table[2 * elem + 1]
483                                                      + 1], c1) == 0)
484                                   {
485                                     /* Yep, this is the entry.  */
486                                     idx = symb_table[2 * elem + 1];
487                                     idx += 1 + extra[idx];
488                                     break;
489                                   }
490
491                                 /* Next entry.  */
492                                 elem += second;
493                               }
494
495                             if (symb_table[2 * elem] != 0)
496                               {
497                                 /* Compare the byte sequence but only if
498                                    this is not part of a range.  */
499 # ifdef WIDE_CHAR_VERSION
500                                 int32_t *wextra;
501
502                                 idx += 1 + extra[idx];
503                                 /* Adjust for the alignment.  */
504                                 idx = (idx + 3) & ~4;
505
506                                 wextra = (int32_t *) &extra[idx + 4];
507 # endif
508
509                                 if (! is_range)
510                                   {
511 # ifdef WIDE_CHAR_VERSION
512                                     for (c1 = 0; c1 < wextra[idx]; ++c1)
513                                       if (n[c1] != wextra[1 + c1])
514                                         break;
515
516                                     if (c1 == wextra[idx])
517                                       goto matched;
518 # else
519                                     for (c1 = 0; c1 < extra[idx]; ++c1)
520                                       if (n[c1] != extra[1 + c1])
521                                         break;
522
523                                     if (c1 == extra[idx])
524                                       goto matched;
525 # endif
526                                   }
527
528                                 /* Get the collation sequence value.  */
529                                 is_seqval = 1;
530 # ifdef WIDE_CHAR_VERSION
531                                 cold = wextra[1 + wextra[idx]];
532 # else
533                                 /* Adjust for the alignment.  */
534                                 idx += 1 + extra[idx];
535                                 idx = (idx + 3) & ~4;
536                                 cold = *((int32_t *) &extra[idx]);
537 # endif
538
539                                 c = *p++;
540                               }
541                             else if (symb_table[2 * elem] != 0 && c1 == 1)
542                               {
543                                 /* No valid character.  Match it as a
544                                    single byte.  */
545                                 if (!is_range && *n == str[0])
546                                   goto matched;
547
548                                 cold = str[0];
549                                 c = *p++;
550                               }
551                             else
552                               return FNM_NOMATCH;
553                           }
554                       }
555                     else
556 # undef str
557 #endif
558                       {
559                         c = FOLD (c);
560                       normal_bracket:
561
562                         /* We have to handling the symbols differently in
563                            ranges since then the collation sequence is
564                            important.  */
565                         is_range = *p == L('-') && p[1] != L('\0');
566
567                         if (!is_range && c == fn)
568                           goto matched;
569
570                         cold = c;
571                         c = *p++;
572                       }
573
574                     if (c == L('-') && *p != L(']'))
575                       {
576 #if _LIBC
577                         /* We have to find the collation sequence
578                            value for C.  Collation sequence is nothing
579                            we can regularly access.  The sequence
580                            value is defined by the order in which the
581                            definitions of the collation values for the
582                            various characters appear in the source
583                            file.  A strange concept, nowhere
584                            documented.  */
585                         uint32_t fcollseq;
586                         uint32_t lcollseq;
587                         UCHAR cend = *p++;
588
589 # ifdef WIDE_CHAR_VERSION
590                         /* Search in the `names' array for the characters.  */
591                         fcollseq = collseq_table_lookup (collseq, fn);
592                         if (fcollseq == ~((uint32_t) 0))
593                           /* XXX We don't know anything about the character
594                              we are supposed to match.  This means we are
595                              failing.  */
596                           goto range_not_matched;
597
598                         if (is_seqval)
599                           lcollseq = cold;
600                         else
601                           lcollseq = collseq_table_lookup (collseq, cold);
602 # else
603                         fcollseq = collseq[fn];
604                         lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
605 # endif
606
607                         is_seqval = 0;
608                         if (cend == L('[') && *p == L('.'))
609                           {
610                             uint32_t nrules =
611                               _NL_CURRENT_WORD (LC_COLLATE,
612                                                 _NL_COLLATE_NRULES);
613                             const CHAR *startp = p;
614                             size_t c1 = 0;
615
616                             while (1)
617                               {
618                                 c = *++p;
619                                 if (c == L('.') && p[1] == L(']'))
620                                   {
621                                     p += 2;
622                                     break;
623                                   }
624                                 if (c == '\0')
625                                   return FNM_NOMATCH;
626                                 ++c1;
627                               }
628
629                             if (nrules == 0)
630                               {
631                                 /* There are no names defined in the
632                                    collation data.  Therefore we only
633                                    accept the trivial names consisting
634                                    of the character itself.  */
635                                 if (c1 != 1)
636                                   return FNM_NOMATCH;
637
638                                 cend = startp[1];
639                               }
640                             else
641                               {
642                                 int32_t table_size;
643                                 const int32_t *symb_table;
644 # ifdef WIDE_CHAR_VERSION
645                                 char str[c1];
646                                 int strcnt;
647 # else
648 #  define str (startp + 1)
649 # endif
650                                 const unsigned char *extra;
651                                 int32_t idx;
652                                 int32_t elem;
653                                 int32_t second;
654                                 int32_t hash;
655
656 # ifdef WIDE_CHAR_VERSION
657                                 /* We have to convert the name to a single-byte
658                                    string.  This is possible since the names
659                                    consist of ASCII characters and the internal
660                                    representation is UCS4.  */
661                                 for (strcnt = 0; strcnt < c1; ++strcnt)
662                                   str[strcnt] = startp[1 + strcnt];
663 #endif
664
665                                 table_size =
666                                   _NL_CURRENT_WORD (LC_COLLATE,
667                                                     _NL_COLLATE_SYMB_HASH_SIZEMB);
668                                 symb_table = (const int32_t *)
669                                   _NL_CURRENT (LC_COLLATE,
670                                                _NL_COLLATE_SYMB_TABLEMB);
671                                 extra = (const unsigned char *)
672                                   _NL_CURRENT (LC_COLLATE,
673                                                _NL_COLLATE_SYMB_EXTRAMB);
674
675                                 /* Locate the character in the hashing
676                                    table.  */
677                                 hash = elem_hash (str, c1);
678
679                                 idx = 0;
680                                 elem = hash % table_size;
681                                 second = hash % (table_size - 2);
682                                 while (symb_table[2 * elem] != 0)
683                                   {
684                                 /* First compare the hashing value.  */
685                                     if (symb_table[2 * elem] == hash
686                                         && (c1
687                                             == extra[symb_table[2 * elem + 1]])
688                                         && memcmp (str,
689                                                    &extra[symb_table[2 * elem + 1]
690                                                          + 1], c1) == 0)
691                                       {
692                                         /* Yep, this is the entry.  */
693                                         idx = symb_table[2 * elem + 1];
694                                         idx += 1 + extra[idx];
695                                         break;
696                                       }
697
698                                     /* Next entry.  */
699                                     elem += second;
700                                   }
701
702                                 if (symb_table[2 * elem] != 0)
703                                   {
704                                     /* Compare the byte sequence but only if
705                                        this is not part of a range.  */
706 # ifdef WIDE_CHAR_VERSION
707                                     int32_t *wextra;
708
709                                     idx += 1 + extra[idx];
710                                     /* Adjust for the alignment.  */
711                                     idx = (idx + 3) & ~4;
712
713                                     wextra = (int32_t *) &extra[idx + 4];
714 # endif
715                                     /* Get the collation sequence value.  */
716                                     is_seqval = 1;
717 # ifdef WIDE_CHAR_VERSION
718                                     cend = wextra[1 + wextra[idx]];
719 # else
720                                     /* Adjust for the alignment.  */
721                                     idx += 1 + extra[idx];
722                                     idx = (idx + 3) & ~4;
723                                     cend = *((int32_t *) &extra[idx]);
724 # endif
725                                   }
726                                 else if (symb_table[2 * elem] != 0 && c1 == 1)
727                                   {
728                                     cend = str[0];
729                                     c = *p++;
730                                   }
731                                 else
732                                   return FNM_NOMATCH;
733                               }
734 # undef str
735                           }
736                         else
737                           {
738                             if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
739                               cend = *p++;
740                             if (cend == L('\0'))
741                               return FNM_NOMATCH;
742                             cend = FOLD (cend);
743                           }
744
745                         /* XXX It is not entirely clear to me how to handle
746                            characters which are not mentioned in the
747                            collation specification.  */
748                         if (
749 # ifdef WIDE_CHAR_VERSION
750                             lcollseq == 0xffffffff ||
751 # endif
752                             lcollseq <= fcollseq)
753                           {
754                             /* We have to look at the upper bound.  */
755                             uint32_t hcollseq;
756
757                             if (is_seqval)
758                               hcollseq = cend;
759                             else
760                               {
761 # ifdef WIDE_CHAR_VERSION
762                                 hcollseq =
763                                   collseq_table_lookup (collseq, cend);
764                                 if (hcollseq == ~((uint32_t) 0))
765                                   {
766                                     /* Hum, no information about the upper
767                                        bound.  The matching succeeds if the
768                                        lower bound is matched exactly.  */
769                                     if (lcollseq != fcollseq)
770                                       goto range_not_matched;
771
772                                     goto matched;
773                                   }
774 # else
775                                 hcollseq = collseq[cend];
776 # endif
777                               }
778
779                             if (lcollseq <= hcollseq && fcollseq <= hcollseq)
780                               goto matched;
781                           }
782 # ifdef WIDE_CHAR_VERSION
783                       range_not_matched:
784 # endif
785 #else
786                         /* We use a boring value comparison of the character
787                            values.  This is better than comparing using
788                            `strcoll' since the latter would have surprising
789                            and sometimes fatal consequences.  */
790                         UCHAR cend = *p++;
791
792                         if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
793                           cend = *p++;
794                         if (cend == L('\0'))
795                           return FNM_NOMATCH;
796
797                         /* It is a range.  */
798                         if (cold <= fn && fn <= c)
799                           goto matched;
800 #endif
801
802                         c = *p++;
803                       }
804                   }
805
806                 if (c == L(']'))
807                   break;
808               }
809
810             if (!not)
811               return FNM_NOMATCH;
812             break;
813
814           matched:
815             /* Skip the rest of the [...] that already matched.  */
816             do
817               {
818               ignore_next:
819                 c = *p++;
820
821                 if (c == L('\0'))
822                   /* [... (unterminated) loses.  */
823                   return FNM_NOMATCH;
824
825                 if (!(flags & FNM_NOESCAPE) && c == L('\\'))
826                   {
827                     if (*p == L('\0'))
828                       return FNM_NOMATCH;
829                     /* XXX 1003.2d11 is unclear if this is right.  */
830                     ++p;
831                   }
832                 else if (c == L('[') && *p == L(':'))
833                   {
834                     int c1 = 0;
835                     const CHAR *startp = p;
836
837                     while (1)
838                       {
839                         c = *++p;
840                         if (++c1 == CHAR_CLASS_MAX_LENGTH)
841                           return FNM_NOMATCH;
842
843                         if (*p == L(':') && p[1] == L(']'))
844                           break;
845
846                         if (c < L('a') || c >= L('z'))
847                           {
848                             p = startp;
849                             goto ignore_next;
850                           }
851                       }
852                     p += 2;
853                     c = *p++;
854                   }
855                 else if (c == L('[') && *p == L('='))
856                   {
857                     c = *++p;
858                     if (c == L('\0'))
859                       return FNM_NOMATCH;
860                     c = *++p;
861                     if (c != L('=') || p[1] != L(']'))
862                       return FNM_NOMATCH;
863                     p += 2;
864                     c = *p++;
865                   }
866                 else if (c == L('[') && *p == L('.'))
867                   {
868                     ++p;
869                     while (1)
870                       {
871                         c = *++p;
872                         if (c == '\0')
873                           return FNM_NOMATCH;
874
875                         if (*p == L('.') && p[1] == L(']'))
876                           break;
877                       }
878                     p += 2;
879                     c = *p++;
880                   }
881               }
882             while (c != L(']'));
883             if (not)
884               return FNM_NOMATCH;
885           }
886           break;
887
888         default:
889           if (c != FOLD ((UCHAR) *n))
890             return FNM_NOMATCH;
891         }
892
893       ++n;
894     }
895
896   if (*n == '\0')
897     return 0;
898
899   if ((flags & FNM_LEADING_DIR) && *n == L('/'))
900     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
901     return 0;
902
903   return FNM_NOMATCH;
904 }
905
906 #undef FOLD
907 #undef CHAR
908 #undef UCHAR
909 #undef FCT
910 #undef STRCHR
911 #undef STRCHRNUL
912 #undef STRCOLL
913 #undef L
914 #undef BTOWC