/* * Copyright (c) 2000 Peter 'Luna' Runestig * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifi- * cation, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright no- * tice, this list of conditions and the following disclaimer in the do- * cumentation and/or other materials provided with the distribution. * * o The names of the contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 REGENTS OR CONTRIBUTORS BE LI- * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- * LITY, 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. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #define STEP 128 char *fgetln(FILE *stream, size_t *len) /* unlike the BSD call, the returned pointer must be free()'d */ { char *ret, *inp; size_t r, tot = 0; ret = (char *) malloc(STEP); if (!ret) return NULL; inp = ret; while ((r = fread(inp, 1, STEP, stream))) { char *p = inp; int i, found = 0; /* check if we read the last of the file */ if (r < STEP) { /* fake that we found it */ found = 1; i = r - 1; } else for (i = 0; i < r; i++) if (*p++ == '\n') { found = 1; break; } if (found) { *len = tot + i + 1; if (r == STEP) { /* we read too much so we must put back stream pos */ if (r - i > 1) fseek(stream, i + 1 - r, SEEK_CUR); } break; } else { p = (char *) realloc(ret, tot + STEP); if (!p) { free(ret); return NULL; } ret = p; tot += r; inp = ret + tot; } } return ret; }