📄 cmpt.c
字号:
#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 + -