summaryrefslogtreecommitdiff
path: root/src/lib/eet/eet_node.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-17 16:35:38 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-17 16:35:38 +0000
commit8abaff3bdf53ecc7e605b82b12e385b8c0a02327 (patch)
tree4c828ae7083f724fd0214cf3624b20a7cf9448d2 /src/lib/eet/eet_node.c
parent12732ab7ebcacad66352d3d48306e9945a4a584f (diff)
merge: add eet
SVN revision: 76768
Diffstat (limited to 'src/lib/eet/eet_node.c')
-rw-r--r--src/lib/eet/eet_node.c797
1 files changed, 797 insertions, 0 deletions
diff --git a/src/lib/eet/eet_node.c b/src/lib/eet/eet_node.c
new file mode 100644
index 0000000000..faaa90587b
--- /dev/null
+++ b/src/lib/eet/eet_node.c
@@ -0,0 +1,797 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#include <string.h>
6#include <stdio.h>
7
8#ifdef HAVE_EVIL
9# include <Evil.h>
10#endif /* ifdef HAVE_EVIL */
11
12#include <Eina.h>
13
14#include "Eet.h"
15#include "Eet_private.h"
16
17static Eina_Mempool *_eet_node_mp = NULL;
18
19Eet_Node *
20eet_node_new(void)
21{
22 Eet_Node *result;
23
24 result = eina_mempool_malloc(_eet_node_mp, sizeof (Eet_Node));
25 if (!result)
26 return NULL;
27
28 memset(result, 0, sizeof (Eet_Node));
29 return result;
30}
31
32void
33eet_node_free(Eet_Node *node)
34{
35 eina_mempool_free(_eet_node_mp, node);
36}
37
38static Eet_Node *
39_eet_node_new(const char *name,
40 int type)
41{
42 Eet_Node *n;
43
44 n = eet_node_new();
45 if (!n)
46 return NULL;
47
48 n->type = type;
49 n->name = eina_stringshare_add(name);
50
51 return n;
52}
53
54static void
55_eet_node_append(Eet_Node *n,
56 Eina_List *nodes)
57{
58 Eet_Node *value;
59 Eina_List *l;
60
61 EINA_LIST_REVERSE_FOREACH(nodes, l, value)
62 {
63 value->next = n->values;
64 n->values = value;
65 }
66}
67
68#define EET_NODE_NEW(Eet_type, Name, Value, Type) \
69 EAPI Eet_Node * \
70 eet_node_ ## Name ## _new(const char *name, Type Value) \
71 { \
72 Eet_Node *n; \
73 \
74 n = _eet_node_new(name, Eet_type); \
75 if (!n) { return NULL; } \
76 \
77 n->data.value.Value = Value; \
78 \
79 return n; \
80 }
81
82#define EET_NODE_STR_NEW(Eet_type, Name, Value, Type) \
83 EAPI Eet_Node * \
84 eet_node_ ## Name ## _new(const char *name, Type Value) \
85 { \
86 Eet_Node *n; \
87 \
88 n = _eet_node_new(name, Eet_type); \
89 if (!n) { return NULL; } \
90 \
91 n->data.value.Value = eina_stringshare_add(Value); \
92 \
93 return n; \
94 }
95
96EET_NODE_NEW(EET_T_CHAR, char, c, char)
97EET_NODE_NEW(EET_T_SHORT, short, s, short)
98EET_NODE_NEW(EET_T_INT, int, i, int)
99EET_NODE_NEW(EET_T_LONG_LONG, long_long, l, long long)
100EET_NODE_NEW(EET_T_FLOAT, float, f, float)
101EET_NODE_NEW(EET_T_DOUBLE, double, d, double)
102EET_NODE_NEW(EET_T_UCHAR, unsigned_char, uc, unsigned char)
103EET_NODE_NEW(EET_T_USHORT, unsigned_short, us, unsigned short)
104EET_NODE_NEW(EET_T_UINT, unsigned_int, ui, unsigned int)
105EET_NODE_NEW(EET_T_ULONG_LONG, unsigned_long_long, ul, unsigned long long)
106EET_NODE_STR_NEW(EET_T_STRING, string, str, const char *)
107EET_NODE_STR_NEW(EET_T_INLINED_STRING, inlined_string, str, const char *)
108
109Eet_Node *
110eet_node_null_new(const char *name)
111{
112 Eet_Node *n;
113
114 n = _eet_node_new(name, EET_T_NULL);
115 if (!n)
116 return NULL;
117
118 n->data.value.str = NULL;
119
120 return n;
121}
122
123Eet_Node *
124eet_node_list_new(const char *name,
125 Eina_List *nodes)
126{
127 Eet_Node *n;
128
129 n = _eet_node_new(name, EET_G_LIST);
130 if (!n)
131 return NULL;
132
133 _eet_node_append(n, nodes);
134
135 return n;
136}
137
138Eet_Node *
139eet_node_array_new(const char *name,
140 int count,
141 Eina_List *nodes)
142{
143 Eet_Node *n;
144
145 n = _eet_node_new(name, EET_G_ARRAY);
146 if (!n)
147 return NULL;
148
149 n->count = count;
150
151 _eet_node_append(n, nodes);
152
153 return n;
154}
155
156Eet_Node *
157eet_node_var_array_new(const char *name,
158 Eina_List *nodes)
159{
160 Eet_Node *n;
161
162 n = _eet_node_new(name, EET_G_VAR_ARRAY);
163 if (!n)
164 return NULL;
165
166 n->count = eina_list_count(nodes);
167
168 _eet_node_append(n, nodes);
169
170 return n;
171}
172
173Eet_Node *
174eet_node_hash_new(const char *name,
175 const char *key,
176 Eet_Node *node)
177{
178 Eina_List *nodes;
179 Eet_Node *n;
180
181 if (!node)
182 return NULL;
183
184 n = _eet_node_new(name, EET_G_HASH);
185 if (!n)
186 return NULL;
187
188 n->key = eina_stringshare_add(key);
189 nodes = eina_list_append(NULL, node);
190
191 _eet_node_append(n, nodes);
192
193 return n;
194}
195
196Eet_Node *
197eet_node_struct_new(const char *name,
198 Eina_List *nodes)
199{
200 Eet_Node *n;
201
202 n = _eet_node_new(name, EET_G_UNKNOWN);
203 if (!n)
204 return NULL;
205
206 _eet_node_append(n, nodes);
207
208 return n;
209}
210
211Eet_Node *
212eet_node_struct_child_new(const char *parent,
213 Eet_Node *child)
214{
215 Eet_Node *n;
216
217 if (!child) return NULL;
218
219 if (child->type != EET_G_UNKNOWN)
220 return child;
221
222 n = _eet_node_new(parent, EET_G_UNKNOWN);
223 if (!n)
224 return NULL;
225
226 _eet_node_append(n, eina_list_prepend(NULL, child));
227
228 return n;
229}
230
231Eet_Node *
232eet_node_children_get(Eet_Node *node)
233{
234 if (!node) return NULL;
235 return node->values;
236}
237
238Eet_Node *
239eet_node_next_get(Eet_Node *node)
240{
241 if (!node) return NULL;
242 return node->next;
243}
244
245Eet_Node *
246eet_node_parent_get(Eet_Node *node)
247{
248 if (!node) return NULL;
249 return node->parent;
250}
251
252void
253eet_node_list_append(Eet_Node *parent,
254 const char *name,
255 Eet_Node *child)
256{
257 const char *tmp;
258 Eet_Node *nn;
259
260 if ((!parent) || (!child)) return;
261 tmp = eina_stringshare_add(name);
262
263 for (nn = parent->values; nn; nn = nn->next)
264 if (nn->name == tmp && nn->type == EET_G_LIST)
265 {
266 Eet_Node *n;
267
268 if (!nn->values)
269 nn->values = child;
270 else
271 {
272 for (n = nn->values; n->next; n = n->next)
273 ;
274 n->next = child;
275 }
276
277 child->next = NULL;
278
279 eina_stringshare_del(tmp);
280
281 return;
282 }
283
284 /* No list found, so create it. */
285 nn = eet_node_list_new(tmp, eina_list_append(NULL, child));
286
287 /* And add it to the parent. */
288 nn->next = parent->values;
289 parent->values = nn;
290
291 eina_stringshare_del(tmp);
292}
293
294void
295eet_node_struct_append(Eet_Node *parent,
296 const char *name,
297 Eet_Node *child)
298{
299 const char *tmp;
300 Eet_Node *prev;
301 Eet_Node *nn;
302
303 if ((!parent) || (!child)) return;
304 if (parent->type != EET_G_UNKNOWN)
305 {
306 ERR("[%s] is not a structure. Will not insert [%s] in it",
307 parent->name,
308 name);
309 eet_node_del(child);
310 return;
311 }
312
313 tmp = eina_stringshare_add(name);
314
315 for (prev = NULL, nn = parent->values; nn; prev = nn, nn = nn->next)
316 if (nn->name == tmp && nn->type == child->type)
317 {
318 if (prev)
319 prev->next = nn->next;
320 else
321 parent->values = nn->next;
322
323 nn->next = NULL;
324 eet_node_del(nn);
325
326 break;
327 }
328
329 if (prev)
330 {
331 prev->next = child;
332 child->next = NULL;
333 }
334 else
335 {
336 child->next = NULL;
337 parent->values = child;
338 }
339
340 eina_stringshare_del(tmp);
341}
342
343void
344eet_node_hash_add(Eet_Node *parent,
345 const char *name,
346 const char *key,
347 Eet_Node *child)
348{
349 Eet_Node *nn;
350
351 if ((!parent) || (!child)) return;
352
353 /* No list found, so create it. */
354 nn = eet_node_hash_new(name, key, child);
355
356 /* And add it to the parent. */
357 nn->next = parent->values;
358 parent->values = nn;
359}
360
361int
362eet_node_type_get(Eet_Node *node)
363{
364 if (!node) return EET_T_UNKNOW;
365 return node->type;
366}
367
368Eet_Node_Data *
369eet_node_value_get(Eet_Node *node)
370{
371 if (!node) return NULL;
372 return &node->data;
373}
374
375const char *
376eet_node_name_get(Eet_Node *node)
377{
378 if (!node) return NULL;
379 return node->name;
380}
381
382void
383eet_node_del(Eet_Node *n)
384{
385 Eet_Node *nn;
386 Eet_Node *tmp;
387
388 if (!n)
389 return;
390
391 switch (n->type)
392 {
393 case EET_G_HASH:
394 eina_stringshare_del(n->key);
395
396 case EET_G_UNKNOWN:
397 case EET_G_VAR_ARRAY:
398 case EET_G_ARRAY:
399 case EET_G_LIST:
400 for (nn = n->values; nn; )
401 {
402 tmp = nn;
403 nn = nn->next;
404 eet_node_del(tmp);
405 }
406 break;
407
408 case EET_T_STRING:
409 case EET_T_INLINED_STRING:
410 eina_stringshare_del(n->data.value.str);
411 break;
412
413 case EET_T_CHAR:
414 case EET_T_SHORT:
415 case EET_T_INT:
416 case EET_T_LONG_LONG:
417 case EET_T_FLOAT:
418 case EET_T_DOUBLE:
419 case EET_T_UCHAR:
420 case EET_T_USHORT:
421 case EET_T_UINT:
422 break;
423 }
424
425 eina_stringshare_del(n->name);
426 eet_node_free(n);
427}
428
429static const char *eet_node_dump_g_name[6] = {
430 "struct",
431 "array",
432 "var_array",
433 "list",
434 "hash",
435 "???"
436};
437
438static const char *eet_node_dump_t_name[14][2] = {
439 { "???: ", "???" },
440 { "char: ", "%hhi" },
441 { "short: ", "%hi" },
442 { "int: ", "%i" },
443 { "long_long: ", "%lli" },
444 { "float: ", "%1.25f" },
445 { "double: ", "%1.25f" },
446 { "uchar: ", "%hhu" },
447 { "ushort: ", "%i" },
448 { "uint: ", "%u" },
449 { "ulong_long: ", "%llu" },
450 { "null", "" }
451};
452
453static void
454eet_node_dump_level(int level,
455 Eet_Dump_Callback dumpfunc,
456 void *dumpdata)
457{
458 int i;
459
460 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
461}
462
463static char *
464eet_node_string_escape(const char *str)
465{
466 char *s, *sp;
467 const char *strp;
468 int sz = 0;
469
470 for (strp = str; *strp; strp++)
471 {
472 if (*strp == '\"')
473 sz += 2;
474 else if (*strp == '\\')
475 sz += 2;
476 else if (*strp == '\n')
477 sz += 2;
478 else
479 sz += 1;
480 }
481 s = malloc(sz + 1);
482 if (!s)
483 return NULL;
484
485 for (strp = str, sp = s; *strp; strp++, sp++)
486 {
487 if (*strp == '\"'
488 || *strp == '\\'
489 || *strp == '\n')
490 {
491 *sp = '\\';
492 sp++;
493 }
494
495 if (*strp == '\n')
496 *sp = 'n';
497 else
498 *sp = *strp;
499 }
500 *sp = 0;
501 return s;
502}
503
504static void
505eet_node_dump_string_escape(void *dumpdata,
506 Eet_Dump_Callback dumpfunc,
507 const char *str)
508{
509 char *s;
510
511 s = eet_node_string_escape(str);
512 if (!s)
513 return;
514
515 dumpfunc(dumpdata, s);
516 free(s);
517}
518
519static void
520eet_node_dump_simple_type(Eet_Node *n,
521 int level,
522 Eet_Dump_Callback dumpfunc,
523 void *dumpdata)
524{
525 const char *type_name = NULL;
526 char tbuf[256];
527
528 eet_node_dump_level(level, dumpfunc, dumpdata);
529 dumpfunc(dumpdata, "value \"");
530 eet_node_dump_string_escape(dumpdata, dumpfunc, n->name);
531 dumpfunc(dumpdata, "\" ");
532
533#ifdef EET_T_TYPE
534# undef EET_T_TYPE
535#endif /* ifdef EET_T_TYPE */
536
537#define EET_T_TYPE(Eet_Type, Type) \
538case Eet_Type: \
539{ \
540 dumpfunc(dumpdata, eet_node_dump_t_name[Eet_Type][0]); \
541 snprintf(tbuf, \
542 sizeof (tbuf), \
543 eet_node_dump_t_name[Eet_Type][1], \
544 n->data.value.Type); \
545 dumpfunc(dumpdata, tbuf); \
546 break; \
547}
548
549 switch (n->type)
550 {
551 EET_T_TYPE(EET_T_CHAR, c);
552 EET_T_TYPE(EET_T_SHORT, s);
553 EET_T_TYPE(EET_T_INT, i);
554 EET_T_TYPE(EET_T_LONG_LONG, l);
555 EET_T_TYPE(EET_T_FLOAT, f);
556 EET_T_TYPE(EET_T_DOUBLE, d);
557 EET_T_TYPE(EET_T_UCHAR, uc);
558 EET_T_TYPE(EET_T_USHORT, us);
559 EET_T_TYPE(EET_T_UINT, ui);
560 EET_T_TYPE(EET_T_ULONG_LONG, ul);
561
562 case EET_T_INLINED_STRING:
563 type_name = "inlined: \"";
564
565 case EET_T_STRING:
566 if (!type_name)
567 type_name = "string: \"";
568
569 dumpfunc(dumpdata, type_name);
570 eet_node_dump_string_escape(dumpdata, dumpfunc, n->data.value.str);
571 dumpfunc(dumpdata, "\"");
572 break;
573
574 case EET_T_NULL:
575 dumpfunc(dumpdata, "null");
576 break;
577
578 default:
579 dumpfunc(dumpdata, "???: ???");
580 break;
581 }
582
583 dumpfunc(dumpdata, ";\n");
584}
585
586static void
587eet_node_dump_group_start(int level,
588 Eet_Dump_Callback dumpfunc,
589 void *dumpdata,
590 int group_type,
591 const char *name)
592{
593 int chnk_type;
594
595 chnk_type = (group_type >= EET_G_UNKNOWN && group_type <= EET_G_HASH) ?
596 group_type : EET_G_LAST;
597
598 eet_node_dump_level(level, dumpfunc, dumpdata);
599 dumpfunc(dumpdata, "group \"");
600 eet_node_dump_string_escape(dumpdata, dumpfunc, name);
601 dumpfunc(dumpdata, "\" ");
602
603 dumpfunc(dumpdata, eet_node_dump_g_name[chnk_type - EET_G_UNKNOWN]);
604 dumpfunc(dumpdata, " {\n");
605}
606
607static void
608eet_node_dump_group_end(int level,
609 Eet_Dump_Callback dumpfunc,
610 void *dumpdata)
611{
612 eet_node_dump_level(level, dumpfunc, dumpdata);
613 dumpfunc(dumpdata, "}\n");
614}
615
616void
617eet_node_dump(Eet_Node *n,
618 int dumplevel,
619 Eet_Dump_Callback dumpfunc,
620 void *dumpdata)
621{
622 Eet_Node *it;
623
624 if (!n)
625 return;
626
627 switch (n->type)
628 {
629 case EET_G_VAR_ARRAY:
630 case EET_G_ARRAY:
631 case EET_G_UNKNOWN:
632 case EET_G_HASH:
633 case EET_G_LIST:
634 eet_node_dump_group_start(dumplevel,
635 dumpfunc,
636 dumpdata,
637 n->type,
638 n->name);
639
640 if (n->type == EET_G_VAR_ARRAY
641 || n->type == EET_G_ARRAY)
642 {
643 char tbuf[256];
644
645 eet_node_dump_level(dumplevel, dumpfunc, dumpdata);
646 dumpfunc(dumpdata, " count ");
647 eina_convert_itoa(n->count, tbuf);
648 dumpfunc(dumpdata, tbuf);
649 dumpfunc(dumpdata, ";\n");
650 }
651 else if (n->type == EET_G_HASH)
652 {
653 eet_node_dump_level(dumplevel, dumpfunc, dumpdata);
654 dumpfunc(dumpdata, " key \"");
655 eet_node_dump_string_escape(dumpdata, dumpfunc, n->key);
656 dumpfunc(dumpdata, "\";\n");
657 }
658
659 for (it = n->values; it; it = it->next)
660 eet_node_dump(it, dumplevel + 2, dumpfunc, dumpdata);
661
662 eet_node_dump_group_end(dumplevel, dumpfunc, dumpdata);
663 break;
664
665 case EET_T_STRING:
666 case EET_T_INLINED_STRING:
667 case EET_T_CHAR:
668 case EET_T_SHORT:
669 case EET_T_INT:
670 case EET_T_LONG_LONG:
671 case EET_T_FLOAT:
672 case EET_T_DOUBLE:
673 case EET_T_UCHAR:
674 case EET_T_USHORT:
675 case EET_T_UINT:
676 case EET_T_ULONG_LONG:
677 eet_node_dump_simple_type(n, dumplevel, dumpfunc, dumpdata);
678 break;
679 }
680}
681
682void *
683eet_node_walk(void *parent,
684 const char *name,
685 Eet_Node *root,
686 Eet_Node_Walk *cb,
687 void *user_data)
688{
689 Eet_Node *it;
690 void *me = NULL;
691 int i;
692
693 if (!root)
694 {
695 if (parent)
696 cb->struct_add(parent, name, NULL, user_data);
697
698 return NULL;
699 }
700
701 switch (root->type)
702 {
703 case EET_G_UNKNOWN:
704 me = cb->struct_alloc(root->name, user_data);
705
706 for (it = root->values; it; it = it->next)
707 eet_node_walk(me, it->name, it, cb, user_data);
708
709 break;
710
711 case EET_G_VAR_ARRAY:
712 case EET_G_ARRAY:
713 me = cb->array(root->type == EET_G_VAR_ARRAY ? EINA_TRUE : EINA_FALSE,
714 root->name, root->count, user_data);
715
716 for (i = 0, it = root->values; it; it = it->next)
717 cb->insert(me, i++, eet_node_walk(NULL,
718 NULL,
719 it,
720 cb,
721 user_data), user_data);
722
723 break;
724
725 case EET_G_LIST:
726 me = cb->list(root->name, user_data);
727
728 for (it = root->values; it; it = it->next)
729 cb->append(me, eet_node_walk(NULL,
730 NULL,
731 it,
732 cb,
733 user_data), user_data);
734
735 break;
736
737 case EET_G_HASH:
738 if (!parent)
739 return NULL;
740
741 return cb->hash(parent, root->name, root->key,
742 eet_node_walk(NULL,
743 NULL,
744 root->values,
745 cb,
746 user_data), user_data);
747
748 case EET_T_STRING:
749 case EET_T_INLINED_STRING:
750 case EET_T_CHAR:
751 case EET_T_SHORT:
752 case EET_T_INT:
753 case EET_T_LONG_LONG:
754 case EET_T_FLOAT:
755 case EET_T_DOUBLE:
756 case EET_T_UCHAR:
757 case EET_T_USHORT:
758 case EET_T_UINT:
759 case EET_T_ULONG_LONG:
760 me = cb->simple(root->type, &root->data, user_data);
761 break;
762 }
763
764 if (parent)
765 cb->struct_add(parent, name, me, user_data);
766
767 return me;
768}
769
770int
771eet_node_init(void)
772{
773 const char *choice;
774 const char *tmp;
775
776#ifdef EINA_DEFAULT_MEMPOOL
777 choice = "pass_through";
778#else
779 choice = "chained_mempool";
780#endif
781 tmp = getenv("EINA_MEMPOOL");
782 if (tmp && tmp[0])
783 choice = tmp;
784
785 _eet_node_mp =
786 eina_mempool_add(choice, "eet-node-alloc", NULL, sizeof(Eet_Node), 32);
787
788 return _eet_node_mp ? 1 : 0;
789}
790
791void
792eet_node_shutdown(void)
793{
794 eina_mempool_del(_eet_node_mp);
795 _eet_node_mp = NULL;
796}
797