http://ndevilla.free.fr/iniparser/ Welcome to iniParser -- version 3.1 released 08 Apr 2012 This modules offers parsing of ini files from the C level. See a complete documentation in HTML format, from this directory open the file html/index.html with any HTML-capable browser. Enjoy! N.Devillard Sun Apr 8 16:38:09 CEST 2012
iniparser.c
00001 00002 /*-------------------------------------------------------------------------*/ 00003 /** 00004 @file iniparser.c 00005 @author N. Devillard 00006 @brief Parser for ini files. 00007 */ 00008 /*--------------------------------------------------------------------------*/ 00009 /*---------------------------- Includes ------------------------------------*/ 00010 #include <ctype.h> 00011 #include "iniparser.h" 00012 00013 /*---------------------------- Defines -------------------------------------*/ 00014 #define ASCIILINESZ (1024) 00015 #define INI_INVALID_KEY ((char*)-1) 00016 00017 /*--------------------------------------------------------------------------- 00018 Private to this module 00019 ---------------------------------------------------------------------------*/ 00020 /** 00021 * This enum stores the status for each parsed line (internal use only). 00022 */ 00023 typedef enum _line_status_ { 00024 LINE_UNPROCESSED, 00025 LINE_ERROR, 00026 LINE_EMPTY, 00027 LINE_COMMENT, 00028 LINE_SECTION, 00029 LINE_VALUE 00030 } line_status ; 00031 00032 /*-------------------------------------------------------------------------*/ 00033 /** 00034 @brief Convert a string to lowercase. 00035 @param s String to convert. 00036 @return ptr to statically allocated string. 00037 00038 This function returns a pointer to a statically allocated string 00039 containing a lowercased version of the input string. Do not free 00040 or modify the returned string! Since the returned string is statically 00041 allocated, it will be modified at each function call (not re-entrant). 00042 */ 00043 /*--------------------------------------------------------------------------*/ 00044 static char * strlwc(const char * s) 00045 { 00046 static char l[ASCIILINESZ+1]; 00047 int i ; 00048 00049 if (s==NULL) return NULL ; 00050 memset(l, 0, ASCIILINESZ+1); 00051 i=0 ; 00052 while (s[i] && i<ASCIILINESZ) { 00053 l[i] = (char)tolower((int)s[i]); 00054 i++ ; 00055 } 00056 l[ASCIILINESZ]=(char)0; 00057 return l ; 00058 } 00059 00060 /*-------------------------------------------------------------------------*/ 00061 /** 00062 @brief Remove blanks at the beginning and the end of a string. 00063 @param s String to parse. 00064 @return ptr to statically allocated string. 00065 00066 This function returns a pointer to a statically allocated string, 00067 which is identical to the input string, except that all blank 00068 characters at the end and the beg. of the string have been removed. 00069 Do not free or modify the returned string! Since the returned string 00070 is statically allocated, it will be modified at each function call 00071 (not re-entrant). 00072 */ 00073 /*--------------------------------------------------------------------------*/ 00074 static char * strstrip(const char * s) 00075 { 00076 static char l[ASCIILINESZ+1]; 00077 char * last ; 00078 00079 if (s==NULL) return NULL ; 00080 00081 while (isspace((int)*s) && *s) s++; 00082 memset(l, 0, ASCIILINESZ+1); 00083 strcpy(l, s); 00084 last = l + strlen(l); 00085 while (last > l) { 00086 if (!isspace((int)*(last-1))) 00087 break ; 00088 last -- ; 00089 } 00090 *last = (char)0; 00091 return (char*)l ; 00092 } 00093 00094 /*-------------------------------------------------------------------------*/ 00095 /** 00096 @brief Get number of sections in a dictionary 00097 @param d Dictionary to examine 00098 @return int Number of sections found in dictionary 00099 00100 This function returns the number of sections found in a dictionary. 00101 The test to recognize sections is done on the string stored in the 00102 dictionary: a section name is given as "section" whereas a key is 00103 stored as "section:key", thus the test looks for entries that do not 00104 contain a colon. 00105 00106 This clearly fails in the case a section name contains a colon, but 00107 this should simply be avoided. 00108 00109 This function returns -1 in case of error. 00110 */ 00111 /*--------------------------------------------------------------------------*/ 00112 int iniparser_getnsec(dictionary * d) 00113 { 00114 int i ; 00115 int nsec ; 00116 00117 if (d==NULL) return -1 ; 00118 nsec=0 ; 00119 for (i=0 ; i<d->size ; i++) { 00120 if (d->key[i]==NULL) 00121 continue ; 00122 if (strchr(d->key[i], ':')==NULL) { 00123 nsec ++ ; 00124 } 00125 } 00126 return nsec ; 00127 } 00128 00129 /*-------------------------------------------------------------------------*/ 00130 /** 00131 @brief Get name for section n in a dictionary. 00132 @param d Dictionary to examine 00133 @param n Section number (from 0 to nsec-1). 00134 @return Pointer to char string 00135 00136 This function locates the n-th section in a dictionary and returns 00137 its name as a pointer to a string statically allocated inside the 00138 dictionary. Do not free or modify the returned string! 00139 00140 This function returns NULL in case of error. 00141 */ 00142 /*--------------------------------------------------------------------------*/ 00143 char * iniparser_getsecname(dictionary * d, int n) 00144 { 00145 int i ; 00146 int foundsec ; 00147 00148 if (d==NULL || n<0) return NULL ; 00149 foundsec=0 ; 00150 for (i=0 ; i<d->size ; i++) { 00151 if (d->key[i]==NULL) 00152 continue ; 00153 if (strchr(d->key[i], ':')==NULL) { 00154 foundsec++ ; 00155 if (foundsec>n) 00156 break ; 00157 } 00158 } 00159 if (foundsec<=n) { 00160 return NULL ; 00161 } 00162 return d->key[i] ; 00163 } 00164 00165 /*-------------------------------------------------------------------------*/ 00166 /** 00167 @brief Dump a dictionary to an opened file pointer. 00168 @param d Dictionary to dump. 00169 @param f Opened file pointer to dump to. 00170 @return void 00171 00172 This function prints out the contents of a dictionary, one element by 00173 line, onto the provided file pointer. It is OK to specify @c stderr 00174 or @c stdout as output files. This function is meant for debugging 00175 purposes mostly. 00176 */ 00177 /*--------------------------------------------------------------------------*/ 00178 void iniparser_dump(dictionary * d, FILE * f) 00179 { 00180 int i ; 00181 00182 if (d==NULL || f==NULL) return ; 00183 for (i=0 ; i<d->size ; i++) { 00184 if (d->key[i]==NULL) 00185 continue ; 00186 if (d->val[i]!=NULL) { 00187 fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); 00188 } else { 00189 fprintf(f, "[%s]=UNDEF\n", d->key[i]); 00190 } 00191 } 00192 return ; 00193 } 00194 00195 /*-------------------------------------------------------------------------*/ 00196 /** 00197 @brief Save a dictionary to a loadable ini file 00198 @param d Dictionary to dump 00199 @param f Opened file pointer to dump to 00200 @return void 00201 00202 This function dumps a given dictionary into a loadable ini file. 00203 It is Ok to specify @c stderr or @c stdout as output files. 00204 */ 00205 /*--------------------------------------------------------------------------*/ 00206 void iniparser_dump_ini(dictionary * d, FILE * f) 00207 { 00208 int i ; 00209 int nsec ; 00210 char * secname ; 00211 00212 if (d==NULL || f==NULL) return ; 00213 00214 nsec = iniparser_getnsec(d); 00215 if (nsec<1) { 00216 /* No section in file: dump all keys as they are */ 00217 for (i=0 ; i<d->size ; i++) { 00218 if (d->key[i]==NULL) 00219 continue ; 00220 fprintf(f, "%s = %s\n", d->key[i], d->val[i]); 00221 } 00222 return ; 00223 } 00224 for (i=0 ; i<nsec ; i++) { 00225 secname = iniparser_getsecname(d, i) ; 00226 iniparser_dumpsection_ini(d, secname, f) ; 00227 } 00228 fprintf(f, "\n"); 00229 return ; 00230 } 00231 00232 /*-------------------------------------------------------------------------*/ 00233 /** 00234 @brief Save a dictionary section to a loadable ini file 00235 @param d Dictionary to dump 00236 @param s Section name of dictionary to dump 00237 @param f Opened file pointer to dump to 00238 @return void 00239 00240 This function dumps a given section of a given dictionary into a loadable ini 00241 file. It is Ok to specify @c stderr or @c stdout as output files. 00242 */ 00243 /*--------------------------------------------------------------------------*/ 00244 void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f) 00245 { 00246 int j ; 00247 char keym[ASCIILINESZ+1]; 00248 int seclen ; 00249 00250 if (d==NULL || f==NULL) return ; 00251 if (! iniparser_find_entry(d, s)) return ; 00252 00253 seclen = (int)strlen(s); 00254 fprintf(f, "\n[%s]\n", s); 00255 sprintf(keym, "%s:", s); 00256 for (j=0 ; j<d->size ; j++) { 00257 if (d->key[j]==NULL) 00258 continue ; 00259 if (!strncmp(d->key[j], keym, seclen+1)) { 00260 fprintf(f, 00261 "%-30s = %s\n", 00262 d->key[j]+seclen+1, 00263 d->val[j] ? d->val[j] : ""); 00264 } 00265 } 00266 fprintf(f, "\n"); 00267 return ; 00268 } 00269 00270 /*-------------------------------------------------------------------------*/ 00271 /** 00272 @brief Get the number of keys in a section of a dictionary. 00273 @param d Dictionary to examine 00274 @param s Section name of dictionary to examine 00275 @return Number of keys in section 00276 */ 00277 /*--------------------------------------------------------------------------*/ 00278 int iniparser_getsecnkeys(dictionary * d, char * s) 00279 { 00280 int seclen, nkeys ; 00281 char keym[ASCIILINESZ+1]; 00282 int j ; 00283 00284 nkeys = 0; 00285 00286 if (d==NULL) return nkeys; 00287 if (! iniparser_find_entry(d, s)) return nkeys; 00288 00289 seclen = (int)strlen(s); 00290 sprintf(keym, "%s:", s); 00291 00292 for (j=0 ; j<d->size ; j++) { 00293 if (d->key[j]==NULL) 00294 continue ; 00295 if (!strncmp(d->key[j], keym, seclen+1)) 00296 nkeys++; 00297 } 00298 00299 return nkeys; 00300 00301 } 00302 00303 /*-------------------------------------------------------------------------*/ 00304 /** 00305 @brief Get the number of keys in a section of a dictionary. 00306 @param d Dictionary to examine 00307 @param s Section name of dictionary to examine 00308 @return pointer to statically allocated character strings 00309 00310 This function queries a dictionary and finds all keys in a given section. 00311 Each pointer in the returned char pointer-to-pointer is pointing to 00312 a string allocated in the dictionary; do not free or modify them. 00313 00314 This function returns NULL in case of error. 00315 */ 00316 /*--------------------------------------------------------------------------*/ 00317 char ** iniparser_getseckeys(dictionary * d, char * s) 00318 { 00319 00320 char **keys; 00321 00322 int i, j ; 00323 char keym[ASCIILINESZ+1]; 00324 int seclen, nkeys ; 00325 00326 keys = NULL; 00327 00328 if (d==NULL) return keys; 00329 if (! iniparser_find_entry(d, s)) return keys; 00330 00331 nkeys = iniparser_getsecnkeys(d, s); 00332 00333 keys = (char**) malloc(nkeys*sizeof(char*)); 00334 00335 seclen = (int)strlen(s); 00336 sprintf(keym, "%s:", s); 00337 00338 i = 0; 00339 00340 for (j=0 ; j<d->size ; j++) { 00341 if (d->key[j]==NULL) 00342 continue ; 00343 if (!strncmp(d->key[j], keym, seclen+1)) { 00344 keys[i] = d->key[j]; 00345 i++; 00346 } 00347 } 00348 00349 return keys; 00350 00351 } 00352 00353 /*-------------------------------------------------------------------------*/ 00354 /** 00355 @brief Get the string associated to a key 00356 @param d Dictionary to search 00357 @param key Key string to look for 00358 @param def Default value to return if key not found. 00359 @return pointer to statically allocated character string 00360 00361 This function queries a dictionary for a key. A key as read from an 00362 ini file is given as "section:key". If the key cannot be found, 00363 the pointer passed as 'def' is returned. 00364 The returned char pointer is pointing to a string allocated in 00365 the dictionary, do not free or modify it. 00366 */ 00367 /*--------------------------------------------------------------------------*/ 00368 char * iniparser_getstring(dictionary * d, const char * key, char * def) 00369 { 00370 char * lc_key ; 00371 char * sval ; 00372 00373 if (d==NULL || key==NULL) 00374 return def ; 00375 00376 lc_key = strlwc(key); 00377 sval = dictionary_get(d, lc_key, def); 00378 return sval ; 00379 } 00380 00381 /*-------------------------------------------------------------------------*/ 00382 /** 00383 @brief Get the string associated to a key, convert to an int 00384 @param d Dictionary to search 00385 @param key Key string to look for 00386 @param notfound Value to return in case of error 00387 @return integer 00388 00389 This function queries a dictionary for a key. A key as read from an 00390 ini file is given as "section:key". If the key cannot be found, 00391 the notfound value is returned. 00392 00393 Supported values for integers include the usual C notation 00394 so decimal, octal (starting with 0) and hexadecimal (starting with 0x) 00395 are supported. Examples: 00396 00397 "42" -> 42 00398 "042" -> 34 (octal -> decimal) 00399 "0x42" -> 66 (hexa -> decimal) 00400 00401 Warning: the conversion may overflow in various ways. Conversion is 00402 totally outsourced to strtol(), see the associated man page for overflow 00403 handling. 00404 00405 Credits: Thanks to A. Becker for suggesting strtol() 00406 */ 00407 /*--------------------------------------------------------------------------*/ 00408 int iniparser_getint(dictionary * d, const char * key, int notfound) 00409 { 00410 char * str ; 00411 00412 str = iniparser_getstring(d, key, INI_INVALID_KEY); 00413 if (str==INI_INVALID_KEY) return notfound ; 00414 return (int)strtol(str, NULL, 0); 00415 } 00416 00417 /*-------------------------------------------------------------------------*/ 00418 /** 00419 @brief Get the string associated to a key, convert to a double 00420 @param d Dictionary to search 00421 @param key Key string to look for 00422 @param notfound Value to return in case of error 00423 @return double 00424 00425 This function queries a dictionary for a key. A key as read from an 00426 ini file is given as "section:key". If the key cannot be found, 00427 the notfound value is returned. 00428 */ 00429 /*--------------------------------------------------------------------------*/ 00430 double iniparser_getdouble(dictionary * d, const char * key, double notfound) 00431 { 00432 char * str ; 00433 00434 str = iniparser_getstring(d, key, INI_INVALID_KEY); 00435 if (str==INI_INVALID_KEY) return notfound ; 00436 return atof(str); 00437 } 00438 00439 /*-------------------------------------------------------------------------*/ 00440 /** 00441 @brief Get the string associated to a key, convert to a boolean 00442 @param d Dictionary to search 00443 @param key Key string to look for 00444 @param notfound Value to return in case of error 00445 @return integer 00446 00447 This function queries a dictionary for a key. A key as read from an 00448 ini file is given as "section:key". If the key cannot be found, 00449 the notfound value is returned. 00450 00451 A true boolean is found if one of the following is matched: 00452 00453 - A string starting with 'y' 00454 - A string starting with 'Y' 00455 - A string starting with 't' 00456 - A string starting with 'T' 00457 - A string starting with '1' 00458 00459 A false boolean is found if one of the following is matched: 00460 00461 - A string starting with 'n' 00462 - A string starting with 'N' 00463 - A string starting with 'f' 00464 - A string starting with 'F' 00465 - A string starting with '0' 00466 00467 The notfound value returned if no boolean is identified, does not 00468 necessarily have to be 0 or 1. 00469 */ 00470 /*--------------------------------------------------------------------------*/ 00471 int iniparser_getboolean(dictionary * d, const char * key, int notfound) 00472 { 00473 char * c ; 00474 int ret ; 00475 00476 c = iniparser_getstring(d, key, INI_INVALID_KEY); 00477 if (c==INI_INVALID_KEY) return notfound ; 00478 if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { 00479 ret = 1 ; 00480 } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { 00481 ret = 0 ; 00482 } else { 00483 ret = notfound ; 00484 } 00485 return ret; 00486 } 00487 00488 /*-------------------------------------------------------------------------*/ 00489 /** 00490 @brief Finds out if a given entry exists in a dictionary 00491 @param ini Dictionary to search 00492 @param entry Name of the entry to look for 00493 @return integer 1 if entry exists, 0 otherwise 00494 00495 Finds out if a given entry exists in the dictionary. Since sections 00496 are stored as keys with NULL associated values, this is the only way 00497 of querying for the presence of sections in a dictionary. 00498 */ 00499 /*--------------------------------------------------------------------------*/ 00500 int iniparser_find_entry( 00501 dictionary * ini, 00502 const char * entry 00503 ) 00504 { 00505 int found=0 ; 00506 if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { 00507 found = 1 ; 00508 } 00509 return found ; 00510 } 00511 00512 /*-------------------------------------------------------------------------*/ 00513 /** 00514 @brief Set an entry in a dictionary. 00515 @param ini Dictionary to modify. 00516 @param entry Entry to modify (entry name) 00517 @param val New value to associate to the entry. 00518 @return int 0 if Ok, -1 otherwise. 00519 00520 If the given entry can be found in the dictionary, it is modified to 00521 contain the provided value. If it cannot be found, -1 is returned. 00522 It is Ok to set val to NULL. 00523 */ 00524 /*--------------------------------------------------------------------------*/ 00525 int iniparser_set(dictionary * ini, const char * entry, const char * val) 00526 { 00527 return dictionary_set(ini, strlwc(entry), val) ; 00528 } 00529 00530 /*-------------------------------------------------------------------------*/ 00531 /** 00532 @brief Delete an entry in a dictionary 00533 @param ini Dictionary to modify 00534 @param entry Entry to delete (entry name) 00535 @return void 00536 00537 If the given entry can be found, it is deleted from the dictionary. 00538 */ 00539 /*--------------------------------------------------------------------------*/ 00540 void iniparser_unset(dictionary * ini, const char * entry) 00541 { 00542 dictionary_unset(ini, strlwc(entry)); 00543 } 00544 00545 /*-------------------------------------------------------------------------*/ 00546 /** 00547 @brief Load a single line from an INI file 00548 @param input_line Input line, may be concatenated multi-line input 00549 @param section Output space to store section 00550 @param key Output space to store key 00551 @param value Output space to store value 00552 @return line_status value 00553 */ 00554 /*--------------------------------------------------------------------------*/ 00555 static line_status iniparser_line( 00556 const char * input_line, 00557 char * section, 00558 char * key, 00559 char * value) 00560 { 00561 line_status sta ; 00562 char line[ASCIILINESZ+1]; 00563 int len ; 00564 00565 strcpy(line, strstrip(input_line)); 00566 len = (int)strlen(line); 00567 00568 sta = LINE_UNPROCESSED ; 00569 if (len<1) { 00570 /* Empty line */ 00571 sta = LINE_EMPTY ; 00572 } else if (line[0]=='#' || line[0]==';') { 00573 /* Comment line */ 00574 sta = LINE_COMMENT ; 00575 } else if (line[0]=='[' && line[len-1]==']') { 00576 /* Section name */ 00577 sscanf(line, "[%[^]]", section); 00578 strcpy(section, strstrip(section)); 00579 strcpy(section, strlwc(section)); 00580 sta = LINE_SECTION ; 00581 } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 00582 || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 00583 || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { 00584 /* Usual key=value, with or without comments */ 00585 strcpy(key, strstrip(key)); 00586 strcpy(key, strlwc(key)); 00587 strcpy(value, strstrip(value)); 00588 /* 00589 * sscanf cannot handle '' or "" as empty values 00590 * this is done here 00591 */ 00592 if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { 00593 value[0]=0 ; 00594 } 00595 sta = LINE_VALUE ; 00596 } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 00597 || sscanf(line, "%[^=] %[=]", key, value) == 2) { 00598 /* 00599 * Special cases: 00600 * key= 00601 * key=; 00602 * key=# 00603 */ 00604 strcpy(key, strstrip(key)); 00605 strcpy(key, strlwc(key)); 00606 value[0]=0 ; 00607 sta = LINE_VALUE ; 00608 } else { 00609 /* Generate syntax error */ 00610 sta = LINE_ERROR ; 00611 } 00612 return sta ; 00613 } 00614 00615 /*-------------------------------------------------------------------------*/ 00616 /** 00617 @brief Parse an ini file and return an allocated dictionary object 00618 @param ininame Name of the ini file to read. 00619 @return Pointer to newly allocated dictionary 00620 00621 This is the parser for ini files. This function is called, providing 00622 the name of the file to be read. It returns a dictionary object that 00623 should not be accessed directly, but through accessor functions 00624 instead. 00625 00626 The returned dictionary must be freed using iniparser_freedict(). 00627 */ 00628 /*--------------------------------------------------------------------------*/ 00629 dictionary * iniparser_load(const char * ininame) 00630 { 00631 FILE * in ; 00632 00633 char line [ASCIILINESZ+1] ; 00634 char section [ASCIILINESZ+1] ; 00635 char key [ASCIILINESZ+1] ; 00636 char tmp [ASCIILINESZ+1] ; 00637 char val [ASCIILINESZ+1] ; 00638 00639 int last=0 ; 00640 int len ; 00641 int lineno=0 ; 00642 int errs=0; 00643 00644 dictionary * dict ; 00645 00646 if ((in=fopen(ininame, "r"))==NULL) { 00647 fprintf(stderr, "iniparser: cannot open %s\n", ininame); 00648 return NULL ; 00649 } 00650 00651 dict = dictionary_new(0) ; 00652 if (!dict) { 00653 fclose(in); 00654 return NULL ; 00655 } 00656 00657 memset(line, 0, ASCIILINESZ); 00658 memset(section, 0, ASCIILINESZ); 00659 memset(key, 0, ASCIILINESZ); 00660 memset(val, 0, ASCIILINESZ); 00661 last=0 ; 00662 00663 while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { 00664 lineno++ ; 00665 len = (int)strlen(line)-1; 00666 if (len==0) 00667 continue; 00668 /* Safety check against buffer overflows */ 00669 if (line[len]!='\n') { 00670 fprintf(stderr, 00671 "iniparser: input line too long in %s (%d)\n", 00672 ininame, 00673 lineno); 00674 dictionary_del(dict); 00675 fclose(in); 00676 return NULL ; 00677 } 00678 /* Get rid of \n and spaces at end of line */ 00679 while ((len>=0) && 00680 ((line[len]=='\n') || (isspace(line[len])))) { 00681 line[len]=0 ; 00682 len-- ; 00683 } 00684 /* Detect multi-line */ 00685 if (line[len]=='\\') { 00686 /* Multi-line value */ 00687 last=len ; 00688 continue ; 00689 } else { 00690 last=0 ; 00691 } 00692 switch (iniparser_line(line, section, key, val)) { 00693 case LINE_EMPTY: 00694 case LINE_COMMENT: 00695 break ; 00696 00697 case LINE_SECTION: 00698 errs = dictionary_set(dict, section, NULL); 00699 break ; 00700 00701 case LINE_VALUE: 00702 sprintf(tmp, "%s:%s", section, key); 00703 errs = dictionary_set(dict, tmp, val) ; 00704 break ; 00705 00706 case LINE_ERROR: 00707 fprintf(stderr, "iniparser: syntax error in %s (%d):\n", 00708 ininame, 00709 lineno); 00710 fprintf(stderr, "-> %s\n", line); 00711 errs++ ; 00712 break; 00713 00714 default: 00715 break ; 00716 } 00717 memset(line, 0, ASCIILINESZ); 00718 last=0; 00719 if (errs<0) { 00720 fprintf(stderr, "iniparser: memory allocation failure\n"); 00721 break ; 00722 } 00723 } 00724 if (errs) { 00725 dictionary_del(dict); 00726 dict = NULL ; 00727 } 00728 fclose(in); 00729 return dict ; 00730 } 00731 00732 /*-------------------------------------------------------------------------*/ 00733 /** 00734 @brief Free all memory associated to an ini dictionary 00735 @param d Dictionary to free 00736 @return void 00737 00738 Free all memory associated to an ini dictionary. 00739 It is mandatory to call this function before the dictionary object 00740 gets out of the current context. 00741 */ 00742 /*--------------------------------------------------------------------------*/ 00743 void iniparser_freedict(dictionary * d) 00744 { 00745 dictionary_del(d); 00746 } 00747 00748 /* vim: set ts=4 et sw=4 tw=75 */
Generated on Tue Jul 12 2022 19:10:58 by 1.7.2