NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lib/50009: strptime small enhancement
The following reply was made to PR lib/50009; it has been noted by GNATS.
From: David CARLIER <devnexen%gmail.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: lib/50009: strptime small enhancement
Date: Mon, 29 Jun 2015 06:13:44 +0100
--Apple-Mail=_75D17FF7-C2FC-496A-BE65-549EA05291B1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=us-ascii
Ok new corrected patch, thanks for your answers.
Index: time/strptime.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/lib/libc/time/strptime.c,v
retrieving revision 1.39
diff -u -r1.39 strptime.c
--- time/strptime.c 6 Apr 2015 14:38:22 -0000 1.39
+++ time/strptime.c 29 Jun 2015 05:06:25 -0000
@@ -36,6 +36,8 @@
#include "namespace.h"
#include <sys/localedef.h>
+#include <sys/types.h>
+#include <sys/clock.h>
#include <ctype.h>
#include <locale.h>
#include <string.h>
@@ -60,6 +62,12 @@
#define ALT_O 0x02
#define LEGAL_ALT(x) { if (alt_format & ~(x)) return =
NULL; }
+#define FLAG_YEAR (1 << 0)
+#define FLAG_MTH (1 << 1)
+#define FLAG_YDAY (1 << 2)
+#define FLAG_MDAY (1 << 3)
+#define FLAG_WDAY (1 << 4)
+
static char gmt[] =3D { "GMT" };
static char utc[] =3D { "UTC" };
/* RFC-822/RFC-2822 */
@@ -74,6 +82,15 @@
static const u_char *find_string(const u_char *, int *, const char * =
const *,
const char * const *, int);
+static const int mths_per_yr_kind[2][12] =3D {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int mths_code[12] =3D {
+ 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5
+};
+
char *
strptime(const char *buf, const char *fmt, struct tm *tm)
{
@@ -85,7 +102,7 @@
{
unsigned char c;
const unsigned char *bp, *ep;
- int alt_format, i, split_year =3D 0, neg =3D 0, offs;
+ int alt_format, i, split_year =3D 0, neg =3D 0, flags =3D 0, =
offs;
const char *new_fmt;
bp =3D (const u_char *)buf;
@@ -180,6 +197,7 @@
bp =3D find_string(bp, &tm->tm_wday,
_TIME_LOCALE(loc)->day, =
_TIME_LOCALE(loc)->abday, 7);
LEGAL_ALT(0);
+ flags |=3D FLAG_WDAY;
continue;
case 'B': /* The month, using the locale's form. =
*/
@@ -207,6 +225,7 @@
case 'e':
bp =3D conv_num(bp, &tm->tm_mday, 1, 31);
LEGAL_ALT(ALT_O);
+ flags |=3D FLAG_MDAY;
continue;
case 'k': /* The hour (24-hour clock =
representation). */
@@ -232,6 +251,7 @@
bp =3D conv_num(bp, &i, 1, 366);
tm->tm_yday =3D i - 1;
LEGAL_ALT(0);
+ flags |=3D FLAG_YDAY;
continue;
case 'M': /* The minute. */
@@ -244,6 +264,7 @@
bp =3D conv_num(bp, &i, 1, 12);
tm->tm_mon =3D i - 1;
LEGAL_ALT(ALT_O);
+ flags |=3D FLAG_MTH;
continue;
case 'p': /* The locale's equivalent of AM/PM. */
@@ -305,12 +326,14 @@
case 'w': /* The day of week, beginning on sunday. =
*/
bp =3D conv_num(bp, &tm->tm_wday, 0, 6);
LEGAL_ALT(ALT_O);
+ flags |=3D FLAG_WDAY;
continue;
case 'u': /* The day of week, monday =3D 1. */
bp =3D conv_num(bp, &i, 1, 7);
tm->tm_wday =3D i % 7;
LEGAL_ALT(ALT_O);
+ flags |=3D FLAG_WDAY;
continue;
case 'g': /* The year corresponding to the ISO =
week
@@ -336,6 +359,7 @@
bp =3D conv_num(bp, &i, 0, 9999);
tm->tm_year =3D i - TM_YEAR_BASE;
LEGAL_ALT(ALT_E);
+ flags |=3D FLAG_YEAR;
continue;
case 'y': /* The year within 100 years of the =
epoch. */
@@ -529,6 +553,57 @@
}
}
+ /**
+ * Post processing of potential additional flags
+ */
+ if (flags & FLAG_YEAR) {
+ int yr =3D 1900 + tm->tm_year;
+ const int *mths_yr =3D =
mths_per_yr_kind[is_leap_year(yr)];
+ if (!(flags & FLAG_YDAY)) {
+ if (flags & FLAG_MTH && flags & FLAG_MDAY) {
+ tm->tm_yday =3D tm->tm_mday - 1;
+ i =3D 0;
+ while (i < tm->tm_mon) {
+ tm->tm_yday +=3D mths_yr[i];
+ i ++;
+ }
+
+ flags |=3D FLAG_YDAY;
+ }
+ }
+ if (flags & FLAG_YDAY) {
+ int d =3D tm->tm_yday;
+ if (!(flags & FLAG_MTH)) {
+ tm->tm_mon =3D 0;
+ i =3D 0;
+ while (i < 12) {
+ d -=3D mths_yr[i++];
+ if (d <=3D mths_yr[i])
+ break;
+ }
+
+ tm->tm_mon =3D i;
+ }
+ if (!(flags & FLAG_MDAY))
+ tm->tm_mday =3D d + 1;
+ if (!(flags & FLAG_WDAY)) {
+ static const int centuries[4] =3D {
+ 6, 4, 2, 0
+ };
+ int byear =3D ((int) yr & ~1) / 100;
+ int century =3D centuries[byear % 4];
+ int wday =3D 0;
+
+ wday =3D mths_code[tm->tm_mon] + =
tm->tm_mday;
+ if (is_leap_year(yr) || tm->tm_mon < 2)
+ wday --;
+ wday =3D (wday + tm->tm_year + =
(tm->tm_year / 4) + century) % 7;
+
+ tm->tm_wday =3D wday > 4 ? 0 : wday;
+ }
+ }
+ }
+
return __UNCONST(bp);
}
> On 29 Jun 2015, at 05:45, matthew green <mrg%eterna.com.au@localhost> wrote:
>=20
> The following reply was made to PR lib/50009; it has been noted by =
GNATS.
>=20
> From: matthew green <mrg%eterna.com.au@localhost>
> To: gnats-bugs%NetBSD.org@localhost
> Cc: lib-bug-people%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
> netbsd-bugs%netbsd.org@localhost, devnexen%gmail.com@localhost
> Subject: re: lib/50009: strptime small enhancement
> Date: Mon, 29 Jun 2015 14:42:18 +1000
>=20
>> On Sun, Jun 28, 2015 at 07:50:00PM +0000, devnexen%gmail.com@localhost wrote:
>>> +#ifndef ISLEAPYEAR
>>> +#define ISLEAPYEAR(y) ((y % 400) =3D=3D 0 && (y % 4) =3D=3D 0 && (y =
% 100) !=3D 0)
>>> +#endif
>>=20
>> ...this is wrong...
>=20
> indeed, sys/clock.h has this:
>=20
> 63 /*
> 64 * This inline avoids some unnecessary modulo operations
> 65 * as compared with the usual macro:
> 66 * ( ((year % 4) =3D=3D 0 &&
> 67 * (year % 100) !=3D 0) ||
> 68 * ((year % 400) =3D=3D 0) )
> 69 * It is otherwise equivalent.
> 70 */
> 71 static inline int
> 72 is_leap_year(uint64_t year)
> 73 {
> 74 if ((year & 3) !=3D 0)
> 75 return 0;
> 76
> 77 if (__predict_false((year % 100) !=3D 0))
> 78 return 1;
> 79
> 80 return __predict_false((year % 400) =3D=3D 0);
> 81 }
>=20
> which should probably be used instead, for netbsd, or at
> least the same expression in the comment.
>=20
> (the macro above also doesn't work properly for various
> inputs, like a good macro should.)
>=20
>=20
> .mrg.
>=20
--Apple-Mail=_75D17FF7-C2FC-496A-BE65-549EA05291B1
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - https://gpgtools.org
iQEcBAEBCgAGBQJVkNQPAAoJECNxxoUnxrf4rJMIANfjh8J2YJFDpXWWoADaE5Pj
UmmiDhzDOLNYMeM3MsGVhAdCBZgUaIwOREc14nfMzgiCugS/s/xMH2v+BgBCdbQy
Q99OGod5LnYCFD0iYOy7T8fzJ6Lvey0PS9xay3/gr64WC9QMdTSlGx4wAFlijR4F
qIooJqpXEIgf83b5h7fXiGlAQ/FbVHNhS+y9n4z+DBRM02PDfeol2iXxmNwCFlap
VjM7CQZ2lbeg0KXcDU4tOWWkWGx7WBCctojn+tCjfb/0s6Xnceyz6bAgvco/yW6z
s6Rj7QZ9miivD14gx1UdWI2kgvnzfM5xS2m7xPolGC5ZIgt7ZHiVJtN9Dg9NUuo=
=KO//
-----END PGP SIGNATURE-----
--Apple-Mail=_75D17FF7-C2FC-496A-BE65-549EA05291B1--
Home |
Main Index |
Thread Index |
Old Index