Expand environment variables for all config option values when loading

This commit is contained in:
Chris Robinson 2014-02-26 17:25:05 -08:00
parent 89506435fa
commit 1b9a722601
2 changed files with 77 additions and 31 deletions

View File

@ -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);
}

View File

@ -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')