[PATCH v2 10/10] timegm: add portable implementation (Solaris support)
authorBlake Jones <blakej@foo.net>
Mon, 5 Nov 2012 19:02:03 +0000 (11:02 +1600)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:50:21 +0000 (09:50 -0800)
cc/f9943b5fde36bdb93dcc866f8c53326dbc7f6a [new file with mode: 0644]

diff --git a/cc/f9943b5fde36bdb93dcc866f8c53326dbc7f6a b/cc/f9943b5fde36bdb93dcc866f8c53326dbc7f6a
new file mode 100644 (file)
index 0000000..871e019
--- /dev/null
@@ -0,0 +1,244 @@
+Return-Path: <blakej@foo.net>\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 B425F431FC2\r
+       for <notmuch@notmuchmail.org>; Mon,  5 Nov 2012 11:02:31 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+       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 eb8xP6Y0T2Jz for <notmuch@notmuchmail.org>;\r
+       Mon,  5 Nov 2012 11:02:30 -0800 (PST)\r
+Received: from foo.net (70-36-235-136.dsl.static.sonic.net [70.36.235.136])\r
+       (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id A6DE8429E2E\r
+       for <notmuch@notmuchmail.org>; Mon,  5 Nov 2012 11:02:26 -0800 (PST)\r
+Received: from foo.net (localhost [127.0.0.1])\r
+       by foo.net (8.14.5+Sun/8.14.5) with ESMTP id qA5J2OhU019149;\r
+       Mon, 5 Nov 2012 11:02:24 -0800 (PST)\r
+Received: (from blakej@localhost)\r
+       by foo.net (8.14.5+Sun/8.14.5/Submit) id qA5J2OX5019148;\r
+       Mon, 5 Nov 2012 11:02:24 -0800 (PST)\r
+From: Blake Jones <blakej@foo.net>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH v2 10/10] timegm: add portable implementation (Solaris\r
+ support)\r
+Date: Mon,  5 Nov 2012 11:02:03 -0800\r
+Message-Id: <1352142123-18286-11-git-send-email-blakej@foo.net>\r
+X-Mailer: git-send-email 1.7.3.2\r
+In-Reply-To: <1352142123-18286-1-git-send-email-blakej@foo.net>\r
+References: <1352142123-18286-1-git-send-email-blakej@foo.net>\r
+X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0.2\r
+       (foo.net [127.0.0.1]); Mon, 05 Nov 2012 11:02:25 -0800 (PST)\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: Mon, 05 Nov 2012 19:02:31 -0000\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
+One complication of this fix is that 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 is the thing which needs to call timegm().  A\r
+straightforward attempt to have the two static libraries reconcile their\r
+symbols from one another fails, because the symbols come from different\r
+.o's, and the linker only does a single pass on each ".a" looking for\r
+dependencies.  To solve this, libparse-time-string includes "compat.h",\r
+and pulls in .o's from the compat directory, in order to get everything\r
+that it needs.\r
+---\r
+ compat/Makefile.local                 |    4 +++\r
+ compat/compat.h                       |   19 ++++++++++------\r
+ compat/have_timegm.c                  |    7 ++++++\r
+ compat/timegm.c                       |   37 +++++++++++++++++++++++++++++++++\r
+ configure                             |   11 +++++++++\r
+ parse-time-string/Makefile.local      |    4 ++-\r
+ parse-time-string/parse-time-string.c |    1 +\r
+ 7 files changed, 75 insertions(+), 8 deletions(-)\r
+ create mode 100644 compat/have_timegm.c\r
+ create mode 100644 compat/timegm.c\r
+\r
+diff --git a/compat/Makefile.local b/compat/Makefile.local\r
+index 2c4f65f..b0d5417 100644\r
+--- a/compat/Makefile.local\r
++++ b/compat/Makefile.local\r
+@@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1)\r
+ notmuch_compat_srcs += $(dir)/strsep.c\r
+ endif\r
+ \r
++ifneq ($(HAVE_TIMEGM),1)\r
++notmuch_compat_srcs += $(dir)/timegm.c\r
++endif\r
++\r
+ SRCS := $(SRCS) $(notmuch_compat_srcs)\r
+diff --git a/compat/compat.h b/compat/compat.h\r
+index 0b5e465..5a402d5 100644\r
+--- a/compat/compat.h\r
++++ b/compat/compat.h\r
+@@ -30,6 +30,13 @@\r
+ extern "C" {\r
+ #endif\r
+ \r
++#if !STD_GETPWUID\r
++#define _POSIX_PTHREAD_SEMANTICS 1\r
++#endif\r
++#if !STD_ASCTIME\r
++#define _POSIX_PTHREAD_SEMANTICS 1\r
++#endif\r
++\r
+ #if !HAVE_GETLINE\r
+ #include <stdio.h>\r
+ #include <unistd.h>\r
+@@ -50,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle);\r
+ char *strsep(char **stringp, const char *delim);\r
+ #endif /* !HAVE_STRSEP */\r
+ \r
++#if !HAVE_TIMEGM\r
++#include <time.h>\r
++time_t timegm (struct tm *tm);\r
++#endif /* !HAVE_TIMEGM */\r
++\r
+ /* Silence gcc warnings about unused results.  These warnings exist\r
+  * for a reason; any use of this needs to be justified. */\r
+ #ifdef __GNUC__\r
+@@ -58,13 +70,6 @@ char *strsep(char **stringp, const char *delim);\r
+ #define IGNORE_RESULT(x) x\r
+ #endif /* __GNUC__ */\r
+ \r
+-#if !STD_GETPWUID\r
+-#define _POSIX_PTHREAD_SEMANTICS 1\r
+-#endif\r
+-#if !STD_ASCTIME\r
+-#define _POSIX_PTHREAD_SEMANTICS 1\r
+-#endif\r
+-\r
+ #ifdef __cplusplus\r
+ }\r
+ #endif\r
+diff --git a/compat/have_timegm.c b/compat/have_timegm.c\r
+new file mode 100644\r
+index 0000000..b62b793\r
+--- /dev/null\r
++++ b/compat/have_timegm.c\r
+@@ -0,0 +1,7 @@\r
++#include <time.h>\r
++#include "compat.h"\r
++\r
++int main()\r
++{\r
++    return (int) timegm((struct tm *)0);\r
++}\r
+diff --git a/compat/timegm.c b/compat/timegm.c\r
+new file mode 100644\r
+index 0000000..6d76164\r
+--- /dev/null\r
++++ b/compat/timegm.c\r
+@@ -0,0 +1,37 @@\r
++#include <time.h>\r
++#include "compat.h"\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
++time_t\r
++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 + tm->tm_sec);\r
++}\r
+diff --git a/configure b/configure\r
+index ab8357f..f3ec9a2 100755\r
+--- a/configure\r
++++ b/configure\r
+@@ -523,6 +523,17 @@ else\r
+ fi\r
+ rm -f compat/have_strsep\r
+ \r
++printf "Checking for timegm... "\r
++if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1\r
++then\r
++    printf "Yes.\n"\r
++    have_timegm="1"\r
++else\r
++    printf "No (will use our own instead).\n"\r
++    have_timegm="0"\r
++fi\r
++rm -f compat/have_timegm\r
++\r
+ printf "Checking for standard version of getpwuid_r... "\r
+ if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1\r
+ then\r
+diff --git a/parse-time-string/Makefile.local b/parse-time-string/Makefile.local\r
+index 53534f3..c011e0b 100644\r
+--- a/parse-time-string/Makefile.local\r
++++ b/parse-time-string/Makefile.local\r
+@@ -1,7 +1,9 @@\r
+ dir := parse-time-string\r
+ extra_cflags += -I$(srcdir)/$(dir)\r
+ \r
+-libparse-time-string_c_srcs := $(dir)/parse-time-string.c\r
++libparse-time-string_c_srcs :=                \\r
++      $(notmuch_compat_srcs)          \\r
++      $(dir)/parse-time-string.c\r
+ \r
+ libparse-time-string_modules := $(libparse-time-string_c_srcs:.c=.o)\r
+ \r
+diff --git a/parse-time-string/parse-time-string.c b/parse-time-string/parse-time-string.c\r
+index 584067d..ccad422 100644\r
+--- a/parse-time-string/parse-time-string.c\r
++++ b/parse-time-string/parse-time-string.c\r
+@@ -32,6 +32,7 @@\r
+ #include <sys/time.h>\r
+ #include <sys/types.h>\r
+ \r
++#include "compat.h"\r
+ #include "parse-time-string.h"\r
+ \r
+ /*\r
+-- \r
+1.7.3.2\r
+\r