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.
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.
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
21 #if defined(_WIN32) && (_WIN32_IE < 0x400)
23 #define _WIN32_IE 0x400
39 typedef struct ConfigEntry
{
44 typedef struct ConfigBlock
{
50 static ConfigBlock
*cfgBlocks
;
51 static size_t cfgCount
;
53 static char buffer
[1024];
55 static void LoadConfigFromFile(FILE *f
)
57 ConfigBlock
*curBlock
= cfgBlocks
;
60 while(fgets(buffer
, sizeof(buffer
), f
))
64 while(isspace(buffer
[i
]))
66 if(!buffer
[i
] || buffer
[i
] == '#')
69 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
73 ConfigBlock
*nextBlock
;
76 while(buffer
[i
] && buffer
[i
] != ']')
81 AL_PRINT("config parse error: bad line \"%s\"\n", buffer
);
88 if(buffer
[i
] && !isspace(buffer
[i
]))
91 AL_PRINT("config warning: extra data after block: \"%s\"\n", buffer
+i
);
97 for(i
= 0;i
< cfgCount
;i
++)
99 if(strcasecmp(cfgBlocks
[i
].name
, buffer
+1) == 0)
101 nextBlock
= cfgBlocks
+i
;
102 // AL_PRINT("found block '%s'\n", nextBlock->name);
109 nextBlock
= realloc(cfgBlocks
, (cfgCount
+1)*sizeof(ConfigBlock
));
112 AL_PRINT("config parse error: error reallocating config blocks\n");
115 cfgBlocks
= nextBlock
;
116 nextBlock
= cfgBlocks
+cfgCount
;
119 nextBlock
->name
= strdup(buffer
+1);
120 nextBlock
->entries
= NULL
;
121 nextBlock
->entryCount
= 0;
123 // AL_PRINT("found new block '%s'\n", nextBlock->name);
125 curBlock
= nextBlock
;
129 /* Look for the option name */
131 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '=' &&
135 if(!buffer
[i
] || buffer
[i
] == '#' || i
== 0)
137 AL_PRINT("config parse error: malformed option line: \"%s\"\n", buffer
);
141 /* Seperate the option */
146 while(isspace(buffer
[i
]))
150 AL_PRINT("config parse error: option without a value: \"%s\"\n", buffer
);
154 /* Find the start of the value */
156 while(isspace(buffer
[i
]))
159 /* Check if we already have this option set */
160 ent
= curBlock
->entries
;
161 while((size_t)(ent
-curBlock
->entries
) < curBlock
->entryCount
)
163 if(strcasecmp(ent
->key
, buffer
) == 0)
168 if((size_t)(ent
-curBlock
->entries
) >= curBlock
->entryCount
)
170 /* Allocate a new option entry */
171 ent
= realloc(curBlock
->entries
, (curBlock
->entryCount
+1)*sizeof(ConfigEntry
));
174 AL_PRINT("config parse error: error reallocating config entries\n");
177 curBlock
->entries
= ent
;
178 ent
= curBlock
->entries
+ curBlock
->entryCount
;
179 curBlock
->entryCount
++;
181 ent
->key
= strdup(buffer
);
185 /* Look for the end of the line (Null term, new-line, or #-symbol) and
186 eat up the trailing whitespace */
187 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
190 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '\n')
194 } while(isspace(buffer
[i
]));
198 ent
->value
= strdup(buffer
);
200 // AL_PRINT("found '%s' = '%s'\n", ent->key, ent->value);
204 void ReadALConfig(void)
208 cfgBlocks
= calloc(1, sizeof(ConfigBlock
));
209 cfgBlocks
->name
= strdup("general");
213 if(SHGetSpecialFolderPathA(NULL
, buffer
, CSIDL_APPDATA
, FALSE
) != FALSE
)
215 size_t p
= strlen(buffer
);
216 snprintf(buffer
+p
, sizeof(buffer
)-p
, "\\alsoft.ini");
217 f
= fopen(buffer
, "rt");
220 LoadConfigFromFile(f
);
225 f
= fopen("/etc/openal/alsoft.conf", "r");
228 LoadConfigFromFile(f
);
231 if(getenv("HOME") && *(getenv("HOME")))
233 snprintf(buffer
, sizeof(buffer
), "%s/.alsoftrc", getenv("HOME"));
234 f
= fopen(buffer
, "r");
237 LoadConfigFromFile(f
);
242 if(getenv("ALSOFT_CONF"))
244 f
= fopen(getenv("ALSOFT_CONF"), "r");
247 LoadConfigFromFile(f
);
253 void FreeALConfig(void)
257 for(i
= 0;i
< cfgCount
;i
++)
260 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
262 free(cfgBlocks
[i
].entries
[j
].key
);
263 free(cfgBlocks
[i
].entries
[j
].value
);
265 free(cfgBlocks
[i
].entries
);
266 free(cfgBlocks
[i
].name
);
273 const char *GetConfigValue(const char *blockName
, const char *keyName
, const char *def
)
280 blockName
= "general";
282 for(i
= 0;i
< cfgCount
;i
++)
284 if(strcasecmp(cfgBlocks
[i
].name
, blockName
) != 0)
287 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
289 if(strcasecmp(cfgBlocks
[i
].entries
[j
].key
, keyName
) == 0)
291 if(cfgBlocks
[i
].entries
[j
].value
[0])
292 return cfgBlocks
[i
].entries
[j
].value
;
302 int ConfigValueExists(const char *blockName
, const char *keyName
)
304 const char *val
= GetConfigValue(blockName
, keyName
, "");
308 int GetConfigValueInt(const char *blockName
, const char *keyName
, int def
)
310 const char *val
= GetConfigValue(blockName
, keyName
, "");
312 if(!val
[0]) return def
;
313 return strtol(val
, NULL
, 0);
316 float GetConfigValueFloat(const char *blockName
, const char *keyName
, float def
)
318 const char *val
= GetConfigValue(blockName
, keyName
, "");
320 if(!val
[0]) return def
;
322 return strtof(val
, NULL
);
324 return (float)strtod(val
, NULL
);
328 int GetConfigValueBool(const char *blockName
, const char *keyName
, int def
)
330 const char *val
= GetConfigValue(blockName
, keyName
, "");
332 if(!val
[0]) return !!def
;
333 return (strcasecmp(val
, "true") == 0 || strcasecmp(val
, "yes") == 0 ||
334 strcasecmp(val
, "on") == 0 || atoi(val
) != 0);