port iniparser code for iRobotwithWIFI

Fork of iniparser by Toby Harris

Committer:
4180skrw
Date:
Tue Dec 10 02:16:00 2013 +0000
Revision:
1:452fd0d30ac6
Parent:
iniparser.c@0:1a9f9f36242e
ported for our code

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) {
4180skrw 1:452fd0d30ac6 187 int length = strlen(d->key[i]);
4180skrw 1:452fd0d30ac6 188 char buff[4];
4180skrw 1:452fd0d30ac6 189 memcpy(buff, &(d->key[i][13]),length-13);
4180skrw 1:452fd0d30ac6 190 buff[3] = '\0';
4180skrw 1:452fd0d30ac6 191
4180skrw 1:452fd0d30ac6 192 fprintf(f, "%s=%s\n", buff, d->val[i]);
tobyspark 0:1a9f9f36242e 193 } else {
4180skrw 1:452fd0d30ac6 194 fprintf(f, "[%s]\n", d->key[i]);
tobyspark 0:1a9f9f36242e 195 }
tobyspark 0:1a9f9f36242e 196 }
tobyspark 0:1a9f9f36242e 197 return ;
tobyspark 0:1a9f9f36242e 198 }
tobyspark 0:1a9f9f36242e 199
tobyspark 0:1a9f9f36242e 200 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 201 /**
tobyspark 0:1a9f9f36242e 202 @brief Save a dictionary to a loadable ini file
tobyspark 0:1a9f9f36242e 203 @param d Dictionary to dump
tobyspark 0:1a9f9f36242e 204 @param f Opened file pointer to dump to
tobyspark 0:1a9f9f36242e 205 @return void
tobyspark 0:1a9f9f36242e 206
tobyspark 0:1a9f9f36242e 207 This function dumps a given dictionary into a loadable ini file.
tobyspark 0:1a9f9f36242e 208 It is Ok to specify @c stderr or @c stdout as output files.
tobyspark 0:1a9f9f36242e 209 */
tobyspark 0:1a9f9f36242e 210 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 211 void iniparser_dump_ini(dictionary * d, FILE * f)
tobyspark 0:1a9f9f36242e 212 {
tobyspark 0:1a9f9f36242e 213 int i ;
tobyspark 0:1a9f9f36242e 214 int nsec ;
tobyspark 0:1a9f9f36242e 215 char * secname ;
tobyspark 0:1a9f9f36242e 216
tobyspark 0:1a9f9f36242e 217 if (d==NULL || f==NULL) return ;
tobyspark 0:1a9f9f36242e 218
tobyspark 0:1a9f9f36242e 219 nsec = iniparser_getnsec(d);
tobyspark 0:1a9f9f36242e 220 if (nsec<1) {
tobyspark 0:1a9f9f36242e 221 /* No section in file: dump all keys as they are */
tobyspark 0:1a9f9f36242e 222 for (i=0 ; i<d->size ; i++) {
tobyspark 0:1a9f9f36242e 223 if (d->key[i]==NULL)
tobyspark 0:1a9f9f36242e 224 continue ;
tobyspark 0:1a9f9f36242e 225 fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
tobyspark 0:1a9f9f36242e 226 }
tobyspark 0:1a9f9f36242e 227 return ;
tobyspark 0:1a9f9f36242e 228 }
tobyspark 0:1a9f9f36242e 229 for (i=0 ; i<nsec ; i++) {
tobyspark 0:1a9f9f36242e 230 secname = iniparser_getsecname(d, i) ;
tobyspark 0:1a9f9f36242e 231 iniparser_dumpsection_ini(d, secname, f) ;
tobyspark 0:1a9f9f36242e 232 }
tobyspark 0:1a9f9f36242e 233 fprintf(f, "\n");
tobyspark 0:1a9f9f36242e 234 return ;
tobyspark 0:1a9f9f36242e 235 }
tobyspark 0:1a9f9f36242e 236
tobyspark 0:1a9f9f36242e 237 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 238 /**
tobyspark 0:1a9f9f36242e 239 @brief Save a dictionary section to a loadable ini file
tobyspark 0:1a9f9f36242e 240 @param d Dictionary to dump
tobyspark 0:1a9f9f36242e 241 @param s Section name of dictionary to dump
tobyspark 0:1a9f9f36242e 242 @param f Opened file pointer to dump to
tobyspark 0:1a9f9f36242e 243 @return void
tobyspark 0:1a9f9f36242e 244
tobyspark 0:1a9f9f36242e 245 This function dumps a given section of a given dictionary into a loadable ini
tobyspark 0:1a9f9f36242e 246 file. It is Ok to specify @c stderr or @c stdout as output files.
tobyspark 0:1a9f9f36242e 247 */
tobyspark 0:1a9f9f36242e 248 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 249 void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f)
tobyspark 0:1a9f9f36242e 250 {
tobyspark 0:1a9f9f36242e 251 int j ;
tobyspark 0:1a9f9f36242e 252 char keym[ASCIILINESZ+1];
tobyspark 0:1a9f9f36242e 253 int seclen ;
tobyspark 0:1a9f9f36242e 254
tobyspark 0:1a9f9f36242e 255 if (d==NULL || f==NULL) return ;
tobyspark 0:1a9f9f36242e 256 if (! iniparser_find_entry(d, s)) return ;
tobyspark 0:1a9f9f36242e 257
tobyspark 0:1a9f9f36242e 258 seclen = (int)strlen(s);
tobyspark 0:1a9f9f36242e 259 fprintf(f, "\n[%s]\n", s);
tobyspark 0:1a9f9f36242e 260 sprintf(keym, "%s:", s);
tobyspark 0:1a9f9f36242e 261 for (j=0 ; j<d->size ; j++) {
tobyspark 0:1a9f9f36242e 262 if (d->key[j]==NULL)
tobyspark 0:1a9f9f36242e 263 continue ;
tobyspark 0:1a9f9f36242e 264 if (!strncmp(d->key[j], keym, seclen+1)) {
tobyspark 0:1a9f9f36242e 265 fprintf(f,
tobyspark 0:1a9f9f36242e 266 "%-30s = %s\n",
tobyspark 0:1a9f9f36242e 267 d->key[j]+seclen+1,
tobyspark 0:1a9f9f36242e 268 d->val[j] ? d->val[j] : "");
tobyspark 0:1a9f9f36242e 269 }
tobyspark 0:1a9f9f36242e 270 }
tobyspark 0:1a9f9f36242e 271 fprintf(f, "\n");
tobyspark 0:1a9f9f36242e 272 return ;
tobyspark 0:1a9f9f36242e 273 }
tobyspark 0:1a9f9f36242e 274
tobyspark 0:1a9f9f36242e 275 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 276 /**
tobyspark 0:1a9f9f36242e 277 @brief Get the number of keys in a section of a dictionary.
tobyspark 0:1a9f9f36242e 278 @param d Dictionary to examine
tobyspark 0:1a9f9f36242e 279 @param s Section name of dictionary to examine
tobyspark 0:1a9f9f36242e 280 @return Number of keys in section
tobyspark 0:1a9f9f36242e 281 */
tobyspark 0:1a9f9f36242e 282 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 283 int iniparser_getsecnkeys(dictionary * d, char * s)
tobyspark 0:1a9f9f36242e 284 {
tobyspark 0:1a9f9f36242e 285 int seclen, nkeys ;
tobyspark 0:1a9f9f36242e 286 char keym[ASCIILINESZ+1];
tobyspark 0:1a9f9f36242e 287 int j ;
tobyspark 0:1a9f9f36242e 288
tobyspark 0:1a9f9f36242e 289 nkeys = 0;
tobyspark 0:1a9f9f36242e 290
tobyspark 0:1a9f9f36242e 291 if (d==NULL) return nkeys;
tobyspark 0:1a9f9f36242e 292 if (! iniparser_find_entry(d, s)) return nkeys;
tobyspark 0:1a9f9f36242e 293
tobyspark 0:1a9f9f36242e 294 seclen = (int)strlen(s);
tobyspark 0:1a9f9f36242e 295 sprintf(keym, "%s:", s);
tobyspark 0:1a9f9f36242e 296
tobyspark 0:1a9f9f36242e 297 for (j=0 ; j<d->size ; j++) {
tobyspark 0:1a9f9f36242e 298 if (d->key[j]==NULL)
tobyspark 0:1a9f9f36242e 299 continue ;
tobyspark 0:1a9f9f36242e 300 if (!strncmp(d->key[j], keym, seclen+1))
tobyspark 0:1a9f9f36242e 301 nkeys++;
tobyspark 0:1a9f9f36242e 302 }
tobyspark 0:1a9f9f36242e 303
tobyspark 0:1a9f9f36242e 304 return nkeys;
tobyspark 0:1a9f9f36242e 305
tobyspark 0:1a9f9f36242e 306 }
tobyspark 0:1a9f9f36242e 307
tobyspark 0:1a9f9f36242e 308 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 309 /**
tobyspark 0:1a9f9f36242e 310 @brief Get the number of keys in a section of a dictionary.
tobyspark 0:1a9f9f36242e 311 @param d Dictionary to examine
tobyspark 0:1a9f9f36242e 312 @param s Section name of dictionary to examine
tobyspark 0:1a9f9f36242e 313 @return pointer to statically allocated character strings
tobyspark 0:1a9f9f36242e 314
tobyspark 0:1a9f9f36242e 315 This function queries a dictionary and finds all keys in a given section.
tobyspark 0:1a9f9f36242e 316 Each pointer in the returned char pointer-to-pointer is pointing to
tobyspark 0:1a9f9f36242e 317 a string allocated in the dictionary; do not free or modify them.
tobyspark 0:1a9f9f36242e 318
tobyspark 0:1a9f9f36242e 319 This function returns NULL in case of error.
tobyspark 0:1a9f9f36242e 320 */
tobyspark 0:1a9f9f36242e 321 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 322 char ** iniparser_getseckeys(dictionary * d, char * s)
tobyspark 0:1a9f9f36242e 323 {
tobyspark 0:1a9f9f36242e 324
tobyspark 0:1a9f9f36242e 325 char **keys;
tobyspark 0:1a9f9f36242e 326
tobyspark 0:1a9f9f36242e 327 int i, j ;
tobyspark 0:1a9f9f36242e 328 char keym[ASCIILINESZ+1];
tobyspark 0:1a9f9f36242e 329 int seclen, nkeys ;
tobyspark 0:1a9f9f36242e 330
tobyspark 0:1a9f9f36242e 331 keys = NULL;
tobyspark 0:1a9f9f36242e 332
tobyspark 0:1a9f9f36242e 333 if (d==NULL) return keys;
tobyspark 0:1a9f9f36242e 334 if (! iniparser_find_entry(d, s)) return keys;
tobyspark 0:1a9f9f36242e 335
tobyspark 0:1a9f9f36242e 336 nkeys = iniparser_getsecnkeys(d, s);
tobyspark 0:1a9f9f36242e 337
tobyspark 0:1a9f9f36242e 338 keys = (char**) malloc(nkeys*sizeof(char*));
tobyspark 0:1a9f9f36242e 339
tobyspark 0:1a9f9f36242e 340 seclen = (int)strlen(s);
tobyspark 0:1a9f9f36242e 341 sprintf(keym, "%s:", s);
tobyspark 0:1a9f9f36242e 342
tobyspark 0:1a9f9f36242e 343 i = 0;
tobyspark 0:1a9f9f36242e 344
tobyspark 0:1a9f9f36242e 345 for (j=0 ; j<d->size ; j++) {
tobyspark 0:1a9f9f36242e 346 if (d->key[j]==NULL)
tobyspark 0:1a9f9f36242e 347 continue ;
tobyspark 0:1a9f9f36242e 348 if (!strncmp(d->key[j], keym, seclen+1)) {
tobyspark 0:1a9f9f36242e 349 keys[i] = d->key[j];
tobyspark 0:1a9f9f36242e 350 i++;
tobyspark 0:1a9f9f36242e 351 }
tobyspark 0:1a9f9f36242e 352 }
tobyspark 0:1a9f9f36242e 353
tobyspark 0:1a9f9f36242e 354 return keys;
tobyspark 0:1a9f9f36242e 355
tobyspark 0:1a9f9f36242e 356 }
tobyspark 0:1a9f9f36242e 357
tobyspark 0:1a9f9f36242e 358 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 359 /**
tobyspark 0:1a9f9f36242e 360 @brief Get the string associated to a key
tobyspark 0:1a9f9f36242e 361 @param d Dictionary to search
tobyspark 0:1a9f9f36242e 362 @param key Key string to look for
tobyspark 0:1a9f9f36242e 363 @param def Default value to return if key not found.
tobyspark 0:1a9f9f36242e 364 @return pointer to statically allocated character string
tobyspark 0:1a9f9f36242e 365
tobyspark 0:1a9f9f36242e 366 This function queries a dictionary for a key. A key as read from an
tobyspark 0:1a9f9f36242e 367 ini file is given as "section:key". If the key cannot be found,
tobyspark 0:1a9f9f36242e 368 the pointer passed as 'def' is returned.
tobyspark 0:1a9f9f36242e 369 The returned char pointer is pointing to a string allocated in
tobyspark 0:1a9f9f36242e 370 the dictionary, do not free or modify it.
tobyspark 0:1a9f9f36242e 371 */
tobyspark 0:1a9f9f36242e 372 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 373 char * iniparser_getstring(dictionary * d, const char * key, char * def)
tobyspark 0:1a9f9f36242e 374 {
tobyspark 0:1a9f9f36242e 375 char * lc_key ;
tobyspark 0:1a9f9f36242e 376 char * sval ;
tobyspark 0:1a9f9f36242e 377
tobyspark 0:1a9f9f36242e 378 if (d==NULL || key==NULL)
tobyspark 0:1a9f9f36242e 379 return def ;
tobyspark 0:1a9f9f36242e 380
tobyspark 0:1a9f9f36242e 381 lc_key = strlwc(key);
tobyspark 0:1a9f9f36242e 382 sval = dictionary_get(d, lc_key, def);
tobyspark 0:1a9f9f36242e 383 return sval ;
tobyspark 0:1a9f9f36242e 384 }
tobyspark 0:1a9f9f36242e 385
tobyspark 0:1a9f9f36242e 386 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 387 /**
tobyspark 0:1a9f9f36242e 388 @brief Get the string associated to a key, convert to an int
tobyspark 0:1a9f9f36242e 389 @param d Dictionary to search
tobyspark 0:1a9f9f36242e 390 @param key Key string to look for
tobyspark 0:1a9f9f36242e 391 @param notfound Value to return in case of error
tobyspark 0:1a9f9f36242e 392 @return integer
tobyspark 0:1a9f9f36242e 393
tobyspark 0:1a9f9f36242e 394 This function queries a dictionary for a key. A key as read from an
tobyspark 0:1a9f9f36242e 395 ini file is given as "section:key". If the key cannot be found,
tobyspark 0:1a9f9f36242e 396 the notfound value is returned.
tobyspark 0:1a9f9f36242e 397
tobyspark 0:1a9f9f36242e 398 Supported values for integers include the usual C notation
tobyspark 0:1a9f9f36242e 399 so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
tobyspark 0:1a9f9f36242e 400 are supported. Examples:
tobyspark 0:1a9f9f36242e 401
tobyspark 0:1a9f9f36242e 402 "42" -> 42
tobyspark 0:1a9f9f36242e 403 "042" -> 34 (octal -> decimal)
tobyspark 0:1a9f9f36242e 404 "0x42" -> 66 (hexa -> decimal)
tobyspark 0:1a9f9f36242e 405
tobyspark 0:1a9f9f36242e 406 Warning: the conversion may overflow in various ways. Conversion is
tobyspark 0:1a9f9f36242e 407 totally outsourced to strtol(), see the associated man page for overflow
tobyspark 0:1a9f9f36242e 408 handling.
tobyspark 0:1a9f9f36242e 409
tobyspark 0:1a9f9f36242e 410 Credits: Thanks to A. Becker for suggesting strtol()
tobyspark 0:1a9f9f36242e 411 */
tobyspark 0:1a9f9f36242e 412 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 413 int iniparser_getint(dictionary * d, const char * key, int notfound)
tobyspark 0:1a9f9f36242e 414 {
tobyspark 0:1a9f9f36242e 415 char * str ;
tobyspark 0:1a9f9f36242e 416
tobyspark 0:1a9f9f36242e 417 str = iniparser_getstring(d, key, INI_INVALID_KEY);
tobyspark 0:1a9f9f36242e 418 if (str==INI_INVALID_KEY) return notfound ;
tobyspark 0:1a9f9f36242e 419 return (int)strtol(str, NULL, 0);
tobyspark 0:1a9f9f36242e 420 }
tobyspark 0:1a9f9f36242e 421
tobyspark 0:1a9f9f36242e 422 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 423 /**
tobyspark 0:1a9f9f36242e 424 @brief Get the string associated to a key, convert to a double
tobyspark 0:1a9f9f36242e 425 @param d Dictionary to search
tobyspark 0:1a9f9f36242e 426 @param key Key string to look for
tobyspark 0:1a9f9f36242e 427 @param notfound Value to return in case of error
tobyspark 0:1a9f9f36242e 428 @return double
tobyspark 0:1a9f9f36242e 429
tobyspark 0:1a9f9f36242e 430 This function queries a dictionary for a key. A key as read from an
tobyspark 0:1a9f9f36242e 431 ini file is given as "section:key". If the key cannot be found,
tobyspark 0:1a9f9f36242e 432 the notfound value is returned.
tobyspark 0:1a9f9f36242e 433 */
tobyspark 0:1a9f9f36242e 434 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 435 double iniparser_getdouble(dictionary * d, const char * key, double notfound)
tobyspark 0:1a9f9f36242e 436 {
tobyspark 0:1a9f9f36242e 437 char * str ;
tobyspark 0:1a9f9f36242e 438
tobyspark 0:1a9f9f36242e 439 str = iniparser_getstring(d, key, INI_INVALID_KEY);
tobyspark 0:1a9f9f36242e 440 if (str==INI_INVALID_KEY) return notfound ;
tobyspark 0:1a9f9f36242e 441 return atof(str);
tobyspark 0:1a9f9f36242e 442 }
tobyspark 0:1a9f9f36242e 443
tobyspark 0:1a9f9f36242e 444 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 445 /**
tobyspark 0:1a9f9f36242e 446 @brief Get the string associated to a key, convert to a boolean
tobyspark 0:1a9f9f36242e 447 @param d Dictionary to search
tobyspark 0:1a9f9f36242e 448 @param key Key string to look for
tobyspark 0:1a9f9f36242e 449 @param notfound Value to return in case of error
tobyspark 0:1a9f9f36242e 450 @return integer
tobyspark 0:1a9f9f36242e 451
tobyspark 0:1a9f9f36242e 452 This function queries a dictionary for a key. A key as read from an
tobyspark 0:1a9f9f36242e 453 ini file is given as "section:key". If the key cannot be found,
tobyspark 0:1a9f9f36242e 454 the notfound value is returned.
tobyspark 0:1a9f9f36242e 455
tobyspark 0:1a9f9f36242e 456 A true boolean is found if one of the following is matched:
tobyspark 0:1a9f9f36242e 457
tobyspark 0:1a9f9f36242e 458 - A string starting with 'y'
tobyspark 0:1a9f9f36242e 459 - A string starting with 'Y'
tobyspark 0:1a9f9f36242e 460 - A string starting with 't'
tobyspark 0:1a9f9f36242e 461 - A string starting with 'T'
tobyspark 0:1a9f9f36242e 462 - A string starting with '1'
tobyspark 0:1a9f9f36242e 463
tobyspark 0:1a9f9f36242e 464 A false boolean is found if one of the following is matched:
tobyspark 0:1a9f9f36242e 465
tobyspark 0:1a9f9f36242e 466 - A string starting with 'n'
tobyspark 0:1a9f9f36242e 467 - A string starting with 'N'
tobyspark 0:1a9f9f36242e 468 - A string starting with 'f'
tobyspark 0:1a9f9f36242e 469 - A string starting with 'F'
tobyspark 0:1a9f9f36242e 470 - A string starting with '0'
tobyspark 0:1a9f9f36242e 471
tobyspark 0:1a9f9f36242e 472 The notfound value returned if no boolean is identified, does not
tobyspark 0:1a9f9f36242e 473 necessarily have to be 0 or 1.
tobyspark 0:1a9f9f36242e 474 */
tobyspark 0:1a9f9f36242e 475 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 476 int iniparser_getboolean(dictionary * d, const char * key, int notfound)
tobyspark 0:1a9f9f36242e 477 {
tobyspark 0:1a9f9f36242e 478 char * c ;
tobyspark 0:1a9f9f36242e 479 int ret ;
tobyspark 0:1a9f9f36242e 480
tobyspark 0:1a9f9f36242e 481 c = iniparser_getstring(d, key, INI_INVALID_KEY);
tobyspark 0:1a9f9f36242e 482 if (c==INI_INVALID_KEY) return notfound ;
tobyspark 0:1a9f9f36242e 483 if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
tobyspark 0:1a9f9f36242e 484 ret = 1 ;
tobyspark 0:1a9f9f36242e 485 } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
tobyspark 0:1a9f9f36242e 486 ret = 0 ;
tobyspark 0:1a9f9f36242e 487 } else {
tobyspark 0:1a9f9f36242e 488 ret = notfound ;
tobyspark 0:1a9f9f36242e 489 }
tobyspark 0:1a9f9f36242e 490 return ret;
tobyspark 0:1a9f9f36242e 491 }
tobyspark 0:1a9f9f36242e 492
tobyspark 0:1a9f9f36242e 493 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 494 /**
tobyspark 0:1a9f9f36242e 495 @brief Finds out if a given entry exists in a dictionary
tobyspark 0:1a9f9f36242e 496 @param ini Dictionary to search
tobyspark 0:1a9f9f36242e 497 @param entry Name of the entry to look for
tobyspark 0:1a9f9f36242e 498 @return integer 1 if entry exists, 0 otherwise
tobyspark 0:1a9f9f36242e 499
tobyspark 0:1a9f9f36242e 500 Finds out if a given entry exists in the dictionary. Since sections
tobyspark 0:1a9f9f36242e 501 are stored as keys with NULL associated values, this is the only way
tobyspark 0:1a9f9f36242e 502 of querying for the presence of sections in a dictionary.
tobyspark 0:1a9f9f36242e 503 */
tobyspark 0:1a9f9f36242e 504 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 505 int iniparser_find_entry(
tobyspark 0:1a9f9f36242e 506 dictionary * ini,
tobyspark 0:1a9f9f36242e 507 const char * entry
tobyspark 0:1a9f9f36242e 508 )
tobyspark 0:1a9f9f36242e 509 {
tobyspark 0:1a9f9f36242e 510 int found=0 ;
tobyspark 0:1a9f9f36242e 511 if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
tobyspark 0:1a9f9f36242e 512 found = 1 ;
tobyspark 0:1a9f9f36242e 513 }
tobyspark 0:1a9f9f36242e 514 return found ;
tobyspark 0:1a9f9f36242e 515 }
tobyspark 0:1a9f9f36242e 516
tobyspark 0:1a9f9f36242e 517 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 518 /**
tobyspark 0:1a9f9f36242e 519 @brief Set an entry in a dictionary.
tobyspark 0:1a9f9f36242e 520 @param ini Dictionary to modify.
tobyspark 0:1a9f9f36242e 521 @param entry Entry to modify (entry name)
tobyspark 0:1a9f9f36242e 522 @param val New value to associate to the entry.
tobyspark 0:1a9f9f36242e 523 @return int 0 if Ok, -1 otherwise.
tobyspark 0:1a9f9f36242e 524
tobyspark 0:1a9f9f36242e 525 If the given entry can be found in the dictionary, it is modified to
tobyspark 0:1a9f9f36242e 526 contain the provided value. If it cannot be found, -1 is returned.
tobyspark 0:1a9f9f36242e 527 It is Ok to set val to NULL.
tobyspark 0:1a9f9f36242e 528 */
tobyspark 0:1a9f9f36242e 529 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 530 int iniparser_set(dictionary * ini, const char * entry, const char * val)
tobyspark 0:1a9f9f36242e 531 {
tobyspark 0:1a9f9f36242e 532 return dictionary_set(ini, strlwc(entry), val) ;
tobyspark 0:1a9f9f36242e 533 }
tobyspark 0:1a9f9f36242e 534
tobyspark 0:1a9f9f36242e 535 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 536 /**
tobyspark 0:1a9f9f36242e 537 @brief Delete an entry in a dictionary
tobyspark 0:1a9f9f36242e 538 @param ini Dictionary to modify
tobyspark 0:1a9f9f36242e 539 @param entry Entry to delete (entry name)
tobyspark 0:1a9f9f36242e 540 @return void
tobyspark 0:1a9f9f36242e 541
tobyspark 0:1a9f9f36242e 542 If the given entry can be found, it is deleted from the dictionary.
tobyspark 0:1a9f9f36242e 543 */
tobyspark 0:1a9f9f36242e 544 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 545 void iniparser_unset(dictionary * ini, const char * entry)
tobyspark 0:1a9f9f36242e 546 {
tobyspark 0:1a9f9f36242e 547 dictionary_unset(ini, strlwc(entry));
tobyspark 0:1a9f9f36242e 548 }
tobyspark 0:1a9f9f36242e 549
tobyspark 0:1a9f9f36242e 550 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 551 /**
tobyspark 0:1a9f9f36242e 552 @brief Load a single line from an INI file
tobyspark 0:1a9f9f36242e 553 @param input_line Input line, may be concatenated multi-line input
tobyspark 0:1a9f9f36242e 554 @param section Output space to store section
tobyspark 0:1a9f9f36242e 555 @param key Output space to store key
tobyspark 0:1a9f9f36242e 556 @param value Output space to store value
tobyspark 0:1a9f9f36242e 557 @return line_status value
tobyspark 0:1a9f9f36242e 558 */
tobyspark 0:1a9f9f36242e 559 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 560 static line_status iniparser_line(
tobyspark 0:1a9f9f36242e 561 const char * input_line,
tobyspark 0:1a9f9f36242e 562 char * section,
tobyspark 0:1a9f9f36242e 563 char * key,
tobyspark 0:1a9f9f36242e 564 char * value)
tobyspark 0:1a9f9f36242e 565 {
tobyspark 0:1a9f9f36242e 566 line_status sta ;
tobyspark 0:1a9f9f36242e 567 char line[ASCIILINESZ+1];
tobyspark 0:1a9f9f36242e 568 int len ;
tobyspark 0:1a9f9f36242e 569
tobyspark 0:1a9f9f36242e 570 strcpy(line, strstrip(input_line));
tobyspark 0:1a9f9f36242e 571 len = (int)strlen(line);
tobyspark 0:1a9f9f36242e 572
tobyspark 0:1a9f9f36242e 573 sta = LINE_UNPROCESSED ;
tobyspark 0:1a9f9f36242e 574 if (len<1) {
tobyspark 0:1a9f9f36242e 575 /* Empty line */
tobyspark 0:1a9f9f36242e 576 sta = LINE_EMPTY ;
tobyspark 0:1a9f9f36242e 577 } else if (line[0]=='#' || line[0]==';') {
tobyspark 0:1a9f9f36242e 578 /* Comment line */
tobyspark 0:1a9f9f36242e 579 sta = LINE_COMMENT ;
tobyspark 0:1a9f9f36242e 580 } else if (line[0]=='[' && line[len-1]==']') {
tobyspark 0:1a9f9f36242e 581 /* Section name */
tobyspark 0:1a9f9f36242e 582 sscanf(line, "[%[^]]", section);
tobyspark 0:1a9f9f36242e 583 strcpy(section, strstrip(section));
tobyspark 0:1a9f9f36242e 584 strcpy(section, strlwc(section));
tobyspark 0:1a9f9f36242e 585 sta = LINE_SECTION ;
tobyspark 0:1a9f9f36242e 586 } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
tobyspark 0:1a9f9f36242e 587 || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2
tobyspark 0:1a9f9f36242e 588 || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) {
tobyspark 0:1a9f9f36242e 589 /* Usual key=value, with or without comments */
tobyspark 0:1a9f9f36242e 590 strcpy(key, strstrip(key));
tobyspark 0:1a9f9f36242e 591 strcpy(key, strlwc(key));
tobyspark 0:1a9f9f36242e 592 strcpy(value, strstrip(value));
tobyspark 0:1a9f9f36242e 593 /*
tobyspark 0:1a9f9f36242e 594 * sscanf cannot handle '' or "" as empty values
tobyspark 0:1a9f9f36242e 595 * this is done here
tobyspark 0:1a9f9f36242e 596 */
tobyspark 0:1a9f9f36242e 597 if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
tobyspark 0:1a9f9f36242e 598 value[0]=0 ;
tobyspark 0:1a9f9f36242e 599 }
tobyspark 0:1a9f9f36242e 600 sta = LINE_VALUE ;
tobyspark 0:1a9f9f36242e 601 } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2
tobyspark 0:1a9f9f36242e 602 || sscanf(line, "%[^=] %[=]", key, value) == 2) {
tobyspark 0:1a9f9f36242e 603 /*
tobyspark 0:1a9f9f36242e 604 * Special cases:
tobyspark 0:1a9f9f36242e 605 * key=
tobyspark 0:1a9f9f36242e 606 * key=;
tobyspark 0:1a9f9f36242e 607 * key=#
tobyspark 0:1a9f9f36242e 608 */
tobyspark 0:1a9f9f36242e 609 strcpy(key, strstrip(key));
tobyspark 0:1a9f9f36242e 610 strcpy(key, strlwc(key));
tobyspark 0:1a9f9f36242e 611 value[0]=0 ;
tobyspark 0:1a9f9f36242e 612 sta = LINE_VALUE ;
tobyspark 0:1a9f9f36242e 613 } else {
tobyspark 0:1a9f9f36242e 614 /* Generate syntax error */
tobyspark 0:1a9f9f36242e 615 sta = LINE_ERROR ;
tobyspark 0:1a9f9f36242e 616 }
tobyspark 0:1a9f9f36242e 617 return sta ;
tobyspark 0:1a9f9f36242e 618 }
tobyspark 0:1a9f9f36242e 619
tobyspark 0:1a9f9f36242e 620 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 621 /**
tobyspark 0:1a9f9f36242e 622 @brief Parse an ini file and return an allocated dictionary object
tobyspark 0:1a9f9f36242e 623 @param ininame Name of the ini file to read.
tobyspark 0:1a9f9f36242e 624 @return Pointer to newly allocated dictionary
tobyspark 0:1a9f9f36242e 625
tobyspark 0:1a9f9f36242e 626 This is the parser for ini files. This function is called, providing
tobyspark 0:1a9f9f36242e 627 the name of the file to be read. It returns a dictionary object that
tobyspark 0:1a9f9f36242e 628 should not be accessed directly, but through accessor functions
tobyspark 0:1a9f9f36242e 629 instead.
tobyspark 0:1a9f9f36242e 630
tobyspark 0:1a9f9f36242e 631 The returned dictionary must be freed using iniparser_freedict().
tobyspark 0:1a9f9f36242e 632 */
tobyspark 0:1a9f9f36242e 633 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 634 dictionary * iniparser_load(const char * ininame)
tobyspark 0:1a9f9f36242e 635 {
tobyspark 0:1a9f9f36242e 636 FILE * in ;
tobyspark 0:1a9f9f36242e 637
tobyspark 0:1a9f9f36242e 638 char line [ASCIILINESZ+1] ;
tobyspark 0:1a9f9f36242e 639 char section [ASCIILINESZ+1] ;
tobyspark 0:1a9f9f36242e 640 char key [ASCIILINESZ+1] ;
tobyspark 0:1a9f9f36242e 641 char tmp [ASCIILINESZ+1] ;
tobyspark 0:1a9f9f36242e 642 char val [ASCIILINESZ+1] ;
tobyspark 0:1a9f9f36242e 643
tobyspark 0:1a9f9f36242e 644 int last=0 ;
tobyspark 0:1a9f9f36242e 645 int len ;
tobyspark 0:1a9f9f36242e 646 int lineno=0 ;
tobyspark 0:1a9f9f36242e 647 int errs=0;
tobyspark 0:1a9f9f36242e 648
tobyspark 0:1a9f9f36242e 649 dictionary * dict ;
tobyspark 0:1a9f9f36242e 650
tobyspark 0:1a9f9f36242e 651 if ((in=fopen(ininame, "r"))==NULL) {
tobyspark 0:1a9f9f36242e 652 fprintf(stderr, "iniparser: cannot open %s\n", ininame);
tobyspark 0:1a9f9f36242e 653 return NULL ;
tobyspark 0:1a9f9f36242e 654 }
tobyspark 0:1a9f9f36242e 655
tobyspark 0:1a9f9f36242e 656 dict = dictionary_new(0) ;
tobyspark 0:1a9f9f36242e 657 if (!dict) {
tobyspark 0:1a9f9f36242e 658 fclose(in);
tobyspark 0:1a9f9f36242e 659 return NULL ;
tobyspark 0:1a9f9f36242e 660 }
tobyspark 0:1a9f9f36242e 661
tobyspark 0:1a9f9f36242e 662 memset(line, 0, ASCIILINESZ);
tobyspark 0:1a9f9f36242e 663 memset(section, 0, ASCIILINESZ);
tobyspark 0:1a9f9f36242e 664 memset(key, 0, ASCIILINESZ);
tobyspark 0:1a9f9f36242e 665 memset(val, 0, ASCIILINESZ);
tobyspark 0:1a9f9f36242e 666 last=0 ;
tobyspark 0:1a9f9f36242e 667
tobyspark 0:1a9f9f36242e 668 while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) {
tobyspark 0:1a9f9f36242e 669 lineno++ ;
tobyspark 0:1a9f9f36242e 670 len = (int)strlen(line)-1;
tobyspark 0:1a9f9f36242e 671 if (len==0)
tobyspark 0:1a9f9f36242e 672 continue;
tobyspark 0:1a9f9f36242e 673 /* Safety check against buffer overflows */
tobyspark 0:1a9f9f36242e 674 if (line[len]!='\n') {
tobyspark 0:1a9f9f36242e 675 fprintf(stderr,
tobyspark 0:1a9f9f36242e 676 "iniparser: input line too long in %s (%d)\n",
tobyspark 0:1a9f9f36242e 677 ininame,
tobyspark 0:1a9f9f36242e 678 lineno);
tobyspark 0:1a9f9f36242e 679 dictionary_del(dict);
tobyspark 0:1a9f9f36242e 680 fclose(in);
tobyspark 0:1a9f9f36242e 681 return NULL ;
tobyspark 0:1a9f9f36242e 682 }
tobyspark 0:1a9f9f36242e 683 /* Get rid of \n and spaces at end of line */
tobyspark 0:1a9f9f36242e 684 while ((len>=0) &&
tobyspark 0:1a9f9f36242e 685 ((line[len]=='\n') || (isspace(line[len])))) {
tobyspark 0:1a9f9f36242e 686 line[len]=0 ;
tobyspark 0:1a9f9f36242e 687 len-- ;
tobyspark 0:1a9f9f36242e 688 }
tobyspark 0:1a9f9f36242e 689 /* Detect multi-line */
tobyspark 0:1a9f9f36242e 690 if (line[len]=='\\') {
tobyspark 0:1a9f9f36242e 691 /* Multi-line value */
tobyspark 0:1a9f9f36242e 692 last=len ;
tobyspark 0:1a9f9f36242e 693 continue ;
tobyspark 0:1a9f9f36242e 694 } else {
tobyspark 0:1a9f9f36242e 695 last=0 ;
tobyspark 0:1a9f9f36242e 696 }
tobyspark 0:1a9f9f36242e 697 switch (iniparser_line(line, section, key, val)) {
tobyspark 0:1a9f9f36242e 698 case LINE_EMPTY:
tobyspark 0:1a9f9f36242e 699 case LINE_COMMENT:
tobyspark 0:1a9f9f36242e 700 break ;
tobyspark 0:1a9f9f36242e 701
tobyspark 0:1a9f9f36242e 702 case LINE_SECTION:
tobyspark 0:1a9f9f36242e 703 errs = dictionary_set(dict, section, NULL);
tobyspark 0:1a9f9f36242e 704 break ;
tobyspark 0:1a9f9f36242e 705
tobyspark 0:1a9f9f36242e 706 case LINE_VALUE:
tobyspark 0:1a9f9f36242e 707 sprintf(tmp, "%s:%s", section, key);
tobyspark 0:1a9f9f36242e 708 errs = dictionary_set(dict, tmp, val) ;
tobyspark 0:1a9f9f36242e 709 break ;
tobyspark 0:1a9f9f36242e 710
tobyspark 0:1a9f9f36242e 711 case LINE_ERROR:
tobyspark 0:1a9f9f36242e 712 fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
tobyspark 0:1a9f9f36242e 713 ininame,
tobyspark 0:1a9f9f36242e 714 lineno);
tobyspark 0:1a9f9f36242e 715 fprintf(stderr, "-> %s\n", line);
tobyspark 0:1a9f9f36242e 716 errs++ ;
tobyspark 0:1a9f9f36242e 717 break;
tobyspark 0:1a9f9f36242e 718
tobyspark 0:1a9f9f36242e 719 default:
tobyspark 0:1a9f9f36242e 720 break ;
tobyspark 0:1a9f9f36242e 721 }
tobyspark 0:1a9f9f36242e 722 memset(line, 0, ASCIILINESZ);
tobyspark 0:1a9f9f36242e 723 last=0;
tobyspark 0:1a9f9f36242e 724 if (errs<0) {
tobyspark 0:1a9f9f36242e 725 fprintf(stderr, "iniparser: memory allocation failure\n");
tobyspark 0:1a9f9f36242e 726 break ;
tobyspark 0:1a9f9f36242e 727 }
tobyspark 0:1a9f9f36242e 728 }
tobyspark 0:1a9f9f36242e 729 if (errs) {
tobyspark 0:1a9f9f36242e 730 dictionary_del(dict);
tobyspark 0:1a9f9f36242e 731 dict = NULL ;
tobyspark 0:1a9f9f36242e 732 }
tobyspark 0:1a9f9f36242e 733 fclose(in);
tobyspark 0:1a9f9f36242e 734 return dict ;
tobyspark 0:1a9f9f36242e 735 }
tobyspark 0:1a9f9f36242e 736
tobyspark 0:1a9f9f36242e 737 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 738 /**
tobyspark 0:1a9f9f36242e 739 @brief Free all memory associated to an ini dictionary
tobyspark 0:1a9f9f36242e 740 @param d Dictionary to free
tobyspark 0:1a9f9f36242e 741 @return void
tobyspark 0:1a9f9f36242e 742
tobyspark 0:1a9f9f36242e 743 Free all memory associated to an ini dictionary.
tobyspark 0:1a9f9f36242e 744 It is mandatory to call this function before the dictionary object
tobyspark 0:1a9f9f36242e 745 gets out of the current context.
tobyspark 0:1a9f9f36242e 746 */
tobyspark 0:1a9f9f36242e 747 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 748 void iniparser_freedict(dictionary * d)
tobyspark 0:1a9f9f36242e 749 {
tobyspark 0:1a9f9f36242e 750 dictionary_del(d);
tobyspark 0:1a9f9f36242e 751 }
tobyspark 0:1a9f9f36242e 752
tobyspark 0:1a9f9f36242e 753 /* vim: set ts=4 et sw=4 tw=75 */