diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2024-11-14 19:35:45 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2024-11-14 19:35:45 +0100 |
commit | df5520aa2dae5b3ce7abf8733dcdd152898af163 (patch) | |
tree | 00d3047bfb14f682bfb5a21010c731ed649bfed7 /app/wlib/mswlib/getline/getline.c | |
parent | df247efec654e512242e4f4f1b0212034f9e01fe (diff) | |
parent | ec3c0f6f6e7153fa797dc57a0e95779cbc63a23b (diff) |
Merge branch 'release/debian/1_5.3.0GA-1'debian/1_5.3.0GA-1
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); +} + |