~ubuntu-branches/ubuntu/trusty/diffutils/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/fnmatch_loop.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2010-02-13 11:49:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100213114900-09lz8jx6wct52qp8
Tags: 1:2.9-1
* New upstream release, now under GPL version 3 or later.
* There is now a --tab-size option. Closes: #82923.
* Manpage for cmp describes exit status. Closes: #200614.
* Manpage for diff describes exit status. Closes: #228441, #473233.
* The file de.po is now more recent. Closes: #313686.
* Fixed bad sdiff behaviour. Closes: #320222.
* Added wdiff to Suggests. Closes: #324627.
* Fixed cmp behaviour regarding stdout and stderr. Closes: #356083.
* The file ru.po is now more recent. Closes: #409274.
* The file es.po is now more recent. Closes: #418005, #481708.
* The file nl.po is now more recent. Closes: #427370.
* Modified watch file to use http instead of ftp.
* Removed .comment section from executables.
* Added Homepage field to control file.

Show diffs side-by-side

added added

removed removed

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