pelib  2.0.0
include/pelib/set.c
Go to the documentation of this file.
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