8
#include <Ecore_Getopt.h>
13
#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
14
#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
15
#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
16
#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
17
#define CRI(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
20
#define INDENT2 INDENT INDENT
21
#define INDENT3 INDENT2 INDENT
22
#define INDENT4 INDENT3 INDENT
24
static char *module_patterns_str = NULL;
27
static Eina_Bool machine = EINA_FALSE;
28
static char *type_glob = NULL;
29
static char *const *module_patterns;
30
static const Eina_List *modules;
33
_module_patterns_str_new(void)
38
if (!module_patterns) return strdup("*");
40
buf = eina_strbuf_new();
41
for (itr = module_patterns; *itr != NULL; itr++)
43
eina_strbuf_append(buf, *itr);
44
if (itr[1]) eina_strbuf_append(buf, ", ");
46
ret = eina_strbuf_string_steal(buf);
47
eina_strbuf_free(buf);
52
module_matches(const char *name)
55
if (!module_patterns) return EINA_TRUE;
57
for (itr = module_patterns; *itr != NULL; itr++)
58
if (eina_fnmatch(*itr, name, 0)) return EINA_TRUE;
63
static inline Eina_Bool
64
type_matches(const char *name)
66
if (!type_glob) return EINA_TRUE;
67
return eina_fnmatch(type_glob, name, 0);
71
_types_sort(const void *pa, const void *pb)
73
const Eina_Hash_Tuple *ha = pa, *hb = pb;
74
const Edje_External_Type *ta = ha->data, *tb = hb->data;
75
const char *na = ha->key, *nb = hb->key;
78
if (!ta->module) return -1;
79
if (!tb->module) return 1;
80
r = strcmp(ta->module, tb->module);
85
return strcmp(na, nb);
89
_param_type_str_get(const Edje_External_Param_Info *param)
93
case EDJE_EXTERNAL_PARAM_TYPE_INT: return "int";
95
case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: return "double";
97
case EDJE_EXTERNAL_PARAM_TYPE_STRING: return "string";
99
case EDJE_EXTERNAL_PARAM_TYPE_BOOL: return "bool";
101
case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: return "choice";
104
ERR("Unknown parameter type %d", param->type);
110
_param_value_str_get(const Edje_External_Type *type, const Edje_External_Param_Info *param, char *buf, size_t buflen)
114
case EDJE_EXTERNAL_PARAM_TYPE_INT:
115
if (param->info.i.def == EDJE_EXTERNAL_INT_UNSET) return NULL;
116
snprintf(buf, buflen, "%d", param->info.i.def);
119
case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
120
if (EINA_DBL_EQ(param->info.d.def, EDJE_EXTERNAL_DOUBLE_UNSET)) return NULL;
121
snprintf(buf, buflen, "%g", param->info.d.def);
124
case EDJE_EXTERNAL_PARAM_TYPE_STRING:
125
return param->info.s.def;
127
case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
128
if (param->info.b.def == 0) return "0";
129
else if (param->info.b.def == 1)
133
case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
136
if (param->info.c.def) return param->info.c.def;
137
if (!param->info.c.def_get) return NULL;
138
def = param->info.c.def_get(type->data, param);
139
if (!def) return NULL;
140
eina_strlcpy(buf, def, buflen);
146
ERR("Unknown parameter type %d", param->type);
152
_param_flags_str_get(const Edje_External_Param_Info *param)
154
static char buf[] = "GET|SET|STATE|CONSTRUCTOR";
156
if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_NONE) return "NONE";
157
if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_REGULAR) return "REGULAR";
161
if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_GET)
164
if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_SET)
166
if (buf[0] != '\0') strcat(buf, "|");
170
if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_STATE)
172
if (buf[0] != '\0') strcat(buf, "|");
173
strcat(buf, "STATE");
176
if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_CONSTRUCTOR)
178
if (buf[0] != '\0') strcat(buf, "|");
179
strcat(buf, "CONSTRUCTOR");
186
_param_choices_print(const char *const *choices)
188
if (machine) puts("CHOICES-BEGIN");
189
else fputs(", choices:", stdout);
190
for (; *choices != NULL; choices++)
192
if (machine) puts(*choices);
193
else printf(" \"%s\"", *choices);
195
if (machine) puts("CHOICES-END");
199
_param_extra_details(const Edje_External_Type *type, const Edje_External_Param_Info *param)
201
const char *str = _param_flags_str_get(param);
202
if (machine) printf("FLAGS: %s\n", str);
203
else printf(" /* flags: %s", str);
207
case EDJE_EXTERNAL_PARAM_TYPE_INT:
208
if (param->info.i.min != EDJE_EXTERNAL_INT_UNSET)
210
if (machine) printf("MIN: %d\n", param->info.i.min);
211
else printf(", min: %d", param->info.i.min);
213
if (param->info.i.max != EDJE_EXTERNAL_INT_UNSET)
215
if (machine) printf("MAX: %d\n", param->info.i.max);
216
else printf(", max: %d", param->info.i.max);
218
if (param->info.i.step != EDJE_EXTERNAL_INT_UNSET)
220
if (machine) printf("STEP: %d\n", param->info.i.step);
221
else printf(", step: %d", param->info.i.step);
225
case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
226
if (EINA_DBL_EQ(param->info.d.min, EDJE_EXTERNAL_DOUBLE_UNSET))
228
if (machine) printf("MIN: %g\n", param->info.d.min);
229
else printf(", min: %g", param->info.d.min);
231
if (EINA_DBL_EQ(param->info.d.max, EDJE_EXTERNAL_DOUBLE_UNSET))
233
if (machine) printf("MAX: %g\n", param->info.d.max);
234
else printf(", max: %g", param->info.d.max);
236
if (EINA_DBL_EQ(param->info.d.step, EDJE_EXTERNAL_DOUBLE_UNSET))
238
if (machine) printf("STEP: %g\n", param->info.d.step);
239
else printf(", step: %g", param->info.d.step);
243
case EDJE_EXTERNAL_PARAM_TYPE_STRING:
244
if (param->info.s.accept_fmt)
246
if (machine) printf("ACCEPT_FMT: %s\n", param->info.s.accept_fmt);
247
else printf(", accept_fmt: \"%s\"", param->info.s.accept_fmt);
249
if (param->info.s.deny_fmt)
251
if (machine) printf("DENY_FMT: %s\n", param->info.s.deny_fmt);
252
else printf(", deny_fmt: \"%s\"", param->info.s.deny_fmt);
256
case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
257
if (param->info.b.false_str)
259
if (machine) printf("FALSE_STR: %s\n", param->info.b.false_str);
260
else printf(", false_str: \"%s\"", param->info.b.false_str);
262
if (param->info.b.true_str)
264
if (machine) printf("TRUE_STR: %s\n", param->info.b.true_str);
265
else printf(", true_str: \"%s\"", param->info.b.true_str);
269
case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
271
if (param->info.c.choices)
272
_param_choices_print(param->info.c.choices);
273
else if (param->info.c.query)
275
char **choices = param->info.c.query(type->data, param);
279
_param_choices_print((const char *const *)choices);
280
for (itr = choices; *itr; itr++)
289
ERR("Unknown parameter type %d", param->type);
292
if (!machine) fputs(" */", stdout); /* \n not desired */
300
const Eina_Hash_Tuple *tuple;
302
const char *name, *last_module;
303
Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
304
Eina_Bool in_module = EINA_FALSE;
306
EINA_LIST_FOREACH(modules, l, name)
308
if (!module_matches(name))
310
DBG("filter out module '%s': does not match '%s'",
311
name, module_patterns_str);
315
if (!edje_module_load(name))
317
ERR("error loading external '%s'", name);
321
module_found = EINA_TRUE;
324
itr = edje_external_iterator_get();
326
EINA_ITERATOR_FOREACH(itr, tuple)
328
const Edje_External_Type *type = tuple->data;
333
ERR("no type value for '%s'", name);
336
else if (type->abi_version != edje_external_type_abi_version_get())
338
ERR("type '%s' with incorrect abi_version %u (expected %u)",
339
name, type->abi_version, edje_external_type_abi_version_get());
343
if (!type_matches(name))
345
DBG("filter out type '%s': does not match '%s'", name, type_glob);
349
types = eina_list_append(types, tuple);
350
type_found = EINA_TRUE;
352
eina_iterator_free(itr);
355
types = eina_list_sort(types, 0, _types_sort);
356
EINA_LIST_FREE(types, tuple)
358
Eina_Bool changed_module = EINA_FALSE;
359
const Edje_External_Type *type = tuple->data;
360
const Edje_External_Param_Info *param;
363
if ((last_module) && (type->module))
365
changed_module = ((last_module != type->module) &&
366
(!strcmp(last_module, type->module)));
368
else if ((!last_module) && (type->module))
369
changed_module = EINA_TRUE;
375
if (machine) puts("TYPES-END\nMODULE-END");
376
else puts(INDENT "}\n}");
380
printf("MODULE-BEGIN\n"
382
"FRIENDLY-NAME: %s\n"
384
type->module, type->module_name);
387
INDENT "name: \"%s\";\n"
388
INDENT "friendly_name: \"%s\";\n"
390
type->module, type->module_name);
392
in_module = EINA_TRUE;
395
if (machine) printf("TYPE-BEGIN\nNAME: %s\n", name);
396
else printf(INDENT2 "type {\n" INDENT3 "name: \"%s\";\n", name);
402
if (!type->label_get) str = NULL;
403
else str = type->label_get(type->data);
404
if (machine) printf("LABEL: %s\n", str ? str : "");
406
printf(INDENT3 "label: \"%s\";\n", str);
408
if (!type->description_get) str = NULL;
409
else str = type->description_get(type->data);
410
if (machine) printf("DESCRIPTION: %s\n", str ? str : "");
412
printf(INDENT3 "description: \"%s\";\n", str);
415
if (machine) puts("PARAMS-BEGIN");
416
else puts(INDENT3 "params {");
418
for (param = type->parameters_info; param->name != NULL; param++)
420
const char *pt = _param_type_str_get(param);
424
printf("PARAM-BEGIN\nNAME: %s\nTYPE: %s\n", param->name, pt);
425
else printf(INDENT4 "%s: \"%s\"", pt, param->name);
429
const char *str = _param_value_str_get
430
(type, param, buf, sizeof(buf));
431
if (machine) printf("DEFAULT: %s\n", str ? str : "");
433
printf(" \"%s\"", str);
437
if (!machine) putchar(';');
438
_param_extra_details(type, param);
442
if (machine) puts("PARAM-END");
448
if (machine) puts("PARAMS-END\nTYPE-END");
449
else puts(INDENT3 "}\n" INDENT2 "}");
451
last_module = type->module;
456
if (machine) puts("MODULE-END");
457
else puts(INDENT "}\n}");
460
if (!module_found) WRN("no modules match '%s'", module_patterns_str);
461
if (!type_found) WRN("no types match '%s'", type_glob);
462
return (!module_found) || (!type_found);
466
_types_names_list(void)
470
const Eina_Hash_Tuple *tuple;
473
Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
475
EINA_LIST_FOREACH(modules, l, name)
477
if (!module_matches(name))
479
DBG("filter out module '%s': does not match '%s'",
480
name, module_patterns_str);
484
if (!edje_module_load(name))
486
ERR("error loading external '%s'", name);
490
module_found = EINA_TRUE;
493
itr = edje_external_iterator_get();
495
EINA_ITERATOR_FOREACH(itr, tuple)
497
const Edje_External_Type *type = tuple->data;
502
ERR("no type value for '%s'", name);
505
else if (type->abi_version != edje_external_type_abi_version_get())
507
ERR("type '%s' with incorrect abi_version %u (expected %u)",
508
name, type->abi_version, edje_external_type_abi_version_get());
512
if (!type_matches(name))
514
DBG("filter out type '%s': does not match '%s'", name, type_glob);
518
types = eina_list_append(types, tuple);
519
type_found = EINA_TRUE;
521
eina_iterator_free(itr);
523
types = eina_list_sort(types, 0, _types_sort);
524
EINA_LIST_FREE(types, tuple)
527
if (!module_found) WRN("no modules match '%s'", module_patterns_str);
528
if (!type_found) WRN("no types match '%s'", type_glob);
529
return (!module_found) || (!type_found);
533
_modules_names_list(void)
537
Eina_Bool found = EINA_FALSE;
539
EINA_LIST_FOREACH(modules, l, name)
541
if (!module_matches(name))
543
DBG("filter out module '%s': does not match '%s'",
544
name, module_patterns_str);
551
if (!found) WRN("no modules match '%s'", module_patterns_str);
555
static const char *mode_choices[] = {
562
static const char *detail_choices[] = {
569
const Ecore_Getopt optdesc = {
570
"edje_external_inspector",
571
"%prog [options] [module|module-glob] ... [module|module-glob]",
573
"(C) 2010 - The Enlightenment Project",
575
"Edje external module inspector.",
578
ECORE_GETOPT_CHOICE('m', "mode", "Choose which mode to operate.",
580
ECORE_GETOPT_STORE_STR('t', "type", "Limit output to type (or glob)."),
581
ECORE_GETOPT_CHOICE('d', "detail", "Choose detail level (default=terse)",
583
ECORE_GETOPT_STORE_TRUE('M', "machine", "Produce machine readable output."),
584
ECORE_GETOPT_LICENSE('L', "license"),
585
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
586
ECORE_GETOPT_VERSION('V', "version"),
587
ECORE_GETOPT_HELP('h', "help"),
588
ECORE_GETOPT_SENTINEL
593
main(int argc, char **argv)
595
Eina_Bool quit_option = EINA_FALSE;
597
char *detail_name = NULL;
600
Ecore_Getopt_Value values[] = {
601
ECORE_GETOPT_VALUE_STR(mode),
602
ECORE_GETOPT_VALUE_STR(type_glob),
603
ECORE_GETOPT_VALUE_STR(detail_name),
604
ECORE_GETOPT_VALUE_BOOL(machine),
605
ECORE_GETOPT_VALUE_BOOL(quit_option),
606
ECORE_GETOPT_VALUE_BOOL(quit_option),
607
ECORE_GETOPT_VALUE_BOOL(quit_option),
608
ECORE_GETOPT_VALUE_BOOL(quit_option),
609
ECORE_GETOPT_VALUE_NONE
612
setlocale(LC_NUMERIC, "C");
614
ecore_app_no_system_modules();
618
_log_dom = eina_log_domain_register
619
("edje_external_inspector", EINA_COLOR_YELLOW);
623
("could not register log domain 'edje_external_inspector'");
630
arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
633
ERR("could not parse arguments.");
637
else if (quit_option)
640
if (!mode) mode = (char *)mode_choices[0];
644
if (!strcmp(detail_name, "none")) detail = 0;
645
else if (!strcmp(detail_name, "terse"))
647
else if (!strcmp(detail_name, "all"))
649
else ERR("Unknown detail level: '%s'", detail_name);
652
if (arg_index < argc) module_patterns = argv + arg_index;
653
else module_patterns = NULL;
655
modules = edje_available_modules_get();
656
module_patterns_str = _module_patterns_str_new();
658
if (!strcmp(mode, "info")) ret = _info_list();
659
else if (!strcmp(mode, "modules-names"))
660
ret = _modules_names_list();
661
else if (!strcmp(mode, "types-names"))
662
ret = _types_names_list();
665
ERR("Unknown mode: %s", mode);
669
free(module_patterns_str);
673
eina_log_domain_unregister(_log_dom);