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

Dependents:   SPK-DVIMXR

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iniparser.c Source File

iniparser.c

Go to the documentation of this file.
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 */