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
28 typedef struct ConfigEntry
{
33 typedef struct ConfigBlock
{
39 static ConfigBlock
*cfgBlocks
;
40 static size_t cfgCount
;
42 static char buffer
[1024];
44 static void LoadConfigFromFile(FILE *f
)
46 ConfigBlock
*curBlock
= cfgBlocks
;
49 while(fgets(buffer
, sizeof(buffer
), f
))
53 while(isspace(buffer
[i
]))
55 if(!buffer
[i
] || buffer
[i
] == '#')
58 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
62 ConfigBlock
*nextBlock
;
65 while(buffer
[i
] && buffer
[i
] != ']')
70 AL_PRINT("config parse error: bad line \"%s\"\n", buffer
);
77 if(buffer
[i
] && !isspace(buffer
[i
]))
80 AL_PRINT("config warning: extra data after block: \"%s\"\n", buffer
+i
);
86 for(i
= 0;i
< cfgCount
;i
++)
88 if(strcasecmp(cfgBlocks
[i
].name
, buffer
+1) == 0)
90 nextBlock
= cfgBlocks
+i
;
91 // AL_PRINT("found block '%s'\n", nextBlock->name);
98 nextBlock
= realloc(cfgBlocks
, (cfgCount
+1)*sizeof(ConfigBlock
));
101 AL_PRINT("config parse error: error reallocating config blocks\n");
104 cfgBlocks
= nextBlock
;
105 nextBlock
= cfgBlocks
+cfgCount
;
108 nextBlock
->name
= strdup(buffer
+1);
109 nextBlock
->entries
= NULL
;
110 nextBlock
->entryCount
= 0;
112 // AL_PRINT("found new block '%s'\n", nextBlock->name);
114 curBlock
= nextBlock
;
118 /* Look for the option name */
120 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '=' &&
124 if(!buffer
[i
] || buffer
[i
] == '#' || i
== 0)
126 AL_PRINT("config parse error: malformed option line: \"%s\"\n", buffer
);
130 /* Seperate the option */
135 while(isspace(buffer
[i
]))
139 AL_PRINT("config parse error: option without a value: \"%s\"\n", buffer
);
143 /* Find the start of the value */
145 while(isspace(buffer
[i
]))
148 /* Check if we already have this option set */
149 ent
= curBlock
->entries
;
150 while((size_t)(ent
-curBlock
->entries
) < curBlock
->entryCount
)
152 if(strcasecmp(ent
->key
, buffer
) == 0)
157 if((size_t)(ent
-curBlock
->entries
) >= curBlock
->entryCount
)
159 /* Allocate a new option entry */
160 ent
= realloc(curBlock
->entries
, (curBlock
->entryCount
+1)*sizeof(ConfigEntry
));
163 AL_PRINT("config parse error: error reallocating config entries\n");
166 curBlock
->entries
= ent
;
167 ent
= curBlock
->entries
+ curBlock
->entryCount
;
168 curBlock
->entryCount
++;
170 ent
->key
= strdup(buffer
);
174 /* Look for the end of the line (Null term, new-line, or #-symbol) and
175 eat up the trailing whitespace */
176 memmove(buffer
, buffer
+i
, strlen(buffer
+i
)+1);
179 while(buffer
[i
] && buffer
[i
] != '#' && buffer
[i
] != '\n')
183 } while(isspace(buffer
[i
]));
187 ent
->value
= strdup(buffer
);
189 // AL_PRINT("found '%s' = '%s'\n", ent->key, ent->value);
193 void ReadALConfig(void)
197 cfgBlocks
= calloc(1, sizeof(ConfigBlock
));
198 cfgBlocks
->name
= strdup("general");
203 f
= fopen("/etc/openal/config", "r");
206 LoadConfigFromFile(f
);
209 if(getenv("HOME") && *(getenv("HOME")))
211 snprintf(buffer
, sizeof(buffer
), "%s/.openalrc", getenv("HOME"));
212 f
= fopen(buffer
, "r");
215 LoadConfigFromFile(f
);
222 void FreeALConfig(void)
226 for(i
= 0;i
< cfgCount
;i
++)
229 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
231 free(cfgBlocks
[i
].entries
[j
].key
);
232 free(cfgBlocks
[i
].entries
[j
].value
);
234 free(cfgBlocks
[i
].entries
);
235 free(cfgBlocks
[i
].name
);
242 const char *GetConfigValue(const char *blockName
, const char *keyName
, const char *def
)
249 blockName
= "general";
251 for(i
= 0;i
< cfgCount
;i
++)
253 if(strcasecmp(cfgBlocks
[i
].name
, blockName
) != 0)
256 for(j
= 0;j
< cfgBlocks
[i
].entryCount
;j
++)
258 if(strcasecmp(cfgBlocks
[i
].entries
[j
].key
, keyName
) == 0)
259 return cfgBlocks
[i
].entries
[j
].value
;
267 int GetConfigValueInt(const char *blockName
, const char *keyName
, int def
)
269 const char *val
= GetConfigValue(blockName
, keyName
, "");
271 if(!val
[0]) return def
;
272 return strtol(val
, NULL
, 0);
275 float GetConfigValueFloat(const char *blockName
, const char *keyName
, float def
)
277 const char *val
= GetConfigValue(blockName
, keyName
, "");
279 if(!val
[0]) return def
;
281 return strtof(val
, NULL
);
283 return (float)strtod(val
, NULL
);