Mercurial > audio-send
diff Alc/alcConfig.c @ 0:f9476ff7637e
initial forking of open-al to create multiple listeners
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 25 Oct 2011 13:02:31 -0700 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/Alc/alcConfig.c Tue Oct 25 13:02:31 2011 -0700 1.3 @@ -0,0 +1,342 @@ 1.4 +/** 1.5 + * OpenAL cross platform audio library 1.6 + * Copyright (C) 1999-2007 by authors. 1.7 + * This library is free software; you can redistribute it and/or 1.8 + * modify it under the terms of the GNU Library General Public 1.9 + * License as published by the Free Software Foundation; either 1.10 + * version 2 of the License, or (at your option) any later version. 1.11 + * 1.12 + * This library is distributed in the hope that it will be useful, 1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.15 + * Library General Public License for more details. 1.16 + * 1.17 + * You should have received a copy of the GNU Library General Public 1.18 + * License along with this library; if not, write to the 1.19 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 1.20 + * Boston, MA 02111-1307, USA. 1.21 + * Or go to http://www.gnu.org/copyleft/lgpl.html 1.22 + */ 1.23 + 1.24 +#ifdef _WIN32 1.25 +#ifdef __MINGW64__ 1.26 +#define _WIN32_IE 0x501 1.27 +#else 1.28 +#define _WIN32_IE 0x400 1.29 +#endif 1.30 +#endif 1.31 + 1.32 +#include "config.h" 1.33 + 1.34 +#include <stdlib.h> 1.35 +#include <stdio.h> 1.36 +#include <ctype.h> 1.37 +#include <string.h> 1.38 + 1.39 +#include "alMain.h" 1.40 + 1.41 +#ifdef _WIN32_IE 1.42 +#include <shlobj.h> 1.43 +#endif 1.44 + 1.45 +typedef struct ConfigEntry { 1.46 + char *key; 1.47 + char *value; 1.48 +} ConfigEntry; 1.49 + 1.50 +typedef struct ConfigBlock { 1.51 + char *name; 1.52 + ConfigEntry *entries; 1.53 + size_t entryCount; 1.54 +} ConfigBlock; 1.55 + 1.56 +static ConfigBlock *cfgBlocks; 1.57 +static size_t cfgCount; 1.58 + 1.59 +static char buffer[1024]; 1.60 + 1.61 +static void LoadConfigFromFile(FILE *f) 1.62 +{ 1.63 + ConfigBlock *curBlock = cfgBlocks; 1.64 + ConfigEntry *ent; 1.65 + 1.66 + while(fgets(buffer, sizeof(buffer), f)) 1.67 + { 1.68 + size_t i = 0; 1.69 + 1.70 + while(isspace(buffer[i])) 1.71 + i++; 1.72 + if(!buffer[i] || buffer[i] == '#') 1.73 + continue; 1.74 + 1.75 + memmove(buffer, buffer+i, strlen(buffer+i)+1); 1.76 + 1.77 + if(buffer[0] == '[') 1.78 + { 1.79 + ConfigBlock *nextBlock; 1.80 + 1.81 + i = 1; 1.82 + while(buffer[i] && buffer[i] != ']') 1.83 + i++; 1.84 + 1.85 + if(!buffer[i]) 1.86 + { 1.87 + ERR("config parse error: bad line \"%s\"\n", buffer); 1.88 + continue; 1.89 + } 1.90 + buffer[i] = 0; 1.91 + 1.92 + do { 1.93 + i++; 1.94 + if(buffer[i] && !isspace(buffer[i])) 1.95 + { 1.96 + if(buffer[i] != '#') 1.97 + WARN("config warning: extra data after block: \"%s\"\n", buffer+i); 1.98 + break; 1.99 + } 1.100 + } while(buffer[i]); 1.101 + 1.102 + nextBlock = NULL; 1.103 + for(i = 0;i < cfgCount;i++) 1.104 + { 1.105 + if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0) 1.106 + { 1.107 + nextBlock = cfgBlocks+i; 1.108 + TRACE("found block '%s'\n", nextBlock->name); 1.109 + break; 1.110 + } 1.111 + } 1.112 + 1.113 + if(!nextBlock) 1.114 + { 1.115 + nextBlock = realloc(cfgBlocks, (cfgCount+1)*sizeof(ConfigBlock)); 1.116 + if(!nextBlock) 1.117 + { 1.118 + ERR("config parse error: error reallocating config blocks\n"); 1.119 + continue; 1.120 + } 1.121 + cfgBlocks = nextBlock; 1.122 + nextBlock = cfgBlocks+cfgCount; 1.123 + cfgCount++; 1.124 + 1.125 + nextBlock->name = strdup(buffer+1); 1.126 + nextBlock->entries = NULL; 1.127 + nextBlock->entryCount = 0; 1.128 + 1.129 + TRACE("found new block '%s'\n", nextBlock->name); 1.130 + } 1.131 + curBlock = nextBlock; 1.132 + continue; 1.133 + } 1.134 + 1.135 + /* Look for the option name */ 1.136 + i = 0; 1.137 + while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' && 1.138 + !isspace(buffer[i])) 1.139 + i++; 1.140 + 1.141 + if(!buffer[i] || buffer[i] == '#' || i == 0) 1.142 + { 1.143 + ERR("config parse error: malformed option line: \"%s\"\n", buffer); 1.144 + continue; 1.145 + } 1.146 + 1.147 + /* Seperate the option */ 1.148 + if(buffer[i] != '=') 1.149 + { 1.150 + buffer[i++] = 0; 1.151 + 1.152 + while(isspace(buffer[i])) 1.153 + i++; 1.154 + if(buffer[i] != '=') 1.155 + { 1.156 + ERR("config parse error: option without a value: \"%s\"\n", buffer); 1.157 + continue; 1.158 + } 1.159 + } 1.160 + /* Find the start of the value */ 1.161 + buffer[i++] = 0; 1.162 + while(isspace(buffer[i])) 1.163 + i++; 1.164 + 1.165 + /* Check if we already have this option set */ 1.166 + ent = curBlock->entries; 1.167 + while((size_t)(ent-curBlock->entries) < curBlock->entryCount) 1.168 + { 1.169 + if(strcasecmp(ent->key, buffer) == 0) 1.170 + break; 1.171 + ent++; 1.172 + } 1.173 + 1.174 + if((size_t)(ent-curBlock->entries) >= curBlock->entryCount) 1.175 + { 1.176 + /* Allocate a new option entry */ 1.177 + ent = realloc(curBlock->entries, (curBlock->entryCount+1)*sizeof(ConfigEntry)); 1.178 + if(!ent) 1.179 + { 1.180 + ERR("config parse error: error reallocating config entries\n"); 1.181 + continue; 1.182 + } 1.183 + curBlock->entries = ent; 1.184 + ent = curBlock->entries + curBlock->entryCount; 1.185 + curBlock->entryCount++; 1.186 + 1.187 + ent->key = strdup(buffer); 1.188 + ent->value = NULL; 1.189 + } 1.190 + 1.191 + /* Look for the end of the line (Null term, new-line, or #-symbol) and 1.192 + eat up the trailing whitespace */ 1.193 + memmove(buffer, buffer+i, strlen(buffer+i)+1); 1.194 + 1.195 + i = 0; 1.196 + while(buffer[i] && buffer[i] != '#' && buffer[i] != '\n') 1.197 + i++; 1.198 + do { 1.199 + i--; 1.200 + } while(isspace(buffer[i])); 1.201 + buffer[++i] = 0; 1.202 + 1.203 + free(ent->value); 1.204 + ent->value = strdup(buffer); 1.205 + 1.206 + TRACE("found '%s' = '%s'\n", ent->key, ent->value); 1.207 + } 1.208 +} 1.209 + 1.210 +void ReadALConfig(void) 1.211 +{ 1.212 + const char *str; 1.213 + FILE *f; 1.214 + 1.215 + cfgBlocks = calloc(1, sizeof(ConfigBlock)); 1.216 + cfgBlocks->name = strdup("general"); 1.217 + cfgCount = 1; 1.218 + 1.219 +#ifdef _WIN32 1.220 + if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE) 1.221 + { 1.222 + size_t p = strlen(buffer); 1.223 + snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini"); 1.224 + f = fopen(buffer, "rt"); 1.225 + if(f) 1.226 + { 1.227 + LoadConfigFromFile(f); 1.228 + fclose(f); 1.229 + } 1.230 + } 1.231 +#else 1.232 + f = fopen("/etc/openal/alsoft.conf", "r"); 1.233 + if(f) 1.234 + { 1.235 + LoadConfigFromFile(f); 1.236 + fclose(f); 1.237 + } 1.238 + if((str=getenv("HOME")) != NULL && *str) 1.239 + { 1.240 + snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str); 1.241 + f = fopen(buffer, "r"); 1.242 + if(f) 1.243 + { 1.244 + LoadConfigFromFile(f); 1.245 + fclose(f); 1.246 + } 1.247 + } 1.248 +#endif 1.249 + if((str=getenv("ALSOFT_CONF")) != NULL && *str) 1.250 + { 1.251 + f = fopen(str, "r"); 1.252 + if(f) 1.253 + { 1.254 + LoadConfigFromFile(f); 1.255 + fclose(f); 1.256 + } 1.257 + } 1.258 +} 1.259 + 1.260 +void FreeALConfig(void) 1.261 +{ 1.262 + size_t i; 1.263 + 1.264 + for(i = 0;i < cfgCount;i++) 1.265 + { 1.266 + size_t j; 1.267 + for(j = 0;j < cfgBlocks[i].entryCount;j++) 1.268 + { 1.269 + free(cfgBlocks[i].entries[j].key); 1.270 + free(cfgBlocks[i].entries[j].value); 1.271 + } 1.272 + free(cfgBlocks[i].entries); 1.273 + free(cfgBlocks[i].name); 1.274 + } 1.275 + free(cfgBlocks); 1.276 + cfgBlocks = NULL; 1.277 + cfgCount = 0; 1.278 +} 1.279 + 1.280 +const char *GetConfigValue(const char *blockName, const char *keyName, const char *def) 1.281 +{ 1.282 + size_t i, j; 1.283 + 1.284 + if(!keyName) 1.285 + return def; 1.286 + 1.287 + if(!blockName) 1.288 + blockName = "general"; 1.289 + 1.290 + for(i = 0;i < cfgCount;i++) 1.291 + { 1.292 + if(strcasecmp(cfgBlocks[i].name, blockName) != 0) 1.293 + continue; 1.294 + 1.295 + for(j = 0;j < cfgBlocks[i].entryCount;j++) 1.296 + { 1.297 + if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0) 1.298 + { 1.299 + TRACE("Found %s:%s = \"%s\"\n", blockName, keyName, 1.300 + cfgBlocks[i].entries[j].value); 1.301 + if(cfgBlocks[i].entries[j].value[0]) 1.302 + return cfgBlocks[i].entries[j].value; 1.303 + return def; 1.304 + } 1.305 + } 1.306 + } 1.307 + 1.308 + TRACE("Key %s:%s not found\n", blockName, keyName); 1.309 + return def; 1.310 +} 1.311 + 1.312 +int ConfigValueExists(const char *blockName, const char *keyName) 1.313 +{ 1.314 + const char *val = GetConfigValue(blockName, keyName, ""); 1.315 + return !!val[0]; 1.316 +} 1.317 + 1.318 +int GetConfigValueInt(const char *blockName, const char *keyName, int def) 1.319 +{ 1.320 + const char *val = GetConfigValue(blockName, keyName, ""); 1.321 + 1.322 + if(!val[0]) return def; 1.323 + return strtol(val, NULL, 0); 1.324 +} 1.325 + 1.326 +float GetConfigValueFloat(const char *blockName, const char *keyName, float def) 1.327 +{ 1.328 + const char *val = GetConfigValue(blockName, keyName, ""); 1.329 + 1.330 + if(!val[0]) return def; 1.331 +#ifdef HAVE_STRTOF 1.332 + return strtof(val, NULL); 1.333 +#else 1.334 + return (float)strtod(val, NULL); 1.335 +#endif 1.336 +} 1.337 + 1.338 +int GetConfigValueBool(const char *blockName, const char *keyName, int def) 1.339 +{ 1.340 + const char *val = GetConfigValue(blockName, keyName, ""); 1.341 + 1.342 + if(!val[0]) return !!def; 1.343 + return (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0 || 1.344 + strcasecmp(val, "on") == 0 || atoi(val) != 0); 1.345 +}