]> mj.ucw.cz Git - eval.git/blob - sherlock/object.c
Better logging of exceptions
[eval.git] / sherlock / object.c
1 /*
2  *      Sherlock Library -- Object Functions
3  *
4  *      (c) 1997--2006 Martin Mares <mj@ucw.cz>
5  *      (c) 2004 Robert Spalek <robert@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "sherlock/sherlock.h"
12 #include "ucw/mempool.h"
13 #include "ucw/fastbuf.h"
14 #include "sherlock/object.h"
15
16 #include <string.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 void
21 obj_dump(struct odes *d)
22 {
23   for(struct oattr *a=d->attrs; a; a=a->next)
24     for(struct oattr *b=a; b; b=b->same)
25       if (a->attr >= OBJ_ATTR_SON)
26         {
27           printf("(%c\n", a->attr - OBJ_ATTR_SON);
28           obj_dump(b->son);
29           printf(")\n");
30         }
31       else
32         printf("%c%s\n", (a==b ? a->attr : ' '), b->val);
33 }
34
35 void
36 obj_dump_indented(struct odes *d, uns indent)
37 {
38   for(struct oattr *a=d->attrs; a; a=a->next)
39     for(struct oattr *b=a; b; b=b->same)
40       {
41         for (uns i=0; i<indent; i++)
42           putchar('\t');
43         if (a->attr >= OBJ_ATTR_SON)
44           {
45             printf("(%c\n", a->attr - OBJ_ATTR_SON);
46             obj_dump_indented(b->son, indent+1);
47             for (uns i=0; i<=indent; i++)
48               putchar('\t');
49             printf(")\n");
50           }
51         else
52           printf("%c%s\n", (a==b ? a->attr : ' '), b->val);
53       }
54 }
55
56 static struct oattr *
57 oa_new(struct odes *o, uns x, byte *v)
58 {
59   uns l = strlen(v)+1;
60   struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr) + l);
61
62   a->next = a->same = NULL;
63   a->attr = x;
64   a->val = (byte*) (a+1);
65   memcpy(a->val, v, l);
66   return a;
67 }
68
69 static struct oattr *
70 oa_new_ref(struct odes *o, uns x, byte *v)
71 {
72   struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr));
73
74   a->next = a->same = NULL;
75   a->attr = x;
76   a->val = v;
77   return a;
78 }
79
80 static struct oattr *
81 oa_new_son(struct odes *o, uns x, struct odes *son)
82 {
83   struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr));
84
85   a->next = a->same = NULL;
86   a->attr = x;
87   a->son = son;
88   son->parent = o;
89   return a;
90 }
91
92 struct odes *
93 obj_new(struct mempool *pool)
94 {
95   struct odes *o = mp_alloc(pool, sizeof(struct odes));
96   o->pool = pool;
97   o->attrs = NULL;
98   o->cached_attr = NULL;
99   o->parent = NULL;
100   return o;
101 }
102
103 struct oattr *
104 obj_find_attr(struct odes *o, uns x)
105 {
106   struct oattr *a;
107   for(a=o->attrs; a && a->attr != x; a=a->next)
108     ;
109   return a;
110 }
111
112 struct oattr *
113 obj_find_attr_last(struct odes *o, uns x)
114 {
115   struct oattr *a = obj_find_attr(o, x);
116
117   if (a)
118     {
119       while (a->same)
120         a = a->same;
121     }
122   return a;
123 }
124
125 uns
126 obj_del_attr(struct odes *o, struct oattr *a)
127 {
128   struct oattr *x, **p;
129   uns aa = a->attr;
130
131   o->cached_attr = NULL;
132   p = &o->attrs;
133   while (x = *p)
134     {
135       if (x->attr == aa)
136         {
137           if (x == a)
138             {
139               if (x->same)
140                 {
141                   x->same->next = x->next;
142                   *p = x->same;
143                 }
144               else
145                 *p = x->next;
146               return 1;
147             }
148           p = &x->same;
149           while (x = *p)
150             {
151               if (x == a)
152                 {
153                   *p = x->same;
154                   return 1;
155                 }
156               p = &x->same;
157             }
158           return 0;
159         }
160       p = &x->next;
161     }
162   return 0;
163 }
164
165 byte *
166 obj_find_aval(struct odes *o, uns x)
167 {
168   struct oattr *a = obj_find_attr(o, x);
169   return a ? a->val : NULL;
170 }
171
172 uns
173 obj_find_anum(struct odes *o, uns x, uns def)
174 {
175   struct oattr *a = obj_find_attr(o, x);
176   return a ? (uns)atol(a->val) : def;
177 }
178
179 u32
180 obj_find_x32(struct odes *o, uns x, u32 def)
181 {
182   struct oattr *a = obj_find_attr(o, x);
183   return a ? (u32)strtoul(a->val, NULL, 16) : def;
184 }
185
186 u64
187 obj_find_x64(struct odes *o, uns x, u64 def)
188 {
189   struct oattr *a = obj_find_attr(o, x);
190   return a ? (u64)strtoull(a->val, NULL, 16) : def;
191 }
192
193 struct oattr *
194 obj_set_attr(struct odes *o, uns x, byte *v)
195 {
196   struct oattr *a, **z;
197
198   z = &o->attrs;
199   while (a = *z)
200     {
201       if (a->attr == x)
202         {
203           *z = a->next;
204           goto set;
205         }
206       z = &a->next;
207     }
208
209  set:
210   if (v)
211     {
212       a = oa_new(o, x, v);
213       a->next = o->attrs;
214       o->attrs = a;
215     }
216   else
217     a = NULL;
218   o->cached_attr = a;
219   return a;
220 }
221
222 struct oattr *
223 obj_set_attr_num(struct odes *o, uns a, uns v)
224 {
225   byte x[32];
226
227   sprintf(x, "%d", v);
228   return obj_set_attr(o, a, x);
229 }
230
231 static inline struct oattr *
232 obj_link_attr(struct odes *o, struct oattr *b)
233 {
234   struct oattr *a, **z;
235
236   if (!(a = o->cached_attr) || a->attr != b->attr)
237     {
238       z = &o->attrs;
239       while ((a = *z) && a->attr != b->attr)
240         z = &a->next;
241       if (!a)
242         {
243           *z = b;
244           /* b->next is NULL */
245           goto done;
246         }
247     }
248   while (a->same)
249     a = a->same;
250   a->same = b;
251  done:
252   o->cached_attr = b;
253   return b;
254 }
255
256 struct oattr *
257 obj_add_attr(struct odes *o, uns x, byte *v)
258 {
259   return obj_link_attr(o, oa_new(o, x, v));
260 }
261
262 struct oattr *
263 obj_add_attr_ref(struct odes *o, uns x, byte *v)
264 {
265   return obj_link_attr(o, oa_new_ref(o, x, v));
266 }
267
268 struct oattr *
269 obj_add_attr_num(struct odes *o, uns a, uns v)
270 {
271   byte x[32];
272
273   sprintf(x, "%d", v);
274   return obj_add_attr(o, a, x);
275 }
276
277 struct oattr *
278 obj_add_attr_son(struct odes *o, uns x, struct odes *son)
279 {
280   return obj_link_attr(o, oa_new_son(o, x, son));
281 }
282
283 struct oattr *
284 obj_prepend_attr(struct odes *o, uns x, byte *v)
285 {
286   struct oattr *a, *b, **z;
287
288   b = oa_new(o, x, v);
289   z = &o->attrs;
290   while (a = *z)
291     {
292       if (a->attr == x)
293         {
294           b->same = a;
295           b->next = a->next;
296           a->next = NULL;
297           *z = b;
298           return b;
299         }
300       z = &a->next;
301     }
302   b->next = o->attrs;
303   o->attrs = b;
304   return b;
305 }
306
307 struct oattr *
308 obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v)
309 {
310   struct oattr *b = oa_new(o, first->attr, v);
311   b->same = after->same;
312   after->same = b;
313   return b;
314 }
315
316 void
317 obj_move_attr_to_head(struct odes *o, uns x)
318 {
319   struct oattr *a, **z;
320
321   z = &o->attrs;
322   while (a = *z)
323     {
324       if (a->attr == x)
325         {
326           *z = a->next;
327           a->next = o->attrs;
328           o->attrs = a;
329           break;
330         }
331       z = &a->next;
332     }
333 }
334
335 void
336 obj_move_attr_to_tail(struct odes *o, uns x)
337 {
338   struct oattr *a, **z;
339
340   z = &o->attrs;
341   while (a = *z)
342     {
343       if (a->attr == x)
344         {
345           *z = a->next;
346           while (*z)
347             z = &(*z)->next;
348           *z = a;
349           a->next = NULL;
350           break;
351         }
352       z = &a->next;
353     }
354 }
355
356 struct odes *
357 obj_find_son(struct odes *o, uns x)
358 {
359   ASSERT(x >= OBJ_ATTR_SON);
360   struct oattr *a = obj_find_attr(o, x);
361   return a ? a->son : NULL;
362 }
363
364 struct oattr *
365 obj_add_son_ref(struct odes *o, uns x, struct odes *son)
366 {
367   struct oattr *oa = oa_new_son(o, x, son);
368   obj_link_attr(o, oa);
369   return oa;
370 }
371
372 struct odes *
373 obj_add_son(struct odes *o, uns x)
374 {
375   struct odes *son = obj_new(o->pool);
376   obj_add_son_ref(o, x, son);
377   return son;
378 }
379
380 static void obj_clone_attr_list(struct odes *dest, struct odes *src);
381
382 static struct oattr *
383 obj_clone_attr(struct odes *dest, struct oattr *a)
384 {
385   struct oattr *res = NULL, **rr = &res;
386   if (a->attr < OBJ_ATTR_SON)
387     {
388       for (; a; a=a->same)
389         {
390           *rr = oa_new(dest, a->attr, a->val);
391           rr = &(*rr)->same;
392         }
393     }
394   else
395     {
396       for (; a; a=a->same)
397         {
398           struct odes *dson = obj_new(dest->pool);
399           *rr = oa_new_son(dest, a->attr, dson);
400           rr = &(*rr)->same;
401           obj_clone_attr_list(dson, a->son);
402         }
403     }
404   return res;
405 }
406
407 static void
408 obj_clone_attr_list(struct odes *dest, struct odes *src)
409 {
410   struct oattr **p = &dest->attrs;
411   for (struct oattr *a = src->attrs; a; a=a->next)
412     {
413       *p = obj_clone_attr(dest, a);
414       p = &(*p)->next;
415     }
416 }
417
418 void
419 obj_add_attr_clone(struct odes *o, struct oattr *a)
420 {
421   obj_link_attr(o, obj_clone_attr(o, a));
422 }
423
424 struct odes *
425 obj_clone(struct mempool *pool, struct odes *src)
426 {
427   struct odes *dest = obj_new(pool);
428   obj_clone_attr_list(dest, src);
429   return dest;
430 }