efl

Форк
0
/
edje_codegen.c 
1241 строка · 40.8 Кб
1
#ifdef HAVE_CONFIG_H
2
# include "config.h"
3
#endif
4

5
#include <stdio.h>
6
#include <ctype.h>
7
#include <fcntl.h>
8
#include <locale.h>
9
#include <unistd.h>
10
#include <errno.h>
11

12
#include <Eina.h>
13
#include <Ecore.h>
14
#include <Ecore_Getopt.h>
15
#include <Ecore_Evas.h>
16
#include <Ecore_File.h>
17

18
#include "Edje.h"
19
#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT 1
20
#include "Edje_Edit.h"
21

22
static int _log_dom;
23
#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
24
#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
25

26
static Ecore_Evas *ee = NULL;
27
static char *file = NULL;
28
static char *group = NULL;
29
static char *prefix = NULL;
30
static FILE *source_fd = NULL;
31
static FILE *header_fd = NULL;
32
static Eina_List *externals = NULL;
33

34
#define H_HEADER          \
35
  "#ifndef _%s\n"         \
36
  "#define _%s\n\n"       \
37
  "#include <Edje.h>\n"   \
38
  "#include <Evas.h>\n\n" \
39
  "#include <stdlib.h>\n\n"
40

41
#define H_FOOTER \
42
  "\n#endif /* _%s */\n"
43

44
#define C_HEADER \
45
  "#include \"%s\"\n\n"
46

47
#define C_CODEGEN_OBJECT_ADD                           \
48
  "Evas_Object *\n"                                    \
49
  "%s_object_add(Evas *e, const char *file)\n"         \
50
  "{\n"                                                \
51
  "   Evas_Object *o;\n\n"                             \
52
  "   o = edje_object_add(e);\n"                       \
53
  "   if (!o) return NULL;\n\n"                        \
54
  "   if (file)\n"                                     \
55
  "      edje_object_file_set(o, file, \"%s\");\n"     \
56
  "   else\n"                                          \
57
  "      edje_object_file_set(o, \"%s\", \"%s\");\n\n" \
58
  "   return o;\n"                                     \
59
  "}\n\n"
60

61
#define H_CODEGEN_OBJECT_ADD                                           \
62
  "/**\n * @brief Creates the Edje object and set the edj file\n"      \
63
  " * @param e The surface\n"                                          \
64
  " * @param file The path to edj, if NULL it's used the path given\n" \
65
  " *             to edje_codegen\n */\n"                              \
66
  "Evas_Object *%s_object_add(Evas *e, const char *file);\n\n"
67

68
#define C_CODEGEN_DRAG_SET(option)                                                              \
69
  "Eina_Bool\n"                                                                                 \
70
  "%s_%s_drag_" #option "_set(Evas_Object *o, double dx, double dy)\n"                          \
71
                        "{\n"                                                                   \
72
                        "   return edje_object_part_drag_" #option "_set(o, \"%s\", dx, dy);\n" \
73
                                                                   "}\n\n"
74

75
#define H_CODEGEN_DRAG_SET(option) \
76
  "Eina_Bool %s_%s_drag_" #option "_set(Evas_Object *o, double dx, double dy);\n"
77

78
#define C_CODEGEN_DRAG_GET(option)                                                              \
79
  "Eina_Bool\n"                                                                                 \
80
  "%s_%s_drag_" #option "_get(Evas_Object *o, double *dx, double *dy)\n"                        \
81
                        "{\n"                                                                   \
82
                        "   return edje_object_part_drag_" #option "_get(o, \"%s\", dx, dy);\n" \
83
                                                                   "}\n\n"
84

85
#define H_CODEGEN_DRAG_GET(option)                                  \
86
  "Eina_Bool %s_%s_drag_" #option "_get(Evas_Object *o, double *dx" \
87
                                  ", double *dy);\n"
88

89
#define C_CODEGEN_DRAG_ACTION(option)                                                       \
90
  "Eina_Bool\n"                                                                             \
91
  "%s_%s_drag_" #option "(Evas_Object *o, double dx, double dy)\n"                          \
92
                        "{\n"                                                               \
93
                        "   return edje_object_part_drag_" #option "(o, \"%s\", dx, dy);\n" \
94
                                                                   "}\n\n"
95

96
#define H_CODEGEN_DRAG_ACTION(option) \
97
  "Eina_Bool %s_%s_drag_" #option "(Evas_Object *o, double dx, double dy);\n"
98

99
#define C_CODEGEN_DRAG_DIR_GET                            \
100
  "Edje_Drag_Dir\n"                                       \
101
  "%s_%s_drag_dir_get(Evas_Object *o)\n"                  \
102
  "{\n"                                                   \
103
  "   return edje_object_part_drag_dir_get(o, \"%s\");\n" \
104
  "}\n\n"
105

106
#define H_CODEGEN_DRAG_DIR_GET \
107
  "Edje_Drag_Dir %s_%s_drag_dir_get(Evas_Object *o);\n"
108

109
#define C_CODEGEN_PART_TEXT_SET                       \
110
  "void\n"                                            \
111
  "%s_%s_set(Evas_Object *o, const char *value)\n"    \
112
  "{\n"                                               \
113
  "   edje_object_part_text_set(o, \"%s\", value);\n" \
114
  "}\n\n"
115

116
#define H_CODEGEN_PART_TEXT_SET \
117
  "void %s_%s_set(Evas_Object *o, const char *value);\n"
118

119
#define C_CODEGEN_PART_SWALLOW_SET                   \
120
  "void\n"                                           \
121
  "%s_%s_set(Evas_Object *o, Evas_Object *value)\n"  \
122
  "{\n"                                              \
123
  "   edje_object_part_swallow(o, \"%s\", value);\n" \
124
  "}\n\n"
125

126
#define H_CODEGEN_PART_SWALLOW_SET \
127
  "void %s_%s_set(Evas_Object *o, Evas_Object *value);\n"
128

129
#define C_CODEGEN_PART_TEXT_GET                       \
130
  "const char *\n"                                    \
131
  "%s_%s_get(const Evas_Object *o)\n"                 \
132
  "{\n"                                               \
133
  "   return edje_object_part_text_get(o, \"%s\");\n" \
134
  "}\n\n"
135

136
#define H_CODEGEN_PART_TEXT_GET \
137
  "const char *%s_%s_get(const Evas_Object *o);\n"
138

139
#define C_CODEGEN_PART_SWALLOW_GET                       \
140
  "Evas_Object *\n"                                      \
141
  "%s_%s_get(const Evas_Object *o)\n"                    \
142
  "{\n"                                                  \
143
  "   return edje_object_part_swallow_get(o, \"%s\");\n" \
144
  "}\n\n"
145

146
#define H_CODEGEN_PART_SWALLOW_GET \
147
  "Evas_Object *%s_%s_get(const Evas_Object *o);\n"
148

149
#define C_CODEGEN_PART_BOX_APPEND                              \
150
  "Eina_Bool\n"                                                \
151
  "%s_%s_append(Evas_Object *o, Evas_Object *child)\n"         \
152
  "{\n"                                                        \
153
  "   return edje_object_part_box_append(o, \"%s\", child);\n" \
154
  "}\n\n"
155

156
#define H_CODEGEN_PART_BOX_APPEND \
157
  "Eina_Bool %s_%s_append(Evas_Object *o, Evas_Object *child);\n"
158

159
#define C_CODEGEN_PART_BOX_PREPEND                              \
160
  "Eina_Bool\n"                                                 \
161
  "%s_%s_prepend(Evas_Object *o, Evas_Object *child)\n"         \
162
  "{\n"                                                         \
163
  "   return edje_object_part_box_prepend(o, \"%s\", child);\n" \
164
  "}\n\n"
165

166
#define H_CODEGEN_PART_BOX_PREPEND \
167
  "Eina_Bool %s_%s_prepend(Evas_Object *o, Evas_Object *child);\n"
168

169
#define C_CODEGEN_PART_BOX_INSERT_BEFORE                     \
170
  "Eina_Bool\n"                                              \
171
  "%s_%s_insert_before(Evas_Object *o, Evas_Object *child, " \
172
  "const Evas_Object *reference)\n"                          \
173
  "{\n"                                                      \
174
  "   return edje_object_part_box_insert_before(o, \"%s\", " \
175
  "child, reference);\n"                                     \
176
  "}\n\n"
177

178
#define H_CODEGEN_PART_BOX_INSERT_BEFORE                               \
179
  "Eina_Bool %s_%s_insert_before(Evas_Object *o, Evas_Object *child, " \
180
  "const Evas_Object *reference);\n"
181

182
#define C_CODEGEN_PART_BOX_INSERT_AT                                        \
183
  "Eina_Bool\n"                                                             \
184
  "%s_%s_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos)\n" \
185
  "{\n"                                                                     \
186
  "   return edje_object_part_box_insert_at(o, \"%s\", child, pos);\n"      \
187
  "}\n\n"
188

189
#define H_CODEGEN_PART_BOX_INSERT_AT                               \
190
  "Eina_Bool %s_%s_insert_at(Evas_Object *o, Evas_Object *child, " \
191
  "unsigned int pos);\n"
192

193
#define C_CODEGEN_PART_BOX_REMOVE                              \
194
  "Evas_Object *\n"                                            \
195
  "%s_%s_remove(Evas_Object *o, Evas_Object *child)\n"         \
196
  "{\n"                                                        \
197
  "   return edje_object_part_box_remove(o, \"%s\", child);\n" \
198
  "}\n\n"
199

200
#define H_CODEGEN_PART_BOX_REMOVE \
201
  "Evas_Object *%s_%s_remove(Evas_Object *o, Evas_Object *child);\n"
202

203
#define C_CODEGEN_PART_BOX_REMOVE_AT                            \
204
  "Evas_Object *\n"                                             \
205
  "%s_%s_remove_at(Evas_Object *o, unsigned int pos)\n"         \
206
  "{\n"                                                         \
207
  "   return edje_object_part_box_remove_at(o, \"%s\", pos);\n" \
208
  "}\n\n"
209

210
#define H_CODEGEN_PART_BOX_REMOVE_AT \
211
  "Evas_Object *%s_%s_remove_at(Evas_Object *o, unsigned int pos);\n"
212

213
#define C_CODEGEN_PART_BOX_REMOVE_ALL                              \
214
  "Eina_Bool\n"                                                    \
215
  "%s_%s_remove_all(Evas_Object *o, Eina_Bool clear)\n"            \
216
  "{\n"                                                            \
217
  "   return edje_object_part_box_remove_all(o, \"%s\", clear);\n" \
218
  "}\n\n"
219

220
#define H_CODEGEN_PART_BOX_REMOVE_ALL \
221
  "Eina_Bool %s_%s_remove_all(Evas_Object *o, Eina_Bool clear);\n"
222

223
#define C_CODEGEN_PART_TABLE_CHILD_GET                                    \
224
  "Evas_Object *\n"                                                       \
225
  "%s_%s_child_get(Evas_Object *o, unsigned int col, unsigned int row)\n" \
226
  "{\n"                                                                   \
227
  "   return edje_object_part_table_child_get(o, \"%s\", col, row);\n"    \
228
  "}\n\n"
229

230
#define H_CODEGEN_PART_TABLE_CHILD_GET                               \
231
  "Evas_Object * %s_%s_child_get(Evas_Object *o, unsigned int col, " \
232
  "unsigned int row);\n"
233

234
#define C_CODEGEN_PART_TABLE_PACK                                         \
235
  "Eina_Bool\n"                                                           \
236
  "%s_%s_pack(Evas_Object *o, Evas_Object *child, unsigned short col, "   \
237
  "unsigned short row, unsigned short colspan, unsigned short rowspan)\n" \
238
  "{\n"                                                                   \
239
  "   return edje_object_part_table_pack(o, \"%s\", child, col, row, "    \
240
  "colspan, rowspan);\n"                                                  \
241
  "}\n\n"
242

243
#define H_CODEGEN_PART_TABLE_PACK                             \
244
  "Eina_Bool %s_%s_pack(Evas_Object *o, Evas_Object *child, " \
245
  "unsigned short col, unsigned short row, unsigned short "   \
246
  "colspan, unsigned short rowspan);\n"
247

248
#define C_CODEGEN_PART_TABLE_UNPACK                              \
249
  "Eina_Bool\n"                                                  \
250
  "%s_%s_unpack(Evas_Object *o, Evas_Object *child)\n"           \
251
  "{\n"                                                          \
252
  "   return edje_object_part_table_unpack(o, \"%s\", child);\n" \
253
  "}\n\n"
254

255
#define H_CODEGEN_PART_TABLE_UNPACK \
256
  "Eina_Bool %s_%s_unpack(Evas_Object *o, Evas_Object *child);\n"
257

258
#define C_CODEGEN_PART_TABLE_CLEAR                              \
259
  "Eina_Bool\n"                                                 \
260
  "%s_%s_clear(Evas_Object *o, Eina_Bool clear)\n"              \
261
  "{\n"                                                         \
262
  "   return edje_object_part_table_clear(o, \"%s\", clear);\n" \
263
  "}\n\n"
264

265
#define H_CODEGEN_PART_TABLE_CLEAR \
266
  "Eina_Bool %s_%s_clear(Evas_Object *o, Eina_Bool clear);\n"
267

268
#define C_CODEGEN_PART_TABLE_COL_ROW_SIZE_GET                       \
269
  "Eina_Bool\n"                                                     \
270
  "%s_%s_col_row_size_get(Evas_Object *o, int  *cols, int *rows)\n" \
271
  "{\n"                                                             \
272
  "   return edje_object_part_table_col_row_size_get(o, \"%s\", "   \
273
  "cols, rows);\n"                                                  \
274
  "}\n\n"
275

276
#define H_CODEGEN_PART_TABLE_COL_ROW_SIZE_GET \
277
  "Eina_Bool %s_%s_col_row_size_get(Evas_Object *o, int *cols, int *rows);\n"
278

279
#define C_CODEGEN_PART_EXTERNAL_PARAM_SET(type, param_type, field)                                                                                        \
280
  "Eina_Bool\n"                                                                                                                                           \
281
  "%s_%s_%s_set(Evas_Object *o, "type "value)\n"                                                                                                          \
282
                                      "{\n"                                                                                                               \
283
                                      "   Edje_External_Param param;\n\n"                                                                                 \
284
                                      "   param.name = \"%s\";\n"                                                                                         \
285
                                      "   param.type = "param_type ";\n"                                                                                  \
286
                                                                   "   param."field " = value;\n"                                                         \
287
                                                                                    "   return edje_object_part_external_param_set(o, \"%s\", &param);\n" \
288
                                                                                    "}\n\n"
289

290
#define H_CODEGEN_PART_EXTERNAL_PARAM_SET(type) \
291
  "Eina_Bool %s_%s_%s_set(Evas_Object *o, "type "value);\n"
292

293
#define C_CODEGEN_PART_EXTERNAL_PARAM_GET(type, param_type, field)                                                                     \
294
  "Eina_Bool\n"                                                                                                                        \
295
  "%s_%s_%s_get(Evas_Object *o, "type "*value)\n"                                                                                      \
296
                                      "{\n"                                                                                            \
297
                                      "   if (!value) return EINA_FALSE;\n\n"                                                          \
298
                                      "   Edje_External_Param param;\n\n"                                                              \
299
                                      "   param.name = \"%s\";\n"                                                                      \
300
                                      "   param.type = "param_type ";\n"                                                               \
301
                                                                   "   if (!edje_object_part_external_param_get(o, \"%s\", &param))\n" \
302
                                                                   "     return EINA_FALSE;\n\n"                                       \
303
                                                                   "   *value = param."field ";\n"                                     \
304
                                                                                             "   return EINA_TRUE;\n"                  \
305
                                                                                             "}\n\n"
306

307
#define H_CODEGEN_PART_EXTERNAL_PARAM_GET(type) \
308
  "Eina_Bool %s_%s_%s_get(Evas_Object *o, "type "*value);\n"
309

310
#define C_CODEGEN_PROGRAM_EMIT                       \
311
  "void\n"                                           \
312
  "%s_%s_emit(Evas_Object *o)\n"                     \
313
  "{\n"                                              \
314
  "   edje_object_signal_emit(o, \"%s\", \"%s\");\n" \
315
  "}\n\n"
316

317
#define H_CODEGEN_PROGRAM_EMIT \
318
  "void %s_%s_emit(Evas_Object *o);\n"
319

320
#define C_CODEGEN_PROGRAM_CALLBACK_ADD                                    \
321
  "void\n"                                                                \
322
  "%s_%s_callback_add(Evas_Object *o, Edje_Signal_Cb func, void *data)\n" \
323
  "{\n"                                                                   \
324
  "   edje_object_signal_callback_add(o, \"%s\", \"%s\", func, data);\n"  \
325
  "}\n\n"
326

327
#define H_CODEGEN_PROGRAM_CALLBACK_ADD                            \
328
  "void %s_%s_callback_add(Evas_Object *o, Edje_Signal_Cb func, " \
329
  "void *data);\n"
330

331
#define C_CODEGEN_PROGRAM_CALLBACK_DEL                                         \
332
  "void\n"                                                                     \
333
  "%s_%s_callback_del_full(Evas_Object *o, Edje_Signal_Cb func, void *data)\n" \
334
  "{\n"                                                                        \
335
  "   edje_object_signal_callback_del_full(o, \"%s\", \"%s\", func, data);\n"  \
336
  "}\n\n"
337

338
#define H_CODEGEN_PROGRAM_CALLBACK_DEL                                 \
339
  "void %s_%s_callback_del_full(Evas_Object *o, Edje_Signal_Cb func, " \
340
  "void *data);\n"
341

342
typedef struct _Part_External_Info Part_External_Info;
343
struct _Part_External_Info
344
{
345
   const char *description, *name, *source;
346
   char       *apiname;
347
   Eina_Bool   draggable;
348
};
349

350
const Ecore_Getopt optdesc = {
351
   "edje_codegen",
352
   "%prog [options] <file.edj> <group> <source_file_name> <header_file_name>",
353
   PACKAGE_VERSION,
354
   "(C) 2012 - The Enlightenment Project",
355
   "BSD",
356
   "Edje generates the boilerplate code to get and set the "
357
   "parts of a group from a compiled (binary) edje "
358
   "file avoiding common errors with typos.\n",
359
   0,
360
   {
361
      ECORE_GETOPT_STORE_STR('p', "prefix", "The prefix for the " \
362
                                            "generataed code."),
363
      ECORE_GETOPT_LICENSE('L', "license"),
364
      ECORE_GETOPT_COPYRIGHT('C', "copyright"),
365
      ECORE_GETOPT_VERSION('V', "version"),
366
      ECORE_GETOPT_HELP('h', "help"),
367
      ECORE_GETOPT_SENTINEL
368
   }
369
};
370

371
static char *
372
_standardizes_header(const char *filename)
373
{
374
   char *str, *itr, *aux;
375

376
   aux = strrchr(filename, '/');
377
   str = itr = strdup(aux ? aux + 1 : filename);
378

379
   for (; *itr; itr++)
380
     if (*itr == '.')
381
       *itr = '_';
382
     else
383
       *itr = toupper(*itr);
384

385
   return str;
386
}
387

388
static Eina_Bool
389
_open_file_descriptors(const char *source, const char *header)
390
{
391
   header_fd = fopen(header, "wb");
392
   if (!header_fd)
393
     return EINA_FALSE;
394

395
   source_fd = fopen(source, "wb");
396
   if (!source_fd)
397
     goto err;
398

399
   return EINA_TRUE;
400

401
err:
402
   fclose(header_fd);
403
   return EINA_FALSE;
404
}
405

406
static Eina_Bool
407
_close_file_descriptors(void)
408
{
409
   Eina_Bool ret = EINA_FALSE;
410

411
   if (!fclose(header_fd))
412
     ret = EINA_TRUE;
413

414
   if (!fclose(source_fd))
415
     ret &= EINA_TRUE;
416

417
   return ret;
418
}
419

420
static Eina_Bool
421
_write_headers(const char *filename)
422
{
423
   char buf[512];
424
   char *str;
425

426
   str = _standardizes_header(filename);
427
   snprintf(buf, sizeof(buf), H_HEADER, str, str);
428
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
429
     {
430
        free(str);
431
        return EINA_FALSE;
432
     }
433

434
   free(str);
435

436
   snprintf(buf, sizeof(buf), C_HEADER, ecore_file_file_get(filename));
437
   if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
438
     return EINA_FALSE;
439

440
   return EINA_TRUE;
441
}
442

443
static Eina_Bool
444
_write_footer(const char *filename)
445
{
446
   char buf[512];
447
   char *str;
448

449
   str = _standardizes_header(filename);
450
   snprintf(buf, sizeof(buf), H_FOOTER, str);
451
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
452
     {
453
        free(str);
454
        return EINA_FALSE;
455
     }
456

457
   free(str);
458

459
   return EINA_TRUE;
460
}
461

462
static Eina_Bool
463
_write_object_get(void)
464
{
465
   char buf[512];
466

467
   snprintf(buf, sizeof(buf), H_CODEGEN_OBJECT_ADD, prefix);
468
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
469
     return EINA_FALSE;
470

471
   snprintf(buf, sizeof(buf), C_CODEGEN_OBJECT_ADD, prefix, group, file, group);
472
   if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
473
     return EINA_FALSE;
474

475
   return EINA_TRUE;
476
}
477

478
static Eina_Bool
479
_write_part_draggable(const char *apiname, const char *partname)
480
{
481
   char buf[1024];
482

483
#define TEMPLATE_DRAGGABLE(sufix, option)                    \
484
  do {                                                       \
485
       const char *template;                                 \
486
       template = C_CODEGEN_DRAG_##sufix(option);            \
487
       snprintf(buf, sizeof(buf), template, prefix, apiname, \
488
                partname);                                   \
489
       if (fwrite(buf, strlen(buf), 1, source_fd) != 1)      \
490
         return EINA_FALSE;                                  \
491
       template = H_CODEGEN_DRAG_##sufix(option);            \
492
       snprintf(buf, sizeof(buf), template, prefix,          \
493
                apiname);                                    \
494
       if (fwrite(buf, strlen(buf), 1, header_fd) != 1)      \
495
         return EINA_FALSE;                                  \
496
    } while (0)
497

498
   TEMPLATE_DRAGGABLE(SET, value);
499
   TEMPLATE_DRAGGABLE(GET, value);
500
   TEMPLATE_DRAGGABLE(SET, size);
501
   TEMPLATE_DRAGGABLE(GET, size);
502
   TEMPLATE_DRAGGABLE(SET, page);
503
   TEMPLATE_DRAGGABLE(GET, page);
504
   TEMPLATE_DRAGGABLE(SET, step);
505
   TEMPLATE_DRAGGABLE(GET, step);
506
   TEMPLATE_DRAGGABLE(ACTION, page);
507
   TEMPLATE_DRAGGABLE(ACTION, step);
508

509
#undef TEMPLATE_DRAGGABLE
510

511
   snprintf(buf, sizeof(buf), C_CODEGEN_DRAG_DIR_GET, prefix,
512
            apiname, partname);
513
   if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
514
     return EINA_FALSE;
515
   snprintf(buf, sizeof(buf), H_CODEGEN_DRAG_DIR_GET, prefix, apiname);
516
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
517
     return EINA_FALSE;
518

519
   return EINA_TRUE;
520
}
521

522
static Eina_Bool
523
_write_part_external_param(const Part_External_Info *info,
524
                           const Edje_External_Param_Info *param)
525
{
526
   const char *template;
527
   char buf[1024];
528

529
#define WRITE_TEMPLATE(type, param_type, field)                               \
530
  do {                                                                        \
531
       template = C_CODEGEN_PART_EXTERNAL_PARAM_SET(type, param_type, field); \
532
       snprintf(buf, sizeof(buf), template, info->apiname, info->name,        \
533
                param->name, param->name, info->name);                        \
534
       if (fwrite(buf, strlen(buf), 1, source_fd) != 1)                       \
535
         return EINA_FALSE;                                                   \
536
       template = H_CODEGEN_PART_EXTERNAL_PARAM_SET(type);                    \
537
       snprintf(buf, sizeof(buf), template, info->apiname, info->name,        \
538
                param->name);                                                 \
539
       if (fwrite(buf, strlen(buf), 1, header_fd) != 1)                       \
540
         return EINA_FALSE;                                                   \
541
       template =                                                             \
542
         C_CODEGEN_PART_EXTERNAL_PARAM_GET(type, param_type, field);          \
543
       snprintf(buf, sizeof(buf), template, info->apiname, info->name,        \
544
                param->name, param->name, info->name);                        \
545
       if (fwrite(buf, strlen(buf), 1, source_fd) != 1)                       \
546
         return EINA_FALSE;                                                   \
547
       template = H_CODEGEN_PART_EXTERNAL_PARAM_GET(type);                    \
548
       snprintf(buf, sizeof(buf), template, info->apiname, info->name,        \
549
                param->name);                                                 \
550
       if (fwrite(buf, strlen(buf), 1, header_fd) != 1)                       \
551
         return EINA_FALSE;                                                   \
552
    } while (0)
553

554
   switch (param->type)
555
     {
556
      case EDJE_EXTERNAL_PARAM_TYPE_INT:
557
        WRITE_TEMPLATE("int ", "EDJE_EXTERNAL_PARAM_TYPE_INT", "i");
558
        break;
559

560
      case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
561
        WRITE_TEMPLATE("double ", "EDJE_EXTERNAL_PARAM_TYPE_DOUBLE", "d");
562
        break;
563

564
      case EDJE_EXTERNAL_PARAM_TYPE_STRING:
565
        WRITE_TEMPLATE("const char *", "EDJE_EXTERNAL_PARAM_TYPE_STRING", "s");
566
        break;
567

568
      case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
569
        WRITE_TEMPLATE("Eina_Bool ", "EDJE_EXTERNAL_PARAM_TYPE_BOOL", "i");
570
        break;
571

572
      case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
573
        WRITE_TEMPLATE("const char *", "EDJE_EXTERNAL_PARAM_TYPE_CHOICE", "s");
574
        break;
575

576
      default:
577
        break;
578
     }
579

580
#undef WRITE_TEMPLATE
581

582
   return EINA_TRUE;
583
}
584

585
static Eina_Bool
586
_write_part_external(Eina_List **parts)
587
{
588
   char buf[1024];
589
   Eina_Iterator *itr;
590
   Part_External_Info *ei;
591
   const Eina_Hash_Tuple *tuple;
592
   Eina_List *l, *l_next;
593
   const char *name;
594
   Eina_Bool ret = EINA_TRUE;
595

596
   itr = edje_external_iterator_get();
597
   EINA_ITERATOR_FOREACH(itr, tuple)
598
     {
599
        const Edje_External_Type *type = tuple->data;
600
        const Edje_External_Param_Info *param;
601
        name = tuple->key;
602

603
        if (!type)
604
          {
605
             ERR("no type value for '%s'", name);
606
             continue;
607
          }
608
        else if (type->abi_version != edje_external_type_abi_version_get())
609
          {
610
             ERR("type '%s' with incorrect abi_version %u (expected %u)",
611
                 name, type->abi_version, edje_external_type_abi_version_get());
612
             continue;
613
          }
614

615
        EINA_LIST_FOREACH_SAFE(*parts, l, l_next, ei)
616
          {
617
             if (!strcmp(ei->source, name))
618
               {
619
                  if (ei->description)
620
                    {
621
                       snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n",
622
                                ei->description);
623
                       if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
624
                         {
625
                            ret = EINA_FALSE;
626
                            goto end;
627
                         }
628
                    }
629

630
                  if (ei->draggable)
631
                    {
632
                       if (!_write_part_draggable(ei->apiname, ei->name))
633
                         {
634
                            ret = EINA_FALSE;
635
                            goto end;
636
                         }
637
                    }
638

639
                  for (param = type->parameters_info; param->name != NULL;
640
                       param++)
641
                    if (!_write_part_external_param(ei, param))
642
                      {
643
                         ret = EINA_FALSE;
644
                         goto end;
645
                      }
646

647
                  edje_edit_string_free(ei->description);
648
                  free(ei->apiname);
649
                  free(ei);
650

651
                  *parts = eina_list_remove_list(*parts, l);
652
               }
653
          }
654
     }
655

656
end:
657
   if (eina_list_count(*parts) == 0) *parts = NULL;
658
   eina_iterator_free(itr);
659

660
   return ret;
661
}
662

663
static Eina_Bool
664
_write_part(const char *apiname, const char *partname, Edje_Part_Type parttype,
665
            const char *description, Eina_Bool draggable)
666
{
667
   char buf[512];
668

669
#define TEMPLATE_NAME(sufix)                                 \
670
  do {                                                       \
671
       snprintf(buf, sizeof(buf), C_CODEGEN_##sufix, prefix, \
672
                apiname, partname);                          \
673
       if (fwrite(buf, strlen(buf), 1, source_fd) != 1)      \
674
         goto err;                                           \
675
       snprintf(buf, sizeof(buf), H_CODEGEN_##sufix, prefix, \
676
                apiname);                                    \
677
       if (fwrite(buf, strlen(buf), 1, header_fd) != 1)      \
678
         goto err;                                           \
679
    } while (0)
680

681
   if (description)
682
     {
683
        snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
684
        if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
685
          goto err;
686
     }
687

688
   switch (parttype)
689
     {
690
      case EDJE_PART_TYPE_BOX:
691
        TEMPLATE_NAME(PART_BOX_APPEND);
692
        TEMPLATE_NAME(PART_BOX_PREPEND);
693
        TEMPLATE_NAME(PART_BOX_INSERT_BEFORE);
694
        TEMPLATE_NAME(PART_BOX_INSERT_AT);
695
        TEMPLATE_NAME(PART_BOX_REMOVE);
696
        TEMPLATE_NAME(PART_BOX_REMOVE_AT);
697
        TEMPLATE_NAME(PART_BOX_REMOVE_ALL);
698
        break;
699

700
      case EDJE_PART_TYPE_TABLE:
701
        TEMPLATE_NAME(PART_TABLE_PACK);
702
        TEMPLATE_NAME(PART_TABLE_UNPACK);
703
        TEMPLATE_NAME(PART_TABLE_CHILD_GET);
704
        TEMPLATE_NAME(PART_TABLE_CLEAR);
705
        TEMPLATE_NAME(PART_TABLE_COL_ROW_SIZE_GET);
706
        break;
707

708
      case EDJE_PART_TYPE_TEXT:
709
        TEMPLATE_NAME(PART_TEXT_SET);
710
        TEMPLATE_NAME(PART_TEXT_GET);
711
        break;
712

713
      case EDJE_PART_TYPE_SWALLOW:
714
        TEMPLATE_NAME(PART_SWALLOW_SET);
715
        TEMPLATE_NAME(PART_SWALLOW_GET);
716
        break;
717

718
      default:
719
        break;
720
     }
721

722
   if (draggable)
723
     if (!_write_part_draggable(apiname, partname))
724
       goto err;
725

726
#undef TEMPLATE_NAME
727

728
   return EINA_TRUE;
729

730
err:
731
   ERR("Could not write the part: %s", partname);
732
   return EINA_FALSE;
733
}
734

735
static inline Eina_Bool
736
_c_id_allowed(char c)
737
{
738
   if ((c >= '0') && (c <= '9')) return EINA_TRUE;
739
   if ((c >= 'a') && (c <= 'z')) return EINA_TRUE;
740
   if ((c >= 'A') && (c <= 'Z')) return EINA_TRUE;
741

742
   return EINA_FALSE;
743
}
744

745
static char *
746
_api_name_fix(const char *orig)
747
{
748
   char *d, *d_end, buf[256];
749
   const char *s;
750

751
   if (!orig) return NULL;
752

753
   s = orig;
754
   d = buf;
755
   d_end = d + sizeof(buf) - 1;
756

757
   for (; (*s != '\0') && (d < d_end); s++, d++)
758
     if (_c_id_allowed(*s)) *d = *s;
759
     else *d = '_';
760
   *d = '\0';
761

762
   return strdup(buf);
763
}
764

765
static char *
766
_part_api_name_get(Evas_Object *ed, const char *program)
767
{
768
   const char *orig;
769
   char *fix;
770

771
   orig = edje_edit_part_api_name_get(ed, program);
772
   fix = _api_name_fix(orig);
773
   edje_edit_string_free(orig);
774

775
   return fix;
776
}
777

778
static Eina_Bool
779
_parse_parts(Evas_Object *ed)
780
{
781
   Eina_List *parts, *l, *parts_external = NULL;
782
   const char *name, *description;
783
   char *apiname;
784
   Edje_Part_Type type;
785
   Eina_Bool draggable, ret = EINA_TRUE;
786
   Part_External_Info *ei;
787

788
   parts = edje_edit_parts_list_get(ed);
789
   EINA_LIST_FOREACH(parts, l, name)
790
     {
791
        if (!(apiname = _part_api_name_get(ed, name)))
792
          {
793
             DBG("filter out part '%s': not API.", name);
794
             continue;
795
          }
796

797
        type = edje_edit_part_type_get(ed, name);
798
        if (!((type == EDJE_PART_TYPE_TEXT) ||
799
              (type == EDJE_PART_TYPE_SWALLOW) ||
800
              (type == EDJE_PART_TYPE_BOX) ||
801
              (type == EDJE_PART_TYPE_EXTERNAL) ||
802
              (type == EDJE_PART_TYPE_IMAGE) ||
803
              (type == EDJE_PART_TYPE_TABLE)))
804
          {
805
             ERR("Invalid part type %d", type);
806
             free(apiname);
807
             continue;
808
          }
809
        if (edje_edit_part_drag_x_get(ed, name) ||
810
            edje_edit_part_drag_y_get(ed, name))
811
          draggable = EINA_TRUE;
812
        else
813
          draggable = EINA_FALSE;
814

815
        description = edje_edit_part_api_description_get(ed, name);
816
        if (type == EDJE_PART_TYPE_EXTERNAL)
817
          {
818
             ei = calloc(1, sizeof(Part_External_Info));
819
             if (!ei)
820
               {
821
                  free(apiname);
822
                  goto end;
823
               }
824
             ei->description = description;
825
             ei->source = edje_edit_part_source_get(ed, name);
826
             ei->apiname = apiname;
827
             ei->name = name;
828
             ei->draggable = draggable;
829

830
             parts_external = eina_list_append(parts_external, ei);
831
          }
832
        else
833
          {
834
             if (!_write_part(apiname, name, type, description, draggable))
835
               {
836
                  ret = EINA_FALSE;
837
                  edje_edit_string_free(description);
838
                  free(apiname);
839
                  goto end;
840
               }
841

842
             edje_edit_string_free(description);
843
             free(apiname);
844
          }
845
     }
846

847
   ret = _write_part_external(&parts_external);
848

849
end:
850
   edje_edit_string_list_free(parts);
851
   EINA_LIST_FREE(parts_external, ei)
852
     {
853
        edje_edit_string_free(ei->description);
854
        free(ei->apiname);
855
        free(ei);
856
     }
857

858
   return ret;
859
}
860

861
static Eina_Bool
862
_write_program_emit(const char *apiname, const char *source, const char *sig,
863
                    const char *description)
864
{
865
   char buf[512];
866

867
   snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_EMIT, prefix,
868
            apiname, sig, source);
869
   if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
870
     goto err;
871

872
   if (description)
873
     {
874
        snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
875
        if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
876
          goto err;
877
     }
878

879
   snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_EMIT, prefix,
880
            apiname);
881
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
882
     goto err;
883

884
   return EINA_TRUE;
885

886
err:
887
   ERR("Could not write the program: %s", apiname);
888
   return EINA_FALSE;
889
}
890

891
static Eina_Bool
892
_write_program_add(const char *apiname, const char *source, const char *sig,
893
                   const char *description)
894
{
895
   char buf[512];
896

897
   snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_CALLBACK_ADD, prefix,
898
            apiname, sig, source);
899
   if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
900
     goto err;
901

902
   snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_CALLBACK_DEL, prefix,
903
            apiname, sig, source);
904
   if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
905
     goto err;
906

907
   if (description)
908
     {
909
        snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
910
        if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
911
          goto err;
912
     }
913

914
   snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_CALLBACK_ADD, prefix,
915
            apiname);
916
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
917
     goto err;
918

919
   snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_CALLBACK_DEL, prefix,
920
            apiname);
921
   if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
922
     goto err;
923

924
   return EINA_TRUE;
925

926
err:
927
   ERR("Could not write the program [action]: %s", apiname);
928
   return EINA_FALSE;
929
}
930

931
static char *
932
_program_api_name_get(Evas_Object *ed, const char *program)
933
{
934
   const char *orig;
935
   char *fix;
936

937
   orig = edje_edit_program_api_name_get(ed, program);
938
   fix = _api_name_fix(orig);
939
   edje_edit_string_free(orig);
940

941
   return fix;
942
}
943

944
static Eina_Bool
945
_parse_programs(Evas_Object *ed)
946
{
947
   Eina_Bool ret = EINA_TRUE;
948
   Eina_List *programs, *l;
949
   const char *name, *source = NULL, *sig = NULL, *description;
950
   char *apiname;
951
   Edje_Action_Type type;
952

953
   programs = edje_edit_programs_list_get(ed);
954
   EINA_LIST_FOREACH(programs, l, name)
955
     {
956
        if (!(apiname = _program_api_name_get(ed, name)))
957
          {
958
             DBG("filter out program '%s': not API.", name);
959
             continue;
960
          }
961

962
        description = edje_edit_program_api_description_get(ed, name);
963
        type = edje_edit_program_action_get(ed, name);
964
        if (type == EDJE_ACTION_TYPE_SIGNAL_EMIT)
965
          {
966
             const char *str, *str2;
967
             str = edje_edit_program_state_get(ed, name);
968
             str2 = edje_edit_program_state2_get(ed, name);
969

970
             if (!_write_program_add(apiname, str2, str, description))
971
               {
972
                  ret = EINA_FALSE;
973
                  edje_edit_string_free(str);
974
                  edje_edit_string_free(str2);
975
                  break;
976
               }
977

978
             edje_edit_string_free(str);
979
             edje_edit_string_free(str2);
980
          }
981

982
        sig = edje_edit_program_signal_get(ed, name);
983
        if (!sig)
984
          {
985
             free(apiname);
986
             edje_edit_string_free(description);
987
             continue;
988
          }
989

990
        source = edje_edit_program_source_get(ed, name);
991
        if (!source)
992
          {
993
             free(apiname);
994
             edje_edit_string_free(sig);
995
             edje_edit_string_free(description);
996
             continue;
997
          }
998

999
        if (!_write_program_emit(apiname, source, sig, description))
1000
          {
1001
             ret = EINA_FALSE;
1002
             break;
1003
          }
1004

1005
        edje_edit_string_free(description);
1006
        edje_edit_string_free(sig);
1007
        edje_edit_string_free(source);
1008
        free(apiname);
1009
     }
1010

1011
   edje_edit_string_list_free(programs);
1012
   if (!ret)
1013
     {
1014
        edje_edit_string_free(description);
1015
        edje_edit_string_free(sig);
1016
        edje_edit_string_free(source);
1017
        free(apiname);
1018
     }
1019

1020
   return ret;
1021
}
1022

1023
static Eina_Bool
1024
_module_matches(const char *module)
1025
{
1026
   Eina_List *l;
1027
   const char *name;
1028

1029
   EINA_LIST_FOREACH(externals, l, name)
1030
     {
1031
        if (!strcmp(module, name))
1032
          return EINA_TRUE;
1033
     }
1034

1035
   return EINA_FALSE;
1036
}
1037

1038
static Eina_Bool
1039
_parse(void)
1040
{
1041
   Evas_Object *ed;
1042
   Eina_Bool ret;
1043
   const char *module_name;
1044
   const Eina_List *modules_available, *l;
1045
   unsigned short modules_loaded = 0;
1046

1047
   modules_available = edje_available_modules_get();
1048
   ed = edje_edit_object_add(ecore_evas_get(ee));
1049
   if (!edje_object_file_set(ed, file, group))
1050
     {
1051
        Edje_Load_Error err = edje_object_load_error_get(ed);
1052
        const char *errmsg = edje_load_error_str(err);
1053
        ERR("could not load group '%s' from file '%s': %s",
1054
            group, file, errmsg);
1055
        evas_object_del(ed);
1056
        return EINA_FALSE;
1057
     }
1058

1059
   externals = edje_edit_externals_list_get(ed);
1060
   if (externals)
1061
     {
1062
        EINA_LIST_FOREACH(modules_available, l, module_name)
1063
          {
1064
             if (_module_matches(module_name))
1065
               {
1066
                  if (!edje_module_load(module_name))
1067
                    {
1068
                       ERR("error loading external '%s'", module_name);
1069
                       continue;
1070
                    }
1071
                  modules_loaded++;
1072
               }
1073
          }
1074
     }
1075

1076
   if (eina_list_count(externals) != modules_loaded)
1077
     {
1078
        edje_edit_string_list_free(externals);
1079
        evas_object_del(ed);
1080
        return EINA_FALSE;
1081
     }
1082

1083
   ret = _parse_parts(ed) && _parse_programs(ed);
1084

1085
   evas_object_del(ed);
1086
   return ret;
1087
}
1088

1089
int
1090
main(int argc, char *argv[])
1091
{
1092
   Eina_Bool quit_option = EINA_FALSE;
1093
   char *source, *header;
1094
   int arg_index, ret = 0;
1095
   Ecore_Getopt_Value values[] = {
1096
      ECORE_GETOPT_VALUE_STR(prefix),
1097
      ECORE_GETOPT_VALUE_BOOL(quit_option),
1098
      ECORE_GETOPT_VALUE_BOOL(quit_option),
1099
      ECORE_GETOPT_VALUE_BOOL(quit_option),
1100
      ECORE_GETOPT_VALUE_BOOL(quit_option),
1101
      ECORE_GETOPT_VALUE_NONE
1102
   };
1103

1104
   setlocale(LC_NUMERIC, "C");
1105

1106
   ecore_app_no_system_modules();
1107

1108
   eina_init();
1109
   ecore_init();
1110
   ecore_evas_init();
1111
   edje_init();
1112

1113
   if (argc < 2)
1114
     {
1115
        fprintf(stderr, "Missing action. See '--help or -h'.\n");
1116
        ret = 1;
1117
        goto error_log;
1118
     }
1119

1120
   _log_dom = eina_log_domain_register("edje_codegen", EINA_COLOR_YELLOW);
1121
   if (_log_dom < 0)
1122
     {
1123
        EINA_LOG_CRIT("could not register log domain 'edje_codegen'");
1124
        ret = 1;
1125
        goto error_log;
1126
     }
1127

1128
   arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
1129
   if (arg_index < 0)
1130
     {
1131
        ERR("could not parse arguments.");
1132
        ret = 1;
1133
        goto error_getopt;
1134
     }
1135
   else if (quit_option)
1136
     goto error_getopt;
1137
   else if (arg_index != argc - 4)
1138
     {
1139
        fprintf(stderr, "Incorrect number of parameters. Requires "          \
1140
                        "fours arguments, an edje, the group, "              \
1141
                        "the source output (foo.c) and the header(foo.h).\n" \
1142
                        "See %s --help\n", argv[0]);
1143
        ret = 1;
1144
        goto error_getopt;
1145
     }
1146

1147
   file = argv[arg_index++];
1148

1149
   // check if the file is accessible
1150
   if (access(file, R_OK) == -1)
1151
     {
1152
        ERR("File '%s' not accessible, error %d (%s).\n",
1153
            file, errno, strerror(errno));
1154
        ret = 1;
1155
        goto error_getopt;
1156
     }
1157

1158
   group = argv[arg_index++];
1159
   source = argv[arg_index++];
1160
   header = argv[arg_index++];
1161

1162
   if (!edje_file_group_exists(file, group))
1163
     {
1164
        ERR("The group %s not exists", group);
1165
        ret = 2;
1166
        goto error_getopt;
1167
     }
1168

1169
   ee = ecore_evas_buffer_new(1, 1);
1170
   if (!ee)
1171
     {
1172
        ERR("could not create ecore_evas_buffer");
1173
        ret = 3;
1174
        goto error_getopt;
1175
     }
1176

1177
   if (!_open_file_descriptors(source, header))
1178
     {
1179
        ERR("Could not create the source files, error %d (%s)",
1180
            errno, strerror(errno));
1181
        ret = 4;
1182
        goto error_getopt;
1183
     }
1184

1185
   if (!_write_headers(header))
1186
     {
1187
        ERR("Could not write the header, error %d (%s)",
1188
            errno, strerror(errno));
1189
        ret = 5;
1190
        goto error_getopt;
1191
     }
1192

1193
   if (!_write_object_get())
1194
     {
1195
        ERR("Could not write the object get, error %d (%s)",
1196
            errno, strerror(errno));
1197
        ret = 6;
1198
        goto error_getopt;
1199
     }
1200

1201
   if (!_parse())
1202
     {
1203
        ERR("Could not parsing the EDJE");
1204
        ret = 7;
1205
        goto error_getopt;
1206
     }
1207

1208
   if (!_write_footer(header))
1209
     {
1210
        ERR("Could not write the footer, error %d (%s)",
1211
            errno, strerror(errno));
1212
        ret = 8;
1213
        goto error_getopt;
1214
     }
1215

1216
   if (!_close_file_descriptors())
1217
     {
1218
        ERR("Could not close the source files, error %d (%s)",
1219
            errno, strerror(errno));
1220
        ret = 9;
1221
     }
1222

1223
error_getopt:
1224
   if (ee)
1225
     ecore_evas_free(ee);
1226

1227
error_log:
1228
   edje_shutdown();
1229
   ecore_evas_shutdown();
1230
   ecore_shutdown();
1231
   eina_log_domain_unregister(_log_dom);
1232
   eina_shutdown();
1233

1234
   if (ret > 4)
1235
     {
1236
        unlink(header);
1237
        unlink(source);
1238
     }
1239

1240
   return ret;
1241
}
1242

1243

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.