zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
alcConfig.c
Go to the documentation of this file.
1 
21 #ifdef _WIN32
22 #ifdef __MINGW32__
23 #define _WIN32_IE 0x501
24 #else
25 #define _WIN32_IE 0x400
26 #endif
27 #endif
28 
29 #include "config.h"
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <string.h>
35 
36 #include "alMain.h"
37 
38 #ifdef _WIN32_IE
39 #include <shlobj.h>
40 #endif
41 
42 typedef struct ConfigEntry {
43  char *key;
44  char *value;
45 } ConfigEntry;
46 
47 typedef struct ConfigBlock {
48  char *name;
50  unsigned int entryCount;
51 } ConfigBlock;
52 
54 static unsigned int cfgCount;
55 
56 static char buffer[1024];
57 
58 static void LoadConfigFromFile(FILE *f)
59 {
60  ConfigBlock *curBlock = cfgBlocks;
61  ConfigEntry *ent;
62 
63  while(fgets(buffer, sizeof(buffer), f))
64  {
65  int i = 0;
66 
67  while(isspace(buffer[i]))
68  i++;
69  if(!buffer[i] || buffer[i] == '#')
70  continue;
71 
72  memmove(buffer, buffer+i, strlen(buffer+i)+1);
73 
74  if(buffer[0] == '[')
75  {
76  ConfigBlock *nextBlock;
77  unsigned int i;
78 
79  i = 1;
80  while(buffer[i] && buffer[i] != ']')
81  i++;
82 
83  if(!buffer[i])
84  {
85  ERR("config parse error: bad line \"%s\"\n", buffer);
86  continue;
87  }
88  buffer[i] = 0;
89 
90  do {
91  i++;
92  if(buffer[i] && !isspace(buffer[i]))
93  {
94  if(buffer[i] != '#')
95  WARN("config warning: extra data after block: \"%s\"\n", buffer+i);
96  break;
97  }
98  } while(buffer[i]);
99 
100  nextBlock = NULL;
101  for(i = 0;i < cfgCount;i++)
102  {
103  if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0)
104  {
105  nextBlock = cfgBlocks+i;
106  TRACE("found block '%s'\n", nextBlock->name);
107  break;
108  }
109  }
110 
111  if(!nextBlock)
112  {
113  nextBlock = realloc(cfgBlocks, (cfgCount+1)*sizeof(ConfigBlock));
114  if(!nextBlock)
115  {
116  ERR("config parse error: error reallocating config blocks\n");
117  continue;
118  }
119  cfgBlocks = nextBlock;
120  nextBlock = cfgBlocks+cfgCount;
121  cfgCount++;
122 
123  nextBlock->name = strdup(buffer+1);
124  nextBlock->entries = NULL;
125  nextBlock->entryCount = 0;
126 
127  TRACE("found new block '%s'\n", nextBlock->name);
128  }
129  curBlock = nextBlock;
130  continue;
131  }
132 
133  /* Look for the option name */
134  i = 0;
135  while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' &&
136  !isspace(buffer[i]))
137  i++;
138 
139  if(!buffer[i] || buffer[i] == '#' || i == 0)
140  {
141  ERR("config parse error: malformed option line: \"%s\"\n", buffer);
142  continue;
143  }
144 
145  /* Seperate the option */
146  if(buffer[i] != '=')
147  {
148  buffer[i++] = 0;
149 
150  while(isspace(buffer[i]))
151  i++;
152  if(buffer[i] != '=')
153  {
154  ERR("config parse error: option without a value: \"%s\"\n", buffer);
155  continue;
156  }
157  }
158  /* Find the start of the value */
159  buffer[i++] = 0;
160  while(isspace(buffer[i]))
161  i++;
162 
163  /* Check if we already have this option set */
164  ent = curBlock->entries;
165  while((unsigned int)(ent-curBlock->entries) < curBlock->entryCount)
166  {
167  if(strcasecmp(ent->key, buffer) == 0)
168  break;
169  ent++;
170  }
171 
172  if((unsigned int)(ent-curBlock->entries) >= curBlock->entryCount)
173  {
174  /* Allocate a new option entry */
175  ent = realloc(curBlock->entries, (curBlock->entryCount+1)*sizeof(ConfigEntry));
176  if(!ent)
177  {
178  ERR("config parse error: error reallocating config entries\n");
179  continue;
180  }
181  curBlock->entries = ent;
182  ent = curBlock->entries + curBlock->entryCount;
183  curBlock->entryCount++;
184 
185  ent->key = strdup(buffer);
186  ent->value = NULL;
187  }
188 
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);
192 
193  i = 0;
194  while(buffer[i] && buffer[i] != '#' && buffer[i] != '\n')
195  i++;
196  do {
197  i--;
198  } while(i >= 0 && isspace(buffer[i]));
199  buffer[++i] = 0;
200 
201  free(ent->value);
202  ent->value = strdup(buffer);
203 
204  TRACE("found '%s' = '%s'\n", ent->key, ent->value);
205  }
206 }
207 
208 void ReadALConfig(void)
209 {
210  const char *str;
211  FILE *f;
212 
213  cfgBlocks = calloc(1, sizeof(ConfigBlock));
214  cfgBlocks->name = strdup("general");
215  cfgCount = 1;
216 
217 #ifdef _WIN32
218  if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE)
219  {
220  size_t p = strlen(buffer);
221  snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini");
222  f = fopen(buffer, "rt");
223  if(f)
224  {
226  fclose(f);
227  }
228  }
229 #else
230  f = fopen("/etc/openal/alsoft.conf", "r");
231  if(f)
232  {
234  fclose(f);
235  }
236  if((str=getenv("HOME")) != NULL && *str)
237  {
238  snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str);
239  f = fopen(buffer, "r");
240  if(f)
241  {
243  fclose(f);
244  }
245  }
246 #endif
247  if((str=getenv("ALSOFT_CONF")) != NULL && *str)
248  {
249  f = fopen(str, "r");
250  if(f)
251  {
253  fclose(f);
254  }
255  }
256 }
257 
258 void FreeALConfig(void)
259 {
260  unsigned int i;
261 
262  for(i = 0;i < cfgCount;i++)
263  {
264  unsigned int j;
265  for(j = 0;j < cfgBlocks[i].entryCount;j++)
266  {
267  free(cfgBlocks[i].entries[j].key);
268  free(cfgBlocks[i].entries[j].value);
269  }
270  free(cfgBlocks[i].entries);
271  free(cfgBlocks[i].name);
272  }
273  free(cfgBlocks);
274  cfgBlocks = NULL;
275  cfgCount = 0;
276 }
277 
278 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def)
279 {
280  unsigned int i, j;
281 
282  if(!keyName)
283  return def;
284 
285  if(!blockName)
286  blockName = "general";
287 
288  for(i = 0;i < cfgCount;i++)
289  {
290  if(strcasecmp(cfgBlocks[i].name, blockName) != 0)
291  continue;
292 
293  for(j = 0;j < cfgBlocks[i].entryCount;j++)
294  {
295  if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0)
296  {
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;
301  return def;
302  }
303  }
304  }
305 
306  TRACE("Key %s:%s not found\n", blockName, keyName);
307  return def;
308 }
309 
310 int ConfigValueExists(const char *blockName, const char *keyName)
311 {
312  const char *val = GetConfigValue(blockName, keyName, "");
313  return !!val[0];
314 }
315 
316 int ConfigValueStr(const char *blockName, const char *keyName, const char **ret)
317 {
318  const char *val = GetConfigValue(blockName, keyName, "");
319  if(!val[0]) return 0;
320 
321  *ret = val;
322  return 1;
323 }
324 
325 int ConfigValueInt(const char *blockName, const char *keyName, int *ret)
326 {
327  const char *val = GetConfigValue(blockName, keyName, "");
328  if(!val[0]) return 0;
329 
330  *ret = strtol(val, NULL, 0);
331  return 1;
332 }
333 
334 int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret)
335 {
336  const char *val = GetConfigValue(blockName, keyName, "");
337  if(!val[0]) return 0;
338 
339  *ret = strtoul(val, NULL, 0);
340  return 1;
341 }
342 
343 int ConfigValueFloat(const char *blockName, const char *keyName, float *ret)
344 {
345  const char *val = GetConfigValue(blockName, keyName, "");
346  if(!val[0]) return 0;
347 
348 #ifdef HAVE_STRTOF
349  *ret = strtof(val, NULL);
350 #else
351  *ret = (float)strtod(val, NULL);
352 #endif
353  return 1;
354 }
355 
356 int GetConfigValueBool(const char *blockName, const char *keyName, int def)
357 {
358  const char *val = GetConfigValue(blockName, keyName, "");
359 
360  if(!val[0]) return !!def;
361  return (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0 ||
362  strcasecmp(val, "on") == 0 || atoi(val) != 0);
363 }
int ConfigValueStr(const char *blockName, const char *keyName, const char **ret)
Definition: alcConfig.c:316
GLuint const GLfloat * val
Definition: glew.h:2715
char * strdup(const char *inStr)
Definition: strdup.c:6
int ConfigValueInt(const char *blockName, const char *keyName, int *ret)
Definition: alcConfig.c:325
#define NULL
Definition: ftobjs.h:61
#define TRACE(...)
Definition: alMain.h:806
GLclampf f
Definition: glew.h:3390
int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret)
Definition: alcConfig.c:334
#define memmove
Definition: SDL_qsort.c:81
SDL_EventEntry * free
Definition: SDL_events.c:80
int32_t j
Definition: e_log.c:102
EGLImageKHR EGLint * name
Definition: eglext.h:284
int ConfigValueExists(const char *blockName, const char *keyName)
Definition: alcConfig.c:310
const char * GetConfigValue(const char *blockName, const char *keyName, const char *def)
Definition: alcConfig.c:278
#define calloc
Definition: SDL_malloc.c:636
ret
Definition: glew_str_glx.c:2
void ReadALConfig(void)
Definition: alcConfig.c:208
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
int GetConfigValueBool(const char *blockName, const char *keyName, int def)
Definition: alcConfig.c:356
new_palette entries
Definition: pngrutil.c:1486
GLfloat GLfloat p
Definition: glew.h:14938
void FreeALConfig(void)
Definition: alcConfig.c:258
static void LoadConfigFromFile(FILE *f)
Definition: alcConfig.c:58
#define realloc
Definition: SDL_malloc.c:637
struct ConfigBlock ConfigBlock
#define WARN(...)
Definition: alMain.h:811
#define FALSE
Definition: ftobjs.h:57
struct ConfigEntry ConfigEntry
static ConfigBlock * cfgBlocks
Definition: alcConfig.c:53
EGLSurface EGLint void ** value
Definition: eglext.h:301
#define ERR(...)
Definition: alMain.h:816
int ConfigValueFloat(const char *blockName, const char *keyName, float *ret)
Definition: alcConfig.c:343
#define str(s)
int i
Definition: pngrutil.c:1377
static unsigned int cfgCount
Definition: alcConfig.c:54