--- /dev/null
+Return-Path: <jani@nikula.org>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 0253A431FAF\r
+ for <notmuch@notmuchmail.org>; Sun, 4 Nov 2012 02:21:04 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.699\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.699 tagged_above=-999 required=5\r
+ tests=[HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id pmrY5ULl70g2 for <notmuch@notmuchmail.org>;\r
+ Sun, 4 Nov 2012 02:21:03 -0800 (PST)\r
+Received: from mail-oa0-f53.google.com (mail-oa0-f53.google.com\r
+ [209.85.219.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id 046CD431FAE\r
+ for <notmuch@notmuchmail.org>; Sun, 4 Nov 2012 02:21:02 -0800 (PST)\r
+Received: by mail-oa0-f53.google.com with SMTP id j6so5171694oag.26\r
+ for <notmuch@notmuchmail.org>; Sun, 04 Nov 2012 02:21:02 -0800 (PST)\r
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
+ d=google.com; s=20120113;\r
+ h=mime-version:in-reply-to:references:date:message-id:subject:from:to\r
+ :cc:content-type:x-gm-message-state;\r
+ bh=zXSpgS3DMSzKlCOsj6qCbUDqK64q4wfMITJmEamc3zU=;\r
+ b=epCEiDFpj5uOPRlHcg3XUPubgEI8yDb0b9jNpF3mBg6LNowsC5sPB2Wwaouwrw7Y8w\r
+ lEjlm4N+Aic3G2zYkBCYtlVXreNQXT59jr7JJeBEGQoSib4DfcTLN+TPLi72e8ybx3/O\r
+ XcEEjI8pntMCCFmS3E5ZYH9NIQJ/vOugAEas8Tof6cCwoQEN5aD4iz5UDpUcArL7pNJD\r
+ EuXb8TOmKkB3acEM/N+U9WJkwiSaDPryMRZe7Mt6aq94YdTZMRNOCiJR96P7W2N+RMgD\r
+ gbkZfNsXiQ0WKfBi/XNFmyPmKGjRxuKlcmgBiSzJyQZzhiwoRciGgSRp7g9Yo1pkwIMT\r
+ Dc7A==\r
+MIME-Version: 1.0\r
+Received: by 10.60.19.168 with SMTP id g8mr5235227oee.101.1352024461364; Sun,\r
+ 04 Nov 2012 02:21:01 -0800 (PST)\r
+Received: by 10.76.69.138 with HTTP; Sun, 4 Nov 2012 02:21:01 -0800 (PST)\r
+Received: by 10.76.69.138 with HTTP; Sun, 4 Nov 2012 02:21:01 -0800 (PST)\r
+In-Reply-To: <1351998962-25135-11-git-send-email-blakej@foo.net>\r
+References: <1351998962-25135-1-git-send-email-blakej@foo.net>\r
+ <1351998962-25135-11-git-send-email-blakej@foo.net>\r
+Date: Sun, 4 Nov 2012 12:21:01 +0200\r
+Message-ID:\r
+ <CAB+hUn-HBMnbrxQtn4E1RkKJa-wUEvm2HbdvtDxJGrv3jmtQdw@mail.gmail.com>\r
+Subject: Re: [PATCH 10/10] timegm: add portable implementation (Solaris\r
+ support)\r
+From: Jani Nikula <jani@nikula.org>\r
+To: Blake Jones <blakej@foo.net>\r
+Content-Type: multipart/alternative; boundary=e89a8fb2062cbf4fcf04cda8b931\r
+X-Gm-Message-State:\r
+ ALoCoQn8vvIW7D7MKT4K4oUEILFZhdWQoLdHoC0rzjt/+cpov8pWrU3mjywLJxzGQbVepmLRh9xd\r
+Cc: notmuch@notmuchmail.org\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 04 Nov 2012 10:21:04 -0000\r
+\r
+--e89a8fb2062cbf4fcf04cda8b931\r
+Content-Type: text/plain; charset=UTF-8\r
+\r
+On Nov 4, 2012 11:30 AM, "Blake Jones" <blakej@foo.net> wrote:\r
+>\r
+> The timegm(3) function is a non-standard extension to libc which is\r
+> available in GNU libc and on some BSDs. Although SunOS had this\r
+> function in its libc, Solaris (unfortunately) removed it. This patch\r
+> implements a very simple version of timegm() which is good enough for\r
+> parse-time-string.c.\r
+>\r
+> Although notmuch's idiom for portability is to test for native\r
+> availability and put alternate versions in compat/, that approach led to\r
+> a compilation problem in this case. libnotmuch.a includes a call to\r
+> parse_time_string() from parse-time-vrp.o, and parse_time_string() in\r
+> libparse-time-string.a needs to call timegm(). An attempt to create\r
+> compat/timegm.c caused the link to fail, because libparse-time-string.a\r
+> acquired a dependency on the new timegm.o in libnotmuch.a, and the\r
+> linker only does a single pass on each ".a" looking for dependencies.\r
+> This seems to be the case both for the GNU linker and the Solaris\r
+> linker. A different possible workaround would have been to include\r
+> libnotmuch.a multiple times on the link line, but that seemed like a\r
+> brittle way to track this dependency.\r
+\r
+I'd prefer to use timegm() where available, and the suggested alternative\r
+[1] elsewhere. I'll look into the compat build issues when I have a moment.\r
+\r
+Jani.\r
+\r
+[1] http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html\r
+\r
+> ---\r
+> parse-time-string/parse-time-string.c | 37\r
+++++++++++++++++++++++++++++++++-\r
+> 1 file changed, 36 insertions(+), 1 deletion(-)\r
+>\r
+> diff --git a/parse-time-string/parse-time-string.c\r
+b/parse-time-string/parse-time-string.c\r
+> index 584067d..28901af 100644\r
+> --- a/parse-time-string/parse-time-string.c\r
+> +++ b/parse-time-string/parse-time-string.c\r
+> @@ -1315,6 +1315,41 @@ fixup_ampm (struct state *state)\r
+> return 0;\r
+> }\r
+>\r
+> +static int\r
+> +leapyear (int year)\r
+> +{\r
+> + return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));\r
+> +}\r
+> +\r
+> +/*\r
+> + * This is a simple implementation of timegm() which does what is needed\r
+> + * by create_output() -- just turns the "struct tm" into a GMT time_t.\r
+> + * It does not normalize any of the fields of the "struct tm", nor does\r
+> + * it set tm_wday or tm_yday.\r
+> + */\r
+> +static time_t\r
+> +local_timegm (struct tm *tm)\r
+> +{\r
+> + int monthlen[2][12] = {\r
+> + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },\r
+> + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },\r
+> + };\r
+> + int year, month, days;\r
+> +\r
+> + days = 365 * (tm->tm_year - 70);\r
+> + for (year = 70; year < tm->tm_year; year++) {\r
+> + if (leapyear(1900 + year)) {\r
+> + days++;\r
+> + }\r
+> + }\r
+> + for (month = 0; month < tm->tm_mon; month++) {\r
+> + days += monthlen[leapyear(1900 + year)][month];\r
+> + }\r
+> + days += tm->tm_mday - 1;\r
+> +\r
+> + return ((((days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 +\r
+tm->tm_sec);\r
+> +}\r
+> +\r
+> /* Combine absolute and relative fields, and round. */\r
+> static int\r
+> create_output (struct state *state, time_t *t_out, const time_t *ref,\r
+> @@ -1465,7 +1500,7 @@ create_output (struct state *state, time_t *t_out,\r
+const time_t *ref,\r
+> if (is_field_set (state, TM_TZ)) {\r
+> /* tm is in specified TZ, convert to UTC for timegm(3). */\r
+> tm.tm_min -= get_field (state, TM_TZ);\r
+> - t = timegm (&tm);\r
+> + t = local_timegm (&tm);\r
+> } else {\r
+> /* tm is in local time. */\r
+> t = mktime (&tm);\r
+> --\r
+> 1.7.9.2\r
+>\r
+> _______________________________________________\r
+> notmuch mailing list\r
+> notmuch@notmuchmail.org\r
+> http://notmuchmail.org/mailman/listinfo/notmuch\r
+\r
+--e89a8fb2062cbf4fcf04cda8b931\r
+Content-Type: text/html; charset=UTF-8\r
+Content-Transfer-Encoding: quoted-printable\r
+\r
+<p><br>\r
+On Nov 4, 2012 11:30 AM, "Blake Jones" <<a href=3D"mailto:blak=\r
+ej@foo.net">blakej@foo.net</a>> wrote:<br>\r
+><br>\r
+> The timegm(3) function is a non-standard extension to libc which is<br=\r
+>\r
+> available in GNU libc and on some BSDs. =C2=A0Although SunOS had this<=\r
+br>\r
+> function in its libc, Solaris (unfortunately) removed it. =C2=A0This p=\r
+atch<br>\r
+> implements a very simple version of timegm() which is good enough for<=\r
+br>\r
+> parse-time-string.c.<br>\r
+><br>\r
+> Although notmuch's idiom for portability is to test for native<br>\r
+> availability and put alternate versions in compat/, that approach led =\r
+to<br>\r
+> a compilation problem in this case. =C2=A0libnotmuch.a includes a call=\r
+ to<br>\r
+> parse_time_string() from parse-time-vrp.o, and parse_time_string() in<=\r
+br>\r
+> libparse-time-string.a needs to call timegm(). =C2=A0An attempt to cre=\r
+ate<br>\r
+> compat/timegm.c caused the link to fail, because libparse-time-string.=\r
+a<br>\r
+> acquired a dependency on the new timegm.o in libnotmuch.a, and the<br>\r
+> linker only does a single pass on each ".a" looking for depe=\r
+ndencies.<br>\r
+> This seems to be the case both for the GNU linker and the Solaris<br>\r
+> linker. =C2=A0A different possible workaround would have been to inclu=\r
+de<br>\r
+> libnotmuch.a multiple times on the link line, but that seemed like a<b=\r
+r>\r
+> brittle way to track this dependency.</p>\r
+<p>I'd prefer to use timegm() where available, and the suggested altern=\r
+ative [1] elsewhere. I'll look into the compat build issues when I have=\r
+ a moment.</p>\r
+<p>Jani.</p>\r
+<p>[1] <a href=3D"http://www.kernel.org/doc/man-pages/online/pages/man3/tim=\r
+egm.3.html">http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.=\r
+html</a><br></p>\r
+<p>> ---<br>\r
+> =C2=A0parse-time-string/parse-time-string.c | =C2=A0 37 ++++++++++++++=\r
+++++++++++++++++++-<br>\r
+> =C2=A01 file changed, 36 insertions(+), 1 deletion(-)<br>\r
+><br>\r
+> diff --git a/parse-time-string/parse-time-string.c b/parse-time-string=\r
+/parse-time-string.c<br>\r
+> index 584067d..28901af 100644<br>\r
+> --- a/parse-time-string/parse-time-string.c<br>\r
+> +++ b/parse-time-string/parse-time-string.c<br>\r
+> @@ -1315,6 +1315,41 @@ fixup_ampm (struct state *state)<br>\r
+> =C2=A0 =C2=A0 =C2=A0return 0;<br>\r
+> =C2=A0}<br>\r
+><br>\r
+> +static int<br>\r
+> +leapyear (int year)<br>\r
+> +{<br>\r
+> + =C2=A0 =C2=A0return ((year % 4) =3D=3D 0 && ((year % 100) !=\r
+=3D 0 || (year % 400) =3D=3D 0));<br>\r
+> +}<br>\r
+> +<br>\r
+> +/*<br>\r
+> + * This is a simple implementation of timegm() which does what is nee=\r
+ded<br>\r
+> + * by create_output() -- just turns the "struct tm" into a =\r
+GMT time_t.<br>\r
+> + * It does not normalize any of the fields of the "struct tm&quo=\r
+t;, nor does<br>\r
+> + * it set tm_wday or tm_yday.<br>\r
+> + */<br>\r
+> +static time_t<br>\r
+> +local_timegm (struct tm *tm)<br>\r
+> +{<br>\r
+> + =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=A0 =C2=A0monthlen[2][12] =3D {<br=\r
+>\r
+> + =C2=A0 =C2=A0 =C2=A0 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 3=\r
+1 },<br>\r
+> + =C2=A0 =C2=A0 =C2=A0 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 3=\r
+1 },<br>\r
+> + =C2=A0 =C2=A0};<br>\r
+> + =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=A0 =C2=A0year, month, days;<br>\r
+> +<br>\r
+> + =C2=A0 =C2=A0days =3D 365 * (tm->tm_year - 70);<br>\r
+> + =C2=A0 =C2=A0for (year =3D 70; year < tm->tm_year; year++) {<b=\r
+r>\r
+> + =C2=A0 =C2=A0 =C2=A0 if (leapyear(1900 + year)) {<br>\r
+> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 days++;<br>\r
+> + =C2=A0 =C2=A0 =C2=A0 }<br>\r
+> + =C2=A0 =C2=A0}<br>\r
+> + =C2=A0 =C2=A0for (month =3D 0; month < tm->tm_mon; month++) {<=\r
+br>\r
+> + =C2=A0 =C2=A0 =C2=A0 days +=3D monthlen[leapyear(1900 + year)][month=\r
+];<br>\r
+> + =C2=A0 =C2=A0}<br>\r
+> + =C2=A0 =C2=A0days +=3D tm->tm_mday - 1;<br>\r
+> +<br>\r
+> + =C2=A0 =C2=A0return ((((days * 24) + tm->tm_hour) * 60 + tm->t=\r
+m_min) * 60 + tm->tm_sec);<br>\r
+> +}<br>\r
+> +<br>\r
+> =C2=A0/* Combine absolute and relative fields, and round. */<br>\r
+> =C2=A0static int<br>\r
+> =C2=A0create_output (struct state *state, time_t *t_out, const time_t =\r
+*ref,<br>\r
+> @@ -1465,7 +1500,7 @@ create_output (struct state *state, time_t *t_ou=\r
+t, const time_t *ref,<br>\r
+> =C2=A0 =C2=A0 =C2=A0if (is_field_set (state, TM_TZ)) {<br>\r
+> =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* tm is in specified TZ, convert to UTC f=\r
+or timegm(3). */<br>\r
+> =C2=A0 =C2=A0 =C2=A0 =C2=A0 tm.tm_min -=3D get_field (state, TM_TZ);<b=\r
+r>\r
+> - =C2=A0 =C2=A0 =C2=A0 t =3D timegm (&tm);<br>\r
+> + =C2=A0 =C2=A0 =C2=A0 t =3D local_timegm (&tm);<br>\r
+> =C2=A0 =C2=A0 =C2=A0} else {<br>\r
+> =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* tm is in local time. */<br>\r
+> =C2=A0 =C2=A0 =C2=A0 =C2=A0 t =3D mktime (&tm);<br>\r
+> --<br>\r
+> 1.7.9.2<br>\r
+><br>\r
+> _______________________________________________<br>\r
+> notmuch mailing list<br>\r
+> <a href=3D"mailto:notmuch@notmuchmail.org">notmuch@notmuchmail.org</a>=\r
+<br>\r
+> <a href=3D"http://notmuchmail.org/mailman/listinfo/notmuch">http://not=\r
+muchmail.org/mailman/listinfo/notmuch</a><br>\r
+</p>\r
+\r
+--e89a8fb2062cbf4fcf04cda8b931--\r