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