From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: 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. --- libraries/edje/src/bin/edje_external_inspector.c | 663 +++++++++++++++++++++++ 1 file changed, 663 insertions(+) create mode 100644 libraries/edje/src/bin/edje_external_inspector.c (limited to 'libraries/edje/src/bin/edje_external_inspector.c') 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 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include + +#include "Edje.h" + +static int _log_dom; +#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__) +#define CRIT(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__) + +#define INDENT " " +#define INDENT2 INDENT INDENT +#define INDENT3 INDENT2 INDENT +#define INDENT4 INDENT3 INDENT + +static char *module_patterns_str = NULL; + +static int detail = 1; +static Eina_Bool machine = EINA_FALSE; +static char *type_glob = NULL; +static char * const *module_patterns; +static const Eina_List *modules; + + +static char * +_module_patterns_str_new(void) +{ + Eina_Strbuf *buf; + char * const *itr; + char *ret; + if (!module_patterns) return strdup("*"); + + buf = eina_strbuf_new(); + for (itr = module_patterns; *itr != NULL; itr++) + { + eina_strbuf_append(buf, *itr); + if (itr[1]) eina_strbuf_append(buf, ", "); + } + ret = eina_strbuf_string_steal(buf); + eina_strbuf_free(buf); + return ret; +} + +static Eina_Bool +module_matches(const char *name) +{ + char * const *itr; + if (!module_patterns) return EINA_TRUE; + + for (itr = module_patterns; *itr != NULL; itr++) + if (fnmatch(*itr, name, 0) == 0) return EINA_TRUE; + + return EINA_FALSE; +} + +static inline Eina_Bool +type_matches(const char *name) +{ + if (!type_glob) return EINA_TRUE; + return fnmatch(type_glob, name, 0) == 0; +} + +static int +_types_sort(const void *pa, const void *pb) +{ + const Eina_Hash_Tuple *ha = pa, *hb = pb; + const Edje_External_Type *ta = ha->data, *tb = hb->data; + const char *na = ha->key, *nb = hb->key; + int r; + + if (!ta->module) return -1; + if (!tb->module) return 1; + r = strcmp(ta->module, tb->module); + if (r != 0) return r; + + if (!na) return -1; + if (!nb) return 1; + return strcmp(na, nb); +} + +static const char * +_param_type_str_get(const Edje_External_Param_Info *param) +{ + switch (param->type) + { + case EDJE_EXTERNAL_PARAM_TYPE_INT: return "int"; + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: return "double"; + case EDJE_EXTERNAL_PARAM_TYPE_STRING: return "string"; + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: return "bool"; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: return "choice"; + default: + ERR("Unknown parameter type %d", param->type); + return "???"; + } +} + +static const char * +_param_value_str_get(const Edje_External_Type *type, const Edje_External_Param_Info *param, char *buf, size_t buflen) +{ + switch (param->type) + { + case EDJE_EXTERNAL_PARAM_TYPE_INT: + if (param->info.i.def == EDJE_EXTERNAL_INT_UNSET) return NULL; + snprintf(buf, buflen, "%d", param->info.i.def); + return buf; + + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: + if (param->info.d.def == EDJE_EXTERNAL_DOUBLE_UNSET) return NULL; + snprintf(buf, buflen, "%g", param->info.d.def); + return buf; + + case EDJE_EXTERNAL_PARAM_TYPE_STRING: + return param->info.s.def; + + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + if (param->info.b.def == 0) return "0"; + else if (param->info.b.def == 1) return "1"; + return NULL; + + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + { + char *def; + if (param->info.c.def) return param->info.c.def; + if (!param->info.c.def_get) return NULL; + def = param->info.c.def_get(type->data, param); + if (!def) return NULL; + eina_strlcpy(buf, def, buflen); + free(def); + return buf; + } + + default: + ERR("Unknown parameter type %d", param->type); + return NULL; + } +} + +static const char * +_param_flags_str_get(const Edje_External_Param_Info *param) +{ + static char buf[] = "GET|SET|STATE|CONSTRUCTOR"; + + if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_NONE) return "NONE"; + if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_REGULAR) return "REGULAR"; + + buf[0] = '\0'; + + if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_GET) + strcat(buf, "GET"); + + if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_SET) + { + if (buf[0] != '\0') strcat(buf, "|"); + strcat(buf, "SET"); + } + + if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_STATE) + { + if (buf[0] != '\0') strcat(buf, "|"); + strcat(buf, "STATE"); + } + + if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_CONSTRUCTOR) + { + if (buf[0] != '\0') strcat(buf, "|"); + strcat(buf, "CONSTRUCTOR"); + } + + return buf; +} + +static void +_param_choices_print(const char * const *choices) +{ + if (machine) puts("CHOICES-BEGIN"); + else fputs(", choices:", stdout); + for (; *choices != NULL; choices++) + { + if (machine) puts(*choices); + else printf(" \"%s\"", *choices); + } + if (machine) puts("CHOICES-END"); +} + +static void +_param_extra_details(const Edje_External_Type *type, const Edje_External_Param_Info *param) +{ + const char *str = _param_flags_str_get(param); + if (machine) printf("FLAGS: %s\n", str); + else printf(" /* flags: %s", str); + + switch (param->type) + { + case EDJE_EXTERNAL_PARAM_TYPE_INT: + if (param->info.i.min != EDJE_EXTERNAL_INT_UNSET) + { + if (machine) printf("MIN: %d\n", param->info.i.min); + else printf(", min: %d", param->info.i.min); + } + if (param->info.i.max != EDJE_EXTERNAL_INT_UNSET) + { + if (machine) printf("MAX: %d\n", param->info.i.max); + else printf(", max: %d", param->info.i.max); + } + if (param->info.i.step != EDJE_EXTERNAL_INT_UNSET) + { + if (machine) printf("STEP: %d\n", param->info.i.step); + else printf(", step: %d", param->info.i.step); + } + break; + + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: + if (param->info.d.min != EDJE_EXTERNAL_DOUBLE_UNSET) + { + if (machine) printf("MIN: %g\n", param->info.d.min); + else printf(", min: %g", param->info.d.min); + } + if (param->info.d.max != EDJE_EXTERNAL_DOUBLE_UNSET) + { + if (machine) printf("MAX: %g\n", param->info.d.max); + else printf(", max: %g", param->info.d.max); + } + if (param->info.d.step != EDJE_EXTERNAL_DOUBLE_UNSET) + { + if (machine) printf("STEP: %g\n", param->info.d.step); + else printf(", step: %g", param->info.d.step); + } + break; + + case EDJE_EXTERNAL_PARAM_TYPE_STRING: + if (param->info.s.accept_fmt) + { + if (machine) printf("ACCEPT_FMT: %s\n", param->info.s.accept_fmt); + else printf(", accept_fmt: \"%s\"", param->info.s.accept_fmt); + } + if (param->info.s.deny_fmt) + { + if (machine) printf("DENY_FMT: %s\n", param->info.s.deny_fmt); + else printf(", deny_fmt: \"%s\"", param->info.s.deny_fmt); + } + break; + + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + if (param->info.b.false_str) + { + if (machine) printf("FALSE_STR: %s\n", param->info.b.false_str); + else printf(", false_str: \"%s\"", param->info.b.false_str); + } + if (param->info.b.true_str) + { + if (machine) printf("TRUE_STR: %s\n", param->info.b.true_str); + else printf(", true_str: \"%s\"", param->info.b.true_str); + } + break; + + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + { + if (param->info.c.choices) + _param_choices_print(param->info.c.choices); + else if (param->info.c.query) + { + char **choices = param->info.c.query(type->data, param); + if (choices) + { + char **itr; + _param_choices_print((const char * const*)choices); + for (itr = choices; *itr; itr++) free(*itr); + free(choices); + } + } + } + break; + + default: + ERR("Unknown parameter type %d", param->type); + } + + if (!machine) fputs(" */", stdout); /* \n not desired */ +} + +static int +_info_list(void) +{ + Eina_Iterator *itr; + Eina_List *types; + const Eina_Hash_Tuple *tuple; + const Eina_List *l; + const char *name, *last_module; + Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE; + Eina_Bool in_module = EINA_FALSE; + + EINA_LIST_FOREACH(modules, l, name) + { + if (!module_matches(name)) + { + DBG("filter out module '%s': does not match '%s'", + name, module_patterns_str); + continue; + } + + if (!edje_module_load(name)) + { + ERR("error loading external '%s'", name); + continue; + } + + module_found = EINA_TRUE; + } + + itr = edje_external_iterator_get(); + types = NULL; + EINA_ITERATOR_FOREACH(itr, tuple) + { + const Edje_External_Type *type = tuple->data; + name = tuple->key; + + if (!type) + { + ERR("no type value for '%s'", name); + continue; + } + else if (type->abi_version != edje_external_type_abi_version_get()) + { + ERR("type '%s' with incorrect abi_version %u (expected %u)", + name, type->abi_version, edje_external_type_abi_version_get()); + continue; + } + + if (!type_matches(name)) + { + DBG("filter out type '%s': does not match '%s'", name, type_glob); + continue; + } + + types = eina_list_append(types, tuple); + type_found = EINA_TRUE; + } + eina_iterator_free(itr); + + last_module = NULL; + types = eina_list_sort(types, 0, _types_sort); + EINA_LIST_FREE(types, tuple) + { + Eina_Bool changed_module = EINA_FALSE; + const Edje_External_Type *type = tuple->data; + const Edje_External_Param_Info *param; + name = tuple->key; + + if ((last_module) && (type->module)) + { + changed_module = ((last_module != type->module) && + (!strcmp(last_module, type->module))); + } + else if ((!last_module) && (type->module)) + changed_module = EINA_TRUE; + + if (changed_module) + { + if (in_module) + { + if (machine) puts("TYPES-END\nMODULE-END"); + else puts(INDENT "}\n}"); + } + + if (machine) + printf("MODULE-BEGIN\n" + "NAME: %s\n" + "FRIENDLY-NAME: %s\n" + "TYPES-BEGIN\n", + type->module, type->module_name); + else + printf("module {\n" + INDENT "name: \"%s\";\n" + INDENT "friendly_name: \"%s\";\n" + INDENT "types {\n", + type->module, type->module_name); + + in_module = EINA_TRUE; + } + + if (machine) printf("TYPE-BEGIN\nNAME: %s\n", name); + else printf(INDENT2 "type {\n" INDENT3 "name: \"%s\";\n", name); + + if (detail > 1) + { + const char *str; + + if (!type->label_get) str = NULL; + else str = type->label_get(type->data); + if (machine) printf("LABEL: %s\n", str ? str : ""); + else if (str) printf(INDENT3 "label: \"%s\";\n", str); + + if (!type->description_get) str = NULL; + else str = type->description_get(type->data); + if (machine) printf("DESCRIPTION: %s\n", str ? str : ""); + else if (str) printf(INDENT3 "description: \"%s\";\n", str); + } + + if (machine) puts("PARAMS-BEGIN"); + else puts(INDENT3 "params {"); + + for (param = type->parameters_info; param->name != NULL; param++) + { + const char *pt = _param_type_str_get(param); + char buf[128]; + + if (machine) + printf("PARAM-BEGIN\nNAME: %s\nTYPE: %s\n", param->name, pt); + else printf(INDENT4 "%s: \"%s\"", pt, param->name); + + if (detail > 0) + { + const char *str = _param_value_str_get + (type, param, buf, sizeof(buf)); + if (machine) printf("DEFAULT: %s\n", str ? str : ""); + else if (str) printf(" \"%s\"", str); + + if (detail > 1) + { + if (!machine) putchar(';'); + _param_extra_details(type, param); + } + } + + if (machine) puts("PARAM-END"); + else if (detail > 1) putchar('\n'); + else puts(";"); + } + + if (machine) puts("PARAMS-END\nTYPE-END"); + else puts(INDENT3 "}\n" INDENT2 "}"); + + last_module = type->module; + } + + if (in_module) + { + if (machine) puts("MODULE-END"); + else puts(INDENT "}\n}"); + } + + if (!module_found) WRN("no modules match '%s'", module_patterns_str); + if (!type_found) WRN("no types match '%s'", type_glob); + return (!module_found) || (!type_found); +} + +static int +_types_names_list(void) +{ + Eina_Iterator *itr; + Eina_List *types; + const Eina_Hash_Tuple *tuple; + const Eina_List *l; + const char *name; + Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE; + + EINA_LIST_FOREACH(modules, l, name) + { + if (!module_matches(name)) + { + DBG("filter out module '%s': does not match '%s'", + name, module_patterns_str); + continue; + } + + if (!edje_module_load(name)) + { + ERR("error loading external '%s'", name); + continue; + } + + module_found = EINA_TRUE; + } + + itr = edje_external_iterator_get(); + types = NULL; + EINA_ITERATOR_FOREACH(itr, tuple) + { + const Edje_External_Type *type = tuple->data; + name = tuple->key; + + if (!type) + { + ERR("no type value for '%s'", name); + continue; + } + else if (type->abi_version != edje_external_type_abi_version_get()) + { + ERR("type '%s' with incorrect abi_version %u (expected %u)", + name, type->abi_version, edje_external_type_abi_version_get()); + continue; + } + + if (!type_matches(name)) + { + DBG("filter out type '%s': does not match '%s'", name, type_glob); + continue; + } + + types = eina_list_append(types, tuple); + type_found = EINA_TRUE; + } + eina_iterator_free(itr); + + types = eina_list_sort(types, 0, _types_sort); + EINA_LIST_FREE(types, tuple) + puts(tuple->key); + + if (!module_found) WRN("no modules match '%s'", module_patterns_str); + if (!type_found) WRN("no types match '%s'", type_glob); + return (!module_found) || (!type_found); +} + +static int +_modules_names_list(void) +{ + const Eina_List *l; + const char *name; + Eina_Bool found = EINA_FALSE; + + EINA_LIST_FOREACH(modules, l, name) + { + if (!module_matches(name)) + { + DBG("filter out module '%s': does not match '%s'", + name, module_patterns_str); + continue; + } + found = EINA_TRUE; + puts(name); + } + + if (!found) WRN("no modules match '%s'", module_patterns_str); + return !found; +} + +static const char *mode_choices[] = { + "info", + "modules-names", + "types-names", + NULL, +}; + +static const char *detail_choices[] = { + "none", + "terse", + "all", + NULL +}; + +const Ecore_Getopt optdesc = { + "edje_external_inspector", + "%prog [options] [module|module-glob] ... [module|module-glob]", + PACKAGE_VERSION, + "(C) 2010 - The Enlightenment Project", + "BSD", + "Edje external module inspector.", + 0, + { + ECORE_GETOPT_CHOICE('m', "mode", "Choose which mode to operate.", + mode_choices), + ECORE_GETOPT_STORE_STR('t', "type", "Limit output to type (or glob)."), + ECORE_GETOPT_CHOICE('d', "detail", "Choose detail level (default=terse)", + detail_choices), + ECORE_GETOPT_STORE_TRUE('M', "machine", "Produce machine readable output."), + ECORE_GETOPT_LICENSE('L', "license"), + ECORE_GETOPT_COPYRIGHT('C', "copyright"), + ECORE_GETOPT_VERSION('V', "version"), + ECORE_GETOPT_HELP('h', "help"), + ECORE_GETOPT_SENTINEL + } +}; + +int +main(int argc, char **argv) +{ + Eina_Bool quit_option = EINA_FALSE; + char *mode = NULL; + char *detail_name = NULL; + int arg_index; + int ret = 0; + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_STR(mode), + ECORE_GETOPT_VALUE_STR(type_glob), + ECORE_GETOPT_VALUE_STR(detail_name), + ECORE_GETOPT_VALUE_BOOL(machine), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_NONE + }; + + setlocale(LC_NUMERIC, "C"); + + ecore_init(); + eina_init(); + edje_init(); + + _log_dom = eina_log_domain_register + ("edje_external_inspector", EINA_COLOR_YELLOW); + if (_log_dom < 0) + { + EINA_LOG_CRIT + ("could not register log domain 'edje_external_inspector'"); + ret = 1; + goto error_log; + } + + arg_index = ecore_getopt_parse(&optdesc, values, argc, argv); + if (arg_index < 0) + { + ERR("could not parse arguments."); + ret = 1; + goto error_getopt; + } + else if (quit_option) goto error_getopt; + + if (!mode) mode = (char *)mode_choices[0]; + + if (detail_name) + { + if (!strcmp(detail_name, "none")) detail = 0; + else if (!strcmp(detail_name, "terse")) detail = 1; + else if (!strcmp(detail_name, "all")) detail = 2; + else ERR("Unknown detail level: '%s'", detail_name); + } + + if (arg_index < argc) module_patterns = argv + arg_index; + else module_patterns = NULL; + + modules = edje_available_modules_get(); + module_patterns_str = _module_patterns_str_new(); + + if (!strcmp(mode, "info")) ret = _info_list(); + else if (!strcmp(mode, "modules-names")) ret = _modules_names_list(); + else if (!strcmp(mode, "types-names")) ret = _types_names_list(); + else + { + ERR("Unknown mode: %s", mode); + ret = 1; + } + + free(module_patterns_str); + + error_getopt: + eina_log_domain_unregister(_log_dom); + error_log: + edje_shutdown(); + ecore_shutdown(); + eina_shutdown(); + + return ret; +} -- cgit v1.1