pelib
2.0.0
|
00001 /* 00002 * map.c 00003 * 00004 * Created on: 5 Sep 2011 00005 * Copyright 2011 Nicolas Melot 00006 * 00007 * This file is part of pelib. 00008 * 00009 * pelib is free software: you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation, either version 3 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * pelib is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with pelib. If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 */ 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <assert.h> 00027 #include <string.h> 00028 00029 #if !(defined MAP_KEY_T && defined MAP_VALUE_T) 00030 #error Using generic map without a type 00031 #endif 00032 00033 /* 00034 #define PAIR_KEY_T MAP_KEY_T 00035 #define PAIR_VALUE_T MAP_VALUE_T 00036 #include "pelib/pair.c" 00037 */ 00038 00039 /* 00040 #define ITERATOR_T pair_t(MAP_KEY_T, MAP_VALUE_T) 00041 #include "pelib/iterator.c" 00042 */ 00043 00044 #if 10 00045 #define debug(var) printf("[%s:%s:%d] %s = \"%s\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00046 #define debug_addr(var) printf("[%s:%s:%d] %s = \"%p\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00047 #define debug_int(var) printf("[%s:%s:%d] %s = \"%d\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00048 #define debug_size_t(var) printf("[%s:%s:%d] %s = \"%zu\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00049 #else 00050 #define debug(var) 00051 #define debug_addr(var) 00052 #define debug_int(var) 00053 #define debug_size_t(var) 00054 #endif 00055 00056 static map_t(MAP_KEY_T, MAP_VALUE_T) *stuff; 00057 00058 map_t(MAP_KEY_T, MAP_VALUE_T)* 00059 pelib_alloc_struct(map_t(MAP_KEY_T, MAP_VALUE_T))() 00060 { 00061 map_t(MAP_KEY_T, MAP_VALUE_T)* map; 00062 00063 map = malloc(sizeof(map_t(MAP_KEY_T, MAP_VALUE_T))); 00064 assert(map != NULL); 00065 00066 return map; 00067 } 00068 00069 map_t(MAP_KEY_T, MAP_VALUE_T)* 00070 pelib_alloc(map_t(MAP_KEY_T, MAP_VALUE_T))() 00071 { 00072 map_t(MAP_KEY_T, MAP_VALUE_T)* map; 00073 00074 map = malloc(sizeof(map_t(MAP_KEY_T, MAP_VALUE_T))); 00075 assert(map != NULL); 00076 00077 return map; 00078 } 00079 00080 int 00081 pelib_init(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T)* map) 00082 { 00083 map->first = NULL; 00084 map->middle = NULL; 00085 map->last = NULL; 00086 00087 return 1; 00088 } 00089 00090 #define pelib_map_insert_element(key, value) PELIB_CONCAT_3(pelib_, map(key, value), _insert_element) 00091 static 00092 int 00093 pelib_map_insert_element(MAP_KEY_T, MAP_VALUE_T)(map_t(MAP_KEY_T, MAP_VALUE_T) *map, iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *elem) 00094 { 00095 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *current = map->first, *previous = NULL; 00096 00097 // If there is at least one element, then browse the list until we find the right spot 00098 // Otherwise, place the element as first and last, that is first and last pointers point 00099 // the the element and next and previous pointers of this element point to nothing. 00100 if(current != NULL) 00101 { 00102 // browse the list until we reach the end or until we find the last element lower 00103 // than the element to insert 00104 while(current != NULL && pelib_compare(MAP_KEY_T)(elem->value.key, current->value.key) > 0) 00105 { 00106 previous = current; 00107 current = current->next; 00108 } 00109 00110 /* Comment out the next block if you want to implement a multimap */ 00111 if(current != 0 && pelib_compare(MAP_KEY_T)(elem->value.key, current->value.key) == 0) 00112 { 00113 return 0; 00114 } 00115 00116 // Insert element 00117 elem->previous = previous; 00118 elem->next = current; 00119 if(previous != NULL) 00120 { 00121 previous->next = elem; 00122 } 00123 00124 // Update tail if the element is insert last 00125 // Otherwise update next element's pointer to 00126 // previous element (the newly inserted one) 00127 if(current == NULL) 00128 { 00129 map->last = elem; 00130 } 00131 else 00132 { 00133 if(current == map->first) 00134 { 00135 map->first = elem; 00136 } 00137 current->previous = elem; 00138 } 00139 } 00140 else 00141 { 00142 elem->next = NULL; 00143 elem->previous = NULL; 00144 map->first = elem; 00145 map->last = elem; 00146 } 00147 00148 return 1; 00149 } 00150 00151 int 00152 pelib_map_insert(MAP_KEY_T, MAP_VALUE_T)(map_t(MAP_KEY_T, MAP_VALUE_T)* map, pair_t(MAP_KEY_T, MAP_VALUE_T) value) 00153 { 00154 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *new = pelib_alloc(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)))(); 00155 pelib_init(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)))(new); 00156 pelib_copy(pair_t(MAP_KEY_T, MAP_VALUE_T))(value, &new->value); 00157 if(!pelib_map_insert_element(MAP_KEY_T, MAP_VALUE_T)(map, new)) 00158 { 00159 pelib_free(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)))(new); 00160 return 0; 00161 } 00162 else 00163 { 00164 return 1; 00165 } 00166 } 00167 00168 int 00169 pelib_copy(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T) src, map_t(MAP_KEY_T, MAP_VALUE_T)* dst) 00170 { 00171 size_t i; 00172 00173 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *elem = src.last; 00174 while(elem != NULL) 00175 { 00176 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *cpy = pelib_alloc(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)))(); 00177 pelib_copy(pair_t(MAP_KEY_T, MAP_VALUE_T))(elem->value, &cpy->value); 00178 pelib_map_insert_element(MAP_KEY_T, MAP_VALUE_T)(dst, cpy); 00179 elem = elem->previous; 00180 } 00181 00182 return 0; 00183 } 00184 00185 #define map_length_debug printf("[PELIB:%s:%s:%d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i); 00186 #define map_length_pre_debug printf("[PELIB:%s:%s:%d] length = %d\n", __FILE__, __FUNCTION__, __LINE__, pelib_map_length(MAP_KEY_T, MAP_VALUE_T)(&map)); 00187 char* 00188 pelib_string(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T) map) 00189 { 00190 char *str, *grow, *elem; 00191 size_t i; 00192 str = malloc(3 * sizeof(char)); 00193 sprintf(str, "["); 00194 00195 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *el = map.first; 00196 while(el != NULL && el->next != NULL) 00197 { 00198 elem = pelib_string(pair_t(MAP_KEY_T, MAP_VALUE_T))(el->value); 00199 grow = malloc((strlen(str) + 1) * sizeof(char)); 00200 sprintf(grow, "%s", str); 00201 00202 free(str); 00203 str = malloc(strlen(grow) + 1 + strlen(elem) + 1); 00204 sprintf(str, "%s%s:", grow, elem); 00205 free(elem); 00206 free(grow); 00207 el = el->next; 00208 } 00209 while(el != NULL) 00210 { 00211 elem = pelib_string(pair_t(MAP_KEY_T, MAP_VALUE_T))(el->value); 00212 grow = malloc((strlen(str) + 1) * sizeof(char)); 00213 sprintf(grow, "%s", str); 00214 00215 free(str); 00216 str = malloc(strlen(grow) + 1 + strlen(elem) + 1); 00217 sprintf(str, "%s%s", grow, elem); 00218 free(elem); 00219 free(grow); 00220 00221 el = el->next; 00222 } 00223 00224 grow = malloc((strlen(str) + 1) * sizeof(char)); 00225 sprintf(grow, "%s", str); 00226 sprintf(str, "%s]", grow); 00227 free(grow); 00228 00229 return str; 00230 } 00231 00232 char* 00233 pelib_string_detail(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T) map, int level) 00234 { 00235 if(level == 0) 00236 { 00237 return pelib_string(map_t(MAP_KEY_T, MAP_VALUE_T))(map); 00238 } 00239 else 00240 { 00241 // Bring it on 00242 char *str, *grow, *elem; 00243 size_t i; 00244 str = malloc(3 * sizeof(char)); 00245 sprintf(str, "["); 00246 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *el = map.first; 00247 00248 while(el != NULL && el->next != NULL) 00249 { 00250 elem = pelib_string_detail(pair_t(MAP_KEY_T, MAP_VALUE_T))(el->value, level); 00251 grow = malloc((strlen(str) + 1) * sizeof(char)); 00252 sprintf(grow, "%s", str); 00253 00254 free(str); 00255 str = malloc(strlen(grow) + 1 + strlen(elem) + 1); 00256 sprintf(str, "%s%s:", grow, elem); 00257 free(elem); 00258 free(grow); 00259 } 00260 while(el != NULL) 00261 { 00262 elem = pelib_string_detail(pair_t(MAP_KEY_T, MAP_VALUE_T))(el->value, level); 00263 grow = malloc((strlen(str) + 1) * sizeof(char)); 00264 sprintf(grow, "%s", str); 00265 00266 free(str); 00267 str = malloc(strlen(grow) + 1 + strlen(elem) + 1); 00268 sprintf(str, "%s%s", grow, elem); 00269 free(elem); 00270 free(grow); 00271 } 00272 00273 grow = malloc((strlen(str) + 1) * sizeof(char)); 00274 sprintf(grow, "%s", str); 00275 sprintf(str, "%s]", grow); 00276 free(grow); 00277 00278 return str; 00279 } 00280 } 00281 00282 FILE* 00283 pelib_printf(map_t(MAP_KEY_T, MAP_VALUE_T))(FILE* stream, map_t(MAP_KEY_T, MAP_VALUE_T) map) 00284 { 00285 char * str; 00286 str = pelib_string(map_t(MAP_KEY_T, MAP_VALUE_T))(map); 00287 00288 fprintf(stream, "%s\n", str); 00289 free(str); 00290 00291 return stream; 00292 } 00293 00294 FILE* 00295 pelib_printf_detail(map_t(MAP_KEY_T, MAP_VALUE_T))(FILE* stream, map_t(MAP_KEY_T, MAP_VALUE_T) map, int level) 00296 { 00297 char * str; 00298 str = pelib_string_detail(map_t(MAP_KEY_T, MAP_VALUE_T))(map, level); 00299 00300 fprintf(stream, "%s\n", str); 00301 free(str); 00302 00303 return stream; 00304 } 00305 00306 int 00307 pelib_destroy(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T) map) 00308 { 00309 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *elem = map.first; 00310 while(elem != NULL) 00311 { 00312 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *current = elem; 00313 elem = elem->next; 00314 pelib_destroy(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)))(*current); 00315 } 00316 return 1; 00317 } 00318 00319 int 00320 pelib_free_buffer(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T)* map) 00321 { 00322 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *elem = map->first; 00323 while(elem != NULL) 00324 { 00325 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *current = elem; 00326 elem = elem->next; 00327 pelib_free(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)))(current); 00328 } 00329 return 1; 00330 } 00331 00332 int 00333 pelib_free_struct(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T)* map) 00334 { 00335 free(map); 00336 return 1; 00337 } 00338 00339 int 00340 pelib_free(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T)* map) 00341 { 00342 pelib_free_buffer(map_t(MAP_KEY_T, MAP_VALUE_T))(map); 00343 pelib_free_struct(map_t(MAP_KEY_T, MAP_VALUE_T))(map); 00344 return 1; 00345 } 00346 00347 int 00348 pelib_compare(map_t(MAP_KEY_T, MAP_VALUE_T))(map_t(MAP_KEY_T, MAP_VALUE_T) a1, map_t(MAP_KEY_T, MAP_VALUE_T) a2) 00349 { 00350 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *e1 = a1.first; 00351 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *e2 = a2.first; 00352 00353 while(e1 != NULL && e2 != NULL && pelib_compare(pair_t(MAP_KEY_T, MAP_VALUE_T))(e1->value, e2->value) == 0) 00354 { 00355 e1 = e1->next; 00356 e2 = e2->next; 00357 } 00358 00359 if(e1 == NULL && e2 != NULL) 00360 { 00361 return 1; 00362 } 00363 else if(e1 != NULL && e2 == NULL) 00364 { 00365 return -1; 00366 } 00367 else return pelib_compare(pair_t(MAP_KEY_T, MAP_VALUE_T))(e1->value, e2->value); 00368 } 00369 00370 /* Returns the first element in map */ 00371 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T))* 00372 pelib_map_begin(MAP_KEY_T, MAP_VALUE_T)(map_t(MAP_KEY_T, MAP_VALUE_T) *map) 00373 { 00374 return map->first; 00375 } 00376 00377 /* Returns the first element in map */ 00378 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T))* 00379 pelib_map_end(MAP_KEY_T, MAP_VALUE_T)(map_t(MAP_KEY_T, MAP_VALUE_T) *map) 00380 { 00381 return NULL; 00382 } 00383 00384 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T))* 00385 pelib_map_next(MAP_KEY_T, MAP_VALUE_T)(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *i) 00386 { 00387 return pelib_iterator_next(pair_t(MAP_KEY_T, MAP_VALUE_T))(i); 00388 } 00389 00390 pair_t(MAP_KEY_T, MAP_VALUE_T) 00391 pelib_map_read(MAP_KEY_T, MAP_VALUE_T)(iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *i) 00392 { 00393 return pelib_iterator_read(pair_t(MAP_KEY_T, MAP_VALUE_T))(i); 00394 } 00395 00396 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T))* 00397 pelib_map_find(MAP_KEY_T, MAP_VALUE_T)(map_t(MAP_KEY_T, MAP_VALUE_T) *map, MAP_KEY_T key) 00398 { 00399 map_iterator_t(MAP_KEY_T, MAP_VALUE_T) *i; 00400 for(i = pelib_map_begin(MAP_KEY_T, MAP_VALUE_T)(map); i != pelib_map_end(MAP_KEY_T, MAP_VALUE_T)(map); i = pelib_map_next(MAP_KEY_T, MAP_VALUE_T)(i)) 00401 { 00402 MAP_KEY_T elem_key = pelib_map_read(MAP_KEY_T, MAP_VALUE_T)(i).key; 00403 if(pelib_compare(MAP_KEY_T)(key, elem_key) == 0) 00404 { 00405 return i; 00406 } 00407 } 00408 00409 return NULL; 00410 } 00411 00412 size_t 00413 pelib_map_size(MAP_KEY_T, MAP_VALUE_T)(map_t(MAP_KEY_T, MAP_VALUE_T) *map) 00414 { 00415 size_t size = 0; 00416 iterator_t(pair_t(MAP_KEY_T, MAP_VALUE_T)) *i; 00417 00418 // Iterate from the beginning until we find the end 00419 for(i = pelib_map_begin(MAP_KEY_T, MAP_VALUE_T)(map); i != pelib_map_end(MAP_KEY_T, MAP_VALUE_T)(map); i = pelib_map_next(MAP_KEY_T, MAP_VALUE_T)(i), size++); 00420 00421 return size; 00422 } 00423 00424 #undef MAP_KEY_T 00425 #undef MAP_VALUE_T 00426