]> sjero.net Git - wget/blob - src/cmpt.c
[svn] Move fnmatch() to cmpt.c and don't use it under GNU libc.
[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   const char *rp_backup;
796   int cnt;
797   size_t val;
798   int have_I, is_pm;
799   int century, want_century;
800   int have_wday, want_xday;
801   int have_yday;
802   int have_mon, have_mday;
803
804   have_I = is_pm = 0;
805   century = -1;
806   want_century = 0;
807   have_wday = want_xday = have_yday = have_mon = have_mday = 0;
808
809   while (*fmt != '\0')
810     {
811       /* A white space in the format string matches 0 more or white
812          space in the input string.  */
813       if (ISSPACE (*fmt))
814         {
815           while (ISSPACE (*rp))
816             ++rp;
817           ++fmt;
818           continue;
819         }
820
821       /* Any character but `%' must be matched by the same character
822          in the iput string.  */
823       if (*fmt != '%')
824         {
825           match_char (*fmt++, *rp++);
826           continue;
827         }
828
829       ++fmt;
830 #ifndef _NL_CURRENT
831       /* We need this for handling the `E' modifier.  */
832     start_over:
833 #endif
834
835       /* Make back up of current processing pointer.  */
836       rp_backup = rp;
837
838       switch (*fmt++)
839         {
840         case '%':
841           /* Match the `%' character itself.  */
842           match_char ('%', *rp++);
843           break;
844         case 'a':
845         case 'A':
846           /* Match day of week.  */
847           for (cnt = 0; cnt < 7; ++cnt)
848             {
849 #ifdef _NL_CURRENT
850               if (*decided !=raw)
851                 {
852                   if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
853                     {
854                       if (*decided == not
855                           && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
856                                      weekday_name[cnt]))
857                         *decided = loc;
858                       break;
859                     }
860                   if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
861                     {
862                       if (*decided == not
863                           && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
864                                      ab_weekday_name[cnt]))
865                         *decided = loc;
866                       break;
867                     }
868                 }
869 #endif
870               if (*decided != loc
871                   && (match_string (weekday_name[cnt], rp)
872                       || match_string (ab_weekday_name[cnt], rp)))
873                 {
874                   *decided = raw;
875                   break;
876                 }
877             }
878           if (cnt == 7)
879             /* Does not match a weekday name.  */
880             return NULL;
881           tm->tm_wday = cnt;
882           have_wday = 1;
883           break;
884         case 'b':
885         case 'B':
886         case 'h':
887           /* Match month name.  */
888           for (cnt = 0; cnt < 12; ++cnt)
889             {
890 #ifdef _NL_CURRENT
891               if (*decided !=raw)
892                 {
893                   if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
894                     {
895                       if (*decided == not
896                           && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
897                                      month_name[cnt]))
898                         *decided = loc;
899                       break;
900                     }
901                   if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
902                     {
903                       if (*decided == not
904                           && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
905                                      ab_month_name[cnt]))
906                         *decided = loc;
907                       break;
908                     }
909                 }
910 #endif
911               if (match_string (month_name[cnt], rp)
912                   || match_string (ab_month_name[cnt], rp))
913                 {
914                   *decided = raw;
915                   break;
916                 }
917             }
918           if (cnt == 12)
919             /* Does not match a month name.  */
920             return NULL;
921           tm->tm_mon = cnt;
922           want_xday = 1;
923           break;
924         case 'c':
925           /* Match locale's date and time format.  */
926 #ifdef _NL_CURRENT
927           if (*decided != raw)
928             {
929               if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
930                 {
931                   if (*decided == loc)
932                     return NULL;
933                   else
934                     rp = rp_backup;
935                 }
936               else
937                 {
938                   if (*decided == not &&
939                       strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
940                     *decided = loc;
941                   want_xday = 1;
942                   break;
943                 }
944               *decided = raw;
945             }
946 #endif
947           if (!recursive (HERE_D_T_FMT))
948             return NULL;
949           want_xday = 1;
950           break;
951         case 'C':
952           /* Match century number.  */
953           get_number (0, 99, 2);
954           century = val;
955           want_xday = 1;
956           break;
957         case 'd':
958         case 'e':
959           /* Match day of month.  */
960           get_number (1, 31, 2);
961           tm->tm_mday = val;
962           have_mday = 1;
963           want_xday = 1;
964           break;
965         case 'F':
966           if (!recursive ("%Y-%m-%d"))
967             return NULL;
968           want_xday = 1;
969           break;
970         case 'x':
971 #ifdef _NL_CURRENT
972           if (*decided != raw)
973             {
974               if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
975                 {
976                   if (*decided == loc)
977                     return NULL;
978                   else
979                     rp = rp_backup;
980                 }
981               else
982                 {
983                   if (*decided == not
984                       && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
985                     *decided = loc;
986                   want_xday = 1;
987                   break;
988                 }
989               *decided = raw;
990             }
991 #endif
992           /* Fall through.  */
993         case 'D':
994           /* Match standard day format.  */
995           if (!recursive (HERE_D_FMT))
996             return NULL;
997           want_xday = 1;
998           break;
999         case 'k':
1000         case 'H':
1001           /* Match hour in 24-hour clock.  */
1002           get_number (0, 23, 2);
1003           tm->tm_hour = val;
1004           have_I = 0;
1005           break;
1006         case 'I':
1007           /* Match hour in 12-hour clock.  */
1008           get_number (1, 12, 2);
1009           tm->tm_hour = val % 12;
1010           have_I = 1;
1011           break;
1012         case 'j':
1013           /* Match day number of year.  */
1014           get_number (1, 366, 3);
1015           tm->tm_yday = val - 1;
1016           have_yday = 1;
1017           break;
1018         case 'm':
1019           /* Match number of month.  */
1020           get_number (1, 12, 2);
1021           tm->tm_mon = val - 1;
1022           have_mon = 1;
1023           want_xday = 1;
1024           break;
1025         case 'M':
1026           /* Match minute.  */
1027           get_number (0, 59, 2);
1028           tm->tm_min = val;
1029           break;
1030         case 'n':
1031         case 't':
1032           /* Match any white space.  */
1033           while (ISSPACE (*rp))
1034             ++rp;
1035           break;
1036         case 'p':
1037           /* Match locale's equivalent of AM/PM.  */
1038 #ifdef _NL_CURRENT
1039           if (*decided != raw)
1040             {
1041               if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
1042                 {
1043                   if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
1044                     *decided = loc;
1045                   break;
1046                 }
1047               if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
1048                 {
1049                   if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
1050                     *decided = loc;
1051                   is_pm = 1;
1052                   break;
1053                 }
1054               *decided = raw;
1055             }
1056 #endif
1057           if (!match_string (HERE_AM_STR, rp))
1058             if (match_string (HERE_PM_STR, rp))
1059               is_pm = 1;
1060             else
1061               return NULL;
1062           break;
1063         case 'r':
1064 #ifdef _NL_CURRENT
1065           if (*decided != raw)
1066             {
1067               if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
1068                 {
1069                   if (*decided == loc)
1070                     return NULL;
1071                   else
1072                     rp = rp_backup;
1073                 }
1074               else
1075                 {
1076                   if (*decided == not &&
1077                       strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
1078                               HERE_T_FMT_AMPM))
1079                     *decided = loc;
1080                   break;
1081                 }
1082               *decided = raw;
1083             }
1084 #endif
1085           if (!recursive (HERE_T_FMT_AMPM))
1086             return NULL;
1087           break;
1088         case 'R':
1089           if (!recursive ("%H:%M"))
1090             return NULL;
1091           break;
1092         case 's':
1093           {
1094             /* The number of seconds may be very high so we cannot use
1095                the `get_number' macro.  Instead read the number
1096                character for character and construct the result while
1097                doing this.  */
1098             time_t secs = 0;
1099             if (*rp < '0' || *rp > '9')
1100               /* We need at least one digit.  */
1101               return NULL;
1102
1103             do
1104               {
1105                 secs *= 10;
1106                 secs += *rp++ - '0';
1107               }
1108             while (*rp >= '0' && *rp <= '9');
1109
1110             if (localtime_r (&secs, tm) == NULL)
1111               /* Error in function.  */
1112               return NULL;
1113           }
1114           break;
1115         case 'S':
1116           get_number (0, 61, 2);
1117           tm->tm_sec = val;
1118           break;
1119         case 'X':
1120 #ifdef _NL_CURRENT
1121           if (*decided != raw)
1122             {
1123               if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
1124                 {
1125                   if (*decided == loc)
1126                     return NULL;
1127                   else
1128                     rp = rp_backup;
1129                 }
1130               else
1131                 {
1132                   if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
1133                     *decided = loc;
1134                   break;
1135                 }
1136               *decided = raw;
1137             }
1138 #endif
1139           /* Fall through.  */
1140         case 'T':
1141           if (!recursive (HERE_T_FMT))
1142             return NULL;
1143           break;
1144         case 'u':
1145           get_number (1, 7, 1);
1146           tm->tm_wday = val % 7;
1147           have_wday = 1;
1148           break;
1149         case 'g':
1150           get_number (0, 99, 2);
1151           /* XXX This cannot determine any field in TM.  */
1152           break;
1153         case 'G':
1154           if (*rp < '0' || *rp > '9')
1155             return NULL;
1156           /* XXX Ignore the number since we would need some more
1157              information to compute a real date.  */
1158           do
1159             ++rp;
1160           while (*rp >= '0' && *rp <= '9');
1161           break;
1162         case 'U':
1163         case 'V':
1164         case 'W':
1165           get_number (0, 53, 2);
1166           /* XXX This cannot determine any field in TM without some
1167              information.  */
1168           break;
1169         case 'w':
1170           /* Match number of weekday.  */
1171           get_number (0, 6, 1);
1172           tm->tm_wday = val;
1173           have_wday = 1;
1174           break;
1175         case 'y':
1176           /* Match year within century.  */
1177           get_number (0, 99, 2);
1178           /* The "Year 2000: The Millennium Rollover" paper suggests that
1179              values in the range 69-99 refer to the twentieth century.  */
1180           tm->tm_year = val >= 69 ? val : val + 100;
1181           /* Indicate that we want to use the century, if specified.  */
1182           want_century = 1;
1183           want_xday = 1;
1184           break;
1185         case 'Y':
1186           /* Match year including century number.  */
1187           get_number (0, 9999, 4);
1188           tm->tm_year = val - 1900;
1189           want_century = 0;
1190           want_xday = 1;
1191           break;
1192         case 'Z':
1193           /* XXX How to handle this?  */
1194           break;
1195         case 'E':
1196 #ifdef _NL_CURRENT
1197           switch (*fmt++)
1198             {
1199             case 'c':
1200               /* Match locale's alternate date and time format.  */
1201               if (*decided != raw)
1202                 {
1203                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1204
1205                   if (*fmt == '\0')
1206                     fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1207
1208                   if (!recursive (fmt))
1209                     {
1210                       if (*decided == loc)
1211                         return NULL;
1212                       else
1213                         rp = rp_backup;
1214                     }
1215                   else
1216                     {
1217                       if (strcmp (fmt, HERE_D_T_FMT))
1218                         *decided = loc;
1219                       want_xday = 1;
1220                       break;
1221                     }
1222                   *decided = raw;
1223                 }
1224               /* The C locale has no era information, so use the
1225                  normal representation.  */
1226               if (!recursive (HERE_D_T_FMT))
1227                 return NULL;
1228               want_xday = 1;
1229               break;
1230             case 'C':
1231             case 'y':
1232             case 'Y':
1233               /* Match name of base year in locale's alternate
1234                  representation.  */
1235               /* XXX This is currently not implemented.  It should
1236                  use the value _NL_CURRENT (LC_TIME, ERA).  */
1237               break;
1238             case 'x':
1239               if (*decided != raw)
1240                 {
1241                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1242
1243                   if (*fmt == '\0')
1244                     fmt = _NL_CURRENT (LC_TIME, D_FMT);
1245
1246                   if (!recursive (fmt))
1247                     {
1248                       if (*decided == loc)
1249                         return NULL;
1250                       else
1251                         rp = rp_backup;
1252                     }
1253                   else
1254                     {
1255                       if (strcmp (fmt, HERE_D_FMT))
1256                         *decided = loc;
1257                       break;
1258                     }
1259                   *decided = raw;
1260                 }
1261               if (!recursive (HERE_D_FMT))
1262                 return NULL;
1263               break;
1264             case 'X':
1265               if (*decided != raw)
1266                 {
1267                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1268
1269                   if (*fmt == '\0')
1270                     fmt = _NL_CURRENT (LC_TIME, T_FMT);
1271
1272                   if (!recursive (fmt))
1273                     {
1274                       if (*decided == loc)
1275                         return NULL;
1276                       else
1277                         rp = rp_backup;
1278                     }
1279                   else
1280                     {
1281                       if (strcmp (fmt, HERE_T_FMT))
1282                         *decided = loc;
1283                       break;
1284                     }
1285                   *decided = raw;
1286                 }
1287               if (!recursive (HERE_T_FMT))
1288                 return NULL;
1289               break;
1290             default:
1291               return NULL;
1292             }
1293           break;
1294 #else
1295           /* We have no information about the era format.  Just use
1296              the normal format.  */
1297           if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1298               && *fmt != 'x' && *fmt != 'X')
1299             /* This is an illegal format.  */
1300             return NULL;
1301
1302           goto start_over;
1303 #endif
1304         case 'O':
1305           switch (*fmt++)
1306             {
1307             case 'd':
1308             case 'e':
1309               /* Match day of month using alternate numeric symbols.  */
1310               get_alt_number (1, 31, 2);
1311               tm->tm_mday = val;
1312               have_mday = 1;
1313               want_xday = 1;
1314               break;
1315             case 'H':
1316               /* Match hour in 24-hour clock using alternate numeric
1317                  symbols.  */
1318               get_alt_number (0, 23, 2);
1319               tm->tm_hour = val;
1320               have_I = 0;
1321               break;
1322             case 'I':
1323               /* Match hour in 12-hour clock using alternate numeric
1324                  symbols.  */
1325               get_alt_number (1, 12, 2);
1326               tm->tm_hour = val - 1;
1327               have_I = 1;
1328               break;
1329             case 'm':
1330               /* Match month using alternate numeric symbols.  */
1331               get_alt_number (1, 12, 2);
1332               tm->tm_mon = val - 1;
1333               have_mon = 1;
1334               want_xday = 1;
1335               break;
1336             case 'M':
1337               /* Match minutes using alternate numeric symbols.  */
1338               get_alt_number (0, 59, 2);
1339               tm->tm_min = val;
1340               break;
1341             case 'S':
1342               /* Match seconds using alternate numeric symbols.  */
1343               get_alt_number (0, 61, 2);
1344               tm->tm_sec = val;
1345               break;
1346             case 'U':
1347             case 'V':
1348             case 'W':
1349               get_alt_number (0, 53, 2);
1350               /* XXX This cannot determine any field in TM without
1351                  further information.  */
1352               break;
1353             case 'w':
1354               /* Match number of weekday using alternate numeric symbols.  */
1355               get_alt_number (0, 6, 1);
1356               tm->tm_wday = val;
1357               have_wday = 1;
1358               break;
1359             case 'y':
1360               /* Match year within century using alternate numeric symbols.  */
1361               get_alt_number (0, 99, 2);
1362               tm->tm_year = val >= 69 ? val : val + 100;
1363               want_xday = 1;
1364               break;
1365             default:
1366               return NULL;
1367             }
1368           break;
1369         default:
1370           return NULL;
1371         }
1372     }
1373
1374   if (have_I && is_pm)
1375     tm->tm_hour += 12;
1376
1377   if (century != -1)
1378     {
1379       if (want_century)
1380         tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1381       else
1382         /* Only the century, but not the year.  Strange, but so be it.  */
1383         tm->tm_year = (century - 19) * 100;
1384     }
1385
1386   if (want_xday && !have_wday) {
1387       if ( !(have_mon && have_mday) && have_yday)  {
1388           /* we don't have tm_mon and/or tm_mday, compute them */
1389           int t_mon = 0;
1390           while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1391               t_mon++;
1392           if (!have_mon)
1393               tm->tm_mon = t_mon - 1;
1394           if (!have_mday)
1395               tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1396       }
1397       day_of_the_week (tm);
1398   }
1399   if (want_xday && !have_yday)
1400     day_of_the_year (tm);
1401
1402   return (char *) rp;
1403 }
1404
1405
1406 char *
1407 strptime (buf, format, tm)
1408      const char *buf;
1409      const char *format;
1410      struct tm *tm;
1411 {
1412   enum locale_status decided;
1413 #ifdef _NL_CURRENT
1414   decided = not;
1415 #else
1416   decided = raw;
1417 #endif
1418   return strptime_internal (buf, format, tm, &decided);
1419 }
1420 #endif /* not HAVE_STRPTIME */
1421
1422 #ifdef NEED_MON_YDAY
1423 /* __mon_yday[][] is common to mktime and strptime implementations.
1424    --abbotti */
1425 const unsigned short int __mon_yday[2][13] =
1426   {
1427     /* Normal years.  */
1428     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1429     /* Leap years.  */
1430     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1431   };
1432 #endif
1433
1434 #ifndef HAVE_USLEEP
1435 #ifndef WINDOWS
1436
1437 /* A simple usleep implementation based on select().  For Unix and
1438    Unix-like systems.  */
1439
1440 int
1441 usleep (unsigned long usec)
1442 {
1443   struct timeval tm;
1444   tm.tv_sec = 0;
1445   tm.tv_usec = usec;
1446   select (0, NULL, NULL, NULL, &tm);
1447   return 0;
1448 }
1449
1450 #endif /* not WINDOWS */
1451 #endif /* not HAVE_USLEEP */
1452
1453
1454 /* Currently unused in Wget.  Uncomment if we start using memmove
1455    again. */
1456 #if 0
1457
1458 #ifndef HAVE_MEMMOVE
1459 void *
1460 memmove (char *dest, const char *source, unsigned length)
1461 {
1462   char *d0 = dest;
1463   if (source < dest)
1464     /* Moving from low mem to hi mem; start at end.  */
1465     for (source += length, dest += length; length; --length)
1466       *--dest = *--source;
1467   else if (source != dest)
1468     {
1469       /* Moving from hi mem to low mem; start at beginning.  */
1470       for (; length; --length)
1471         *dest++ = *source++;
1472     }
1473   return (void *) d0;
1474 }
1475 #endif /* not HAVE_MEMMOVE */
1476
1477 #endif /* 0 */
1478
1479 /* fnmatch is a POSIX function, but we include an implementation for
1480    the sake of systems that don't have it.  Furthermore, according to
1481    anecdotal evidence, historical implementations of fnmatch are buggy
1482    and unreliable.  So we use our version, except when compiling under
1483    systems where fnmatch is known to work (currently glibc.)  */
1484
1485 #ifndef SYSTEM_FNMATCH
1486
1487 #define __FNM_FLAGS     (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
1488
1489 /* Match STRING against the filename pattern PATTERN, returning zero
1490    if it matches, FNM_NOMATCH if not.  This implementation comes from
1491    an earlier version of GNU Bash.  (It doesn't make sense to update
1492    it with a newer version because it adds a lot of features Wget
1493    doesn't use or care about.)  */
1494
1495 int
1496 fnmatch (const char *pattern, const char *string, int flags)
1497 {
1498   register const char *p = pattern, *n = string;
1499   register char c;
1500
1501   if ((flags & ~__FNM_FLAGS) != 0)
1502     {
1503       errno = EINVAL;
1504       return (-1);
1505     }
1506
1507   while ((c = *p++) != '\0')
1508     {
1509       switch (c)
1510         {
1511         case '?':
1512           if (*n == '\0')
1513             return (FNM_NOMATCH);
1514           else if ((flags & FNM_PATHNAME) && *n == '/')
1515             return (FNM_NOMATCH);
1516           else if ((flags & FNM_PERIOD) && *n == '.' &&
1517                    (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1518             return (FNM_NOMATCH);
1519           break;
1520
1521         case '\\':
1522           if (!(flags & FNM_NOESCAPE))
1523             c = *p++;
1524           if (*n != c)
1525             return (FNM_NOMATCH);
1526           break;
1527
1528         case '*':
1529           if ((flags & FNM_PERIOD) && *n == '.' &&
1530               (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1531             return (FNM_NOMATCH);
1532
1533           for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1534             if (((flags & FNM_PATHNAME) && *n == '/') ||
1535                 (c == '?' && *n == '\0'))
1536               return (FNM_NOMATCH);
1537
1538           if (c == '\0')
1539             return (0);
1540
1541           {
1542             char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1543             for (--p; *n != '\0'; ++n)
1544               if ((c == '[' || *n == c1) &&
1545                   fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1546                 return (0);
1547             return (FNM_NOMATCH);
1548           }
1549
1550         case '[':
1551           {
1552             /* Nonzero if the sense of the character class is
1553                inverted.  */
1554             register int not;
1555
1556             if (*n == '\0')
1557               return (FNM_NOMATCH);
1558
1559             if ((flags & FNM_PERIOD) && *n == '.' &&
1560                 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1561               return (FNM_NOMATCH);
1562
1563             /* Make sure there is a closing `]'.  If there isn't,
1564                the `[' is just a character to be matched.  */
1565             {
1566               register const char *np;
1567
1568               for (np = p; np && *np && *np != ']'; np++);
1569
1570               if (np && !*np)
1571                 {
1572                   if (*n != '[')
1573                     return (FNM_NOMATCH);
1574                   goto next_char;
1575                 }
1576             }
1577
1578             not = (*p == '!' || *p == '^');
1579             if (not)
1580               ++p;
1581
1582             c = *p++;
1583             while (1)
1584               {
1585                 register char cstart = c, cend = c;
1586
1587                 if (!(flags & FNM_NOESCAPE) && c == '\\')
1588                   cstart = cend = *p++;
1589
1590                 if (c == '\0')
1591                   /* [ (unterminated) loses.  */
1592                   return (FNM_NOMATCH);
1593
1594                 c = *p++;
1595
1596                 if ((flags & FNM_PATHNAME) && c == '/')
1597                   /* [/] can never match.  */
1598                   return (FNM_NOMATCH);
1599
1600                 if (c == '-' && *p != ']')
1601                   {
1602                     cend = *p++;
1603                     if (!(flags & FNM_NOESCAPE) && cend == '\\')
1604                       cend = *p++;
1605                     if (cend == '\0')
1606                       return (FNM_NOMATCH);
1607                     c = *p++;
1608                   }
1609
1610                 if (*n >= cstart && *n <= cend)
1611                   goto matched;
1612
1613                 if (c == ']')
1614                   break;
1615               }
1616             if (!not)
1617               return (FNM_NOMATCH);
1618
1619           next_char:
1620             break;
1621
1622           matched:
1623             /* Skip the rest of the [...] that already matched.  */
1624             while (c != ']')
1625               {
1626                 if (c == '\0')
1627                   /* [... (unterminated) loses.  */
1628                   return (FNM_NOMATCH);
1629
1630                 c = *p++;
1631                 if (!(flags & FNM_NOESCAPE) && c == '\\')
1632                   /* 1003.2d11 is unclear if this is right.  %%% */
1633                   ++p;
1634               }
1635             if (not)
1636               return (FNM_NOMATCH);
1637           }
1638           break;
1639
1640         default:
1641           if (c != *n)
1642             return (FNM_NOMATCH);
1643         }
1644
1645       ++n;
1646     }
1647
1648   if (*n == '\0')
1649     return (0);
1650
1651   return (FNM_NOMATCH);
1652 }
1653
1654 #endif /* not SYSTEM_FNMATCH */