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

Committer:
tobyspark
Date:
Mon Sep 17 00:33:09 2012 +0000
Revision:
0:1a9f9f36242e
//#include <unistd.h> // Not required for MBED

Who changed what in which revision?

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