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
23 #define _WIN32_IE 0x501
25 #define _WIN32_IE 0x400
42 typedef struct ConfigEntry
{
47 typedef struct ConfigBlock
{
50 unsigned int entryCount
;
53 static ConfigBlock
*cfgBlocks
;
54 static unsigned int cfgCount
;
56 static char buffer
[1024];
58 static void LoadConfigFromFile(FILE *f
)
60 ConfigBlock
*curBlock
= cfgBlocks
;
63 while(fgets(buffer
, sizeof(buffer
), f
))
67 while(isspace(buffer
[i
]))
69 if(!buffer
[i
] || buffer
[i
] == '#')
72 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
76 ConfigBlock
*nextBlock
;
80 while(buffer
[i
] && buffer
[i
] != ']')
85 ERR("config parse error: bad line \"%s\"\n", buffer
);
92 if(buffer
[i
] && !isspace(buffer
[i
]))
95 WARN("config warning: extra data after block: \"%s\"\n", buffer
+i
);
101 for(i
= 0;i
< cfgCount
;i
++)
103 if(strcasecmp(cfgBlocks
[i
].name
, buffer
+1) == 0)
105 nextBlock
= cfgBlocks
+i
;
106 TRACE("found block '%s'\n", nextBlock
->name
);
113 nextBlock
= realloc(cfgBlocks
, (cfgCount
+1)*sizeof(ConfigBlock
));
116 ERR("config parse error: error reallocating config blocks\n");
119 cfgBlocks
= nextBlock
;
120 nextBlock
= cfgBlocks
+cfgCount
;
123 nextBlock
->name
= strdup(buffer
+1);
124 nextBlock
->entries
= NULL
;
125 nextBlock
->entryCount
= 0;
127 TRACE("found new block '%s'\n", nextBlock
->name
);
129 curBlock
= nextBlock
;
133 /* Look for the option name */
135 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '=' &&
139 if(!buffer
[i
] || buffer
[i
] == '#' || i
== 0)
141 ERR("config parse error: malformed option line: \"%s\"\n", buffer
);
145 /* Seperate the option */
150 while(isspace(buffer
[i
]))
154 ERR("config parse error: option without a value: \"%s\"\n", buffer
);
158 /* Find the start of the value */
160 while(isspace(buffer
[i
]))
163 /* Check if we already have this option set */
164 ent
= curBlock
->entries
;
165 while((unsigned int)(ent
-curBlock
->entries
) < curBlock
->entryCount
)
167 if(strcasecmp(ent
->key
, buffer
) == 0)
172 if((unsigned int)(ent
-curBlock
->entries
) >= curBlock
->entryCount
)
174 /* Allocate a new option entry */
175 ent
= realloc(curBlock
->entries
, (curBlock
->entryCount
+1)*sizeof(ConfigEntry
));
178 ERR("config parse error: error reallocating config entries\n");
181 curBlock
->entries
= ent
;
182 ent
= curBlock
->entries
+ curBlock
->entryCount
;
183 curBlock
->entryCount
++;
185 ent
->key
= strdup(buffer
);
189 /* Look for the end of the line (Null term, new-line, or #-symbol) and
190 eat up the trailing whitespace */
191 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
194 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '\n')
198 } while(i
>= 0 && isspace(buffer
[i
]));
202 ent
->value
= strdup(buffer
);
204 TRACE("found '%s' = '%s'\n", ent
->key
, ent
->value
);
208 void ReadALConfig(void)
213 cfgBlocks
= calloc(1, sizeof(ConfigBlock
));
214 cfgBlocks
->name
= strdup("general");
218 if(SHGetSpecialFolderPathA(NULL
, buffer
, CSIDL_APPDATA
, FALSE
) != FALSE
)
220 size_t p
= strlen(buffer
);
221 snprintf(buffer
+p
, sizeof(buffer
)-p
, "\\alsoft.ini");
222 f
= fopen(buffer
, "rt");
225 LoadConfigFromFile(f
);
230 f
= fopen("/etc/openal/alsoft.conf", "r");
233 LoadConfigFromFile(f
);
236 if((str
=getenv("HOME")) != NULL
&& *str
)
238 snprintf(buffer
, sizeof(buffer
), "%s/.alsoftrc", str
);
239 f
= fopen(buffer
, "r");
242 LoadConfigFromFile(f
);
247 if((str
=getenv("ALSOFT_CONF")) != NULL
&& *str
)
252 LoadConfigFromFile(f
);
258 void FreeALConfig(void)
262 for(i
= 0;i
< cfgCount
;i
++)
265 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
267 free(cfgBlocks
[i
].entries
[j
].key
);
268 free(cfgBlocks
[i
].entries
[j
].value
);
270 free(cfgBlocks
[i
].entries
);
271 free(cfgBlocks
[i
].name
);
278 const char *GetConfigValue(const char *blockName
, const char *keyName
, const char *def
)
286 blockName
= "general";
288 for(i
= 0;i
< cfgCount
;i
++)
290 if(strcasecmp(cfgBlocks
[i
].name
, blockName
) != 0)
293 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
295 if(strcasecmp(cfgBlocks
[i
].entries
[j
].key
, keyName
) == 0)
297 TRACE("Found %s:%s = \"%s\"\n", blockName
, keyName
,
298 cfgBlocks
[i
].entries
[j
].value
);
299 if(cfgBlocks
[i
].entries
[j
].value
[0])
300 return cfgBlocks
[i
].entries
[j
].value
;
306 TRACE("Key %s:%s not found\n", blockName
, keyName
);
310 int ConfigValueExists(const char *blockName
, const char *keyName
)
312 const char *val
= GetConfigValue(blockName
, keyName
, "");
316 int ConfigValueStr(const char *blockName
, const char *keyName
, const char **ret
)
318 const char *val
= GetConfigValue(blockName
, keyName
, "");
319 if(!val
[0]) return 0;
325 int ConfigValueInt(const char *blockName
, const char *keyName
, int *ret
)
327 const char *val
= GetConfigValue(blockName
, keyName
, "");
328 if(!val
[0]) return 0;
330 *ret
= strtol(val
, NULL
, 0);
334 int ConfigValueUInt(const char *blockName
, const char *keyName
, unsigned int *ret
)
336 const char *val
= GetConfigValue(blockName
, keyName
, "");
337 if(!val
[0]) return 0;
339 *ret
= strtoul(val
, NULL
, 0);
343 int ConfigValueFloat(const char *blockName
, const char *keyName
, float *ret
)
345 const char *val
= GetConfigValue(blockName
, keyName
, "");
346 if(!val
[0]) return 0;
349 *ret
= strtof(val
, NULL
);
351 *ret
= (float)strtod(val
, NULL
);
356 int GetConfigValueBool(const char *blockName
, const char *keyName
, int def
)
358 const char *val
= GetConfigValue(blockName
, keyName
, "");
360 if(!val
[0]) return !!def
;
361 return (strcasecmp(val
, "true") == 0 || strcasecmp(val
, "yes") == 0 ||
362 strcasecmp(val
, "on") == 0 || atoi(val
) != 0);