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