ekg2
|
00001 /* $Id$ */ 00002 00003 /* 00004 * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl> 00005 * Dawid Jarosz <dawjar@poczta.onet.pl> 00006 * Adam Wysocki <gophi@ekg.chmurka.net> 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License Version 2 as 00010 * published by the Free Software Foundation. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 00022 #ifndef __EKG_DYNSTUFF_H 00023 #define __EKG_DYNSTUFF_H 00024 00025 #ifdef __cplusplus 00026 extern "C" { 00027 #endif 00028 00029 /* 00030 * typedef list_t 00031 * 00032 * list_t jest prostym typem listy używanej w praktycznie wszystkich 00033 * dynamicznych strukturach ekg. obecnie jest to lista jednokierunkowa 00034 * (pole `prev' jest równe NULL), ale zostawiono możliwość rozbudowy 00035 * do dwukierunkowej bez zmiany ABI. dane są przechowywane w polu `data', 00036 * kolejny element w `next'. przykładowy kod iteracji: 00037 * 00038 * list_t l; 00039 * 00040 * for (l = lista; l; l = l->next) { 00041 * struct cokolwiek *c = l->data; 00042 * printf("%s\n", c->cokolwiek); 00043 * } 00044 * 00045 * większość list występujących w ekg można iterować bez obawy o zmiany 00046 * ABI. pierwsze pole, będące jednoznacznym identyfikatorem elementu listy 00047 * jest dostępne bezpośrednio, reszta przez odpowiednie funkcje. 00048 */ 00049 00050 /* 00051 * New *3() lists 00052 * 00053 * Instead of allocing additional list of dual-pointer structs, we add 00054 * 'next' field to the beginning of real struct. C allows us to point 00055 * to that first field independently of which struct is it, so we can 00056 * use some type-indepdendent functions for that. The main target is 00057 * to totally remove old functions, but leave 'list_t'. 00058 * 00059 * Then, for example, session_t would point to first entry of userlist 00060 * (as userlist_t*), and that entry would point to second one, second 00061 * one to third, etc. But if we want to group few userlist entries 00062 * independently of their original structure, we could just catch them 00063 * in standard list_t and use its' 'next' field. 00064 */ 00065 00066 struct list { 00067 /* it is important that we keep 'next' first field, 00068 * because C allows us to call first field of any structure 00069 * without knowing its' type 00070 * 00071 * so *3() would work peacefully w/ both list_t and not-list_t lists */ 00072 struct list *next; 00073 00074 void *data; 00075 }; 00076 00077 typedef struct list *list_t; 00078 00079 #ifndef EKG2_WIN32_NOFUNCTION 00080 #define LIST_ADD_COMPARE(x, type) int x(const type data1, const type data2) 00081 #define LIST_ADD_SORTED(list, data, comp) list_add_sorted(list, data, (void *) comp) 00082 #define LIST_ADD_SORTED2(list, data, comp) list_add_sorted3((list_t *) (void *) list, (list_t) data, (void *) comp) 00083 #define LIST_ADD_BEGINNING2(list, data) list_add_beginning3((list_t *) (void *) list, (list_t) data) 00084 #define LIST_ADD2(list, data) list_add3((list_t *) (void *) list, (list_t) data) 00085 00086 #define LIST_COUNT2(list) list_count((list_t) list) 00087 #define LIST_GET_NTH2(list, id) list_get_nth3((list_t) list, id) 00088 #define LIST_RESORT(list, comp) list_resort(list, (void *) comp) 00089 #define LIST_RESORT2(list, comp) list_resort3((list_t *) (void *) list, (void *) comp) 00090 00091 #define LIST_REMOVE(list, data, func) list_remove2(list, data, (void *) func) 00092 #define LIST_REMOVE2(list, elem, func) list_remove3((list_t *) (void *) list, (list_t) elem, (void *) func) 00093 #define LIST_UNLINK2(list, elem) list_unlink3((list_t *) (void *) list, (list_t) elem) 00094 #define LIST_FREE_ITEM(x, type) void x(type data) 00095 00096 #define LIST_DESTROY(list, func) list_destroy2(list, (void *) func) 00097 #define LIST_DESTROY2(list, func) list_destroy3((list_t) list, (void *) func) 00098 00099 void *list_add(list_t *list, void *data); 00100 void *list_add_beginning(list_t *list, void *data); 00101 void *list_add_sorted(list_t *list, void *data, int (*comparision)(void *, void *)); 00102 00103 void *list_add3(list_t *list, list_t new_); 00104 void *list_add_beginning3(list_t *list, list_t new_); 00105 void *list_add_sorted3(list_t *list, list_t new_, int (*comparision)(void *, void *)); 00106 00107 00108 int list_count(list_t list); 00109 void *list_get_nth(list_t list, int id); 00110 void *list_get_nth3(list_t list, int id); 00111 void list_resort(list_t *list, int (*comparision)(void *, void *)); 00112 void list_resort3(list_t *list, int (*comparision)(void *, void *)); 00113 00114 int list_remove(list_t *list, void *data, int free_data); 00115 int list_remove2(list_t *list, void *data, void (*func)(void *)); 00116 void *list_remove3(list_t *list, list_t elem, void (*func)(list_t)); 00117 void *list_remove3i(list_t *list, list_t elem, void (*func)(list_t data)); 00118 void *list_unlink3(list_t *list, list_t elem); 00119 00120 int list_destroy(list_t list, int free_data); 00121 int list_destroy2(list_t list, void (*func)(void *)); 00122 int list_destroy3(list_t list, void (*func)(void *)); 00123 00124 void list_cleanup(list_t *list); 00125 int list_remove_safe(list_t *list, void *data, int free_data); 00126 #endif 00127 00128 /* 00129 * typedef string_t 00130 * 00131 * prosty typ tekstowy pozwalający tworzyć ciągi tekstowe o dowolnej 00132 * długości bez obawy o rozmiar bufora. ciąg tekstowy jest dostępny 00133 * przez pole `str'. nie należy go zmieniać bezpośrednio. przykładowy 00134 * kod: 00135 * 00136 * string_t s; 00137 * 00138 * s = string_init("ala"); 00139 * string_append_c(s, ' '); 00140 * string_append(s, "ma kota"); 00141 * printf("%s\n", s->str); 00142 * string_free(s, 1); 00143 */ 00144 00145 struct string { 00146 char *str; 00147 int len, size; 00148 }; 00149 00150 typedef struct string *string_t; 00151 00152 #ifndef EKG2_WIN32_NOFUNCTION 00153 00154 string_t string_init(const char *str); 00155 int string_append(string_t s, const char *str); 00156 int string_append_n(string_t s, const char *str, int count); 00157 int string_append_c(string_t s, char ch); 00158 int string_append_raw(string_t s, const char *str, int count); 00159 int string_append_format(string_t s, const char *format, ...); 00160 void string_insert(string_t s, int index, const char *str); 00161 void string_insert_n(string_t s, int index, const char *str, int count); 00162 void string_remove(string_t s, int count); 00163 void string_clear(string_t s); 00164 char *string_free(string_t s, int free_string); 00165 00166 /* tablice stringow */ 00167 char **array_make(const char *string, const char *sep, int max, int trim, int quotes); 00168 char *array_join(char **array, const char *sep); 00169 char *array_join_count(char **array, const char *sep, int count); 00170 00171 int array_add(char ***array, char *string); 00172 int array_add_check(char ***array, char *string, int casesensitive); 00173 int array_count(char **array); 00174 int array_contains(char **array, const char *string, int casesensitive); 00175 int array_item_contains(char **array, const char *string, int casesensitive); 00176 char *array_shift(char ***array); 00177 void array_free(char **array); 00178 void array_free_count(char **array, int count); 00179 00180 /* rozszerzenia libców */ 00181 00182 const char *itoa(long int i); 00183 const char *cssfind(const char *haystack, const char *needle, const char sep, int caseinsensitive); 00184 00185 #endif 00186 00187 char *escape(const char *src); 00188 char *unescape(const char *src); 00189 00190 /* 00191 * handle private data 00192 */ 00193 typedef struct private_data_s { 00194 struct private_data_s *next; 00195 00196 char *name; 00197 char *value; 00198 } private_data_t; 00199 00200 int private_item_get_safe(private_data_t **data, const char *item_name, char **result); 00201 const char *private_item_get(private_data_t **data, const char *item_name); 00202 00203 int private_item_get_int_safe(private_data_t **data, const char *item_name, int *result); 00204 int private_item_get_int(private_data_t **data, const char *item_name); 00205 00206 void private_item_set(private_data_t **data, const char *item_name, const char *value); 00207 void private_item_set_int(private_data_t **data, const char *item_name, int value); 00208 00209 void private_items_destroy(private_data_t **data); 00210 00211 #ifdef __cplusplus 00212 } 00213 #endif 00214 00215 #endif /* __EKG_DYNSTUFF_H */ 00216 00217 /* 00218 * Local Variables: 00219 * mode: c 00220 * c-file-style: "k&r" 00221 * c-basic-offset: 8 00222 * indent-tabs-mode: t 00223 * End: 00224 */