diff options
Diffstat (limited to 'lib/compat')
-rw-r--r-- | lib/compat/Makemodule.am | 4 | ||||
-rw-r--r-- | lib/compat/getline.c | 50 | ||||
-rw-r--r-- | lib/compat/getsubopt.c | 45 | ||||
-rw-r--r-- | lib/compat/strndup.c | 31 |
4 files changed, 130 insertions, 0 deletions
diff --git a/lib/compat/Makemodule.am b/lib/compat/Makemodule.am new file mode 100644 index 0000000..c197fb0 --- /dev/null +++ b/lib/compat/Makemodule.am @@ -0,0 +1,4 @@ +libcompat_a_SOURCES = lib/compat/getline.c lib/compat/getsubopt.c +libcompat_a_SOURCES += lib/compat/strndup.c include/compat.h + +noinst_LIBRARIES += libcompat.a diff --git a/lib/compat/getline.c b/lib/compat/getline.c new file mode 100644 index 0000000..f330c6d --- /dev/null +++ b/lib/compat/getline.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * getline.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "compat.h" + +#include <string.h> +#include <stdlib.h> + +#ifndef HAVE_GETLINE +ssize_t getline(char **line, size_t *n, FILE *fp) +{ + size_t new_cap, len = 0, cap = 0; + char *buffer = NULL, *new; + int c; + + if (feof(fp) || ferror(fp)) + return -1; + + do { + c = fgetc(fp); + + if (ferror(fp)) + return -1; + + if (c == EOF) + c = '\n'; + + if (len == cap) { + new_cap = cap ? cap * 2 : 32; + new = realloc(buffer, new_cap); + + if (new == NULL) + return -1; + + buffer = new; + cap = new_cap; + } + + buffer[len++] = c; + } while (c != '\n'); + + *line = buffer; + *n = len; + return len; +} +#endif diff --git a/lib/compat/getsubopt.c b/lib/compat/getsubopt.c new file mode 100644 index 0000000..d53a37d --- /dev/null +++ b/lib/compat/getsubopt.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * getsubopt.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "compat.h" + +#include <stdlib.h> +#include <string.h> + +#ifndef HAVE_GETSUBOPT +int getsubopt(char **opt, char *const *keys, char **val) +{ + char *str = *opt; + size_t i, len; + + *val = NULL; + *opt = strchr(str, ','); + + if (*opt == NULL) { + *opt = str + strlen(str); + } else { + *(*opt)++ = '\0'; + } + + for (i = 0; keys[i]; ++i) { + len = strlen(keys[i]); + + if (strncmp(keys[i], str, len) != 0) + continue; + + if (str[len] != '=' && str[len] != '\0') + continue; + + if (str[len] == '=') + *val = str + len + 1; + + return i; + } + + return -1; +} +#endif diff --git a/lib/compat/strndup.c b/lib/compat/strndup.c new file mode 100644 index 0000000..dff79d7 --- /dev/null +++ b/lib/compat/strndup.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * strndup.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "compat.h" + +#include <string.h> +#include <stdlib.h> + +#ifndef HAVE_STRNDUP +char *strndup(const char *str, size_t max_len) +{ + size_t len = 0; + char *out; + + while (len < max_len && str[len] != '\0') + ++len; + + out = malloc(len + 1); + + if (out != NULL) { + memcpy(out, str, len); + out[len] = '\0'; + } + + return out; +} +#endif |