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 @file dictionary.c
tobyspark 0:1a9f9f36242e 4 @author N. Devillard
tobyspark 0:1a9f9f36242e 5 @brief Implements a dictionary for string variables.
tobyspark 0:1a9f9f36242e 6
tobyspark 0:1a9f9f36242e 7 This module implements a simple dictionary object, i.e. a list
tobyspark 0:1a9f9f36242e 8 of string/string associations. This object is useful to store e.g.
tobyspark 0:1a9f9f36242e 9 informations retrieved from a configuration file (ini files).
tobyspark 0:1a9f9f36242e 10 */
tobyspark 0:1a9f9f36242e 11 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 12
tobyspark 0:1a9f9f36242e 13 /*---------------------------------------------------------------------------
tobyspark 0:1a9f9f36242e 14 Includes
tobyspark 0:1a9f9f36242e 15 ---------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 16 #include "dictionary.h"
tobyspark 0:1a9f9f36242e 17
tobyspark 0:1a9f9f36242e 18 #include <stdio.h>
tobyspark 0:1a9f9f36242e 19 #include <stdlib.h>
tobyspark 0:1a9f9f36242e 20 #include <string.h>
tobyspark 0:1a9f9f36242e 21 //#include <unistd.h> // Not required for MBED
tobyspark 0:1a9f9f36242e 22
tobyspark 0:1a9f9f36242e 23 /** Maximum value size for integers and doubles. */
tobyspark 0:1a9f9f36242e 24 #define MAXVALSZ 1024
tobyspark 0:1a9f9f36242e 25
tobyspark 0:1a9f9f36242e 26 /** Minimal allocated number of entries in a dictionary */
tobyspark 0:1a9f9f36242e 27 #define DICTMINSZ 128
tobyspark 0:1a9f9f36242e 28
tobyspark 0:1a9f9f36242e 29 /** Invalid key token */
tobyspark 0:1a9f9f36242e 30 #define DICT_INVALID_KEY ((char*)-1)
tobyspark 0:1a9f9f36242e 31
tobyspark 0:1a9f9f36242e 32 /*---------------------------------------------------------------------------
tobyspark 0:1a9f9f36242e 33 Private functions
tobyspark 0:1a9f9f36242e 34 ---------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 35
tobyspark 0:1a9f9f36242e 36 /* Doubles the allocated size associated to a pointer */
tobyspark 0:1a9f9f36242e 37 /* 'size' is the current allocated size. */
tobyspark 0:1a9f9f36242e 38 static void * mem_double(void * ptr, int size)
tobyspark 0:1a9f9f36242e 39 {
tobyspark 0:1a9f9f36242e 40 void * newptr ;
tobyspark 0:1a9f9f36242e 41
tobyspark 0:1a9f9f36242e 42 newptr = calloc(2*size, 1);
tobyspark 0:1a9f9f36242e 43 if (newptr==NULL) {
tobyspark 0:1a9f9f36242e 44 return NULL ;
tobyspark 0:1a9f9f36242e 45 }
tobyspark 0:1a9f9f36242e 46 memcpy(newptr, ptr, size);
tobyspark 0:1a9f9f36242e 47 free(ptr);
tobyspark 0:1a9f9f36242e 48 return newptr ;
tobyspark 0:1a9f9f36242e 49 }
tobyspark 0:1a9f9f36242e 50
tobyspark 0:1a9f9f36242e 51 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 52 /**
tobyspark 0:1a9f9f36242e 53 @brief Duplicate a string
tobyspark 0:1a9f9f36242e 54 @param s String to duplicate
tobyspark 0:1a9f9f36242e 55 @return Pointer to a newly allocated string, to be freed with free()
tobyspark 0:1a9f9f36242e 56
tobyspark 0:1a9f9f36242e 57 This is a replacement for strdup(). This implementation is provided
tobyspark 0:1a9f9f36242e 58 for systems that do not have it.
tobyspark 0:1a9f9f36242e 59 */
tobyspark 0:1a9f9f36242e 60 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 61 static char * xstrdup(const char * s)
tobyspark 0:1a9f9f36242e 62 {
tobyspark 0:1a9f9f36242e 63 char * t ;
tobyspark 0:1a9f9f36242e 64 if (!s)
tobyspark 0:1a9f9f36242e 65 return NULL ;
tobyspark 0:1a9f9f36242e 66 t = (char*)malloc(strlen(s)+1) ;
tobyspark 0:1a9f9f36242e 67 if (t) {
tobyspark 0:1a9f9f36242e 68 strcpy(t,s);
tobyspark 0:1a9f9f36242e 69 }
tobyspark 0:1a9f9f36242e 70 return t ;
tobyspark 0:1a9f9f36242e 71 }
tobyspark 0:1a9f9f36242e 72
tobyspark 0:1a9f9f36242e 73 /*---------------------------------------------------------------------------
tobyspark 0:1a9f9f36242e 74 Function codes
tobyspark 0:1a9f9f36242e 75 ---------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 76 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 77 /**
tobyspark 0:1a9f9f36242e 78 @brief Compute the hash key for a string.
tobyspark 0:1a9f9f36242e 79 @param key Character string to use for key.
tobyspark 0:1a9f9f36242e 80 @return 1 unsigned int on at least 32 bits.
tobyspark 0:1a9f9f36242e 81
tobyspark 0:1a9f9f36242e 82 This hash function has been taken from an Article in Dr Dobbs Journal.
tobyspark 0:1a9f9f36242e 83 This is normally a collision-free function, distributing keys evenly.
tobyspark 0:1a9f9f36242e 84 The key is stored anyway in the struct so that collision can be avoided
tobyspark 0:1a9f9f36242e 85 by comparing the key itself in last resort.
tobyspark 0:1a9f9f36242e 86 */
tobyspark 0:1a9f9f36242e 87 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 88 unsigned dictionary_hash(const char * key)
tobyspark 0:1a9f9f36242e 89 {
tobyspark 0:1a9f9f36242e 90 int len ;
tobyspark 0:1a9f9f36242e 91 unsigned hash ;
tobyspark 0:1a9f9f36242e 92 int i ;
tobyspark 0:1a9f9f36242e 93
tobyspark 0:1a9f9f36242e 94 len = strlen(key);
tobyspark 0:1a9f9f36242e 95 for (hash=0, i=0 ; i<len ; i++) {
tobyspark 0:1a9f9f36242e 96 hash += (unsigned)key[i] ;
tobyspark 0:1a9f9f36242e 97 hash += (hash<<10);
tobyspark 0:1a9f9f36242e 98 hash ^= (hash>>6) ;
tobyspark 0:1a9f9f36242e 99 }
tobyspark 0:1a9f9f36242e 100 hash += (hash <<3);
tobyspark 0:1a9f9f36242e 101 hash ^= (hash >>11);
tobyspark 0:1a9f9f36242e 102 hash += (hash <<15);
tobyspark 0:1a9f9f36242e 103 return hash ;
tobyspark 0:1a9f9f36242e 104 }
tobyspark 0:1a9f9f36242e 105
tobyspark 0:1a9f9f36242e 106 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 107 /**
tobyspark 0:1a9f9f36242e 108 @brief Create a new dictionary object.
tobyspark 0:1a9f9f36242e 109 @param size Optional initial size of the dictionary.
tobyspark 0:1a9f9f36242e 110 @return 1 newly allocated dictionary objet.
tobyspark 0:1a9f9f36242e 111
tobyspark 0:1a9f9f36242e 112 This function allocates a new dictionary object of given size and returns
tobyspark 0:1a9f9f36242e 113 it. If you do not know in advance (roughly) the number of entries in the
tobyspark 0:1a9f9f36242e 114 dictionary, give size=0.
tobyspark 0:1a9f9f36242e 115 */
tobyspark 0:1a9f9f36242e 116 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 117 dictionary * dictionary_new(int size)
tobyspark 0:1a9f9f36242e 118 {
tobyspark 0:1a9f9f36242e 119 dictionary * d ;
tobyspark 0:1a9f9f36242e 120
tobyspark 0:1a9f9f36242e 121 /* If no size was specified, allocate space for DICTMINSZ */
tobyspark 0:1a9f9f36242e 122 if (size<DICTMINSZ) size=DICTMINSZ ;
tobyspark 0:1a9f9f36242e 123
tobyspark 0:1a9f9f36242e 124 if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
tobyspark 0:1a9f9f36242e 125 return NULL;
tobyspark 0:1a9f9f36242e 126 }
tobyspark 0:1a9f9f36242e 127 d->size = size ;
tobyspark 0:1a9f9f36242e 128 d->val = (char **)calloc(size, sizeof(char*));
tobyspark 0:1a9f9f36242e 129 d->key = (char **)calloc(size, sizeof(char*));
tobyspark 0:1a9f9f36242e 130 d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
tobyspark 0:1a9f9f36242e 131 return d ;
tobyspark 0:1a9f9f36242e 132 }
tobyspark 0:1a9f9f36242e 133
tobyspark 0:1a9f9f36242e 134 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 135 /**
tobyspark 0:1a9f9f36242e 136 @brief Delete a dictionary object
tobyspark 0:1a9f9f36242e 137 @param d dictionary object to deallocate.
tobyspark 0:1a9f9f36242e 138 @return void
tobyspark 0:1a9f9f36242e 139
tobyspark 0:1a9f9f36242e 140 Deallocate a dictionary object and all memory associated to it.
tobyspark 0:1a9f9f36242e 141 */
tobyspark 0:1a9f9f36242e 142 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 143 void dictionary_del(dictionary * d)
tobyspark 0:1a9f9f36242e 144 {
tobyspark 0:1a9f9f36242e 145 int i ;
tobyspark 0:1a9f9f36242e 146
tobyspark 0:1a9f9f36242e 147 if (d==NULL) return ;
tobyspark 0:1a9f9f36242e 148 for (i=0 ; i<d->size ; i++) {
tobyspark 0:1a9f9f36242e 149 if (d->key[i]!=NULL)
tobyspark 0:1a9f9f36242e 150 free(d->key[i]);
tobyspark 0:1a9f9f36242e 151 if (d->val[i]!=NULL)
tobyspark 0:1a9f9f36242e 152 free(d->val[i]);
tobyspark 0:1a9f9f36242e 153 }
tobyspark 0:1a9f9f36242e 154 free(d->val);
tobyspark 0:1a9f9f36242e 155 free(d->key);
tobyspark 0:1a9f9f36242e 156 free(d->hash);
tobyspark 0:1a9f9f36242e 157 free(d);
tobyspark 0:1a9f9f36242e 158 return ;
tobyspark 0:1a9f9f36242e 159 }
tobyspark 0:1a9f9f36242e 160
tobyspark 0:1a9f9f36242e 161 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 162 /**
tobyspark 0:1a9f9f36242e 163 @brief Get a value from a dictionary.
tobyspark 0:1a9f9f36242e 164 @param d dictionary object to search.
tobyspark 0:1a9f9f36242e 165 @param key Key to look for in the dictionary.
tobyspark 0:1a9f9f36242e 166 @param def Default value to return if key not found.
tobyspark 0:1a9f9f36242e 167 @return 1 pointer to internally allocated character string.
tobyspark 0:1a9f9f36242e 168
tobyspark 0:1a9f9f36242e 169 This function locates a key in a dictionary and returns a pointer to its
tobyspark 0:1a9f9f36242e 170 value, or the passed 'def' pointer if no such key can be found in
tobyspark 0:1a9f9f36242e 171 dictionary. The returned character pointer points to data internal to the
tobyspark 0:1a9f9f36242e 172 dictionary object, you should not try to free it or modify it.
tobyspark 0:1a9f9f36242e 173 */
tobyspark 0:1a9f9f36242e 174 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 175 char * dictionary_get(dictionary * d, const char * key, char * def)
tobyspark 0:1a9f9f36242e 176 {
tobyspark 0:1a9f9f36242e 177 unsigned hash ;
tobyspark 0:1a9f9f36242e 178 int i ;
tobyspark 0:1a9f9f36242e 179
tobyspark 0:1a9f9f36242e 180 hash = dictionary_hash(key);
tobyspark 0:1a9f9f36242e 181 for (i=0 ; i<d->size ; i++) {
tobyspark 0:1a9f9f36242e 182 if (d->key[i]==NULL)
tobyspark 0:1a9f9f36242e 183 continue ;
tobyspark 0:1a9f9f36242e 184 /* Compare hash */
tobyspark 0:1a9f9f36242e 185 if (hash==d->hash[i]) {
tobyspark 0:1a9f9f36242e 186 /* Compare string, to avoid hash collisions */
tobyspark 0:1a9f9f36242e 187 if (!strcmp(key, d->key[i])) {
tobyspark 0:1a9f9f36242e 188 return d->val[i] ;
tobyspark 0:1a9f9f36242e 189 }
tobyspark 0:1a9f9f36242e 190 }
tobyspark 0:1a9f9f36242e 191 }
tobyspark 0:1a9f9f36242e 192 return def ;
tobyspark 0:1a9f9f36242e 193 }
tobyspark 0:1a9f9f36242e 194
tobyspark 0:1a9f9f36242e 195 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 196 /**
tobyspark 0:1a9f9f36242e 197 @brief Set a value in a dictionary.
tobyspark 0:1a9f9f36242e 198 @param d dictionary object to modify.
tobyspark 0:1a9f9f36242e 199 @param key Key to modify or add.
tobyspark 0:1a9f9f36242e 200 @param val Value to add.
tobyspark 0:1a9f9f36242e 201 @return int 0 if Ok, anything else otherwise
tobyspark 0:1a9f9f36242e 202
tobyspark 0:1a9f9f36242e 203 If the given key is found in the dictionary, the associated value is
tobyspark 0:1a9f9f36242e 204 replaced by the provided one. If the key cannot be found in the
tobyspark 0:1a9f9f36242e 205 dictionary, it is added to it.
tobyspark 0:1a9f9f36242e 206
tobyspark 0:1a9f9f36242e 207 It is Ok to provide a NULL value for val, but NULL values for the dictionary
tobyspark 0:1a9f9f36242e 208 or the key are considered as errors: the function will return immediately
tobyspark 0:1a9f9f36242e 209 in such a case.
tobyspark 0:1a9f9f36242e 210
tobyspark 0:1a9f9f36242e 211 Notice that if you dictionary_set a variable to NULL, a call to
tobyspark 0:1a9f9f36242e 212 dictionary_get will return a NULL value: the variable will be found, and
tobyspark 0:1a9f9f36242e 213 its value (NULL) is returned. In other words, setting the variable
tobyspark 0:1a9f9f36242e 214 content to NULL is equivalent to deleting the variable from the
tobyspark 0:1a9f9f36242e 215 dictionary. It is not possible (in this implementation) to have a key in
tobyspark 0:1a9f9f36242e 216 the dictionary without value.
tobyspark 0:1a9f9f36242e 217
tobyspark 0:1a9f9f36242e 218 This function returns non-zero in case of failure.
tobyspark 0:1a9f9f36242e 219 */
tobyspark 0:1a9f9f36242e 220 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 221 int dictionary_set(dictionary * d, const char * key, const char * val)
tobyspark 0:1a9f9f36242e 222 {
tobyspark 0:1a9f9f36242e 223 int i ;
tobyspark 0:1a9f9f36242e 224 unsigned hash ;
tobyspark 0:1a9f9f36242e 225
tobyspark 0:1a9f9f36242e 226 if (d==NULL || key==NULL) return -1 ;
tobyspark 0:1a9f9f36242e 227
tobyspark 0:1a9f9f36242e 228 /* Compute hash for this key */
tobyspark 0:1a9f9f36242e 229 hash = dictionary_hash(key) ;
tobyspark 0:1a9f9f36242e 230 /* Find if value is already in dictionary */
tobyspark 0:1a9f9f36242e 231 if (d->n>0) {
tobyspark 0:1a9f9f36242e 232 for (i=0 ; i<d->size ; i++) {
tobyspark 0:1a9f9f36242e 233 if (d->key[i]==NULL)
tobyspark 0:1a9f9f36242e 234 continue ;
tobyspark 0:1a9f9f36242e 235 if (hash==d->hash[i]) { /* Same hash value */
tobyspark 0:1a9f9f36242e 236 if (!strcmp(key, d->key[i])) { /* Same key */
tobyspark 0:1a9f9f36242e 237 /* Found a value: modify and return */
tobyspark 0:1a9f9f36242e 238 if (d->val[i]!=NULL)
tobyspark 0:1a9f9f36242e 239 free(d->val[i]);
tobyspark 0:1a9f9f36242e 240 d->val[i] = val ? xstrdup(val) : NULL ;
tobyspark 0:1a9f9f36242e 241 /* Value has been modified: return */
tobyspark 0:1a9f9f36242e 242 return 0 ;
tobyspark 0:1a9f9f36242e 243 }
tobyspark 0:1a9f9f36242e 244 }
tobyspark 0:1a9f9f36242e 245 }
tobyspark 0:1a9f9f36242e 246 }
tobyspark 0:1a9f9f36242e 247 /* Add a new value */
tobyspark 0:1a9f9f36242e 248 /* See if dictionary needs to grow */
tobyspark 0:1a9f9f36242e 249 if (d->n==d->size) {
tobyspark 0:1a9f9f36242e 250
tobyspark 0:1a9f9f36242e 251 /* Reached maximum size: reallocate dictionary */
tobyspark 0:1a9f9f36242e 252 d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ;
tobyspark 0:1a9f9f36242e 253 d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ;
tobyspark 0:1a9f9f36242e 254 d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
tobyspark 0:1a9f9f36242e 255 if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) {
tobyspark 0:1a9f9f36242e 256 /* Cannot grow dictionary */
tobyspark 0:1a9f9f36242e 257 return -1 ;
tobyspark 0:1a9f9f36242e 258 }
tobyspark 0:1a9f9f36242e 259 /* Double size */
tobyspark 0:1a9f9f36242e 260 d->size *= 2 ;
tobyspark 0:1a9f9f36242e 261 }
tobyspark 0:1a9f9f36242e 262
tobyspark 0:1a9f9f36242e 263 /* Insert key in the first empty slot. Start at d->n and wrap at
tobyspark 0:1a9f9f36242e 264 d->size. Because d->n < d->size this will necessarily
tobyspark 0:1a9f9f36242e 265 terminate. */
tobyspark 0:1a9f9f36242e 266 for (i=d->n ; d->key[i] ; ) {
tobyspark 0:1a9f9f36242e 267 if(++i == d->size) i = 0;
tobyspark 0:1a9f9f36242e 268 }
tobyspark 0:1a9f9f36242e 269 /* Copy key */
tobyspark 0:1a9f9f36242e 270 d->key[i] = xstrdup(key);
tobyspark 0:1a9f9f36242e 271 d->val[i] = val ? xstrdup(val) : NULL ;
tobyspark 0:1a9f9f36242e 272 d->hash[i] = hash;
tobyspark 0:1a9f9f36242e 273 d->n ++ ;
tobyspark 0:1a9f9f36242e 274 return 0 ;
tobyspark 0:1a9f9f36242e 275 }
tobyspark 0:1a9f9f36242e 276
tobyspark 0:1a9f9f36242e 277 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 278 /**
tobyspark 0:1a9f9f36242e 279 @brief Delete a key in a dictionary
tobyspark 0:1a9f9f36242e 280 @param d dictionary object to modify.
tobyspark 0:1a9f9f36242e 281 @param key Key to remove.
tobyspark 0:1a9f9f36242e 282 @return void
tobyspark 0:1a9f9f36242e 283
tobyspark 0:1a9f9f36242e 284 This function deletes a key in a dictionary. Nothing is done if the
tobyspark 0:1a9f9f36242e 285 key cannot be found.
tobyspark 0:1a9f9f36242e 286 */
tobyspark 0:1a9f9f36242e 287 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 288 void dictionary_unset(dictionary * d, const char * key)
tobyspark 0:1a9f9f36242e 289 {
tobyspark 0:1a9f9f36242e 290 unsigned hash ;
tobyspark 0:1a9f9f36242e 291 int i ;
tobyspark 0:1a9f9f36242e 292
tobyspark 0:1a9f9f36242e 293 if (key == NULL) {
tobyspark 0:1a9f9f36242e 294 return;
tobyspark 0:1a9f9f36242e 295 }
tobyspark 0:1a9f9f36242e 296
tobyspark 0:1a9f9f36242e 297 hash = dictionary_hash(key);
tobyspark 0:1a9f9f36242e 298 for (i=0 ; i<d->size ; i++) {
tobyspark 0:1a9f9f36242e 299 if (d->key[i]==NULL)
tobyspark 0:1a9f9f36242e 300 continue ;
tobyspark 0:1a9f9f36242e 301 /* Compare hash */
tobyspark 0:1a9f9f36242e 302 if (hash==d->hash[i]) {
tobyspark 0:1a9f9f36242e 303 /* Compare string, to avoid hash collisions */
tobyspark 0:1a9f9f36242e 304 if (!strcmp(key, d->key[i])) {
tobyspark 0:1a9f9f36242e 305 /* Found key */
tobyspark 0:1a9f9f36242e 306 break ;
tobyspark 0:1a9f9f36242e 307 }
tobyspark 0:1a9f9f36242e 308 }
tobyspark 0:1a9f9f36242e 309 }
tobyspark 0:1a9f9f36242e 310 if (i>=d->size)
tobyspark 0:1a9f9f36242e 311 /* Key not found */
tobyspark 0:1a9f9f36242e 312 return ;
tobyspark 0:1a9f9f36242e 313
tobyspark 0:1a9f9f36242e 314 free(d->key[i]);
tobyspark 0:1a9f9f36242e 315 d->key[i] = NULL ;
tobyspark 0:1a9f9f36242e 316 if (d->val[i]!=NULL) {
tobyspark 0:1a9f9f36242e 317 free(d->val[i]);
tobyspark 0:1a9f9f36242e 318 d->val[i] = NULL ;
tobyspark 0:1a9f9f36242e 319 }
tobyspark 0:1a9f9f36242e 320 d->hash[i] = 0 ;
tobyspark 0:1a9f9f36242e 321 d->n -- ;
tobyspark 0:1a9f9f36242e 322 return ;
tobyspark 0:1a9f9f36242e 323 }
tobyspark 0:1a9f9f36242e 324
tobyspark 0:1a9f9f36242e 325 /*-------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 326 /**
tobyspark 0:1a9f9f36242e 327 @brief Dump a dictionary to an opened file pointer.
tobyspark 0:1a9f9f36242e 328 @param d Dictionary to dump
tobyspark 0:1a9f9f36242e 329 @param f Opened file pointer.
tobyspark 0:1a9f9f36242e 330 @return void
tobyspark 0:1a9f9f36242e 331
tobyspark 0:1a9f9f36242e 332 Dumps a dictionary onto an opened file pointer. Key pairs are printed out
tobyspark 0:1a9f9f36242e 333 as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
tobyspark 0:1a9f9f36242e 334 output file pointers.
tobyspark 0:1a9f9f36242e 335 */
tobyspark 0:1a9f9f36242e 336 /*--------------------------------------------------------------------------*/
tobyspark 0:1a9f9f36242e 337 void dictionary_dump(dictionary * d, FILE * out)
tobyspark 0:1a9f9f36242e 338 {
tobyspark 0:1a9f9f36242e 339 int i ;
tobyspark 0:1a9f9f36242e 340
tobyspark 0:1a9f9f36242e 341 if (d==NULL || out==NULL) return ;
tobyspark 0:1a9f9f36242e 342 if (d->n<1) {
tobyspark 0:1a9f9f36242e 343 fprintf(out, "empty dictionary\n");
tobyspark 0:1a9f9f36242e 344 return ;
tobyspark 0:1a9f9f36242e 345 }
tobyspark 0:1a9f9f36242e 346 for (i=0 ; i<d->size ; i++) {
tobyspark 0:1a9f9f36242e 347 if (d->key[i]) {
tobyspark 0:1a9f9f36242e 348 fprintf(out, "%20s\t[%s]\n",
tobyspark 0:1a9f9f36242e 349 d->key[i],
tobyspark 0:1a9f9f36242e 350 d->val[i] ? d->val[i] : "UNDEF");
tobyspark 0:1a9f9f36242e 351 }
tobyspark 0:1a9f9f36242e 352 }
tobyspark 0:1a9f9f36242e 353 return ;
tobyspark 0:1a9f9f36242e 354 }
tobyspark 0:1a9f9f36242e 355
tobyspark 0:1a9f9f36242e 356
tobyspark 0:1a9f9f36242e 357 /* Test code */
tobyspark 0:1a9f9f36242e 358 #ifdef TESTDIC
tobyspark 0:1a9f9f36242e 359 #define NVALS 20000
tobyspark 0:1a9f9f36242e 360 int main(int argc, char *argv[])
tobyspark 0:1a9f9f36242e 361 {
tobyspark 0:1a9f9f36242e 362 dictionary * d ;
tobyspark 0:1a9f9f36242e 363 char * val ;
tobyspark 0:1a9f9f36242e 364 int i ;
tobyspark 0:1a9f9f36242e 365 char cval[90] ;
tobyspark 0:1a9f9f36242e 366
tobyspark 0:1a9f9f36242e 367 /* Allocate dictionary */
tobyspark 0:1a9f9f36242e 368 printf("allocating...\n");
tobyspark 0:1a9f9f36242e 369 d = dictionary_new(0);
tobyspark 0:1a9f9f36242e 370
tobyspark 0:1a9f9f36242e 371 /* Set values in dictionary */
tobyspark 0:1a9f9f36242e 372 printf("setting %d values...\n", NVALS);
tobyspark 0:1a9f9f36242e 373 for (i=0 ; i<NVALS ; i++) {
tobyspark 0:1a9f9f36242e 374 sprintf(cval, "%04d", i);
tobyspark 0:1a9f9f36242e 375 dictionary_set(d, cval, "salut");
tobyspark 0:1a9f9f36242e 376 }
tobyspark 0:1a9f9f36242e 377 printf("getting %d values...\n", NVALS);
tobyspark 0:1a9f9f36242e 378 for (i=0 ; i<NVALS ; i++) {
tobyspark 0:1a9f9f36242e 379 sprintf(cval, "%04d", i);
tobyspark 0:1a9f9f36242e 380 val = dictionary_get(d, cval, DICT_INVALID_KEY);
tobyspark 0:1a9f9f36242e 381 if (val==DICT_INVALID_KEY) {
tobyspark 0:1a9f9f36242e 382 printf("cannot get value for key [%s]\n", cval);
tobyspark 0:1a9f9f36242e 383 }
tobyspark 0:1a9f9f36242e 384 }
tobyspark 0:1a9f9f36242e 385 printf("unsetting %d values...\n", NVALS);
tobyspark 0:1a9f9f36242e 386 for (i=0 ; i<NVALS ; i++) {
tobyspark 0:1a9f9f36242e 387 sprintf(cval, "%04d", i);
tobyspark 0:1a9f9f36242e 388 dictionary_unset(d, cval);
tobyspark 0:1a9f9f36242e 389 }
tobyspark 0:1a9f9f36242e 390 if (d->n != 0) {
tobyspark 0:1a9f9f36242e 391 printf("error deleting values\n");
tobyspark 0:1a9f9f36242e 392 }
tobyspark 0:1a9f9f36242e 393 printf("deallocating...\n");
tobyspark 0:1a9f9f36242e 394 dictionary_del(d);
tobyspark 0:1a9f9f36242e 395 return 0 ;
tobyspark 0:1a9f9f36242e 396 }
tobyspark 0:1a9f9f36242e 397 #endif
tobyspark 0:1a9f9f36242e 398 /* vim: set ts=4 et sw=4 tw=75 */