edje_cc: Add -dd/--data_dir option
[platform/upstream/edje.git] / src / bin / edje_cc.c
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
10 #include "edje_cc.h"
11 int _edje_cc_log_dom = -1;
12 static void main_help(void);
13
14 Eina_Prefix  *pfx = NULL;
15 Eina_List *snd_dirs = NULL;
16 Eina_List *img_dirs = NULL;
17 Eina_List *fnt_dirs = NULL;
18 Eina_List *data_dirs = NULL;
19 Eina_List *defines = NULL;
20 char      *file_in = NULL;
21 char      *tmp_dir = NULL;
22 char      *file_out = NULL;
23 char      *watchfile = NULL;
24
25 static const char *progname = NULL;
26
27 int        no_lossy = 0;
28 int        no_comp = 0;
29 int        no_raw = 0;
30 int        no_save = 0;
31 int        min_quality = 0;
32 int        max_quality = 100;
33 int        compress_mode = EET_COMPRESSION_HI;
34 int        threads = 0;
35
36 static void
37 _edje_cc_log_cb(const Eina_Log_Domain *d,
38                 Eina_Log_Level level,
39                 const char *file,
40                 const char *fnc,
41                 int line,
42                 const char *fmt,
43                 __UNUSED__ void *data,
44                 va_list args)
45 {
46    if ((d->name) && (d->namelen == sizeof("edje_cc") - 1) &&
47        (memcmp(d->name, "edje_cc", sizeof("edje_cc") - 1) == 0))
48      {
49         const char *prefix;
50
51         eina_log_console_color_set(stderr, eina_log_level_color_get(level));
52         switch (level)
53           {
54            case EINA_LOG_LEVEL_CRITICAL:
55               prefix = "Critical. ";
56               break;
57            case EINA_LOG_LEVEL_ERR:
58               prefix = "Error. ";
59               break;
60            case EINA_LOG_LEVEL_WARN:
61               prefix = "Warning. ";
62               break;
63            default:
64               prefix = "";
65           }
66         fprintf(stderr, "%s: %s", progname, prefix);
67         eina_log_console_color_set(stderr, EINA_COLOR_RESET);
68
69         vfprintf(stderr, fmt, args);
70         putc('\n', stderr);
71      }
72    else
73      eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args);
74 }
75
76 static void
77 main_help(void)
78 {
79    printf
80      ("Usage:\n"
81       "\t%s [OPTIONS] input_file.edc [output_file.edj]\n"
82       "\n"
83       "Where OPTIONS is one or more of:\n"
84       "\n"
85       "-w files.txt             Dump all sources files path into files.txt\n"
86       "-id image/directory      Add a directory to look in for relative path images\n"
87       "-fd font/directory       Add a directory to look in for relative path fonts\n"
88       "-sd sound/directory      Add a directory to look in for relative path sounds samples\n"
89       "-dd data/directory       Add a directory to look in for relative path data.file entries\n"
90       "-td temp/directory       Directory to store temporary files\n"
91       "-v                       Verbose output\n"
92       "-no-lossy                Do NOT allow images to be lossy\n"
93       "-no-comp                 Do NOT allow images to be stored with lossless compression\n"
94       "-no-raw                  Do NOT allow images to be stored with zero compression (raw)\n"
95       "-no-save                 Do NOT store the input EDC file in the EDJ file\n"
96       "-min-quality VAL         Do NOT allow lossy images with quality < VAL (0-100)\n"
97       "-max-quality VAL         Do NOT allow lossy images with quality > VAL (0-100)\n"
98       "-Ddefine_val=to          CPP style define to define input macro definitions to the .edc source\n"
99       "-fastcomp                Use a faster compression algorithm (LZ4) (mutually exclusive with -fastdecomp)\n"
100       "-fastdecomp              Use a faster decompression algorithm (LZ4HC) (mutually exclusive with -fastcomp)\n"
101       "-threads                 Compile the edje file using multiple parallel threads (by default)\n"
102       "-nothreads               Compile the edje file using only the main loop\n"
103       ,progname);
104 }
105
106 int
107 main(int argc, char **argv)
108 {
109    int i;
110    struct stat st;
111    char rpath[PATH_MAX], rpath2[PATH_MAX];
112
113    setlocale(LC_NUMERIC, "C");
114
115    if (!eina_init())
116      return -1;
117
118    _edje_cc_log_dom = eina_log_domain_register
119      ("edje_cc", EDJE_CC_DEFAULT_LOG_COLOR);
120    if (_edje_cc_log_dom < 0)
121      {
122        EINA_LOG_ERR("Enable to create a log domain.");
123        exit(-1);
124      }
125    if (!eina_log_domain_level_check(_edje_cc_log_dom, EINA_LOG_LEVEL_WARN))
126      eina_log_domain_level_set("edje_cc", EINA_LOG_LEVEL_WARN);
127
128    progname = ecore_file_file_get(argv[0]);
129    eina_log_print_cb_set(_edje_cc_log_cb, NULL);
130
131    tmp_dir = getenv("TMPDIR");
132
133    img_dirs = eina_list_append(img_dirs, ".");
134    
135    /* add defines to epp so edc files can detect edje_cc version */
136    defines = eina_list_append(defines, mem_strdup("-DEDJE_VERSION_12=12"));
137
138    for (i = 1; i < argc; i++)
139      {
140         if (!strcmp(argv[i], "-h"))
141           {
142              main_help();
143              exit(0);
144           }
145         else if (!strcmp(argv[i], "-v"))
146           {
147              eina_log_domain_level_set("edje_cc", EINA_LOG_LEVEL_INFO);
148           }
149         else if (!strcmp(argv[i], "-no-lossy"))
150           {
151              no_lossy = 1;
152           }
153         else if (!strcmp(argv[i], "-no-comp"))
154           {
155              no_comp = 1;
156           }
157         else if (!strcmp(argv[i], "-no-raw"))
158           {
159              no_raw = 1;
160           }
161         else if (!strcmp(argv[i], "-no-save"))
162           {
163              no_save = 1;
164           }
165         else if ((!strcmp(argv[i], "-id") || !strcmp(argv[i], "--image_dir")) && (i < (argc - 1)))
166           {
167              i++;
168              img_dirs = eina_list_append(img_dirs, argv[i]);
169           }
170         else if ((!strcmp(argv[i], "-fd") || !strcmp(argv[i], "--font_dir")) && (i < (argc - 1)))
171           {
172              i++;
173              fnt_dirs = eina_list_append(fnt_dirs, argv[i]);
174           }
175         else if ((!strcmp(argv[i], "-sd") || !strcmp(argv[i], "--sound_dir")) && (i < (argc - 1)))
176           {
177              i++;
178              snd_dirs = eina_list_append(snd_dirs, argv[i]);
179           }
180         else if ((!strcmp(argv[i], "-dd") || !strcmp(argv[i], "--data_dir")) && (i < (argc - 1)))
181           {
182              i++;
183              data_dirs = eina_list_append(data_dirs, argv[i]);
184           }
185         else if ((!strcmp(argv[i], "-td") || !strcmp(argv[i], "--tmp_dir")) && (i < (argc - 1)))
186           {
187              i++;
188              if (!tmp_dir)
189                tmp_dir = argv[i];
190           }
191         else if ((!strcmp(argv[i], "-min-quality")) && (i < (argc - 1)))
192           {
193              i++;
194              min_quality = atoi(argv[i]);
195              if (min_quality < 0) min_quality = 0;
196              if (min_quality > 100) min_quality = 100;
197           }
198         else if ((!strcmp(argv[i], "-max-quality")) && (i < (argc - 1)))
199           {
200              i++;
201              max_quality = atoi(argv[i]);
202              if (max_quality < 0) max_quality = 0;
203              if (max_quality > 100) max_quality = 100;
204           }
205         else if (!strcmp(argv[i], "-fastcomp"))
206           {
207              compress_mode = EET_COMPRESSION_SUPERFAST;
208           }
209         else if (!strcmp(argv[i], "-fastdecomp"))
210           {
211              compress_mode = EET_COMPRESSION_VERYFAST;
212           }
213         else if (!strcmp(argv[i], "-threads"))
214           {
215              threads = 1;
216           }
217         else if (!strcmp(argv[i], "-nothreads"))
218           {
219              threads = 0;
220           }
221         else if (!strncmp(argv[i], "-D", 2))
222           {
223              defines = eina_list_append(defines, mem_strdup(argv[i]));
224           }
225         else if ((!strcmp(argv[i], "-o")) && (i < (argc - 1)))
226           {
227              i++;
228              file_out = argv[i];
229           }
230         else if ((!strcmp(argv[i], "-w")) && (i < (argc - 1)))
231           {
232              i++;
233              watchfile = argv[i];
234              unlink(watchfile);
235           }
236         else if (!file_in)
237           file_in = argv[i];
238         else if (!file_out)
239           file_out = argv[i];
240      }
241
242    if (!file_in)
243      {
244         ERR("no input file specified.");
245         main_help();
246         exit(-1);
247      }
248
249    
250
251    pfx = eina_prefix_new(argv[0],            /* argv[0] value (optional) */
252                          main,               /* an optional symbol to check path of */
253                          "EDJE",             /* env var prefix to use (XXX_PREFIX, XXX_BIN_DIR etc. */
254                          "edje",             /* dir to add after "share" (PREFIX/share/DIRNAME) */
255                          "include/edje.inc", /* a magic file to check for in PREFIX/share/DIRNAME for success */
256                          PACKAGE_BIN_DIR,    /* package bin dir @ compile time */
257                          PACKAGE_LIB_DIR,    /* package lib dir @ compile time */
258                          PACKAGE_DATA_DIR,   /* package data dir @ compile time */
259                          PACKAGE_DATA_DIR    /* if locale needed  use LOCALE_DIR */
260                         );
261
262    /* check whether file_in exists */
263 #ifdef HAVE_REALPATH
264    if (!realpath(file_in, rpath) || stat(rpath, &st) || !S_ISREG(st.st_mode))
265 #else
266    if (stat(file_in, &st) || !S_ISREG(st.st_mode))
267 #endif
268      {
269         ERR("file not found: %s.", file_in);
270         main_help();
271         exit(-1);
272      }
273
274    if (!file_out)
275       {
276          char *suffix;
277
278          if ((suffix = strstr(file_in,".edc")) && (suffix[4] == 0))
279             {
280                file_out = strdup(file_in);
281                if (file_out)
282                   {
283                      suffix = strstr(file_out,".edc");
284                      strcpy(suffix,".edj");
285                   }
286             }
287       }
288    if (!file_out)
289      {
290         ERR("no output file specified.");
291         main_help();
292         exit(-1);
293      }
294
295 #ifdef HAVE_REALPATH
296    if (realpath(file_out, rpath2) && !strcmp (rpath, rpath2))
297 #else
298    if (!strcmp (file_in, file_out))
299 #endif
300      {
301         ERR("input file equals output file.");
302         main_help();
303         exit(-1);
304      }
305
306    using_file(file_in);
307
308    if (!edje_init())
309      exit(-1);
310
311    edje_file = mem_alloc(SZ(Edje_File));
312    edje_file->compiler = strdup("edje_cc");
313    edje_file->version = EDJE_FILE_VERSION;
314    edje_file->minor = EDJE_FILE_MINOR;
315    edje_file->feature_ver = 1; /* increment this every time we add a field
316                                 * or feature to the edje file format that
317                                 * does not load nicely as a NULL or 0 value
318                                 * and needs a special fallback initialization
319                                 */
320
321    source_edd();
322    source_fetch();
323
324    data_setup();
325    compile();
326    reorder_parts();
327    data_process_scripts();
328    data_process_lookups();
329    data_process_script_lookups();
330    data_write();
331
332    eina_prefix_free(pfx);
333    pfx = NULL;
334    
335    edje_shutdown();
336    eina_log_domain_unregister(_edje_cc_log_dom);
337    eina_shutdown();
338
339    return 0;
340 }