pelib  2.0.0
include/pelib/iterator.c
Go to the documentation of this file.
00001 /*
00002  * iterator.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 #ifndef ITERATOR_T
00030 #error Using generic iterator without a type
00031 #endif
00032 
00033 iterator_t(ITERATOR_T)*
00034 pelib_alloc_struct(iterator_t(ITERATOR_T))()
00035 {
00036         iterator_t(ITERATOR_T)* iterator;
00037 
00038         iterator = malloc(sizeof(iterator_t(ITERATOR_T)));
00039         assert(iterator != NULL);
00040 
00041         return iterator;
00042 }
00043 
00044 iterator_t(ITERATOR_T)*
00045 pelib_alloc(iterator_t(ITERATOR_T))()
00046 {
00047         iterator_t(ITERATOR_T)* iterator;
00048 
00049         iterator = malloc(sizeof(iterator_t(ITERATOR_T)));
00050         assert(iterator != NULL);
00051 
00052         return iterator;
00053 }
00054 
00055 int
00056 pelib_init(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T)* iterator)
00057 {
00058         iterator->previous = NULL;
00059         iterator->next = NULL;
00060         return pelib_init(ITERATOR_T)(&iterator->value);
00061 }
00062 
00063 int
00064 pelib_copy(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T) src, iterator_t(ITERATOR_T)* dst)
00065 {
00066         size_t i;
00067 
00068         *dst = src;
00069         return pelib_copy(ITERATOR_T)(src.value, &dst->value);
00070 }
00071 
00072 #define iterator_length_debug printf("[PELIB:%s:%s:%d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i);
00073 #define iterator_length_pre_debug printf("[PELIB:%s:%s:%d] length = %d\n", __FILE__, __FUNCTION__, __LINE__, pelib_iterator_length(ITERATOR_T)(&iterator));
00074 char*
00075 pelib_string(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T) iterator)
00076 {
00077         char *value = pelib_string(ITERATOR_T)(iterator.value);
00078         char *elem = malloc((strlen(value) + 3) * sizeof(char*));
00079         strcpy(&elem[1], value);
00080         elem[0] = '{';
00081         elem[strlen(value)] = '}';
00082         elem[strlen(value) + 1] = '\0';
00083         free(value);
00084 
00085         return elem;
00086 }
00087 
00088 char*
00089 pelib_string_detail(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T) iterator, int level)
00090 {
00091         if(level == 0)
00092         {
00093                 return pelib_string(iterator_t(ITERATOR_T))(iterator);
00094         }
00095         else
00096         {
00097                 char *value = pelib_string_detail(ITERATOR_T)(iterator.value, level);
00098                 char *elem = malloc((strlen(value) + 3) * sizeof(char*));
00099                 strcpy(&elem[1], value);
00100                 elem[0] = '{';
00101                 elem[strlen(value)] = '}';
00102                 elem[strlen(value) + 1] = '\0';
00103                 free(value);
00104 
00105                 return elem;
00106         }
00107 }
00108 
00109 FILE*
00110 pelib_printf(iterator_t(ITERATOR_T))(FILE* stream, iterator_t(ITERATOR_T) iterator)
00111 {
00112         char * str;
00113         str = pelib_string(iterator_t(ITERATOR_T))(iterator);
00114 
00115         fprintf(stream, "%s\n", str);
00116         free(str);
00117 
00118         return stream;
00119 }
00120 
00121 FILE*
00122 pelib_printf_detail(iterator_t(ITERATOR_T))(FILE* stream, iterator_t(ITERATOR_T) iterator, int level)
00123 {
00124         char * str;
00125         str = pelib_string_detail(iterator_t(ITERATOR_T))(iterator, level);
00126 
00127         fprintf(stream, "%s\n", str);
00128         free(str);
00129 
00130         return stream;
00131 }
00132 
00133 int
00134 pelib_destroy(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T) iterator)
00135 {
00136         pelib_destroy(ITERATOR_T)(iterator.value);
00137         return 1;
00138 }
00139 
00140 int
00141 pelib_free(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T)* iterator)
00142 {
00143         return pelib_free_struct(iterator_t(ITERATOR_T))(iterator);
00144 }
00145 
00146 int
00147 pelib_free_struct(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T)* iterator)
00148 {
00149         free(iterator);
00150         return 0;
00151 }
00152 
00153 int
00154 pelib_compare(iterator_t(ITERATOR_T))(iterator_t(ITERATOR_T) a1, iterator_t(ITERATOR_T) a2)
00155 {
00156         return pelib_compare(ITERATOR_T)(a1.value, a2.value);
00157 }
00158 
00159 iterator_t(ITERATOR_T)*
00160 pelib_iterator_next(ITERATOR_T)(iterator_t(ITERATOR_T) *el)
00161 {
00162         if(el != NULL)
00163         {
00164                 return el->next;
00165         }
00166         else
00167         {
00168                 return NULL;
00169         }
00170 }
00171 
00172 ITERATOR_T
00173 pelib_iterator_read(ITERATOR_T)(iterator_t(ITERATOR_T) *el)
00174 {
00175         return el->value;
00176 }
00177 
00178 size_t
00179 pelib_iterator_distance(ITERATOR_T)(iterator_t(ITERATOR_T) *start, iterator_t(ITERATOR_T) *stop)
00180 {
00181         size_t distance = 0;
00182 
00183         iterator_t(ITERATOR_T) *i = start;
00184 
00185         while(pelib_compare(iterator_t(ITERATOR_T))(*i, *stop) != 0)
00186         {
00187                 i = pelib_iterator_next(ITERATOR_T)(start);
00188                 distance++;
00189         }
00190         
00191         return distance;
00192 }
00193 
00194 #undef ITERATOR_T