diff options
author | Jan200101 <sentrycraft123@gmail.com> | 2020-12-16 16:39:47 +0100 |
---|---|---|
committer | Jan200101 <sentrycraft123@gmail.com> | 2021-03-26 18:53:25 +0100 |
commit | 90c0539f392f0ab8fa69b1f66b10da4a185c371f (patch) | |
tree | 8c341a403cbddfee0415bce09f8a62cb8dd3c767 /src | |
parent | da7bbea605b33f46e13234da5bb147ecc99537ce (diff) | |
download | polecat-90c0539f392f0ab8fa69b1f66b10da4a185c371f.tar.gz polecat-90c0539f392f0ab8fa69b1f66b10da4a185c371f.zip |
commit variable parser
this is a simple variable parser written in standard C that tries to be as safe as possible
Diffstat (limited to 'src')
-rw-r--r-- | src/lutris.c | 90 | ||||
-rw-r--r-- | src/lutris.h | 8 |
2 files changed, 96 insertions, 2 deletions
diff --git a/src/lutris.c b/src/lutris.c index b80d830..0580818 100644 --- a/src/lutris.c +++ b/src/lutris.c @@ -519,3 +519,93 @@ void lutris_freeInstaller(struct script_t* installer) } } } + +size_t parseVar(char** pvar, struct list_t* variables, size_t variable_count) +{ + char* var = *pvar; + char* head = var; + char* tail, *end; + char* buf, *key; + + size_t varcount = 0; + + while (*head != '\0') + { + if (*head == VARIABLESIGN) + { + // ensure sanity by clearing variables + buf = NULL; + key = NULL; + + end = strlen(var) + var; + + int bufend = (head-var); + + // find variable key + tail = ++head; + while (*tail <= 'z' && *tail >= 'A') // we ONLY accept ascii variables + { + + ++tail; + } + + if ((tail-head) > 0) + { + // resolve variable key and store it + buf = malloc(tail-head); + strncpy(buf, head, tail-head); + for (size_t i = 0; i < variable_count; ++i) + { + if (strncmp(variables[i].key, buf, tail-head) == 0) + { + switch (variables[i].type) + { + case value_string: + key = variables[i].value.str; + break; + + case value_function: + variables[i].value.func(); + break; + + default: + UNREACHABLE + break; + } + } + } + free(buf); + } + + if (!key) continue; + + // copy everything from variable key end to end of string + buf = malloc(end-tail+1); + strncpy(buf, tail, end-tail+1); + + size_t varsize = (head-var) + strlen(key) + (end-tail) + 1; + + var = realloc(var, varsize); + // end of the string up until the variable + // we cannot fetch this after the realloc because it points to completly different memory making pointer math impossible + var[bufend] = '\0'; + strncat(var, key, varsize - strlen(var) - 1); + strncat(var, buf, varsize - strlen(var) - 1); + // cleanup + free(buf); + buf = NULL; + + varcount++; + + // bring your head back to the world of living memory + head = var; + } + + head++; + } + + // point pvar back to the string + *pvar = var; + + return varcount; +} diff --git a/src/lutris.h b/src/lutris.h index d0fe782..bc815c1 100644 --- a/src/lutris.h +++ b/src/lutris.h @@ -4,6 +4,8 @@ #include <stddef.h> #include <json.h> +#define VARIABLESIGN '$' + enum keyword { MOVE = 0, MERGE, @@ -100,8 +102,8 @@ struct file_t { }; enum value_type_t { - string, - function + value_string, + value_function }; struct list_t { @@ -146,4 +148,6 @@ void lutris_getInstallerURL(char*, char*, size_t); struct script_t lutris_getInstaller(char*); void lutris_freeInstaller(struct script_t*); +size_t parseVar(char**, struct list_t*, size_t); + #endif |