From: git Date: Sun, 3 May 2026 15:09:56 +0000 (-0400) Subject: add fgetln X-Git-Url: https://git.datadissipation.net/?a=commitdiff_plain;h=429122ae78262efcb3da5b67d6d746ba93cb209a;p=single-header-libcext.git add fgetln --- diff --git a/README.md b/README.md index a10245f..cea3998 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ includes `vasprintf()` and `asprintf()` --- +### fgetln + +includes `fgetln()` + +--- + ### getopt\_long includes `getopt()`, `getsubopt()`, `getopt_long()` and `getopt_long_only()` @@ -54,14 +60,15 @@ permuting, defining those enables it per function (GNU behaviour, can still be d --- -### strlcat - -includes `strlcat()` and `strlcpy()` - ---- - ### strdup includes `strdup()` and `strndup()` `strndup()` follows the latest standard, meaning that it copies at most _n_ chars, not _n_ + 1. +also, no standard specifies that `strndup()` should return less than _n_ if `strlen(s) + 1` < _n_, but this implementation does so. + +--- + +### strlcat + +includes `strlcat()` and `strlcpy()` diff --git a/fgetln.h b/fgetln.h new file mode 100644 index 0000000..92a0f95 --- /dev/null +++ b/fgetln.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* https://git.datadissipation.net */ +#ifndef FGETLN_H_ + #define FGETLN_H_ 1 + + #ifdef FGETLN_INCLUDE_LIBC + #include + #include + #include + #include + #include + #endif /* FGETLN_INCLUDE_LIBC */ + + #ifndef HAVE_FGETLN + #define HAVE_FGETLN 1 + #define fgetln i_fgetln_ +char *i_fgetln_(FILE *, size_t *); + #endif /* !HAVE_FGETLN */ + + #ifdef FGETLN_IMPLEMENTATION +char * +i_fgetln_(FILE *fp, size_t *len) +{ + static char *buf = NULL; + static size_t bufsiz = 0; + char *ptr; + + if (buf == NULL) { + bufsiz = BUFSIZ; + if ((buf = malloc(bufsiz)) == NULL) + return NULL; + } + + if (fgets(buf, bufsiz, fp) == NULL) + return NULL; + + *len = 0; + while ((ptr = strchr(&buf[*len], '\n')) == NULL) { + size_t nbufsiz = bufsiz + BUFSIZ; + char *nbuf = realloc(buf, nbufsiz); + + if (nbuf == NULL) { + int oerrno = errno; + free(buf); + errno = oerrno; + buf = NULL; + return NULL; + } else { + buf = nbuf; + } + + if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) { + buf[bufsiz] = '\0'; + *len = strlen(buf); + return buf; + } + + *len = bufsiz; + bufsiz = nbufsiz; + } + + *len = (ptr - buf) + 1; + return buf; +} + #endif /* FGETLN_IMPLEMENTATION */ +#endif /* !FGETLN_H_ */