efl

Форк
0
/
edje_external_inspector.c 
678 строк · 18.5 Кб
1
#ifdef HAVE_CONFIG_H
2
# include "config.h"
3
#endif
4

5
#include <locale.h>
6

7
#include <Ecore.h>
8
#include <Ecore_Getopt.h>
9

10
#include "Edje.h"
11

12
static int _log_dom;
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__)
18

19
#define INDENT  "   "
20
#define INDENT2 INDENT INDENT
21
#define INDENT3 INDENT2 INDENT
22
#define INDENT4 INDENT3 INDENT
23

24
static char *module_patterns_str = NULL;
25

26
static int detail = 1;
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;
31

32
static char *
33
_module_patterns_str_new(void)
34
{
35
   Eina_Strbuf *buf;
36
   char *const *itr;
37
   char *ret;
38
   if (!module_patterns) return strdup("*");
39

40
   buf = eina_strbuf_new();
41
   for (itr = module_patterns; *itr != NULL; itr++)
42
     {
43
        eina_strbuf_append(buf, *itr);
44
        if (itr[1]) eina_strbuf_append(buf, ", ");
45
     }
46
   ret = eina_strbuf_string_steal(buf);
47
   eina_strbuf_free(buf);
48
   return ret;
49
}
50

51
static Eina_Bool
52
module_matches(const char *name)
53
{
54
   char *const *itr;
55
   if (!module_patterns) return EINA_TRUE;
56

57
   for (itr = module_patterns; *itr != NULL; itr++)
58
     if (eina_fnmatch(*itr, name, 0)) return EINA_TRUE;
59

60
   return EINA_FALSE;
61
}
62

63
static inline Eina_Bool
64
type_matches(const char *name)
65
{
66
   if (!type_glob) return EINA_TRUE;
67
   return eina_fnmatch(type_glob, name, 0);
68
}
69

70
static int
71
_types_sort(const void *pa, const void *pb)
72
{
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;
76
   int r;
77

78
   if (!ta->module) return -1;
79
   if (!tb->module) return 1;
80
   r = strcmp(ta->module, tb->module);
81
   if (r != 0) return r;
82

83
   if (!na) return -1;
84
   if (!nb) return 1;
85
   return strcmp(na, nb);
86
}
87

88
static const char *
89
_param_type_str_get(const Edje_External_Param_Info *param)
90
{
91
   switch (param->type)
92
     {
93
      case EDJE_EXTERNAL_PARAM_TYPE_INT: return "int";
94

95
      case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: return "double";
96

97
      case EDJE_EXTERNAL_PARAM_TYPE_STRING: return "string";
98

99
      case EDJE_EXTERNAL_PARAM_TYPE_BOOL: return "bool";
100

101
      case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: return "choice";
102

103
      default:
104
        ERR("Unknown parameter type %d", param->type);
105
        return "???";
106
     }
107
}
108

109
static const char *
110
_param_value_str_get(const Edje_External_Type *type, const Edje_External_Param_Info *param, char *buf, size_t buflen)
111
{
112
   switch (param->type)
113
     {
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);
117
        return buf;
118

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);
122
        return buf;
123

124
      case EDJE_EXTERNAL_PARAM_TYPE_STRING:
125
        return param->info.s.def;
126

127
      case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
128
        if (param->info.b.def == 0) return "0";
129
        else if (param->info.b.def == 1)
130
          return "1";
131
        return NULL;
132

133
      case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
134
      {
135
         char *def;
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);
141
         free(def);
142
         return buf;
143
      }
144

145
      default:
146
        ERR("Unknown parameter type %d", param->type);
147
        return NULL;
148
     }
149
}
150

151
static const char *
152
_param_flags_str_get(const Edje_External_Param_Info *param)
153
{
154
   static char buf[] = "GET|SET|STATE|CONSTRUCTOR";
155

156
   if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_NONE) return "NONE";
157
   if (param->flags == EDJE_EXTERNAL_PARAM_FLAGS_REGULAR) return "REGULAR";
158

159
   buf[0] = '\0';
160

161
   if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_GET)
162
     strcat(buf, "GET");
163

164
   if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_SET)
165
     {
166
        if (buf[0] != '\0') strcat(buf, "|");
167
        strcat(buf, "SET");
168
     }
169

170
   if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_STATE)
171
     {
172
        if (buf[0] != '\0') strcat(buf, "|");
173
        strcat(buf, "STATE");
174
     }
175

176
   if (param->flags & EDJE_EXTERNAL_PARAM_FLAGS_CONSTRUCTOR)
177
     {
178
        if (buf[0] != '\0') strcat(buf, "|");
179
        strcat(buf, "CONSTRUCTOR");
180
     }
181

182
   return buf;
183
}
184

185
static void
186
_param_choices_print(const char *const *choices)
187
{
188
   if (machine) puts("CHOICES-BEGIN");
189
   else fputs(", choices:", stdout);
190
   for (; *choices != NULL; choices++)
191
     {
192
        if (machine) puts(*choices);
193
        else printf(" \"%s\"", *choices);
194
     }
195
   if (machine) puts("CHOICES-END");
196
}
197

198
static void
199
_param_extra_details(const Edje_External_Type *type, const Edje_External_Param_Info *param)
200
{
201
   const char *str = _param_flags_str_get(param);
202
   if (machine) printf("FLAGS: %s\n", str);
203
   else printf(" /* flags: %s", str);
204

205
   switch (param->type)
206
     {
207
      case EDJE_EXTERNAL_PARAM_TYPE_INT:
208
        if (param->info.i.min != EDJE_EXTERNAL_INT_UNSET)
209
          {
210
             if (machine) printf("MIN: %d\n", param->info.i.min);
211
             else printf(", min: %d", param->info.i.min);
212
          }
213
        if (param->info.i.max != EDJE_EXTERNAL_INT_UNSET)
214
          {
215
             if (machine) printf("MAX: %d\n", param->info.i.max);
216
             else printf(", max: %d", param->info.i.max);
217
          }
218
        if (param->info.i.step != EDJE_EXTERNAL_INT_UNSET)
219
          {
220
             if (machine) printf("STEP: %d\n", param->info.i.step);
221
             else printf(", step: %d", param->info.i.step);
222
          }
223
        break;
224

225
      case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
226
        if (EINA_DBL_EQ(param->info.d.min, EDJE_EXTERNAL_DOUBLE_UNSET))
227
          {
228
             if (machine) printf("MIN: %g\n", param->info.d.min);
229
             else printf(", min: %g", param->info.d.min);
230
          }
231
        if (EINA_DBL_EQ(param->info.d.max, EDJE_EXTERNAL_DOUBLE_UNSET))
232
          {
233
             if (machine) printf("MAX: %g\n", param->info.d.max);
234
             else printf(", max: %g", param->info.d.max);
235
          }
236
        if (EINA_DBL_EQ(param->info.d.step, EDJE_EXTERNAL_DOUBLE_UNSET))
237
          {
238
             if (machine) printf("STEP: %g\n", param->info.d.step);
239
             else printf(", step: %g", param->info.d.step);
240
          }
241
        break;
242

243
      case EDJE_EXTERNAL_PARAM_TYPE_STRING:
244
        if (param->info.s.accept_fmt)
245
          {
246
             if (machine) printf("ACCEPT_FMT: %s\n", param->info.s.accept_fmt);
247
             else printf(", accept_fmt: \"%s\"", param->info.s.accept_fmt);
248
          }
249
        if (param->info.s.deny_fmt)
250
          {
251
             if (machine) printf("DENY_FMT: %s\n", param->info.s.deny_fmt);
252
             else printf(", deny_fmt: \"%s\"", param->info.s.deny_fmt);
253
          }
254
        break;
255

256
      case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
257
        if (param->info.b.false_str)
258
          {
259
             if (machine) printf("FALSE_STR: %s\n", param->info.b.false_str);
260
             else printf(", false_str: \"%s\"", param->info.b.false_str);
261
          }
262
        if (param->info.b.true_str)
263
          {
264
             if (machine) printf("TRUE_STR: %s\n", param->info.b.true_str);
265
             else printf(", true_str: \"%s\"", param->info.b.true_str);
266
          }
267
        break;
268

269
      case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
270
      {
271
         if (param->info.c.choices)
272
           _param_choices_print(param->info.c.choices);
273
         else if (param->info.c.query)
274
           {
275
              char **choices = param->info.c.query(type->data, param);
276
              if (choices)
277
                {
278
                   char **itr;
279
                   _param_choices_print((const char *const *)choices);
280
                   for (itr = choices; *itr; itr++)
281
                     free(*itr);
282
                   free(choices);
283
                }
284
           }
285
      }
286
      break;
287

288
      default:
289
        ERR("Unknown parameter type %d", param->type);
290
     }
291

292
   if (!machine) fputs(" */", stdout);  /* \n not desired */
293
}
294

295
static int
296
_info_list(void)
297
{
298
   Eina_Iterator *itr;
299
   Eina_List *types;
300
   const Eina_Hash_Tuple *tuple;
301
   const Eina_List *l;
302
   const char *name, *last_module;
303
   Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
304
   Eina_Bool in_module = EINA_FALSE;
305

306
   EINA_LIST_FOREACH(modules, l, name)
307
     {
308
        if (!module_matches(name))
309
          {
310
             DBG("filter out module '%s': does not match '%s'",
311
                 name, module_patterns_str);
312
             continue;
313
          }
314

315
        if (!edje_module_load(name))
316
          {
317
             ERR("error loading external '%s'", name);
318
             continue;
319
          }
320

321
        module_found = EINA_TRUE;
322
     }
323

324
   itr = edje_external_iterator_get();
325
   types = NULL;
326
   EINA_ITERATOR_FOREACH(itr, tuple)
327
     {
328
        const Edje_External_Type *type = tuple->data;
329
        name = tuple->key;
330

331
        if (!type)
332
          {
333
             ERR("no type value for '%s'", name);
334
             continue;
335
          }
336
        else if (type->abi_version != edje_external_type_abi_version_get())
337
          {
338
             ERR("type '%s' with incorrect abi_version %u (expected %u)",
339
                 name, type->abi_version, edje_external_type_abi_version_get());
340
             continue;
341
          }
342

343
        if (!type_matches(name))
344
          {
345
             DBG("filter out type '%s': does not match '%s'", name, type_glob);
346
             continue;
347
          }
348

349
        types = eina_list_append(types, tuple);
350
        type_found = EINA_TRUE;
351
     }
352
   eina_iterator_free(itr);
353

354
   last_module = NULL;
355
   types = eina_list_sort(types, 0, _types_sort);
356
   EINA_LIST_FREE(types, tuple)
357
     {
358
        Eina_Bool changed_module = EINA_FALSE;
359
        const Edje_External_Type *type = tuple->data;
360
        const Edje_External_Param_Info *param;
361
        name = tuple->key;
362

363
        if ((last_module) && (type->module))
364
          {
365
             changed_module = ((last_module != type->module) &&
366
                               (!strcmp(last_module, type->module)));
367
          }
368
        else if ((!last_module) && (type->module))
369
          changed_module = EINA_TRUE;
370

371
        if (changed_module)
372
          {
373
             if (in_module)
374
               {
375
                  if (machine) puts("TYPES-END\nMODULE-END");
376
                  else puts(INDENT "}\n}");
377
               }
378

379
             if (machine)
380
               printf("MODULE-BEGIN\n"
381
                      "NAME: %s\n"
382
                      "FRIENDLY-NAME: %s\n"
383
                      "TYPES-BEGIN\n",
384
                      type->module, type->module_name);
385
             else
386
               printf("module {\n"
387
                      INDENT "name: \"%s\";\n"
388
                      INDENT "friendly_name: \"%s\";\n"
389
                      INDENT "types {\n",
390
                      type->module, type->module_name);
391

392
             in_module = EINA_TRUE;
393
          }
394

395
        if (machine) printf("TYPE-BEGIN\nNAME: %s\n", name);
396
        else printf(INDENT2 "type {\n" INDENT3 "name: \"%s\";\n", name);
397

398
        if (detail > 1)
399
          {
400
             const char *str;
401

402
             if (!type->label_get) str = NULL;
403
             else str = type->label_get(type->data);
404
             if (machine) printf("LABEL: %s\n", str ? str : "");
405
             else if (str)
406
               printf(INDENT3 "label: \"%s\";\n", str);
407

408
             if (!type->description_get) str = NULL;
409
             else str = type->description_get(type->data);
410
             if (machine) printf("DESCRIPTION: %s\n", str ? str : "");
411
             else if (str)
412
               printf(INDENT3 "description: \"%s\";\n", str);
413
          }
414

415
        if (machine) puts("PARAMS-BEGIN");
416
        else puts(INDENT3 "params {");
417

418
        for (param = type->parameters_info; param->name != NULL; param++)
419
          {
420
             const char *pt = _param_type_str_get(param);
421
             char buf[128];
422

423
             if (machine)
424
               printf("PARAM-BEGIN\nNAME: %s\nTYPE: %s\n", param->name, pt);
425
             else printf(INDENT4 "%s: \"%s\"", pt, param->name);
426

427
             if (detail > 0)
428
               {
429
                  const char *str = _param_value_str_get
430
                      (type, param, buf, sizeof(buf));
431
                  if (machine) printf("DEFAULT: %s\n", str ? str : "");
432
                  else if (str)
433
                    printf(" \"%s\"", str);
434

435
                  if (detail > 1)
436
                    {
437
                       if (!machine) putchar(';');
438
                       _param_extra_details(type, param);
439
                    }
440
               }
441

442
             if (machine) puts("PARAM-END");
443
             else if (detail > 1)
444
               putchar('\n');
445
             else puts(";");
446
          }
447

448
        if (machine) puts("PARAMS-END\nTYPE-END");
449
        else puts(INDENT3 "}\n" INDENT2 "}");
450

451
        last_module = type->module;
452
     }
453

454
   if (in_module)
455
     {
456
        if (machine) puts("MODULE-END");
457
        else puts(INDENT "}\n}");
458
     }
459

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);
463
}
464

465
static int
466
_types_names_list(void)
467
{
468
   Eina_Iterator *itr;
469
   Eina_List *types;
470
   const Eina_Hash_Tuple *tuple;
471
   const Eina_List *l;
472
   const char *name;
473
   Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
474

475
   EINA_LIST_FOREACH(modules, l, name)
476
     {
477
        if (!module_matches(name))
478
          {
479
             DBG("filter out module '%s': does not match '%s'",
480
                 name, module_patterns_str);
481
             continue;
482
          }
483

484
        if (!edje_module_load(name))
485
          {
486
             ERR("error loading external '%s'", name);
487
             continue;
488
          }
489

490
        module_found = EINA_TRUE;
491
     }
492

493
   itr = edje_external_iterator_get();
494
   types = NULL;
495
   EINA_ITERATOR_FOREACH(itr, tuple)
496
     {
497
        const Edje_External_Type *type = tuple->data;
498
        name = tuple->key;
499

500
        if (!type)
501
          {
502
             ERR("no type value for '%s'", name);
503
             continue;
504
          }
505
        else if (type->abi_version != edje_external_type_abi_version_get())
506
          {
507
             ERR("type '%s' with incorrect abi_version %u (expected %u)",
508
                 name, type->abi_version, edje_external_type_abi_version_get());
509
             continue;
510
          }
511

512
        if (!type_matches(name))
513
          {
514
             DBG("filter out type '%s': does not match '%s'", name, type_glob);
515
             continue;
516
          }
517

518
        types = eina_list_append(types, tuple);
519
        type_found = EINA_TRUE;
520
     }
521
   eina_iterator_free(itr);
522

523
   types = eina_list_sort(types, 0, _types_sort);
524
   EINA_LIST_FREE(types, tuple)
525
     puts(tuple->key);
526

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);
530
}
531

532
static int
533
_modules_names_list(void)
534
{
535
   const Eina_List *l;
536
   const char *name;
537
   Eina_Bool found = EINA_FALSE;
538

539
   EINA_LIST_FOREACH(modules, l, name)
540
     {
541
        if (!module_matches(name))
542
          {
543
             DBG("filter out module '%s': does not match '%s'",
544
                 name, module_patterns_str);
545
             continue;
546
          }
547
        found = EINA_TRUE;
548
        puts(name);
549
     }
550

551
   if (!found) WRN("no modules match '%s'", module_patterns_str);
552
   return !found;
553
}
554

555
static const char *mode_choices[] = {
556
   "info",
557
   "modules-names",
558
   "types-names",
559
   NULL,
560
};
561

562
static const char *detail_choices[] = {
563
   "none",
564
   "terse",
565
   "all",
566
   NULL
567
};
568

569
const Ecore_Getopt optdesc = {
570
   "edje_external_inspector",
571
   "%prog [options] [module|module-glob] ... [module|module-glob]",
572
   PACKAGE_VERSION,
573
   "(C) 2010 - The Enlightenment Project",
574
   "BSD",
575
   "Edje external module inspector.",
576
   0,
577
   {
578
      ECORE_GETOPT_CHOICE('m', "mode", "Choose which mode to operate.",
579
                          mode_choices),
580
      ECORE_GETOPT_STORE_STR('t', "type", "Limit output to type (or glob)."),
581
      ECORE_GETOPT_CHOICE('d', "detail", "Choose detail level (default=terse)",
582
                          detail_choices),
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
589
   }
590
};
591

592
int
593
main(int argc, char **argv)
594
{
595
   Eina_Bool quit_option = EINA_FALSE;
596
   char *mode = NULL;
597
   char *detail_name = NULL;
598
   int arg_index;
599
   int ret = 0;
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
610
   };
611

612
   setlocale(LC_NUMERIC, "C");
613

614
   ecore_app_no_system_modules();
615

616
   eina_init();
617

618
   _log_dom = eina_log_domain_register
619
       ("edje_external_inspector", EINA_COLOR_YELLOW);
620
   if (_log_dom < 0)
621
     {
622
        EINA_LOG_CRIT
623
          ("could not register log domain 'edje_external_inspector'");
624
        ret = 1;
625
        goto error_log;
626
     }
627

628
   edje_init();
629

630
   arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
631
   if (arg_index < 0)
632
     {
633
        ERR("could not parse arguments.");
634
        ret = 1;
635
        goto error_getopt;
636
     }
637
   else if (quit_option)
638
     goto error_getopt;
639

640
   if (!mode) mode = (char *)mode_choices[0];
641

642
   if (detail_name)
643
     {
644
        if (!strcmp(detail_name, "none")) detail = 0;
645
        else if (!strcmp(detail_name, "terse"))
646
          detail = 1;
647
        else if (!strcmp(detail_name, "all"))
648
          detail = 2;
649
        else ERR("Unknown detail level: '%s'", detail_name);
650
     }
651

652
   if (arg_index < argc) module_patterns = argv + arg_index;
653
   else module_patterns = NULL;
654

655
   modules = edje_available_modules_get();
656
   module_patterns_str = _module_patterns_str_new();
657

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();
663
   else
664
     {
665
        ERR("Unknown mode: %s", mode);
666
        ret = 1;
667
     }
668

669
   free(module_patterns_str);
670

671
error_getopt:
672
   edje_shutdown();
673
   eina_log_domain_unregister(_log_dom);
674
error_log:
675
   eina_shutdown();
676

677
   return ret;
678
}
679

680

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.