aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/bin/edje_external_inspector.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/edje/src/bin/edje_external_inspector.c
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/edje/src/bin/edje_external_inspector.c')
-rw-r--r--libraries/edje/src/bin/edje_external_inspector.c663
1 files changed, 663 insertions, 0 deletions
diff --git a/libraries/edje/src/bin/edje_external_inspector.c b/libraries/edje/src/bin/edje_external_inspector.c
new file mode 100644
index 0000000..6bd9a35
--- /dev/null
+++ b/libraries/edje/src/bin/edje_external_inspector.c
@@ -0,0 +1,663 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <locale.h>
6#include <fnmatch.h>
7
8#include <Ecore.h>
9#include <Ecore_Getopt.h>
10
11#include "Edje.h"
12
13static int _log_dom;
14#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
15#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
16#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
17#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
18#define CRIT(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
19
20#define INDENT " "
21#define INDENT2 INDENT INDENT
22#define INDENT3 INDENT2 INDENT
23#define INDENT4 INDENT3 INDENT
24
25static char *module_patterns_str = NULL;
26
27static int detail = 1;
28static Eina_Bool machine = EINA_FALSE;
29static char *type_glob = NULL;
30static char * const *module_patterns;
31static const Eina_List *modules;
32
33
34static char *
35_module_patterns_str_new(void)
36{
37 Eina_Strbuf *buf;
38 char * const *itr;
39 char *ret;
40 if (!module_patterns) return strdup("*");
41
42 buf = eina_strbuf_new();
43 for (itr = module_patterns; *itr != NULL; itr++)
44 {
45 eina_strbuf_append(buf, *itr);
46 if (itr[1]) eina_strbuf_append(buf, ", ");
47 }
48 ret = eina_strbuf_string_steal(buf);
49 eina_strbuf_free(buf);
50 return ret;
51}
52
53static Eina_Bool
54module_matches(const char *name)
55{
56 char * const *itr;
57 if (!module_patterns) return EINA_TRUE;
58
59 for (itr = module_patterns; *itr != NULL; itr++)
60 if (fnmatch(*itr, name, 0) == 0) return EINA_TRUE;
61
62 return EINA_FALSE;
63}
64
65static inline Eina_Bool
66type_matches(const char *name)
67{
68 if (!type_glob) return EINA_TRUE;
69 return fnmatch(type_glob, name, 0) == 0;
70}
71
72static int
73_types_sort(const void *pa, const void *pb)
74{
75 const Eina_Hash_Tuple *ha = pa, *hb = pb;
76 const Edje_External_Type *ta = ha->data, *tb = hb->data;
77 const char *na = ha->key, *nb = hb->key;
78 int r;
79
80 if (!ta->module) return -1;
81 if (!tb->module) return 1;
82 r = strcmp(ta->module, tb->module);
83 if (r != 0) return r;
84
85 if (!na) return -1;
86 if (!nb) return 1;
87 return strcmp(na, nb);
88}
89
90static const char *
91_param_type_str_get(const Edje_External_Param_Info *param)
92{
93 switch (param->type)
94 {
95 case EDJE_EXTERNAL_PARAM_TYPE_INT: return "int";
96 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: return "double";
97 case EDJE_EXTERNAL_PARAM_TYPE_STRING: return "string";
98 case EDJE_EXTERNAL_PARAM_TYPE_BOOL: return "bool";
99 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: return "choice";
100 default:
101 ERR("Unknown parameter type %d", param->type);
102 return "???";
103 }
104}
105
106static const char *
107_param_value_str_get(const Edje_External_Type *type, const Edje_External_Param_Info *param, char *buf, size_t buflen)
108{
109 switch (param->type)
110 {
111 case EDJE_EXTERNAL_PARAM_TYPE_INT:
112 if (param->info.i.def == EDJE_EXTERNAL_INT_UNSET) return NULL;
113 snprintf(buf, buflen, "%d", param->info.i.def);
114 return buf;
115
116 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
117 if (param->info.d.def == EDJE_EXTERNAL_DOUBLE_UNSET) return NULL;
118 snprintf(buf, buflen, "%g", param->info.d.def);
119 return buf;
120
121 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
122 return param->info.s.def;
123
124 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
125 if (param->info.b.def == 0) return "0";
126 else if (param->info.b.def == 1) return "1";
127 return NULL;
128
129 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
130 {
131 char *def;
132 if (param->info.c.def) return param->info.c.def;
133 if (!param->info.c.def_get) return NULL;
134 def = param->info.c.def_get(type->data, param);
135 if (!def) return NULL;
136 eina_strlcpy(buf, def, buflen);
137 free(def);
138 return buf;
139 }
140
141 default:
142 ERR("Unknown parameter type %d", param->type);
143 return NULL;
144 }
145}
146
147static const char *
148_param_flags_str_get(const Edje_External_Param_Info *param)
149{
150 static char buf[] = "GET|SET|STATE|CONSTRUCTOR";
151
152 if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_NONE) return "NONE";
153 if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_REGULAR) return "REGULAR";
154
155 buf[0] = '\0';
156
157 if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_GET)
158 strcat(buf, "GET");
159
160 if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_SET)
161 {
162 if (buf[0] != '\0') strcat(buf, "|");
163 strcat(buf, "SET");
164 }
165
166 if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_STATE)
167 {
168 if (buf[0] != '\0') strcat(buf, "|");
169 strcat(buf, "STATE");
170 }
171
172 if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_CONSTRUCTOR)
173 {
174 if (buf[0] != '\0') strcat(buf, "|");
175 strcat(buf, "CONSTRUCTOR");
176 }
177
178 return buf;
179}
180
181static void
182_param_choices_print(const char * const *choices)
183{
184 if (machine) puts("CHOICES-BEGIN");
185 else fputs(", choices:", stdout);
186 for (; *choices != NULL; choices++)
187 {
188 if (machine) puts(*choices);
189 else printf(" \"%s\"", *choices);
190 }
191 if (machine) puts("CHOICES-END");
192}
193
194static void
195_param_extra_details(const Edje_External_Type *type, const Edje_External_Param_Info *param)
196{
197 const char *str = _param_flags_str_get(param);
198 if (machine) printf("FLAGS: %s\n", str);
199 else printf(" /* flags: %s", str);
200
201 switch (param->type)
202 {
203 case EDJE_EXTERNAL_PARAM_TYPE_INT:
204 if (param->info.i.min != EDJE_EXTERNAL_INT_UNSET)
205 {
206 if (machine) printf("MIN: %d\n", param->info.i.min);
207 else printf(", min: %d", param->info.i.min);
208 }
209 if (param->info.i.max != EDJE_EXTERNAL_INT_UNSET)
210 {
211 if (machine) printf("MAX: %d\n", param->info.i.max);
212 else printf(", max: %d", param->info.i.max);
213 }
214 if (param->info.i.step != EDJE_EXTERNAL_INT_UNSET)
215 {
216 if (machine) printf("STEP: %d\n", param->info.i.step);
217 else printf(", step: %d", param->info.i.step);
218 }
219 break;
220
221 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
222 if (param->info.d.min != EDJE_EXTERNAL_DOUBLE_UNSET)
223 {
224 if (machine) printf("MIN: %g\n", param->info.d.min);
225 else printf(", min: %g", param->info.d.min);
226 }
227 if (param->info.d.max != EDJE_EXTERNAL_DOUBLE_UNSET)
228 {
229 if (machine) printf("MAX: %g\n", param->info.d.max);
230 else printf(", max: %g", param->info.d.max);
231 }
232 if (param->info.d.step != EDJE_EXTERNAL_DOUBLE_UNSET)
233 {
234 if (machine) printf("STEP: %g\n", param->info.d.step);
235 else printf(", step: %g", param->info.d.step);
236 }
237 break;
238
239 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
240 if (param->info.s.accept_fmt)
241 {
242 if (machine) printf("ACCEPT_FMT: %s\n", param->info.s.accept_fmt);
243 else printf(", accept_fmt: \"%s\"", param->info.s.accept_fmt);
244 }
245 if (param->info.s.deny_fmt)
246 {
247 if (machine) printf("DENY_FMT: %s\n", param->info.s.deny_fmt);
248 else printf(", deny_fmt: \"%s\"", param->info.s.deny_fmt);
249 }
250 break;
251
252 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
253 if (param->info.b.false_str)
254 {
255 if (machine) printf("FALSE_STR: %s\n", param->info.b.false_str);
256 else printf(", false_str: \"%s\"", param->info.b.false_str);
257 }
258 if (param->info.b.true_str)
259 {
260 if (machine) printf("TRUE_STR: %s\n", param->info.b.true_str);
261 else printf(", true_str: \"%s\"", param->info.b.true_str);
262 }
263 break;
264
265 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
266 {
267 if (param->info.c.choices)
268 _param_choices_print(param->info.c.choices);
269 else if (param->info.c.query)
270 {
271 char **choices = param->info.c.query(type->data, param);
272 if (choices)
273 {
274 char **itr;
275 _param_choices_print((const char * const*)choices);
276 for (itr = choices; *itr; itr++) free(*itr);
277 free(choices);
278 }
279 }
280 }
281 break;
282
283 default:
284 ERR("Unknown parameter type %d", param->type);
285 }
286
287 if (!machine) fputs(" */", stdout); /* \n not desired */
288}
289
290static int
291_info_list(void)
292{
293 Eina_Iterator *itr;
294 Eina_List *types;
295 const Eina_Hash_Tuple *tuple;
296 const Eina_List *l;
297 const char *name, *last_module;
298 Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
299 Eina_Bool in_module = EINA_FALSE;
300
301 EINA_LIST_FOREACH(modules, l, name)
302 {
303 if (!module_matches(name))
304 {
305 DBG("filter out module '%s': does not match '%s'",
306 name, module_patterns_str);
307 continue;
308 }
309
310 if (!edje_module_load(name))
311 {
312 ERR("error loading external '%s'", name);
313 continue;
314 }
315
316 module_found = EINA_TRUE;
317 }
318
319 itr = edje_external_iterator_get();
320 types = NULL;
321 EINA_ITERATOR_FOREACH(itr, tuple)
322 {
323 const Edje_External_Type *type = tuple->data;
324 name = tuple->key;
325
326 if (!type)
327 {
328 ERR("no type value for '%s'", name);
329 continue;
330 }
331 else if (type->abi_version != edje_external_type_abi_version_get())
332 {
333 ERR("type '%s' with incorrect abi_version %u (expected %u)",
334 name, type->abi_version, edje_external_type_abi_version_get());
335 continue;
336 }
337
338 if (!type_matches(name))
339 {
340 DBG("filter out type '%s': does not match '%s'", name, type_glob);
341 continue;
342 }
343
344 types = eina_list_append(types, tuple);
345 type_found = EINA_TRUE;
346 }
347 eina_iterator_free(itr);
348
349 last_module = NULL;
350 types = eina_list_sort(types, 0, _types_sort);
351 EINA_LIST_FREE(types, tuple)
352 {
353 Eina_Bool changed_module = EINA_FALSE;
354 const Edje_External_Type *type = tuple->data;
355 const Edje_External_Param_Info *param;
356 name = tuple->key;
357
358 if ((last_module) && (type->module))
359 {
360 changed_module = ((last_module != type->module) &&
361 (!strcmp(last_module, type->module)));
362 }
363 else if ((!last_module) && (type->module))
364 changed_module = EINA_TRUE;
365
366 if (changed_module)
367 {
368 if (in_module)
369 {
370 if (machine) puts("TYPES-END\nMODULE-END");
371 else puts(INDENT "}\n}");
372 }
373
374 if (machine)
375 printf("MODULE-BEGIN\n"
376 "NAME: %s\n"
377 "FRIENDLY-NAME: %s\n"
378 "TYPES-BEGIN\n",
379 type->module, type->module_name);
380 else
381 printf("module {\n"
382 INDENT "name: \"%s\";\n"
383 INDENT "friendly_name: \"%s\";\n"
384 INDENT "types {\n",
385 type->module, type->module_name);
386
387 in_module = EINA_TRUE;
388 }
389
390 if (machine) printf("TYPE-BEGIN\nNAME: %s\n", name);
391 else printf(INDENT2 "type {\n" INDENT3 "name: \"%s\";\n", name);
392
393 if (detail > 1)
394 {
395 const char *str;
396
397 if (!type->label_get) str = NULL;
398 else str = type->label_get(type->data);
399 if (machine) printf("LABEL: %s\n", str ? str : "");
400 else if (str) printf(INDENT3 "label: \"%s\";\n", str);
401
402 if (!type->description_get) str = NULL;
403 else str = type->description_get(type->data);
404 if (machine) printf("DESCRIPTION: %s\n", str ? str : "");
405 else if (str) printf(INDENT3 "description: \"%s\";\n", str);
406 }
407
408 if (machine) puts("PARAMS-BEGIN");
409 else puts(INDENT3 "params {");
410
411 for (param = type->parameters_info; param->name != NULL; param++)
412 {
413 const char *pt = _param_type_str_get(param);
414 char buf[128];
415
416 if (machine)
417 printf("PARAM-BEGIN\nNAME: %s\nTYPE: %s\n", param->name, pt);
418 else printf(INDENT4 "%s: \"%s\"", pt, param->name);
419
420 if (detail > 0)
421 {
422 const char *str = _param_value_str_get
423 (type, param, buf, sizeof(buf));
424 if (machine) printf("DEFAULT: %s\n", str ? str : "");
425 else if (str) printf(" \"%s\"", str);
426
427 if (detail > 1)
428 {
429 if (!machine) putchar(';');
430 _param_extra_details(type, param);
431 }
432 }
433
434 if (machine) puts("PARAM-END");
435 else if (detail > 1) putchar('\n');
436 else puts(";");
437 }
438
439 if (machine) puts("PARAMS-END\nTYPE-END");
440 else puts(INDENT3 "}\n" INDENT2 "}");
441
442 last_module = type->module;
443 }
444
445 if (in_module)
446 {
447 if (machine) puts("MODULE-END");
448 else puts(INDENT "}\n}");
449 }
450
451 if (!module_found) WRN("no modules match '%s'", module_patterns_str);
452 if (!type_found) WRN("no types match '%s'", type_glob);
453 return (!module_found) || (!type_found);
454}
455
456static int
457_types_names_list(void)
458{
459 Eina_Iterator *itr;
460 Eina_List *types;
461 const Eina_Hash_Tuple *tuple;
462 const Eina_List *l;
463 const char *name;
464 Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
465
466 EINA_LIST_FOREACH(modules, l, name)
467 {
468 if (!module_matches(name))
469 {
470 DBG("filter out module '%s': does not match '%s'",
471 name, module_patterns_str);
472 continue;
473 }
474
475 if (!edje_module_load(name))
476 {
477 ERR("error loading external '%s'", name);
478 continue;
479 }
480
481 module_found = EINA_TRUE;
482 }
483
484 itr = edje_external_iterator_get();
485 types = NULL;
486 EINA_ITERATOR_FOREACH(itr, tuple)
487 {
488 const Edje_External_Type *type = tuple->data;
489 name = tuple->key;
490
491 if (!type)
492 {
493 ERR("no type value for '%s'", name);
494 continue;
495 }
496 else if (type->abi_version != edje_external_type_abi_version_get())
497 {
498 ERR("type '%s' with incorrect abi_version %u (expected %u)",
499 name, type->abi_version, edje_external_type_abi_version_get());
500 continue;
501 }
502
503 if (!type_matches(name))
504 {
505 DBG("filter out type '%s': does not match '%s'", name, type_glob);
506 continue;
507 }
508
509 types = eina_list_append(types, tuple);
510 type_found = EINA_TRUE;
511 }
512 eina_iterator_free(itr);
513
514 types = eina_list_sort(types, 0, _types_sort);
515 EINA_LIST_FREE(types, tuple)
516 puts(tuple->key);
517
518 if (!module_found) WRN("no modules match '%s'", module_patterns_str);
519 if (!type_found) WRN("no types match '%s'", type_glob);
520 return (!module_found) || (!type_found);
521}
522
523static int
524_modules_names_list(void)
525{
526 const Eina_List *l;
527 const char *name;
528 Eina_Bool found = EINA_FALSE;
529
530 EINA_LIST_FOREACH(modules, l, name)
531 {
532 if (!module_matches(name))
533 {
534 DBG("filter out module '%s': does not match '%s'",
535 name, module_patterns_str);
536 continue;
537 }
538 found = EINA_TRUE;
539 puts(name);
540 }
541
542 if (!found) WRN("no modules match '%s'", module_patterns_str);
543 return !found;
544}
545
546static const char *mode_choices[] = {
547 "info",
548 "modules-names",
549 "types-names",
550 NULL,
551};
552
553static const char *detail_choices[] = {
554 "none",
555 "terse",
556 "all",
557 NULL
558};
559
560const Ecore_Getopt optdesc = {
561 "edje_external_inspector",
562 "%prog [options] [module|module-glob] ... [module|module-glob]",
563 PACKAGE_VERSION,
564 "(C) 2010 - The Enlightenment Project",
565 "BSD",
566 "Edje external module inspector.",
567 0,
568 {
569 ECORE_GETOPT_CHOICE('m', "mode", "Choose which mode to operate.",
570 mode_choices),
571 ECORE_GETOPT_STORE_STR('t', "type", "Limit output to type (or glob)."),
572 ECORE_GETOPT_CHOICE('d', "detail", "Choose detail level (default=terse)",
573 detail_choices),
574 ECORE_GETOPT_STORE_TRUE('M', "machine", "Produce machine readable output."),
575 ECORE_GETOPT_LICENSE('L', "license"),
576 ECORE_GETOPT_COPYRIGHT('C', "copyright"),
577 ECORE_GETOPT_VERSION('V', "version"),
578 ECORE_GETOPT_HELP('h', "help"),
579 ECORE_GETOPT_SENTINEL
580 }
581};
582
583int
584main(int argc, char **argv)
585{
586 Eina_Bool quit_option = EINA_FALSE;
587 char *mode = NULL;
588 char *detail_name = NULL;
589 int arg_index;
590 int ret = 0;
591 Ecore_Getopt_Value values[] = {
592 ECORE_GETOPT_VALUE_STR(mode),
593 ECORE_GETOPT_VALUE_STR(type_glob),
594 ECORE_GETOPT_VALUE_STR(detail_name),
595 ECORE_GETOPT_VALUE_BOOL(machine),
596 ECORE_GETOPT_VALUE_BOOL(quit_option),
597 ECORE_GETOPT_VALUE_BOOL(quit_option),
598 ECORE_GETOPT_VALUE_BOOL(quit_option),
599 ECORE_GETOPT_VALUE_BOOL(quit_option),
600 ECORE_GETOPT_VALUE_NONE
601 };
602
603 setlocale(LC_NUMERIC, "C");
604
605 ecore_init();
606 eina_init();
607 edje_init();
608
609 _log_dom = eina_log_domain_register
610 ("edje_external_inspector", EINA_COLOR_YELLOW);
611 if (_log_dom < 0)
612 {
613 EINA_LOG_CRIT
614 ("could not register log domain 'edje_external_inspector'");
615 ret = 1;
616 goto error_log;
617 }
618
619 arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
620 if (arg_index < 0)
621 {
622 ERR("could not parse arguments.");
623 ret = 1;
624 goto error_getopt;
625 }
626 else if (quit_option) goto error_getopt;
627
628 if (!mode) mode = (char *)mode_choices[0];
629
630 if (detail_name)
631 {
632 if (!strcmp(detail_name, "none")) detail = 0;
633 else if (!strcmp(detail_name, "terse")) detail = 1;
634 else if (!strcmp(detail_name, "all")) detail = 2;
635 else ERR("Unknown detail level: '%s'", detail_name);
636 }
637
638 if (arg_index < argc) module_patterns = argv + arg_index;
639 else module_patterns = NULL;
640
641 modules = edje_available_modules_get();
642 module_patterns_str = _module_patterns_str_new();
643
644 if (!strcmp(mode, "info")) ret = _info_list();
645 else if (!strcmp(mode, "modules-names")) ret = _modules_names_list();
646 else if (!strcmp(mode, "types-names")) ret = _types_names_list();
647 else
648 {
649 ERR("Unknown mode: %s", mode);
650 ret = 1;
651 }
652
653 free(module_patterns_str);
654
655 error_getopt:
656 eina_log_domain_unregister(_log_dom);
657 error_log:
658 edje_shutdown();
659 ecore_shutdown();
660 eina_shutdown();
661
662 return ret;
663}