1) Microoptimize %p case.

2) Implememt %u for GNU compatibility.
3) Don't forget to advance buf for %w/%u.
4) Fail with incomplete week (week 0) request and no such week in the
year.
5) Fix yday formula when Sunday requested and the week started from Monday.
6) Fail with impossible yday for incomplete week (week 0) and direct %w/%u
request.
7) Shift yday/wday to the first day of the year, if incomplete week
(week 0) requested and no %w/%u used.

MFC after:      7 days
This commit is contained in:
Andrey A. Chernov 2016-09-21 06:44:32 +00:00
parent d1c1d97e6a
commit 62b939ebfb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=306075

View File

@ -301,10 +301,11 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
* XXX This is bogus if parsed before hour-related
* specifiers.
*/
if (tm->tm_hour > 12)
return (NULL);
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;
@ -313,8 +314,6 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
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;
@ -374,15 +373,17 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
break;
case 'u':
case 'w':
if (!isdigit_l((unsigned char)*buf, locale))
return (NULL);
i = *buf - '0';
if (i > 6)
i = *buf++ - '0';
if (i < 0 || i > 7 || (c == 'u' && i < 1) ||
(c == 'w' && i > 6))
return (NULL);
tm->tm_wday = i;
tm->tm_wday = i % 7;
flags |= FLAG_WDAY;
break;
@ -609,17 +610,28 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1);
flags |= FLAG_YDAY;
} else if (day_offset != -1) {
int tmpwday, tmpyday, fwo;
fwo = first_wday_of(tm->tm_year + TM_YEAR_BASE);
/* No incomplete week (week 0). */
if (week_offset == 0 && fwo == day_offset)
return (NULL);
/* 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;
tmpwday = (flags & FLAG_WDAY) ? tm->tm_wday :
day_offset;
tmpyday = (7 - fwo + day_offset) % 7 +
(week_offset - 1) * 7 +
(tmpwday - day_offset + 7) % 7;
/* Impossible yday for incomplete week (week 0). */
if (tmpyday < 0) {
if (flags & FLAG_WDAY)
return (NULL);
tmpyday = 0;
}
tm->tm_yday = (7 -
first_wday_of(tm->tm_year + TM_YEAR_BASE) +
day_offset) % 7 + (week_offset - 1) * 7 +
tm->tm_wday - day_offset;
tm->tm_yday = tmpyday;
flags |= FLAG_YDAY;
}
}