⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmpt.c

📁 Wget很好的处理了http和ftp的下载,很值得学习的经典代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#define __FNM_FLAGS     (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)/* Match STRING against the filename pattern PATTERN, returning zero   if it matches, FNM_NOMATCH if not.  This implementation comes from   an earlier version of GNU Bash.  (It doesn't make sense to update   it with a newer version because those versions add a lot of   features Wget doesn't use or care about.)  */intfnmatch (const char *pattern, const char *string, int flags){  register const char *p = pattern, *n = string;  register char c;  if ((flags & ~__FNM_FLAGS) != 0)    {      errno = EINVAL;      return (-1);    }  while ((c = *p++) != '\0')    {      switch (c)        {        case '?':          if (*n == '\0')            return (FNM_NOMATCH);          else if ((flags & FNM_PATHNAME) && *n == '/')            return (FNM_NOMATCH);          else if ((flags & FNM_PERIOD) && *n == '.' &&                   (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))            return (FNM_NOMATCH);          break;        case '\\':          if (!(flags & FNM_NOESCAPE))            c = *p++;          if (*n != c)            return (FNM_NOMATCH);          break;        case '*':          if ((flags & FNM_PERIOD) && *n == '.' &&              (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))            return (FNM_NOMATCH);          for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)            if (((flags & FNM_PATHNAME) && *n == '/') ||                (c == '?' && *n == '\0'))              return (FNM_NOMATCH);          if (c == '\0')            return (0);          {            char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;            for (--p; *n != '\0'; ++n)              if ((c == '[' || *n == c1) &&                  fnmatch (p, n, flags & ~FNM_PERIOD) == 0)                return (0);            return (FNM_NOMATCH);          }        case '[':          {            /* Nonzero if the sense of the character class is               inverted.  */            register int not;            if (*n == '\0')              return (FNM_NOMATCH);            if ((flags & FNM_PERIOD) && *n == '.' &&                (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))              return (FNM_NOMATCH);            /* Make sure there is a closing `]'.  If there isn't,               the `[' is just a character to be matched.  */            {              register const char *np;              for (np = p; np && *np && *np != ']'; np++)                ;              if (np && !*np)                {                  if (*n != '[')                    return (FNM_NOMATCH);                  goto next_char;                }            }            not = (*p == '!' || *p == '^');            if (not)              ++p;            c = *p++;            while (1)              {                register char cstart = c, cend = c;                if (!(flags & FNM_NOESCAPE) && c == '\\')                  cstart = cend = *p++;                if (c == '\0')                  /* [ (unterminated) loses.  */                  return (FNM_NOMATCH);                c = *p++;                if ((flags & FNM_PATHNAME) && c == '/')                  /* [/] can never match.  */                  return (FNM_NOMATCH);                if (c == '-' && *p != ']')                  {                    cend = *p++;                    if (!(flags & FNM_NOESCAPE) && cend == '\\')                      cend = *p++;                    if (cend == '\0')                      return (FNM_NOMATCH);                    c = *p++;                  }                if (*n >= cstart && *n <= cend)                  goto matched;                if (c == ']')                  break;              }            if (!not)              return (FNM_NOMATCH);          next_char:            break;          matched:            /* Skip the rest of the [...] that already matched.  */            while (c != ']')              {                if (c == '\0')                  /* [... (unterminated) loses.  */                  return (FNM_NOMATCH);                c = *p++;                if (!(flags & FNM_NOESCAPE) && c == '\\')                  /* 1003.2d11 is unclear if this is right.  %%% */                  ++p;              }            if (not)              return (FNM_NOMATCH);          }          break;        default:          if (c != *n)            return (FNM_NOMATCH);        }      ++n;    }  if (*n == '\0')    return (0);  return (FNM_NOMATCH);}#endif /* not SYSTEM_FNMATCH */#ifndef HAVE_TIMEGM/* timegm is a GNU extension, but lately also available on *BSD   systems and possibly elsewhere. *//* True if YEAR is a leap year. */#define ISLEAP(year)                                            \  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))/* Number of leap years in the range [y1, y2). */#define LEAPYEARS(y1, y2)                                               \  ((y2-1)/4 - (y1-1)/4) - ((y2-1)/100 - (y1-1)/100) + ((y2-1)/400 - (y1-1)/400)/* Inverse of gmtime: converts struct tm to time_t, assuming the data   in tm is UTC rather than local timezone.  This implementation   returns the number of seconds elapsed since midnight 1970-01-01,   converted to time_t.  */time_ttimegm (struct tm *t){  static const unsigned short int month_to_days[][13] = {    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, /* normal */    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }  /* leap */  };  const int year = 1900 + t->tm_year;  unsigned long secs;  /* until 2106-02-07 for 32-bit unsigned long */  int days;  if (year < 1970)    return (time_t) -1;  days = 365 * (year - 1970);  /* Take into account leap years between 1970 and YEAR, not counting     YEAR itself.  */  days += LEAPYEARS (1970, year);  if (t->tm_mon < 0 || t->tm_mon >= 12)    return (time_t) -1;  days += month_to_days[ISLEAP (year)][t->tm_mon];  days += t->tm_mday - 1;  secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec;  return (time_t) secs;}#endif /* HAVE_TIMEGM */#ifdef NEED_STRTOLL/* strtoll is required by C99 and used by Wget only on systems with   LFS.  Unfortunately, some systems have LFS, but no strtoll or   equivalent.  These include HPUX 11.0 and Windows.   We use #ifdef NEED_STRTOLL instead of #ifndef HAVE_STRTOLL because   of the systems which have a suitable replacement (e.g. _strtoi64 on   Windows), on which Wget's str_to_wgint is instructed to use that   instead.  */static inline intchar_value (char c, int base){  int value;  if (c < '0')    return -1;  if ('0' <= c && c <= '9')    value = c - '0';  else if ('a' <= c && c <= 'z')    value = c - 'a' + 10;  else if ('A' <= c && c <= 'Z')    value = c - 'A' + 10;  else    return -1;  if (value >= base)    return -1;  return value;}#define STRTOLL_MAX TYPE_MAXIMUM (strtoll_type)/* This definition assumes two's complement arithmetic */#define STRTOLL_MIN (-STRTOLL_MAX - 1)/* Like a%b, but always returns a positive number when A is negative.   (C doesn't guarantee the sign of the result.)  */#define MOD(a, b) ((strtoll_type) -1 % 2 == 1 ? (a) % (b) : - ((a) % (b)))/* A strtoll-like replacement for systems that have an integral type   larger than long but don't supply strtoll.  This implementation   makes no assumptions about the size of strtoll_type.  */strtoll_typestrtoll (const char *nptr, char **endptr, int base){  strtoll_type result = 0;  bool negative;  if (base != 0 && (base < 2 || base > 36))    {      errno = EINVAL;      return 0;    }  while (*nptr == ' ' || *nptr == '\t')    ++nptr;  if (*nptr == '-')    {      negative = true;      ++nptr;    }  else if (*nptr == '+')    {      negative = false;      ++nptr;    }  else    negative = false;  /* If BASE is 0, determine the real base based on the beginning on     the number; octal numbers begin with "0", hexadecimal with "0x",     and the others are considered octal.  */  if (*nptr == '0')    {      if ((base == 0 || base == 16)          &&          (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))        {          base = 16;          nptr += 2;          /* "0x" must be followed by at least one hex char.  If not,             return 0 and place ENDPTR on 'x'. */          if (!ISXDIGIT (*nptr))            {              --nptr;              goto out;            }        }      else if (base == 0)        base = 8;    }  else if (base == 0)    base = 10;  if (!negative)    {      /* Parse positive number, checking for overflow. */      int digit;      /* Overflow watermark.  If RESULT exceeds it, overflow occurs on         this digit.  If result==WATERMARK, current digit may not         exceed the last digit of maximum value. */      const strtoll_type WATERMARK = STRTOLL_MAX / base;      for (; (digit = char_value (*nptr, base)) != -1; ++nptr)        {          if (result > WATERMARK              || (result == WATERMARK && digit > STRTOLL_MAX % base))            {              result = STRTOLL_MAX;              errno = ERANGE;              break;            }          result = base * result + digit;        }    }  else    {      /* Parse negative number, checking for underflow. */      int digit;      const strtoll_type WATERMARK = STRTOLL_MIN / base;      for (; (digit = char_value (*nptr, base)) != -1; ++nptr)        {          if (result < WATERMARK              || (result == WATERMARK && digit > MOD (STRTOLL_MIN, base)))            {              result = STRTOLL_MIN;              errno = ERANGE;              break;            }          result = base * result - digit;        }    } out:  if (endptr)    *endptr = (char *) nptr;  return result;}#undef STRTOLL_MAX#undef STRTOLL_MIN#undef ABS#endif  /* NEED_STRTOLL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -