summaryrefslogtreecommitdiff
path: root/app/wlib/mswlib/getline/getline.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2024-07-03 10:19:36 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2024-07-03 10:19:36 +0200
commitb6bd52cd7330a90fc0e44dbe6022551a8dd768a1 (patch)
tree9804282102f8c40d27407b9c94119b35eeb5013c /app/wlib/mswlib/getline/getline.c
parentc9d0740841fbe0539e42e66d3865672bfcd3ac02 (diff)
parenta14a7a0ccc9de76aeab0b2e4bbf58f1a79deedc2 (diff)
Update upstream source from tag 'upstream/5.3.0GA'
Update to upstream version '5.3.0GA' with Debian dir dfd14d63b0238e276ade6f54dd9100325df5b2f9
Diffstat (limited to 'app/wlib/mswlib/getline/getline.c')
-rw-r--r--app/wlib/mswlib/getline/getline.c73
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);
+}
+