1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 
5 #include <string.h>
6 #include <locale.h>
7 #include <limits.h>
8 #include <sys/stat.h>
9 #include <sys/time.h>
10 
11 #ifdef HAVE_SYS_RESOURCE_H
12 # include <sys/resource.h>
13 #endif
14 
15 #ifdef _WIN32
16 # include <evil_private.h> /* realpath */
17 #endif
18 
19 #include "edje_cc.h"
20 int _edje_cc_log_dom = -1;
21 static void main_help(void);
22 
23 Eina_Prefix *pfx = NULL;
24 Eina_List *snd_dirs = NULL;
25 Eina_List *mo_dirs = NULL;
26 Eina_List *vibration_dirs = NULL;
27 Eina_List *img_dirs = NULL;
28 Eina_List *fnt_dirs = NULL;
29 Eina_List *data_dirs = NULL;
30 Eina_List *defines = NULL;
31 char *file_in = NULL;
32 char *tmp_dir = NULL;
33 char *file_out = NULL;
34 char *watchfile = NULL;
35 char *depfile = NULL;
36 char *authors = NULL;
37 char *license = NULL;
38 Eina_List *licenses = NULL;
39 Eina_Array *requires;
40 
41 static const char *progname = NULL;
42 
43 int no_lossy = 0;
44 int no_comp = 0;
45 int no_raw = 0;
46 int no_save = 0;
47 int min_quality = 0;
48 int max_quality = 100;
49 int compress_mode = EET_COMPRESSION_HI;
50 int threads = 0;
51 int annotate = 0;
52 int no_etc1 = 0;
53 int no_etc2 = 0;
54 int beta = 0;
55 Eina_Bool namespace_verify;
56 
57 unsigned int max_open_files;
58 
59 static void
_edje_cc_log_cb(const Eina_Log_Domain * d,Eina_Log_Level level,const char * file,const char * fnc,int fline,const char * fmt,EINA_UNUSED void * data,va_list args)60 _edje_cc_log_cb(const Eina_Log_Domain *d,
61                 Eina_Log_Level level,
62                 const char *file,
63                 const char *fnc,
64                 int fline,
65                 const char *fmt,
66                 EINA_UNUSED void *data,
67                 va_list args)
68 {
69    if ((d->name) && (d->namelen == sizeof("edje_cc") - 1) &&
70        (memcmp(d->name, "edje_cc", sizeof("edje_cc") - 1) == 0))
71      {
72         const char *prefix;
73 
74         eina_log_console_color_set(stderr, eina_log_level_color_get(level));
75         switch (level)
76           {
77            case EINA_LOG_LEVEL_CRITICAL:
78              prefix = "Critical. ";
79              break;
80 
81            case EINA_LOG_LEVEL_ERR:
82              prefix = "Error. ";
83              break;
84 
85            case EINA_LOG_LEVEL_WARN:
86              prefix = "Warning. ";
87              break;
88 
89            default:
90              prefix = "";
91           }
92         fprintf(stderr, "%s: %s", progname, prefix);
93         eina_log_console_color_set(stderr, EINA_COLOR_RESET);
94 
95         vfprintf(stderr, fmt, args);
96         putc('\n', stderr);
97      }
98    else
99      eina_log_print_cb_stderr(d, level, file, fnc, fline, fmt, NULL, args);
100 }
101 
102 static void
main_help(void)103 main_help(void)
104 {
105    printf
106      ("Usage:\n"
107       "\t%s [OPTIONS] input_file.edc [output_file.edj]\n"
108       "\n"
109       "Where OPTIONS is one or more of:\n"
110       "\n"
111       "-w files.txt             Dump all sources files path into files.txt\n"
112       "-annotate                Annotate the dumped files.\n"
113       "-deps files.txt          Dump gnu style include dependencies path into files.txt (overrides -w/-annotate)\n"
114       "-id image/directory      Add a directory to look in for relative path images\n"
115       "-fd font/directory       Add a directory to look in for relative path fonts\n"
116       "-sd sound/directory      Add a directory to look in for relative path sounds samples\n"
117       "-vd vibration/directory  Add a directory to look in for relative path vibration samples\n"
118       "-dd data/directory       Add a directory to look in for relative path data.file entries\n"
119       "-md mo/directory         Add a directory to look in for relative path mo files\n"
120       "-td temp/directory       Directory to store temporary files\n"
121       "-l license               Specify the license of a theme (file with license text)\n"
122       "-a authors               Specify AUTHORS (file with list of authors)\n"
123       "-v                       Verbose output\n"
124       "-no-lossy                Do NOT allow images to be lossy\n"
125       "-no-comp                 Do NOT allow images to be stored with lossless compression\n"
126       "-no-raw                  Do NOT allow images to be stored with zero compression (raw)\n"
127       "-no-etc1                 Do NOT allow images to be stored as ETC1\n"
128       "-no-etc2                 Do NOT allow images to be stored as ETC2\n"
129       "-no-save                 Do NOT store the input EDC file in the EDJ file\n"
130       "-min-quality VAL         Do NOT allow lossy images with quality < VAL (0-100)\n"
131       "-max-quality VAL         Do NOT allow lossy images with quality > VAL (0-100)\n"
132       "-Ddefine_val=to          CPP style define to define input macro definitions to the .edc source\n"
133       "-fastcomp                Use a faster compression algorithm (LZ4) (mutually exclusive with -fastdecomp)\n"
134       "-fastdecomp              Use a faster decompression algorithm (LZ4HC) (mutually exclusive with -fastcomp)\n"
135       "-threads                 Compile the edje file using multiple parallel threads (by default)\n"
136       "-nothreads               Compile the edje file using only the main loop\n"
137       "-N                       Use the first segment of each group name as a namespace to verify parts/signals\n"
138       "-V [--version]           show program version\n"
139      , progname);
140 }
141 
142 int
main(int argc,char ** argv)143 main(int argc, char **argv)
144 {
145    int i;
146    struct stat st;
147 #ifdef HAVE_REALPATH
148    char rpath[PATH_MAX], rpath2[PATH_MAX];
149 #endif
150 
151    setlocale(LC_NUMERIC, "C");
152 
153    ecore_app_no_system_modules();
154    efreet_cache_disable();
155 
156    if (!eina_init())
157      return -1;
158 
159    _edje_cc_log_dom = eina_log_domain_register
160        ("edje_cc", EDJE_CC_DEFAULT_LOG_COLOR);
161    if (_edje_cc_log_dom < 0)
162      {
163         EINA_LOG_ERR("Enable to create a log domain.");
164         exit(-1);
165      }
166    if (!eina_log_domain_level_check(_edje_cc_log_dom, EINA_LOG_LEVEL_WARN))
167      eina_log_domain_level_set("edje_cc", EINA_LOG_LEVEL_WARN);
168 
169    progname = ecore_file_file_get(argv[0]);
170    eina_log_print_cb_set(_edje_cc_log_cb, NULL);
171 
172    tmp_dir = (char *)eina_environment_tmp_get();
173 
174    img_dirs = eina_list_append(img_dirs, ".");
175 
176    /* add defines to epp so edc files can detect edje_cc version */
177    defines = eina_list_append(defines, mem_strdup("-DEDJE_VERSION_12=12"));
178 
179    for (i = 1; i < argc; i++)
180      {
181         if (!strcmp(argv[i], "-h"))
182           {
183              main_help();
184              exit(0);
185           }
186         else if ((!strcmp(argv[i], "-V")) || (!strcmp(argv[i], "--version")))
187           {
188              printf("Version: %s\n", PACKAGE_VERSION);
189              exit(0);
190           }
191         else if (!strcmp(argv[i], "-v"))
192           {
193              eina_log_domain_level_set("edje_cc", EINA_LOG_LEVEL_INFO);
194           }
195         else if (!strcmp(argv[i], "-no-lossy"))
196           {
197              no_lossy = 1;
198           }
199         else if (!strcmp(argv[i], "-no-comp"))
200           {
201              no_comp = 1;
202           }
203         else if (!strcmp(argv[i], "-no-raw"))
204           {
205              no_raw = 1;
206           }
207         else if (!strcmp(argv[i], "-no-etc1"))
208           {
209              no_etc1 = 1;
210           }
211         else if (!strcmp(argv[i], "-no-etc2"))
212           {
213              no_etc2 = 1;
214           }
215         else if (!strcmp(argv[i], "-no-save"))
216           {
217              no_save = 1;
218           }
219         else if ((!strcmp(argv[i], "-id") || !strcmp(argv[i], "--image_dir")) && (i < (argc - 1)))
220           {
221              i++;
222              img_dirs = eina_list_append(img_dirs, argv[i]);
223           }
224         else if ((!strcmp(argv[i], "-fd") || !strcmp(argv[i], "--font_dir")) && (i < (argc - 1)))
225           {
226              i++;
227              fnt_dirs = eina_list_append(fnt_dirs, argv[i]);
228           }
229         else if ((!strcmp(argv[i], "-sd") || !strcmp(argv[i], "--sound_dir")) && (i < (argc - 1)))
230           {
231              i++;
232              snd_dirs = eina_list_append(snd_dirs, argv[i]);
233           }
234         else if ((!strcmp(argv[i], "-md") || !strcmp(argv[i], "--mo_dir")) && (i < (argc - 1)))
235           {
236              i++;
237              mo_dirs = eina_list_append(mo_dirs, argv[i]);
238           }
239         else if ((!strcmp(argv[i], "-vd") || !strcmp(argv[i], "--vibration_dir")) && (i < (argc - 1)))
240           {
241              i++;
242              vibration_dirs = eina_list_append(vibration_dirs, argv[i]);
243           }
244         else if ((!strcmp(argv[i], "-dd") || !strcmp(argv[i], "--data_dir")) && (i < (argc - 1)))
245           {
246              i++;
247              data_dirs = eina_list_append(data_dirs, argv[i]);
248           }
249         else if ((!strcmp(argv[i], "-td") || !strcmp(argv[i], "--tmp_dir")) && (i < (argc - 1)))
250           {
251              i++;
252              if (!tmp_dir)
253                tmp_dir = argv[i];
254           }
255         else if ((!strcmp(argv[i], "-l") || !strcmp(argv[i], "--license")) && (i < (argc - 1)))
256           {
257              i++;
258              if (!license)
259                license = argv[i];
260              else
261                licenses = eina_list_append(licenses, argv[i]);
262           }
263         else if ((!strcmp(argv[i], "-a") || !strcmp(argv[i], "--authors")) && (i < (argc - 1)))
264           {
265              i++;
266              if (!authors)
267                authors = argv[i];
268           }
269         else if ((!strcmp(argv[i], "-min-quality")) && (i < (argc - 1)))
270           {
271              i++;
272              min_quality = atoi(argv[i]);
273              if (min_quality < 0) min_quality = 0;
274              if (min_quality > 100) min_quality = 100;
275           }
276         else if ((!strcmp(argv[i], "-max-quality")) && (i < (argc - 1)))
277           {
278              i++;
279              max_quality = atoi(argv[i]);
280              if (max_quality < 0) max_quality = 0;
281              if (max_quality > 100) max_quality = 100;
282           }
283         else if (!strcmp(argv[i], "-fastcomp"))
284           {
285              compress_mode = EET_COMPRESSION_SUPERFAST;
286           }
287         else if (!strcmp(argv[i], "-fastdecomp"))
288           {
289              compress_mode = EET_COMPRESSION_VERYFAST;
290           }
291         else if (!strcmp(argv[i], "-threads"))
292           {
293              threads = 1;
294           }
295         else if (!strcmp(argv[i], "-nothreads"))
296           {
297              threads = 0;
298           }
299         else if (!strncmp(argv[i], "-D", 2))
300           {
301              defines = eina_list_append(defines, mem_strdup(argv[i]));
302           }
303         else if ((!strcmp(argv[i], "-o")) && (i < (argc - 1)))
304           {
305              i++;
306              file_out = argv[i];
307           }
308         else if ((!strcmp(argv[i], "-w")) && (i < (argc - 1)))
309           {
310              i++;
311              watchfile = argv[i];
312              unlink(watchfile);
313           }
314         else if (!strcmp(argv[i], "-annotate"))
315           {
316              annotate = 1;
317           }
318         else if ((!strcmp(argv[i], "-deps")) && (i < (argc - 1)))
319           {
320              i++;
321              depfile = argv[i];
322              unlink(depfile);
323           }
324         else if (!strcmp(argv[i], "-beta"))
325           {
326              beta = 1;
327           }
328         else if (!strcmp(argv[i], "-N"))
329           {
330              namespace_verify = 1;
331           }
332         else if (!file_in)
333           file_in = argv[i];
334         else if (!file_out)
335           file_out = argv[i];
336      }
337 
338    if (!file_in)
339      {
340         ERR("no input file specified.");
341         main_help();
342         exit(-1);
343      }
344 
345    pfx = eina_prefix_new(argv[0], /* argv[0] value (optional) */
346                          main, /* an optional symbol to check path of */
347                          "EDJE", /* env var prefix to use (XXX_PREFIX, XXX_BIN_DIR etc. */
348                          "edje", /* dir to add after "share" (PREFIX/share/DIRNAME) */
349                          "include/edje.inc", /* a magic file to check for in PREFIX/share/DIRNAME for success */
350                          PACKAGE_BIN_DIR,    /* package bin dir @ compile time */
351                          PACKAGE_LIB_DIR,    /* package lib dir @ compile time */
352                          PACKAGE_DATA_DIR,   /* package data dir @ compile time */
353                          PACKAGE_DATA_DIR    /* if locale needed  use LOCALE_DIR */
354                          );
355 
356    /* check whether file_in exists */
357 #ifdef HAVE_REALPATH
358    if (!realpath(file_in, rpath) || stat(rpath, &st) || !S_ISREG(st.st_mode))
359 #else
360    if (stat(file_in, &st) || !S_ISREG(st.st_mode))
361 #endif
362      {
363         ERR("file not found: %s.", file_in);
364         main_help();
365         exit(-1);
366      }
367 
368    if (!file_out)
369      {
370         char *suffix;
371 
372         if ((suffix = strstr(file_in, ".edc")) && (suffix[4] == 0))
373           {
374              file_out = strdup(file_in);
375              if (file_out)
376                {
377                   suffix = strstr(file_out, ".edc");
378                   strcpy(suffix, ".edj");
379                }
380           }
381      }
382    if (!file_out)
383      {
384         ERR("no output file specified.");
385         main_help();
386         exit(-1);
387      }
388 
389 #ifdef HAVE_REALPATH
390    if (realpath(file_out, rpath2) && !strcmp(rpath, rpath2))
391 #else
392    if (!strcmp(file_in, file_out))
393 #endif
394      {
395         ERR("input file equals output file.");
396         main_help();
397         exit(-1);
398      }
399 
400    using_file(file_in, 'E');
401    if (annotate) using_file(file_out, 'O');
402 
403    if (!edje_init())
404      exit(-1);
405 
406    edje_file = mem_alloc(SZ(Edje_File));
407    edje_file->compiler = strdup("edje_cc");
408    edje_file->version = EDJE_FILE_VERSION;
409    edje_file->minor = EDJE_FILE_MINOR;
410    edje_file->feature_ver = 1; /* increment this every time we add a field
411                                 * or feature to the edje file format that
412                                 * does not load nicely as a NULL or 0 value
413                                 * and needs a special fallback initialization
414                                 */
415    /* efl_version is used for specify efl's version
416     * which was used for developing a edje file.
417     * It is useful if Edje(or other EFL libs) need to keep
418     * backward compatibility.
419     * efl_version was added to fix backward compatibility issue caused from EFL 1.19.
420     * Thus, 1.18 will be default.
421     */
422    edje_file->efl_version.major = 1;
423    edje_file->efl_version.minor = 18;
424    edje_file->base_scale = FROM_INT(1);
425    requires = eina_array_new(10);
426 
427 #ifdef HAVE_SYS_RESOURCE_H
428    {
429       struct rlimit lim;
430       if (getrlimit(RLIMIT_NOFILE, &lim))
431         fprintf(stderr, "error getting max open file limit: %s\n", strerror(errno));
432       max_open_files = lim.rlim_cur;
433    }
434 #else
435    max_open_files = 1024;
436 #endif
437    ecore_evas_init();
438 
439    source_edd();
440    source_fetch();
441 
442    data_setup();
443    compile();
444    reorder_parts();
445    data_process_scripts();
446    data_process_lookups();
447    data_process_script_lookups();
448    data_write();
449 
450    eina_prefix_free(pfx);
451    pfx = NULL;
452 
453    ecore_evas_shutdown();
454    edje_shutdown();
455    eina_log_domain_unregister(_edje_cc_log_dom);
456    eina_shutdown();
457 
458    return 0;
459 }
460 
461