1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mozbase/mozprocess/tests/iniparser/iniparser.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,648 @@ 1.4 + 1.5 +/*-------------------------------------------------------------------------*/ 1.6 +/** 1.7 + @file iniparser.c 1.8 + @author N. Devillard 1.9 + @date Sep 2007 1.10 + @version 3.0 1.11 + @brief Parser for ini files. 1.12 +*/ 1.13 +/*--------------------------------------------------------------------------*/ 1.14 +/* 1.15 + $Id: iniparser.c,v 2.19 2011-03-02 20:15:13 ndevilla Exp $ 1.16 + $Revision: 2.19 $ 1.17 + $Date: 2011-03-02 20:15:13 $ 1.18 +*/ 1.19 +/*---------------------------- Includes ------------------------------------*/ 1.20 +#include <ctype.h> 1.21 +#include "iniparser.h" 1.22 + 1.23 +/*---------------------------- Defines -------------------------------------*/ 1.24 +#define ASCIILINESZ (1024) 1.25 +#define INI_INVALID_KEY ((char*)-1) 1.26 + 1.27 +/*--------------------------------------------------------------------------- 1.28 + Private to this module 1.29 + ---------------------------------------------------------------------------*/ 1.30 +/** 1.31 + * This enum stores the status for each parsed line (internal use only). 1.32 + */ 1.33 +typedef enum _line_status_ { 1.34 + LINE_UNPROCESSED, 1.35 + LINE_ERROR, 1.36 + LINE_EMPTY, 1.37 + LINE_COMMENT, 1.38 + LINE_SECTION, 1.39 + LINE_VALUE 1.40 +} line_status ; 1.41 + 1.42 +/*-------------------------------------------------------------------------*/ 1.43 +/** 1.44 + @brief Convert a string to lowercase. 1.45 + @param s String to convert. 1.46 + @return ptr to statically allocated string. 1.47 + 1.48 + This function returns a pointer to a statically allocated string 1.49 + containing a lowercased version of the input string. Do not free 1.50 + or modify the returned string! Since the returned string is statically 1.51 + allocated, it will be modified at each function call (not re-entrant). 1.52 + */ 1.53 +/*--------------------------------------------------------------------------*/ 1.54 +static char * strlwc(char * s) 1.55 +{ 1.56 + static char l[ASCIILINESZ+1]; 1.57 + int i ; 1.58 + 1.59 + if (s==NULL) return NULL ; 1.60 + memset(l, 0, ASCIILINESZ+1); 1.61 + i=0 ; 1.62 + while (s[i] && i<ASCIILINESZ) { 1.63 + l[i] = (char)tolower((int)s[i]); 1.64 + i++ ; 1.65 + } 1.66 + l[ASCIILINESZ]=(char)0; 1.67 + return l ; 1.68 +} 1.69 + 1.70 +/*-------------------------------------------------------------------------*/ 1.71 +/** 1.72 + @brief Remove blanks at the beginning and the end of a string. 1.73 + @param s String to parse. 1.74 + @return ptr to statically allocated string. 1.75 + 1.76 + This function returns a pointer to a statically allocated string, 1.77 + which is identical to the input string, except that all blank 1.78 + characters at the end and the beg. of the string have been removed. 1.79 + Do not free or modify the returned string! Since the returned string 1.80 + is statically allocated, it will be modified at each function call 1.81 + (not re-entrant). 1.82 + */ 1.83 +/*--------------------------------------------------------------------------*/ 1.84 +static char * strstrip(char * s) 1.85 +{ 1.86 + static char l[ASCIILINESZ+1]; 1.87 + char * last ; 1.88 + 1.89 + if (s==NULL) return NULL ; 1.90 + 1.91 + while (isspace((int)*s) && *s) s++; 1.92 + memset(l, 0, ASCIILINESZ+1); 1.93 + strcpy(l, s); 1.94 + last = l + strlen(l); 1.95 + while (last > l) { 1.96 + if (!isspace((int)*(last-1))) 1.97 + break ; 1.98 + last -- ; 1.99 + } 1.100 + *last = (char)0; 1.101 + return (char*)l ; 1.102 +} 1.103 + 1.104 +/*-------------------------------------------------------------------------*/ 1.105 +/** 1.106 + @brief Get number of sections in a dictionary 1.107 + @param d Dictionary to examine 1.108 + @return int Number of sections found in dictionary 1.109 + 1.110 + This function returns the number of sections found in a dictionary. 1.111 + The test to recognize sections is done on the string stored in the 1.112 + dictionary: a section name is given as "section" whereas a key is 1.113 + stored as "section:key", thus the test looks for entries that do not 1.114 + contain a colon. 1.115 + 1.116 + This clearly fails in the case a section name contains a colon, but 1.117 + this should simply be avoided. 1.118 + 1.119 + This function returns -1 in case of error. 1.120 + */ 1.121 +/*--------------------------------------------------------------------------*/ 1.122 +int iniparser_getnsec(dictionary * d) 1.123 +{ 1.124 + int i ; 1.125 + int nsec ; 1.126 + 1.127 + if (d==NULL) return -1 ; 1.128 + nsec=0 ; 1.129 + for (i=0 ; i<d->size ; i++) { 1.130 + if (d->key[i]==NULL) 1.131 + continue ; 1.132 + if (strchr(d->key[i], ':')==NULL) { 1.133 + nsec ++ ; 1.134 + } 1.135 + } 1.136 + return nsec ; 1.137 +} 1.138 + 1.139 +/*-------------------------------------------------------------------------*/ 1.140 +/** 1.141 + @brief Get name for section n in a dictionary. 1.142 + @param d Dictionary to examine 1.143 + @param n Section number (from 0 to nsec-1). 1.144 + @return Pointer to char string 1.145 + 1.146 + This function locates the n-th section in a dictionary and returns 1.147 + its name as a pointer to a string statically allocated inside the 1.148 + dictionary. Do not free or modify the returned string! 1.149 + 1.150 + This function returns NULL in case of error. 1.151 + */ 1.152 +/*--------------------------------------------------------------------------*/ 1.153 +char * iniparser_getsecname(dictionary * d, int n) 1.154 +{ 1.155 + int i ; 1.156 + int foundsec ; 1.157 + 1.158 + if (d==NULL || n<0) return NULL ; 1.159 + foundsec=0 ; 1.160 + for (i=0 ; i<d->size ; i++) { 1.161 + if (d->key[i]==NULL) 1.162 + continue ; 1.163 + if (strchr(d->key[i], ':')==NULL) { 1.164 + foundsec++ ; 1.165 + if (foundsec>n) 1.166 + break ; 1.167 + } 1.168 + } 1.169 + if (foundsec<=n) { 1.170 + return NULL ; 1.171 + } 1.172 + return d->key[i] ; 1.173 +} 1.174 + 1.175 +/*-------------------------------------------------------------------------*/ 1.176 +/** 1.177 + @brief Dump a dictionary to an opened file pointer. 1.178 + @param d Dictionary to dump. 1.179 + @param f Opened file pointer to dump to. 1.180 + @return void 1.181 + 1.182 + This function prints out the contents of a dictionary, one element by 1.183 + line, onto the provided file pointer. It is OK to specify @c stderr 1.184 + or @c stdout as output files. This function is meant for debugging 1.185 + purposes mostly. 1.186 + */ 1.187 +/*--------------------------------------------------------------------------*/ 1.188 +void iniparser_dump(dictionary * d, FILE * f) 1.189 +{ 1.190 + int i ; 1.191 + 1.192 + if (d==NULL || f==NULL) return ; 1.193 + for (i=0 ; i<d->size ; i++) { 1.194 + if (d->key[i]==NULL) 1.195 + continue ; 1.196 + if (d->val[i]!=NULL) { 1.197 + fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); 1.198 + } else { 1.199 + fprintf(f, "[%s]=UNDEF\n", d->key[i]); 1.200 + } 1.201 + } 1.202 + return ; 1.203 +} 1.204 + 1.205 +/*-------------------------------------------------------------------------*/ 1.206 +/** 1.207 + @brief Save a dictionary to a loadable ini file 1.208 + @param d Dictionary to dump 1.209 + @param f Opened file pointer to dump to 1.210 + @return void 1.211 + 1.212 + This function dumps a given dictionary into a loadable ini file. 1.213 + It is Ok to specify @c stderr or @c stdout as output files. 1.214 + */ 1.215 +/*--------------------------------------------------------------------------*/ 1.216 +void iniparser_dump_ini(dictionary * d, FILE * f) 1.217 +{ 1.218 + int i, j ; 1.219 + char keym[ASCIILINESZ+1]; 1.220 + int nsec ; 1.221 + char * secname ; 1.222 + int seclen ; 1.223 + 1.224 + if (d==NULL || f==NULL) return ; 1.225 + 1.226 + nsec = iniparser_getnsec(d); 1.227 + if (nsec<1) { 1.228 + /* No section in file: dump all keys as they are */ 1.229 + for (i=0 ; i<d->size ; i++) { 1.230 + if (d->key[i]==NULL) 1.231 + continue ; 1.232 + fprintf(f, "%s = %s\n", d->key[i], d->val[i]); 1.233 + } 1.234 + return ; 1.235 + } 1.236 + for (i=0 ; i<nsec ; i++) { 1.237 + secname = iniparser_getsecname(d, i) ; 1.238 + seclen = (int)strlen(secname); 1.239 + fprintf(f, "\n[%s]\n", secname); 1.240 + sprintf(keym, "%s:", secname); 1.241 + for (j=0 ; j<d->size ; j++) { 1.242 + if (d->key[j]==NULL) 1.243 + continue ; 1.244 + if (!strncmp(d->key[j], keym, seclen+1)) { 1.245 + fprintf(f, 1.246 + "%-30s = %s\n", 1.247 + d->key[j]+seclen+1, 1.248 + d->val[j] ? d->val[j] : ""); 1.249 + } 1.250 + } 1.251 + } 1.252 + fprintf(f, "\n"); 1.253 + return ; 1.254 +} 1.255 + 1.256 +/*-------------------------------------------------------------------------*/ 1.257 +/** 1.258 + @brief Get the string associated to a key 1.259 + @param d Dictionary to search 1.260 + @param key Key string to look for 1.261 + @param def Default value to return if key not found. 1.262 + @return pointer to statically allocated character string 1.263 + 1.264 + This function queries a dictionary for a key. A key as read from an 1.265 + ini file is given as "section:key". If the key cannot be found, 1.266 + the pointer passed as 'def' is returned. 1.267 + The returned char pointer is pointing to a string allocated in 1.268 + the dictionary, do not free or modify it. 1.269 + */ 1.270 +/*--------------------------------------------------------------------------*/ 1.271 +char * iniparser_getstring(dictionary * d, char * key, char * def) 1.272 +{ 1.273 + char * lc_key ; 1.274 + char * sval ; 1.275 + 1.276 + if (d==NULL || key==NULL) 1.277 + return def ; 1.278 + 1.279 + lc_key = strlwc(key); 1.280 + sval = dictionary_get(d, lc_key, def); 1.281 + return sval ; 1.282 +} 1.283 + 1.284 +/*-------------------------------------------------------------------------*/ 1.285 +/** 1.286 + @brief Get the string associated to a key, convert to an int 1.287 + @param d Dictionary to search 1.288 + @param key Key string to look for 1.289 + @param notfound Value to return in case of error 1.290 + @return integer 1.291 + 1.292 + This function queries a dictionary for a key. A key as read from an 1.293 + ini file is given as "section:key". If the key cannot be found, 1.294 + the notfound value is returned. 1.295 + 1.296 + Supported values for integers include the usual C notation 1.297 + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) 1.298 + are supported. Examples: 1.299 + 1.300 + "42" -> 42 1.301 + "042" -> 34 (octal -> decimal) 1.302 + "0x42" -> 66 (hexa -> decimal) 1.303 + 1.304 + Warning: the conversion may overflow in various ways. Conversion is 1.305 + totally outsourced to strtol(), see the associated man page for overflow 1.306 + handling. 1.307 + 1.308 + Credits: Thanks to A. Becker for suggesting strtol() 1.309 + */ 1.310 +/*--------------------------------------------------------------------------*/ 1.311 +int iniparser_getint(dictionary * d, char * key, int notfound) 1.312 +{ 1.313 + char * str ; 1.314 + 1.315 + str = iniparser_getstring(d, key, INI_INVALID_KEY); 1.316 + if (str==INI_INVALID_KEY) return notfound ; 1.317 + return (int)strtol(str, NULL, 0); 1.318 +} 1.319 + 1.320 +/*-------------------------------------------------------------------------*/ 1.321 +/** 1.322 + @brief Get the string associated to a key, convert to a double 1.323 + @param d Dictionary to search 1.324 + @param key Key string to look for 1.325 + @param notfound Value to return in case of error 1.326 + @return double 1.327 + 1.328 + This function queries a dictionary for a key. A key as read from an 1.329 + ini file is given as "section:key". If the key cannot be found, 1.330 + the notfound value is returned. 1.331 + */ 1.332 +/*--------------------------------------------------------------------------*/ 1.333 +double iniparser_getdouble(dictionary * d, char * key, double notfound) 1.334 +{ 1.335 + char * str ; 1.336 + 1.337 + str = iniparser_getstring(d, key, INI_INVALID_KEY); 1.338 + if (str==INI_INVALID_KEY) return notfound ; 1.339 + return atof(str); 1.340 +} 1.341 + 1.342 +/*-------------------------------------------------------------------------*/ 1.343 +/** 1.344 + @brief Get the string associated to a key, convert to a boolean 1.345 + @param d Dictionary to search 1.346 + @param key Key string to look for 1.347 + @param notfound Value to return in case of error 1.348 + @return integer 1.349 + 1.350 + This function queries a dictionary for a key. A key as read from an 1.351 + ini file is given as "section:key". If the key cannot be found, 1.352 + the notfound value is returned. 1.353 + 1.354 + A true boolean is found if one of the following is matched: 1.355 + 1.356 + - A string starting with 'y' 1.357 + - A string starting with 'Y' 1.358 + - A string starting with 't' 1.359 + - A string starting with 'T' 1.360 + - A string starting with '1' 1.361 + 1.362 + A false boolean is found if one of the following is matched: 1.363 + 1.364 + - A string starting with 'n' 1.365 + - A string starting with 'N' 1.366 + - A string starting with 'f' 1.367 + - A string starting with 'F' 1.368 + - A string starting with '0' 1.369 + 1.370 + The notfound value returned if no boolean is identified, does not 1.371 + necessarily have to be 0 or 1. 1.372 + */ 1.373 +/*--------------------------------------------------------------------------*/ 1.374 +int iniparser_getboolean(dictionary * d, char * key, int notfound) 1.375 +{ 1.376 + char * c ; 1.377 + int ret ; 1.378 + 1.379 + c = iniparser_getstring(d, key, INI_INVALID_KEY); 1.380 + if (c==INI_INVALID_KEY) return notfound ; 1.381 + if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { 1.382 + ret = 1 ; 1.383 + } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { 1.384 + ret = 0 ; 1.385 + } else { 1.386 + ret = notfound ; 1.387 + } 1.388 + return ret; 1.389 +} 1.390 + 1.391 +/*-------------------------------------------------------------------------*/ 1.392 +/** 1.393 + @brief Finds out if a given entry exists in a dictionary 1.394 + @param ini Dictionary to search 1.395 + @param entry Name of the entry to look for 1.396 + @return integer 1 if entry exists, 0 otherwise 1.397 + 1.398 + Finds out if a given entry exists in the dictionary. Since sections 1.399 + are stored as keys with NULL associated values, this is the only way 1.400 + of querying for the presence of sections in a dictionary. 1.401 + */ 1.402 +/*--------------------------------------------------------------------------*/ 1.403 +int iniparser_find_entry( 1.404 + dictionary * ini, 1.405 + char * entry 1.406 +) 1.407 +{ 1.408 + int found=0 ; 1.409 + if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { 1.410 + found = 1 ; 1.411 + } 1.412 + return found ; 1.413 +} 1.414 + 1.415 +/*-------------------------------------------------------------------------*/ 1.416 +/** 1.417 + @brief Set an entry in a dictionary. 1.418 + @param ini Dictionary to modify. 1.419 + @param entry Entry to modify (entry name) 1.420 + @param val New value to associate to the entry. 1.421 + @return int 0 if Ok, -1 otherwise. 1.422 + 1.423 + If the given entry can be found in the dictionary, it is modified to 1.424 + contain the provided value. If it cannot be found, -1 is returned. 1.425 + It is Ok to set val to NULL. 1.426 + */ 1.427 +/*--------------------------------------------------------------------------*/ 1.428 +int iniparser_set(dictionary * ini, char * entry, char * val) 1.429 +{ 1.430 + return dictionary_set(ini, strlwc(entry), val) ; 1.431 +} 1.432 + 1.433 +/*-------------------------------------------------------------------------*/ 1.434 +/** 1.435 + @brief Delete an entry in a dictionary 1.436 + @param ini Dictionary to modify 1.437 + @param entry Entry to delete (entry name) 1.438 + @return void 1.439 + 1.440 + If the given entry can be found, it is deleted from the dictionary. 1.441 + */ 1.442 +/*--------------------------------------------------------------------------*/ 1.443 +void iniparser_unset(dictionary * ini, char * entry) 1.444 +{ 1.445 + dictionary_unset(ini, strlwc(entry)); 1.446 +} 1.447 + 1.448 +/*-------------------------------------------------------------------------*/ 1.449 +/** 1.450 + @brief Load a single line from an INI file 1.451 + @param input_line Input line, may be concatenated multi-line input 1.452 + @param section Output space to store section 1.453 + @param key Output space to store key 1.454 + @param value Output space to store value 1.455 + @return line_status value 1.456 + */ 1.457 +/*--------------------------------------------------------------------------*/ 1.458 +static line_status iniparser_line( 1.459 + char * input_line, 1.460 + char * section, 1.461 + char * key, 1.462 + char * value) 1.463 +{ 1.464 + line_status sta ; 1.465 + char line[ASCIILINESZ+1]; 1.466 + int len ; 1.467 + 1.468 + strcpy(line, strstrip(input_line)); 1.469 + len = (int)strlen(line); 1.470 + 1.471 + sta = LINE_UNPROCESSED ; 1.472 + if (len<1) { 1.473 + /* Empty line */ 1.474 + sta = LINE_EMPTY ; 1.475 + } else if (line[0]=='#' || line[0]==';') { 1.476 + /* Comment line */ 1.477 + sta = LINE_COMMENT ; 1.478 + } else if (line[0]=='[' && line[len-1]==']') { 1.479 + /* Section name */ 1.480 + sscanf(line, "[%[^]]", section); 1.481 + strcpy(section, strstrip(section)); 1.482 + strcpy(section, strlwc(section)); 1.483 + sta = LINE_SECTION ; 1.484 + } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 1.485 + || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 1.486 + || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { 1.487 + /* Usual key=value, with or without comments */ 1.488 + strcpy(key, strstrip(key)); 1.489 + strcpy(key, strlwc(key)); 1.490 + strcpy(value, strstrip(value)); 1.491 + /* 1.492 + * sscanf cannot handle '' or "" as empty values 1.493 + * this is done here 1.494 + */ 1.495 + if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { 1.496 + value[0]=0 ; 1.497 + } 1.498 + sta = LINE_VALUE ; 1.499 + } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 1.500 + || sscanf(line, "%[^=] %[=]", key, value) == 2) { 1.501 + /* 1.502 + * Special cases: 1.503 + * key= 1.504 + * key=; 1.505 + * key=# 1.506 + */ 1.507 + strcpy(key, strstrip(key)); 1.508 + strcpy(key, strlwc(key)); 1.509 + value[0]=0 ; 1.510 + sta = LINE_VALUE ; 1.511 + } else { 1.512 + /* Generate syntax error */ 1.513 + sta = LINE_ERROR ; 1.514 + } 1.515 + return sta ; 1.516 +} 1.517 + 1.518 +/*-------------------------------------------------------------------------*/ 1.519 +/** 1.520 + @brief Parse an ini file and return an allocated dictionary object 1.521 + @param ininame Name of the ini file to read. 1.522 + @return Pointer to newly allocated dictionary 1.523 + 1.524 + This is the parser for ini files. This function is called, providing 1.525 + the name of the file to be read. It returns a dictionary object that 1.526 + should not be accessed directly, but through accessor functions 1.527 + instead. 1.528 + 1.529 + The returned dictionary must be freed using iniparser_freedict(). 1.530 + */ 1.531 +/*--------------------------------------------------------------------------*/ 1.532 +dictionary * iniparser_load(char * ininame) 1.533 +{ 1.534 + FILE * in ; 1.535 + 1.536 + char line [ASCIILINESZ+1] ; 1.537 + char section [ASCIILINESZ+1] ; 1.538 + char key [ASCIILINESZ+1] ; 1.539 + char tmp [ASCIILINESZ+1] ; 1.540 + char val [ASCIILINESZ+1] ; 1.541 + 1.542 + int last=0 ; 1.543 + int len ; 1.544 + int lineno=0 ; 1.545 + int errs=0; 1.546 + 1.547 + dictionary * dict ; 1.548 + 1.549 + if ((in=fopen(ininame, "r"))==NULL) { 1.550 + fprintf(stderr, "iniparser: cannot open %s\n", ininame); 1.551 + return NULL ; 1.552 + } 1.553 + 1.554 + dict = dictionary_new(0) ; 1.555 + if (!dict) { 1.556 + fclose(in); 1.557 + return NULL ; 1.558 + } 1.559 + 1.560 + memset(line, 0, ASCIILINESZ); 1.561 + memset(section, 0, ASCIILINESZ); 1.562 + memset(key, 0, ASCIILINESZ); 1.563 + memset(val, 0, ASCIILINESZ); 1.564 + last=0 ; 1.565 + 1.566 + while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { 1.567 + lineno++ ; 1.568 + len = (int)strlen(line)-1; 1.569 + if (len==0) 1.570 + continue; 1.571 + /* Safety check against buffer overflows */ 1.572 + if (line[len]!='\n') { 1.573 + fprintf(stderr, 1.574 + "iniparser: input line too long in %s (%d)\n", 1.575 + ininame, 1.576 + lineno); 1.577 + dictionary_del(dict); 1.578 + fclose(in); 1.579 + return NULL ; 1.580 + } 1.581 + /* Get rid of \n and spaces at end of line */ 1.582 + while ((len>=0) && 1.583 + ((line[len]=='\n') || (isspace(line[len])))) { 1.584 + line[len]=0 ; 1.585 + len-- ; 1.586 + } 1.587 + /* Detect multi-line */ 1.588 + if (line[len]=='\\') { 1.589 + /* Multi-line value */ 1.590 + last=len ; 1.591 + continue ; 1.592 + } else { 1.593 + last=0 ; 1.594 + } 1.595 + switch (iniparser_line(line, section, key, val)) { 1.596 + case LINE_EMPTY: 1.597 + case LINE_COMMENT: 1.598 + break ; 1.599 + 1.600 + case LINE_SECTION: 1.601 + errs = dictionary_set(dict, section, NULL); 1.602 + break ; 1.603 + 1.604 + case LINE_VALUE: 1.605 + sprintf(tmp, "%s:%s", section, key); 1.606 + errs = dictionary_set(dict, tmp, val) ; 1.607 + break ; 1.608 + 1.609 + case LINE_ERROR: 1.610 + fprintf(stderr, "iniparser: syntax error in %s (%d):\n", 1.611 + ininame, 1.612 + lineno); 1.613 + fprintf(stderr, "-> %s\n", line); 1.614 + errs++ ; 1.615 + break; 1.616 + 1.617 + default: 1.618 + break ; 1.619 + } 1.620 + memset(line, 0, ASCIILINESZ); 1.621 + last=0; 1.622 + if (errs<0) { 1.623 + fprintf(stderr, "iniparser: memory allocation failure\n"); 1.624 + break ; 1.625 + } 1.626 + } 1.627 + if (errs) { 1.628 + dictionary_del(dict); 1.629 + dict = NULL ; 1.630 + } 1.631 + fclose(in); 1.632 + return dict ; 1.633 +} 1.634 + 1.635 +/*-------------------------------------------------------------------------*/ 1.636 +/** 1.637 + @brief Free all memory associated to an ini dictionary 1.638 + @param d Dictionary to free 1.639 + @return void 1.640 + 1.641 + Free all memory associated to an ini dictionary. 1.642 + It is mandatory to call this function before the dictionary object 1.643 + gets out of the current context. 1.644 + */ 1.645 +/*--------------------------------------------------------------------------*/ 1.646 +void iniparser_freedict(dictionary * d) 1.647 +{ 1.648 + dictionary_del(d); 1.649 +} 1.650 + 1.651 +/* vim: set ts=4 et sw=4 tw=75 */