15
#include <Ecore_File.h>
16
#include <Ecore_Evas.h>
20
int _edje_cc_log_dom = -1;
21
static const char *progname = NULL;
25
int compress_mode = EET_COMPRESSION_DEFAULT;
27
Edje_File *edje_file = NULL;
28
SrcFile_List *srcfiles = NULL;
29
Edje_Font_List *fontlist = NULL;
37
static int compiler_cmd_is_sane(void);
38
static int root_filename_is_sane(void);
41
_edje_cc_log_cb(const Eina_Log_Domain *d,
47
EINA_UNUSED void *data,
50
if ((d->name) && (d->namelen == sizeof("edje_decc") - 1) &&
51
(memcmp(d->name, "edje_decc", sizeof("edje_decc") - 1) == 0))
54
Eina_Bool use_color = !eina_log_color_disable_get();
59
fputs(eina_log_level_color_get(level), stderr);
64
case EINA_LOG_LEVEL_CRITICAL:
65
color = FOREGROUND_RED | FOREGROUND_INTENSITY;
68
case EINA_LOG_LEVEL_ERR:
69
color = FOREGROUND_RED;
72
case EINA_LOG_LEVEL_WARN:
73
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
76
case EINA_LOG_LEVEL_INFO:
77
color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
80
case EINA_LOG_LEVEL_DBG:
81
color = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
85
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
87
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
93
case EINA_LOG_LEVEL_CRITICAL:
94
prefix = "Critical. ";
97
case EINA_LOG_LEVEL_ERR:
101
case EINA_LOG_LEVEL_WARN:
102
prefix = "Warning. ";
108
fprintf(stderr, "%s: %s", progname, prefix);
113
fputs(EINA_COLOR_RESET, stderr);
115
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
116
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
120
vfprintf(stderr, fmt, args);
124
eina_log_print_cb_stderr(d, level, file, fnc, cur_line, fmt, NULL, args);
132
"\t%s input_file.edj [-main-out file.edc] [-no-build-sh] [-current-dir | -output path_to_dir]\n"
134
" -main-out\tCreate a symbolic link to the main edc (disabled on Windows) \n"
135
" -no-build-sh\tDon't output build.sh \n"
136
" -output, -o\tOutput to specified directory \n"
137
" -current-dir\tOutput to current directory \n"
138
" -quiet\t\tProduce less output\n"
147
main(int argc, char **argv)
151
setlocale(LC_NUMERIC, "C");
153
ecore_app_no_system_modules();
157
_edje_cc_log_dom = eina_log_domain_register
158
("edje_decc", EDJE_CC_DEFAULT_LOG_COLOR);
159
if (_edje_cc_log_dom < 0)
161
EINA_LOG_ERR("Impossible to create a log domain.");
165
progname = ecore_file_file_get(argv[0]);
166
eina_log_print_cb_set(_edje_cc_log_cb, NULL);
167
eina_log_domain_level_set("edje_decc", EINA_LOG_LEVEL_INFO);
169
for (i = 1; i < argc; i++)
171
if (!strcmp(argv[i], "-h"))
178
else if ((!strcmp(argv[i], "-main-out")) && (i < (argc - 1)))
185
else if (!strcmp(argv[i], "-no-build-sh"))
187
else if (!strcmp(argv[i], "-current-dir"))
189
else if (!strcmp(argv[i], "-quiet"))
190
eina_log_domain_level_set("edje_decc", EINA_LOG_LEVEL_WARN);
191
else if ((!strcmp(argv[i], "-o") || !strcmp(argv[i], "-output")) && (i < (argc - 1)))
194
outdir = strdup(argv[i]);
199
ERR("no input file specified.");
208
if (!decomp()) return -1;
211
WRN("If any Image or audio data was encoded in a LOSSY way, then "
212
"re-encoding will drop quality even more. "
213
"You need access to the original data to ensure no loss of quality.");
216
eina_log_domain_unregister(_edje_cc_log_dom);
217
_edje_cc_log_dom = -1;
225
ef = eet_open(file_in, EET_FILE_MODE_READ);
228
ERR("cannot open %s", file_in);
232
srcfiles = source_load(ef);
233
if (!srcfiles || !srcfiles->list)
235
ERR("%s has no decompile information", file_in);
239
if (!eina_list_data_get(srcfiles->list) || !root_filename_is_sane())
241
ERR("Invalid root filename: '%s'", (char *)eina_list_data_get(srcfiles->list));
245
edje_file = eet_data_read(ef, _edje_edd_edje_file, "edje/file");
248
ERR("%s does not appear to be an edje file", file_in);
253
edje_file->compiler = strdup("edje_cc");
254
if (!edje_file->compiler)
256
edje_file->compiler = strdup("edje_cc");
258
else if (!compiler_cmd_is_sane())
260
ERR("invalid compiler executable: '%s'", edje_file->compiler);
264
fontlist = source_fontmap_load(ef);
279
outdir = strdup(".");
282
p = strrchr(file_in, '/');
284
outdir = strdup(p + 1);
286
outdir = strdup(file_in);
287
p = strrchr(outdir, '.');
289
ecore_file_mkpath(outdir);
293
tef = eet_open(file_in, EET_FILE_MODE_READ);
295
if (edje_file->image_dir)
297
Edje_Image_Directory_Entry *ei;
300
for (i = 0; i < edje_file->image_dir->entries_count; ++i)
302
ei = &edje_file->image_dir->entries[i];
304
if ((ei->source_type > EDJE_IMAGE_SOURCE_TYPE_NONE) &&
305
(ei->source_type < EDJE_IMAGE_SOURCE_TYPE_LAST) &&
306
(ei->source_type != EDJE_IMAGE_SOURCE_TYPE_USER) &&
307
(ei->source_type != EDJE_IMAGE_SOURCE_TYPE_EXTERNAL) &&
319
ee = ecore_evas_buffer_new(1, 1);
322
ERR("Cannot create buffer engine canvas for image save.");
325
evas = ecore_evas_get(ee);
326
im = evas_object_image_add(evas);
329
ERR("Cannot create image object for save.");
332
snprintf(buf, sizeof(buf), "edje/images/%i", ei->id);
333
evas_object_image_file_set(im, file_in, buf);
334
snprintf(out, sizeof(out), "%s/%s", outdir, ei->entry);
335
INF("Output Image: %s", out);
337
p = strrchr(pp, '/');
339
if (strstr(pp, "../"))
341
ERR("Potential security violation. attempt to write in parent dir.");
344
ecore_file_mkpath(pp);
346
if (!evas_object_image_save(im, out, NULL, "quality=100 compress=9 encoding=auto"))
348
ERR("Cannot write file %s. Perhaps missing JPEG or PNG saver modules for Evas.", out);
353
ecore_evas_shutdown();
359
EINA_LIST_FOREACH(srcfiles->list, l, sf)
365
snprintf(out, sizeof(out), "%s/%s", outdir, sf->name);
366
INF("Output Source File: %s", out);
368
p = strrchr(pp, '/');
370
if (strstr(pp, "../"))
372
ERR("Potential security violation. attempt to write in parent dir.");
375
ecore_file_mkpath(pp);
377
if (strstr(out, "../"))
379
ERR("Potential security violation. attempt to write in parent dir.");
382
f = fopen(out, "wb");
385
ERR("Unable to write file (%s).", out);
392
if (sf->file) fputs(sf->file, f);
395
if (edje_file->fonts)
397
Edje_Font_Directory_Entry *fn;
400
it = eina_hash_iterator_data_new(edje_file->fonts);
401
EINA_ITERATOR_FOREACH(it, fn)
408
snprintf(out, sizeof(out), "edje/fonts/%s", fn->file);
409
font = eet_read(tef, out, &fontsize);
416
snprintf(out, sizeof(out), "%s/%s", outdir, fn->entry);
417
INF("Output Font: %s", out);
419
p = strrchr(pp, '/');
421
if (strstr(pp, "../"))
423
ERR("Potential security violation. attempt to write in parent dir.");
426
ecore_file_mkpath(pp);
428
if (strstr(out, "../"))
430
ERR("Potential security violation. attempt to write in parent dir.");
433
if (!(f = fopen(out, "wb")))
435
ERR("Could not open file: %s", out);
438
if (fwrite(font, fontsize, 1, f) != 1)
439
ERR("Could not write font: %s", strerror(errno));
444
eina_iterator_free(it);
449
sf = eina_list_data_get(srcfiles->list);
453
snprintf(out, sizeof(out), "%s/build.sh", outdir);
454
INF("Output Build Script: %s", out);
455
if (strstr(out, "../"))
457
ERR("potential security violation. attempt to write in parent dir.");
460
if ((f = fopen(out, "wb")))
462
fprintf(f, "#!/bin/sh\n");
463
fprintf(f, "%s $@ -id . -fd . %s -o %s.edj\n",
464
edje_file->compiler, sf->name, outdir);
467
S_IRUSR | S_IWUSR | S_IXUSR |
468
S_IRGRP | S_IWGRP | S_IXGRP) < 0)
469
ERR("chmod on %s failed", out);
472
WRN("*** CAUTION ***\n"
473
"Please check the build script for anything malicious "
474
"before running it!\n\n");
479
snprintf(out, sizeof(out), "%s/%s", outdir, file_out);
480
if (ecore_file_symlink(sf->name, out) != EINA_TRUE)
482
ERR("symlink %s -> %s failed", sf->name, out);
487
if (edje_file->sound_dir)
489
Edje_Sound_Sample *sample;
498
for (i = 0; i < (int)edje_file->sound_dir->samples_count; i++)
500
sample = &edje_file->sound_dir->samples[i];
501
if ((!sample) || (!sample->name)) continue;
502
snprintf(out, sizeof(out), "edje/sounds/%i", sample->id);
503
sound_data = (void *)eet_read_direct(tef, out, &sound_data_size);
506
snprintf(out1, sizeof(out1), "%s/%s", outdir, sample->snd_src);
508
p = strrchr(pp, '/');
510
if (strstr(pp, "../"))
512
ERR("Potential security violation. attempt to write in parent dir.");
515
ecore_file_mkpath(pp);
517
if (strstr(out, "../"))
519
ERR("Potential security violation. attempt to write in parent dir.");
522
f = fopen(out1, "wb");
525
if (fwrite(sound_data, sound_data_size, 1, f) != 1)
526
ERR("Could not write sound: %s: %s", out1, strerror(errno));
529
else ERR("Could not open for writing sound: %s: %s", out1, strerror(errno));
533
if (edje_file->vibration_dir)
535
Edje_Vibration_Sample *sample;
544
for (i = 0; i < (int)edje_file->vibration_dir->samples_count; i++)
546
sample = &edje_file->vibration_dir->samples[i];
547
if ((!sample) || (!sample->name)) continue;
548
snprintf(out, sizeof(out), "edje/vibrations/%i", sample->id);
549
data = (void *)eet_read_direct(tef, out, &data_size);
552
snprintf(out1, sizeof(out1), "%s/%s", outdir, sample->src);
554
p = strrchr(pp, '/');
556
if (strstr(pp, "../"))
558
ERR("Potential security violation. attempt to write in parent dir.");
561
ecore_file_mkpath(pp);
563
if (strstr(out, "../"))
565
ERR("Potential security violation. attempt to write in parent dir.");
568
f = fopen(out1, "wb");
571
if (fwrite(data, data_size, 1, f) != 1)
572
ERR("Could not write sound: %s", strerror(errno));
575
else ERR("Could not open for writing sound: %s: %s", out1, strerror(errno));
581
if (outdir) free(outdir);
585
compiler_cmd_is_sane()
587
const char *c = edje_file->compiler, *ptr;
594
for (ptr = c; ptr && *ptr; ptr++)
597
if ((!isalnum(*ptr)) && (*ptr != '_') && (*ptr != '-'))
607
root_filename_is_sane()
609
SrcFile *sf = eina_list_data_get(srcfiles->list);
610
char *f = sf->name, *ptr;
617
for (ptr = f; ptr && *ptr; ptr++)