From owner-svn-src-head@freebsd.org Wed Sep 21 06:44:33 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 65F33BE3B39; Wed, 21 Sep 2016 06:44:33 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 286B7A77; Wed, 21 Sep 2016 06:44:33 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u8L6iWjv013597; Wed, 21 Sep 2016 06:44:32 GMT (envelope-from ache@FreeBSD.org) Received: (from ache@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u8L6iWm6013596; Wed, 21 Sep 2016 06:44:32 GMT (envelope-from ache@FreeBSD.org) Message-Id: <201609210644.u8L6iWm6013596@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ache set sender to ache@FreeBSD.org using -f From: "Andrey A. Chernov" Date: Wed, 21 Sep 2016 06:44:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r306075 - head/lib/libc/stdtime X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Sep 2016 06:44:33 -0000 Author: ache Date: Wed Sep 21 06:44:32 2016 New Revision: 306075 URL: https://svnweb.freebsd.org/changeset/base/306075 Log: 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 Modified: head/lib/libc/stdtime/strptime.c Modified: head/lib/libc/stdtime/strptime.c ============================================================================== --- head/lib/libc/stdtime/strptime.c Wed Sep 21 06:43:52 2016 (r306074) +++ head/lib/libc/stdtime/strptime.c Wed Sep 21 06:44:32 2016 (r306075) @@ -301,10 +301,11 @@ label: * 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 @@ label: 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 @@ label: 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 @@ label: 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; - } - 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; + 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 = tmpyday; flags |= FLAG_YDAY; } }