OLD | NEW |
(Empty) | |
| 1 |
| 2 /*-------------------------------------------------------------------------*/ |
| 3 /** |
| 4 @file iniparser.c |
| 5 @author N. Devillard |
| 6 @date Sep 2007 |
| 7 @version 3.0 |
| 8 @brief Parser for ini files. |
| 9 */ |
| 10 /*--------------------------------------------------------------------------*/ |
| 11 /* |
| 12 $Id: iniparser.c,v 2.19 2011-03-02 20:15:13 ndevilla Exp $ |
| 13 $Revision: 2.19 $ |
| 14 $Date: 2011-03-02 20:15:13 $ |
| 15 */ |
| 16 /*---------------------------- Includes ------------------------------------*/ |
| 17 #include <ctype.h> |
| 18 #include "iniparser.h" |
| 19 |
| 20 /*---------------------------- Defines -------------------------------------*/ |
| 21 #define ASCIILINESZ (1024) |
| 22 #define INI_INVALID_KEY ((char*)-1) |
| 23 |
| 24 /*--------------------------------------------------------------------------- |
| 25 Private to this module |
| 26 ---------------------------------------------------------------------------*/ |
| 27 /** |
| 28 * This enum stores the status for each parsed line (internal use only). |
| 29 */ |
| 30 typedef enum _line_status_ { |
| 31 LINE_UNPROCESSED, |
| 32 LINE_ERROR, |
| 33 LINE_EMPTY, |
| 34 LINE_COMMENT, |
| 35 LINE_SECTION, |
| 36 LINE_VALUE |
| 37 } line_status ; |
| 38 |
| 39 /*-------------------------------------------------------------------------*/ |
| 40 /** |
| 41 @brief Convert a string to lowercase. |
| 42 @param s String to convert. |
| 43 @return ptr to statically allocated string. |
| 44 |
| 45 This function returns a pointer to a statically allocated string |
| 46 containing a lowercased version of the input string. Do not free |
| 47 or modify the returned string! Since the returned string is statically |
| 48 allocated, it will be modified at each function call (not re-entrant). |
| 49 */ |
| 50 /*--------------------------------------------------------------------------*/ |
| 51 static char * strlwc(char * s) |
| 52 { |
| 53 static char l[ASCIILINESZ+1]; |
| 54 int i ; |
| 55 |
| 56 if (s==NULL) return NULL ; |
| 57 memset(l, 0, ASCIILINESZ+1); |
| 58 i=0 ; |
| 59 while (s[i] && i<ASCIILINESZ) { |
| 60 l[i] = (char)tolower((int)s[i]); |
| 61 i++ ; |
| 62 } |
| 63 l[ASCIILINESZ]=(char)0; |
| 64 return l ; |
| 65 } |
| 66 |
| 67 /*-------------------------------------------------------------------------*/ |
| 68 /** |
| 69 @brief Remove blanks at the beginning and the end of a string. |
| 70 @param s String to parse. |
| 71 @return ptr to statically allocated string. |
| 72 |
| 73 This function returns a pointer to a statically allocated string, |
| 74 which is identical to the input string, except that all blank |
| 75 characters at the end and the beg. of the string have been removed. |
| 76 Do not free or modify the returned string! Since the returned string |
| 77 is statically allocated, it will be modified at each function call |
| 78 (not re-entrant). |
| 79 */ |
| 80 /*--------------------------------------------------------------------------*/ |
| 81 static char * strstrip(char * s) |
| 82 { |
| 83 static char l[ASCIILINESZ+1]; |
| 84 char * last ; |
| 85 |
| 86 if (s==NULL) return NULL ; |
| 87 |
| 88 while (isspace((int)*s) && *s) s++; |
| 89 memset(l, 0, ASCIILINESZ+1); |
| 90 strcpy(l, s); |
| 91 last = l + strlen(l); |
| 92 while (last > l) { |
| 93 if (!isspace((int)*(last-1))) |
| 94 break ; |
| 95 last -- ; |
| 96 } |
| 97 *last = (char)0; |
| 98 return (char*)l ; |
| 99 } |
| 100 |
| 101 /*-------------------------------------------------------------------------*/ |
| 102 /** |
| 103 @brief Get number of sections in a dictionary |
| 104 @param d Dictionary to examine |
| 105 @return int Number of sections found in dictionary |
| 106 |
| 107 This function returns the number of sections found in a dictionary. |
| 108 The test to recognize sections is done on the string stored in the |
| 109 dictionary: a section name is given as "section" whereas a key is |
| 110 stored as "section:key", thus the test looks for entries that do not |
| 111 contain a colon. |
| 112 |
| 113 This clearly fails in the case a section name contains a colon, but |
| 114 this should simply be avoided. |
| 115 |
| 116 This function returns -1 in case of error. |
| 117 */ |
| 118 /*--------------------------------------------------------------------------*/ |
| 119 int iniparser_getnsec(dictionary * d) |
| 120 { |
| 121 int i ; |
| 122 int nsec ; |
| 123 |
| 124 if (d==NULL) return -1 ; |
| 125 nsec=0 ; |
| 126 for (i=0 ; i<d->size ; i++) { |
| 127 if (d->key[i]==NULL) |
| 128 continue ; |
| 129 if (strchr(d->key[i], ':')==NULL) { |
| 130 nsec ++ ; |
| 131 } |
| 132 } |
| 133 return nsec ; |
| 134 } |
| 135 |
| 136 /*-------------------------------------------------------------------------*/ |
| 137 /** |
| 138 @brief Get name for section n in a dictionary. |
| 139 @param d Dictionary to examine |
| 140 @param n Section number (from 0 to nsec-1). |
| 141 @return Pointer to char string |
| 142 |
| 143 This function locates the n-th section in a dictionary and returns |
| 144 its name as a pointer to a string statically allocated inside the |
| 145 dictionary. Do not free or modify the returned string! |
| 146 |
| 147 This function returns NULL in case of error. |
| 148 */ |
| 149 /*--------------------------------------------------------------------------*/ |
| 150 char * iniparser_getsecname(dictionary * d, int n) |
| 151 { |
| 152 int i ; |
| 153 int foundsec ; |
| 154 |
| 155 if (d==NULL || n<0) return NULL ; |
| 156 foundsec=0 ; |
| 157 for (i=0 ; i<d->size ; i++) { |
| 158 if (d->key[i]==NULL) |
| 159 continue ; |
| 160 if (strchr(d->key[i], ':')==NULL) { |
| 161 foundsec++ ; |
| 162 if (foundsec>n) |
| 163 break ; |
| 164 } |
| 165 } |
| 166 if (foundsec<=n) { |
| 167 return NULL ; |
| 168 } |
| 169 return d->key[i] ; |
| 170 } |
| 171 |
| 172 /*-------------------------------------------------------------------------*/ |
| 173 /** |
| 174 @brief Dump a dictionary to an opened file pointer. |
| 175 @param d Dictionary to dump. |
| 176 @param f Opened file pointer to dump to. |
| 177 @return void |
| 178 |
| 179 This function prints out the contents of a dictionary, one element by |
| 180 line, onto the provided file pointer. It is OK to specify @c stderr |
| 181 or @c stdout as output files. This function is meant for debugging |
| 182 purposes mostly. |
| 183 */ |
| 184 /*--------------------------------------------------------------------------*/ |
| 185 void iniparser_dump(dictionary * d, FILE * f) |
| 186 { |
| 187 int i ; |
| 188 |
| 189 if (d==NULL || f==NULL) return ; |
| 190 for (i=0 ; i<d->size ; i++) { |
| 191 if (d->key[i]==NULL) |
| 192 continue ; |
| 193 if (d->val[i]!=NULL) { |
| 194 fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); |
| 195 } else { |
| 196 fprintf(f, "[%s]=UNDEF\n", d->key[i]); |
| 197 } |
| 198 } |
| 199 return ; |
| 200 } |
| 201 |
| 202 /*-------------------------------------------------------------------------*/ |
| 203 /** |
| 204 @brief Save a dictionary to a loadable ini file |
| 205 @param d Dictionary to dump |
| 206 @param f Opened file pointer to dump to |
| 207 @return void |
| 208 |
| 209 This function dumps a given dictionary into a loadable ini file. |
| 210 It is Ok to specify @c stderr or @c stdout as output files. |
| 211 */ |
| 212 /*--------------------------------------------------------------------------*/ |
| 213 void iniparser_dump_ini(dictionary * d, FILE * f) |
| 214 { |
| 215 int i, j ; |
| 216 char keym[ASCIILINESZ+1]; |
| 217 int nsec ; |
| 218 char * secname ; |
| 219 int seclen ; |
| 220 |
| 221 if (d==NULL || f==NULL) return ; |
| 222 |
| 223 nsec = iniparser_getnsec(d); |
| 224 if (nsec<1) { |
| 225 /* No section in file: dump all keys as they are */ |
| 226 for (i=0 ; i<d->size ; i++) { |
| 227 if (d->key[i]==NULL) |
| 228 continue ; |
| 229 fprintf(f, "%s = %s\n", d->key[i], d->val[i]); |
| 230 } |
| 231 return ; |
| 232 } |
| 233 for (i=0 ; i<nsec ; i++) { |
| 234 secname = iniparser_getsecname(d, i) ; |
| 235 seclen = (int)strlen(secname); |
| 236 fprintf(f, "\n[%s]\n", secname); |
| 237 sprintf(keym, "%s:", secname); |
| 238 for (j=0 ; j<d->size ; j++) { |
| 239 if (d->key[j]==NULL) |
| 240 continue ; |
| 241 if (!strncmp(d->key[j], keym, seclen+1)) { |
| 242 fprintf(f, |
| 243 "%-30s = %s\n", |
| 244 d->key[j]+seclen+1, |
| 245 d->val[j] ? d->val[j] : ""); |
| 246 } |
| 247 } |
| 248 } |
| 249 fprintf(f, "\n"); |
| 250 return ; |
| 251 } |
| 252 |
| 253 /*-------------------------------------------------------------------------*/ |
| 254 /** |
| 255 @brief Get the string associated to a key |
| 256 @param d Dictionary to search |
| 257 @param key Key string to look for |
| 258 @param def Default value to return if key not found. |
| 259 @return pointer to statically allocated character string |
| 260 |
| 261 This function queries a dictionary for a key. A key as read from an |
| 262 ini file is given as "section:key". If the key cannot be found, |
| 263 the pointer passed as 'def' is returned. |
| 264 The returned char pointer is pointing to a string allocated in |
| 265 the dictionary, do not free or modify it. |
| 266 */ |
| 267 /*--------------------------------------------------------------------------*/ |
| 268 char * iniparser_getstring(dictionary * d, char * key, char * def) |
| 269 { |
| 270 char * lc_key ; |
| 271 char * sval ; |
| 272 |
| 273 if (d==NULL || key==NULL) |
| 274 return def ; |
| 275 |
| 276 lc_key = strlwc(key); |
| 277 sval = dictionary_get(d, lc_key, def); |
| 278 return sval ; |
| 279 } |
| 280 |
| 281 /*-------------------------------------------------------------------------*/ |
| 282 /** |
| 283 @brief Get the string associated to a key, convert to an int |
| 284 @param d Dictionary to search |
| 285 @param key Key string to look for |
| 286 @param notfound Value to return in case of error |
| 287 @return integer |
| 288 |
| 289 This function queries a dictionary for a key. A key as read from an |
| 290 ini file is given as "section:key". If the key cannot be found, |
| 291 the notfound value is returned. |
| 292 |
| 293 Supported values for integers include the usual C notation |
| 294 so decimal, octal (starting with 0) and hexadecimal (starting with 0x) |
| 295 are supported. Examples: |
| 296 |
| 297 "42" -> 42 |
| 298 "042" -> 34 (octal -> decimal) |
| 299 "0x42" -> 66 (hexa -> decimal) |
| 300 |
| 301 Warning: the conversion may overflow in various ways. Conversion is |
| 302 totally outsourced to strtol(), see the associated man page for overflow |
| 303 handling. |
| 304 |
| 305 Credits: Thanks to A. Becker for suggesting strtol() |
| 306 */ |
| 307 /*--------------------------------------------------------------------------*/ |
| 308 int iniparser_getint(dictionary * d, char * key, int notfound) |
| 309 { |
| 310 char * str ; |
| 311 |
| 312 str = iniparser_getstring(d, key, INI_INVALID_KEY); |
| 313 if (str==INI_INVALID_KEY) return notfound ; |
| 314 return (int)strtol(str, NULL, 0); |
| 315 } |
| 316 |
| 317 /*-------------------------------------------------------------------------*/ |
| 318 /** |
| 319 @brief Get the string associated to a key, convert to a double |
| 320 @param d Dictionary to search |
| 321 @param key Key string to look for |
| 322 @param notfound Value to return in case of error |
| 323 @return double |
| 324 |
| 325 This function queries a dictionary for a key. A key as read from an |
| 326 ini file is given as "section:key". If the key cannot be found, |
| 327 the notfound value is returned. |
| 328 */ |
| 329 /*--------------------------------------------------------------------------*/ |
| 330 double iniparser_getdouble(dictionary * d, char * key, double notfound) |
| 331 { |
| 332 char * str ; |
| 333 |
| 334 str = iniparser_getstring(d, key, INI_INVALID_KEY); |
| 335 if (str==INI_INVALID_KEY) return notfound ; |
| 336 return atof(str); |
| 337 } |
| 338 |
| 339 /*-------------------------------------------------------------------------*/ |
| 340 /** |
| 341 @brief Get the string associated to a key, convert to a boolean |
| 342 @param d Dictionary to search |
| 343 @param key Key string to look for |
| 344 @param notfound Value to return in case of error |
| 345 @return integer |
| 346 |
| 347 This function queries a dictionary for a key. A key as read from an |
| 348 ini file is given as "section:key". If the key cannot be found, |
| 349 the notfound value is returned. |
| 350 |
| 351 A true boolean is found if one of the following is matched: |
| 352 |
| 353 - A string starting with 'y' |
| 354 - A string starting with 'Y' |
| 355 - A string starting with 't' |
| 356 - A string starting with 'T' |
| 357 - A string starting with '1' |
| 358 |
| 359 A false boolean is found if one of the following is matched: |
| 360 |
| 361 - A string starting with 'n' |
| 362 - A string starting with 'N' |
| 363 - A string starting with 'f' |
| 364 - A string starting with 'F' |
| 365 - A string starting with '0' |
| 366 |
| 367 The notfound value returned if no boolean is identified, does not |
| 368 necessarily have to be 0 or 1. |
| 369 */ |
| 370 /*--------------------------------------------------------------------------*/ |
| 371 int iniparser_getboolean(dictionary * d, char * key, int notfound) |
| 372 { |
| 373 char * c ; |
| 374 int ret ; |
| 375 |
| 376 c = iniparser_getstring(d, key, INI_INVALID_KEY); |
| 377 if (c==INI_INVALID_KEY) return notfound ; |
| 378 if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { |
| 379 ret = 1 ; |
| 380 } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { |
| 381 ret = 0 ; |
| 382 } else { |
| 383 ret = notfound ; |
| 384 } |
| 385 return ret; |
| 386 } |
| 387 |
| 388 /*-------------------------------------------------------------------------*/ |
| 389 /** |
| 390 @brief Finds out if a given entry exists in a dictionary |
| 391 @param ini Dictionary to search |
| 392 @param entry Name of the entry to look for |
| 393 @return integer 1 if entry exists, 0 otherwise |
| 394 |
| 395 Finds out if a given entry exists in the dictionary. Since sections |
| 396 are stored as keys with NULL associated values, this is the only way |
| 397 of querying for the presence of sections in a dictionary. |
| 398 */ |
| 399 /*--------------------------------------------------------------------------*/ |
| 400 int iniparser_find_entry( |
| 401 dictionary * ini, |
| 402 char * entry |
| 403 ) |
| 404 { |
| 405 int found=0 ; |
| 406 if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { |
| 407 found = 1 ; |
| 408 } |
| 409 return found ; |
| 410 } |
| 411 |
| 412 /*-------------------------------------------------------------------------*/ |
| 413 /** |
| 414 @brief Set an entry in a dictionary. |
| 415 @param ini Dictionary to modify. |
| 416 @param entry Entry to modify (entry name) |
| 417 @param val New value to associate to the entry. |
| 418 @return int 0 if Ok, -1 otherwise. |
| 419 |
| 420 If the given entry can be found in the dictionary, it is modified to |
| 421 contain the provided value. If it cannot be found, -1 is returned. |
| 422 It is Ok to set val to NULL. |
| 423 */ |
| 424 /*--------------------------------------------------------------------------*/ |
| 425 int iniparser_set(dictionary * ini, char * entry, char * val) |
| 426 { |
| 427 return dictionary_set(ini, strlwc(entry), val) ; |
| 428 } |
| 429 |
| 430 /*-------------------------------------------------------------------------*/ |
| 431 /** |
| 432 @brief Delete an entry in a dictionary |
| 433 @param ini Dictionary to modify |
| 434 @param entry Entry to delete (entry name) |
| 435 @return void |
| 436 |
| 437 If the given entry can be found, it is deleted from the dictionary. |
| 438 */ |
| 439 /*--------------------------------------------------------------------------*/ |
| 440 void iniparser_unset(dictionary * ini, char * entry) |
| 441 { |
| 442 dictionary_unset(ini, strlwc(entry)); |
| 443 } |
| 444 |
| 445 /*-------------------------------------------------------------------------*/ |
| 446 /** |
| 447 @brief Load a single line from an INI file |
| 448 @param input_line Input line, may be concatenated multi-line input |
| 449 @param section Output space to store section |
| 450 @param key Output space to store key |
| 451 @param value Output space to store value |
| 452 @return line_status value |
| 453 */ |
| 454 /*--------------------------------------------------------------------------*/ |
| 455 static line_status iniparser_line( |
| 456 char * input_line, |
| 457 char * section, |
| 458 char * key, |
| 459 char * value) |
| 460 { |
| 461 line_status sta ; |
| 462 char line[ASCIILINESZ+1]; |
| 463 int len ; |
| 464 |
| 465 strcpy(line, strstrip(input_line)); |
| 466 len = (int)strlen(line); |
| 467 |
| 468 sta = LINE_UNPROCESSED ; |
| 469 if (len<1) { |
| 470 /* Empty line */ |
| 471 sta = LINE_EMPTY ; |
| 472 } else if (line[0]=='#' || line[0]==';') { |
| 473 /* Comment line */ |
| 474 sta = LINE_COMMENT ; |
| 475 } else if (line[0]=='[' && line[len-1]==']') { |
| 476 /* Section name */ |
| 477 sscanf(line, "[%[^]]", section); |
| 478 strcpy(section, strstrip(section)); |
| 479 strcpy(section, strlwc(section)); |
| 480 sta = LINE_SECTION ; |
| 481 } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 |
| 482 || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 |
| 483 || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { |
| 484 /* Usual key=value, with or without comments */ |
| 485 strcpy(key, strstrip(key)); |
| 486 strcpy(key, strlwc(key)); |
| 487 strcpy(value, strstrip(value)); |
| 488 /* |
| 489 * sscanf cannot handle '' or "" as empty values |
| 490 * this is done here |
| 491 */ |
| 492 if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { |
| 493 value[0]=0 ; |
| 494 } |
| 495 sta = LINE_VALUE ; |
| 496 } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 |
| 497 || sscanf(line, "%[^=] %[=]", key, value) == 2) { |
| 498 /* |
| 499 * Special cases: |
| 500 * key= |
| 501 * key=; |
| 502 * key=# |
| 503 */ |
| 504 strcpy(key, strstrip(key)); |
| 505 strcpy(key, strlwc(key)); |
| 506 value[0]=0 ; |
| 507 sta = LINE_VALUE ; |
| 508 } else { |
| 509 /* Generate syntax error */ |
| 510 sta = LINE_ERROR ; |
| 511 } |
| 512 return sta ; |
| 513 } |
| 514 |
| 515 /*-------------------------------------------------------------------------*/ |
| 516 /** |
| 517 @brief Parse an ini file and return an allocated dictionary object |
| 518 @param ininame Name of the ini file to read. |
| 519 @return Pointer to newly allocated dictionary |
| 520 |
| 521 This is the parser for ini files. This function is called, providing |
| 522 the name of the file to be read. It returns a dictionary object that |
| 523 should not be accessed directly, but through accessor functions |
| 524 instead. |
| 525 |
| 526 The returned dictionary must be freed using iniparser_freedict(). |
| 527 */ |
| 528 /*--------------------------------------------------------------------------*/ |
| 529 dictionary * iniparser_load(char * ininame) |
| 530 { |
| 531 FILE * in ; |
| 532 |
| 533 char line [ASCIILINESZ+1] ; |
| 534 char section [ASCIILINESZ+1] ; |
| 535 char key [ASCIILINESZ+1] ; |
| 536 char tmp [ASCIILINESZ+1] ; |
| 537 char val [ASCIILINESZ+1] ; |
| 538 |
| 539 int last=0 ; |
| 540 int len ; |
| 541 int lineno=0 ; |
| 542 int errs=0; |
| 543 |
| 544 dictionary * dict ; |
| 545 |
| 546 if ((in=fopen(ininame, "r"))==NULL) { |
| 547 fprintf(stderr, "iniparser: cannot open %s\n", ininame); |
| 548 return NULL ; |
| 549 } |
| 550 |
| 551 dict = dictionary_new(0) ; |
| 552 if (!dict) { |
| 553 fclose(in); |
| 554 return NULL ; |
| 555 } |
| 556 |
| 557 memset(line, 0, ASCIILINESZ); |
| 558 memset(section, 0, ASCIILINESZ); |
| 559 memset(key, 0, ASCIILINESZ); |
| 560 memset(val, 0, ASCIILINESZ); |
| 561 last=0 ; |
| 562 |
| 563 while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { |
| 564 lineno++ ; |
| 565 len = (int)strlen(line)-1; |
| 566 if (len==0) |
| 567 continue; |
| 568 /* Safety check against buffer overflows */ |
| 569 if (line[len]!='\n') { |
| 570 fprintf(stderr, |
| 571 "iniparser: input line too long in %s (%d)\n", |
| 572 ininame, |
| 573 lineno); |
| 574 dictionary_del(dict); |
| 575 fclose(in); |
| 576 return NULL ; |
| 577 } |
| 578 /* Get rid of \n and spaces at end of line */ |
| 579 while ((len>=0) && |
| 580 ((line[len]=='\n') || (isspace(line[len])))) { |
| 581 line[len]=0 ; |
| 582 len-- ; |
| 583 } |
| 584 /* Detect multi-line */ |
| 585 if (line[len]=='\\') { |
| 586 /* Multi-line value */ |
| 587 last=len ; |
| 588 continue ; |
| 589 } else { |
| 590 last=0 ; |
| 591 } |
| 592 switch (iniparser_line(line, section, key, val)) { |
| 593 case LINE_EMPTY: |
| 594 case LINE_COMMENT: |
| 595 break ; |
| 596 |
| 597 case LINE_SECTION: |
| 598 errs = dictionary_set(dict, section, NULL); |
| 599 break ; |
| 600 |
| 601 case LINE_VALUE: |
| 602 sprintf(tmp, "%s:%s", section, key); |
| 603 errs = dictionary_set(dict, tmp, val) ; |
| 604 break ; |
| 605 |
| 606 case LINE_ERROR: |
| 607 fprintf(stderr, "iniparser: syntax error in %s (%d):\n", |
| 608 ininame, |
| 609 lineno); |
| 610 fprintf(stderr, "-> %s\n", line); |
| 611 errs++ ; |
| 612 break; |
| 613 |
| 614 default: |
| 615 break ; |
| 616 } |
| 617 memset(line, 0, ASCIILINESZ); |
| 618 last=0; |
| 619 if (errs<0) { |
| 620 fprintf(stderr, "iniparser: memory allocation failure\n"); |
| 621 break ; |
| 622 } |
| 623 } |
| 624 if (errs) { |
| 625 dictionary_del(dict); |
| 626 dict = NULL ; |
| 627 } |
| 628 fclose(in); |
| 629 return dict ; |
| 630 } |
| 631 |
| 632 /*-------------------------------------------------------------------------*/ |
| 633 /** |
| 634 @brief Free all memory associated to an ini dictionary |
| 635 @param d Dictionary to free |
| 636 @return void |
| 637 |
| 638 Free all memory associated to an ini dictionary. |
| 639 It is mandatory to call this function before the dictionary object |
| 640 gets out of the current context. |
| 641 */ |
| 642 /*--------------------------------------------------------------------------*/ |
| 643 void iniparser_freedict(dictionary * d) |
| 644 { |
| 645 dictionary_del(d); |
| 646 } |
| 647 |
| 648 /* vim: set ts=4 et sw=4 tw=75 */ |
OLD | NEW |