[PATCH 4/4] timegm: add portable implementation (Solaris support)

2013-08-21 Thread vladimir.ma...@oracle.com
From: Blake Jones 

The timegm(3) function is a non-standard extension to libc which is
available in GNU libc and on some BSDs.  Although SunOS had this
function in its libc, Solaris (unfortunately) removed it.  This patch
implements a very simple version of timegm() which is good enough for
parse-time-string.c.

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 +++
 compat/compat.h   |5 +++
 compat/have_timegm.c  |7 +
 compat/timegm.c   |   56 +
 configure |   11 +++
 parse-time-string/parse-time-string.c |1 +
 6 files changed, 84 insertions(+)
 create mode 100644 compat/have_timegm.c
 create mode 100644 compat/timegm.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 2c4f65f..b0d5417 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1)
 notmuch_compat_srcs += $(dir)/strsep.c
 endif

+ifneq ($(HAVE_TIMEGM),1)
+notmuch_compat_srcs += $(dir)/timegm.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index ae762c3..5a402d5 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -57,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle);
 char *strsep(char **stringp, const char *delim);
 #endif /* !HAVE_STRSEP */

+#if !HAVE_TIMEGM
+#include 
+time_t timegm (struct tm *tm);
+#endif /* !HAVE_TIMEGM */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_timegm.c b/compat/have_timegm.c
new file mode 100644
index 000..b62b793
--- /dev/null
+++ b/compat/have_timegm.c
@@ -0,0 +1,7 @@
+#include 
+#include "compat.h"
+
+int main()
+{
+return (int) timegm((struct tm *)0);
+}
diff --git a/compat/timegm.c b/compat/timegm.c
new file mode 100644
index 000..a986887
--- /dev/null
+++ b/compat/timegm.c
@@ -0,0 +1,56 @@
+/* timegm.c --- Implementation of replacement timegm function.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 3, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Written by Blake Jones. */
+
+#include 
+#include "compat.h"
+
+static int
+leapyear (int year)
+{
+return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
+}
+
+/*
+ * This is a simple implementation of timegm() which does what is needed
+ * by create_output() -- just turns the "struct tm" into a GMT time_t.
+ * It does not normalize any of the fields of the "struct tm", nor does
+ * it set tm_wday or tm_yday.
+ */
+time_t
+timegm (struct tm *tm)
+{
+intmonthlen[2][12] = {
+   { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+   { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+};
+intyear, month, days;
+
+days = 365 * (tm->tm_year - 70);
+for (year = 70; year < tm->tm_year; year++) {
+   if (leapyear(1900 + year)) {
+   days++;
+   }
+}
+for (month = 0; month < tm->tm_mon; month++) {
+   days += monthlen[leapyear(1900 + year)][month];
+}
+days += tm->tm_mday - 1;
+
+return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec);
+}
diff --git a/configure b/configure
index ac44857..6166917 100755
--- a/configure
+++ b/configure
@@ -530,6 +530,17 @@ else
 fi
 rm -f compat/have_strsep

+printf "Checking for timegm... "
+if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_timegm="1"
+else
+printf "No (will use our own instead).\n"
+have_timegm="0"
+fi
+rm -f compat/have_timegm
+
 printf "Checking for standard version of getpwuid_r... "
 if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
 then
diff --git a/parse-time-string/parse-time-string.c 
b/parse-time-string/parse-time-string.c
index 584067d..ccad422 100644
--- a/parse-time-string/parse-time-string.c
+++ b/parse-time-string/parse-time-string.c
@@ -32,6 +32,7 @@
 #include 
 #include 

+#include "compat.h"
 #include "parse-time-string.h"

 /*
-- 
1.7.9.2



[PATCH 4/4] timegm: add portable implementation (Solaris support)

2013-08-20 Thread vladimir.ma...@oracle.com
From: Blake Jones 

The timegm(3) function is a non-standard extension to libc which is
available in GNU libc and on some BSDs.  Although SunOS had this
function in its libc, Solaris (unfortunately) removed it.  This patch
implements a very simple version of timegm() which is good enough for
parse-time-string.c.

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 +++
 compat/compat.h   |5 +++
 compat/have_timegm.c  |7 
 compat/timegm.c   |   57 +
 configure |   11 +++
 parse-time-string/parse-time-string.c |1 +
 6 files changed, 85 insertions(+)
 create mode 100644 compat/have_timegm.c
 create mode 100644 compat/timegm.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 2c4f65f..b0d5417 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1)
 notmuch_compat_srcs += $(dir)/strsep.c
 endif

+ifneq ($(HAVE_TIMEGM),1)
+notmuch_compat_srcs += $(dir)/timegm.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index ae762c3..5a402d5 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -57,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle);
 char *strsep(char **stringp, const char *delim);
 #endif /* !HAVE_STRSEP */

+#if !HAVE_TIMEGM
+#include 
+time_t timegm (struct tm *tm);
+#endif /* !HAVE_TIMEGM */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_timegm.c b/compat/have_timegm.c
new file mode 100644
index 000..b62b793
--- /dev/null
+++ b/compat/have_timegm.c
@@ -0,0 +1,7 @@
+#include 
+#include "compat.h"
+
+int main()
+{
+return (int) timegm((struct tm *)0);
+}
diff --git a/compat/timegm.c b/compat/timegm.c
new file mode 100644
index 000..213963b
--- /dev/null
+++ b/compat/timegm.c
@@ -0,0 +1,57 @@
+/* timegm.c --- Implementation of replacement timegm function.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 3, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Written by Blake Jones. */
+
+#include 
+#include "compat.h"
+
+static int
+leapyear (int year)
+{
+return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
+}
+
+/*
+ * This is a simple implementation of timegm() which does what is needed
+ * by create_output() -- just turns the "struct tm" into a GMT time_t.
+ * It does not normalize any of the fields of the "struct tm", nor does
+ * it set tm_wday or tm_yday.
+ */
+time_t
+timegm (struct tm *tm)
+{
+intmonthlen[2][12] = {
+   { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+   { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+};
+intyear, month, days;
+
+days = 365 * (tm->tm_year - 70);
+for (year = 70; year < tm->tm_year; year++) {
+   if (leapyear(1900 + year)) {
+   days++;
+   }
+}
+for (month = 0; month < tm->tm_mon; month++) {
+   days += monthlen[leapyear(1900 + year)][month];
+}
+days += tm->tm_mday - 1;
+
+return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec);
+}
diff --git a/configure b/configure
index ac44857..6166917 100755
--- a/configure
+++ b/configure
@@ -530,6 +530,17 @@ else
 fi
 rm -f compat/have_strsep

+printf "Checking for timegm... "
+if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_timegm="1"
+else
+printf "No (will use our own instead).\n"
+have_timegm="0"
+fi
+rm -f compat/have_timegm
+
 printf "Checking for standard version of getpwuid_r... "
 if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
 then
diff --git a/parse-time-string/parse-time-string.c 
b/parse-time-string/parse-time-string.c
index 584067d..ccad422 100644
--- a/parse-time-string/parse-time-string.c
+++ b/parse-time-string/parse-time-string.c
@@ -32,6 +32,7 @@
 #include 
 #include 

+#include "compat.h"
 #include "parse-time-string.h"

 /*
-- 
1.7.9.2



[PATCH 4/4] timegm: add portable implementation (Solaris support)

2013-08-16 Thread vladimir.ma...@oracle.com
From: Blake Jones 

The timegm(3) function is a non-standard extension to libc which is
available in GNU libc and on some BSDs.  Although SunOS had this
function in its libc, Solaris (unfortunately) removed it.  This patch
implements a very simple version of timegm() which is good enough for
parse-time-string.c.

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 
 compat/compat.h   |5 +
 compat/have_timegm.c  |7 +++
 compat/timegm.c   |   37 +
 configure |   11 ++
 parse-time-string/parse-time-string.c |1 +
 6 files changed, 65 insertions(+)
 create mode 100644 compat/have_timegm.c
 create mode 100644 compat/timegm.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 2c4f65f..b0d5417 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1)
 notmuch_compat_srcs += $(dir)/strsep.c
 endif

+ifneq ($(HAVE_TIMEGM),1)
+notmuch_compat_srcs += $(dir)/timegm.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index ae762c3..5a402d5 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -57,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle);
 char *strsep(char **stringp, const char *delim);
 #endif /* !HAVE_STRSEP */

+#if !HAVE_TIMEGM
+#include 
+time_t timegm (struct tm *tm);
+#endif /* !HAVE_TIMEGM */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_timegm.c b/compat/have_timegm.c
new file mode 100644
index 000..b62b793
--- /dev/null
+++ b/compat/have_timegm.c
@@ -0,0 +1,7 @@
+#include 
+#include "compat.h"
+
+int main()
+{
+return (int) timegm((struct tm *)0);
+}
diff --git a/compat/timegm.c b/compat/timegm.c
new file mode 100644
index 000..6d76164
--- /dev/null
+++ b/compat/timegm.c
@@ -0,0 +1,37 @@
+#include 
+#include "compat.h"
+
+static int
+leapyear (int year)
+{
+return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
+}
+
+/*
+ * This is a simple implementation of timegm() which does what is needed
+ * by create_output() -- just turns the "struct tm" into a GMT time_t.
+ * It does not normalize any of the fields of the "struct tm", nor does
+ * it set tm_wday or tm_yday.
+ */
+time_t
+timegm (struct tm *tm)
+{
+intmonthlen[2][12] = {
+   { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+   { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+};
+intyear, month, days;
+
+days = 365 * (tm->tm_year - 70);
+for (year = 70; year < tm->tm_year; year++) {
+   if (leapyear(1900 + year)) {
+   days++;
+   }
+}
+for (month = 0; month < tm->tm_mon; month++) {
+   days += monthlen[leapyear(1900 + year)][month];
+}
+days += tm->tm_mday - 1;
+
+return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec);
+}
diff --git a/configure b/configure
index ac44857..6166917 100755
--- a/configure
+++ b/configure
@@ -530,6 +530,17 @@ else
 fi
 rm -f compat/have_strsep

+printf "Checking for timegm... "
+if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_timegm="1"
+else
+printf "No (will use our own instead).\n"
+have_timegm="0"
+fi
+rm -f compat/have_timegm
+
 printf "Checking for standard version of getpwuid_r... "
 if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
 then
diff --git a/parse-time-string/parse-time-string.c 
b/parse-time-string/parse-time-string.c
index 584067d..ccad422 100644
--- a/parse-time-string/parse-time-string.c
+++ b/parse-time-string/parse-time-string.c
@@ -32,6 +32,7 @@
 #include 
 #include 

+#include "compat.h"
 #include "parse-time-string.h"

 /*
-- 
1.7.9.2



[PATCH 3/4] strsep: check for availability (Solaris support)

2013-08-16 Thread vladimir.ma...@oracle.com
From: Blake Jones 

Solaris does not ship a version of the strsep() function.  This change
adds a check to "configure" to see whether notmuch needs to provide its
own implementation, and if so, it uses the new version in
"compat/strsep.c" (which was copied from Mutt, and apparently before
that from glibc).

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 +++
 compat/compat.h   |4 +++
 compat/have_strsep.c  |   11 +
 compat/strsep.c   |   65 +
 configure |   17 +
 5 files changed, 101 insertions(+)
 create mode 100644 compat/have_strsep.c
 create mode 100644 compat/strsep.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 13f16cd..2c4f65f 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1)
 notmuch_compat_srcs += $(dir)/strcasestr.c
 endif

+ifneq ($(HAVE_STRSEP),1)
+notmuch_compat_srcs += $(dir)/strsep.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index 0c4ac66..ae762c3 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -53,6 +53,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE 
*fp);
 char* strcasestr(const char *haystack, const char *needle);
 #endif /* !HAVE_STRCASESTR */

+#if !HAVE_STRSEP
+char *strsep(char **stringp, const char *delim);
+#endif /* !HAVE_STRSEP */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_strsep.c b/compat/have_strsep.c
new file mode 100644
index 000..2abab81
--- /dev/null
+++ b/compat/have_strsep.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include 
+
+int main()
+{
+char *found;
+char **stringp;
+const char *delim;
+
+found = strsep(stringp, delim);
+}
diff --git a/compat/strsep.c b/compat/strsep.c
new file mode 100644
index 000..78ab9e7
--- /dev/null
+++ b/compat/strsep.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include 
+
+/* Taken from glibc 2.6.1 */
+
+char *strsep (char **stringp, const char *delim)
+{
+  char *begin, *end;
+
+  begin = *stringp;
+  if (begin == NULL)
+return NULL;
+
+  /* A frequent case is when the delimiter string contains only one
+ character.  Here we don't need to call the expensive `strpbrk'
+ function and instead work using `strchr'.  */
+  if (delim[0] == '\0' || delim[1] == '\0')
+{
+  char ch = delim[0];
+
+  if (ch == '\0')
+   end = NULL;
+  else
+   {
+ if (*begin == ch)
+   end = begin;
+ else if (*begin == '\0')
+   end = NULL;
+ else
+   end = strchr (begin + 1, ch);
+   }
+}
+  else
+/* Find the end of the token.  */
+end = strpbrk (begin, delim);
+
+  if (end)
+{
+  /* Terminate the token and set *STRINGP past NUL character.  */
+  *end++ = '\0';
+  *stringp = end;
+}
+  else
+/* No more delimiters; this is the last token.  */
+*stringp = NULL;
+
+  return begin;
+}
diff --git a/configure b/configure
index e3aa857..ac44857 100755
--- a/configure
+++ b/configure
@@ -519,6 +519,17 @@ else
 fi
 rm -f compat/have_strcasestr

+printf "Checking for strsep... "
+if ${CC} -o compat/have_strsep "$srcdir"/compat/have_strsep.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_strsep="1"
+else
+printf "No (will use our own instead).\n"
+have_strsep="0"
+fi
+rm -f compat/have_strsep
+
 printf "Checking for standard version of getpwuid_r... "
 if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
 then
@@ -703,6 +714,10 @@ HAVE_GETLINE = ${have_getline}
 # build its own version)
 HAVE_STRCASESTR = ${have_strcasestr}

+# Whether the strsep function is available (if not, then notmuch will
+# build its own version)
+HAVE_STRSEP = ${have_strsep}
+
 # Whether the getpwuid_r function is standards-compliant
 # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
 # to enable the standards-compliant version -- needed 

[PATCH 2/4] asctime: check for standards compliance (Solaris support)

2013-08-16 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs
to be defined to get the right number of arguments in the prototypes for
asctime_r().  Solaris' default implementation conforms to POSIX.1c
Draft 6, rather than the final POSIX.1c spec.  The standards-compliant
version can be used by defining _POSIX_PTHREAD_SEMANTICS.

This change also adds the file "compat/check_asctime.c", which
configure uses to perform its check, and modifies compat/compat.h to
define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed.

Signed-off-by: Vladimir Marek 
---
 compat/check_asctime.c |   11 +++
 compat/compat.h|3 +++
 configure  |   22 --
 3 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 compat/check_asctime.c

diff --git a/compat/check_asctime.c b/compat/check_asctime.c
new file mode 100644
index 000..b0e56f0
--- /dev/null
+++ b/compat/check_asctime.c
@@ -0,0 +1,11 @@
+#include 
+#include 
+
+int main()
+{
+struct tm tm;
+
+(void) asctime_r (, NULL);
+
+return (0);
+}
diff --git a/compat/compat.h b/compat/compat.h
index c1ee0f9..0c4ac66 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -33,6 +33,9 @@ extern "C" {
 #if !STD_GETPWUID
 #define _POSIX_PTHREAD_SEMANTICS 1
 #endif
+#if !STD_ASCTIME
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif

 #if !HAVE_GETLINE
 #include 
diff --git a/configure b/configure
index b5465e4..e3aa857 100755
--- a/configure
+++ b/configure
@@ -530,6 +530,17 @@ else
 fi
 rm -f compat/check_getpwuid

+printf "Checking for standard version of asctime_r... "
+if ${CC} -o compat/check_asctime "$srcdir"/compat/check_asctime.c > /dev/null 
2>&1
+then
+printf "Yes.\n"
+std_asctime=1
+else
+printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n"
+std_asctime=0
+fi
+rm -f compat/check_asctime
+
 printf "int main(void){return 0;}\n" > minimal.c

 printf "Checking for rpath support... "
@@ -697,6 +708,11 @@ HAVE_STRCASESTR = ${have_strcasestr}
 # to enable the standards-compliant version -- needed for Solaris)
 STD_GETPWUID = ${std_getpwuid}

+# Whether the asctime_r function is standards-compliant
+# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
+# to enable the standards-compliant version -- needed for Solaris)
+STD_ASCTIME = ${std_asctime}
+
 # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD
 PLATFORM = ${platform}

@@ -743,11 +759,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) 
\$(GMIME_CFLAGS)  \\
   \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND)   \\
   \$(VALGRIND_CFLAGS)   \\
   -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
-  -DSTD_GETPWUID=\$(STD_GETPWUID)
+  -DSTD_GETPWUID=\$(STD_GETPWUID)   \\
+  -DSTD_ASCTIME=\$(STD_ASCTIME)
 CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\
 \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
 \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
 -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)   \\
--DSTD_GETPWUID=\$(STD_GETPWUID)
+-DSTD_GETPWUID=\$(STD_GETPWUID) \\
+-DSTD_ASCTIME=\$(STD_ASCTIME)
 CONFIGURE_LDFLAGS =  \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
 EOF
-- 
1.7.9.2



[PATCH 1/4] getpwuid: check for standards compliance (Solaris support)

2013-08-16 Thread vladimir.ma...@oracle.com
From: Blake Jones 

Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs
to be defined to get the right number of arguments in the prototypes for
getpwuid_r().  Solaris' default implementation conforms to POSIX.1c
Draft 6, rather than the final POSIX.1c spec.  The standards-compliant
version can be used by defining _POSIX_PTHREAD_SEMANTICS.

This change also adds the file "compat/check_getpwuid.c", which
configure uses to perform its check, and modifies compat/compat.h to
define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed.

Signed-off-by: Vladimir Marek 
---
 compat/check_getpwuid.c |   11 +++
 compat/compat.h |4 
 configure   |   23 +--
 3 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 compat/check_getpwuid.c

diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c
new file mode 100644
index 000..c435eb8
--- /dev/null
+++ b/compat/check_getpwuid.c
@@ -0,0 +1,11 @@
+#include 
+#include 
+
+int main()
+{
+struct passwd passwd, *ignored;
+
+(void) getpwuid_r (0, , NULL, 0, );
+
+return (0);
+}
diff --git a/compat/compat.h b/compat/compat.h
index b2e2736..c1ee0f9 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -30,6 +30,10 @@
 extern "C" {
 #endif

+#if !STD_GETPWUID
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+
 #if !HAVE_GETLINE
 #include 
 #include 
diff --git a/configure b/configure
index 3ba1ec3..b5465e4 100755
--- a/configure
+++ b/configure
@@ -519,6 +519,17 @@ else
 fi
 rm -f compat/have_strcasestr

+printf "Checking for standard version of getpwuid_r... "
+if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
+then
+printf "Yes.\n"
+std_getpwuid=1
+else
+printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n"
+std_getpwuid=0
+fi
+rm -f compat/check_getpwuid
+
 printf "int main(void){return 0;}\n" > minimal.c

 printf "Checking for rpath support... "
@@ -681,6 +692,11 @@ HAVE_GETLINE = ${have_getline}
 # build its own version)
 HAVE_STRCASESTR = ${have_strcasestr}

+# Whether the getpwuid_r function is standards-compliant
+# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
+# to enable the standards-compliant version -- needed for Solaris)
+STD_GETPWUID = ${std_getpwuid}
+
 # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD
 PLATFORM = ${platform}

@@ -725,10 +741,13 @@ WITH_ZSH = ${WITH_ZSH}
 # Combined flags for compiling and linking against all of the above
 CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)  \\
   \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND)   \\
-  \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)
+  \$(VALGRIND_CFLAGS)   \\
+  -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
+  -DSTD_GETPWUID=\$(STD_GETPWUID)
 CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\
 \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
 \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
- -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)
+-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)   \\
+-DSTD_GETPWUID=\$(STD_GETPWUID)
 CONFIGURE_LDFLAGS =  \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
 EOF
-- 
1.7.9.2



Solaris support - missing or incompatible functions (v2)

2013-08-16 Thread vladimir.ma...@oracle.com
Hi,

I'm re-sending the patches which were rebased to current top of the tree. Apart
from rebasing there has been no change made. I am using this notmuch for half a
year and it seems to work fine.

As I said in my previous email, not all the tests pass, but I know that the
failures in the testing itself and not in the code.

Notmuch test suite complete.
548/557 tests passed.
9 tests failed.

1 test fails because there are new exported symbols in notmuch binary
2 test fails because I don't have gpg
6 test fails because my emacs somehow refuses to send email


Thank you
-- 
Vlad


[PATCH 4/4] timegm: add portable implementation (Solaris support)

2013-05-06 Thread vladimir.ma...@oracle.com
From: Blake Jones 

The timegm(3) function is a non-standard extension to libc which is
available in GNU libc and on some BSDs.  Although SunOS had this
function in its libc, Solaris (unfortunately) removed it.  This patch
implements a very simple version of timegm() which is good enough for
parse-time-string.c.

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 
 compat/compat.h   |5 +
 compat/have_timegm.c  |7 +++
 compat/timegm.c   |   37 +
 configure |   11 ++
 parse-time-string/parse-time-string.c |1 +
 6 files changed, 65 insertions(+)
 create mode 100644 compat/have_timegm.c
 create mode 100644 compat/timegm.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 2c4f65f..b0d5417 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -17,4 +17,8 @@ ifneq ($(HAVE_STRSEP),1)
 notmuch_compat_srcs += $(dir)/strsep.c
 endif

+ifneq ($(HAVE_TIMEGM),1)
+notmuch_compat_srcs += $(dir)/timegm.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index ae762c3..5a402d5 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -57,6 +57,11 @@ char* strcasestr(const char *haystack, const char *needle);
 char *strsep(char **stringp, const char *delim);
 #endif /* !HAVE_STRSEP */

+#if !HAVE_TIMEGM
+#include 
+time_t timegm (struct tm *tm);
+#endif /* !HAVE_TIMEGM */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_timegm.c b/compat/have_timegm.c
new file mode 100644
index 000..b62b793
--- /dev/null
+++ b/compat/have_timegm.c
@@ -0,0 +1,7 @@
+#include 
+#include "compat.h"
+
+int main()
+{
+return (int) timegm((struct tm *)0);
+}
diff --git a/compat/timegm.c b/compat/timegm.c
new file mode 100644
index 000..6d76164
--- /dev/null
+++ b/compat/timegm.c
@@ -0,0 +1,37 @@
+#include 
+#include "compat.h"
+
+static int
+leapyear (int year)
+{
+return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
+}
+
+/*
+ * This is a simple implementation of timegm() which does what is needed
+ * by create_output() -- just turns the "struct tm" into a GMT time_t.
+ * It does not normalize any of the fields of the "struct tm", nor does
+ * it set tm_wday or tm_yday.
+ */
+time_t
+timegm (struct tm *tm)
+{
+intmonthlen[2][12] = {
+   { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+   { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+};
+intyear, month, days;
+
+days = 365 * (tm->tm_year - 70);
+for (year = 70; year < tm->tm_year; year++) {
+   if (leapyear(1900 + year)) {
+   days++;
+   }
+}
+for (month = 0; month < tm->tm_mon; month++) {
+   days += monthlen[leapyear(1900 + year)][month];
+}
+days += tm->tm_mday - 1;
+
+return days * 24) + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec);
+}
diff --git a/configure b/configure
index 5243cac..ee037d8 100755
--- a/configure
+++ b/configure
@@ -528,6 +528,17 @@ else
 fi
 rm -f compat/have_strsep

+printf "Checking for timegm... "
+if ${CC} -o compat/have_timegm "$srcdir"/compat/have_timegm.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_timegm="1"
+else
+printf "No (will use our own instead).\n"
+have_timegm="0"
+fi
+rm -f compat/have_timegm
+
 printf "Checking for standard version of getpwuid_r... "
 if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
 then
diff --git a/parse-time-string/parse-time-string.c 
b/parse-time-string/parse-time-string.c
index 584067d..ccad422 100644
--- a/parse-time-string/parse-time-string.c
+++ b/parse-time-string/parse-time-string.c
@@ -32,6 +32,7 @@
 #include 
 #include 

+#include "compat.h"
 #include "parse-time-string.h"

 /*
-- 
1.7.9.2



[PATCH 3/4] strsep: check for availability (Solaris support)

2013-05-06 Thread vladimir.ma...@oracle.com
From: Blake Jones 

Solaris does not ship a version of the strsep() function.  This change
adds a check to "configure" to see whether notmuch needs to provide its
own implementation, and if so, it uses the new version in
"compat/strsep.c" (which was copied from Mutt, and apparently before
that from glibc).

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 +++
 compat/compat.h   |4 +++
 compat/have_strsep.c  |   11 +
 compat/strsep.c   |   65 +
 configure |   17 +
 5 files changed, 101 insertions(+)
 create mode 100644 compat/have_strsep.c
 create mode 100644 compat/strsep.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 13f16cd..2c4f65f 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1)
 notmuch_compat_srcs += $(dir)/strcasestr.c
 endif

+ifneq ($(HAVE_STRSEP),1)
+notmuch_compat_srcs += $(dir)/strsep.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index 0c4ac66..ae762c3 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -53,6 +53,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE 
*fp);
 char* strcasestr(const char *haystack, const char *needle);
 #endif /* !HAVE_STRCASESTR */

+#if !HAVE_STRSEP
+char *strsep(char **stringp, const char *delim);
+#endif /* !HAVE_STRSEP */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_strsep.c b/compat/have_strsep.c
new file mode 100644
index 000..2abab81
--- /dev/null
+++ b/compat/have_strsep.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include 
+
+int main()
+{
+char *found;
+char **stringp;
+const char *delim;
+
+found = strsep(stringp, delim);
+}
diff --git a/compat/strsep.c b/compat/strsep.c
new file mode 100644
index 000..78ab9e7
--- /dev/null
+++ b/compat/strsep.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include 
+
+/* Taken from glibc 2.6.1 */
+
+char *strsep (char **stringp, const char *delim)
+{
+  char *begin, *end;
+
+  begin = *stringp;
+  if (begin == NULL)
+return NULL;
+
+  /* A frequent case is when the delimiter string contains only one
+ character.  Here we don't need to call the expensive `strpbrk'
+ function and instead work using `strchr'.  */
+  if (delim[0] == '\0' || delim[1] == '\0')
+{
+  char ch = delim[0];
+
+  if (ch == '\0')
+   end = NULL;
+  else
+   {
+ if (*begin == ch)
+   end = begin;
+ else if (*begin == '\0')
+   end = NULL;
+ else
+   end = strchr (begin + 1, ch);
+   }
+}
+  else
+/* Find the end of the token.  */
+end = strpbrk (begin, delim);
+
+  if (end)
+{
+  /* Terminate the token and set *STRINGP past NUL character.  */
+  *end++ = '\0';
+  *stringp = end;
+}
+  else
+/* No more delimiters; this is the last token.  */
+*stringp = NULL;
+
+  return begin;
+}
diff --git a/configure b/configure
index 99ec71a..5243cac 100755
--- a/configure
+++ b/configure
@@ -517,6 +517,17 @@ else
 fi
 rm -f compat/have_strcasestr

+printf "Checking for strsep... "
+if ${CC} -o compat/have_strsep "$srcdir"/compat/have_strsep.c > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_strsep="1"
+else
+printf "No (will use our own instead).\n"
+have_strsep="0"
+fi
+rm -f compat/have_strsep
+
 printf "Checking for standard version of getpwuid_r... "
 if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
 then
@@ -698,6 +709,10 @@ HAVE_GETLINE = ${have_getline}
 # build its own version)
 HAVE_STRCASESTR = ${have_strcasestr}

+# Whether the strsep function is available (if not, then notmuch will
+# build its own version)
+HAVE_STRSEP = ${have_strsep}
+
 # Whether the getpwuid_r function is standards-compliant
 # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
 # to enable the standards-compliant version -- needed 

[PATCH 2/4] asctime: check for standards compliance (Solaris support)

2013-05-06 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs
to be defined to get the right number of arguments in the prototypes for
asctime_r().  Solaris' default implementation conforms to POSIX.1c
Draft 6, rather than the final POSIX.1c spec.  The standards-compliant
version can be used by defining _POSIX_PTHREAD_SEMANTICS.

This change also adds the file "compat/check_asctime.c", which
configure uses to perform its check, and modifies compat/compat.h to
define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed.

Signed-off-by: Vladimir Marek 
---
 compat/check_asctime.c |   11 +++
 compat/compat.h|3 +++
 configure  |   22 --
 3 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 compat/check_asctime.c

diff --git a/compat/check_asctime.c b/compat/check_asctime.c
new file mode 100644
index 000..b0e56f0
--- /dev/null
+++ b/compat/check_asctime.c
@@ -0,0 +1,11 @@
+#include 
+#include 
+
+int main()
+{
+struct tm tm;
+
+(void) asctime_r (, NULL);
+
+return (0);
+}
diff --git a/compat/compat.h b/compat/compat.h
index c1ee0f9..0c4ac66 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -33,6 +33,9 @@ extern "C" {
 #if !STD_GETPWUID
 #define _POSIX_PTHREAD_SEMANTICS 1
 #endif
+#if !STD_ASCTIME
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif

 #if !HAVE_GETLINE
 #include 
diff --git a/configure b/configure
index 8ef7bac..99ec71a 100755
--- a/configure
+++ b/configure
@@ -528,6 +528,17 @@ else
 fi
 rm -f compat/check_getpwuid

+printf "Checking for standard version of asctime_r... "
+if ${CC} -o compat/check_asctime "$srcdir"/compat/check_asctime.c > /dev/null 
2>&1
+then
+printf "Yes.\n"
+std_asctime=1
+else
+printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n"
+std_asctime=0
+fi
+rm -f compat/check_asctime
+
 printf "int main(void){return 0;}\n" > minimal.c

 printf "Checking for rpath support... "
@@ -692,6 +703,11 @@ HAVE_STRCASESTR = ${have_strcasestr}
 # to enable the standards-compliant version -- needed for Solaris)
 STD_GETPWUID = ${std_getpwuid}

+# Whether the asctime_r function is standards-compliant
+# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
+# to enable the standards-compliant version -- needed for Solaris)
+STD_ASCTIME = ${std_asctime}
+
 # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD
 PLATFORM = ${platform}

@@ -738,11 +754,13 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) 
\$(GMIME_CFLAGS)  \\
   \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND)   \\
   \$(VALGRIND_CFLAGS)   \\
   -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
-  -DSTD_GETPWUID=\$(STD_GETPWUID)
+  -DSTD_GETPWUID=\$(STD_GETPWUID)   \\
+  -DSTD_ASCTIME=\$(STD_ASCTIME)
 CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\
 \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
 \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
 -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)   \\
--DSTD_GETPWUID=\$(STD_GETPWUID)
+-DSTD_GETPWUID=\$(STD_GETPWUID) \\
+-DSTD_ASCTIME=\$(STD_ASCTIME)
 CONFIGURE_LDFLAGS =  \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
 EOF
-- 
1.7.9.2



[PATCH 1/4] getpwuid: check for standards compliance (Solaris support)

2013-05-06 Thread vladimir.ma...@oracle.com
From: Blake Jones 

Add checks to "configure" to see whether _POSIX_PTHREAD_SEMANTICS needs
to be defined to get the right number of arguments in the prototypes for
getpwuid_r().  Solaris' default implementation conforms to POSIX.1c
Draft 6, rather than the final POSIX.1c spec.  The standards-compliant
version can be used by defining _POSIX_PTHREAD_SEMANTICS.

This change also adds the file "compat/check_getpwuid.c", which
configure uses to perform its check, and modifies compat/compat.h to
define _POSIX_PTHREAD_SEMANTICS if configure detected it was needed.

Signed-off-by: Vladimir Marek 
---
 compat/check_getpwuid.c |   11 +++
 compat/compat.h |4 
 configure   |   23 +--
 3 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 compat/check_getpwuid.c

diff --git a/compat/check_getpwuid.c b/compat/check_getpwuid.c
new file mode 100644
index 000..c435eb8
--- /dev/null
+++ b/compat/check_getpwuid.c
@@ -0,0 +1,11 @@
+#include 
+#include 
+
+int main()
+{
+struct passwd passwd, *ignored;
+
+(void) getpwuid_r (0, , NULL, 0, );
+
+return (0);
+}
diff --git a/compat/compat.h b/compat/compat.h
index b2e2736..c1ee0f9 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -30,6 +30,10 @@
 extern "C" {
 #endif

+#if !STD_GETPWUID
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+
 #if !HAVE_GETLINE
 #include 
 #include 
diff --git a/configure b/configure
index 460fcfc..8ef7bac 100755
--- a/configure
+++ b/configure
@@ -517,6 +517,17 @@ else
 fi
 rm -f compat/have_strcasestr

+printf "Checking for standard version of getpwuid_r... "
+if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > 
/dev/null 2>&1
+then
+printf "Yes.\n"
+std_getpwuid=1
+else
+printf "No (will define _POSIX_PTHREAD_SEMANTICS to get it).\n"
+std_getpwuid=0
+fi
+rm -f compat/check_getpwuid
+
 printf "int main(void){return 0;}\n" > minimal.c

 printf "Checking for rpath support... "
@@ -676,6 +687,11 @@ HAVE_GETLINE = ${have_getline}
 # build its own version)
 HAVE_STRCASESTR = ${have_strcasestr}

+# Whether the getpwuid_r function is standards-compliant
+# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
+# to enable the standards-compliant version -- needed for Solaris)
+STD_GETPWUID = ${std_getpwuid}
+
 # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS, FREEBSD, OPENBSD
 PLATFORM = ${platform}

@@ -720,10 +736,13 @@ WITH_ZSH = ${WITH_ZSH}
 # Combined flags for compiling and linking against all of the above
 CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)  \\
   \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND)   \\
-  \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)
+  \$(VALGRIND_CFLAGS)   \\
+  -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
+  -DSTD_GETPWUID=\$(STD_GETPWUID)
 CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)\\
 \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
 \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
- -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)
+-DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)   \\
+-DSTD_GETPWUID=\$(STD_GETPWUID)
 CONFIGURE_LDFLAGS =  \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
 EOF
-- 
1.7.9.2



Solaris support - missing or incompatible functions

2013-05-06 Thread vladimir.ma...@oracle.com
Hi,

This is next series of patches adding Solaris support to notmuch. I am mostly
using what Blake Jones sent some time ago + I fixed all the comments he
received back then. Since it's mostly his work, it's IMO fair to keep
him as an author. But since I made sure the patches work, I'm signing
them. I'm really git newbie, so hopefully this is right thing to do ...

I tested the build on Solaris using Oracle Studio and on Linux using
gcc (to make sure I haven't break anything).

I can't run the notmuch 'make test' on Solaris (too old bash) and on linux the
results are

421/525 tests passed.
25 tests failed.
79 tests skipped.

but they are the same without my changes too ...

Cheers
-- 
Vlad


[PATCH] lib/message.cc: stale pointer bug (v3)

2013-05-02 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

Xapian::TermIterator::operator* returns std::string which is destroyed
as soon as (*i).c_str() finishes. The remembered pointer 'term' then
references invalid memory.

Signed-off-by: Vladimir Marek 
---
 lib/message.cc |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 8720c1b..c4261e6 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -266,18 +266,18 @@ _notmuch_message_get_term (notmuch_message_t *message,
   const char *prefix)
 {
 int prefix_len = strlen (prefix);
-const char *term = NULL;
 char *value;

 i.skip_to (prefix);

-if (i != end)
-   term = (*i).c_str ();
+if (i == end)
+   return NULL;

-if (!term || strncmp (term, prefix, prefix_len))
+std::string term = *i;
+if (strncmp (term.c_str(), prefix, prefix_len))
return NULL;

-value = talloc_strdup (message, term + prefix_len);
+value = talloc_strdup (message, term.c_str() + prefix_len);

 #if DEBUG_DATABASE_SANITY
 i++;
-- 
1.7.9.2



[PATCH 01/24] lib/message.cc: stale pointer bug

2013-05-02 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

Xapian::TermIterator::operator* returns std::string which is destroyed
as soon as (*i).c_str() finishes. The remembered pointer 'term' then
references invalid memory.

Signed-off-by: Vladimir Marek 
---
 lib/message.cc |   11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 8720c1b..a890550 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -266,18 +266,19 @@ _notmuch_message_get_term (notmuch_message_t *message,
   const char *prefix)
 {
 int prefix_len = strlen (prefix);
-const char *term = NULL;
+std::string term;
 char *value;

 i.skip_to (prefix);

-if (i != end)
-   term = (*i).c_str ();
+if (i == end)
+   return NULL;

-if (!term || strncmp (term, prefix, prefix_len))
+term = *i;
+if (strncmp (term.c_str(), prefix, prefix_len))
return NULL;

-value = talloc_strdup (message, term + prefix_len);
+value = talloc_strdup (message, term.c_str() + prefix_len);

 #if DEBUG_DATABASE_SANITY
 i++;
-- 
1.7.9.2



[PATCH] don't store temporary value returned from c_str()

2013-04-20 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

This is causing problems when compiled by Oracle Studio. Memory pointed
by (const char*)term was already changed once talloc_strdup was called.

Signed-off-by: Vladimir Marek 
---
 lib/message.cc |9 -
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 8720c1b..8d329d1 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -266,18 +266,17 @@ _notmuch_message_get_term (notmuch_message_t *message,
   const char *prefix)
 {
 int prefix_len = strlen (prefix);
-const char *term = NULL;
 char *value;

 i.skip_to (prefix);

-if (i != end)
-   term = (*i).c_str ();
+if (i == end)
+   return NULL;

-if (!term || strncmp (term, prefix, prefix_len))
+if (strncmp ((*i).c_str(), prefix, prefix_len))
return NULL;

-value = talloc_strdup (message, term + prefix_len);
+value = talloc_strdup (message, (*i).c_str() + prefix_len);

 #if DEBUG_DATABASE_SANITY
 i++;
-- 
1.7.3.2



[PATCH 2/4] dirent->d_type not available on Soalris

2012-04-09 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

The inspiration was taken from similar issue in mutt:
http://does-not-exist.org/mail-archives/mutt-dev/msg11290.html

Signed-off-by: Vladimir Marek 
---
 notmuch-new.c |   28 
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index 4f13535..3d265bd 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -21,6 +21,9 @@
 #include "notmuch-client.h"

 #include 
+#ifndef _DIRENT_HAVE_D_TYPE
+#include 
+#endif

 typedef struct _filename_node {
 char *filename;
@@ -167,7 +170,14 @@ _entries_resemble_maildir (struct dirent **entries, int 
count)
 int i, found = 0;

 for (i = 0; i < count; i++) {
+#ifdef _DIRENT_HAVE_D_TYPE
if (entries[i]->d_type != DT_DIR && entries[i]->d_type != DT_UNKNOWN)
+#else
+   struct stat statbuf;
+   if (stat(entries[i]->d_name, ) == -1)
+   continue;
+   if (! S_ISDIR(statbuf.st_mode))
+#endif
continue;

if (strcmp(entries[i]->d_name, "new") == 0 ||
@@ -258,6 +268,9 @@ add_files_recursive (notmuch_database_t *notmuch,
 struct stat st;
 notmuch_bool_t is_maildir, new_directory;
 const char **tag;
+#ifndef _DIRENT_HAVE_D_TYPE
+struct stat statbuf;
+#endif

 if (stat (path, )) {
fprintf (stderr, "Error reading directory %s: %s\n",
@@ -328,9 +341,16 @@ add_files_recursive (notmuch_database_t *notmuch,
 * scandir results, then it might be a directory (and if not,
 * then we'll stat and return immediately in the next level of
 * recursion). */
+#ifdef _DIRENT_HAVE_D_TYPE
if (entry->d_type != DT_DIR &&
entry->d_type != DT_LNK &&
entry->d_type != DT_UNKNOWN)
+#else
+   if (stat(entry->d_name, ) == -1)
+   continue;
+   if (!(statbuf.st_mode & S_IFDIR) &&
+   !(statbuf.st_mode & S_IFLNK))
+#endif
{
continue;
}
@@ -427,7 +447,11 @@ add_files_recursive (notmuch_database_t *notmuch,
 *
 * In either case, a stat does the trick.
 */
+#ifdef _DIRENT_HAVE_D_TYPE
if (entry->d_type == DT_LNK || entry->d_type == DT_UNKNOWN) {
+#else
+   if (stat(entry->d_name, ) == -1 || statbuf.st_mode & S_IFLNK) {
+#endif
int err;

next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
@@ -443,7 +467,11 @@ add_files_recursive (notmuch_database_t *notmuch,

if (! S_ISREG (st.st_mode))
continue;
+#ifdef _DIRENT_HAVE_D_TYPE
} else if (entry->d_type != DT_REG) {
+#else
+   } else if (statbuf.st_mode & S_IFREG) {
+#endif
continue;
}

-- 
1.7.3.2



[PATCH 4/4] Explicitly type void* pointers

2012-04-09 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 


Signed-off-by: Vladimir Marek 
---
 lib/database.cc |2 +-
 lib/message.cc  |2 +-
 lib/thread.cc   |2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index 16c4354..3c82632 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -1361,7 +1361,7 @@ _resolve_message_id_to_thread_id (notmuch_database_t 
*notmuch,
return status;

 if (message) {
-   *thread_id_ret = talloc_steal (ctx,
+   *thread_id_ret = (const char*)talloc_steal (ctx,
   notmuch_message_get_thread_id (message));

notmuch_message_destroy (message);
diff --git a/lib/message.cc b/lib/message.cc
index 0075425..d56d442 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -220,7 +220,7 @@ _notmuch_message_create_for_message_id (notmuch_database_t 
*notmuch,

message_id,

);
 if (message)
-   return talloc_steal (notmuch, message);
+   return (notmuch_message_t*) talloc_steal (notmuch, message);
 else if (*status_ret)
return NULL;

diff --git a/lib/thread.cc b/lib/thread.cc
index e976d64..d41ff3e 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -225,7 +225,7 @@ _thread_add_message (notmuch_thread_t *thread,
 char *clean_author;

 _notmuch_message_list_add_message (thread->message_list,
-  talloc_steal (thread, message));
+  (_notmuch_message*)talloc_steal (thread, 
message));
 thread->total_messages++;

 g_hash_table_insert (thread->message_hash,
-- 
1.7.3.2



[PATCH 3/4] Private strsep implementation

2012-04-09 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

strsep is not available on Solaris 10, so we stole the one used by mutt.

Signed-off-by: Vladimir Marek 
---
 compat/Makefile.local |4 +++
 compat/compat.h   |4 +++
 compat/have_strsep.c  |   10 +++
 compat/strsep.c   |   65 +
 configure |   21 ++-
 5 files changed, 102 insertions(+), 2 deletions(-)
 create mode 100644 compat/have_strsep.c
 create mode 100644 compat/strsep.c

diff --git a/compat/Makefile.local b/compat/Makefile.local
index 13f16cd..2c4f65f 100644
--- a/compat/Makefile.local
+++ b/compat/Makefile.local
@@ -13,4 +13,8 @@ ifneq ($(HAVE_STRCASESTR),1)
 notmuch_compat_srcs += $(dir)/strcasestr.c
 endif

+ifneq ($(HAVE_STRSEP),1)
+notmuch_compat_srcs += $(dir)/strsep.c
+endif
+
 SRCS := $(SRCS) $(notmuch_compat_srcs)
diff --git a/compat/compat.h b/compat/compat.h
index b2e2736..cf8d56d 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -46,6 +46,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE 
*fp);
 char* strcasestr(const char *haystack, const char *needle);
 #endif /* !HAVE_STRCASESTR */

+#if !HAVE_STRSEP
+char *strsep(char **stringp, const char *delim);
+#endif /* !HAVE_STRSEP */
+
 /* Silence gcc warnings about unused results.  These warnings exist
  * for a reason; any use of this needs to be justified. */
 #ifdef __GNUC__
diff --git a/compat/have_strsep.c b/compat/have_strsep.c
new file mode 100644
index 000..5bd396c
--- /dev/null
+++ b/compat/have_strsep.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include 
+
+int main()
+{
+char *found;
+char **stringp, const char *delim;
+
+found = strsep(stringp, delim);
+}
diff --git a/compat/strsep.c b/compat/strsep.c
new file mode 100644
index 000..78ab9e7
--- /dev/null
+++ b/compat/strsep.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1992, 93, 96, 97, 98, 99, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include 
+
+/* Taken from glibc 2.6.1 */
+
+char *strsep (char **stringp, const char *delim)
+{
+  char *begin, *end;
+
+  begin = *stringp;
+  if (begin == NULL)
+return NULL;
+
+  /* A frequent case is when the delimiter string contains only one
+ character.  Here we don't need to call the expensive `strpbrk'
+ function and instead work using `strchr'.  */
+  if (delim[0] == '\0' || delim[1] == '\0')
+{
+  char ch = delim[0];
+
+  if (ch == '\0')
+   end = NULL;
+  else
+   {
+ if (*begin == ch)
+   end = begin;
+ else if (*begin == '\0')
+   end = NULL;
+ else
+   end = strchr (begin + 1, ch);
+   }
+}
+  else
+/* Find the end of the token.  */
+end = strpbrk (begin, delim);
+
+  if (end)
+{
+  /* Terminate the token and set *STRINGP past NUL character.  */
+  *end++ = '\0';
+  *stringp = end;
+}
+  else
+/* No more delimiters; this is the last token.  */
+*stringp = NULL;
+
+  return begin;
+}
diff --git a/configure b/configure
index 6870341..a06df7c 100755
--- a/configure
+++ b/configure
@@ -486,6 +486,17 @@ else
 fi
 rm -f compat/have_strcasestr

+printf "Checking for strsep... "
+if ${CC} -o compat/have_strsep "$srcdir"/compat/have_strsep > /dev/null 2>&1
+then
+printf "Yes.\n"
+have_strsep=1
+else
+printf "No (will use our own instead).\n"
+have_strsep=0
+fi
+rm -f compat/have_strsep
+
 printf "int main(void){return 0;}\n" > minimal.c

 printf "Checking for rpath support... "
@@ -645,6 +656,10 @@ HAVE_GETLINE = ${have_getline}
 # build its own version)
 HAVE_STRCASESTR = ${have_strcasestr}

+# Whether the strsep function is available (if not, then notmuch will
+# build its own version)
+HAVE_STRSEP = ${have_strsep}
+
 # Supported platforms (so far) are: LINUX, MACOSX, SOLARIS
 PLATFORM = ${platform}

@@ -689,10 +704,12 @@ WITH_ZSH = ${WITH_ZSH}
 # Combined flags for compiling and linking against all of the above
 CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)  \\
   \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND)   \\
-  \$(VALGRIND_CFLAGS) -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR)
+

[PATCH 2/4] dirent->d_type not available on Soalris

2012-04-09 Thread vladimir.ma...@oracle.com
From: Vladimir Marek 

The inspiration was taken from similar issue in mutt:
http://does-not-exist.org/mail-archives/mutt-dev/msg11290.html

Signed-off-by: Vladimir Marek 
---
 notmuch-new.c |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index 4f13535..20bc580 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -21,6 +21,7 @@
 #include "notmuch-client.h"

 #include 
+#include 

 typedef struct _filename_node {
 char *filename;
@@ -165,9 +166,12 @@ static int
 _entries_resemble_maildir (struct dirent **entries, int count)
 {
 int i, found = 0;
+struct stat statbuf;

 for (i = 0; i < count; i++) {
-   if (entries[i]->d_type != DT_DIR && entries[i]->d_type != DT_UNKNOWN)
+   if (stat(entries[i]->d_name, ) == -1)
+   continue;
+   if (! S_ISDIR(statbuf.st_mode))
continue;

if (strcmp(entries[i]->d_name, "new") == 0 ||
@@ -258,6 +262,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 struct stat st;
 notmuch_bool_t is_maildir, new_directory;
 const char **tag;
+struct stat statbuf;

 if (stat (path, )) {
fprintf (stderr, "Error reading directory %s: %s\n",
@@ -321,6 +326,9 @@ add_files_recursive (notmuch_database_t *notmuch,

entry = fs_entries[i];

+   if (stat(entry->d_name, ) == -1)
+   continue;
+
/* We only want to descend into directories.
 * But symlinks can be to directories too, of course.
 *
@@ -328,9 +336,8 @@ add_files_recursive (notmuch_database_t *notmuch,
 * scandir results, then it might be a directory (and if not,
 * then we'll stat and return immediately in the next level of
 * recursion). */
-   if (entry->d_type != DT_DIR &&
-   entry->d_type != DT_LNK &&
-   entry->d_type != DT_UNKNOWN)
+   if (!(statbuf.st_mode & S_IFDIR) &&
+   !(statbuf.st_mode & S_IFLNK))
{
continue;
}
@@ -427,7 +434,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 *
 * In either case, a stat does the trick.
 */
-   if (entry->d_type == DT_LNK || entry->d_type == DT_UNKNOWN) {
+   if (stat(entry->d_name, ) == -1 || statbuf.st_mode & S_IFLNK) {
int err;

next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
@@ -443,7 +450,7 @@ add_files_recursive (notmuch_database_t *notmuch,

if (! S_ISREG (st.st_mode))
continue;
-   } else if (entry->d_type != DT_REG) {
+   } else if ( statbuf.st_mode & S_IFREG) {
continue;
}

-- 
1.7.3.2



notmuch on Solaris

2012-04-09 Thread vladimir.ma...@oracle.com
Hi,

In order to make notmuch compilable on Solaris, I had to make some
changes in the source code. Some changes are not yet ready to be
included to official tree, some I believe are. So I took first few to
see if I'm doing anything which could be accepted and hopefully decrease
number of local patches I have to hold. Comments are mostly welcome.

Thank you
-- 
Vlad