Mercurial > audio-send
view Alc/alcConfig.c @ 1:c41d773a85fb
moved org files, ignored html files
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 25 Oct 2011 13:03:35 -0700 |
parents | f9476ff7637e |
children |
line wrap: on
line source
1 /**2 * OpenAL cross platform audio library3 * Copyright (C) 1999-2007 by authors.4 * This library is free software; you can redistribute it and/or5 * modify it under the terms of the GNU Library General Public6 * License as published by the Free Software Foundation; either7 * version 2 of the License, or (at your option) any later version.8 *9 * This library is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 * Library General Public License for more details.13 *14 * You should have received a copy of the GNU Library General Public15 * License along with this library; if not, write to the16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,17 * Boston, MA 02111-1307, USA.18 * Or go to http://www.gnu.org/copyleft/lgpl.html19 */21 #ifdef _WIN3222 #ifdef __MINGW64__23 #define _WIN32_IE 0x50124 #else25 #define _WIN32_IE 0x40026 #endif27 #endif29 #include "config.h"31 #include <stdlib.h>32 #include <stdio.h>33 #include <ctype.h>34 #include <string.h>36 #include "alMain.h"38 #ifdef _WIN32_IE39 #include <shlobj.h>40 #endif42 typedef struct ConfigEntry {43 char *key;44 char *value;45 } ConfigEntry;47 typedef struct ConfigBlock {48 char *name;49 ConfigEntry *entries;50 size_t entryCount;51 } ConfigBlock;53 static ConfigBlock *cfgBlocks;54 static size_t cfgCount;56 static char buffer[1024];58 static void LoadConfigFromFile(FILE *f)59 {60 ConfigBlock *curBlock = cfgBlocks;61 ConfigEntry *ent;63 while(fgets(buffer, sizeof(buffer), f))64 {65 size_t i = 0;67 while(isspace(buffer[i]))68 i++;69 if(!buffer[i] || buffer[i] == '#')70 continue;72 memmove(buffer, buffer+i, strlen(buffer+i)+1);74 if(buffer[0] == '[')75 {76 ConfigBlock *nextBlock;78 i = 1;79 while(buffer[i] && buffer[i] != ']')80 i++;82 if(!buffer[i])83 {84 ERR("config parse error: bad line \"%s\"\n", buffer);85 continue;86 }87 buffer[i] = 0;89 do {90 i++;91 if(buffer[i] && !isspace(buffer[i]))92 {93 if(buffer[i] != '#')94 WARN("config warning: extra data after block: \"%s\"\n", buffer+i);95 break;96 }97 } while(buffer[i]);99 nextBlock = NULL;100 for(i = 0;i < cfgCount;i++)101 {102 if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0)103 {104 nextBlock = cfgBlocks+i;105 TRACE("found block '%s'\n", nextBlock->name);106 break;107 }108 }110 if(!nextBlock)111 {112 nextBlock = realloc(cfgBlocks, (cfgCount+1)*sizeof(ConfigBlock));113 if(!nextBlock)114 {115 ERR("config parse error: error reallocating config blocks\n");116 continue;117 }118 cfgBlocks = nextBlock;119 nextBlock = cfgBlocks+cfgCount;120 cfgCount++;122 nextBlock->name = strdup(buffer+1);123 nextBlock->entries = NULL;124 nextBlock->entryCount = 0;126 TRACE("found new block '%s'\n", nextBlock->name);127 }128 curBlock = nextBlock;129 continue;130 }132 /* Look for the option name */133 i = 0;134 while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' &&135 !isspace(buffer[i]))136 i++;138 if(!buffer[i] || buffer[i] == '#' || i == 0)139 {140 ERR("config parse error: malformed option line: \"%s\"\n", buffer);141 continue;142 }144 /* Seperate the option */145 if(buffer[i] != '=')146 {147 buffer[i++] = 0;149 while(isspace(buffer[i]))150 i++;151 if(buffer[i] != '=')152 {153 ERR("config parse error: option without a value: \"%s\"\n", buffer);154 continue;155 }156 }157 /* Find the start of the value */158 buffer[i++] = 0;159 while(isspace(buffer[i]))160 i++;162 /* Check if we already have this option set */163 ent = curBlock->entries;164 while((size_t)(ent-curBlock->entries) < curBlock->entryCount)165 {166 if(strcasecmp(ent->key, buffer) == 0)167 break;168 ent++;169 }171 if((size_t)(ent-curBlock->entries) >= curBlock->entryCount)172 {173 /* Allocate a new option entry */174 ent = realloc(curBlock->entries, (curBlock->entryCount+1)*sizeof(ConfigEntry));175 if(!ent)176 {177 ERR("config parse error: error reallocating config entries\n");178 continue;179 }180 curBlock->entries = ent;181 ent = curBlock->entries + curBlock->entryCount;182 curBlock->entryCount++;184 ent->key = strdup(buffer);185 ent->value = NULL;186 }188 /* Look for the end of the line (Null term, new-line, or #-symbol) and189 eat up the trailing whitespace */190 memmove(buffer, buffer+i, strlen(buffer+i)+1);192 i = 0;193 while(buffer[i] && buffer[i] != '#' && buffer[i] != '\n')194 i++;195 do {196 i--;197 } while(isspace(buffer[i]));198 buffer[++i] = 0;200 free(ent->value);201 ent->value = strdup(buffer);203 TRACE("found '%s' = '%s'\n", ent->key, ent->value);204 }205 }207 void ReadALConfig(void)208 {209 const char *str;210 FILE *f;212 cfgBlocks = calloc(1, sizeof(ConfigBlock));213 cfgBlocks->name = strdup("general");214 cfgCount = 1;216 #ifdef _WIN32217 if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE)218 {219 size_t p = strlen(buffer);220 snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini");221 f = fopen(buffer, "rt");222 if(f)223 {224 LoadConfigFromFile(f);225 fclose(f);226 }227 }228 #else229 f = fopen("/etc/openal/alsoft.conf", "r");230 if(f)231 {232 LoadConfigFromFile(f);233 fclose(f);234 }235 if((str=getenv("HOME")) != NULL && *str)236 {237 snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str);238 f = fopen(buffer, "r");239 if(f)240 {241 LoadConfigFromFile(f);242 fclose(f);243 }244 }245 #endif246 if((str=getenv("ALSOFT_CONF")) != NULL && *str)247 {248 f = fopen(str, "r");249 if(f)250 {251 LoadConfigFromFile(f);252 fclose(f);253 }254 }255 }257 void FreeALConfig(void)258 {259 size_t i;261 for(i = 0;i < cfgCount;i++)262 {263 size_t j;264 for(j = 0;j < cfgBlocks[i].entryCount;j++)265 {266 free(cfgBlocks[i].entries[j].key);267 free(cfgBlocks[i].entries[j].value);268 }269 free(cfgBlocks[i].entries);270 free(cfgBlocks[i].name);271 }272 free(cfgBlocks);273 cfgBlocks = NULL;274 cfgCount = 0;275 }277 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def)278 {279 size_t i, j;281 if(!keyName)282 return def;284 if(!blockName)285 blockName = "general";287 for(i = 0;i < cfgCount;i++)288 {289 if(strcasecmp(cfgBlocks[i].name, blockName) != 0)290 continue;292 for(j = 0;j < cfgBlocks[i].entryCount;j++)293 {294 if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0)295 {296 TRACE("Found %s:%s = \"%s\"\n", blockName, keyName,297 cfgBlocks[i].entries[j].value);298 if(cfgBlocks[i].entries[j].value[0])299 return cfgBlocks[i].entries[j].value;300 return def;301 }302 }303 }305 TRACE("Key %s:%s not found\n", blockName, keyName);306 return def;307 }309 int ConfigValueExists(const char *blockName, const char *keyName)310 {311 const char *val = GetConfigValue(blockName, keyName, "");312 return !!val[0];313 }315 int GetConfigValueInt(const char *blockName, const char *keyName, int def)316 {317 const char *val = GetConfigValue(blockName, keyName, "");319 if(!val[0]) return def;320 return strtol(val, NULL, 0);321 }323 float GetConfigValueFloat(const char *blockName, const char *keyName, float def)324 {325 const char *val = GetConfigValue(blockName, keyName, "");327 if(!val[0]) return def;328 #ifdef HAVE_STRTOF329 return strtof(val, NULL);330 #else331 return (float)strtod(val, NULL);332 #endif333 }335 int GetConfigValueBool(const char *blockName, const char *keyName, int def)336 {337 const char *val = GetConfigValue(blockName, keyName, "");339 if(!val[0]) return !!def;340 return (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0 ||341 strcasecmp(val, "on") == 0 || atoi(val) != 0);342 }