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