From 9a88f7da453eadc72d8f333700dbd80777feecd1 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 25 Feb 2018 14:33:19 +0100 Subject: Initial commit Signed-off-by: David Oberhollenzer --- lib/src/splitkv.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 lib/src/splitkv.c (limited to 'lib/src/splitkv.c') diff --git a/lib/src/splitkv.c b/lib/src/splitkv.c new file mode 100644 index 0000000..6c6fe94 --- /dev/null +++ b/lib/src/splitkv.c @@ -0,0 +1,124 @@ +#include + +#include "util.h" + +static char *skpspc(char *ptr) +{ + while (*ptr == ' ' || *ptr == '\t') + ++ptr; + return ptr; +} + +static int xdigit(int x) +{ + if (isupper(x)) + return x - 'A' + 0x0A; + if (islower(x)) + return x - 'a' + 0x0A; + return x - '0'; +} + +static char *parse_str(char *src) +{ + char *dst = src; + int c; + + for (;;) { + c = *(src++); + + switch (c) { + case '\\': + c = *(src++); + + switch (c) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 't': c = '\t'; break; + case '\\': break; + case '"': break; + case 'x': + c = 0; + if (isxdigit(*src)) + c = (c << 4) | xdigit(*(src++)); + if (isxdigit(*src)) + c = (c << 4) | xdigit(*(src++)); + break; + case '0': + c = 0; + if (isdigit(*src) && *src < '8') + c = (c << 3) | (*(src++) - '0'); + if (isdigit(*src) && *src < '8') + c = (c << 3) | (*(src++) - '0'); + if (isdigit(*src) && *src < '8') + c = (c << 3) | (*(src++) - '0'); + break; + default: + return NULL; + } + break; + case '"': + *(dst++) = '\0'; + goto out; + } + + *(dst++) = c; + } +out: + return src; +} + +int splitkv(char *line, char **key, char **value) +{ + *key = NULL; + *value = NULL; + + line = skpspc(line); + + if (*line == '#' || *line == '\0') + return 0; + + if (!isalpha(*line)) + return -1; + + *key = line; + + while (isalnum(*line)) + ++line; + + if (*line == ' ' || *line == '\t') { + *(line++) = '\0'; + line = skpspc(line); + } + + if (*line != '=') + return -1; + + *(line++) = '\0'; + line = skpspc(line); + + if (*line == '"') { + ++line; + *value = line; + + line = parse_str(line); + } else if (isalnum(*line)) { + *value = line; + + while (isalnum(*line) || *line == '.' || *line == '_') + ++line; + + if (*line != '\0') + *(line++) = '\0'; + } else { + return -1; + } + + line = skpspc(line); + + if (*line != '\0' && *line != '#') + return -1; + + return 0; +} -- cgit v1.2.3