[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