Beispiel #1
0
static int
pg_wc_isupper(pg_wchar c)
{
	switch (pg_regex_strategy)
	{
		case PG_REGEX_LOCALE_C:
			return (c <= (pg_wchar) 127 &&
					(pg_char_properties[c] & PG_ISUPPER));
		case PG_REGEX_LOCALE_WIDE:
#ifdef USE_WIDE_UPPER_LOWER
			if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
				return iswupper((wint_t) c);
#endif
			/* FALL THRU */
		case PG_REGEX_LOCALE_1BYTE:
			return (c <= (pg_wchar) UCHAR_MAX &&
					isupper((unsigned char) c));
		case PG_REGEX_LOCALE_WIDE_L:
#if defined(HAVE_LOCALE_T) && defined(USE_WIDE_UPPER_LOWER)
			if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
				return iswupper_l((wint_t) c, pg_regex_locale);
#endif
			/* FALL THRU */
		case PG_REGEX_LOCALE_1BYTE_L:
#ifdef HAVE_LOCALE_T
			return (c <= (pg_wchar) UCHAR_MAX &&
					isupper_l((unsigned char) c, pg_regex_locale));
#endif
			break;
	}
	return 0;					/* can't get here, but keep compiler quiet */
}
Beispiel #2
0
static char *
_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
          locale_t locale)
{
    char	c;
    const char *ptr;
    int	day_offset = -1, wday_offset;
    int week_offset;
    int	i, len;
    int flags;
    int Ealternative, Oalternative;
    const struct lc_time_T *tptr = __get_current_time_locale(locale);
    static int start_of_month[2][13] = {
        {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
        {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
    };

    flags = FLAG_NONE;

    ptr = fmt;
    while (*ptr != 0) {
        c = *ptr++;

        if (c != '%') {
            if (isspace_l((unsigned char)c, locale))
                while (*buf != 0 &&
                        isspace_l((unsigned char)*buf, locale))
                    buf++;
            else if (c != *buf++)
                return (NULL);
            continue;
        }

        Ealternative = 0;
        Oalternative = 0;
label:
        c = *ptr++;
        switch (c) {
        case '%':
            if (*buf++ != '%')
                return (NULL);
            break;

        case '+':
            buf = _strptime(buf, tptr->date_fmt, tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR;
            break;

        case 'C':
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            /* XXX This will break for 3-digit centuries. */
            len = 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (i < 19)
                return (NULL);

            tm->tm_year = i * 100 - TM_YEAR_BASE;
            flags |= FLAG_YEAR;

            break;

        case 'c':
            buf = _strptime(buf, tptr->c_fmt, tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR;
            break;

        case 'D':
            buf = _strptime(buf, "%m/%d/%y", tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR;
            break;

        case 'E':
            if (Ealternative || Oalternative)
                break;
            Ealternative++;
            goto label;

        case 'O':
            if (Ealternative || Oalternative)
                break;
            Oalternative++;
            goto label;

        case 'F':
            buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR;
            break;

        case 'R':
            buf = _strptime(buf, "%H:%M", tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            break;

        case 'r':
            buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            break;

        case 'T':
            buf = _strptime(buf, "%H:%M:%S", tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            break;

        case 'X':
            buf = _strptime(buf, tptr->X_fmt, tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            break;

        case 'x':
            buf = _strptime(buf, tptr->x_fmt, tm, GMTp, locale);
            if (buf == NULL)
                return (NULL);
            flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR;
            break;

        case 'j':
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = 3;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (i < 1 || i > 366)
                return (NULL);

            tm->tm_yday = i - 1;
            flags |= FLAG_YDAY;

            break;

        case 'M':
        case 'S':
            if (*buf == 0 ||
                    isspace_l((unsigned char)*buf, locale))
                break;

            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }

            if (c == 'M') {
                if (i > 59)
                    return (NULL);
                tm->tm_min = i;
            } else {
                if (i > 60)
                    return (NULL);
                tm->tm_sec = i;
            }

            break;

        case 'H':
        case 'I':
        case 'k':
        case 'l':
            /*
             * Of these, %l is the only specifier explicitly
             * documented as not being zero-padded.  However,
             * there is no harm in allowing zero-padding.
             *
             * XXX The %l specifier may gobble one too many
             * digits if used incorrectly.
             */
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (c == 'H' || c == 'k') {
                if (i > 23)
                    return (NULL);
            } else if (i > 12)
                return (NULL);

            tm->tm_hour = i;

            break;

        case 'p':
            /*
             * XXX This is bogus if parsed before hour-related
             * specifiers.
             */
            len = strlen(tptr->am);
            if (strncasecmp_l(buf, tptr->am, len, locale) == 0) {
                if (tm->tm_hour > 12)
                    return (NULL);
                if (tm->tm_hour == 12)
                    tm->tm_hour = 0;
                buf += len;
                break;
            }

            len = strlen(tptr->pm);
            if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) {
                if (tm->tm_hour > 12)
                    return (NULL);
                if (tm->tm_hour != 12)
                    tm->tm_hour += 12;
                buf += len;
                break;
            }

            return (NULL);

        case 'A':
        case 'a':
            for (i = 0; i < asizeof(tptr->weekday); i++) {
                len = strlen(tptr->weekday[i]);
                if (strncasecmp_l(buf, tptr->weekday[i],
                                  len, locale) == 0)
                    break;
                len = strlen(tptr->wday[i]);
                if (strncasecmp_l(buf, tptr->wday[i],
                                  len, locale) == 0)
                    break;
            }
            if (i == asizeof(tptr->weekday))
                return (NULL);

            buf += len;
            tm->tm_wday = i;
            flags |= FLAG_WDAY;
            break;

        case 'U':
        case 'W':
            /*
             * XXX This is bogus, as we can not assume any valid
             * information present in the tm structure at this
             * point to calculate a real value, so just check the
             * range for now.
             */
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (i > 53)
                return (NULL);

            if (c == 'U')
                day_offset = TM_SUNDAY;
            else
                day_offset = TM_MONDAY;


            week_offset = i;

            break;

        case 'w':
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            i = *buf - '0';
            buf++;
            if (i > 6)
                return (NULL);

            tm->tm_wday = i;
            flags |= FLAG_WDAY;

            break;

        case 'e':
            /*
             * With %e format, our strftime(3) adds a blank space
             * before single digits.
             */
            if (*buf != 0 &&
                    isspace_l((unsigned char)*buf, locale))
                buf++;
        /* FALLTHROUGH */
        case 'd':
            /*
             * The %e specifier was once explicitly documented as
             * not being zero-padded but was later changed to
             * equivalent to %d.  There is no harm in allowing
             * such padding.
             *
             * XXX The %e specifier may gobble one too many
             * digits if used incorrectly.
             */
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (i > 31)
                return (NULL);

            tm->tm_mday = i;
            flags |= FLAG_MDAY;

            break;

        case 'B':
        case 'b':
        case 'h':
            for (i = 0; i < asizeof(tptr->month); i++) {
                if (Oalternative) {
                    if (c == 'B') {
                        len = strlen(tptr->alt_month[i]);
                        if (strncasecmp_l(buf,
                                          tptr->alt_month[i],
                                          len, locale) == 0)
                            break;
                    }
                } else {
                    len = strlen(tptr->month[i]);
                    if (strncasecmp_l(buf, tptr->month[i],
                                      len, locale) == 0)
                        break;
                }
            }
            /*
             * Try the abbreviated month name if the full name
             * wasn't found and Oalternative was not requested.
             */
            if (i == asizeof(tptr->month) && !Oalternative) {
                for (i = 0; i < asizeof(tptr->month); i++) {
                    len = strlen(tptr->mon[i]);
                    if (strncasecmp_l(buf, tptr->mon[i],
                                      len, locale) == 0)
                        break;
                }
            }
            if (i == asizeof(tptr->month))
                return (NULL);

            tm->tm_mon = i;
            buf += len;
            flags |= FLAG_MONTH;

            break;

        case 'm':
            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (i < 1 || i > 12)
                return (NULL);

            tm->tm_mon = i - 1;
            flags |= FLAG_MONTH;

            break;

        case 's':
        {
            char *cp;
            int sverrno;
            long n;
            time_t t;

            sverrno = errno;
            errno = 0;
            n = strtol_l(buf, &cp, 10, locale);
            if (errno == ERANGE || (long)(t = n) != n) {
                errno = sverrno;
                return (NULL);
            }
            errno = sverrno;
            buf = cp;
            if (gmtime_r(&t, tm) == NULL)
                return (NULL);
            *GMTp = 1;
            flags |= FLAG_YDAY | FLAG_WDAY | FLAG_MONTH |
                     FLAG_MDAY | FLAG_YEAR;
        }
        break;

        case 'Y':
        case 'y':
            if (*buf == 0 ||
                    isspace_l((unsigned char)*buf, locale))
                break;

            if (!isdigit_l((unsigned char)*buf, locale))
                return (NULL);

            len = (c == 'Y') ? 4 : 2;
            for (i = 0; len && *buf != 0 &&
                    isdigit_l((unsigned char)*buf, locale); buf++) {
                i *= 10;
                i += *buf - '0';
                len--;
            }
            if (c == 'Y')
                i -= TM_YEAR_BASE;
            if (c == 'y' && i < 69)
                i += 100;
            if (i < 0)
                return (NULL);

            tm->tm_year = i;
            flags |= FLAG_YEAR;

            break;

        case 'Z':
        {
            const char *cp;
            char *zonestr;

            for (cp = buf; *cp &&
                    isupper_l((unsigned char)*cp, locale); ++cp) {
                /*empty*/
            }
            if (cp - buf) {
                zonestr = alloca(cp - buf + 1);
                strncpy(zonestr, buf, cp - buf);
                zonestr[cp - buf] = '\0';
                tzset();
                if (0 == strcmp(zonestr, "GMT") ||
                        0 == strcmp(zonestr, "UTC")) {
                    *GMTp = 1;
                } else if (0 == strcmp(zonestr, tzname[0])) {
                    tm->tm_isdst = 0;
                } else if (0 == strcmp(zonestr, tzname[1])) {
                    tm->tm_isdst = 1;
                } else {
                    return (NULL);
                }
                buf += cp - buf;
            }
        }
        break;

        case 'z':
        {
            int sign = 1;
            len = 4;			/* RFC 822/ISO 8601 */

            if (*buf != '+') {
                if (*buf == '-')
                    sign = -1;
                else if (*buf == 'Z')	/* ISO 8601 Z (UTC) */
                    len = 0;
                else
                    return (NULL);
            }

            buf++;
            i = 0;
            for (; len > 0; len--) {
                if (isdigit_l((unsigned char)*buf, locale)) {
                    i *= 10;
                    i += *buf - '0';
                    buf++;
                } else if (*buf == ':' && len == 2) {
                    buf++;		/* ISO 8601 +hh:mm */
                    if (isdigit_l((unsigned char)*buf,
                                  locale)) {
                        i *= 10;
                        i += *buf - '0';
                        buf++;
                    } else {
                        return (NULL);
                    }
                } else if (len == 2) {
                    i *= 100;	/* ISO 8601 +hh */
                    break;
                } else {
                    return (NULL);
                }
            }

            tm->tm_hour -= sign * (i / 100);
            tm->tm_min  -= sign * (i % 100);
            *GMTp = 1;
        }
        break;

        case 'n':
        case 't':
            while (isspace_l((unsigned char)*buf, locale))
                buf++;
            break;

        default:
            return (NULL);
        }
    }

    if (!(flags & FLAG_YDAY) && (flags & FLAG_YEAR)) {
        if ((flags & (FLAG_MONTH | FLAG_MDAY)) ==
                (FLAG_MONTH | FLAG_MDAY)) {
            tm->tm_yday = start_of_month[isleap(tm->tm_year +
                                                TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1);
            flags |= FLAG_YDAY;
        } else if (day_offset != -1) {
            /* Set the date to the first Sunday (or Monday)
             * of the specified week of the year.
             */
            if (!(flags & FLAG_WDAY)) {
                tm->tm_wday = day_offset;
                flags |= FLAG_WDAY;
            }
            tm->tm_yday = (7 -
                           first_wday_of(tm->tm_year + TM_YEAR_BASE) +
                           day_offset) % 7 + (week_offset - 1 +
                                              (tm->tm_wday == 0 ? day_offset : 0)) * 7 +
                          tm->tm_wday - day_offset;
            flags |= FLAG_YDAY;
        }
    }

    if ((flags & (FLAG_YEAR | FLAG_YDAY)) == (FLAG_YEAR | FLAG_YDAY)) {
        if (!(flags & FLAG_MONTH)) {
            i = 0;
            while (tm->tm_yday >=
                    start_of_month[isleap(tm->tm_year +
                                          TM_YEAR_BASE)][i])
                i++;
            if (i > 12) {
                i = 1;
                tm->tm_yday -=
                    start_of_month[isleap(tm->tm_year +
                                          TM_YEAR_BASE)][12];
                tm->tm_year++;
            }
            tm->tm_mon = i - 1;
            flags |= FLAG_MONTH;
        }
        if (!(flags & FLAG_MDAY)) {
            tm->tm_mday = tm->tm_yday -
                          start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)]
                          [tm->tm_mon] + 1;
            flags |= FLAG_MDAY;
        }
        if (!(flags & FLAG_WDAY)) {
            i = 0;
            wday_offset = first_wday_of(tm->tm_year);
            while (i++ <= tm->tm_yday) {
                if (wday_offset++ >= 6)
                    wday_offset = 0;
            }
            tm->tm_wday = wday_offset;
            flags |= FLAG_WDAY;
        }
    }

    return ((char *)buf);
}
Beispiel #3
0
int isupper(int c) {
	return isupper_l(c, uselocale((locale_t)0));
}