diff options
author | Sven Gothel <[email protected]> | 2014-06-10 05:30:02 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-06-10 05:30:02 +0200 |
commit | f95bf4457fbc31112fa82dacbc1b7e094b9fd1cf (patch) | |
tree | 965ba5b8e6fc8e6bfe7a981c1dfb1179bb9adcde /Alc/alcConfig.c | |
parent | 7297c3214a4c648aaee81a9877da15b88f798197 (diff) | |
parent | c07fb7b45c1e345dbaa439882250de5b2213026f (diff) |
Merge branch 'UPSTREAM' into UPSTREAM_MERGE
Diffstat (limited to 'Alc/alcConfig.c')
-rw-r--r-- | Alc/alcConfig.c | 219 |
1 files changed, 174 insertions, 45 deletions
diff --git a/Alc/alcConfig.c b/Alc/alcConfig.c index 98c0df32..2c9aef41 100644 --- a/Alc/alcConfig.c +++ b/Alc/alcConfig.c @@ -32,13 +32,14 @@ #include <stdio.h> #include <ctype.h> #include <string.h> - -#include "alMain.h" - #ifdef _WIN32_IE #include <shlobj.h> #endif +#include "alMain.h" +#include "compat.h" + + typedef struct ConfigEntry { char *key; char *value; @@ -48,10 +49,8 @@ typedef struct ConfigBlock { ConfigEntry *entries; unsigned int entryCount; } ConfigBlock; - static ConfigBlock cfgBlock; -static char buffer[1024]; static char *lstrip(char *line) { @@ -69,23 +68,132 @@ static char *rstrip(char *line) return line; } +static int readline(FILE *f, char **output, size_t *maxlen) +{ + size_t len = 0; + int c; + + while((c=fgetc(f)) != EOF && (c == '\r' || c == '\n')) + ; + if(c == EOF) + return 0; + + do { + if(len+1 >= *maxlen) + { + void *temp = NULL; + size_t newmax; + + newmax = (*maxlen ? (*maxlen)<<1 : 32); + if(newmax > *maxlen) + temp = realloc(*output, newmax); + if(!temp) + { + ERR("Failed to realloc "SZFMT" bytes from "SZFMT"!\n", newmax, *maxlen); + return 0; + } + + *output = temp; + *maxlen = newmax; + } + (*output)[len++] = c; + (*output)[len] = '\0'; + } while((c=fgetc(f)) != EOF && c != '\r' && c != '\n'); + + return 1; +} + + +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 = len+addstrlen+1; + if(newmax > maxlen) + temp = realloc(output, newmax); + if(!temp) + { + ERR("Failed to realloc "SZFMT" bytes from "SZFMT"!\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] = ""; + char *buffer = NULL; + size_t maxlen = 0; ConfigEntry *ent; - while(fgets(buffer, sizeof(buffer), f)) + while(readline(f, &buffer, &maxlen)) { char *line, *comment; char key[256] = ""; char value[256] = ""; comment = strchr(buffer, '#'); - if(comment) - { - *(comment++) = 0; - comment = rstrip(lstrip(comment)); - } + if(comment) *(comment++) = 0; line = rstrip(lstrip(buffer)); if(!line[0]) @@ -123,26 +231,26 @@ static void LoadConfigFromFile(FILE *f) * manually. */ if(strcmp(value, "\"\"") == 0 || strcmp(value, "''") == 0) value[0] = 0; - } - else if(sscanf(line, "%255[^=] %255[=]", key, value) == 2) - { - /* Special case for 'key =' */ - value[0] = 0; - } - else - { - ERR("config parse error: malformed option line: \"%s\"\n\n", line); - continue; - } - rstrip(key); - - if(curSection[0] != 0) - { - size_t len = strlen(curSection); - memmove(&key[len+1], key, sizeof(key)-1-len); - key[len] = '/'; - memcpy(key, curSection, len); - } + } + else if(sscanf(line, "%255[^=] %255[=]", key, value) == 2) + { + /* Special case for 'key =' */ + value[0] = 0; + } + else + { + ERR("config parse error: malformed option line: \"%s\"\n\n", line); + continue; + } + rstrip(key); + + if(curSection[0] != 0) + { + size_t len = strlen(curSection); + memmove(&key[len+1], key, sizeof(key)-1-len); + key[len] = '/'; + memcpy(key, curSection, len); + } /* Check if we already have this option set */ ent = cfgBlock.entries; @@ -171,36 +279,57 @@ 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); } + + free(buffer); } +#ifdef _WIN32 void ReadALConfig(void) { - const char *str; + WCHAR buffer[PATH_MAX]; + const WCHAR *str; FILE *f; -#ifdef _WIN32 - if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE) + if(SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE) { - size_t p = strlen(buffer); - snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini"); + size_t p = lstrlenW(buffer); + _snwprintf(buffer+p, PATH_MAX-p, L"\\alsoft.ini"); - TRACE("Loading config %s...\n", buffer); - f = fopen(buffer, "rt"); + TRACE("Loading config %ls...\n", buffer); + f = _wfopen(buffer, L"rt"); if(f) { LoadConfigFromFile(f); fclose(f); } } + + if((str=_wgetenv(L"ALSOFT_CONF")) != NULL && *str) + { + TRACE("Loading config %ls...\n", str); + f = _wfopen(str, L"rt"); + if(f) + { + LoadConfigFromFile(f); + fclose(f); + } + } +} #else +void ReadALConfig(void) +{ + char buffer[PATH_MAX]; + const char *str; + FILE *f; + str = "/etc/openal/alsoft.conf"; TRACE("Loading config %s...\n", str); - f = fopen(str, "r"); + f = al_fopen(str, "r"); if(f) { LoadConfigFromFile(f); @@ -231,7 +360,7 @@ void ReadALConfig(void) buffer[sizeof(buffer)-1] = 0; TRACE("Loading config %s...\n", next); - f = fopen(next, "r"); + f = al_fopen(next, "r"); if(f) { LoadConfigFromFile(f); @@ -247,7 +376,7 @@ void ReadALConfig(void) snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str); TRACE("Loading config %s...\n", buffer); - f = fopen(buffer, "r"); + f = al_fopen(buffer, "r"); if(f) { LoadConfigFromFile(f); @@ -266,19 +395,18 @@ void ReadALConfig(void) if(buffer[0] != 0) { TRACE("Loading config %s...\n", buffer); - f = fopen(buffer, "r"); + f = al_fopen(buffer, "r"); if(f) { LoadConfigFromFile(f); fclose(f); } } -#endif if((str=getenv("ALSOFT_CONF")) != NULL && *str) { TRACE("Loading config %s...\n", str); - f = fopen(str, "r"); + f = al_fopen(str, "r"); if(f) { LoadConfigFromFile(f); @@ -286,6 +414,7 @@ void ReadALConfig(void) } } } +#endif void FreeALConfig(void) { |