[notmuch] [PATCH] Add private implementations of strndup and getline.

Jeffrey C. Ollie jeff at ocjtech.us
Mon Nov 23 05:43:30 PST 2009


Add private implementations of strndup and getline for those platforms
that don't have them (notably Mac OS X) no matter what preprocessor
symbols you define.

Signed-off-by: Jeffrey C. Ollie <jeff at ocjtech.us>
---
 lib/xutil.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/xutil.h |    6 +++
 2 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/lib/xutil.c b/lib/xutil.c
index 6fa5eb0..61467f1 100644
--- a/lib/xutil.c
+++ b/lib/xutil.c
@@ -79,6 +79,105 @@ xstrdup (const char *s)
     return ret;
 }
 
+/* Mac OS X don't have strndup even if _GNU_SOURCE is defined */
+char *
+_notmuch_strndup (const char *s, size_t n)
+{
+    size_t len = strlen (s);
+    char *ret;
+
+    if (len <= n)
+       return strdup (s);
+
+    ret = malloc(n + 1);
+    strncpy(ret, s, n);
+    ret[n] = '\0';
+    return ret;
+}
+
+/* getline implementation is copied from glibc. */
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+ssize_t
+_notmuch_getline (char **lineptr, size_t *n, FILE *fp)
+{
+    ssize_t result;
+    size_t cur_len = 0;
+
+    if (lineptr == NULL || n == NULL || fp == NULL)
+    {
+       errno = EINVAL;
+       return -1;
+    }
+
+    if (*lineptr == NULL || *n == 0)
+    {
+       *n = 120;
+       *lineptr = (char *) malloc (*n);
+       if (*lineptr == NULL)
+       {
+           result = -1;
+           goto end;
+       }
+    }
+
+    for (;;)
+    {
+       int i;
+
+       i = getc (fp);
+       if (i == EOF)
+       {
+           result = -1;
+           break;
+       }
+
+       /* Make enough space for len+1 (for final NUL) bytes.  */
+       if (cur_len + 1 >= *n)
+       {
+           size_t needed_max =
+               SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+           size_t needed = 2 * *n + 1;   /* Be generous. */
+           char *new_lineptr;
+
+           if (needed_max < needed)
+               needed = needed_max;
+           if (cur_len + 1 >= needed)
+           {
+               result = -1;
+               goto end;
+           }
+
+           new_lineptr = (char *) realloc (*lineptr, needed);
+           if (new_lineptr == NULL)
+           {
+               result = -1;
+               goto end;
+           }
+
+           *lineptr = new_lineptr;
+           *n = needed;
+       }
+
+       (*lineptr)[cur_len] = i;
+       cur_len++;
+
+       if (i == '\n')
+           break;
+    }
+    (*lineptr)[cur_len] = '\0';
+    result = cur_len ? (ssize_t) cur_len : result;
+
+end:
+    return result;
+}
+
 char *
 xstrndup (const char *s, size_t n)
 {
diff --git a/lib/xutil.h b/lib/xutil.h
index b973f7d..d13259a 100644
--- a/lib/xutil.h
+++ b/lib/xutil.h
@@ -39,6 +39,12 @@ char *
 xstrdup (const char *s);
 
 char *
+_notmuch_strndup (const char *s, size_t n);
+
+ssize_t
+_notmuch_getline (char **lineptr, size_t *n, FILE *stream);
+
+char *
 xstrndup (const char *s, size_t n);
 
 void
-- 
1.6.5.2



More information about the notmuch mailing list