diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2024-07-03 10:19:30 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2024-07-03 10:19:30 +0200 |
commit | a14a7a0ccc9de76aeab0b2e4bbf58f1a79deedc2 (patch) | |
tree | e469179df67a0e0db49161a43cbf8076a189f6f4 /app/wlib/mswlib/getline/getline.c | |
parent | 5d2c2b27a6323e2666378b986129b2a7c2c39e5c (diff) |
New upstream version 5.3.0GAupstream/5.3.0GAupstream
Diffstat (limited to 'app/wlib/mswlib/getline/getline.c')
-rw-r--r-- | app/wlib/mswlib/getline/getline.c | 73 |
1 files changed, 73 insertions, 0 deletions
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); +} + |