<p><br>
On Nov 4, 2012 11:30 AM, "Blake Jones" <<a href="mailto:blakej@foo.net">blakej@foo.net</a>> wrote:<br>
><br>
> The timegm(3) function is a non-standard extension to libc which is<br>
> available in GNU libc and on some BSDs.  Although SunOS had this<br>
> function in its libc, Solaris (unfortunately) removed it.  This patch<br>
> implements a very simple version of timegm() which is good enough for<br>
> parse-time-string.c.<br>
><br>
> Although notmuch's idiom for portability is to test for native<br>
> availability and put alternate versions in compat/, that approach led to<br>
> a compilation problem in this case.  libnotmuch.a includes a call to<br>
> parse_time_string() from parse-time-vrp.o, and parse_time_string() in<br>
> libparse-time-string.a needs to call timegm().  An attempt to create<br>
> compat/timegm.c caused the link to fail, because libparse-time-string.a<br>
> acquired a dependency on the new timegm.o in libnotmuch.a, and the<br>
> linker only does a single pass on each ".a" looking for dependencies.<br>
> This seems to be the case both for the GNU linker and the Solaris<br>
> linker.  A different possible workaround would have been to include<br>
> libnotmuch.a multiple times on the link line, but that seemed like a<br>
> brittle way to track this dependency.</p>
<p>I'd prefer to use timegm() where available, and the suggested alternative [1] elsewhere. I'll look into the compat build issues when I have a moment.</p>
<p>Jani.</p>
<p>[1] <a href="http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html">http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html</a><br></p>
<p>> ---<br>
>  parse-time-string/parse-time-string.c |   37 ++++++++++++++++++++++++++++++++-<br>
>  1 file changed, 36 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/parse-time-string/parse-time-string.c b/parse-time-string/parse-time-string.c<br>
> index 584067d..28901af 100644<br>
> --- a/parse-time-string/parse-time-string.c<br>
> +++ b/parse-time-string/parse-time-string.c<br>
> @@ -1315,6 +1315,41 @@ fixup_ampm (struct state *state)<br>
>      return 0;<br>
>  }<br>
><br>
> +static int<br>
> +leapyear (int year)<br>
> +{<br>
> +    return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));<br>
> +}<br>
> +<br>
> +/*<br>
> + * This is a simple implementation of timegm() which does what is needed<br>
> + * by create_output() -- just turns the "struct tm" into a GMT time_t.<br>
> + * It does not normalize any of the fields of the "struct tm", nor does<br>
> + * it set tm_wday or tm_yday.<br>
> + */<br>
> +static time_t<br>
> +local_timegm (struct tm *tm)<br>
> +{<br>
> +    int        monthlen[2][12] = {<br>
> +       { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },<br>
> +       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },<br>
> +    };<br>
> +    int        year, month, days;<br>
> +<br>
> +    days = 365 * (tm->tm_year - 70);<br>
> +    for (year = 70; year < tm->tm_year; year++) {<br>
> +       if (leapyear(1900 + year)) {<br>
> +           days++;<br>
> +       }<br>
> +    }<br>
> +    for (month = 0; month < tm->tm_mon; month++) {<br>
> +       days += monthlen[leapyear(1900 + year)][month];<br>
> +    }<br>
> +    days += tm->tm_mday - 1;<br>
> +<br>
> +    return ((((days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec);<br>
> +}<br>
> +<br>
>  /* Combine absolute and relative fields, and round. */<br>
>  static int<br>
>  create_output (struct state *state, time_t *t_out, const time_t *ref,<br>
> @@ -1465,7 +1500,7 @@ create_output (struct state *state, time_t *t_out, const time_t *ref,<br>
>      if (is_field_set (state, TM_TZ)) {<br>
>         /* tm is in specified TZ, convert to UTC for timegm(3). */<br>
>         tm.tm_min -= get_field (state, TM_TZ);<br>
> -       t = timegm (&tm);<br>
> +       t = local_timegm (&tm);<br>
>      } else {<br>
>         /* tm is in local time. */<br>
>         t = mktime (&tm);<br>
> --<br>
> 1.7.9.2<br>
><br>
> _______________________________________________<br>
> notmuch mailing list<br>
> <a href="mailto:notmuch@notmuchmail.org">notmuch@notmuchmail.org</a><br>
> <a href="http://notmuchmail.org/mailman/listinfo/notmuch">http://notmuchmail.org/mailman/listinfo/notmuch</a><br>
</p>