Mercurial > audio-send
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f9476ff7637e |
---|---|
1 /** | |
2 * OpenAL cross platform audio library | |
3 * Copyright (C) 1999-2007 by authors. | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * 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 of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public | |
15 * License along with this library; if not, write to the | |
16 * 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.html | |
19 */ | |
20 | |
21 #ifdef _WIN32 | |
22 #ifdef __MINGW64__ | |
23 #define _WIN32_IE 0x501 | |
24 #else | |
25 #define _WIN32_IE 0x400 | |
26 #endif | |
27 #endif | |
28 | |
29 #include "config.h" | |
30 | |
31 #include <stdlib.h> | |
32 #include <stdio.h> | |
33 #include <ctype.h> | |
34 #include <string.h> | |
35 | |
36 #include "alMain.h" | |
37 | |
38 #ifdef _WIN32_IE | |
39 #include <shlobj.h> | |
40 #endif | |
41 | |
42 typedef struct ConfigEntry { | |
43 char *key; | |
44 char *value; | |
45 } ConfigEntry; | |
46 | |
47 typedef struct ConfigBlock { | |
48 char *name; | |
49 ConfigEntry *entries; | |
50 size_t entryCount; | |
51 } ConfigBlock; | |
52 | |
53 static ConfigBlock *cfgBlocks; | |
54 static size_t cfgCount; | |
55 | |
56 static char buffer[1024]; | |
57 | |
58 static void LoadConfigFromFile(FILE *f) | |
59 { | |
60 ConfigBlock *curBlock = cfgBlocks; | |
61 ConfigEntry *ent; | |
62 | |
63 while(fgets(buffer, sizeof(buffer), f)) | |
64 { | |
65 size_t i = 0; | |
66 | |
67 while(isspace(buffer[i])) | |
68 i++; | |
69 if(!buffer[i] || buffer[i] == '#') | |
70 continue; | |
71 | |
72 memmove(buffer, buffer+i, strlen(buffer+i)+1); | |
73 | |
74 if(buffer[0] == '[') | |
75 { | |
76 ConfigBlock *nextBlock; | |
77 | |
78 i = 1; | |
79 while(buffer[i] && buffer[i] != ']') | |
80 i++; | |
81 | |
82 if(!buffer[i]) | |
83 { | |
84 ERR("config parse error: bad line \"%s\"\n", buffer); | |
85 continue; | |
86 } | |
87 buffer[i] = 0; | |
88 | |
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]); | |
98 | |
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 } | |
109 | |
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++; | |
121 | |
122 nextBlock->name = strdup(buffer+1); | |
123 nextBlock->entries = NULL; | |
124 nextBlock->entryCount = 0; | |
125 | |
126 TRACE("found new block '%s'\n", nextBlock->name); | |
127 } | |
128 curBlock = nextBlock; | |
129 continue; | |
130 } | |
131 | |
132 /* Look for the option name */ | |
133 i = 0; | |
134 while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' && | |
135 !isspace(buffer[i])) | |
136 i++; | |
137 | |
138 if(!buffer[i] || buffer[i] == '#' || i == 0) | |
139 { | |
140 ERR("config parse error: malformed option line: \"%s\"\n", buffer); | |
141 continue; | |
142 } | |
143 | |
144 /* Seperate the option */ | |
145 if(buffer[i] != '=') | |
146 { | |
147 buffer[i++] = 0; | |
148 | |
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++; | |
161 | |
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 } | |
170 | |
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++; | |
183 | |
184 ent->key = strdup(buffer); | |
185 ent->value = NULL; | |
186 } | |
187 | |
188 /* Look for the end of the line (Null term, new-line, or #-symbol) and | |
189 eat up the trailing whitespace */ | |
190 memmove(buffer, buffer+i, strlen(buffer+i)+1); | |
191 | |
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; | |
199 | |
200 free(ent->value); | |
201 ent->value = strdup(buffer); | |
202 | |
203 TRACE("found '%s' = '%s'\n", ent->key, ent->value); | |
204 } | |
205 } | |
206 | |
207 void ReadALConfig(void) | |
208 { | |
209 const char *str; | |
210 FILE *f; | |
211 | |
212 cfgBlocks = calloc(1, sizeof(ConfigBlock)); | |
213 cfgBlocks->name = strdup("general"); | |
214 cfgCount = 1; | |
215 | |
216 #ifdef _WIN32 | |
217 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 #else | |
229 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 #endif | |
246 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 } | |
256 | |
257 void FreeALConfig(void) | |
258 { | |
259 size_t i; | |
260 | |
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 } | |
276 | |
277 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def) | |
278 { | |
279 size_t i, j; | |
280 | |
281 if(!keyName) | |
282 return def; | |
283 | |
284 if(!blockName) | |
285 blockName = "general"; | |
286 | |
287 for(i = 0;i < cfgCount;i++) | |
288 { | |
289 if(strcasecmp(cfgBlocks[i].name, blockName) != 0) | |
290 continue; | |
291 | |
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 } | |
304 | |
305 TRACE("Key %s:%s not found\n", blockName, keyName); | |
306 return def; | |
307 } | |
308 | |
309 int ConfigValueExists(const char *blockName, const char *keyName) | |
310 { | |
311 const char *val = GetConfigValue(blockName, keyName, ""); | |
312 return !!val[0]; | |
313 } | |
314 | |
315 int GetConfigValueInt(const char *blockName, const char *keyName, int def) | |
316 { | |
317 const char *val = GetConfigValue(blockName, keyName, ""); | |
318 | |
319 if(!val[0]) return def; | |
320 return strtol(val, NULL, 0); | |
321 } | |
322 | |
323 float GetConfigValueFloat(const char *blockName, const char *keyName, float def) | |
324 { | |
325 const char *val = GetConfigValue(blockName, keyName, ""); | |
326 | |
327 if(!val[0]) return def; | |
328 #ifdef HAVE_STRTOF | |
329 return strtof(val, NULL); | |
330 #else | |
331 return (float)strtod(val, NULL); | |
332 #endif | |
333 } | |
334 | |
335 int GetConfigValueBool(const char *blockName, const char *keyName, int def) | |
336 { | |
337 const char *val = GetConfigValue(blockName, keyName, ""); | |
338 | |
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 } |