1 | //␊ |
2 | // CoreHash.h␊ |
3 | //␊ |
4 | // Created by Cadet-petit Armel <armelcadetpetit@gmail.com> on 08/03/12.␊ |
5 | // Copyright (c) 2012 . All rights reserved.␊ |
6 | //␊ |
7 | // CoreHash allows in few lines to take full advantages of hashable structures.␊ |
8 | ␊ |
9 | #ifndef CoreHash_h␊ |
10 | #define CoreHash_h␊ |
11 | ␊ |
12 | #include "uthash.h"␊ |
13 | ␊ |
14 | //CoreHash Header and reserved fields␊ |
15 | #define CoreHashHeader \␊ |
16 | char *name; \␊ |
17 | int id; \␊ |
18 | UT_hash_handle hh; /* makes this structure hashable */␊ |
19 | ␊ |
20 | ␊ |
21 | #define __CHFindStrVar(HObj) \␊ |
22 | static struct HObj * HObj##_FindStrVar(const char *name, struct HObj *container) { \␊ |
23 | struct HObj *var; \␊ |
24 | \␊ |
25 | ␉if (setjmp(h_buf_error) == -1) { \␊ |
26 | \␊ |
27 | ␉␉return NULL; \␊ |
28 | ␉} else { \␊ |
29 | ␉␉HASH_FIND_STR( container, name, var ); \␊ |
30 | ␉} \␊ |
31 | return var; \␊ |
32 | }␊ |
33 | ␊ |
34 | #define __CHNewStrVar(HObj) \␊ |
35 | static struct HObj * HObj##_NewStrVar(const char *name, struct HObj **container ) { \␊ |
36 | struct HObj *var; \␊ |
37 | \␊ |
38 | var = (struct HObj*)malloc(sizeof(struct HObj)); \␊ |
39 | if (!var) \␊ |
40 | return NULL; \␊ |
41 | \␊ |
42 | bzero(var,sizeof(struct HObj)); \␊ |
43 | \␊ |
44 | var->name = newString(name); \␊ |
45 | if (!var->name) { \␊ |
46 | free(var); \␊ |
47 | return NULL; \␊ |
48 | } \␊ |
49 | \␊ |
50 | ␉if (setjmp(h_buf_error) == -1) { \␊ |
51 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
52 | ␉␉free(var); \␊ |
53 | ␉␉return NULL; \␊ |
54 | ␉} else { \␊ |
55 | HASH_ADD_KEYPTR( hh, *container, name, strlen(name), var ); \␊ |
56 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
57 | ␉} \␊ |
58 | ␉return var;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
59 | }␊ |
60 | ␊ |
61 | #define __CHFindStrVarOrCreate(HObj)␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
62 | static struct HObj * HObj##_FindStrVarOrCreate(const char *name, struct HObj *container )␉␉\␊ |
63 | {␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
64 | ␉struct HObj *var;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
65 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
66 | var = HObj##_FindStrVar(name,container);␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
67 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
68 | if (!var) {␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
69 | HObj##_NewStrVar(name,&container); \␊ |
70 | }␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
71 | ␉return var;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
72 | }␊ |
73 | ␊ |
74 | #define __CHDeleteStrVar(HObj) \␊ |
75 | static void HObj##_DeleteStrVar(const char *name, struct HObj *container ) { \␊ |
76 | struct HObj *var; \␊ |
77 | \␊ |
78 | var = HObj##_FindStrVar(name,container); \␊ |
79 | \␊ |
80 | if (!var) { \␊ |
81 | return; \␊ |
82 | } \␊ |
83 | \␊ |
84 | ␉if (setjmp(h_buf_error) == -1) { \␊ |
85 | ␉␉return; \␊ |
86 | ␉} else { \␊ |
87 | ␉␉HASH_DEL( container, var); \␊ |
88 | ␉} \␊ |
89 | if (var->name) free(var->name); \␊ |
90 | free(var); \␊ |
91 | }␊ |
92 | ␊ |
93 | #define CHInitStr(HObj) \␊ |
94 | __CHFindStrVar(HObj) \␊ |
95 | __CHNewStrVar(HObj) \␊ |
96 | __CHFindStrVarOrCreate(HObj) \␊ |
97 | __CHDeleteStrVar(HObj) ␊ |
98 | ␊ |
99 | ␊ |
100 | ␊ |
101 | //CoreHash Int Implementation␊ |
102 | ␊ |
103 | #define __CHFindIntVar(HObj) \␊ |
104 | static struct HObj * HObj##_FindIntVar(int id, struct HObj *container) {␉␉␉␉␉\␊ |
105 | struct HObj *var; \␊ |
106 | \␊ |
107 | if (setjmp(h_buf_error) == -1) { \␊ |
108 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
109 | return NULL; \␊ |
110 | } else { \␊ |
111 | HASH_FIND_INT( container, &id, var ); \␊ |
112 | } \␊ |
113 | return var; \␊ |
114 | }␊ |
115 | ␊ |
116 | #define __CHNewIntVar(HObj) \␊ |
117 | static struct HObj * HObj##_NewIntVar(int id, struct HObj **container ) {␉␉␉␉␉\␊ |
118 | struct HObj *var; \␊ |
119 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
120 | var = (struct HObj*)malloc(sizeof(struct HObj)); \␊ |
121 | if (!var) \␊ |
122 | return NULL; \␊ |
123 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
124 | var->id = id;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
125 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
126 | if (setjmp(h_buf_error) == -1) { \␊ |
127 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
128 | free(var); \␊ |
129 | return NULL; \␊ |
130 | } else { \␊ |
131 | HASH_ADD_INT( *container, id, var ); \␊ |
132 | \␊ |
133 | } \␊ |
134 | return var;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
135 | }␊ |
136 | ␊ |
137 | #define __CHFindIntVarOrCreate(HObj) \␊ |
138 | static struct HObj * HObj##_FindIntVarOrCreate(int id, struct HObj *container )␉␉␉␉\␊ |
139 | { \␊ |
140 | struct HObj *var; \␊ |
141 | \␊ |
142 | var = HObj##_FindIntVar(id,container);␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
143 | \␊ |
144 | if (!var) { \␊ |
145 | HObj##_NewIntVar(id,&container); \␊ |
146 | } \␊ |
147 | return var; \␊ |
148 | }␊ |
149 | ␊ |
150 | #define __CHDeleteIntVar(HObj)␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
151 | static void HObj##_DeleteIntVar(int id, struct HObj *container ) {␉␉␉␉␉\␊ |
152 | struct HObj *var;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
153 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
154 | var = HObj##_FindIntVar(id,container);␉␉␉␉␉␉␉␉␉␉␉\␊ |
155 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
156 | if (!var) {␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
157 | return;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
158 | }␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
159 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
160 | if (setjmp(h_buf_error) == -1) {␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
161 | return;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
162 | } else {␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
163 | HASH_DEL( container, var);␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
164 | }␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
165 | if (var->name) free(var->name); \␊ |
166 | free(var);␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
167 | }␊ |
168 | ␊ |
169 | #define CHInitInt(HObj) \␊ |
170 | __CHFindIntVar(HObj) \␊ |
171 | __CHNewIntVar(HObj) \␊ |
172 | __CHFindIntVarOrCreate(HObj) \␊ |
173 | __CHDeleteIntVar(HObj) ␊ |
174 | ␊ |
175 | ␊ |
176 | ␊ |
177 | ␊ |
178 | // CoreHash Common Implementation␊ |
179 | ␊ |
180 | ␊ |
181 | #define __CHDebug(HObj) \␊ |
182 | static void HObj##_Debug(struct HObj *container ) \␊ |
183 | { \␊ |
184 | ␉struct HObj *current_var; \␊ |
185 | ␉printf("Var list: \n");␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
186 | ␉for(current_var=container;current_var;current_var=(struct HObj*)(current_var->hh.next)) \␊ |
187 | ␉{ \␊ |
188 | ␉␉printf(" Name = %s , id = %d\n",current_var->name, current_var->id); \␊ |
189 | ␉} \␊ |
190 | }␊ |
191 | ␊ |
192 | ␊ |
193 | #define __CHDeleteAll(HObj) \␊ |
194 | static void HObj##_DeleteAll(struct HObj *container ) { \␊ |
195 | ␉struct HObj *current_var, *tmp; \␊ |
196 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
197 | ␉if (setjmp(h_buf_error) == -1) { \␊ |
198 | ␉return;␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
199 | ␉} else { \␊ |
200 | ␉␉␉HASH_ITER(hh, container, current_var, tmp) { \␊ |
201 | ␉␉␉HASH_DEL(container,current_var); \␊ |
202 | if (current_var->name) free(current_var->name); \␊ |
203 | ␉␉␉free(current_var); \␊ |
204 | ␉␉} \␊ |
205 | ␉} \␊ |
206 | }␊ |
207 | ␊ |
208 | #define CHUnInit(HObj)␉␉\␊ |
209 | ␉__CHDeleteAll(HObj) ␊ |
210 | ␊ |
211 | #define CHDebug(HObj) \␊ |
212 | ␉__CHDebug(HObj)␊ |
213 | ␊ |
214 | #endif␊ |
215 | |