~ubuntu-branches/debian/squeeze/stellarium/squeeze

« back to all changes in this revision

Viewing changes to src/iniparser/iniparser.c

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2008-05-19 21:28:23 UTC
  • mfrom: (3.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080519212823-m5nfiuntxstxzxj7
Tags: 0.9.1-4
Add libxcursor-dev, libxfixes-dev, libxinerama-dev, libqt4-opengl-dev to
build-deps (Closes: #479906)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/*-------------------------------------------------------------------------*/
3
 
/**
4
 
   @file    iniparser.c
5
 
   @author  N. Devillard
6
 
   @date    Mar 2000
7
 
   @version $Revision: 1.7 $
8
 
   @brief   Parser for ini files.
9
 
*/
10
 
/*--------------------------------------------------------------------------*/
11
 
 
12
 
/*
13
 
    $Id: iniparser.c,v 1.7 2003/08/25 16:29:59 xalioth Exp $
14
 
    $Author: xalioth $
15
 
    $Date: 2003/08/25 16:29:59 $
16
 
    $Revision: 1.7 $
17
 
*/
18
 
 
19
 
/*---------------------------------------------------------------------------
20
 
                                Includes
21
 
 ---------------------------------------------------------------------------*/
22
 
 
23
 
#include "iniparser.h"
24
 
#include "strlib.h"
25
 
 
26
 
#define ASCIILINESZ         1024
27
 
#define INI_INVALID_KEY     ((char*)-1)
28
 
 
29
 
/*---------------------------------------------------------------------------
30
 
                        Private to this module
31
 
 ---------------------------------------------------------------------------*/
32
 
 
33
 
/* Private: add an entry to the dictionary */
34
 
static void iniparser_add_entry(
35
 
    dictionary * d,
36
 
    char * sec,
37
 
    char * key,
38
 
    char * val)
39
 
{
40
 
    char longkey[2*ASCIILINESZ+1];
41
 
 
42
 
    /* Make a key as section:keyword */
43
 
    if (key!=NULL) {
44
 
        sprintf(longkey, "%s:%s", sec, key);
45
 
    } else {
46
 
        strcpy(longkey, sec);
47
 
    }
48
 
 
49
 
    /* Add (key,val) to dictionary */
50
 
    dictionary_set(d, longkey, val);
51
 
    return ;
52
 
}
53
 
 
54
 
 
55
 
/*-------------------------------------------------------------------------*/
56
 
/**
57
 
  @brief    Get number of sections in a dictionary
58
 
  @param    d   Dictionary to examine
59
 
  @return   int Number of sections found in dictionary
60
 
 
61
 
  This function returns the number of sections found in a dictionary.
62
 
  The test to recognize sections is done on the string stored in the
63
 
  dictionary: a section name is given as "section" whereas a key is
64
 
  stored as "section:key", thus the test looks for entries that do not
65
 
  contain a colon.
66
 
 
67
 
  This clearly fails in the case a section name contains a colon, but
68
 
  this should simply be avoided.
69
 
 
70
 
  This function returns -1 in case of error.
71
 
 */
72
 
/*--------------------------------------------------------------------------*/
73
 
 
74
 
int iniparser_getnsec(dictionary * d)
75
 
{
76
 
    int i ;
77
 
    int nsec ;
78
 
 
79
 
    if (d==NULL) return -1 ;
80
 
    nsec=0 ;
81
 
    for (i=0 ; i<d->size ; i++) {
82
 
        if (d->key[i]==NULL)
83
 
            continue ;
84
 
        if (strchr(d->key[i], ':')==NULL) {
85
 
            nsec ++ ;
86
 
        }
87
 
    }
88
 
    return nsec ;
89
 
}
90
 
 
91
 
 
92
 
/*-------------------------------------------------------------------------*/
93
 
/**
94
 
  @brief    Get name for section n in a dictionary.
95
 
  @param    d   Dictionary to examine
96
 
  @param    n   Section number (from 0 to nsec-1).
97
 
  @return   Pointer to char string
98
 
 
99
 
  This function locates the n-th section in a dictionary and returns
100
 
  its name as a pointer to a string statically allocated inside the
101
 
  dictionary. Do not free or modify the returned string!
102
 
 
103
 
  This function returns NULL in case of error.
104
 
 */
105
 
/*--------------------------------------------------------------------------*/
106
 
 
107
 
char * iniparser_getsecname(dictionary * d, int n)
108
 
{
109
 
    int i ;
110
 
    int foundsec ;
111
 
 
112
 
    if (d==NULL || n<0) return NULL ;
113
 
    foundsec=0 ;
114
 
    for (i=0 ; i<d->size ; i++) {
115
 
        if (d->key[i]==NULL)
116
 
            continue ;
117
 
        if (strchr(d->key[i], ':')==NULL) {
118
 
            foundsec++ ;
119
 
            if (foundsec>n)
120
 
                break ;
121
 
        }
122
 
    }
123
 
    if (foundsec<=n) {
124
 
        return NULL ;
125
 
    }
126
 
    return d->key[i] ;
127
 
}
128
 
 
129
 
 
130
 
/*-------------------------------------------------------------------------*/
131
 
/**
132
 
  @brief    Dump a dictionary to an opened file pointer.
133
 
  @param    d   Dictionary to dump.
134
 
  @param    f   Opened file pointer to dump to.
135
 
  @return   void
136
 
 
137
 
  This function prints out the contents of a dictionary, one element by
138
 
  line, onto the provided file pointer. It is OK to specify @c stderr
139
 
  or @c stdout as output files. This function is meant for debugging
140
 
  purposes mostly.
141
 
 */
142
 
/*--------------------------------------------------------------------------*/
143
 
void iniparser_dump(dictionary * d, FILE * f)
144
 
{
145
 
    int     i ;
146
 
 
147
 
    if (d==NULL || f==NULL) return ;
148
 
    for (i=0 ; i<d->size ; i++) {
149
 
        if (d->key[i]==NULL)
150
 
            continue ;
151
 
        if (d->val[i]!=NULL) {
152
 
            fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
153
 
        } else {
154
 
            fprintf(f, "[%s]=UNDEF\n", d->key[i]);
155
 
        }
156
 
    }
157
 
    return ;
158
 
}
159
 
 
160
 
/*-------------------------------------------------------------------------*/
161
 
/**
162
 
  @brief    Save a dictionary to a loadable ini file
163
 
  @param    d   Dictionary to dump
164
 
  @param    f   Opened file pointer to dump to
165
 
  @return   void
166
 
 
167
 
  This function dumps a given dictionary into a loadable ini file.
168
 
  It is Ok to specify @c stderr or @c stdout as output files.
169
 
 */
170
 
/*--------------------------------------------------------------------------*/
171
 
 
172
 
void iniparser_dump_ini(dictionary * d, FILE * f)
173
 
{
174
 
    int     i, j ;
175
 
    char    keym[ASCIILINESZ+1];
176
 
    int     nsec ;
177
 
    char *  secname ;
178
 
    int     seclen ;
179
 
 
180
 
    if (d==NULL || f==NULL) return ;
181
 
 
182
 
    nsec = iniparser_getnsec(d);
183
 
    if (nsec<1) {
184
 
        /* No section in file: dump all keys as they are */
185
 
        for (i=0 ; i<d->size ; i++) {
186
 
            if (d->key[i]==NULL)
187
 
                continue ;
188
 
            fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
189
 
        }
190
 
        return ;
191
 
    }
192
 
    for (i=0 ; i<nsec ; i++) {
193
 
        secname = iniparser_getsecname(d, i) ;
194
 
        seclen  = (int)strlen(secname);
195
 
        fprintf(f, "\n[%s]\n", secname);
196
 
        sprintf(keym, "%s:", secname);
197
 
        for (j=0 ; j<d->size ; j++) {
198
 
            if (d->key[j]==NULL)
199
 
                continue ;
200
 
            if (!strncmp(d->key[j], keym, seclen+1)) {
201
 
                fprintf(f,
202
 
                        "%-30s = %s\n",
203
 
                        d->key[j]+seclen+1,
204
 
                        d->val[j] ? d->val[j] : "");
205
 
            }
206
 
        }
207
 
    }
208
 
    fprintf(f, "\n");
209
 
    return ;
210
 
}
211
 
 
212
 
 
213
 
 
214
 
 
215
 
/*-------------------------------------------------------------------------*/
216
 
/**
217
 
  @brief        Get the string associated to a key, return NULL if not found
218
 
  @param    d   Dictionary to search
219
 
  @param    key Key string to look for
220
 
  @return   pointer to statically allocated character string, or NULL.
221
 
 
222
 
  This function queries a dictionary for a key. A key as read from an
223
 
  ini file is given as "section:key". If the key cannot be found,
224
 
  NULL is returned.
225
 
  The returned char pointer is pointing to a string allocated in
226
 
  the dictionary, do not free or modify it.
227
 
 
228
 
  This function is only provided for backwards compatibility with 
229
 
  previous versions of iniparser. It is recommended to use
230
 
  iniparser_getstring() instead.
231
 
 */
232
 
/*--------------------------------------------------------------------------*/
233
 
const char * iniparser_getstr(const dictionary * d, const char * key)
234
 
{
235
 
    return iniparser_getstring(d, key, NULL);
236
 
}
237
 
 
238
 
 
239
 
/*-------------------------------------------------------------------------*/
240
 
/**
241
 
  @brief    Get the string associated to a key
242
 
  @param    d       Dictionary to search
243
 
  @param    key     Key string to look for
244
 
  @param    def     Default value to return if key not found.
245
 
  @return   pointer to statically allocated character string
246
 
 
247
 
  This function queries a dictionary for a key. A key as read from an
248
 
  ini file is given as "section:key". If the key cannot be found,
249
 
  the pointer passed as 'def' is returned.
250
 
  The returned char pointer is pointing to a string allocated in
251
 
  the dictionary, do not free or modify it.
252
 
 */
253
 
/*--------------------------------------------------------------------------*/
254
 
const char * iniparser_getstring(const dictionary * d, const char * key, const char * def)
255
 
{
256
 
    const char * lc_key ;
257
 
    const char * sval ;
258
 
 
259
 
    if (d==NULL || key==NULL)
260
 
        return def ;
261
 
 
262
 
    lc_key = strlwc(key);
263
 
    sval = dictionary_get(d, lc_key, def);
264
 
 
265
 
    return sval ;
266
 
}
267
 
 
268
 
 
269
 
 
270
 
/*-------------------------------------------------------------------------*/
271
 
/**
272
 
  @brief    Get the string associated to a key, convert to an int
273
 
  @param    d Dictionary to search
274
 
  @param    key Key string to look for
275
 
  @param    notfound Value to return in case of error
276
 
  @return   integer
277
 
 
278
 
  This function queries a dictionary for a key. A key as read from an
279
 
  ini file is given as "section:key". If the key cannot be found,
280
 
  the notfound value is returned.
281
 
 */
282
 
/*--------------------------------------------------------------------------*/
283
 
int iniparser_getint(dictionary * d, const char * key, int notfound)
284
 
{
285
 
    const char * str ;
286
 
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
287
 
    if (str==INI_INVALID_KEY) return notfound ;
288
 
    return atoi(str);
289
 
}
290
 
 
291
 
 
292
 
/*-------------------------------------------------------------------------*/
293
 
/**
294
 
  @brief    Get the string associated to a key, convert to a double
295
 
  @param    d Dictionary to search
296
 
  @param    key Key string to look for
297
 
  @param    notfound Value to return in case of error
298
 
  @return   double
299
 
 
300
 
  This function queries a dictionary for a key. A key as read from an
301
 
  ini file is given as "section:key". If the key cannot be found,
302
 
  the notfound value is returned.
303
 
 */
304
 
/*--------------------------------------------------------------------------*/
305
 
double iniparser_getdouble(dictionary * d, const char * key, double notfound)
306
 
{
307
 
    const char * str;
308
 
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
309
 
    if (str==INI_INVALID_KEY) return notfound ;
310
 
    return atof(str);
311
 
}
312
 
 
313
 
 
314
 
 
315
 
/*-------------------------------------------------------------------------*/
316
 
/**
317
 
  @brief    Get the string associated to a key, convert to a boolean
318
 
  @param    d Dictionary to search
319
 
  @param    key Key string to look for
320
 
  @param    notfound Value to return in case of error
321
 
  @return   integer
322
 
 
323
 
  This function queries a dictionary for a key. A key as read from an
324
 
  ini file is given as "section:key". If the key cannot be found,
325
 
  the notfound value is returned.
326
 
 
327
 
  A true boolean is found if one of the following is matched:
328
 
 
329
 
  - A string starting with 'y'
330
 
  - A string starting with 'Y'
331
 
  - A string starting with 't'
332
 
  - A string starting with 'T'
333
 
  - A string starting with '1'
334
 
 
335
 
  A false boolean is found if one of the following is matched:
336
 
 
337
 
  - A string starting with 'n'
338
 
  - A string starting with 'N'
339
 
  - A string starting with 'f'
340
 
  - A string starting with 'F'
341
 
  - A string starting with '0'
342
 
 
343
 
  The notfound value returned if no boolean is identified, does not
344
 
  necessarily have to be 0 or 1.
345
 
 */
346
 
/*--------------------------------------------------------------------------*/
347
 
int iniparser_getboolean(dictionary * d, const char * key, int notfound)
348
 
{
349
 
    const char * c;
350
 
    int         ret ;
351
 
 
352
 
    c = iniparser_getstring(d, key, INI_INVALID_KEY);
353
 
    if (c==INI_INVALID_KEY) return notfound ;
354
 
    if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
355
 
        ret = 1 ;
356
 
    } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
357
 
        ret = 0 ;
358
 
    } else {
359
 
        ret = notfound ;
360
 
    }
361
 
    return ret;
362
 
}
363
 
 
364
 
 
365
 
/*-------------------------------------------------------------------------*/
366
 
/**
367
 
  @brief    Finds out if a given entry exists in a dictionary
368
 
  @param    ini     Dictionary to search
369
 
  @param    entry   Name of the entry to look for
370
 
  @return   integer 1 if entry exists, 0 otherwise
371
 
 
372
 
  Finds out if a given entry exists in the dictionary. Since sections
373
 
  are stored as keys with NULL associated values, this is the only way
374
 
  of querying for the presence of sections in a dictionary.
375
 
 */
376
 
/*--------------------------------------------------------------------------*/
377
 
 
378
 
int iniparser_find_entry(
379
 
    dictionary  *   ini,
380
 
    const char        *   entry
381
 
)
382
 
{
383
 
    int found=0 ;
384
 
    if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
385
 
        found = 1 ;
386
 
    }
387
 
    return found ;
388
 
}
389
 
 
390
 
 
391
 
 
392
 
/*-------------------------------------------------------------------------*/
393
 
/**
394
 
  @brief    Set an entry in a dictionary.
395
 
  @param    ini     Dictionary to modify.
396
 
  @param    entry   Entry to modify (entry name)
397
 
  @param    val     New value to associate to the entry.
398
 
  @return   int 0 if Ok, -1 otherwise.
399
 
 
400
 
  If the given entry can be found in the dictionary, it is modified to
401
 
  contain the provided value. If it cannot be found the entry is created.
402
 
  It is Ok to set val to NULL.
403
 
 */
404
 
/*--------------------------------------------------------------------------*/
405
 
 
406
 
int iniparser_setstr(dictionary * ini, const char * entry, const char * val)
407
 
{
408
 
    dictionary_set(ini, strlwc(entry), val);
409
 
    return 0 ;
410
 
}
411
 
 
412
 
/*-------------------------------------------------------------------------*/
413
 
/**
414
 
  @brief    Delete an entry in a dictionary
415
 
  @param    ini     Dictionary to modify
416
 
  @param    entry   Entry to delete (entry name)
417
 
  @return   void
418
 
 
419
 
  If the given entry can be found, it is deleted from the dictionary.
420
 
 */
421
 
/*--------------------------------------------------------------------------*/
422
 
void iniparser_unset(dictionary * ini, const char * entry)
423
 
{
424
 
    dictionary_unset(ini, strlwc(entry));
425
 
}
426
 
 
427
 
 
428
 
/*-------------------------------------------------------------------------*/
429
 
/**
430
 
  @brief    Parse an ini file and return an allocated dictionary object
431
 
  @param    ininame Name of the ini file to read.
432
 
  @return   Pointer to newly allocated dictionary
433
 
 
434
 
  This is the parser for ini files. This function is called, providing
435
 
  the name of the file to be read. It returns a dictionary object that
436
 
  should not be accessed directly, but through accessor functions
437
 
  instead.
438
 
 
439
 
  The returned dictionary must be freed using iniparser_freedict().
440
 
 */
441
 
/*--------------------------------------------------------------------------*/
442
 
 
443
 
dictionary * iniparser_load(const char * ininame)
444
 
{
445
 
    dictionary  *   d ;
446
 
    char        lin[ASCIILINESZ+1];
447
 
    char        sec[ASCIILINESZ+1];
448
 
    char        key[ASCIILINESZ+1];
449
 
    char        val[ASCIILINESZ+1];
450
 
    char    *   where ;
451
 
    FILE    *   ini ;
452
 
    int         lineno ;
453
 
 
454
 
    if ((ini=fopen(ininame, "r"))==NULL) {
455
 
        return NULL ;
456
 
    }
457
 
 
458
 
    sec[0]=0;
459
 
 
460
 
    /*
461
 
     * Initialize a new dictionary entry
462
 
     */
463
 
    d = dictionary_new(0);
464
 
    lineno = 0 ;
465
 
    while (fgets(lin, ASCIILINESZ, ini)!=NULL) {
466
 
        lineno++ ;
467
 
        where = strskp(lin); /* Skip leading spaces */
468
 
        if (*where==';' || *where=='#' || *where==0)
469
 
            continue ; /* Comment lines */
470
 
        else {
471
 
            if (sscanf(where, "[%[^]]", sec)==1) {
472
 
                /* Valid section name */
473
 
                strcpy(sec, strlwc(sec));
474
 
                iniparser_add_entry(d, sec, NULL, NULL);
475
 
            } else if (sscanf (where, "%[^=] = \"%[^\"]\"", key, val) == 2
476
 
                   ||  sscanf (where, "%[^=] = '%[^\']'",   key, val) == 2
477
 
                   ||  sscanf (where, "%[^=] = %[^;#]",     key, val) == 2) {
478
 
                strcpy(key, strlwc(strcrop(key)));
479
 
                /*
480
 
                 * sscanf cannot handle "" or '' as empty value,
481
 
                 * this is done here
482
 
                 */
483
 
                if (!strcmp(val, "\"\"") || !strcmp(val, "''")) {
484
 
                    val[0] = (char)0;
485
 
                } else {
486
 
                    strcpy(val, strcrop(val));
487
 
                }
488
 
                iniparser_add_entry(d, sec, key, val);
489
 
            }
490
 
        }
491
 
    }
492
 
    fclose(ini);
493
 
    return d ;
494
 
}
495
 
 
496
 
 
497
 
 
498
 
/*-------------------------------------------------------------------------*/
499
 
/**
500
 
  @brief    Free all memory associated to an ini dictionary
501
 
  @param    d Dictionary to free
502
 
  @return   void
503
 
 
504
 
  Free all memory associated to an ini dictionary.
505
 
  It is mandatory to call this function before the dictionary object
506
 
  gets out of the current context.
507
 
 */
508
 
/*--------------------------------------------------------------------------*/
509
 
 
510
 
void iniparser_freedict(dictionary * d)
511
 
{
512
 
    dictionary_del(d);
513
 
}
514
 
 
515
 
/* vim: set ts=4 et sw=4 tw=75 */