diff options
Diffstat (limited to 'app/wlib/mswlib/getline')
| -rw-r--r-- | app/wlib/mswlib/getline/LICENSE | 25 | ||||
| -rw-r--r-- | app/wlib/mswlib/getline/README.md | 5 | ||||
| -rw-r--r-- | app/wlib/mswlib/getline/getline.c | 73 | 
3 files changed, 103 insertions, 0 deletions
| diff --git a/app/wlib/mswlib/getline/LICENSE b/app/wlib/mswlib/getline/LICENSE new file mode 100644 index 0000000..22df455 --- /dev/null +++ b/app/wlib/mswlib/getline/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2022, Costantino Grana +All rights reserved. + +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 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 COPYRIGHT HOLDER 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. diff --git a/app/wlib/mswlib/getline/README.md b/app/wlib/mswlib/getline/README.md new file mode 100644 index 0000000..60f0dae --- /dev/null +++ b/app/wlib/mswlib/getline/README.md @@ -0,0 +1,5 @@ +A POSIX getdelim() and getline() implementation for MSVC + +Tired of always having problems in reading arbitrary length lines from file under Windows, I tried to write a POSIX getdelim() and getline() implementation for MSVC. Let me know if you have any suggestion for improving this. + +This probably needs a test suite. diff --git a/app/wlib/mswlib/getline/getline.c b/app/wlib/mswlib/getline/getline.c new file mode 100644 index 0000000..202c7e2 --- /dev/null +++ b/app/wlib/mswlib/getline/getline.c @@ -0,0 +1,73 @@ +#include "getline.h" + +#include <stdlib.h> +#include <errno.h> + +// MSVC specific implementation +static void fseterr(FILE *fp) +{ +    struct file { // Undocumented implementation detail +        unsigned char *_ptr; +        unsigned char *_base; +        int _cnt; +        int _flag; +        int _file; +        int _charbuf; +        int _bufsiz; +    }; +    #define _IOERR 0x10 + +    ((struct file *)fp)->_flag |= _IOERR; +} + +ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delim, FILE *restrict stream) +{ +    if (lineptr == NULL || n == NULL || stream == NULL || (*lineptr == NULL && *n != 0)) { +        errno = EINVAL; +        return -1; +    } +    if (feof(stream) || ferror(stream)) { +        return -1; +    } + +    if (*lineptr == NULL) { +        *n = 256; +        *lineptr = malloc(*n); +        if (*lineptr == NULL) { +            fseterr(stream); +            errno = ENOMEM; +            return -1; +        } +    } +    ssize_t nread = 0; +    int c = EOF; +    while (c != delim) { +        c = fgetc(stream); +        if (c == EOF) { +            break; +        } +        if (nread >= (ssize_t)(*n - 1)) { +            size_t newn = *n * 2; +            char *newptr = realloc(*lineptr, newn); +            if (newptr == NULL) { +                fseterr(stream); +                errno = ENOMEM; +                return -1; +            } +            *lineptr = newptr; +            *n = newn; +        } +        (*lineptr)[nread++] = c; +    } +    if (c == EOF && nread == 0) { +        return -1; +    } +    (*lineptr)[nread] = 0; +    return nread; +} + +ssize_t getline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream) +{ +    return getdelim(lineptr, n, '\n', stream); +} + | 
