1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <errno.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <ctype.h>
12 #include <Ecore_Getopt.h>
13 
14 #include "edje_cc.h"
15 #include "edje_private.h"
16 
17 #define EDJE_PICK_HELP_STRING \
18   "\nEdje Pick - the \"edj\" merging tool.\n\
19 ===================================\n\n\
20 Use Edje Pick to compose a single edj file \
21 by selecting groups from edj files.\n\n\
22 Use Edje Pick as follows:\n\
23 Include files with \'--include\' file-name\n\
24 Follow the included file-name by names of selected groups from this file.\n\
25 To select a group use: \'--group\' group-name.\n\n\
26 You must specify merged file name with \'--output\' file-name.\n\
27 Use '--verbose' switch to get detailed log.\n\n\
28 To produce 3rd file \'out.edj\' that composed  of:\n\
29 Group \'test\' from \'ex1.edj\' and \'test2\', \'test3\', from \'ex2.edj\'\n\
30 edje_pick -i ex1.edj -g test -i ex2.edj -g test2 -g test3 -o out.edj\n\n\
31 By using \'--append\' whole file content is selected.\n\
32 No need to specify selected groups with this switch.\n\
33 Note that selected group with will override group with the same name\n\
34 from appended-file when using \'--append\' switch.\n\n\
35 Example, the command:\n\
36 edje_pick -a theme1.edj -i default.edj -g elm/button/base/default \
37 -g elm/check/base/default -o hybrid.edj\n\n\
38 will produce a 3rd theme file \'hybrid.edj\',\n\
39 composed of all theme1.edj components.\n\
40 Replacing the button and check with widgets taken from default theme.\n\
41 (Given that theme1.edj button, check group-name are as in default.edj)\n"
42 
43 struct _Edje_Pick_Id
44 {
45    int       old_id;
46    int       new_id;
47    Eina_Bool used;
48 };
49 typedef struct _Edje_Pick_Id Edje_Pick_Id;
50 
51 struct _Edje_Pick_File_Params
52 {
53    const char *name;
54    Eina_List  *groups;
55    Edje_File  *edf;    /* Keeps all file data after reading  */
56    Eina_Bool   append; /* Take everything from this file */
57 
58    /* We hold list of IDs for each file */
59    Eina_List  *scriptlist;
60    Eina_List  *luascriptlist;
61    Eina_List  *imagelist;
62    Eina_List  *imagesetlist; /* List of IDs (Edje_Pick_Data) for image sets */
63    Eina_List  *vectorlist;
64    Eina_List  *samplelist;
65    Eina_List  *tonelist;
66    Eina_List  *vibrationlist;
67    Eina_List  *fontlist;
68 };
69 typedef struct _Edje_Pick_File_Params Edje_Pick_File_Params;
70 
71 struct _Edje_Pick_Data
72 {
73    const char  *filename; /* Image, Sample File Name       */
74    void        *entry; /* used to build output file dir FIXME: REMOVE THIS */
75    void        *data; /* Data as taken from input file */
76 
77    int          size;
78    Edje_Pick_Id id;
79 };
80 typedef struct _Edje_Pick_Data Edje_Pick_Data;
81 
82 struct _Edje_Pick_Tone
83 {
84    Edje_Sound_Tone *tone;
85    Eina_Bool        used;
86 };
87 typedef struct _Edje_Pick_Tone Edje_Pick_Tone;
88 
89 struct _Edje_Pick_Font
90 {
91    Edje_Font *f;
92 
93    void      *data; /* Font data as take from source edj file */
94    int        size; /* data size */
95    Eina_Bool  used;
96 };
97 typedef struct _Edje_Pick_Font Edje_Pick_Font;
98 
99 struct _Edje_Pick
100 {
101    Eina_Bool              v; /* Verbose */
102    Edje_Pick_File_Params *current_file;
103 };
104 typedef struct _Edje_Pick Edje_Pick;
105 
106 static Edje_Pick context = { EINA_FALSE, NULL };
107 
108 #define VERBOSE(COMMAND) if (context.v) { COMMAND; }
109 
110 enum _Edje_Pick_Status
111 {
112    EDJE_PICK_NO_ERROR,
113    EDJE_PICK_OUT_FILENAME_MISSING,
114    EDJE_PICK_FAILED_OPEN_INP,
115    EDJE_PICK_FAILED_READ_INP,
116    EDJE_PICK_GROUP_NOT_FOUND,
117    EDJE_PICK_IMAGE_NOT_FOUND,
118    EDJE_PICK_SAMPLE_NOT_FOUND,
119    EDJE_PICK_INCLUDE_MISSING,
120    EDJE_PICK_GROUP_MISSING,
121    EDJE_PICK_PARSE_FAILED,
122    EDJE_PICK_HELP_SHOWN,
123    EDJE_PICK_DUP_GROUP
124 };
125 typedef enum _Edje_Pick_Status Edje_Pick_Status;
126 
127 static void
_edje_pick_args_show(Eina_List * ifs,char * out)128 _edje_pick_args_show(Eina_List *ifs, char *out)
129 {  /* Print command-line arguments after parsing phase */
130   Edje_Pick_File_Params *p;
131   Eina_List *l;
132   char *g;
133 
134   EINA_LOG_INFO("Got args for <%d> input files.\n", eina_list_count(ifs));
135 
136   EINA_LIST_FOREACH(ifs, l, p)
137     {
138        Eina_List *ll;
139 
140        if (p->append)
141          printf("\nFile name: %s\n\tGroups: ALL (append mode)\n", p->name);
142        else
143          {
144             printf("\nFile name: %s\n\tGroups:\n", p->name);
145             EINA_LIST_FOREACH(p->groups, ll, g)
146               printf("\t\t%s\n", g);
147          }
148     }
149 
150   EINA_LOG_INFO("\nOutput file name was <%s>\n", out);
151 }
152 
153 static void
_edje_pick_data_free(Eina_List * l)154 _edje_pick_data_free(Eina_List *l)
155 {
156    Edje_Pick_Data *ep;
157 
158    EINA_LIST_FREE(l, ep)
159      {
160         if (ep->filename) eina_stringshare_del(ep->filename);
161         free(ep->data);
162         free(ep);
163      }
164 }
165 
166 static void
_edje_pick_out_file_free(Edje_File * out_file)167 _edje_pick_out_file_free(Edje_File *out_file)
168 {
169    if (out_file)
170      {
171         /* Free output file memory allocation */
172         if (out_file->ef)
173           eet_close(out_file->ef);
174 
175         if (out_file->external_dir)
176           {
177              if (out_file->external_dir->entries)
178                free(out_file->external_dir->entries);
179 
180              free(out_file->external_dir);
181           }
182 
183         if (out_file->image_dir)
184           {
185              if (out_file->image_dir->entries)
186                free(out_file->image_dir->entries);
187 
188              free(out_file->image_dir);
189           }
190 
191         if (out_file->sound_dir)
192           {
193              if (out_file->sound_dir->samples)
194                free(out_file->sound_dir->samples);
195 
196              if (out_file->sound_dir->tones)
197                free(out_file->sound_dir->tones);
198 
199              free(out_file->sound_dir);
200           }
201         if (out_file->vibration_dir)
202           {
203              if (out_file->vibration_dir->samples)
204                free(out_file->vibration_dir->samples);
205 
206              free(out_file->vibration_dir);
207           }
208 
209         eina_list_free(out_file->color_classes);
210         eina_hash_free_cb_set(out_file->collection, free);
211         eina_hash_free(out_file->collection);
212         eina_stringshare_del(out_file->compiler);
213 
214         free(out_file);
215      }
216 }
217 
218 static int
_edje_pick_cleanup(Eina_List * ifs,Edje_File * out_file,Edje_Pick_Status s)219 _edje_pick_cleanup(Eina_List *ifs, Edje_File *out_file, Edje_Pick_Status s)
220 {
221    Edje_Pick_File_Params *p;
222    Edje_Pick_Font *ft;
223    void *n;
224 
225    _edje_pick_out_file_free(out_file);
226 
227    EINA_LIST_FREE(ifs, p)
228      {
229         EINA_LIST_FREE(p->groups, n)
230           eina_stringshare_del(n);
231 
232         _edje_pick_data_free(p->scriptlist);
233         p->scriptlist = NULL;
234 
235         _edje_pick_data_free(p->luascriptlist);
236         p->luascriptlist = NULL;
237 
238         _edje_pick_data_free(p->imagelist);
239         p->imagelist = NULL;
240 
241         _edje_pick_data_free(p->vectorlist);
242         p->vectorlist = NULL;
243 
244         _edje_pick_data_free(p->imagesetlist);
245         p->imagesetlist = NULL;
246 
247         _edje_pick_data_free(p->samplelist);
248 
249         EINA_LIST_FREE(p->tonelist, n)
250           free(n);
251 
252         if (p->edf)
253           _edje_cache_file_unref(p->edf);
254 
255         EINA_LIST_FREE(p->fontlist, ft)
256           {
257              Edje_Font *st = ft->f;
258 
259              eina_stringshare_del(st->name);
260              eina_stringshare_del(st->file);
261              free(ft->data);
262              free(st);
263              free(ft);
264           }
265 
266         free(p);
267      }
268 
269    switch (s)
270      {
271       case EDJE_PICK_OUT_FILENAME_MISSING:
272         EINA_LOG_ERR("Output file name missing.\n");
273         break;
274 
275       case EDJE_PICK_FAILED_OPEN_INP:
276         EINA_LOG_ERR("Failed to open input file.\n");
277         break;
278 
279       case EDJE_PICK_FAILED_READ_INP:
280         EINA_LOG_ERR("Failed to read input file.\n");
281         break;
282 
283       case EDJE_PICK_DUP_GROUP:
284         EINA_LOG_ERR("Can't fetch groups with identical name from various files.\n");
285         break;
286 
287       case EDJE_PICK_INCLUDE_MISSING:
288         EINA_LOG_ERR("Cannot select groups when no input file included.\n");
289         break;
290 
291       case EDJE_PICK_GROUP_MISSING:
292         EINA_LOG_ERR("Group name missing for include file.\n");
293         break;
294 
295       case EDJE_PICK_PARSE_FAILED:
296         EINA_LOG_ERR("Command parsing failed.\n");
297         break;
298 
299       default:
300         return s;
301      }
302 
303    _edje_edd_shutdown();
304    eet_shutdown();
305    return s;
306 }
307 
308 /* Look for group name in all input files that are not d1 */
309 static int
_group_name_in_other_file(Eina_List * inp_files,void * d1,void * d2)310 _group_name_in_other_file(Eina_List *inp_files, void *d1, void *d2)
311 {
312    Edje_Pick_File_Params *inp_file = d1;
313    char *group = d2; /* Group name to search */
314    Eina_List *f;
315    Edje_Pick_File_Params *current_file;
316 
317    EINA_LIST_FOREACH(inp_files, f, current_file)
318      if (inp_file != current_file)
319        if (eina_list_search_unsorted(current_file->groups,
320                                      (Eina_Compare_Cb)strcmp,
321                                      group))
322          return 1;
323 
324    return 0;  /* Not found */
325 }
326 
327 static int
_edje_pick_command_line_parse(int argc,char ** argv,Eina_List ** ifs,char ** ofn)328 _edje_pick_command_line_parse(int argc, char **argv,
329                               Eina_List **ifs, char **ofn)
330 {  /* On return ifs is Input Files List, ofn is Output File Name */
331   Eina_List *gpf = NULL;  /* List including counters of groups-per-file */
332   Eina_List *a_files = NULL;
333   Eina_List *i_files = NULL;
334   Eina_List *l;
335   Eina_List *ll;
336   Eina_List *cg;
337   Eina_List *groups = NULL;
338   char *output_filename = NULL;
339   Edje_Pick_File_Params *current_inp = NULL;
340   Eina_List *files = NULL;   /* List of input files */
341   int *c = NULL;
342   char *str = NULL;
343   int k;
344   Eina_Bool show_help = EINA_FALSE;
345 
346   /* Define args syntax */
347 #define IS_GROUP(x)   ((!strcmp(x, "-g")) || (!strcmp(x, "--group")))
348 #define IS_INCLUDE(x) ((!strcmp(x, "-i")) || (!strcmp(x, "--include")))
349 #define IS_HELP(x)    ((!strcmp(x, "-h")) || (!strcmp(x, "--help")))
350   static const Ecore_Getopt optdesc = {
351      "edje_pick",
352      NULL,
353      "0.0",
354      "(C) 2012 Enlightenment",
355      "Public domain?",
356      "Edje Pick - the \"edj\" merging tool.",
357 
358      EINA_TRUE,
359      {
360         ECORE_GETOPT_STORE_TRUE('v', "verbose", "Verbose"),
361         ECORE_GETOPT_STORE('o', "output", "Output File",
362                            ECORE_GETOPT_TYPE_STR),
363         ECORE_GETOPT_APPEND_METAVAR('a', "append", "Append File",
364                                     "STRING", ECORE_GETOPT_TYPE_STR),
365         ECORE_GETOPT_APPEND_METAVAR('i', "include", "Include File",
366                                     "STRING", ECORE_GETOPT_TYPE_STR),
367         ECORE_GETOPT_APPEND_METAVAR('g', "group", "Add Group",
368                                     "STRING", ECORE_GETOPT_TYPE_STR),
369         ECORE_GETOPT_HELP('h', "help"),
370         ECORE_GETOPT_SENTINEL
371      }
372   };
373 
374   Ecore_Getopt_Value values[] = {
375      ECORE_GETOPT_VALUE_BOOL(context.v),
376      ECORE_GETOPT_VALUE_STR(output_filename),
377      ECORE_GETOPT_VALUE_LIST(a_files),
378      ECORE_GETOPT_VALUE_LIST(i_files),
379      ECORE_GETOPT_VALUE_LIST(groups),
380      ECORE_GETOPT_VALUE_NONE
381   };
382 
383   /* START - Read command line args */
384   c = NULL;
385   for (k = 1; k < argc; k++)
386     {   /* Run through args, count how many groups per file */
387       if (IS_GROUP(argv[k]))
388         {
389            if (!c)
390              return _edje_pick_cleanup(files, NULL,
391                                        EDJE_PICK_INCLUDE_MISSING);
392 
393            (*c)++;
394            continue;
395         }
396 
397       if (IS_INCLUDE(argv[k]))
398         {
399            c = calloc(1, sizeof(int));
400            gpf = eina_list_append(gpf, c);
401            continue;
402         }
403 
404       show_help |= IS_HELP(argv[k]);
405     }
406 
407   if (show_help)
408     puts(EDJE_PICK_HELP_STRING);
409 
410   if (ecore_getopt_parse(&optdesc, values, argc, argv) < 0)
411     {
412        EINA_LIST_FREE(gpf, c)
413          free(c);
414 
415        return _edje_pick_cleanup(files, NULL, EDJE_PICK_PARSE_FAILED);
416     }
417 
418   if (show_help)
419     {
420        EINA_LIST_FREE(gpf, c)
421          free(c);
422 
423        ecore_getopt_list_free(i_files);
424        ecore_getopt_list_free(groups);
425        return _edje_pick_cleanup(files, NULL, EDJE_PICK_HELP_SHOWN);
426     }
427 
428   if (context.v) /* Changed to INFO if verbose */
429     eina_log_level_set(EINA_LOG_LEVEL_INFO);
430 
431   EINA_LIST_FOREACH(a_files, l, str)
432     {
433        current_inp = calloc(1, sizeof(*current_inp));
434        current_inp->append = EINA_TRUE;
435        current_inp->name = eina_stringshare_add(str);
436        files = eina_list_append(files, current_inp);
437     }
438   ecore_getopt_list_free(a_files);
439 
440   ll = gpf;
441   cg = groups;
442   EINA_LIST_FOREACH(i_files, l, str)
443     {   /* Now match groups from groups-list with included files */
444       current_inp = calloc(1, sizeof(*current_inp));
445       current_inp->name = eina_stringshare_add(str);
446       files = eina_list_append(files, current_inp);
447       c = eina_list_data_get(ll);
448       if (c)
449         {
450            while (*c)
451              {
452                 char *g_name;
453                 if (!cg)
454                   {
455                      EINA_LIST_FREE(gpf, c)
456                        free(c);
457 
458                      ecore_getopt_list_free(i_files);
459                      ecore_getopt_list_free(groups);
460                      return _edje_pick_cleanup(files, NULL,
461                                                EDJE_PICK_GROUP_MISSING);
462                   }
463 
464                 g_name = eina_list_data_get(cg);
465                 if (_group_name_in_other_file(files, current_inp, g_name))
466                   return _edje_pick_cleanup(files, NULL, EDJE_PICK_DUP_GROUP);
467 
468                 if (!eina_list_search_unsorted(current_inp->groups,
469                                                (Eina_Compare_Cb)strcmp, g_name))
470                   current_inp->groups = eina_list_append(
471                       current_inp->groups, eina_stringshare_add(g_name));
472 
473                 cg = eina_list_next(cg);
474                 (*c)--;
475              }
476         }
477       ll = eina_list_next(ll);
478     }
479 
480   EINA_LIST_FREE(gpf, c)
481     free(c);
482 
483   ecore_getopt_list_free(i_files);
484   ecore_getopt_list_free(groups);
485 
486   if (!output_filename)
487     return _edje_pick_cleanup(files, NULL, EDJE_PICK_OUT_FILENAME_MISSING);
488   /* END   - Read command line args */
489 
490   /* Set output params, return OK */
491   *ifs = files;
492   *ofn = output_filename;
493   return EDJE_PICK_NO_ERROR;
494 }
495 
496 static void
_edje_pick_external_dir_update(Edje_File * o,Edje_File * edf)497 _edje_pick_external_dir_update(Edje_File *o, Edje_File *edf)
498 {
499    if (edf->external_dir && edf->external_dir->entries_count)
500      {
501         /* Add external-dir entries */
502         unsigned int total = 0;
503         unsigned int base = 0;
504         Edje_External_Directory_Entry *entries;
505 
506         if (o->external_dir)
507           base = total = o->external_dir->entries_count;
508         else
509           o->external_dir = calloc(1, sizeof(*(o->external_dir)));
510 
511         total += edf->external_dir->entries_count;
512 
513         entries = realloc(o->external_dir->entries,
514                           total * sizeof(Edje_External_Directory_Entry));
515         if (!entries)
516           {
517              EINA_LOG_ERR("Out of memory in realloc()");
518              return;
519           }
520         o->external_dir->entries = entries;
521 
522         memcpy(&o->external_dir->entries[base], edf->external_dir->entries,
523                edf->external_dir->entries_count *
524                sizeof(Edje_External_Directory_Entry));
525 
526         o->external_dir->entries_count = total;
527      }
528 }
529 
530 static Edje_File *
_edje_pick_output_prepare(Edje_File * o,Edje_File * edf,char * name)531 _edje_pick_output_prepare(Edje_File *o, Edje_File *edf, char *name)
532 {
533    /* Allocate and prepare header memory buffer */
534    if (!o)
535      {
536         o = calloc(1, sizeof(Edje_File));
537         o->compiler = eina_stringshare_add("edje_cc");
538         o->version = edf->version;
539         o->minor = edf->minor;
540         o->feature_ver = edf->feature_ver;
541         o->base_scale = edf->base_scale;
542         o->collection = eina_hash_string_small_new(NULL);
543         o->data = eina_hash_string_small_new(NULL);
544         o->fonts = eina_hash_string_small_new(NULL);
545 
546         /* Open output file */
547         o->ef = eet_open(name, EET_FILE_MODE_WRITE);
548      }
549    else
550      {
551         if (o->version != edf->version)
552           {
553              EINA_LOG_WARN("Warning: Merging files of various version.\n");
554              if (o->version < edf->version)
555                o->version = edf->version;
556           }
557 
558         if (o->minor != edf->minor)
559           {
560              EINA_LOG_WARN("Warning: Merging files of various minor.\n");
561              if (o->minor < edf->minor)
562                o->minor = edf->minor;
563           }
564 
565         if (o->feature_ver != edf->feature_ver)
566           {
567              EINA_LOG_WARN("Warning: Merging files of various feature_ver.\n");
568              if (o->feature_ver < edf->feature_ver)
569                o->feature_ver = edf->feature_ver;
570           }
571         if (NEQ(o->base_scale, edf->base_scale))
572           {
573              EINA_LOG_ERR("Error: Merging files of various base scale. Base scale of the files should be same.\n");
574              free(o);
575              return NULL;
576           }
577      }
578 
579    _edje_pick_external_dir_update(o, edf);
580    return o;
581 }
582 
583 static void
_edje_pick_header_alias_parent_add(Edje_File * out_file,Edje_File * edf,Edje_Part_Collection_Directory_Entry * ce,Edje_Part_Collection_Directory_Entry * ce_out)584 _edje_pick_header_alias_parent_add(Edje_File *out_file, Edje_File *edf, Edje_Part_Collection_Directory_Entry *ce, Edje_Part_Collection_Directory_Entry *ce_out)
585 {
586    Edje_Part_Collection_Directory_Entry *ce_cor, *ce_new, *ce_f;
587    Eina_Iterator *i;
588 
589    if (!ce->group_alias) return;
590 
591    i = eina_hash_iterator_data_new(edf->collection);
592    EINA_ITERATOR_FOREACH(i, ce_cor)
593      {
594         /* find the alias parent group */
595         if ((ce->id == ce_cor->id) && (!ce_cor->group_alias))
596           {
597              ce_f = eina_hash_find(out_file->collection, ce_cor->entry);
598              if (!ce_f)
599                {
600                   ce_new = malloc(sizeof(*ce_new));
601                   memcpy(ce_new, ce_cor, sizeof(*ce_new));
602                   ce_new->id = ce_out->id;
603                   eina_hash_direct_add(out_file->collection, ce_new->entry, ce_new);
604                }
605              else
606                {
607                   ce_out->id = ce_f->id;
608                }
609           }
610      }
611    eina_iterator_free(i);
612 }
613 
614 static Eina_List *
_edje_pick_header_dependencies_check(Edje_File * out_file,Edje_File * edf,Eina_List * groups,Edje_Part_Collection_Directory_Entry * ce,int * current_id)615 _edje_pick_header_dependencies_check(Edje_File *out_file, Edje_File *edf, Eina_List *groups, Edje_Part_Collection_Directory_Entry *ce, int *current_id)
616 {
617    char buf[1024];
618    Edje_Part_Collection *edc;
619    Edje_Part *part;
620    unsigned int i, j;
621    Edje_Pack_Element *item;
622    Eina_List *dep_list = NULL, *dep_list_inner = NULL;
623 
624    edje_cache_emp_alloc(ce);
625 
626    snprintf(buf, sizeof(buf), "edje/collections/%i", ce->id);
627    EINA_LOG_INFO("Trying to read group <%s>\n", buf);
628    edc = eet_data_read(edf->ef, _edje_edd_edje_part_collection, buf);
629    if (!edc)
630      {
631         EINA_LOG_ERR("Failed to read group <%s> id <%d>\n", ce->entry, ce->id);
632         goto exit;
633      }
634 #define GROUP_CHECK_AND_ADD(NAME)                                                                             \
635   if (NAME)                                                                                                   \
636     {                                                                                                         \
637        Edje_Part_Collection_Directory_Entry *ce_cor;                                                          \
638        if (eina_list_search_unsorted(groups, (void *)strcmp, NAME)) goto exit;                                \
639        ce_cor = eina_hash_find(edf->collection, NAME);                                                        \
640        if (!eina_hash_find(out_file->collection, ce_cor->entry))                                              \
641          {                                                                                                    \
642             dep_list_inner = _edje_pick_header_dependencies_check(out_file, edf, groups, ce_cor, current_id); \
643             dep_list = eina_list_merge(dep_list, dep_list_inner);                                             \
644          }                                                                                                    \
645        if ((ce_cor) && (!eina_hash_find(out_file->collection, NAME)))                                         \
646          {                                                                                                    \
647             Edje_Part_Collection_Directory_Entry *ce_out;                                                     \
648             ce_out = malloc(sizeof(*ce_out));                                                                 \
649             memcpy(ce_out, ce_cor, sizeof(*ce_out));                                                          \
650             ce_out->id = *current_id;                                                                         \
651             if (ce_out->group_alias)                                                                          \
652               _edje_pick_header_alias_parent_add(out_file, edf, ce, ce_out);                                  \
653             EINA_LOG_INFO("Changing ID of group <%d> to <%d>\n", ce->id, ce_out->id);                         \
654             eina_hash_direct_add(out_file->collection, ce_out->entry, ce_out);                                \
655             (*current_id)++;                                                                                  \
656             dep_list = eina_list_append(dep_list, eina_stringshare_add(ce_out->entry));                       \
657          }                                                                                                    \
658     }
659 
660    for (i = 0; i < edc->parts_count; i++)
661      {
662         part = edc->parts[i];
663         GROUP_CHECK_AND_ADD(part->source);
664         GROUP_CHECK_AND_ADD(part->source2);
665         GROUP_CHECK_AND_ADD(part->source3);
666         GROUP_CHECK_AND_ADD(part->source4);
667         GROUP_CHECK_AND_ADD(part->source5);
668         GROUP_CHECK_AND_ADD(part->source6);
669         for (j = 0; j < part->items_count; j++)
670           {
671              item = part->items[j];
672              GROUP_CHECK_AND_ADD(item->source);
673           }
674      }
675 
676 exit:
677    edje_cache_emp_free(ce);
678    return dep_list;
679 #undef GROUP_CHECK_AND_ADD
680 }
681 
682 static int
_edje_pick_data_update(Edje_File * out_file,Edje_File * edf)683 _edje_pick_data_update(Edje_File *out_file, Edje_File *edf)
684 {
685    Eina_Bool status = EDJE_PICK_NO_ERROR;
686    Eina_Iterator *i;
687    Eina_Stringshare *key, *value;
688 
689    i = eina_hash_iterator_key_new(edf->data);
690    EINA_ITERATOR_FOREACH(i, key)
691      {
692         if (eina_hash_find(out_file->data, key)) continue;
693         value = eina_hash_find(edf->data, key);
694         eina_hash_direct_add(out_file->data, key, value);
695      }
696 
697    return status;
698 }
699 
700 static int
_edje_pick_header_make(Edje_File * out_file,Edje_File * edf,Eina_List * ifs)701 _edje_pick_header_make(Edje_File *out_file, Edje_File *edf, Eina_List *ifs)
702 {
703    static int current_group_id = 0;
704    Edje_Part_Collection_Directory_Entry *ce;
705    Eina_Bool status = EDJE_PICK_NO_ERROR;
706    Eina_List *l, *alist = NULL;
707    char *name1 = NULL;
708    Eina_List *deps = NULL, *dep_list = NULL;
709    Eina_Iterator *i;
710 
711    /* Build file header */
712    if (context.current_file->append)
713      {
714         i = eina_hash_iterator_key_new(edf->collection);
715         EINA_ITERATOR_FOREACH(i, name1)  /* Run through all keys */
716           {
717              Edje_Part_Collection_Directory_Entry *ce_out;
718 
719              /* Use ALL groups from this file */
720              /* Test that no duplicate-group name for files in append mode */
721              /* Done here because we don't read EDC before parse cmd line  */
722              /* We SKIP group of file in append-mode if we got this group  */
723              /* from file in include mode.                                 */
724              if (_group_name_in_other_file(ifs, context.current_file, name1))
725                continue;  /* Skip group of file in append mode */
726 
727              ce = eina_hash_find(edf->collection, name1);
728              ce_out = malloc(sizeof(*ce_out));
729              memcpy(ce_out, ce, sizeof(*ce_out));
730              if (ce_out->group_alias)
731                alist = eina_list_append(alist, eina_stringshare_add(name1));
732 
733              ce_out->id = current_group_id;
734              current_group_id++;
735 
736              eina_hash_direct_add(out_file->collection, ce_out->entry, ce_out);
737 
738              /* Add this group to groups to handle for this file */
739              context.current_file->groups = eina_list_append(
740                  context.current_file->groups, eina_stringshare_add(name1));
741           }
742 
743         eina_iterator_free(i);
744         EINA_LIST_FOREACH(alist, l, name1)
745           {
746              Edje_Part_Collection_Directory_Entry *ce_cor;
747 
748              ce = eina_hash_find(edf->collection, name1);
749              i = eina_hash_iterator_data_new(edf->collection);
750              EINA_ITERATOR_FOREACH(i, ce_cor)
751                {
752                   if ((ce->id == ce_cor->id) && (!ce_cor->group_alias))
753                     break;
754                }
755              ce = eina_hash_find(out_file->collection, ce_cor->entry);
756              ce_cor = eina_hash_find(out_file->collection, name1);
757              ce_cor->id = ce->id;
758              eina_iterator_free(i);
759           }
760         EINA_LIST_FREE(alist, name1)
761           eina_stringshare_del(name1);
762      }
763    else
764      {
765         EINA_LIST_FOREACH(context.current_file->groups, l, name1)
766           {
767              /* Verify group found then add to ouput file header */
768              ce = eina_hash_find(edf->collection, name1);
769 
770              if (!ce)
771                {
772                   EINA_LOG_ERR("Group <%s> was not found in <%s> file.\n",
773                                name1, context.current_file->name);
774                   status = EDJE_PICK_GROUP_NOT_FOUND;
775                }
776              else
777                {
778                   Edje_Part_Collection_Directory_Entry *ce_out;
779 
780                   /* Add this groups to hash, with filname pefix for entries */
781                   ce_out = malloc(sizeof(*ce_out));
782 
783                   memcpy(ce_out, ce, sizeof(*ce_out));
784                   ce_out->id = current_group_id;
785                   if (ce_out->group_alias)
786                     _edje_pick_header_alias_parent_add(out_file, edf, ce, ce_out);
787                   EINA_LOG_INFO("Changing ID of group <%d> to <%d>\n", ce->id, ce_out->id);
788                   current_group_id++;
789 
790                   eina_hash_direct_add(out_file->collection, ce_out->entry,
791                                        ce_out);
792                   dep_list = _edje_pick_header_dependencies_check(out_file, edf, context.current_file->groups, ce, &current_group_id);
793                   if (!deps) deps = dep_list;
794                   else deps = eina_list_merge(deps, dep_list);
795                }
796           }
797         EINA_LIST_FREE(deps, name1)
798           context.current_file->groups = eina_list_append(context.current_file->groups, name1);
799      }
800 
801    return status;
802 }
803 
804 static int
_old_id_cmp(const void * d1,const void * d2)805 _old_id_cmp(const void *d1, const void *d2)
806 {
807    /* Find currect ID struct */
808    return ((Edje_Pick_Data *)d1)->id.old_id - ((intptr_t)d2);
809 }
810 
811 static int
_new_id_cmp(const void * d1,const void * d2)812 _new_id_cmp(const void *d1, const void *d2)
813 {
814    /* Find currect ID struct */
815    return ((Edje_Pick_Data *)d1)->id.new_id - ((intptr_t)d2);
816 }
817 
818 static int
_edje_pick_new_id_get(Eina_List * id_list,int id,Eina_Bool set_used)819 _edje_pick_new_id_get(Eina_List *id_list, int id, Eina_Bool set_used)
820 {
821    if (id >= 0)
822      {
823         Edje_Pick_Data *p_id = eina_list_search_unsorted(id_list,
824                                                          _old_id_cmp,
825                                                          (void *)(intptr_t)id);
826 
827         if (p_id)
828           {
829              if (set_used)
830                p_id->id.used = EINA_TRUE;
831 
832              return p_id->id.new_id;
833           }
834      }
835 
836    return id;
837 }
838 
839 static int
_edje_pick_image_new_id_get(Eina_List * id_list,int id)840 _edje_pick_image_new_id_get(Eina_List *id_list, int id)
841 {
842    if (id >= 0)
843      {
844         Edje_Pick_Data *p_id = eina_list_search_unsorted(id_list,
845                                                          _old_id_cmp,
846                                                          (void *)(intptr_t)id);
847         if (p_id) return p_id->id.new_id;
848      }
849 
850    return -1;
851 }
852 
853 static int
_edje_pick_image_old_id_get(Eina_List * id_list,int id)854 _edje_pick_image_old_id_get(Eina_List *id_list, int id)
855 {
856    if (id >= 0)
857      {
858         Edje_Pick_Data *p_id = eina_list_search_unsorted(id_list,
859                                                          _new_id_cmp,
860                                                          (void *)(intptr_t)id);
861         if (p_id) return p_id->id.old_id;
862      }
863 
864    return -1;
865 }
866 
867 static int
_edje_pick_images_copy(Edje_File * edf,Edje_File * o)868 _edje_pick_images_copy(Edje_File *edf, Edje_File *o)
869 {
870    int old_id;
871    Eina_Bool status = EDJE_PICK_NO_ERROR;
872    Eina_List *l, *l1;
873    Edje_Pick_Data *image, *set, *vector;
874 
875    if (edf->image_dir)
876      {
877         if (edf->image_dir->entries) /* Copy image dir entries of current file */
878           {
879              Edje_Image_Directory_Entry *entries = NULL;
880 
881              EINA_LIST_FOREACH(context.current_file->imagelist, l, image)
882                {
883                   if (image->id.used)
884                     {
885                        o->image_dir->entries_count += 1;
886 
887                        /* alloc mem first time  or  re-allocate again (bigger array) */
888                        entries = realloc(o->image_dir->entries,
889                                          o->image_dir->entries_count *
890                                          sizeof(Edje_Image_Directory_Entry));
891                        if (!entries)
892                          {
893                             EINA_LOG_ERR("Out of memory in realloc()");
894                             return EDJE_PICK_IMAGE_NOT_FOUND;
895                          }
896                        o->image_dir->entries = entries;
897 
898                        old_id = _edje_pick_image_old_id_get(
899                            context.current_file->imagelist, o->image_dir->entries_count - 1);
900                        /* Concatenate current file entries to re-allocated array */
901                        memcpy(&o->image_dir->entries[o->image_dir->entries_count - 1],
902                               &edf->image_dir->entries[old_id],
903                               sizeof(Edje_Image_Directory_Entry));
904                        o->image_dir->entries[o->image_dir->entries_count - 1].id = image->id.new_id;
905                     }
906                }
907           }
908 
909         if (edf->image_dir->sets) /* Copy image dir sets of current file */
910           {
911              Edje_Image_Directory_Set *sets;
912 
913              EINA_LIST_FOREACH(context.current_file->imagesetlist, l, set)
914                {
915                   if (set->id.used)
916                     {
917                        Edje_Image_Directory_Set_Entry *e;
918 
919                        o->image_dir->sets_count += 1;
920                        /* alloc mem first time  or  re-allocate again (bigger array) */
921                        sets = realloc(o->image_dir->sets,
922                                       o->image_dir->sets_count *
923                                       sizeof(Edje_Image_Directory_Set));
924                        if (!sets)
925                          {
926                             EINA_LOG_ERR("Out of memory in realloc()");
927                             return EDJE_PICK_IMAGE_NOT_FOUND;
928                          }
929                        o->image_dir->sets = sets;
930 
931                        old_id = _edje_pick_image_old_id_get(
932                            context.current_file->imagesetlist, o->image_dir->sets_count - 1);
933                        /* Concatenate current file sets to re-allocated array */
934                        memcpy(&o->image_dir->sets[o->image_dir->sets_count - 1],
935                               &edf->image_dir->sets[old_id],
936                               sizeof(Edje_Image_Directory_Set));
937                        o->image_dir->sets[o->image_dir->sets_count - 1].id = set->id.new_id;
938 
939                        EINA_LIST_FOREACH(o->image_dir->sets[o->image_dir->sets_count - 1].entries, l1, e)
940                          e->id = _edje_pick_image_new_id_get(
941                              context.current_file->imagelist,
942                              e->id);
943                     }
944                }
945           }
946 
947         if (edf->image_dir->vectors) /* Copy vector dir entries of current file */
948           {
949              Edje_Vector_Directory_Entry *vectors = NULL;
950 
951              EINA_LIST_FOREACH(context.current_file->vectorlist, l, vector)
952                {
953                   if (vector->id.used)
954                     {
955                        o->image_dir->vectors_count += 1;
956 
957                        /* alloc mem first time  or  re-allocate again (bigger array) */
958                        vectors = realloc(o->image_dir->vectors,
959                                          o->image_dir->vectors_count *
960                                          sizeof(Edje_Vector_Directory_Entry));
961                        if (!vectors)
962                          {
963                             EINA_LOG_ERR("Out of memory in realloc()");
964                             return EDJE_PICK_IMAGE_NOT_FOUND;
965                          }
966                        o->image_dir->vectors = vectors;
967 
968                        old_id = _edje_pick_image_old_id_get(
969                            context.current_file->vectorlist, o->image_dir->vectors_count - 1);
970                        /* Concatenate current file vectors to re-allocated array */
971                        memcpy(&o->image_dir->vectors[o->image_dir->vectors_count - 1],
972                               &edf->image_dir->vectors[old_id],
973                               sizeof(Edje_Vector_Directory_Entry));
974                        o->image_dir->vectors[o->image_dir->vectors_count - 1].id = vector->id.new_id;
975                     }
976                }
977           }
978      }
979 
980    return status;
981 }
982 
983 static int
_edje_pick_sounds_add(Edje_File * edf)984 _edje_pick_sounds_add(Edje_File *edf)
985 {
986    char buf[1024];
987    int size, k;
988    void *data;
989    Eina_Bool status = EDJE_PICK_NO_ERROR;
990    static int current_sample_id = 0;
991 
992    if (edf->sound_dir)  /* Copy Sounds */
993      {
994         for (k = 0; k < (int)edf->sound_dir->samples_count; k++)
995           {
996              Edje_Sound_Sample *sample = &edf->sound_dir->samples[k];
997 
998              snprintf(buf, sizeof(buf), "edje/sounds/%i", sample->id);
999              VERBOSE(EINA_LOG_INFO("Trying to read <%s>\n", sample->snd_src));
1000 
1001              data = eet_read(edf->ef, buf, &size);
1002              if (size)
1003                {
1004                   Edje_Pick_Data *smpl = malloc(sizeof(*smpl));
1005                   smpl->filename = eina_stringshare_add(sample->snd_src);
1006                   smpl->data = data;
1007                   smpl->size = size;
1008                   smpl->entry = (void *)sample;  /* for output file sound dir */
1009                   smpl->id.old_id = sample->id;
1010                   sample->id = smpl->id.new_id = current_sample_id;
1011                   smpl->id.used = EINA_FALSE;
1012 
1013                   VERBOSE(EINA_LOG_INFO("Read <%s> sample data <%p> size <%d>\n",
1014                                         buf, smpl->data, smpl->size));
1015 
1016                   current_sample_id++;
1017                   context.current_file->samplelist =
1018                     eina_list_append(context.current_file->samplelist, smpl);
1019                }
1020              else
1021                {
1022                   EINA_LOG_ERR("Sample <%s> was not found in <%s> file.\n",
1023                                sample->name, context.current_file->name);
1024                   status = EDJE_PICK_SAMPLE_NOT_FOUND;
1025                   /* Should that really be freed? Or is some other handling needed? */
1026                   free(data);
1027                }
1028           }
1029 
1030         for (k = 0; k < (int)edf->sound_dir->tones_count; k++)
1031           {
1032              /* Save all tones as well */
1033              Edje_Pick_Tone *t = malloc(sizeof(*t));
1034 
1035              t->tone = &edf->sound_dir->tones[k];
1036              /* Update ID to new ID */
1037              t->tone->id = _edje_pick_new_id_get(context.current_file->samplelist,   /* From samplelist */
1038                                                  t->tone->id, EINA_FALSE);
1039 
1040              t->used = EINA_FALSE;
1041              context.current_file->tonelist = eina_list_append(context.current_file->tonelist, t);
1042           }
1043      }
1044 
1045    return status;
1046 }
1047 
1048 static int
_edje_pick_vibrations_add(Edje_File * edf)1049 _edje_pick_vibrations_add(Edje_File *edf)
1050 {
1051    char buf[1024];
1052    int size, k;
1053    void *data;
1054    Eina_Bool status = EDJE_PICK_NO_ERROR;
1055    static int current_sample_id = 0;
1056 
1057    if (edf->vibration_dir)  /* Copy Sounds */
1058      {
1059         for (k = 0; k < (int)edf->vibration_dir->samples_count; k++)
1060           {
1061              Edje_Vibration_Sample *sample = &edf->vibration_dir->samples[k];
1062 
1063              snprintf(buf, sizeof(buf), "edje/vibrations/%i", sample->id);
1064              VERBOSE(EINA_LOG_INFO("Trying to read <%s>\n", sample->name));
1065 
1066              data = eet_read(edf->ef, buf, &size);
1067              if (size)
1068                {
1069                   Edje_Pick_Data *smpl = malloc(sizeof(*smpl));
1070                   smpl->filename = eina_stringshare_add(sample->name);
1071                   smpl->data = data;
1072                   smpl->size = size;
1073                   smpl->entry = (void *)sample;  /* for output file vibration dir */
1074                   smpl->id.old_id = sample->id;
1075                   sample->id = smpl->id.new_id = current_sample_id;
1076                   smpl->id.used = EINA_FALSE;
1077 
1078                   VERBOSE(EINA_LOG_INFO("Read <%s> sample data <%p> size <%d>\n",
1079                                         buf, smpl->data, smpl->size));
1080 
1081                   current_sample_id++;
1082                   context.current_file->vibrationlist =
1083                     eina_list_append(context.current_file->vibrationlist, smpl);
1084                }
1085              else
1086                {
1087                   EINA_LOG_ERR("Sample <%s> was not found in <%s> file.\n",
1088                                sample->name, context.current_file->name);
1089                   status = EDJE_PICK_SAMPLE_NOT_FOUND;
1090                   /* Should that really be freed? Or is some other handling needed? */
1091                   free(data);
1092                }
1093           }
1094      }
1095 
1096    return status;
1097 }
1098 
1099 static int
_font_cmp(const void * d1,const void * d2)1100 _font_cmp(const void *d1, const void *d2)
1101 {
1102    const Edje_Font *f1 = d1;
1103    const Edje_Font *f2 = d2;
1104 
1105    /* Same font if (d1->name == d2->name) AND (d1->file == d2->file) */
1106    return strcmp(f1->name, f2->name) |
1107           strcmp(f1->file, f2->file);
1108 }
1109 
1110 static int
_Edje_Pick_Fonts_add(Edje_File * out_file,Edje_File * edf)1111 _Edje_Pick_Fonts_add(Edje_File *out_file, Edje_File *edf)
1112 {
1113    Eina_Iterator *it;
1114    Edje_Font *f;
1115    char buf[1024];
1116 
1117    if (!edf->fonts) return -1;
1118 
1119    it = eina_hash_iterator_data_new(edf->fonts);
1120    if (!it) return -1;
1121 
1122    EINA_ITERATOR_FOREACH(it, f)
1123      {
1124         if (!eina_list_search_unsorted(context.current_file->fontlist, _font_cmp, f))
1125           continue;
1126         /* Add only fonts that are NOT regestered in our list */
1127         Edje_Pick_Font *ft = malloc(sizeof(*ft));
1128         Edje_Font *st = malloc(sizeof(*st));
1129         ft->size = 0;
1130 
1131         st->name = (char *)eina_stringshare_add(f->name);
1132         st->file = (char *)eina_stringshare_add(f->file);
1133 
1134         snprintf(buf, sizeof(buf), "edje/fonts/%s", f->name);
1135         VERBOSE(EINA_LOG_INFO("Trying to read <%s>\n", f->name));
1136         ft->data = eet_read(edf->ef, buf, &ft->size);
1137         if (!ft->size)
1138           {
1139              eina_stringshare_del(st->name);
1140              eina_stringshare_del(st->file);
1141              free(st);
1142              free(ft);
1143              VERBOSE(EINA_LOG_INFO("Enable to read <%s>. Skip.\n", f->name));
1144              continue;
1145           }
1146 
1147         ft->f = st;
1148         ft->used = EINA_TRUE;  /* TODO: Fix this later */
1149         context.current_file->fontlist = eina_list_append(context.current_file->fontlist, ft);
1150         eina_hash_direct_add(out_file->fonts, st->name, st);
1151      }
1152 
1153    eina_iterator_free(it);
1154 
1155    return EDJE_PICK_NO_ERROR;
1156 }
1157 
1158 static int
_edje_pick_scripts_add(Edje_File * edf,int id,int new_id)1159 _edje_pick_scripts_add(Edje_File *edf, int id, int new_id)
1160 {
1161    int size;
1162    void *data;
1163    char buf[1024];
1164 
1165    /* Copy Script */
1166    snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%i", id);
1167    data = eet_read(edf->ef, buf, &size);
1168    if (size)
1169      {
1170         Edje_Pick_Data *s = calloc(1, sizeof(*s));
1171 
1172         s->data = data;
1173         s->size = size;
1174         s->id.old_id = id;
1175         s->id.new_id = new_id;
1176         s->id.used = EINA_TRUE;
1177 
1178         VERBOSE(EINA_LOG_INFO("Read embryo script <%s> data <%p> size <%d>\n",
1179                               buf, s->data, s->size));
1180         context.current_file->scriptlist = eina_list_append(context.current_file->scriptlist, s);
1181      }
1182    else
1183      {
1184         /* Should that really be freed? Or is some other handling needed? */
1185         free(data);
1186      }
1187 
1188    return EDJE_PICK_NO_ERROR;
1189 }
1190 
1191 static int
_edje_pick_lua_scripts_add(Edje_File * edf,int id,int new_id)1192 _edje_pick_lua_scripts_add(Edje_File *edf, int id, int new_id)
1193 {
1194    int size;
1195    void *data;
1196    char buf[1024];
1197 
1198    /* Copy Script */
1199    snprintf(buf, sizeof(buf), "edje/scripts/lua/%i", id);
1200    data = eet_read(edf->ef, buf, &size);
1201    if (size)
1202      {
1203         Edje_Pick_Data *s = calloc(1, sizeof(*s));
1204 
1205         s->data = data;
1206         s->size = size;
1207         s->id.old_id = id;
1208         s->id.new_id = new_id;
1209         s->id.used = EINA_TRUE;
1210 
1211         VERBOSE(EINA_LOG_INFO("Read lua script <%s> data <%p> size <%d>\n",
1212                               buf, s->data, s->size));
1213         context.current_file->luascriptlist = eina_list_append(context.current_file->luascriptlist, s);
1214      }
1215    else
1216      {
1217         /* Should that really be freed? Or is some other handling needed? */
1218         free(data);
1219      }
1220 
1221    return EDJE_PICK_NO_ERROR;
1222 }
1223 
1224 static int
_edje_pick_image_entry_add(int id,Edje_File * edf,Edje_File * o)1225 _edje_pick_image_entry_add(int id, Edje_File *edf, Edje_File *o)
1226 {
1227    char buf[1024];
1228    int size;
1229    void *data;
1230    static int current_img_id = -1;
1231 
1232    int new_id = _edje_pick_image_new_id_get(context.current_file->imagelist, id);
1233    if (new_id >= 0) return new_id;
1234 
1235    if (edf->image_dir)
1236      {
1237         if (!o->image_dir) /* First time only */
1238           o->image_dir = calloc(1, sizeof(*(o->image_dir)));
1239 
1240         if (edf->image_dir->entries) /* Copy Images */
1241           {
1242              Edje_Image_Directory_Entry *img = &edf->image_dir->entries[id];
1243 
1244              snprintf(buf, sizeof(buf), "edje/images/%i", img->id);
1245              VERBOSE(EINA_LOG_INFO("Trying to read <%s>\n", img->entry));
1246              data = eet_read(edf->ef, buf, &size);
1247              if (size) /* Advance image ID and register this in imagelist */
1248                {
1249                   current_img_id++;
1250                   Edje_Pick_Data *image = malloc(sizeof(*image));
1251 
1252                   image->filename = eina_stringshare_add(img->entry);
1253                   image->data = data;
1254                   image->size = size;
1255                   image->entry = (void *)img;   /* for output file image dir */
1256                   image->id.old_id = img->id;
1257                   img->id = image->id.new_id = current_img_id;
1258                   image->id.used = EINA_TRUE;
1259 
1260                   VERBOSE(EINA_LOG_INFO("Read image <%s> data <%p> size <%d>, new_id : %d\n",
1261                                         buf, image->data, image->size, image->id.new_id));
1262 
1263                   context.current_file->imagelist = eina_list_append(
1264                       context.current_file->imagelist, image);
1265                }
1266              else
1267                {
1268                   if (img->entry)
1269                     {
1270                        EINA_LOG_ERR("Image <%s> was not found in <%s> file.\n",
1271                                     img->entry, context.current_file->name);
1272                     }
1273                   else
1274                     {
1275                        EINA_LOG_ERR("Image entry <%s> was not found in <%s> file.\n", buf, context.current_file->name);
1276                     }
1277                   /* Should that really be freed? Or is some other handling needed? */
1278                   free(data);
1279                }
1280           }
1281      }
1282 
1283    return current_img_id;
1284 }
1285 
1286 static int
_edje_pick_image_set_add(int id,Edje_File * edf,Edje_File * o)1287 _edje_pick_image_set_add(int id, Edje_File *edf, Edje_File *o)
1288 {
1289    static int current_set_id = -1;
1290    Edje_Image_Directory_Set_Entry *ent;
1291    Eina_List *l;
1292 
1293    int new_id = _edje_pick_image_new_id_get(context.current_file->imagesetlist, id);
1294    if (new_id >= 0) return new_id;
1295 
1296    if (edf->image_dir)
1297      {
1298         if (!o->image_dir) /* First time only */
1299           o->image_dir = calloc(1, sizeof(*(o->image_dir)));
1300 
1301         if (edf->image_dir->sets) /* Fix IDs in sets to new assigned IDs of entries */
1302           {
1303              current_set_id++;
1304              Edje_Pick_Data *set = calloc(1, sizeof(*set));
1305              set->id.old_id = edf->image_dir->sets[id].id;
1306              set->id.new_id = current_set_id;
1307              set->id.used = EINA_TRUE;
1308 
1309              /* Save IDs in set-list, used in Desc update later */
1310              context.current_file->imagesetlist = eina_list_append(
1311                  context.current_file->imagesetlist, set);
1312              EINA_LIST_FOREACH(edf->image_dir->sets[id].entries, l, ent)
1313                {
1314                   _edje_pick_image_entry_add(ent->id, edf, o);
1315                }
1316           }
1317      }
1318 
1319    return current_set_id;
1320 }
1321 
1322 static int
_edje_pick_vector_entry_add(int id,Edje_File * edf,Edje_File * o)1323 _edje_pick_vector_entry_add(int id, Edje_File *edf, Edje_File *o)
1324 {
1325    char buf[1024];
1326    int size;
1327    void *data;
1328    static int current_vg_id = -1;
1329 
1330    int new_id = _edje_pick_image_new_id_get(context.current_file->vectorlist, id);
1331    if (new_id >= 0) return new_id;
1332 
1333    if (edf->image_dir)
1334      {
1335         if (!o->image_dir) /* First time only */
1336           o->image_dir = calloc(1, sizeof(*(o->image_dir)));
1337 
1338         if (edf->image_dir->vectors) /* Copy Vectors */
1339           {
1340              Edje_Vector_Directory_Entry *vg = &edf->image_dir->vectors[id];
1341 
1342              snprintf(buf, sizeof(buf), "edje/vectors/%i", vg->id);
1343              VERBOSE(EINA_LOG_INFO("Trying to read <%s>\n", vg->entry));
1344              data = eet_read(edf->ef, buf, &size);
1345              if (size) /* Advance vector ID and register this in vectorlist */
1346                {
1347                   current_vg_id++;
1348                   Edje_Pick_Data *vector = malloc(sizeof(*vector));
1349 
1350                   vector->filename = eina_stringshare_add(vg->entry);
1351                   vector->data = data;
1352                   vector->size = size;
1353                   vector->entry = (void *)vg;   /* for output file vector dir */
1354                   vector->id.old_id = vg->id;
1355                   vg->id = vector->id.new_id = current_vg_id;
1356                   vector->id.used = EINA_TRUE;
1357 
1358                   VERBOSE(EINA_LOG_INFO("Read vector <%s> data <%p> size <%d>, new_id : %d\n",
1359                                         buf, vector->data, vector->size, vector->id.new_id));
1360 
1361                   context.current_file->vectorlist = eina_list_append(
1362                       context.current_file->vectorlist, vector);
1363                }
1364              else
1365                {
1366                   if (vg->entry)
1367                     {
1368                        EINA_LOG_ERR("Vector <%s> was not found in <%s> file.\n",
1369                                     vg->entry, context.current_file->name);
1370                     }
1371                   else
1372                     {
1373                        EINA_LOG_ERR("Vector entry <%s> was not found in <%s> file.\n", buf, context.current_file->name);
1374                     }
1375                   /* Should that really be freed? Or is some other handling needed? */
1376                   free(data);
1377                }
1378           }
1379      }
1380 
1381    return current_vg_id;
1382 }
1383 
1384 static void
_edje_pick_images_desc_update(Edje_Part_Description_Image * desc,Edje_File * edf,Edje_File * o)1385 _edje_pick_images_desc_update(Edje_Part_Description_Image *desc, Edje_File *edf, Edje_File *o)
1386 {
1387    /* Update all IDs of images in descs */
1388    if (desc)
1389      {
1390         unsigned int k;
1391         int new_id = (desc->image.set) ?
1392           _edje_pick_image_set_add(desc->image.id, edf, o) :
1393           _edje_pick_image_entry_add(desc->image.id, edf, o);
1394 
1395         desc->image.id = new_id;
1396 
1397         for (k = 0; k < desc->image.tweens_count; k++)
1398           {
1399              new_id = (desc->image.set) ?
1400                _edje_pick_image_set_add(desc->image.tweens[k]->id, edf, o) :
1401                _edje_pick_image_entry_add(desc->image.tweens[k]->id, edf, o);
1402 
1403              desc->image.tweens[k]->id = new_id;
1404           }
1405      }
1406 }
1407 
1408 static void
_edje_pick_vectors_desc_update(Edje_Part_Description_Vector * desc,Edje_File * edf,Edje_File * o)1409 _edje_pick_vectors_desc_update(Edje_Part_Description_Vector *desc, Edje_File *edf, Edje_File *o)
1410 {
1411    /* Update all IDs of vectors in descs */
1412    if (desc)
1413      {
1414         int new_id = _edje_pick_vector_entry_add(desc->vg.id, edf, o);
1415 
1416         desc->vg.id = new_id;
1417      }
1418 }
1419 
1420 static void
_edje_pick_styles_desc_update(Edje_Part_Description_Text * desc,Edje_File * edf,Edje_File * o)1421 _edje_pick_styles_desc_update(Edje_Part_Description_Text *desc, Edje_File *edf, Edje_File *o)
1422 {
1423    Eina_List *l;
1424    Edje_Style *stl;
1425    const char *style;
1426 
1427    if (desc)
1428      {
1429         style = desc->text.style.str;
1430 
1431         if (style)
1432           {
1433              EINA_LIST_FOREACH(edf->styles, l, stl)
1434                if ((stl->name) && (!strcmp(stl->name, style)))
1435                  o->styles = eina_list_append(o->styles, stl);
1436           }
1437      }
1438 }
1439 
1440 static void
_edje_pick_color_class_desc_update(Edje_Part_Description_Common * desc,Edje_File * edf,Edje_File * o)1441 _edje_pick_color_class_desc_update(Edje_Part_Description_Common *desc, Edje_File *edf, Edje_File *o)
1442 {
1443    Eina_List *l;
1444    Edje_Color_Class *cc;
1445    const char *color_class;
1446 
1447    if (desc)
1448      {
1449         color_class = desc->color_class;
1450 
1451         if (color_class)
1452           {
1453              EINA_LIST_FOREACH(edf->color_classes, l, cc)
1454                if ((cc->name) && (!strcmp(cc->name, color_class)))
1455                  o->color_classes = eina_list_append(o->color_classes, cc);
1456           }
1457      }
1458 }
1459 
1460 static void
_edje_pick_resources_process(Edje_Part_Collection * edc,Edje_File * edf,Edje_File * o)1461 _edje_pick_resources_process(Edje_Part_Collection *edc, Edje_File *edf, Edje_File *o)
1462 {
1463    /* Find what imagees are used, update IDs, mark as USED */
1464    /* Find what styles and color classes are used */
1465    unsigned int i, k;
1466 
1467    for (i = 0; i < edc->parts_count; i++)
1468      {
1469         /* Scan all parts, locate what resources used */
1470         Edje_Part *part = edc->parts[i];
1471 
1472         /* Update all color class in ALL descs of this part */
1473         _edje_pick_color_class_desc_update((Edje_Part_Description_Common *)part->default_desc, edf, o);
1474 
1475         for (k = 0; k < part->other.desc_count; k++)
1476           _edje_pick_color_class_desc_update((Edje_Part_Description_Common *)part->other.desc[k], edf, o);
1477 
1478         if (part->type == EDJE_PART_TYPE_IMAGE)
1479           {
1480              /* Update IDs of all images in ALL descs of this part */
1481              _edje_pick_images_desc_update((Edje_Part_Description_Image *)part->default_desc, edf, o);
1482 
1483              for (k = 0; k < part->other.desc_count; k++)
1484                _edje_pick_images_desc_update((Edje_Part_Description_Image *)part->other.desc[k], edf, o);
1485           }
1486         else if (part->type == EDJE_PART_TYPE_VECTOR)
1487           {
1488              /* Update IDs of all vectors in ALL descs of this part */
1489              _edje_pick_vectors_desc_update((Edje_Part_Description_Vector *)part->default_desc, edf, o);
1490 
1491              for (k = 0; k < part->other.desc_count; k++)
1492                _edje_pick_vectors_desc_update((Edje_Part_Description_Vector *)part->other.desc[k], edf, o);
1493           }
1494         else if (part->type == EDJE_PART_TYPE_TEXT || part->type == EDJE_PART_TYPE_TEXTBLOCK)
1495           {
1496              /* Update all styles in ALL descs of this part */
1497              _edje_pick_styles_desc_update((Edje_Part_Description_Text *)part->default_desc, edf, o);
1498 
1499              for (k = 0; k < part->other.desc_count; k++)
1500                _edje_pick_styles_desc_update((Edje_Part_Description_Text *)part->other.desc[k], edf, o);
1501           }
1502      }
1503 }
1504 
1505 static int
_sample_cmp(const void * d1,const void * d2)1506 _sample_cmp(const void *d1, const void *d2)
1507 {
1508    /* Locate sample by name */
1509    if (d2)
1510      {
1511         Edje_Sound_Sample *sample = ((Edje_Pick_Data *)d1)->entry;
1512 
1513         return strcmp(sample->name, d2);
1514      }
1515 
1516    return 1;
1517 }
1518 
1519 static int
_tone_cmp(const void * d1,const void * d2)1520 _tone_cmp(const void *d1, const void *d2)
1521 {
1522    /* Locate tone by name */
1523    if (d2)
1524      {
1525         Edje_Sound_Tone *tone = ((Edje_Pick_Tone *)d1)->tone;
1526 
1527         return strcmp(tone->name, d2);
1528      }
1529 
1530    return 1;
1531 }
1532 
1533 static void
_edje_pick_program_update(Edje_Program * prog)1534 _edje_pick_program_update(Edje_Program *prog)
1535 {
1536    Edje_Pick_Data *p;
1537    Edje_Pick_Tone *t;
1538 
1539    /* Scan for used samples, update samples IDs */
1540    p = eina_list_search_unsorted(context.current_file->samplelist,
1541                                  (Eina_Compare_Cb)_sample_cmp,
1542                                  prog->sample_name);
1543 
1544    /* Sample is used by program, should be saved */
1545    if (p)
1546      p->id.used = EINA_TRUE;
1547 
1548    /* handle tones as well */
1549    t = eina_list_search_unsorted(context.current_file->tonelist,
1550                                  (Eina_Compare_Cb)_tone_cmp,
1551                                  prog->tone_name);
1552 
1553    /* Tone is used by program, should be saved */
1554    if (t)
1555      t->used = EINA_TRUE;
1556 }
1557 
1558 static int
_edje_pick_programs_process(Edje_Part_Collection * edc)1559 _edje_pick_programs_process(Edje_Part_Collection *edc)
1560 {
1561    /* This wil mark which samples are used and should be saved */
1562    unsigned int i;
1563 
1564    for (i = 0; i < edc->programs.fnmatch_count; i++)
1565      _edje_pick_program_update(edc->programs.fnmatch[i]);
1566 
1567    for (i = 0; i < edc->programs.strcmp_count; i++)
1568      _edje_pick_program_update(edc->programs.strcmp[i]);
1569 
1570    for (i = 0; i < edc->programs.strncmp_count; i++)
1571      _edje_pick_program_update(edc->programs.strncmp[i]);
1572 
1573    for (i = 0; i < edc->programs.strrncmp_count; i++)
1574      _edje_pick_program_update(edc->programs.strrncmp[i]);
1575 
1576    for (i = 0; i < edc->programs.nocmp_count; i++)
1577      _edje_pick_program_update(edc->programs.nocmp[i]);
1578 
1579    return EDJE_PICK_NO_ERROR;
1580 }
1581 
1582 static int
_edje_pick_collection_process(Edje_Part_Collection * edc,Edje_File * edf,Edje_File * o)1583 _edje_pick_collection_process(Edje_Part_Collection *edc, Edje_File *edf, Edje_File *o)
1584 {
1585    /* Update all IDs, NAMES in current collection */
1586    Edje_Part_Collection_Directory_Entry *ce;
1587 
1588    ce = eina_hash_find(o->collection, edc->part);
1589    edc->id = ce->id;
1590 
1591    _edje_pick_resources_process(edc, edf, o);
1592    _edje_pick_programs_process(edc);
1593 
1594    return EDJE_PICK_NO_ERROR;
1595 }
1596 
1597 static void
_edje_pick_sound_dir_compose(Eina_List * samples,Eina_List * tones,Edje_File * o)1598 _edje_pick_sound_dir_compose(Eina_List *samples, Eina_List *tones, Edje_File *o)
1599 {  /* Compose sound_dir array from all used samples, tones */
1600   if (samples)
1601     {
1602        Edje_Sound_Sample *sample;
1603        Edje_Sound_Sample *p;
1604        Eina_List *l;
1605 
1606        o->sound_dir = calloc(1, sizeof(*(o->sound_dir)));
1607        o->sound_dir->samples = malloc(eina_list_count(samples) *
1608                                       sizeof(Edje_Sound_Sample));
1609 
1610        p = o->sound_dir->samples;
1611        EINA_LIST_FOREACH(samples, l, sample)
1612          {
1613             memcpy(p, sample, sizeof(Edje_Sound_Sample));
1614             p++;
1615          }
1616 
1617        o->sound_dir->samples_count = eina_list_count(samples);
1618 
1619        if (tones)
1620          {
1621             Edje_Sound_Tone *tone;
1622             Edje_Sound_Tone *t;
1623 
1624             o->sound_dir->tones = malloc(eina_list_count(tones) *
1625                                          sizeof(Edje_Sound_Tone));
1626 
1627             t = o->sound_dir->tones;
1628             EINA_LIST_FOREACH(tones, l, tone)
1629               {
1630                  memcpy(t, tone, sizeof(Edje_Sound_Tone));
1631                  t++;
1632               }
1633 
1634             o->sound_dir->tones_count = eina_list_count(tones);
1635          }
1636     }
1637 }
1638 
1639 static void
_edje_pick_vibration_dir_compose(Eina_List * vibrations,Edje_File * o)1640 _edje_pick_vibration_dir_compose(Eina_List *vibrations, Edje_File *o)
1641 {  /* Compose vibrationdir array from all used vibrations */
1642   if (vibrations)
1643     {
1644        Edje_Vibration_Sample *sample;
1645        Edje_Vibration_Sample *p;
1646        Eina_List *l;
1647 
1648        o->vibration_dir = calloc(1, sizeof(*(o->vibration_dir)));
1649        o->vibration_dir->samples = malloc(eina_list_count(vibrations) *
1650                                           sizeof(Edje_Vibration_Sample));
1651 
1652        p = o->vibration_dir->samples;
1653        EINA_LIST_FOREACH(vibrations, l, sample)
1654          {
1655             memcpy(p, sample, sizeof(Edje_Vibration_Sample));
1656             p++;
1657          }
1658 
1659        o->vibration_dir->samples_count = eina_list_count(vibrations);
1660     }
1661 }
1662 
1663 int
main(int argc,char ** argv)1664 main(int argc, char **argv)
1665 {
1666    char *name1, *output_filename = NULL;
1667    Eina_List *inp_files = NULL;
1668    int comp_mode = EET_COMPRESSION_DEFAULT;
1669    Edje_File *out_file = NULL;
1670    Eina_List *images = NULL;
1671    Eina_List *samples = NULL;
1672    Eina_List *tones = NULL;
1673    Eina_List *vibrations = NULL;
1674 
1675    Edje_Part_Collection *edc;
1676    Edje_Part_Collection_Directory_Entry *ce;
1677    Eet_File *ef;
1678    Eina_List *f, *l;
1679    char buf[1024];
1680    int k, bytes;
1681 
1682    ecore_app_no_system_modules();
1683 
1684    eina_init();
1685    eet_init();
1686    ecore_init();
1687    _edje_edd_init();
1688    eina_log_level_set(EINA_LOG_LEVEL_WARN);  /* Changed to INFO if verbose */
1689 
1690    k = _edje_pick_command_line_parse(argc, argv, &inp_files, &output_filename);
1691    if ( k != EDJE_PICK_NO_ERROR)
1692      return k;
1693 
1694    _edje_pick_args_show(inp_files, output_filename);
1695 
1696    /* START - Main loop scanning input files */
1697    EINA_LIST_FOREACH(inp_files, f, context.current_file)
1698      {
1699         Edje_File *edf;
1700 
1701         ef = eet_open(context.current_file->name, EET_FILE_MODE_READ);
1702         if (!ef)
1703           return _edje_pick_cleanup(inp_files, out_file,
1704                                     EDJE_PICK_FAILED_OPEN_INP);
1705 
1706         edf = eet_data_read(ef, _edje_edd_edje_file, "edje/file");
1707         if (!edf)
1708           return _edje_pick_cleanup(inp_files, out_file,
1709                                     EDJE_PICK_FAILED_READ_INP);
1710 
1711         context.current_file->edf = edf;
1712         edf->ef = ef;
1713 
1714         out_file = _edje_pick_output_prepare(out_file, edf, output_filename);
1715         if (!out_file)
1716           {
1717              _edje_cache_file_unref(edf);
1718              eet_close(ef);
1719              return _edje_pick_cleanup(inp_files, out_file, k);
1720           }
1721 
1722         k = _edje_pick_header_make(out_file, edf, inp_files);
1723         if (k != EDJE_PICK_NO_ERROR)
1724           {
1725              _edje_cache_file_unref(edf);
1726              eet_close(ef);
1727              return _edje_pick_cleanup(inp_files, out_file, k);
1728           }
1729 
1730         /* Build lists of all samples and fonts of input files    */
1731         _edje_pick_sounds_add(edf);  /* Add Sounds to samplelist          */
1732         _edje_pick_vibrations_add(edf);  /* Add Vibrations to samplelist  */
1733 
1734         _edje_pick_data_update(out_file, edf);
1735 
1736         /* Process Groups */
1737         EINA_LIST_FOREACH(context.current_file->groups, l, name1)
1738           {  /* Read group info */
1739             ce = eina_hash_find(edf->collection, name1);
1740             if (!ce || (ce->id < 0))
1741               {
1742                  EINA_LOG_ERR("Failed to find group <%s> id\n", name1);
1743                  _edje_cache_file_unref(edf);
1744                  return _edje_pick_cleanup(inp_files, out_file,
1745                                            EDJE_PICK_GROUP_NOT_FOUND);
1746               }
1747 
1748             VERBOSE(EINA_LOG_INFO("Copy group: <%s>\n", name1));
1749 
1750             edje_cache_emp_alloc(ce);
1751 
1752             snprintf(buf, sizeof(buf), "edje/collections/%i", ce->id);
1753             EINA_LOG_INFO("Trying to read group <%s>\n", buf);
1754             edc = eet_data_read(edf->ef, _edje_edd_edje_part_collection, buf);
1755             if (!edc)
1756               {
1757                  EINA_LOG_ERR("Failed to read group <%s> id <%d>\n", name1, ce->id);
1758                  _edje_cache_file_unref(edf);
1759                  return _edje_pick_cleanup(inp_files, out_file,
1760                                            EDJE_PICK_GROUP_NOT_FOUND);
1761               }
1762 
1763             /* Update IDs */
1764             _edje_pick_collection_process(edc, edf, out_file);
1765 
1766             /* Build lists of all scripts with new IDs */
1767             _edje_pick_scripts_add(edf, ce->id, edc->id);
1768             _edje_pick_lua_scripts_add(edf, ce->id, edc->id);
1769 
1770             {
1771                /* Write the group to output file using new id */
1772                snprintf(buf, sizeof(buf),
1773                         "edje/collections/%i", edc->id);
1774                bytes = eet_data_write(out_file->ef,
1775                                       _edje_edd_edje_part_collection,
1776                                       buf, edc, comp_mode);
1777                EINA_LOG_INFO("Wrote <%d> bytes for group <%s>\n", bytes, buf);
1778             }
1779 
1780             free(edc);
1781             edje_cache_emp_free(ce);
1782             eet_close(ef);
1783           }
1784 
1785         _edje_pick_images_copy(edf, out_file);  /* Add Images to imagelist */
1786         _edje_cache_file_unref(edf);
1787         _Edje_Pick_Fonts_add(out_file, edf);   /* Add fonts from file to fonts list */
1788 
1789         /* We SKIP writing source, just can't compose it */
1790         /* FIXME: use Edje_Edit code to generate source */
1791      } /* END   - Main loop scanning input files */
1792 
1793    /* Write rest of output */
1794 
1795    EINA_LIST_FOREACH(inp_files, f, context.current_file)
1796      {
1797         /* Write Scripts from ALL files */
1798         Edje_Pick_Data *s;
1799         Edje_Pick_Tone *tn;
1800         Edje_Pick_Font *fn;
1801         Eina_List *t;
1802 
1803         EINA_LIST_FOREACH(context.current_file->scriptlist, t, s)
1804           {
1805              /* Write Scripts */
1806              snprintf(buf, sizeof(buf),
1807                       "edje/scripts/embryo/compiled/%i", s->id.new_id);
1808              VERBOSE(EINA_LOG_INFO("wrote embryo scr <%s> data <%p> size <%d>\n",
1809                                    buf, s->data, s->size));
1810              eet_write(out_file->ef, buf, s->data, s->size, comp_mode);
1811           }
1812 
1813         EINA_LIST_FOREACH(context.current_file->luascriptlist, t, s)
1814           {
1815              /* Write Lua Scripts */
1816              snprintf(buf, sizeof(buf),
1817                       "edje/scripts/lua/%i", s->id.new_id);
1818              VERBOSE(EINA_LOG_INFO("wrote lua scr <%s> data <%p> size <%d>\n",
1819                                    buf, s->data, s->size));
1820              eet_write(out_file->ef, buf, s->data, s->size, comp_mode);
1821           }
1822 
1823         EINA_LIST_FOREACH(context.current_file->imagelist, t, s)
1824           {
1825              if (context.current_file->append || s->id.used)
1826                {
1827                   snprintf(buf, sizeof(buf), "edje/images/%i", s->id.new_id);
1828                   eet_write(out_file->ef, buf, s->data, s->size, EINA_TRUE);
1829                   VERBOSE(EINA_LOG_INFO("Wrote <%s> image data <%p> size <%d>\n", buf, s->data, s->size));
1830                }
1831           }
1832 
1833         EINA_LIST_FOREACH(context.current_file->vectorlist, t, s)
1834           {
1835              if (context.current_file->append || s->id.used)
1836                {
1837                   snprintf(buf, sizeof(buf), "edje/vectors/%i", s->id.new_id);
1838                   eet_write(out_file->ef, buf, s->data, s->size, EINA_TRUE);
1839                   VERBOSE(EINA_LOG_INFO("Wrote <%s> vector data <%p> size <%d>\n", buf, s->data, s->size));
1840                }
1841           }
1842 
1843         EINA_LIST_FOREACH(context.current_file->fontlist, t, fn)
1844           {
1845              if (context.current_file->append || fn->used)
1846                {
1847                   snprintf(buf, sizeof(buf), "edje/fonts/%s", fn->f->name);
1848                   eet_write(out_file->ef, buf, fn->data, fn->size, EINA_TRUE);
1849                   VERBOSE(EINA_LOG_INFO("Wrote <%s> fonts data <%p> size <%d>\n", buf, fn->data, fn->size));
1850                }
1851           }
1852 
1853         EINA_LIST_FOREACH(context.current_file->samplelist, l, s)
1854           {
1855              if (context.current_file->append || s->id.used) /* Write only used samples */
1856                {
1857                   samples = eina_list_append(samples, s->entry);
1858 
1859                   snprintf(buf, sizeof(buf), "edje/sounds/%i",
1860                            s->id.new_id);
1861                   eet_write(out_file->ef, buf,
1862                             s->data, s->size, EET_COMPRESSION_NONE);
1863                   VERBOSE(EINA_LOG_INFO("Wrote <%s> sample data <%p> size <%d>\n",
1864                                         buf, s->data, s->size));
1865                }
1866           }
1867 
1868         EINA_LIST_FOREACH(context.current_file->tonelist, l, tn)
1869           {
1870              if (context.current_file->append || tn->used)
1871                tones = eina_list_append(tones, tn->tone);
1872           }
1873 
1874         EINA_LIST_FOREACH(context.current_file->vibrationlist, l, s)
1875           {
1876              if (context.current_file->append || s->id.used) /* Write only used vibrations */
1877                {
1878                   vibrations = eina_list_append(vibrations, s->entry);
1879 
1880                   snprintf(buf, sizeof(buf), "edje/vibrations/%i",
1881                            s->id.new_id);
1882                   eet_write(out_file->ef, buf,
1883                             s->data, s->size, EINA_TRUE);
1884                   VERBOSE(EINA_LOG_INFO("Wrote <%s> vibration data <%p> size <%d>\n",
1885                                         buf, s->data, s->size));
1886                }
1887           }
1888      }
1889 
1890    _edje_pick_sound_dir_compose(samples, tones, out_file);
1891    _edje_pick_vibration_dir_compose(vibrations, out_file);
1892 
1893    /* Write file header after processing all groups */
1894    if (out_file)
1895      {
1896         bytes = eet_data_write(out_file->ef, _edje_edd_edje_file, "edje/file",
1897                                out_file, comp_mode);
1898         VERBOSE(EINA_LOG_INFO("Wrote <%d> bytes for file header.\n", bytes));
1899      }
1900 
1901    eina_list_free(images);
1902    eina_list_free(samples);
1903    eina_list_free(tones);
1904 
1905    if (output_filename)
1906      printf("Wrote <%s> output file.\n", output_filename);
1907 
1908    return _edje_pick_cleanup(inp_files, out_file, EDJE_PICK_NO_ERROR);
1909 }
1910 
1911