]> sjero.net Git - wget/blob - src/cmpt.c
[svn] Remove K&R support.
[wget] / src / cmpt.c
1 /* Replacements for routines missing on some systems.
2    Copyright (C) 1995-2005 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables.  You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL".  If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so.  If you do not wish to do
28 so, delete this exception statement from your version.  */
29
30 #include <config.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #ifdef HAVE_UNISTD_H
37 # include <unistd.h>
38 #endif
39
40 #include <errno.h>
41
42 #include "wget.h"
43
44 /* Some systems don't have some str* functions in libc.  Here we
45    define them.  The same goes for strptime.  */
46
47 #ifndef HAVE_STRCASECMP
48 /* From GNU libc.  */
49 /* Compare S1 and S2, ignoring case, returning less than, equal to or
50    greater than zero if S1 is lexiographically less than,
51    equal to or greater than S2.  */
52 int
53 strcasecmp (const char *s1, const char *s2)
54 {
55   register const unsigned char *p1 = (const unsigned char *) s1;
56   register const unsigned char *p2 = (const unsigned char *) s2;
57   unsigned char c1, c2;
58
59   if (p1 == p2)
60     return 0;
61
62   do
63     {
64       c1 = TOLOWER (*p1++);
65       c2 = TOLOWER (*p2++);
66       if (c1 == '\0')
67         break;
68     }
69   while (c1 == c2);
70
71   return c1 - c2;
72 }
73 #endif /* not HAVE_STRCASECMP */
74
75 #ifndef HAVE_STRNCASECMP
76 /* From GNU libc.  */
77 /* Compare no more than N characters of S1 and S2,
78    ignoring case, returning less than, equal to or
79    greater than zero if S1 is lexicographically less
80    than, equal to or greater than S2.  */
81 int
82 strncasecmp (const char *s1, const char *s2, size_t n)
83 {
84   register const unsigned char *p1 = (const unsigned char *) s1;
85   register const unsigned char *p2 = (const unsigned char *) s2;
86   unsigned char c1, c2;
87
88   if (p1 == p2 || n == 0)
89     return 0;
90
91   do
92     {
93       c1 = TOLOWER (*p1++);
94       c2 = TOLOWER (*p2++);
95       if (c1 == '\0' || c1 != c2)
96         return c1 - c2;
97     } while (--n > 0);
98
99   return c1 - c2;
100 }
101 #endif /* not HAVE_STRNCASECMP */
102
103 #ifndef HAVE_STRPBRK
104 /* Find the first ocurrence in S of any character in ACCEPT.  */
105 char *
106 strpbrk (const char *s, const char *accept)
107 {
108   while (*s != '\0')
109     {
110       const char *a = accept;
111       while (*a != '\0')
112         if (*a++ == *s)
113           return (char *) s;
114       ++s;
115     }
116
117   return 0;
118 }
119 #endif /* HAVE_STRPBRK */
120
121 #ifndef HAVE_MKTIME
122 /* From GNU libc 2.0.  */
123
124 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
125    This file is part of the GNU C Library.
126    Contributed by Paul Eggert (eggert@twinsun.com).  */
127
128 #ifdef _LIBC
129 # define HAVE_LIMITS_H 1
130 # define HAVE_LOCALTIME_R 1
131 # define STDC_HEADERS 1
132 #endif
133
134 /* Assume that leap seconds are possible, unless told otherwise.
135    If the host has a `zic' command with a `-L leapsecondfilename' option,
136    then it supports leap seconds; otherwise it probably doesn't.  */
137 #ifndef LEAP_SECONDS_POSSIBLE
138 # define LEAP_SECONDS_POSSIBLE 1
139 #endif
140
141 #ifndef __P
142 # define __P(args) args
143 #endif  /* Not __P.  */
144
145 #ifndef CHAR_BIT
146 # define CHAR_BIT 8
147 #endif
148
149 #ifndef INT_MIN
150 # define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
151 #endif
152 #ifndef INT_MAX
153 # define INT_MAX (~0 - INT_MIN)
154 #endif
155
156 #ifndef TIME_T_MIN
157 /* The outer cast to time_t works around a bug in Cray C 5.0.3.0.  */
158 # define TIME_T_MIN ((time_t) \
159                     (0 < (time_t) -1 ? (time_t) 0 \
160                      : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
161 #endif
162 #ifndef TIME_T_MAX
163 # define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
164 #endif
165
166 #define TM_YEAR_BASE 1900
167 #define EPOCH_YEAR 1970
168
169 #ifndef __isleap
170 /* Nonzero if YEAR is a leap year (every 4 years,
171    except every 100th isn't, and every 400th is).  */
172 # define __isleap(year) \
173   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
174 #endif
175
176 /* How many days come before each month (0-12).  */
177 /* __mon_yday[][] is common to mktime and strptime implementations.
178    --abbotti */
179 const unsigned short int __mon_yday[2][13];
180 #ifndef NEED_MON_YDAY
181 # define NEED_MON_YDAY
182 #endif
183
184 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
185 time_t __mktime_internal __P ((struct tm *,
186                                struct tm *(*) (const time_t *, struct tm *),
187                                time_t *));
188
189
190 #ifdef _LIBC
191 # define localtime_r __localtime_r
192 #else
193 # if ! HAVE_LOCALTIME_R && ! defined localtime_r
194 /* Approximate localtime_r as best we can in its absence.  */
195 #  define localtime_r my_mktime_localtime_r
196 static struct tm *localtime_r __P ((const time_t *, struct tm *));
197 static struct tm *
198 localtime_r (t, tp)
199      const time_t *t;
200      struct tm *tp;
201 {
202   struct tm *l = localtime (t);
203   if (! l)
204     return 0;
205   *tp = *l;
206   return tp;
207 }
208 # endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
209 #endif /* ! _LIBC */
210
211
212 /* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
213    measured in seconds, ignoring leap seconds.
214    YEAR uses the same numbering as TM->tm_year.
215    All values are in range, except possibly YEAR.
216    If overflow occurs, yield the low order bits of the correct answer.  */
217 static time_t
218 ydhms_tm_diff (year, yday, hour, min, sec, tp)
219      int year, yday, hour, min, sec;
220      const struct tm *tp;
221 {
222   /* Compute intervening leap days correctly even if year is negative.
223      Take care to avoid int overflow.  time_t overflow is OK, since
224      only the low order bits of the correct time_t answer are needed.
225      Don't convert to time_t until after all divisions are done, since
226      time_t might be unsigned.  */
227   int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
228   int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
229   int a100 = a4 / 25 - (a4 % 25 < 0);
230   int b100 = b4 / 25 - (b4 % 25 < 0);
231   int a400 = a100 >> 2;
232   int b400 = b100 >> 2;
233   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
234   time_t years = year - (time_t) tp->tm_year;
235   time_t days = (365 * years + intervening_leap_days
236                  + (yday - tp->tm_yday));
237   return (60 * (60 * (24 * days + (hour - tp->tm_hour))
238                 + (min - tp->tm_min))
239           + (sec - tp->tm_sec));
240 }
241
242
243 static time_t localtime_offset;
244
245 /* Convert *TP to a time_t value.  */
246 time_t
247 mktime (tp)
248      struct tm *tp;
249 {
250 #ifdef _LIBC
251   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
252      time zone names contained in the external variable `tzname' shall
253      be set as if the tzset() function had been called.  */
254   __tzset ();
255 #endif
256
257   return __mktime_internal (tp, localtime_r, &localtime_offset);
258 }
259
260 /* Convert *TP to a time_t value, inverting
261    the monotonic and mostly-unit-linear conversion function CONVERT.
262    Use *OFFSET to keep track of a guess at the offset of the result,
263    compared to what the result would be for UTC without leap seconds.
264    If *OFFSET's guess is correct, only one CONVERT call is needed.  */
265 time_t
266 __mktime_internal (tp, convert, offset)
267      struct tm *tp;
268      struct tm *(*convert) __P ((const time_t *, struct tm *));
269      time_t *offset;
270 {
271   time_t t, dt, t0;
272   struct tm tm;
273
274   /* The maximum number of probes (calls to CONVERT) should be enough
275      to handle any combinations of time zone rule changes, solar time,
276      and leap seconds.  Posix.1 prohibits leap seconds, but some hosts
277      have them anyway.  */
278   int remaining_probes = 4;
279
280   /* Time requested.  Copy it in case CONVERT modifies *TP; this can
281      occur if TP is localtime's returned value and CONVERT is localtime.  */
282   int sec = tp->tm_sec;
283   int min = tp->tm_min;
284   int hour = tp->tm_hour;
285   int mday = tp->tm_mday;
286   int mon = tp->tm_mon;
287   int year_requested = tp->tm_year;
288   int isdst = tp->tm_isdst;
289
290   /* Ensure that mon is in range, and set year accordingly.  */
291   int mon_remainder = mon % 12;
292   int negative_mon_remainder = mon_remainder < 0;
293   int mon_years = mon / 12 - negative_mon_remainder;
294   int year = year_requested + mon_years;
295
296   /* The other values need not be in range:
297      the remaining code handles minor overflows correctly,
298      assuming int and time_t arithmetic wraps around.
299      Major overflows are caught at the end.  */
300
301   /* Calculate day of year from year, month, and day of month.
302      The result need not be in range.  */
303   int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
304                [mon_remainder + 12 * negative_mon_remainder])
305               + mday - 1);
306
307   int sec_requested = sec;
308 #if LEAP_SECONDS_POSSIBLE
309   /* Handle out-of-range seconds specially,
310      since ydhms_tm_diff assumes every minute has 60 seconds.  */
311   if (sec < 0)
312     sec = 0;
313   if (59 < sec)
314     sec = 59;
315 #endif
316
317   /* Invert CONVERT by probing.  First assume the same offset as last time.
318      Then repeatedly use the error to improve the guess.  */
319
320   tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
321   tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
322   t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
323
324   for (t = t0 + *offset;
325        (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
326        t += dt)
327     if (--remaining_probes == 0)
328       return -1;
329
330   /* Check whether tm.tm_isdst has the requested value, if any.  */
331   if (0 <= isdst && 0 <= tm.tm_isdst)
332     {
333       int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
334       if (dst_diff)
335         {
336           /* Move two hours in the direction indicated by the disagreement,
337              probe some more, and switch to a new time if found.
338              The largest known fallback due to daylight savings is two hours:
339              once, in Newfoundland, 1988-10-30 02:00 -> 00:00.  */
340           time_t ot = t - 2 * 60 * 60 * dst_diff;
341           while (--remaining_probes != 0)
342             {
343               struct tm otm;
344               if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
345                                          (*convert) (&ot, &otm))))
346                 {
347                   t = ot;
348                   tm = otm;
349                   break;
350                 }
351               if ((ot += dt) == t)
352                 break;  /* Avoid a redundant probe.  */
353             }
354         }
355     }
356
357   *offset = t - t0;
358
359 #if LEAP_SECONDS_POSSIBLE
360   if (sec_requested != tm.tm_sec)
361     {
362       /* Adjust time to reflect the tm_sec requested, not the normalized value.
363          Also, repair any damage from a false match due to a leap second.  */
364       t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
365       (*convert) (&t, &tm);
366     }
367 #endif
368
369   if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
370     {
371       /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
372          so check for major overflows.  A gross check suffices,
373          since if t has overflowed, it is off by a multiple of
374          TIME_T_MAX - TIME_T_MIN + 1.  So ignore any component of
375          the difference that is bounded by a small value.  */
376
377       double dyear = (double) year_requested + mon_years - tm.tm_year;
378       double dday = 366 * dyear + mday;
379       double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
380
381       if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
382         return -1;
383     }
384
385   *tp = tm;
386   return t;
387 }
388
389 #ifdef weak_alias
390 weak_alias (mktime, timelocal)
391 #endif
392 #endif /* not HAVE_MKTIME */
393
394
395 #ifndef HAVE_STRPTIME
396 /* From GNU libc 2.1.3.  */
397 /* Ulrich, thanks for helping me out with this!  --hniksic  */
398
399 /* strptime - Convert a string representation of time to a time value.
400    Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
401    This file is part of the GNU C Library.
402    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.  */
403
404 /* XXX This version of the implementation is not really complete.
405    Some of the fields cannot add information alone.  But if seeing
406    some of them in the same format (such as year, week and weekday)
407    this is enough information for determining the date.  */
408
409 #ifndef __P
410 # define __P(args) args
411 #endif /* not __P */
412
413 #if ! HAVE_LOCALTIME_R && ! defined localtime_r
414 # ifdef _LIBC
415 #  define localtime_r __localtime_r
416 # else
417 /* Approximate localtime_r as best we can in its absence.  */
418 #  define localtime_r my_localtime_r
419 static struct tm *localtime_r __P ((const time_t *, struct tm *));
420 static struct tm *
421 localtime_r (t, tp)
422      const time_t *t;
423      struct tm *tp;
424 {
425   struct tm *l = localtime (t);
426   if (! l)
427     return 0;
428   *tp = *l;
429   return tp;
430 }
431 # endif /* ! _LIBC */
432 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
433
434
435 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
436 #if defined __GNUC__ && __GNUC__ >= 2
437 # define match_string(cs1, s2) \
438   ({ size_t len = strlen (cs1);                                               \
439      int result = strncasecmp ((cs1), (s2), len) == 0;                        \
440      if (result) (s2) += len;                                                 \
441      result; })
442 #else
443 /* Oh come on.  Get a reasonable compiler.  */
444 # define match_string(cs1, s2) \
445   (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
446 #endif
447 /* We intentionally do not use isdigit() for testing because this will
448    lead to problems with the wide character version.  */
449 #define get_number(from, to, n) \
450   do {                                                                        \
451     int __n = n;                                                              \
452     val = 0;                                                                  \
453     while (*rp == ' ')                                                        \
454       ++rp;                                                                   \
455     if (*rp < '0' || *rp > '9')                                               \
456       return NULL;                                                            \
457     do {                                                                      \
458       val *= 10;                                                              \
459       val += *rp++ - '0';                                                     \
460     } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9');        \
461     if (val < from || val > to)                                               \
462       return NULL;                                                            \
463   } while (0)
464 #ifdef _NL_CURRENT
465 /* Added check for __GNUC__ extensions here for Wget. --abbotti */
466 # if defined __GNUC__ && __GNUC__ >= 2
467 #  define get_alt_number(from, to, n) \
468   ({                                                                          \
469     __label__ do_normal;                                                      \
470     if (*decided != raw)                                                      \
471       {                                                                       \
472         const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS);                 \
473         int __n = n;                                                          \
474         int any = 0;                                                          \
475         while (*rp == ' ')                                                    \
476           ++rp;                                                               \
477         val = 0;                                                              \
478         do {                                                                  \
479           val *= 10;                                                          \
480           while (*alts != '\0')                                               \
481             {                                                                 \
482               size_t len = strlen (alts);                                     \
483               if (strncasecmp (alts, rp, len) == 0)                           \
484                 break;                                                        \
485               alts += len + 1;                                                \
486               ++val;                                                          \
487             }                                                                 \
488           if (*alts == '\0')                                                  \
489             {                                                                 \
490               if (*decided == not && ! any)                                   \
491                 goto do_normal;                                               \
492               /* If we haven't read anything it's an error.  */               \
493               if (! any)                                                      \
494                 return NULL;                                                  \
495               /* Correct the premature multiplication.  */                    \
496               val /= 10;                                                      \
497               break;                                                          \
498             }                                                                 \
499           else                                                                \
500             *decided = loc;                                                   \
501         } while (--__n > 0 && val * 10 <= to);                                \
502         if (val < from || val > to)                                           \
503           return NULL;                                                        \
504       }                                                                       \
505     else                                                                      \
506       {                                                                       \
507        do_normal:                                                             \
508         get_number (from, to, n);                                             \
509       }                                                                       \
510     0;                                                                        \
511   })
512 # else
513 #  define get_alt_number(from, to, n) \
514   do {
515     if (*decided != raw)                                                      \
516       {                                                                       \
517         const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS);                 \
518         int __n = n;                                                          \
519         int any = 0;                                                          \
520         while (*rp == ' ')                                                    \
521           ++rp;                                                               \
522         val = 0;                                                              \
523         do {                                                                  \
524           val *= 10;                                                          \
525           while (*alts != '\0')                                               \
526             {                                                                 \
527               size_t len = strlen (alts);                                     \
528               if (strncasecmp (alts, rp, len) == 0)                           \
529                 break;                                                        \
530               alts += len + 1;                                                \
531               ++val;                                                          \
532             }                                                                 \
533           if (*alts == '\0')                                                  \
534             {                                                                 \
535               if (*decided == not && ! any)                                   \
536                 goto do_normal;                                               \
537               /* If we haven't read anything it's an error.  */               \
538               if (! any)                                                      \
539                 return NULL;                                                  \
540               /* Correct the premature multiplication.  */                    \
541               val /= 10;                                                      \
542               break;                                                          \
543             }                                                                 \
544           else                                                                \
545             *decided = loc;                                                   \
546         } while (--__n > 0 && val * 10 <= to);                                \
547         if (val < from || val > to)                                           \
548           return NULL;                                                        \
549       }                                                                       \
550     else                                                                      \
551       {                                                                       \
552        do_normal:                                                             \
553         get_number (from, to, n);                                             \
554       }                                                                       \
555   } while (0)
556 # endif /* defined __GNUC__ && __GNUC__ >= 2 */
557 #else
558 # define get_alt_number(from, to, n) \
559   /* We don't have the alternate representation.  */                          \
560   get_number(from, to, n)
561 #endif
562 #define recursive(new_fmt) \
563   (*(new_fmt) != '\0'                                                         \
564    && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
565
566
567 #ifdef _LIBC
568 /* This is defined in locale/C-time.c in the GNU libc.  */
569 extern const struct locale_data _nl_C_LC_TIME;
570 extern const unsigned short int __mon_yday[2][13];
571
572 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
573 # define ab_weekday_name \
574   (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
575 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
576 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
577 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
578 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
579 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
580 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
581 # define HERE_T_FMT_AMPM \
582   (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
583 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
584
585 # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
586 #else
587 static char const weekday_name[][10] =
588   {
589     "Sunday", "Monday", "Tuesday", "Wednesday",
590     "Thursday", "Friday", "Saturday"
591   };
592 static char const ab_weekday_name[][4] =
593   {
594     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
595   };
596 static char const month_name[][10] =
597   {
598     "January", "February", "March", "April", "May", "June",
599     "July", "August", "September", "October", "November", "December"
600   };
601 static char const ab_month_name[][4] =
602   {
603     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
604     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
605   };
606 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
607 # define HERE_D_FMT "%m/%d/%y"
608 # define HERE_AM_STR "AM"
609 # define HERE_PM_STR "PM"
610 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
611 # define HERE_T_FMT "%H:%M:%S"
612
613 /* __mon_yday[][] is common to mktime and strptime implementations.
614    --abbotti */
615 const unsigned short int __mon_yday[2][13];
616 # ifndef NEED_MON_YDAY
617 #  define NEED_MON_YDAY
618 # endif
619 #endif
620
621 /* Status of lookup: do we use the locale data or the raw data?  */
622 enum locale_status { not, loc, raw };
623
624
625 #ifndef __isleap
626 /* Nonzero if YEAR is a leap year (every 4 years,
627    except every 100th isn't, and every 400th is).  */
628 # define __isleap(year) \
629   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
630 #endif
631
632 /* Compute the day of the week.  */
633 static void
634 day_of_the_week (struct tm *tm)
635 {
636   /* We know that January 1st 1970 was a Thursday (= 4).  Compute the
637      the difference between this data in the one on TM and so determine
638      the weekday.  */
639   int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
640   int wday = (-473
641               + (365 * (tm->tm_year - 70))
642               + (corr_year / 4)
643               - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
644               + (((corr_year / 4) / 25) / 4)
645               + __mon_yday[0][tm->tm_mon]
646               + tm->tm_mday - 1);
647   tm->tm_wday = ((wday % 7) + 7) % 7;
648 }
649
650 /* Compute the day of the year.  */
651 static void
652 day_of_the_year (struct tm *tm)
653 {
654   tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
655                  + (tm->tm_mday - 1));
656 }
657
658 static char *
659 #ifdef _LIBC
660 internal_function
661 #endif
662 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
663                         enum locale_status *decided));
664
665 static char *
666 #ifdef _LIBC
667 internal_function
668 #endif
669 strptime_internal (rp, fmt, tm, decided)
670      const char *rp;
671      const char *fmt;
672      struct tm *tm;
673      enum locale_status *decided;
674 {
675 #ifdef _NL_CURRENT
676   const char *rp_backup;
677 #endif
678   int cnt;
679   size_t val;
680   int have_I, is_pm;
681   int century, want_century;
682   int have_wday, want_xday;
683   int have_yday;
684   int have_mon, have_mday;
685
686   have_I = is_pm = 0;
687   century = -1;
688   want_century = 0;
689   have_wday = want_xday = have_yday = have_mon = have_mday = 0;
690
691   while (*fmt != '\0')
692     {
693       /* A white space in the format string matches 0 more or white
694          space in the input string.  */
695       if (ISSPACE (*fmt))
696         {
697           while (ISSPACE (*rp))
698             ++rp;
699           ++fmt;
700           continue;
701         }
702
703       /* Any character but `%' must be matched by the same character
704          in the iput string.  */
705       if (*fmt != '%')
706         {
707           match_char (*fmt++, *rp++);
708           continue;
709         }
710
711       ++fmt;
712 #ifndef _NL_CURRENT
713       /* We need this for handling the `E' modifier.  */
714     start_over:
715 #endif
716
717 #ifdef _NL_CURRENT
718       /* Make back up of current processing pointer.  */
719       rp_backup = rp;
720 #endif
721
722       switch (*fmt++)
723         {
724         case '%':
725           /* Match the `%' character itself.  */
726           match_char ('%', *rp++);
727           break;
728         case 'a':
729         case 'A':
730           /* Match day of week.  */
731           for (cnt = 0; cnt < 7; ++cnt)
732             {
733 #ifdef _NL_CURRENT
734               if (*decided !=raw)
735                 {
736                   if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
737                     {
738                       if (*decided == not
739                           && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
740                                      weekday_name[cnt]))
741                         *decided = loc;
742                       break;
743                     }
744                   if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
745                     {
746                       if (*decided == not
747                           && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
748                                      ab_weekday_name[cnt]))
749                         *decided = loc;
750                       break;
751                     }
752                 }
753 #endif
754               if (*decided != loc
755                   && (match_string (weekday_name[cnt], rp)
756                       || match_string (ab_weekday_name[cnt], rp)))
757                 {
758                   *decided = raw;
759                   break;
760                 }
761             }
762           if (cnt == 7)
763             /* Does not match a weekday name.  */
764             return NULL;
765           tm->tm_wday = cnt;
766           have_wday = 1;
767           break;
768         case 'b':
769         case 'B':
770         case 'h':
771           /* Match month name.  */
772           for (cnt = 0; cnt < 12; ++cnt)
773             {
774 #ifdef _NL_CURRENT
775               if (*decided !=raw)
776                 {
777                   if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
778                     {
779                       if (*decided == not
780                           && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
781                                      month_name[cnt]))
782                         *decided = loc;
783                       break;
784                     }
785                   if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
786                     {
787                       if (*decided == not
788                           && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
789                                      ab_month_name[cnt]))
790                         *decided = loc;
791                       break;
792                     }
793                 }
794 #endif
795               if (match_string (month_name[cnt], rp)
796                   || match_string (ab_month_name[cnt], rp))
797                 {
798                   *decided = raw;
799                   break;
800                 }
801             }
802           if (cnt == 12)
803             /* Does not match a month name.  */
804             return NULL;
805           tm->tm_mon = cnt;
806           want_xday = 1;
807           break;
808         case 'c':
809           /* Match locale's date and time format.  */
810 #ifdef _NL_CURRENT
811           if (*decided != raw)
812             {
813               if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
814                 {
815                   if (*decided == loc)
816                     return NULL;
817                   else
818                     rp = rp_backup;
819                 }
820               else
821                 {
822                   if (*decided == not &&
823                       strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
824                     *decided = loc;
825                   want_xday = 1;
826                   break;
827                 }
828               *decided = raw;
829             }
830 #endif
831           if (!recursive (HERE_D_T_FMT))
832             return NULL;
833           want_xday = 1;
834           break;
835         case 'C':
836           /* Match century number.  */
837           get_number (0, 99, 2);
838           century = val;
839           want_xday = 1;
840           break;
841         case 'd':
842         case 'e':
843           /* Match day of month.  */
844           get_number (1, 31, 2);
845           tm->tm_mday = val;
846           have_mday = 1;
847           want_xday = 1;
848           break;
849         case 'F':
850           if (!recursive ("%Y-%m-%d"))
851             return NULL;
852           want_xday = 1;
853           break;
854         case 'x':
855 #ifdef _NL_CURRENT
856           if (*decided != raw)
857             {
858               if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
859                 {
860                   if (*decided == loc)
861                     return NULL;
862                   else
863                     rp = rp_backup;
864                 }
865               else
866                 {
867                   if (*decided == not
868                       && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
869                     *decided = loc;
870                   want_xday = 1;
871                   break;
872                 }
873               *decided = raw;
874             }
875 #endif
876           /* Fall through.  */
877         case 'D':
878           /* Match standard day format.  */
879           if (!recursive (HERE_D_FMT))
880             return NULL;
881           want_xday = 1;
882           break;
883         case 'k':
884         case 'H':
885           /* Match hour in 24-hour clock.  */
886           get_number (0, 23, 2);
887           tm->tm_hour = val;
888           have_I = 0;
889           break;
890         case 'I':
891           /* Match hour in 12-hour clock.  */
892           get_number (1, 12, 2);
893           tm->tm_hour = val % 12;
894           have_I = 1;
895           break;
896         case 'j':
897           /* Match day number of year.  */
898           get_number (1, 366, 3);
899           tm->tm_yday = val - 1;
900           have_yday = 1;
901           break;
902         case 'm':
903           /* Match number of month.  */
904           get_number (1, 12, 2);
905           tm->tm_mon = val - 1;
906           have_mon = 1;
907           want_xday = 1;
908           break;
909         case 'M':
910           /* Match minute.  */
911           get_number (0, 59, 2);
912           tm->tm_min = val;
913           break;
914         case 'n':
915         case 't':
916           /* Match any white space.  */
917           while (ISSPACE (*rp))
918             ++rp;
919           break;
920         case 'p':
921           /* Match locale's equivalent of AM/PM.  */
922 #ifdef _NL_CURRENT
923           if (*decided != raw)
924             {
925               if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
926                 {
927                   if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
928                     *decided = loc;
929                   break;
930                 }
931               if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
932                 {
933                   if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
934                     *decided = loc;
935                   is_pm = 1;
936                   break;
937                 }
938               *decided = raw;
939             }
940 #endif
941           if (!match_string (HERE_AM_STR, rp))
942             if (match_string (HERE_PM_STR, rp))
943               is_pm = 1;
944             else
945               return NULL;
946           break;
947         case 'r':
948 #ifdef _NL_CURRENT
949           if (*decided != raw)
950             {
951               if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
952                 {
953                   if (*decided == loc)
954                     return NULL;
955                   else
956                     rp = rp_backup;
957                 }
958               else
959                 {
960                   if (*decided == not &&
961                       strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
962                               HERE_T_FMT_AMPM))
963                     *decided = loc;
964                   break;
965                 }
966               *decided = raw;
967             }
968 #endif
969           if (!recursive (HERE_T_FMT_AMPM))
970             return NULL;
971           break;
972         case 'R':
973           if (!recursive ("%H:%M"))
974             return NULL;
975           break;
976         case 's':
977           {
978             /* The number of seconds may be very high so we cannot use
979                the `get_number' macro.  Instead read the number
980                character for character and construct the result while
981                doing this.  */
982             time_t secs = 0;
983             if (*rp < '0' || *rp > '9')
984               /* We need at least one digit.  */
985               return NULL;
986
987             do
988               {
989                 secs *= 10;
990                 secs += *rp++ - '0';
991               }
992             while (*rp >= '0' && *rp <= '9');
993
994             if (localtime_r (&secs, tm) == NULL)
995               /* Error in function.  */
996               return NULL;
997           }
998           break;
999         case 'S':
1000           get_number (0, 61, 2);
1001           tm->tm_sec = val;
1002           break;
1003         case 'X':
1004 #ifdef _NL_CURRENT
1005           if (*decided != raw)
1006             {
1007               if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
1008                 {
1009                   if (*decided == loc)
1010                     return NULL;
1011                   else
1012                     rp = rp_backup;
1013                 }
1014               else
1015                 {
1016                   if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
1017                     *decided = loc;
1018                   break;
1019                 }
1020               *decided = raw;
1021             }
1022 #endif
1023           /* Fall through.  */
1024         case 'T':
1025           if (!recursive (HERE_T_FMT))
1026             return NULL;
1027           break;
1028         case 'u':
1029           get_number (1, 7, 1);
1030           tm->tm_wday = val % 7;
1031           have_wday = 1;
1032           break;
1033         case 'g':
1034           get_number (0, 99, 2);
1035           /* XXX This cannot determine any field in TM.  */
1036           break;
1037         case 'G':
1038           if (*rp < '0' || *rp > '9')
1039             return NULL;
1040           /* XXX Ignore the number since we would need some more
1041              information to compute a real date.  */
1042           do
1043             ++rp;
1044           while (*rp >= '0' && *rp <= '9');
1045           break;
1046         case 'U':
1047         case 'V':
1048         case 'W':
1049           get_number (0, 53, 2);
1050           /* XXX This cannot determine any field in TM without some
1051              information.  */
1052           break;
1053         case 'w':
1054           /* Match number of weekday.  */
1055           get_number (0, 6, 1);
1056           tm->tm_wday = val;
1057           have_wday = 1;
1058           break;
1059         case 'y':
1060           /* Match year within century.  */
1061           get_number (0, 99, 2);
1062           /* The "Year 2000: The Millennium Rollover" paper suggests that
1063              values in the range 69-99 refer to the twentieth century.  */
1064           tm->tm_year = val >= 69 ? val : val + 100;
1065           /* Indicate that we want to use the century, if specified.  */
1066           want_century = 1;
1067           want_xday = 1;
1068           break;
1069         case 'Y':
1070           /* Match year including century number.  */
1071           get_number (0, 9999, 4);
1072           tm->tm_year = val - 1900;
1073           want_century = 0;
1074           want_xday = 1;
1075           break;
1076         case 'Z':
1077           /* XXX How to handle this?  */
1078           break;
1079         case 'E':
1080 #ifdef _NL_CURRENT
1081           switch (*fmt++)
1082             {
1083             case 'c':
1084               /* Match locale's alternate date and time format.  */
1085               if (*decided != raw)
1086                 {
1087                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1088
1089                   if (*fmt == '\0')
1090                     fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1091
1092                   if (!recursive (fmt))
1093                     {
1094                       if (*decided == loc)
1095                         return NULL;
1096                       else
1097                         rp = rp_backup;
1098                     }
1099                   else
1100                     {
1101                       if (strcmp (fmt, HERE_D_T_FMT))
1102                         *decided = loc;
1103                       want_xday = 1;
1104                       break;
1105                     }
1106                   *decided = raw;
1107                 }
1108               /* The C locale has no era information, so use the
1109                  normal representation.  */
1110               if (!recursive (HERE_D_T_FMT))
1111                 return NULL;
1112               want_xday = 1;
1113               break;
1114             case 'C':
1115             case 'y':
1116             case 'Y':
1117               /* Match name of base year in locale's alternate
1118                  representation.  */
1119               /* XXX This is currently not implemented.  It should
1120                  use the value _NL_CURRENT (LC_TIME, ERA).  */
1121               break;
1122             case 'x':
1123               if (*decided != raw)
1124                 {
1125                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1126
1127                   if (*fmt == '\0')
1128                     fmt = _NL_CURRENT (LC_TIME, D_FMT);
1129
1130                   if (!recursive (fmt))
1131                     {
1132                       if (*decided == loc)
1133                         return NULL;
1134                       else
1135                         rp = rp_backup;
1136                     }
1137                   else
1138                     {
1139                       if (strcmp (fmt, HERE_D_FMT))
1140                         *decided = loc;
1141                       break;
1142                     }
1143                   *decided = raw;
1144                 }
1145               if (!recursive (HERE_D_FMT))
1146                 return NULL;
1147               break;
1148             case 'X':
1149               if (*decided != raw)
1150                 {
1151                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1152
1153                   if (*fmt == '\0')
1154                     fmt = _NL_CURRENT (LC_TIME, T_FMT);
1155
1156                   if (!recursive (fmt))
1157                     {
1158                       if (*decided == loc)
1159                         return NULL;
1160                       else
1161                         rp = rp_backup;
1162                     }
1163                   else
1164                     {
1165                       if (strcmp (fmt, HERE_T_FMT))
1166                         *decided = loc;
1167                       break;
1168                     }
1169                   *decided = raw;
1170                 }
1171               if (!recursive (HERE_T_FMT))
1172                 return NULL;
1173               break;
1174             default:
1175               return NULL;
1176             }
1177           break;
1178 #else
1179           /* We have no information about the era format.  Just use
1180              the normal format.  */
1181           if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1182               && *fmt != 'x' && *fmt != 'X')
1183             /* This is an illegal format.  */
1184             return NULL;
1185
1186           goto start_over;
1187 #endif
1188         case 'O':
1189           switch (*fmt++)
1190             {
1191             case 'd':
1192             case 'e':
1193               /* Match day of month using alternate numeric symbols.  */
1194               get_alt_number (1, 31, 2);
1195               tm->tm_mday = val;
1196               have_mday = 1;
1197               want_xday = 1;
1198               break;
1199             case 'H':
1200               /* Match hour in 24-hour clock using alternate numeric
1201                  symbols.  */
1202               get_alt_number (0, 23, 2);
1203               tm->tm_hour = val;
1204               have_I = 0;
1205               break;
1206             case 'I':
1207               /* Match hour in 12-hour clock using alternate numeric
1208                  symbols.  */
1209               get_alt_number (1, 12, 2);
1210               tm->tm_hour = val - 1;
1211               have_I = 1;
1212               break;
1213             case 'm':
1214               /* Match month using alternate numeric symbols.  */
1215               get_alt_number (1, 12, 2);
1216               tm->tm_mon = val - 1;
1217               have_mon = 1;
1218               want_xday = 1;
1219               break;
1220             case 'M':
1221               /* Match minutes using alternate numeric symbols.  */
1222               get_alt_number (0, 59, 2);
1223               tm->tm_min = val;
1224               break;
1225             case 'S':
1226               /* Match seconds using alternate numeric symbols.  */
1227               get_alt_number (0, 61, 2);
1228               tm->tm_sec = val;
1229               break;
1230             case 'U':
1231             case 'V':
1232             case 'W':
1233               get_alt_number (0, 53, 2);
1234               /* XXX This cannot determine any field in TM without
1235                  further information.  */
1236               break;
1237             case 'w':
1238               /* Match number of weekday using alternate numeric symbols.  */
1239               get_alt_number (0, 6, 1);
1240               tm->tm_wday = val;
1241               have_wday = 1;
1242               break;
1243             case 'y':
1244               /* Match year within century using alternate numeric symbols.  */
1245               get_alt_number (0, 99, 2);
1246               tm->tm_year = val >= 69 ? val : val + 100;
1247               want_xday = 1;
1248               break;
1249             default:
1250               return NULL;
1251             }
1252           break;
1253         default:
1254           return NULL;
1255         }
1256     }
1257
1258   if (have_I && is_pm)
1259     tm->tm_hour += 12;
1260
1261   if (century != -1)
1262     {
1263       if (want_century)
1264         tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1265       else
1266         /* Only the century, but not the year.  Strange, but so be it.  */
1267         tm->tm_year = (century - 19) * 100;
1268     }
1269
1270   if (want_xday && !have_wday) {
1271       if ( !(have_mon && have_mday) && have_yday)  {
1272           /* we don't have tm_mon and/or tm_mday, compute them */
1273           int t_mon = 0;
1274           while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1275               t_mon++;
1276           if (!have_mon)
1277               tm->tm_mon = t_mon - 1;
1278           if (!have_mday)
1279               tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1280       }
1281       day_of_the_week (tm);
1282   }
1283   if (want_xday && !have_yday)
1284     day_of_the_year (tm);
1285
1286   return (char *) rp;
1287 }
1288
1289
1290 char *
1291 strptime (buf, format, tm)
1292      const char *buf;
1293      const char *format;
1294      struct tm *tm;
1295 {
1296   enum locale_status decided;
1297 #ifdef _NL_CURRENT
1298   decided = not;
1299 #else
1300   decided = raw;
1301 #endif
1302   return strptime_internal (buf, format, tm, &decided);
1303 }
1304 #endif /* not HAVE_STRPTIME */
1305
1306 #ifdef NEED_MON_YDAY
1307 /* __mon_yday[][] is common to mktime and strptime implementations.
1308    --abbotti */
1309 const unsigned short int __mon_yday[2][13] =
1310   {
1311     /* Normal years.  */
1312     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1313     /* Leap years.  */
1314     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1315   };
1316 #endif
1317
1318 /* fnmatch is defined by POSIX, but we include an implementation for
1319    the sake of systems that don't have it.  Some systems do have
1320    fnmatch, but Apache installs its own fnmatch.h (incompatible with
1321    the system one) in a system include directory, effectively
1322    rendering fnmatch unusable.
1323
1324    Additionally according to anecdotal evidence and conventional
1325    wisdom I lack courage to challenge, many implementations of fnmatch
1326    are notoriously buggy and unreliable.  So we use our version by
1327    default, except when compiling under systems where fnmatch is known
1328    to work (currently on GNU libc-based systems and Solaris.)  */
1329
1330 #ifndef SYSTEM_FNMATCH
1331
1332 #define __FNM_FLAGS     (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
1333
1334 /* Match STRING against the filename pattern PATTERN, returning zero
1335    if it matches, FNM_NOMATCH if not.  This implementation comes from
1336    an earlier version of GNU Bash.  (It doesn't make sense to update
1337    it with a newer version because those versions add a lot of
1338    features Wget doesn't use or care about.)  */
1339
1340 int
1341 fnmatch (const char *pattern, const char *string, int flags)
1342 {
1343   register const char *p = pattern, *n = string;
1344   register char c;
1345
1346   if ((flags & ~__FNM_FLAGS) != 0)
1347     {
1348       errno = EINVAL;
1349       return (-1);
1350     }
1351
1352   while ((c = *p++) != '\0')
1353     {
1354       switch (c)
1355         {
1356         case '?':
1357           if (*n == '\0')
1358             return (FNM_NOMATCH);
1359           else if ((flags & FNM_PATHNAME) && *n == '/')
1360             return (FNM_NOMATCH);
1361           else if ((flags & FNM_PERIOD) && *n == '.' &&
1362                    (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1363             return (FNM_NOMATCH);
1364           break;
1365
1366         case '\\':
1367           if (!(flags & FNM_NOESCAPE))
1368             c = *p++;
1369           if (*n != c)
1370             return (FNM_NOMATCH);
1371           break;
1372
1373         case '*':
1374           if ((flags & FNM_PERIOD) && *n == '.' &&
1375               (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1376             return (FNM_NOMATCH);
1377
1378           for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1379             if (((flags & FNM_PATHNAME) && *n == '/') ||
1380                 (c == '?' && *n == '\0'))
1381               return (FNM_NOMATCH);
1382
1383           if (c == '\0')
1384             return (0);
1385
1386           {
1387             char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1388             for (--p; *n != '\0'; ++n)
1389               if ((c == '[' || *n == c1) &&
1390                   fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1391                 return (0);
1392             return (FNM_NOMATCH);
1393           }
1394
1395         case '[':
1396           {
1397             /* Nonzero if the sense of the character class is
1398                inverted.  */
1399             register int not;
1400
1401             if (*n == '\0')
1402               return (FNM_NOMATCH);
1403
1404             if ((flags & FNM_PERIOD) && *n == '.' &&
1405                 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1406               return (FNM_NOMATCH);
1407
1408             /* Make sure there is a closing `]'.  If there isn't,
1409                the `[' is just a character to be matched.  */
1410             {
1411               register const char *np;
1412
1413               for (np = p; np && *np && *np != ']'; np++);
1414
1415               if (np && !*np)
1416                 {
1417                   if (*n != '[')
1418                     return (FNM_NOMATCH);
1419                   goto next_char;
1420                 }
1421             }
1422
1423             not = (*p == '!' || *p == '^');
1424             if (not)
1425               ++p;
1426
1427             c = *p++;
1428             while (1)
1429               {
1430                 register char cstart = c, cend = c;
1431
1432                 if (!(flags & FNM_NOESCAPE) && c == '\\')
1433                   cstart = cend = *p++;
1434
1435                 if (c == '\0')
1436                   /* [ (unterminated) loses.  */
1437                   return (FNM_NOMATCH);
1438
1439                 c = *p++;
1440
1441                 if ((flags & FNM_PATHNAME) && c == '/')
1442                   /* [/] can never match.  */
1443                   return (FNM_NOMATCH);
1444
1445                 if (c == '-' && *p != ']')
1446                   {
1447                     cend = *p++;
1448                     if (!(flags & FNM_NOESCAPE) && cend == '\\')
1449                       cend = *p++;
1450                     if (cend == '\0')
1451                       return (FNM_NOMATCH);
1452                     c = *p++;
1453                   }
1454
1455                 if (*n >= cstart && *n <= cend)
1456                   goto matched;
1457
1458                 if (c == ']')
1459                   break;
1460               }
1461             if (!not)
1462               return (FNM_NOMATCH);
1463
1464           next_char:
1465             break;
1466
1467           matched:
1468             /* Skip the rest of the [...] that already matched.  */
1469             while (c != ']')
1470               {
1471                 if (c == '\0')
1472                   /* [... (unterminated) loses.  */
1473                   return (FNM_NOMATCH);
1474
1475                 c = *p++;
1476                 if (!(flags & FNM_NOESCAPE) && c == '\\')
1477                   /* 1003.2d11 is unclear if this is right.  %%% */
1478                   ++p;
1479               }
1480             if (not)
1481               return (FNM_NOMATCH);
1482           }
1483           break;
1484
1485         default:
1486           if (c != *n)
1487             return (FNM_NOMATCH);
1488         }
1489
1490       ++n;
1491     }
1492
1493   if (*n == '\0')
1494     return (0);
1495
1496   return (FNM_NOMATCH);
1497 }
1498
1499 #endif /* not SYSTEM_FNMATCH */