pelib
2.0.0
|
00001 /* 00002 * set.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 #include <pelib/size_t.h> 00030 00031 #ifndef SET_T 00032 #error Using generic set without a type 00033 #endif 00034 00035 // Now include the generic set implementation 00036 //#define ITERATOR_T SET_T 00037 //#include "pelib/iterator.c" 00038 00039 #ifdef debug 00040 #undef debug 00041 #undef debug_addr 00042 #undef debug_int 00043 #undef debug_size_t 00044 #endif 00045 00046 #if 10 00047 #define debug(var) printf("[%s:%s:%d] %s = \"%s\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00048 #define debug_addr(var) printf("[%s:%s:%d] %s = \"%p\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00049 #define debug_int(var) printf("[%s:%s:%d] %s = \"%d\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00050 #define debug_size_t(var) printf("[%s:%s:%d] %s = \"%zu\"\n", __FILE__, __FUNCTION__, __LINE__, #var, var); fflush(NULL) 00051 #else 00052 #define debug(var) 00053 #define debug_addr(var) 00054 #define debug_int(var) 00055 #define debug_size_t(var) 00056 #endif 00057 00058 set_t(SET_T)* 00059 pelib_alloc_struct(set_t(SET_T))() 00060 { 00061 set_t(SET_T)* set; 00062 00063 set = malloc(sizeof(set_t(SET_T))); 00064 assert(set != NULL); 00065 00066 return set; 00067 } 00068 00069 set_t(SET_T)* 00070 pelib_alloc(set_t(SET_T))() 00071 { 00072 set_t(SET_T)* set; 00073 00074 set = malloc(sizeof(set_t(SET_T))); 00075 assert(set != NULL); 00076 00077 return set; 00078 } 00079 00080 int 00081 pelib_init(set_t(SET_T))(set_t(SET_T)* set) 00082 { 00083 set->first = NULL; 00084 set->middle = NULL; 00085 set->last = NULL; 00086 00087 return 1; 00088 } 00089 00090 #define pelib_set_insert_element(elem) PELIB_CONCAT_3(pelib_, set(elem), _insert_element) 00091 static 00092 int 00093 pelib_set_insert_element(SET_T)(set_t(SET_T) *set, iterator_t(SET_T) *elem) 00094 { 00095 iterator_t(SET_T) *current = set->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(SET_T)(elem->value, current->value) > 0) 00105 { 00106 previous = current; 00107 current = current->next; 00108 } 00109 00110 /* Comment out the next block if you want to implement a multiset */ 00111 if(current != 0 && pelib_compare(SET_T)(elem->value, current->value) == 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 set->last = elem; 00130 } 00131 else 00132 { 00133 if(current == set->first) 00134 { 00135 set->first = elem; 00136 } 00137 current->previous = elem; 00138 } 00139 } 00140 else 00141 { 00142 elem->next = NULL; 00143 elem->previous = NULL; 00144 set->first = elem; 00145 set->last = elem; 00146 } 00147 00148 return 1; 00149 } 00150 00151 int 00152 pelib_set_insert(SET_T)(set_t(SET_T)* set, SET_T value) 00153 { 00154 iterator_t(SET_T) *new = pelib_alloc(iterator_t(SET_T))(); 00155 pelib_init(iterator_t(SET_T))(new); 00156 pelib_copy(SET_T)(value, &new->value); 00157 if(!pelib_set_insert_element(SET_T)(set, new)) 00158 { 00159 pelib_free(iterator_t(SET_T))(new); 00160 return 0; 00161 } 00162 else 00163 { 00164 return 1; 00165 } 00166 } 00167 00168 int 00169 pelib_copy(set_t(SET_T))(set_t(SET_T) src, set_t(SET_T)* dst) 00170 { 00171 size_t i; 00172 00173 iterator_t(SET_T) *elem = src.last; 00174 while(elem != NULL) 00175 { 00176 iterator_t(SET_T) *cpy = pelib_alloc(iterator_t(SET_T))(); 00177 pelib_copy(SET_T)(elem->value, &cpy->value); 00178 pelib_set_insert_element(SET_T)(dst, cpy); 00179 elem = elem->previous; 00180 } 00181 00182 return 0; 00183 } 00184 00185 #define set_length_debug printf("[PELIB:%s:%s:%d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i); 00186 #define set_length_pre_debug printf("[PELIB:%s:%s:%d] length = %d\n", __FILE__, __FUNCTION__, __LINE__, pelib_set_length(SET_T)(&set)); 00187 char* 00188 pelib_string(set_t(SET_T))(set_t(SET_T) set) 00189 { 00190 char *str, *grow, *elem; 00191 size_t i; 00192 str = malloc(3 * sizeof(char)); 00193 sprintf(str, "["); 00194 00195 iterator_t(SET_T) *el = set.first; 00196 while(el != NULL && el->next != NULL) 00197 { 00198 elem = pelib_string(SET_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(SET_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(set_t(SET_T))(set_t(SET_T) set, int level) 00234 { 00235 if(level == 0) 00236 { 00237 return pelib_string(set_t(SET_T))(set); 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(SET_T) *el = set.first; 00247 00248 while(el != NULL && el->next != NULL) 00249 { 00250 elem = pelib_string_detail(SET_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(SET_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(set_t(SET_T))(FILE* stream, set_t(SET_T) set) 00284 { 00285 char * str; 00286 str = pelib_string(set_t(SET_T))(set); 00287 00288 fprintf(stream, "%s\n", str); 00289 free(str); 00290 00291 return stream; 00292 } 00293 00294 FILE* 00295 pelib_printf_detail(set_t(SET_T))(FILE* stream, set_t(SET_T) set, int level) 00296 { 00297 char * str; 00298 str = pelib_string_detail(set_t(SET_T))(set, level); 00299 00300 fprintf(stream, "%s\n", str); 00301 free(str); 00302 00303 return stream; 00304 } 00305 00306 int 00307 pelib_destroy(set_t(SET_T))(set_t(SET_T) set) 00308 { 00309 iterator_t(SET_T) *elem = set.first; 00310 while(elem != NULL) 00311 { 00312 iterator_t(SET_T) *current = elem; 00313 elem = elem->next; 00314 pelib_destroy(iterator_t(SET_T))(*current); 00315 pelib_free(iterator_t(SET_T))(current); 00316 } 00317 return 1; 00318 } 00319 00320 int 00321 pelib_free_buffer(set_t(SET_T))(set_t(SET_T)* set) 00322 { 00323 iterator_t(SET_T) *elem = set->first; 00324 while(elem != NULL) 00325 { 00326 iterator_t(SET_T) *current = elem; 00327 elem = elem->next; 00328 pelib_destroy(iterator_t(SET_T))(*current); 00329 pelib_free(iterator_t(SET_T))(current); 00330 } 00331 return 1; 00332 } 00333 00334 int 00335 pelib_free_struct(set_t(SET_T))(set_t(SET_T)* set) 00336 { 00337 free(set); 00338 return 1; 00339 } 00340 00341 int 00342 pelib_free(set_t(SET_T))(set_t(SET_T)* set) 00343 { 00344 pelib_free_buffer(set_t(SET_T))(set); 00345 pelib_free_struct(set_t(SET_T))(set); 00346 return 1; 00347 } 00348 00349 int 00350 pelib_compare(set_t(SET_T))(set_t(SET_T) a1, set_t(SET_T) a2) 00351 { 00352 iterator_t(SET_T) *e1 = a1.first; 00353 iterator_t(SET_T) *e2 = a2.first; 00354 00355 while(e1 != NULL && e2 != NULL && pelib_compare(iterator_t(SET_T))(*e1, *e2) == 0) 00356 { 00357 e1 = e1->next; 00358 e2 = e2->next; 00359 } 00360 00361 if(e1 == NULL && e2 != NULL) 00362 { 00363 return 1; 00364 } 00365 else if(e1 != NULL && e2 == NULL) 00366 { 00367 return -1; 00368 } 00369 else return pelib_compare(iterator_t(SET_T))(*e1, *e2); 00370 } 00371 00372 #undef SET_T