1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Ecore.h>
6 #include <Ecore_File.h>
7 #include <Ecore_Evas.h>
8 #include <Ecore_Getopt.h>
9 #include <Edje.h>
10 #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT 1
11 #include <Edje_Edit.h>
12 #include <Eina.h>
13
14 #include <Elementary.h>
15
16 #include <ctype.h>
17 #include <fcntl.h>
18 #include <locale.h>
19 #include <stdio.h>
20 #include <unistd.h>
21
22 #ifndef ENABLE_NLS
23 # ifndef libintl_setlocale
24 # define libintl_setlocale(c, l)
25 # endif
26 #endif
27
28 static int _log_dom;
29 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
30 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
31 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
32
33 static Ecore_Evas *ee = NULL;
34 static char *file = NULL;
35 static char *group = NULL;
36 static char *prefix = NULL;
37 static FILE *source_fd = NULL;
38 static FILE *header_fd = NULL;
39
40 #define H_HEADER \
41 "#ifndef _%s\n" \
42 "#define _%s\n\n" \
43 "#include <Edje.h>\n" \
44 "#include <Elementary.h>\n" \
45 "#include <Evas.h>\n\n" \
46 "#include <stdlib.h>\n\n"
47
48 #define H_FOOTER \
49 "\n#endif /* _%s */\n"
50
51 #define C_HEADER \
52 "#include \"%s\"\n\n"
53
54 #define H_CODEGEN_LAYOUT_ADD \
55 "/**\n * @brief Creates the layout object and set the theme\n" \
56 " * @param o The parent\n" \
57 " * @param th The theme to add to, or if NULL, the default theme\n" \
58 " * @param edje_file The path to edj, if NULL it's used the path given\n" \
59 " * to elementary_codegen\n */\n" \
60 "Evas_Object *%s_layout_add(Evas_Object *o, Elm_Theme *th, " \
61 "const char *edje_file);\n"
62
63 #define C_CODEGEN_LAYOUT_ADD \
64 "Evas_Object *\n" \
65 "%s_layout_add(Evas_Object *o, Elm_Theme *th, const char *edje_file)\n" \
66 "{\n" \
67 " Evas_Object *l;\n\n" \
68 " if (edje_file)\n" \
69 " elm_theme_extension_add(th, edje_file);\n" \
70 " else\n" \
71 " elm_theme_extension_add(th, \"./%s\");\n\n" \
72 " l = elm_layout_add(o);\n" \
73 " if (!l) return NULL;\n\n" \
74 " if (!elm_layout_theme_set(l, \"%s\", \"%s\", \"%s\"))\n" \
75 " {\n" \
76 " evas_object_del(l);\n" \
77 " return NULL;\n" \
78 " }\n\n" \
79 " return l;\n" \
80 "}\n\n"
81
82 #define C_CODEGEN_PART_CONTENT_SET \
83 "void\n" \
84 "%s_%s_set(Evas_Object *o, Evas_Object *value)\n" \
85 "{\n" \
86 " elm_layout_content_set(o, \"%s\", value);\n" \
87 "}\n\n"
88
89 #define C_CODEGEN_PART_TEXT_SET \
90 "void\n" \
91 "%s_%s_set(Evas_Object *o, const char *value)\n" \
92 "{\n" \
93 " elm_layout_text_set(o, \"%s\", value);\n" \
94 "}\n\n"
95
96 #define C_CODEGEN_PART_CONTENT_UNSET \
97 "Evas_Object *\n" \
98 "%s_%s_unset(Evas_Object *o)\n" \
99 "{\n" \
100 " return elm_layout_content_unset(o, \"%s\");\n" \
101 "}\n\n"
102
103 #define H_CODEGEN_PART_CONTENT_SET \
104 "void %s_%s_set(Evas_Object *o, Evas_Object *value);\n"
105
106 #define H_CODEGEN_PART_TEXT_SET \
107 "void %s_%s_set(Evas_Object *o, const char *value);\n"
108
109 #define H_CODEGEN_PART_CONTENT_UNSET \
110 "Evas_Object *%s_%s_unset(Evas_Object *o);\n"
111
112 #define C_CODEGEN_PART_CONTENT_GET \
113 "Evas_Object *\n" \
114 "%s_%s_get(const Evas_Object *o)\n" \
115 "{\n" \
116 " return elm_layout_content_get(o, \"%s\");\n" \
117 "}\n\n"
118
119 #define H_CODEGEN_PART_CONTENT_GET \
120 "Evas_Object *%s_%s_get(const Evas_Object *o);\n"
121
122 #define C_CODEGEN_PART_TEXT_GET \
123 "const char *\n" \
124 "%s_%s_get(const Evas_Object *o)\n" \
125 "{\n" \
126 " return elm_layout_text_get(o, \"%s\");\n" \
127 "}\n\n"
128
129 #define H_CODEGEN_PART_TEXT_GET \
130 "const char *%s_%s_get(const Evas_Object *o);\n"
131
132 #define C_CODEGEN_PART_BOX_APPEND \
133 "Eina_Bool\n" \
134 "%s_%s_append(Evas_Object *o, Evas_Object *child)\n" \
135 "{\n" \
136 " return elm_layout_box_append(o, \"%s\", child);\n" \
137 "}\n\n"
138
139 #define H_CODEGEN_PART_BOX_APPEND \
140 "Eina_Bool %s_%s_append(Evas_Object *o, Evas_Object *child);\n"
141
142 #define C_CODEGEN_PART_BOX_PREPEND \
143 "Eina_Bool\n" \
144 "%s_%s_prepend(Evas_Object *o, Evas_Object *child)\n" \
145 "{\n" \
146 " return elm_layout_box_prepend(o, \"%s\", child);\n" \
147 "}\n\n"
148
149 #define H_CODEGEN_PART_BOX_PREPEND \
150 "Eina_Bool %s_%s_prepend(Evas_Object *o, Evas_Object *child);\n"
151
152 #define C_CODEGEN_PART_BOX_INSERT_BEFORE \
153 "Eina_Bool\n" \
154 "%s_%s_insert_before(Evas_Object *o, Evas_Object *child, " \
155 "const Evas_Object *reference)\n" \
156 "{\n" \
157 " return elm_layout_box_insert_before(o, \"%s\", " \
158 "child, reference);\n" \
159 "}\n\n"
160
161 #define H_CODEGEN_PART_BOX_INSERT_BEFORE \
162 "Eina_Bool %s_%s_insert_before(Evas_Object *o, Evas_Object *child, " \
163 "const Evas_Object *reference);\n"
164
165 #define C_CODEGEN_PART_BOX_INSERT_AT \
166 "Eina_Bool\n" \
167 "%s_%s_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos)\n" \
168 "{\n" \
169 " return elm_layout_box_insert_at(o, \"%s\", child, pos);\n" \
170 "}\n\n"
171
172 #define H_CODEGEN_PART_BOX_INSERT_AT \
173 "Eina_Bool %s_%s_insert_at(Evas_Object *o, Evas_Object *child, " \
174 "unsigned int pos);\n"
175
176 #define C_CODEGEN_PART_BOX_REMOVE \
177 "Evas_Object *\n" \
178 "%s_%s_remove(Evas_Object *o, Evas_Object *child)\n" \
179 "{\n" \
180 " return elm_layout_box_remove(o, \"%s\", child);\n" \
181 "}\n\n"
182
183 #define H_CODEGEN_PART_BOX_REMOVE \
184 "Evas_Object *%s_%s_remove(Evas_Object *o, Evas_Object *child);\n"
185
186 #define C_CODEGEN_PART_BOX_REMOVE_ALL \
187 "Eina_Bool\n" \
188 "%s_%s_remove_all(Evas_Object *o, Eina_Bool clear)\n" \
189 "{\n" \
190 " return elm_layout_box_remove_all(o, \"%s\", clear);\n" \
191 "}\n\n"
192
193 #define H_CODEGEN_PART_BOX_REMOVE_ALL \
194 "Eina_Bool %s_%s_remove_all(Evas_Object *o, Eina_Bool clear);\n"
195
196 #define C_CODEGEN_PART_TABLE_PACK \
197 "Eina_Bool\n" \
198 "%s_%s_pack(Evas_Object *o, Evas_Object *child, unsigned short col, " \
199 "unsigned short row, unsigned short colspan, unsigned short rowspan)\n" \
200 "{\n" \
201 " return elm_layout_table_pack(o, \"%s\", child, col, row, " \
202 "colspan, rowspan);\n" \
203 "}\n\n"
204
205 #define H_CODEGEN_PART_TABLE_PACK \
206 "Eina_Bool %s_%s_pack(Evas_Object *o, Evas_Object *child, " \
207 "unsigned short col, unsigned short row, unsigned short " \
208 "colspan, unsigned short rowspan);\n"
209
210 #define C_CODEGEN_PART_TABLE_UNPACK \
211 "Evas_Object *\n" \
212 "%s_%s_unpack(Evas_Object *o, Evas_Object *child)\n" \
213 "{\n" \
214 " return elm_layout_table_unpack(o, \"%s\", child);\n" \
215 "}\n\n"
216
217 #define H_CODEGEN_PART_TABLE_UNPACK \
218 "Evas_Object *%s_%s_unpack(Evas_Object *o, Evas_Object *child);\n"
219
220 #define C_CODEGEN_PART_TABLE_CLEAR \
221 "Eina_Bool\n" \
222 "%s_%s_clear(Evas_Object *o, Eina_Bool clear)\n" \
223 "{\n" \
224 " return elm_layout_table_clear(o, \"%s\", clear);\n" \
225 "}\n\n"
226
227 #define H_CODEGEN_PART_TABLE_CLEAR \
228 "Eina_Bool %s_%s_clear(Evas_Object *o, Eina_Bool clear);\n"
229
230 #define C_CODEGEN_PROGRAM_EMIT \
231 "void\n" \
232 "%s_%s_emit(Evas_Object *o)\n" \
233 "{\n" \
234 " elm_layout_signal_emit(o, \"%s\", \"%s\");\n" \
235 "}\n\n"
236
237 #define H_CODEGEN_PROGRAM_EMIT \
238 "void %s_%s_emit(Evas_Object *o);\n"
239
240 #define C_CODEGEN_PROGRAM_CALLBACK_ADD \
241 "void\n" \
242 "%s_%s_callback_add(Evas_Object *o, Edje_Signal_Cb func, void *data)\n" \
243 "{\n" \
244 " elm_layout_signal_callback_add(o, \"%s\", \"%s\", func, data);\n" \
245 "}\n\n"
246
247 #define H_CODEGEN_PROGRAM_CALLBACK_ADD \
248 "void %s_%s_callback_add(Evas_Object *o, Edje_Signal_Cb func, " \
249 "void *data);\n"
250
251 #define C_CODEGEN_PROGRAM_CALLBACK_DEL \
252 "void\n" \
253 "%s_%s_callback_del(Evas_Object *o, Edje_Signal_Cb func)\n" \
254 "{\n" \
255 " elm_layout_signal_callback_del(o, \"%s\", \"%s\", func);\n" \
256 "}\n\n"
257
258 #define H_CODEGEN_PROGRAM_CALLBACK_DEL \
259 "void %s_%s_callback_del(Evas_Object *o, Edje_Signal_Cb func);\n"
260
261 const Ecore_Getopt optdesc =
262 {
263 "elm_codegen",
264 "%prog [options] <file.edj> <group> <source_file_name> <header_file_name>",
265 PACKAGE_VERSION,
266 "(C) 2012 - The Enlightenment Project",
267 "BSD",
268 "elm_codegen generates the boilerplate code to get and set the "
269 "parts of a group from a compiled (binary) edje "
270 "file avoiding common errors with typos.\n",
271 0,
272 {
273 ECORE_GETOPT_STORE_STR('p', "prefix", "The prefix for the " \
274 "generataed code."),
275 ECORE_GETOPT_LICENSE('L', "license"),
276 ECORE_GETOPT_COPYRIGHT('C', "copyright"),
277 ECORE_GETOPT_VERSION('V', "version"),
278 ECORE_GETOPT_HELP('h', "help"),
279 ECORE_GETOPT_SENTINEL
280 }
281 };
282
283 static char *
_header_standardize(const char * filename)284 _header_standardize(const char *filename)
285 {
286 char *str, *itr, *aux;
287
288 aux = strrchr(filename, '/');
289 str = itr = strdup(aux ? aux + 1 : filename);
290
291 for (; *itr; itr++)
292 if (*itr == '.')
293 *itr = '_';
294 else
295 *itr = toupper(*itr);
296
297 return str;
298 }
299
300 static Eina_Bool
_file_descriptors_open(const char * source,const char * header)301 _file_descriptors_open(const char *source, const char *header)
302 {
303 header_fd = fopen(header, "w");
304 if (!header_fd)
305 return EINA_FALSE;
306
307 source_fd = fopen(source, "w");
308 if (!source_fd)
309 goto err;
310
311 return EINA_TRUE;
312
313 err:
314 fclose(header_fd);
315 return EINA_FALSE;
316 }
317
318 static Eina_Bool
_file_descriptors_close(void)319 _file_descriptors_close(void)
320 {
321 Eina_Bool ret = EINA_FALSE;
322
323 if (!fclose(header_fd))
324 ret = EINA_TRUE;
325
326 if (!fclose(source_fd))
327 ret &= EINA_TRUE;
328
329 return ret;
330 }
331
332 static Eina_Bool
_headers_write(const char * filename)333 _headers_write(const char *filename)
334 {
335 char buf[512];
336 char *str;
337
338 str = _header_standardize(filename);
339 snprintf(buf, sizeof(buf), H_HEADER, str, str);
340 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
341 {
342 free(str);
343 return EINA_FALSE;
344 }
345
346 free(str);
347
348 snprintf(buf, sizeof(buf), C_HEADER, ecore_file_file_get(filename));
349 if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
350 return EINA_FALSE;
351
352 return EINA_TRUE;
353 }
354
355 static Eina_Bool
_footer_write(const char * filename)356 _footer_write(const char *filename)
357 {
358 char buf[512];
359 char *str;
360
361 str = _header_standardize(filename);
362 snprintf(buf, sizeof(buf), H_FOOTER, str);
363 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
364 {
365 free(str);
366 return EINA_FALSE;
367 }
368
369 free(str);
370
371 return EINA_TRUE;
372 }
373
374 static Eina_Bool
_theme_set_write(void)375 _theme_set_write(void)
376 {
377 Eina_Bool ret = EINA_FALSE;
378 char *str[3]; /* *klas, *style, *group */
379 char *token, *_group, buf[512];
380 int i;
381
382 str[0] = str[1] = str[2] = NULL;
383 if (strncmp(group, "elm/", 4)) return EINA_FALSE;
384
385 _group = strdup(group);
386 if (!_group) return EINA_FALSE;
387
388 strtok(_group, "/");
389 for (i = 0; i < 3; i++)
390 {
391 token = strtok(NULL, "/");
392 if (!token) break;
393
394 str[i] = token;
395 }
396
397 if (!str[0] || !str[1] || !str[2])
398 goto end;
399
400 snprintf(buf, sizeof(buf), C_CODEGEN_LAYOUT_ADD, prefix, file, str[0],
401 str[1], str[2]);
402 if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
403 goto end;
404
405 snprintf(buf, sizeof(buf), H_CODEGEN_LAYOUT_ADD, prefix);
406 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
407 goto end;
408
409 ret = EINA_TRUE;
410
411 end:
412 free(_group);
413 return ret;
414 }
415
416 static Eina_Bool
_part_write(const char * apiname,const char * partname,const char * description,Edje_Part_Type type)417 _part_write(const char *apiname, const char *partname, const char *description,
418 Edje_Part_Type type)
419 {
420 char buf[1024];
421
422 #define TEMPLATE_NAME(sufix) \
423 do { \
424 snprintf(buf, sizeof(buf), C_CODEGEN_PART_##sufix, prefix, \
425 apiname, partname); \
426 if (fwrite(buf, strlen(buf), 1, source_fd) != 1) \
427 goto err; \
428 snprintf(buf, sizeof(buf), H_CODEGEN_PART_##sufix, prefix, \
429 apiname); \
430 if (fwrite(buf, strlen(buf), 1, header_fd) != 1) \
431 goto err; \
432 } while(0)
433
434 if (description)
435 {
436 snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
437 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
438 goto err;
439 }
440
441 switch (type)
442 {
443 case EDJE_PART_TYPE_BOX:
444 TEMPLATE_NAME(BOX_APPEND);
445 TEMPLATE_NAME(BOX_PREPEND);
446 TEMPLATE_NAME(BOX_INSERT_BEFORE);
447 TEMPLATE_NAME(BOX_INSERT_AT);
448 TEMPLATE_NAME(BOX_REMOVE);
449 TEMPLATE_NAME(BOX_REMOVE_ALL);
450 break;
451
452 case EDJE_PART_TYPE_TABLE:
453 TEMPLATE_NAME(TABLE_PACK);
454 TEMPLATE_NAME(TABLE_UNPACK);
455 TEMPLATE_NAME(TABLE_CLEAR);
456 break;
457
458 case EDJE_PART_TYPE_TEXT:
459 TEMPLATE_NAME(TEXT_SET);
460 TEMPLATE_NAME(TEXT_GET);
461 break;
462
463 default:
464 TEMPLATE_NAME(CONTENT_SET);
465 TEMPLATE_NAME(CONTENT_UNSET);
466 TEMPLATE_NAME(CONTENT_GET);
467 break;
468 }
469
470 #undef TEMPLATE_NAME
471
472 return EINA_TRUE;
473
474 err:
475 ERR("Could not write the part: %s", partname);
476 return EINA_FALSE;
477 }
478
479 static inline Eina_Bool
_c_id_allowed(char c)480 _c_id_allowed(char c)
481 {
482 if ((c >= '0') && (c <= '9')) return EINA_TRUE;
483 if ((c >= 'a') && (c <= 'z')) return EINA_TRUE;
484 if ((c >= 'A') && (c <= 'Z')) return EINA_TRUE;
485
486 return EINA_FALSE;
487 }
488
489 static char *
_api_name_fix(const char * orig)490 _api_name_fix(const char *orig)
491 {
492 char *d, *d_end, buf[256];
493 const char *s;
494
495 if (!orig) return NULL;
496
497 s = orig;
498 d = buf;
499 d_end = d + sizeof(buf) - 1;
500
501 for (; (*s != '\0') && (d < d_end); s++, d++)
502 if (_c_id_allowed(*s)) *d = *s;
503 else *d = '_';
504 *d = '\0';
505
506 return strdup(buf);
507 }
508
509 static char *
_part_api_name_get(Evas_Object * ed,const char * program)510 _part_api_name_get(Evas_Object *ed, const char *program)
511 {
512 const char *orig;
513 char *fix;
514
515 orig = edje_edit_part_api_name_get(ed, program);
516 fix = _api_name_fix(orig);
517 edje_edit_string_free(orig);
518
519 return fix;
520 }
521
522 static Eina_Bool
_parts_parse(Evas_Object * ed)523 _parts_parse(Evas_Object *ed)
524 {
525 Eina_List *parts, *l;
526 const char *name, *description;
527 char *apiname;
528 Edje_Part_Type type;
529 Eina_Bool ret = EINA_TRUE;
530
531 parts = edje_edit_parts_list_get(ed);
532 EINA_LIST_FOREACH(parts, l, name)
533 {
534 if (!(apiname = _part_api_name_get(ed, name)))
535 {
536 DBG("filter out part '%s': not API.", name);
537 continue;
538 }
539
540 type = edje_edit_part_type_get(ed, name);
541 if ((type != EDJE_PART_TYPE_SWALLOW) &&
542 (type != EDJE_PART_TYPE_TEXT) &&
543 (type != EDJE_PART_TYPE_BOX) &&
544 (type != EDJE_PART_TYPE_TABLE))
545 {
546 free(apiname);
547 continue;
548 }
549
550 description = edje_edit_part_api_description_get(ed, name);
551 if (!_part_write(apiname, name, description, type))
552 {
553 ret = EINA_FALSE;
554 edje_edit_string_free(description);
555 free(apiname);
556 break;
557 }
558
559 edje_edit_string_free(description);
560 free(apiname);
561 }
562
563 edje_edit_string_list_free(parts);
564 return ret;
565 }
566
567 static Eina_Bool
_program_emit_write(const char * apiname,const char * source,const char * sig,const char * description)568 _program_emit_write(const char *apiname, const char *source, const char *sig,
569 const char *description)
570 {
571 char buf[512];
572
573 snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_EMIT, prefix,
574 apiname, sig, source);
575 if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
576 goto err;
577
578 if (description)
579 {
580 snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
581 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
582 goto err;
583 }
584
585 snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_EMIT, prefix,
586 apiname);
587 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
588 goto err;
589
590 return EINA_TRUE;
591
592 err:
593 ERR("Could not write the program: %s", apiname);
594 return EINA_FALSE;
595 }
596
597 static Eina_Bool
_program_add_write(const char * apiname,const char * source,const char * sig,const char * description)598 _program_add_write(const char *apiname, const char *source, const char *sig,
599 const char *description)
600 {
601 char buf[512];
602
603 snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_CALLBACK_ADD, prefix,
604 apiname, sig, source);
605 if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
606 goto err;
607
608 snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_CALLBACK_DEL, prefix,
609 apiname, sig, source);
610 if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
611 goto err;
612
613 if (description)
614 {
615 snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
616 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
617 goto err;
618 }
619
620 snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_CALLBACK_ADD, prefix,
621 apiname);
622 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
623 goto err;
624
625 snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_CALLBACK_DEL, prefix,
626 apiname);
627 if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
628 goto err;
629
630 return EINA_TRUE;
631
632 err:
633 ERR("Could not write the program [action]: %s", apiname);
634 return EINA_FALSE;
635 }
636
637 static char *
_program_api_name_get(Evas_Object * ed,const char * program)638 _program_api_name_get(Evas_Object *ed, const char *program)
639 {
640 const char *orig;
641 char *fix;
642
643 orig = edje_edit_program_api_name_get(ed, program);
644 fix = _api_name_fix(orig);
645 edje_edit_string_free(orig);
646
647 return fix;
648 }
649
650 static Eina_Bool
_programs_parse(Evas_Object * ed)651 _programs_parse(Evas_Object *ed)
652 {
653 Eina_Bool ret = EINA_TRUE;
654 Eina_List *programs, *l;
655 const char *name, *source = NULL, *sig = NULL, *description;
656 char *apiname;
657 Edje_Action_Type type;
658
659 programs = edje_edit_programs_list_get(ed);
660 EINA_LIST_FOREACH(programs, l, name)
661 {
662 if (!(apiname = _program_api_name_get(ed, name)))
663 {
664 DBG("filter out program '%s': not API.", name);
665 continue;
666 }
667
668 description = edje_edit_program_api_description_get(ed, name);
669 type = edje_edit_program_action_get(ed, name);
670 if (type == EDJE_ACTION_TYPE_SIGNAL_EMIT)
671 {
672 const char *str, *str2;
673 str = edje_edit_program_state_get(ed, name);
674 str2 = edje_edit_program_state2_get(ed, name);
675
676 if (!_program_add_write(apiname, str2, str, description))
677 {
678 ret = EINA_FALSE;
679 edje_edit_string_free(str);
680 edje_edit_string_free(str2);
681 break;
682 }
683
684 edje_edit_string_free(str);
685 edje_edit_string_free(str2);
686 }
687
688 sig = edje_edit_program_signal_get(ed, name);
689 if (!sig) sig = eina_stringshare_add("");
690
691 source = edje_edit_program_source_get(ed, name);
692 if (!source) source = eina_stringshare_add("");
693
694 if (strlen (sig))
695 {
696 if (!_program_emit_write(apiname, source, sig, description))
697 {
698 ret = EINA_FALSE;
699 break;
700 }
701 }
702
703 edje_edit_string_free(description);
704 description = NULL;
705 edje_edit_string_free(sig);
706 sig = NULL;
707 edje_edit_string_free(source);
708 source = NULL;
709 free(apiname);
710 apiname = NULL;
711 }
712
713 edje_edit_string_list_free(programs);
714 if (!ret)
715 {
716 edje_edit_string_free(description);
717 edje_edit_string_free(sig);
718 edje_edit_string_free(source);
719 free(apiname);
720 }
721
722 return ret;
723 }
724
725 static Eina_Bool
_parse(void)726 _parse(void)
727 {
728 Evas_Object *ed;
729 Eina_Bool ret;
730
731 ed = edje_edit_object_add(ecore_evas_get(ee));
732 if (!edje_object_file_set(ed, file, group))
733 {
734 Edje_Load_Error err = edje_object_load_error_get(ed);
735 const char *errmsg = edje_load_error_str(err);
736 ERR("could not load group '%s' from file '%s': %s",
737 group, file, errmsg);
738 evas_object_del(ed);
739 return EINA_FALSE;
740 }
741
742 ret = _parts_parse(ed) && _programs_parse(ed);
743
744 evas_object_del(ed);
745 return ret;
746 }
747
748 int
main(int argc,char * argv[])749 main(int argc, char *argv[])
750 {
751 Eina_Bool quit_option = EINA_FALSE;
752 char *source = NULL, *header = NULL;
753 int arg_index, ret = 0;
754 Ecore_Getopt_Value values[] = {
755 ECORE_GETOPT_VALUE_STR(prefix),
756 ECORE_GETOPT_VALUE_BOOL(quit_option),
757 ECORE_GETOPT_VALUE_BOOL(quit_option),
758 ECORE_GETOPT_VALUE_BOOL(quit_option),
759 ECORE_GETOPT_VALUE_BOOL(quit_option),
760 ECORE_GETOPT_VALUE_NONE
761 };
762
763 setlocale(LC_NUMERIC, "C");
764
765 eina_init();
766 ecore_init();
767 ecore_evas_init();
768 edje_init();
769
770 if (argc < 2)
771 {
772 fprintf(stderr, "Missing action. See '--help or -h'.\n");
773 ret = 1;
774 goto error_log;
775 }
776
777 _log_dom = eina_log_domain_register("elementary_codegen", EINA_COLOR_YELLOW);
778 if (_log_dom < 0)
779 {
780 EINA_LOG_CRIT("could not register log domain 'elementary_codegen'");
781 ret = 1;
782 goto error_log;
783 }
784
785 arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
786 if (arg_index < 0)
787 {
788 ERR("could not parse arguments.");
789 ret = 1;
790 goto error_getopt;
791 }
792 else if (quit_option) goto error_getopt;
793 else if (arg_index != argc - 4)
794 {
795 fprintf(stderr, "Incorrect number of parameters. Requires " \
796 "fours arguments, an edje, the group, " \
797 "the source output (foo.c) and the header(foo.h).\n" \
798 "See %s --help\n", argv[0]);
799 ret = 1;
800 goto error_getopt;
801 }
802
803 file = argv[arg_index++];
804
805 // check if the file is accessible
806 if (access(file, R_OK) == -1)
807 {
808 ERR("File '%s' not accessible, error %d (%s).\n",
809 file, errno, strerror(errno));
810 ret = 1;
811 goto error_getopt;
812 }
813
814 group = argv[arg_index++];
815 source = argv[arg_index++];
816 header = argv[arg_index++];
817
818 if (!edje_file_group_exists(file, group))
819 {
820 ERR("The group %s not exists", group);
821 ret = 2;
822 goto error_getopt;
823 }
824
825 ee = ecore_evas_buffer_new(1, 1);
826 if (!ee)
827 {
828 ERR("could not create ecore_evas_buffer");
829 ret = 3;
830 goto error_getopt;
831 }
832
833 if (!_file_descriptors_open(source, header))
834 {
835 ERR("Could not create the source files, error %d (%s)",
836 errno, strerror(errno));
837 ret = 4;
838 goto error_getopt;
839 }
840
841 if (!_headers_write(header))
842 {
843 ERR("Could not write the header, error %d (%s)",
844 errno, strerror(errno));
845 ret = 5;
846 goto error_getopt;
847 }
848
849 if (!_theme_set_write())
850 WRN("Theme set getter/setter not created. Group name: %s invalid.", group);
851
852 if (!_parse())
853 {
854 ERR("Could not parsing the EDJE");
855 ret = 6;
856 goto error_getopt;
857 }
858
859 if (!_footer_write(header))
860 {
861 ERR("Could not write the footer, error %d (%s)",
862 errno, strerror(errno));
863 ret = 7;
864 goto error_getopt;
865 }
866
867 if (!_file_descriptors_close())
868 {
869 ERR("Could not close the source files, error %d (%s)",
870 errno, strerror(errno));
871 ret = 8;
872 }
873
874 error_getopt:
875 if (ee)
876 ecore_evas_free(ee);
877
878 error_log:
879 edje_shutdown();
880 ecore_evas_shutdown();
881 ecore_shutdown();
882 eina_log_domain_unregister(_log_dom);
883 eina_shutdown();
884
885 if (ret > 4)
886 {
887 unlink(header);
888 unlink(source);
889 }
890
891 return ret;
892 }
893