2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
19 #include "Eet_private.h"
21 static Eina_Mempool *_eet_node_mp = NULL;
28 result = eina_mempool_malloc(_eet_node_mp, sizeof (Eet_Node));
32 memset(result, 0, sizeof (Eet_Node));
37 eet_node_free(Eet_Node *node)
39 eina_mempool_free(_eet_node_mp, node);
43 _eet_node_new(const char *name, int type)
51 n->name = eina_stringshare_add(name);
57 _eet_node_append(Eet_Node *n, Eina_List *nodes)
62 EINA_LIST_REVERSE_FOREACH(nodes, l, value)
64 value->next = n->values;
69 #define EET_NODE_NEW(Eet_type, Name, Value, Type) \
71 eet_node_##Name##_new(const char *name, Type Value) \
75 n = _eet_node_new(name, Eet_type); \
76 if (!n) return NULL; \
78 n->data.value.Value = Value; \
83 #define EET_NODE_STR_NEW(Eet_type, Name, Value, Type) \
85 eet_node_##Name##_new(const char *name, Type Value) \
89 n = _eet_node_new(name, Eet_type); \
90 if (!n) return NULL; \
92 n->data.value.Value = eina_stringshare_add(Value); \
97 EET_NODE_NEW(EET_T_CHAR, char, c, char)
98 EET_NODE_NEW(EET_T_SHORT, short, s, short)
99 EET_NODE_NEW(EET_T_INT, int, i, int)
100 EET_NODE_NEW(EET_T_LONG_LONG, long_long, l, long long)
101 EET_NODE_NEW(EET_T_FLOAT, float, f, float)
102 EET_NODE_NEW(EET_T_DOUBLE, double, d, double)
103 EET_NODE_NEW(EET_T_UCHAR, unsigned_char, uc, unsigned char)
104 EET_NODE_NEW(EET_T_USHORT, unsigned_short, us, unsigned short)
105 EET_NODE_NEW(EET_T_UINT, unsigned_int, ui, unsigned int)
106 EET_NODE_NEW(EET_T_ULONG_LONG, unsigned_long_long, ul, unsigned long long)
107 EET_NODE_STR_NEW(EET_T_STRING, string, str, const char *)
108 EET_NODE_STR_NEW(EET_T_INLINED_STRING, inlined_string, str, const char *)
111 eet_node_null_new(const char *name)
115 n = _eet_node_new(name, EET_T_NULL);
118 n->data.value.str = NULL;
124 eet_node_list_new(const char *name, Eina_List *nodes)
128 n = _eet_node_new(name, EET_G_LIST);
131 _eet_node_append(n, nodes);
137 eet_node_array_new(const char *name, int count, Eina_List *nodes)
141 n = _eet_node_new(name, EET_G_ARRAY);
146 _eet_node_append(n, nodes);
152 eet_node_var_array_new(const char *name, Eina_List *nodes)
156 n = _eet_node_new(name, EET_G_VAR_ARRAY);
159 n->count = eina_list_count(nodes);
161 _eet_node_append(n, nodes);
167 eet_node_hash_new(const char *name, const char *key, Eet_Node *node)
172 if (!node) return NULL;
174 n = _eet_node_new(name, EET_G_HASH);
177 n->key = eina_stringshare_add(key);
178 nodes = eina_list_append(NULL, node);
180 _eet_node_append(n, nodes);
186 eet_node_struct_new(const char *name, Eina_List *nodes)
190 n = _eet_node_new(name, EET_G_UNKNOWN);
193 _eet_node_append(n, nodes);
199 eet_node_struct_child_new(const char *parent, Eet_Node *child)
203 if (child->type != EET_G_UNKNOWN)
206 n = _eet_node_new(parent, EET_G_UNKNOWN);
209 _eet_node_append(n, eina_list_prepend(NULL, child));
215 eet_node_list_append(Eet_Node *parent, const char *name, Eet_Node *child)
220 tmp = eina_stringshare_add(name);
222 for (nn = parent->values; nn; nn = nn->next)
223 if (nn->name == tmp && nn->type == EET_G_LIST)
227 if (!nn->values) nn->values = child;
230 for (n = nn->values; n->next; n = n->next)
236 eina_stringshare_del(tmp);
241 /* No list found, so create it. */
242 nn = eet_node_list_new(tmp, eina_list_append(NULL, child));
244 /* And add it to the parent. */
245 nn->next = parent->values;
248 eina_stringshare_del(tmp);
252 eet_node_struct_append(Eet_Node *parent, const char *name, Eet_Node *child)
258 if (parent->type != EET_G_UNKNOWN)
260 ERR("[%s] is not a structure. Will not insert [%s] in it", parent->name, name);
265 tmp = eina_stringshare_add(name);
267 for (prev = NULL, nn = parent->values; nn; prev = nn, nn = nn->next)
268 if (nn->name == tmp && nn->type == child->type)
270 if (prev) prev->next = nn->next;
271 else parent->values = nn->next;
287 parent->values = child;
290 eina_stringshare_del(tmp);
294 eet_node_hash_add(Eet_Node *parent, const char *name, const char *key, Eet_Node *child)
298 /* No list found, so create it. */
299 nn = eet_node_hash_new(name, key, child);
301 /* And add it to the parent. */
302 nn->next = parent->values;
307 eet_node_del(Eet_Node *n)
317 eina_stringshare_del(n->key);
319 case EET_G_VAR_ARRAY:
322 for (nn = n->values; nn; )
330 case EET_T_INLINED_STRING:
331 eina_stringshare_del(n->data.value.str);
336 case EET_T_LONG_LONG:
345 eina_stringshare_del(n->name);
349 static const char *eet_node_dump_g_name[6] = {
358 static const char *eet_node_dump_t_name[14][2] = {
360 { "char: ", "%hhi" },
361 { "short: ", "%hi" },
363 { "long_long: ", "%lli" },
364 { "float: ", "%1.25f" },
365 { "double: ", "%1.25f" },
366 { "uchar: ", "%hhu" },
367 { "ushort: ", "%i" },
369 { "ulong_long: ", "%llu" },
374 eet_node_dump_level(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata)
378 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
382 eet_node_string_escape(const char *str)
388 for (strp = str; *strp; strp++)
390 if (*strp == '\"') sz += 2;
391 else if (*strp == '\\') sz += 2;
392 else if (*strp == '\n') sz += 2;
397 for (strp = str, sp = s; *strp; strp++, sp++)
406 if (*strp == '\n') *sp = 'n';
414 eet_node_dump_string_escape(void *dumpdata, void dumpfunc(void *data, const char *str), const char *str)
418 s = eet_node_string_escape(str);
421 dumpfunc(dumpdata, s);
426 eet_node_dump_simple_type(Eet_Node *n, int level,
427 void (*dumpfunc) (void *data, const char *str), void *dumpdata)
429 const char *type_name = NULL;
432 eet_node_dump_level(level, dumpfunc, dumpdata);
433 dumpfunc(dumpdata, "value \"");
434 eet_node_dump_string_escape(dumpdata, dumpfunc, n->name);
435 dumpfunc(dumpdata, "\" ");
441 #define EET_T_TYPE(Eet_Type, Type) \
444 dumpfunc(dumpdata, eet_node_dump_t_name[Eet_Type][0]); \
445 snprintf(tbuf, sizeof (tbuf), eet_node_dump_t_name[Eet_Type][1], n->data.value.Type); \
446 dumpfunc(dumpdata, tbuf); \
452 EET_T_TYPE(EET_T_CHAR, c);
453 EET_T_TYPE(EET_T_SHORT, s);
454 EET_T_TYPE(EET_T_INT, i);
455 EET_T_TYPE(EET_T_LONG_LONG, l);
456 EET_T_TYPE(EET_T_FLOAT, f);
457 EET_T_TYPE(EET_T_DOUBLE, d);
458 EET_T_TYPE(EET_T_UCHAR, uc);
459 EET_T_TYPE(EET_T_USHORT, us);
460 EET_T_TYPE(EET_T_UINT, ui);
461 EET_T_TYPE(EET_T_ULONG_LONG, ul);
462 case EET_T_INLINED_STRING:
463 type_name = "inlined: \"";
465 if (!type_name) type_name = "string: \"";
467 dumpfunc(dumpdata, type_name);
468 eet_node_dump_string_escape(dumpdata, dumpfunc, n->data.value.str);
469 dumpfunc(dumpdata, "\"");
472 dumpfunc(dumpdata, "null");
475 dumpfunc(dumpdata, "???: ???");
479 dumpfunc(dumpdata, ";\n");
483 eet_node_dump_group_start(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
484 int group_type, const char *name)
488 chnk_type = (group_type >= EET_G_UNKNOWN && group_type <= EET_G_HASH) ?
489 group_type : EET_G_LAST;
491 eet_node_dump_level(level, dumpfunc, dumpdata);
492 dumpfunc(dumpdata, "group \"");
493 eet_node_dump_string_escape(dumpdata, dumpfunc, name);
494 dumpfunc(dumpdata, "\" ");
496 dumpfunc(dumpdata, eet_node_dump_g_name[chnk_type - EET_G_UNKNOWN]);
497 dumpfunc(dumpdata, " {\n");
501 eet_node_dump_group_end(int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata)
503 eet_node_dump_level(level, dumpfunc, dumpdata);
504 dumpfunc(dumpdata, "}\n");
508 eet_node_dump(Eet_Node *n, int dumplevel, void (*dumpfunc) (void *data, const char *str), void *dumpdata)
516 case EET_G_VAR_ARRAY:
521 eet_node_dump_group_start(dumplevel, dumpfunc, dumpdata, n->type, n->name);
523 if (n->type == EET_G_VAR_ARRAY
524 || n->type == EET_G_ARRAY)
528 eet_node_dump_level(dumplevel, dumpfunc, dumpdata);
529 dumpfunc(dumpdata, " count ");
530 eina_convert_itoa(n->count, tbuf);
531 dumpfunc(dumpdata, tbuf);
532 dumpfunc(dumpdata, ";\n");
534 else if (n->type == EET_G_HASH)
536 eet_node_dump_level(dumplevel, dumpfunc, dumpdata);
537 dumpfunc(dumpdata, " key \"");
538 eet_node_dump_string_escape(dumpdata, dumpfunc, n->key);
539 dumpfunc(dumpdata, "\";\n");
542 for (it = n->values; it != NULL; it = it->next)
543 eet_node_dump(it, dumplevel + 2, dumpfunc, dumpdata);
545 eet_node_dump_group_end(dumplevel, dumpfunc, dumpdata);
548 case EET_T_INLINED_STRING:
552 case EET_T_LONG_LONG:
558 case EET_T_ULONG_LONG:
559 eet_node_dump_simple_type(n, dumplevel, dumpfunc, dumpdata);
565 eet_node_walk(void *parent, const char *name, Eet_Node *root, Eet_Node_Walk *cb, void *user_data)
573 if (parent) cb->struct_add(parent, name, NULL, user_data);
580 me = cb->struct_alloc(root->name, user_data);
582 for (it = root->values; it != NULL; it = it->next)
583 eet_node_walk(me, it->name, it, cb, user_data);
586 case EET_G_VAR_ARRAY:
588 me = cb->array(root->type == EET_G_VAR_ARRAY ? EINA_TRUE : EINA_FALSE,
589 root->name, root->count, user_data);
591 for (i = 0, it = root->values; it != NULL; it = it->next)
592 cb->insert(me, i++, eet_node_walk(NULL, NULL, it, cb, user_data), user_data);
596 me = cb->list(root->name, user_data);
598 for (it = root->values; it != NULL; it = it->next)
599 cb->append(me, eet_node_walk(NULL, NULL, it, cb, user_data), user_data);
603 if (!parent) return NULL;
605 return cb->hash(parent, root->name, root->key, eet_node_walk(NULL, NULL, root->values, cb, user_data), user_data);
607 case EET_T_INLINED_STRING:
611 case EET_T_LONG_LONG:
617 case EET_T_ULONG_LONG:
618 me = cb->simple(root->type, &root->data, user_data);
622 if (parent) cb->struct_add(parent, name, me, user_data);
632 choice = "chained_mempool";
633 tmp = getenv("EET_MEMPOOL");
637 _eet_node_mp = eina_mempool_add(choice, "eet-node-alloc", NULL, sizeof(Eet_Node), 1024);
639 return _eet_node_mp ? 1 : 0;
643 eet_node_shutdown(void)
645 eina_mempool_del(_eet_node_mp);