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
22 #define _WIN32_IE 0x400
38 typedef struct ConfigEntry
{
43 typedef struct ConfigBlock
{
49 static ConfigBlock
*cfgBlocks
;
50 static size_t cfgCount
;
52 static char buffer
[1024];
54 static void LoadConfigFromFile(FILE *f
)
56 ConfigBlock
*curBlock
= cfgBlocks
;
59 while(fgets(buffer
, sizeof(buffer
), f
))
63 while(isspace(buffer
[i
]))
65 if(!buffer
[i
] || buffer
[i
] == '#')
68 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
72 ConfigBlock
*nextBlock
;
75 while(buffer
[i
] && buffer
[i
] != ']')
80 AL_PRINT("config parse error: bad line \"%s\"\n", buffer
);
87 if(buffer
[i
] && !isspace(buffer
[i
]))
90 AL_PRINT("config warning: extra data after block: \"%s\"\n", buffer
+i
);
96 for(i
= 0;i
< cfgCount
;i
++)
98 if(strcasecmp(cfgBlocks
[i
].name
, buffer
+1) == 0)
100 nextBlock
= cfgBlocks
+i
;
101 // AL_PRINT("found block '%s'\n", nextBlock->name);
108 nextBlock
= realloc(cfgBlocks
, (cfgCount
+1)*sizeof(ConfigBlock
));
111 AL_PRINT("config parse error: error reallocating config blocks\n");
114 cfgBlocks
= nextBlock
;
115 nextBlock
= cfgBlocks
+cfgCount
;
118 nextBlock
->name
= strdup(buffer
+1);
119 nextBlock
->entries
= NULL
;
120 nextBlock
->entryCount
= 0;
122 // AL_PRINT("found new block '%s'\n", nextBlock->name);
124 curBlock
= nextBlock
;
128 /* Look for the option name */
130 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '=' &&
134 if(!buffer
[i
] || buffer
[i
] == '#' || i
== 0)
136 AL_PRINT("config parse error: malformed option line: \"%s\"\n", buffer
);
140 /* Seperate the option */
145 while(isspace(buffer
[i
]))
149 AL_PRINT("config parse error: option without a value: \"%s\"\n", buffer
);
153 /* Find the start of the value */
155 while(isspace(buffer
[i
]))
158 /* Check if we already have this option set */
159 ent
= curBlock
->entries
;
160 while((size_t)(ent
-curBlock
->entries
) < curBlock
->entryCount
)
162 if(strcasecmp(ent
->key
, buffer
) == 0)
167 if((size_t)(ent
-curBlock
->entries
) >= curBlock
->entryCount
)
169 /* Allocate a new option entry */
170 ent
= realloc(curBlock
->entries
, (curBlock
->entryCount
+1)*sizeof(ConfigEntry
));
173 AL_PRINT("config parse error: error reallocating config entries\n");
176 curBlock
->entries
= ent
;
177 ent
= curBlock
->entries
+ curBlock
->entryCount
;
178 curBlock
->entryCount
++;
180 ent
->key
= strdup(buffer
);
184 /* Look for the end of the line (Null term, new-line, or #-symbol) and
185 eat up the trailing whitespace */
186 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
189 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '\n')
193 } while(isspace(buffer
[i
]));
197 ent
->value
= strdup(buffer
);
199 // AL_PRINT("found '%s' = '%s'\n", ent->key, ent->value);
203 void ReadALConfig(void)
207 cfgBlocks
= calloc(1, sizeof(ConfigBlock
));
208 cfgBlocks
->name
= strdup("general");
212 if(SHGetSpecialFolderPathA(NULL
, buffer
, CSIDL_APPDATA
, FALSE
) != FALSE
)
214 int p
= strlen(buffer
);
215 snprintf(buffer
+p
, sizeof(buffer
)-p
, "\\alsoft.ini");
216 f
= fopen(buffer
, "rt");
219 LoadConfigFromFile(f
);
224 f
= fopen("/etc/openal/alsoft.conf", "r");
227 LoadConfigFromFile(f
);
230 if(getenv("HOME") && *(getenv("HOME")))
232 snprintf(buffer
, sizeof(buffer
), "%s/.alsoftrc", getenv("HOME"));
233 f
= fopen(buffer
, "r");
236 LoadConfigFromFile(f
);
241 if(getenv("ALSOFT_CONF"))
243 f
= fopen(getenv("ALSOFT_CONF"), "r");
246 LoadConfigFromFile(f
);
252 void FreeALConfig(void)
256 for(i
= 0;i
< cfgCount
;i
++)
259 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
261 free(cfgBlocks
[i
].entries
[j
].key
);
262 free(cfgBlocks
[i
].entries
[j
].value
);
264 free(cfgBlocks
[i
].entries
);
265 free(cfgBlocks
[i
].name
);
272 const char *GetConfigValue(const char *blockName
, const char *keyName
, const char *def
)
279 blockName
= "general";
281 for(i
= 0;i
< cfgCount
;i
++)
283 if(strcasecmp(cfgBlocks
[i
].name
, blockName
) != 0)
286 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
288 if(strcasecmp(cfgBlocks
[i
].entries
[j
].key
, keyName
) == 0)
289 return cfgBlocks
[i
].entries
[j
].value
;
297 int GetConfigValueInt(const char *blockName
, const char *keyName
, int def
)
299 const char *val
= GetConfigValue(blockName
, keyName
, "");
301 if(!val
[0]) return def
;
302 return strtol(val
, NULL
, 0);
305 float GetConfigValueFloat(const char *blockName
, const char *keyName
, float def
)
307 const char *val
= GetConfigValue(blockName
, keyName
, "");
309 if(!val
[0]) return def
;
311 return strtof(val
, NULL
);
313 return (float)strtod(val
, NULL
);