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@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