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 | |
parent | 89506435fa02ceea57db6e7709e8412d4b749311 (diff) |
Expand environment variables for all config option values when loading
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/alcConfig.c | 77 | ||||
-rw-r--r-- | Alc/hrtf.c | 31 |
2 files changed, 77 insertions, 31 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); } @@ -798,42 +798,13 @@ static struct Hrtf *LoadHrtf(ALuint deviceRate) next = fnamelist; while(*(fnamelist=next) != '\0' && *fnamelist != ',') { - next = strpbrk(fnamelist, "%,$"); + next = strpbrk(fnamelist, "%,"); while(fnamelist != next && *fnamelist && i < sizeof(fname)) fname[i++] = *(fnamelist++); if(!next || *next == ',') break; - if(*next == '$') - { - next++; - if(*next == '$') - { - /* '$$' becomes a single '$'. */ - if(i < sizeof(fname)) - fname[i++] = '$'; - next++; - } - else - { - const char *str; - char envname[1024]; - size_t k = 0; - - while((isalnum(*next) || *next == '_') && k < sizeof(envname)-1) - envname[k++] = *(next++); - envname[k++] = '\0'; - - if((str=getenv(envname)) != NULL) - { - int wrote = snprintf(&fname[i], sizeof(fname)-i, "%s", str); - i += minu(wrote, sizeof(fname)-i); - } - } - continue; - } - /* *next == '%' */ next++; if(*next == 'r') |