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
31 #define _WIN32_IE 0x400
35 typedef struct ConfigEntry
{
40 typedef struct ConfigBlock
{
46 static ConfigBlock
*cfgBlocks
;
47 static size_t cfgCount
;
49 static char buffer
[1024];
51 static void LoadConfigFromFile(FILE *f
)
53 ConfigBlock
*curBlock
= cfgBlocks
;
56 while(fgets(buffer
, sizeof(buffer
), f
))
60 while(isspace(buffer
[i
]))
62 if(!buffer
[i
] || buffer
[i
] == '#')
65 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
69 ConfigBlock
*nextBlock
;
72 while(buffer
[i
] && buffer
[i
] != ']')
77 AL_PRINT("config parse error: bad line \"%s\"\n", buffer
);
84 if(buffer
[i
] && !isspace(buffer
[i
]))
87 AL_PRINT("config warning: extra data after block: \"%s\"\n", buffer
+i
);
93 for(i
= 0;i
< cfgCount
;i
++)
95 if(strcasecmp(cfgBlocks
[i
].name
, buffer
+1) == 0)
97 nextBlock
= cfgBlocks
+i
;
98 // AL_PRINT("found block '%s'\n", nextBlock->name);
105 nextBlock
= realloc(cfgBlocks
, (cfgCount
+1)*sizeof(ConfigBlock
));
108 AL_PRINT("config parse error: error reallocating config blocks\n");
111 cfgBlocks
= nextBlock
;
112 nextBlock
= cfgBlocks
+cfgCount
;
115 nextBlock
->name
= strdup(buffer
+1);
116 nextBlock
->entries
= NULL
;
117 nextBlock
->entryCount
= 0;
119 // AL_PRINT("found new block '%s'\n", nextBlock->name);
121 curBlock
= nextBlock
;
125 /* Look for the option name */
127 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '=' &&
131 if(!buffer
[i
] || buffer
[i
] == '#' || i
== 0)
133 AL_PRINT("config parse error: malformed option line: \"%s\"\n", buffer
);
137 /* Seperate the option */
142 while(isspace(buffer
[i
]))
146 AL_PRINT("config parse error: option without a value: \"%s\"\n", buffer
);
150 /* Find the start of the value */
152 while(isspace(buffer
[i
]))
155 /* Check if we already have this option set */
156 ent
= curBlock
->entries
;
157 while((size_t)(ent
-curBlock
->entries
) < curBlock
->entryCount
)
159 if(strcasecmp(ent
->key
, buffer
) == 0)
164 if((size_t)(ent
-curBlock
->entries
) >= curBlock
->entryCount
)
166 /* Allocate a new option entry */
167 ent
= realloc(curBlock
->entries
, (curBlock
->entryCount
+1)*sizeof(ConfigEntry
));
170 AL_PRINT("config parse error: error reallocating config entries\n");
173 curBlock
->entries
= ent
;
174 ent
= curBlock
->entries
+ curBlock
->entryCount
;
175 curBlock
->entryCount
++;
177 ent
->key
= strdup(buffer
);
181 /* Look for the end of the line (Null term, new-line, or #-symbol) and
182 eat up the trailing whitespace */
183 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
186 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '\n')
190 } while(isspace(buffer
[i
]));
194 ent
->value
= strdup(buffer
);
196 // AL_PRINT("found '%s' = '%s'\n", ent->key, ent->value);
200 void ReadALConfig(void)
204 cfgBlocks
= calloc(1, sizeof(ConfigBlock
));
205 cfgBlocks
->name
= strdup("general");
209 if(SHGetSpecialFolderPathA(NULL
, buffer
, CSIDL_APPDATA
, FALSE
) != FALSE
)
211 int p
= strlen(buffer
);
212 snprintf(buffer
+p
, sizeof(buffer
)-p
, "\\alsoft.ini");
213 f
= fopen(buffer
, "rt");
216 LoadConfigFromFile(f
);
221 f
= fopen("/etc/openal/alsoft.conf", "r");
224 f
= fopen("/etc/openal/config", "r");
226 AL_PRINT("Reading /etc/openal/config; this file is deprecated\n"
227 "\tPlease rename it to /etc/openal/alsoft.conf\n");
231 LoadConfigFromFile(f
);
234 if(getenv("HOME") && *(getenv("HOME")))
236 snprintf(buffer
, sizeof(buffer
), "%s/.alsoftrc", getenv("HOME"));
237 f
= fopen(buffer
, "r");
240 snprintf(buffer
, sizeof(buffer
), "%s/.openalrc", getenv("HOME"));
241 f
= fopen(buffer
, "r");
243 AL_PRINT("Reading ~/.openalrc; this file is deprecated\n"
244 "\tPlease rename it to ~/.alsoftrc\n");
248 LoadConfigFromFile(f
);
255 void FreeALConfig(void)
259 for(i
= 0;i
< cfgCount
;i
++)
262 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
264 free(cfgBlocks
[i
].entries
[j
].key
);
265 free(cfgBlocks
[i
].entries
[j
].value
);
267 free(cfgBlocks
[i
].entries
);
268 free(cfgBlocks
[i
].name
);
275 const char *GetConfigValue(const char *blockName
, const char *keyName
, const char *def
)
282 blockName
= "general";
284 for(i
= 0;i
< cfgCount
;i
++)
286 if(strcasecmp(cfgBlocks
[i
].name
, blockName
) != 0)
289 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
291 if(strcasecmp(cfgBlocks
[i
].entries
[j
].key
, keyName
) == 0)
292 return cfgBlocks
[i
].entries
[j
].value
;
300 int GetConfigValueInt(const char *blockName
, const char *keyName
, int def
)
302 const char *val
= GetConfigValue(blockName
, keyName
, "");
304 if(!val
[0]) return def
;
305 return strtol(val
, NULL
, 0);
308 float GetConfigValueFloat(const char *blockName
, const char *keyName
, float def
)
310 const char *val
= GetConfigValue(blockName
, keyName
, "");
312 if(!val
[0]) return def
;
314 return strtof(val
, NULL
);
316 return (float)strtod(val
, NULL
);