diff options
author | Chris Robinson <[email protected]> | 2014-02-26 17:25:05 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-02-26 17:25:05 -0800 |
commit | 1b9a722601e59baa1f78cc42f39df40bc6fb9cf6 (patch) | |
tree | 3e5338616cf3289d2bd7c2d1e2dc6779d5742eb6 /Alc/alcConfig.c | |
parent | 89506435fa02ceea57db6e7709e8412d4b749311 (diff) |
Expand environment variables for all config option values when loading
Diffstat (limited to 'Alc/alcConfig.c')
-rw-r--r-- | Alc/alcConfig.c | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/Alc/alcConfig.c b/Alc/alcConfig.c index a3c8aa1e..a2355fc0 100644 --- a/Alc/alcConfig.c +++ b/Alc/alcConfig.c @@ -112,6 +112,81 @@ static int readline(FILE *f, char **output, size_t *maxlen) } +static char *expdup(const char *str) +{ + char *output = NULL; + size_t maxlen = 0; + size_t len = 0; + + while(*str != '\0') + { + const char *addstr; + size_t addstrlen; + size_t i; + + if(str[0] != '$') + { + const char *next = strchr(str, '$'); + addstr = str; + addstrlen = next ? (size_t)(next-str) : strlen(str); + + str += addstrlen; + } + else + { + str++; + if(*str == '$') + { + const char *next = strchr(str+1, '$'); + addstr = str; + addstrlen = next ? (size_t)(next-str) : strlen(str); + + str += addstrlen; + } + else + { + char envname[1024]; + size_t k = 0; + + while((isalnum(*str) || *str == '_') && k < sizeof(envname)-1) + envname[k++] = *(str++); + envname[k++] = '\0'; + + if((addstr=getenv(envname)) == NULL) + continue; + addstrlen = strlen(addstr); + } + } + if(addstrlen == 0) + continue; + + if(addstrlen >= maxlen-len) + { + void *temp = NULL; + size_t newmax; + + newmax = NextPowerOf2(len+addstrlen+1); + if(newmax > maxlen) + temp = realloc(output, newmax); + if(!temp) + { + ERR("Failed to realloc %lu bytes from %lu!\n", newmax, maxlen); + return output; + } + + output = temp; + maxlen = newmax; + } + + for(i = 0;i < addstrlen;i++) + output[len++] = addstr[i]; + output[len] = '\0'; + } + + return output ? output : calloc(1, 1); +} + + static void LoadConfigFromFile(FILE *f) { char curSection[128] = ""; @@ -216,7 +291,7 @@ static void LoadConfigFromFile(FILE *f) } free(ent->value); - ent->value = strdup(value); + ent->value = expdup(value); TRACE("found '%s' = '%s'\n", ent->key, ent->value); } |