Created
January 15, 2010 16:20
-
-
Save kylef/278167 to your computer and use it in GitHub Desktop.
Mac OS X port of getdelim by Simon Josefsson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* getdelim.c --- Implementation of replacement getdelim function. | |
Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 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 2, 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. */ | |
/* Ported from glibc by Simon Josefsson. */ | |
#ifdef HAVE_CONFIG_H | |
# include <config.h> | |
#endif | |
#include <limits.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#ifndef SIZE_MAX | |
# define SIZE_MAX ((size_t) -1) | |
#endif | |
#ifndef SSIZE_MAX | |
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) | |
#endif | |
#if !HAVE_FLOCKFILE | |
# undef flockfile | |
# define flockfile(x) ((void) 0) | |
#endif | |
#if !HAVE_FUNLOCKFILE | |
# undef funlockfile | |
# define funlockfile(x) ((void) 0) | |
#endif | |
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and | |
NUL-terminate it). *LINEPTR is a pointer returned from malloc (or | |
NULL), pointing to *N characters of space. It is realloc'ed as | |
necessary. Returns the number of characters read (not including | |
the null terminator), or -1 on error or EOF. */ | |
ssize_t | |
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) | |
{ | |
ssize_t result; | |
size_t cur_len = 0; | |
if (lineptr == NULL || n == NULL || fp == NULL) | |
{ | |
errno = EINVAL; | |
return -1; | |
} | |
flockfile (fp); | |
if (*lineptr == NULL || *n == 0) | |
{ | |
*n = 120; | |
*lineptr = (char *) malloc (*n); | |
if (*lineptr == NULL) | |
{ | |
result = -1; | |
goto unlock_return; | |
} | |
} | |
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 unlock_return; | |
} | |
new_lineptr = (char *) realloc (*lineptr, needed); | |
if (new_lineptr == NULL) | |
{ | |
result = -1; | |
goto unlock_return; | |
} | |
*lineptr = new_lineptr; | |
*n = needed; | |
} | |
(*lineptr)[cur_len] = i; | |
cur_len++; | |
if (i == delimiter) | |
break; | |
} | |
(*lineptr)[cur_len] = '\0'; | |
result = cur_len ? cur_len : result; | |
unlock_return: | |
funlockfile (fp); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment