forked from enlightenment/efl
elementary_codegen: generating source code from edj
Parsing the parts and programs of the specified group and generating the header/source. Usage: elementary_codegen --prefix myapp_myobj input.edj a_group source.c header.h SVN revision: 76614
This commit is contained in:
parent
bc2a1bd996
commit
1a39b4de1d
|
@ -63,3 +63,4 @@ Artem Popov <artem.popov@samsung.com>
|
||||||
Minseok Kim <minseok3.kim@samsung.com>
|
Minseok Kim <minseok3.kim@samsung.com>
|
||||||
Jean-Philippe André <jpeg@videolan.org>
|
Jean-Philippe André <jpeg@videolan.org>
|
||||||
JiHyeon Seol <jihyeon.seol@samsung.com>
|
JiHyeon Seol <jihyeon.seol@samsung.com>
|
||||||
|
Flavio Ceolin <flavio.ceolin@profusion.mobi>
|
||||||
|
|
|
@ -485,3 +485,20 @@
|
||||||
2012-09-13 Prince Kumar Dubey
|
2012-09-13 Prince Kumar Dubey
|
||||||
|
|
||||||
* Fix diskselector when bounce off and round enabled.
|
* Fix diskselector when bounce off and round enabled.
|
||||||
|
|
||||||
|
2012-09-12 Flavio Ceolin
|
||||||
|
|
||||||
|
* Add elementary_codegen - tool that genereates code to working with
|
||||||
|
edje files. Given an edje file and a group, it searchs for SWALLOW
|
||||||
|
parts and programs and generates a source/header with the helpers
|
||||||
|
for the follow functions:
|
||||||
|
|
||||||
|
- elm_layout_signal_callback_del
|
||||||
|
- elm_layout_signal_callback_add
|
||||||
|
- elm_layout_signal_emit
|
||||||
|
- elm_layout_content_get
|
||||||
|
- elm_layout_content_set
|
||||||
|
- elm_layout_content_unset
|
||||||
|
- elm_layout_text_get
|
||||||
|
- elm_layout_text_set
|
||||||
|
- elm_layout_theme_set
|
||||||
|
|
|
@ -4,6 +4,7 @@ Changes since Elementary 1.7.0:
|
||||||
Additions:
|
Additions:
|
||||||
|
|
||||||
* Add ELM_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN.
|
* Add ELM_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN.
|
||||||
|
* Add elementary_codegen
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
|
|
|
@ -688,6 +688,7 @@ EFL_WITH_BIN([edje], [edje-cc], [edje_cc])
|
||||||
EFL_CHECK_DOXYGEN([build_doc="yes"], [build_doc="no"])
|
EFL_CHECK_DOXYGEN([build_doc="yes"], [build_doc="no"])
|
||||||
|
|
||||||
EFL_ENABLE_BIN([elementary-test])
|
EFL_ENABLE_BIN([elementary-test])
|
||||||
|
EFL_ENABLE_BIN([elementary-codegen])
|
||||||
EFL_ENABLE_BIN([elementary-config])
|
EFL_ENABLE_BIN([elementary-config])
|
||||||
|
|
||||||
m4_ifdef([AM_GNU_GETTEXT_VERSION], [
|
m4_ifdef([AM_GNU_GETTEXT_VERSION], [
|
||||||
|
@ -803,6 +804,7 @@ echo " eet......................: ${eet_eet}"
|
||||||
echo " edje_cc..................: ${edje_cc}"
|
echo " edje_cc..................: ${edje_cc}"
|
||||||
echo
|
echo
|
||||||
echo " Build elementary_test....: ${have_elementary_test}"
|
echo " Build elementary_test....: ${have_elementary_test}"
|
||||||
|
echo " Build elementary_codegen.: ${have_elementary_codegen}"
|
||||||
echo " Examples.................: ${enable_build_examples}"
|
echo " Examples.................: ${enable_build_examples}"
|
||||||
echo " Examples installed.......: ${enable_install_examples}"
|
echo " Examples installed.......: ${enable_install_examples}"
|
||||||
echo " Build elementary_config..: ${have_elementary_config}"
|
echo " Build elementary_config..: ${have_elementary_config}"
|
||||||
|
|
|
@ -28,12 +28,12 @@ AM_CPPFLAGS = \
|
||||||
@EIO_CFLAGS@ \
|
@EIO_CFLAGS@ \
|
||||||
@EMOTION_CFLAGS@
|
@EMOTION_CFLAGS@
|
||||||
|
|
||||||
bin_PROGRAMS = @ELEMENTARY_TEST_PRG@ @ELEMENTARY_CONFIG_PRG@
|
bin_PROGRAMS = @ELEMENTARY_TEST_PRG@ @ELEMENTARY_CONFIG_PRG@ @ELEMENTARY_CODEGEN_PRG@
|
||||||
if BUILD_QUICKLAUNCH
|
if BUILD_QUICKLAUNCH
|
||||||
bin_PROGRAMS += elementary_quicklaunch elementary_run elementary_testql
|
bin_PROGRAMS += elementary_quicklaunch elementary_run elementary_testql
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_PROGRAMS = elementary_test elementary_config
|
EXTRA_PROGRAMS = elementary_test elementary_config elementary_codegen
|
||||||
|
|
||||||
elementary_test_SOURCES = \
|
elementary_test_SOURCES = \
|
||||||
test.c \
|
test.c \
|
||||||
|
@ -152,6 +152,14 @@ elementary_config_LDADD = $(top_builddir)/src/lib/libelementary.la \
|
||||||
@my_libs@
|
@my_libs@
|
||||||
elementary_config_LDFLAGS =
|
elementary_config_LDFLAGS =
|
||||||
|
|
||||||
|
elementary_codegen_SOURCES = \
|
||||||
|
elementary_codegen.c
|
||||||
|
|
||||||
|
elementary_codegen_LDADD = \
|
||||||
|
$(top_builddir)/src/lib/libelementary.la \
|
||||||
|
@my_libs@
|
||||||
|
elementary_codegen_LDFLAGS =
|
||||||
|
|
||||||
if BUILD_QUICKLAUNCH
|
if BUILD_QUICKLAUNCH
|
||||||
elementary_quicklaunch_SOURCES = quicklaunch.c
|
elementary_quicklaunch_SOURCES = quicklaunch.c
|
||||||
elementary_quicklaunch_LDADD = $(top_builddir)/src/lib/libelementary.la \
|
elementary_quicklaunch_LDADD = $(top_builddir)/src/lib/libelementary.la \
|
||||||
|
|
|
@ -0,0 +1,790 @@
|
||||||
|
#include <Elementary.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "elementary_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Ecore.h>
|
||||||
|
#include <Ecore_Evas.h>
|
||||||
|
#include <Ecore_Getopt.h>
|
||||||
|
#include <Edje.h>
|
||||||
|
#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT 1
|
||||||
|
#include <Edje_Edit.h>
|
||||||
|
#include <Eina.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static int _log_dom;
|
||||||
|
#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
|
||||||
|
#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
|
||||||
|
#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
static Ecore_Evas *ee = NULL;
|
||||||
|
static char *file = NULL;
|
||||||
|
static char *group = NULL;
|
||||||
|
static char *prefix = NULL;
|
||||||
|
static FILE *source_fd = NULL;
|
||||||
|
static FILE *header_fd = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
#define H_HEADER \
|
||||||
|
"#ifndef _%s\n" \
|
||||||
|
"#define _%s\n\n" \
|
||||||
|
"#include <Edje.h>\n" \
|
||||||
|
"#include <Elementary.h>\n" \
|
||||||
|
"#include <Evas.h>\n\n" \
|
||||||
|
"#include <stdlib.h>\n\n"
|
||||||
|
|
||||||
|
#define H_FOOTER \
|
||||||
|
"\n#endif /* _%s */\n"
|
||||||
|
|
||||||
|
#define C_HEADER \
|
||||||
|
"#include \"%s\"\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_LAYOUT_ADD \
|
||||||
|
"/**\n * @brief Creates the layout object and set the theme\n" \
|
||||||
|
" * @param o The parent\n" \
|
||||||
|
" * @param th The theme to add to, or if NULL, the default theme\n" \
|
||||||
|
" * @param edje_file The path to edj, if NULL it's used the path given\n" \
|
||||||
|
" * to elementary_codegen\n */\n" \
|
||||||
|
"Evas_Object *%s_layout_add(Evas_Object *o, Elm_Theme *th, " \
|
||||||
|
"const char *edje_file);\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_LAYOUT_ADD \
|
||||||
|
"Evas_Object *\n" \
|
||||||
|
"%s_layout_add(Evas_Object *o, Elm_Theme *th, const char *edje_file)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" Evas_Object *l;\n\n" \
|
||||||
|
" if (edje_file)\n" \
|
||||||
|
" elm_theme_extension_add(th, edje_file);\n" \
|
||||||
|
" else\n" \
|
||||||
|
" elm_theme_extension_add(th, \"./%s\");\n\n" \
|
||||||
|
" l = elm_layout_add(o);\n" \
|
||||||
|
" if (!l) return NULL;\n\n" \
|
||||||
|
" if (!elm_layout_theme_set(l, \"%s\", \"%s\", \"%s\"))\n" \
|
||||||
|
" {\n" \
|
||||||
|
" evas_object_del(l);\n" \
|
||||||
|
" return NULL;\n" \
|
||||||
|
" }\n\n" \
|
||||||
|
" return l;\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PART_CONTENT_SET \
|
||||||
|
"void\n" \
|
||||||
|
"%s_%s_set(Evas_Object *o, Evas_Object *value)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" elm_layout_content_set(o, \"%s\", value);\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PART_TEXT_SET \
|
||||||
|
"void\n" \
|
||||||
|
"%s_%s_set(Evas_Object *o, const char *value)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" elm_layout_text_set(o, \"%s\", value);\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PART_CONTENT_UNSET \
|
||||||
|
"Evas_Object *\n" \
|
||||||
|
"%s_%s_unset(Evas_Object *o)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" return elm_layout_content_unset(o, \"%s\");\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PART_CONTENT_SET \
|
||||||
|
"void %s_%s_set(Evas_Object *o, Evas_Object *value);\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PART_TEXT_SET \
|
||||||
|
"void %s_%s_set(Evas_Object *o, const char *value);\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PART_CONTENT_UNSET \
|
||||||
|
"Evas_Object *%s_%s_unset(Evas_Object *o);\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PART_CONTENT_GET \
|
||||||
|
"Evas_Object *\n" \
|
||||||
|
"%s_%s_get(const Evas_Object *o)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" return elm_layout_content_get(o, \"%s\");\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PART_CONTENT_GET \
|
||||||
|
"Evas_Object *%s_%s_get(const Evas_Object *o);\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PART_TEXT_GET \
|
||||||
|
"const char *\n" \
|
||||||
|
"%s_%s_get(const Evas_Object *o)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" return elm_layout_text_get(o, \"%s\");\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PART_TEXT_GET \
|
||||||
|
"const char *%s_%s_get(const Evas_Object *o);\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PROGRAM_EMIT \
|
||||||
|
"void\n" \
|
||||||
|
"%s_%s_emit(Evas_Object *o)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" elm_layout_signal_emit(o, \"%s\", \"%s\");\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PROGRAM_EMIT \
|
||||||
|
"void %s_%s_emit(Evas_Object *o);\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PROGRAM_CALLBACK_ADD \
|
||||||
|
"void\n" \
|
||||||
|
"%s_%s_callback_add(Evas_Object *o, Edje_Signal_Cb func, void *data)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" elm_layout_signal_callback_add(o, \"%s\", \"%s\", func, data);\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PROGRAM_CALLBACK_ADD \
|
||||||
|
"void %s_%s_callback_add(Evas_Object *o, Edje_Signal_Cb func, " \
|
||||||
|
"void *data);\n"
|
||||||
|
|
||||||
|
#define C_CODEGEN_PROGRAM_CALLBACK_DEL \
|
||||||
|
"void\n" \
|
||||||
|
"%s_%s_callback_del(Evas_Object *o, Edje_Signal_Cb func)\n" \
|
||||||
|
"{\n" \
|
||||||
|
" elm_layout_signal_callback_del(o, \"%s\", \"%s\", func);\n" \
|
||||||
|
"}\n\n"
|
||||||
|
|
||||||
|
#define H_CODEGEN_PROGRAM_CALLBACK_DEL \
|
||||||
|
"void %s_%s_callback_del(Evas_Object *o, Edje_Signal_Cb func);\n"
|
||||||
|
|
||||||
|
|
||||||
|
const Ecore_Getopt optdesc = {
|
||||||
|
"elm_codegen",
|
||||||
|
"%prog [options] <file.edj> <group> <source_file_name> <header_file_name>",
|
||||||
|
PACKAGE_VERSION,
|
||||||
|
"(C) 2012 - The Enlightenment Project",
|
||||||
|
"BSD",
|
||||||
|
"elm_codegen generates the boilerplate code to get and set the "
|
||||||
|
"parts of a group from a compiled (binary) edje "
|
||||||
|
"file avoiding common errors with typos.\n",
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
ECORE_GETOPT_STORE_STR('p', "prefix", "The prefix for the " \
|
||||||
|
"generataed code."),
|
||||||
|
ECORE_GETOPT_LICENSE('L', "license"),
|
||||||
|
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
|
||||||
|
ECORE_GETOPT_VERSION('V', "version"),
|
||||||
|
ECORE_GETOPT_HELP('h', "help"),
|
||||||
|
ECORE_GETOPT_SENTINEL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_header_standardize(const char *filename)
|
||||||
|
{
|
||||||
|
char *str, *itr, *aux;
|
||||||
|
|
||||||
|
aux = strrchr(filename, '/');
|
||||||
|
str = itr = strdup(aux ? aux + 1 : filename);
|
||||||
|
|
||||||
|
for (; *itr; itr++)
|
||||||
|
if (*itr == '.')
|
||||||
|
*itr = '_';
|
||||||
|
else
|
||||||
|
*itr = toupper(*itr);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_file_descriptors_open(const char *source, const char *header)
|
||||||
|
{
|
||||||
|
header_fd = fopen(header, "w");
|
||||||
|
if (!header_fd)
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
source_fd = fopen(source, "w");
|
||||||
|
if (!source_fd)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
fclose(header_fd);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_file_descriptors_close(void)
|
||||||
|
{
|
||||||
|
Eina_Bool ret = EINA_FALSE;
|
||||||
|
|
||||||
|
if (!fclose(header_fd))
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
|
||||||
|
if (!fclose(source_fd))
|
||||||
|
ret &= EINA_TRUE;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_headers_write(const char *filename)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = _header_standardize(filename);
|
||||||
|
snprintf(buf, sizeof(buf), H_HEADER, str, str);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
{
|
||||||
|
free(str);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_HEADER, filename);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_footer_write(const char *filename)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = _header_standardize(filename);
|
||||||
|
snprintf(buf, sizeof(buf), H_FOOTER, str);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
{
|
||||||
|
free(str);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_theme_set_write(void)
|
||||||
|
{
|
||||||
|
Eina_Bool ret = EINA_FALSE;
|
||||||
|
char *str[3]; /* *klas, *style, *group */
|
||||||
|
char *aux, *token, *_group, buf[512];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
str[0] = str[1] = str[2] = NULL;
|
||||||
|
if (strncmp(group, "elm/", 4)) return EINA_FALSE;
|
||||||
|
|
||||||
|
_group = strdup(group);
|
||||||
|
if (!_group) return EINA_FALSE;
|
||||||
|
|
||||||
|
token = strtok(_group, "/");
|
||||||
|
for (i = 0, aux = NULL; i < 3; i++, aux = NULL)
|
||||||
|
{
|
||||||
|
token = strtok(aux, "/");
|
||||||
|
if (!token) break;
|
||||||
|
|
||||||
|
str[i] = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str[0] || !str[1] || !str[2])
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_LAYOUT_ADD, prefix, file, str[0],
|
||||||
|
str[1], str[2]);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_LAYOUT_ADD, prefix);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
|
||||||
|
end:
|
||||||
|
free(_group);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_part_write(const char *apiname, const char *partname, const char *description,
|
||||||
|
Edje_Part_Type type)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
if (type == EDJE_PART_TYPE_SWALLOW)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PART_CONTENT_SET , prefix, apiname, partname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PART_CONTENT_UNSET , prefix, apiname, partname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PART_CONTENT_SET, prefix, apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PART_CONTENT_UNSET, prefix, apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PART_CONTENT_GET, prefix, apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PART_CONTENT_GET, prefix, apiname, partname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PART_TEXT_SET , prefix, apiname, partname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PART_TEXT_SET, prefix, apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PART_TEXT_GET, prefix, apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PART_TEXT_GET, prefix, apiname, partname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ERR("Could not write the part: %s", partname);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Bool
|
||||||
|
_c_id_allowed(char c)
|
||||||
|
{
|
||||||
|
if ((c >= '0') && (c <= '9')) return EINA_TRUE;
|
||||||
|
if ((c >= 'a') && (c <= 'z')) return EINA_TRUE;
|
||||||
|
if ((c >= 'A') && (c <= 'Z')) return EINA_TRUE;
|
||||||
|
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_api_name_fix(const char *orig)
|
||||||
|
{
|
||||||
|
char *d, *d_end, buf[256];
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if (!orig) return NULL;
|
||||||
|
|
||||||
|
s = orig;
|
||||||
|
d = buf;
|
||||||
|
d_end = d + sizeof(buf) - 1;
|
||||||
|
|
||||||
|
for (; (*s != '\0') && (d < d_end); s++, d++)
|
||||||
|
if (_c_id_allowed(*s)) *d = *s;
|
||||||
|
else *d = '_';
|
||||||
|
*d = '\0';
|
||||||
|
|
||||||
|
return strdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_part_api_name_get(Evas_Object *ed, const char *program)
|
||||||
|
{
|
||||||
|
const char *orig;
|
||||||
|
char *fix;
|
||||||
|
|
||||||
|
orig = edje_edit_part_api_name_get(ed, program);
|
||||||
|
fix = _api_name_fix(orig);
|
||||||
|
edje_edit_string_free(orig);
|
||||||
|
|
||||||
|
return fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_parts_parse(Evas_Object *ed)
|
||||||
|
{
|
||||||
|
Eina_List *parts, *l;
|
||||||
|
const char *name, *description;
|
||||||
|
char *apiname;
|
||||||
|
Edje_Part_Type type;
|
||||||
|
Eina_Bool ret = EINA_TRUE;
|
||||||
|
|
||||||
|
parts = edje_edit_parts_list_get(ed);
|
||||||
|
EINA_LIST_FOREACH(parts, l, name)
|
||||||
|
{
|
||||||
|
if (!(apiname = _part_api_name_get(ed, name)))
|
||||||
|
{
|
||||||
|
DBG("filter out part '%s': not API.", name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = edje_edit_part_type_get(ed, name);
|
||||||
|
if ((type != EDJE_PART_TYPE_SWALLOW) && (type != EDJE_PART_TYPE_TEXT))
|
||||||
|
{
|
||||||
|
free(apiname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
description = edje_edit_part_api_description_get(ed, name);
|
||||||
|
if (!_part_write(apiname, name, description, type))
|
||||||
|
{
|
||||||
|
ret = EINA_FALSE;
|
||||||
|
edje_edit_string_free(description);
|
||||||
|
free(apiname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
edje_edit_string_free(description);
|
||||||
|
free(apiname);
|
||||||
|
}
|
||||||
|
|
||||||
|
edje_edit_string_list_free(parts);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_program_emit_write(const char *apiname, const char *source, const char *signal,
|
||||||
|
const char *description)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_EMIT, prefix,
|
||||||
|
apiname, signal, source);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_EMIT, prefix,
|
||||||
|
apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ERR("Could not write the program: %s", apiname);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_program_add_write(const char *apiname, const char *source, const char *signal,
|
||||||
|
const char *description)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_CALLBACK_ADD, prefix,
|
||||||
|
apiname, signal, source);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), C_CODEGEN_PROGRAM_CALLBACK_DEL, prefix,
|
||||||
|
apiname, signal, source);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, source_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "\n/**\n * @brief %s\n */\n", description);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_CALLBACK_ADD, prefix,
|
||||||
|
apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), H_CODEGEN_PROGRAM_CALLBACK_DEL, prefix,
|
||||||
|
apiname);
|
||||||
|
if (fwrite(buf, strlen(buf), 1, header_fd) != 1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ERR("Could not write the program [action]: %s", apiname);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_program_api_name_get(Evas_Object *ed, const char *program)
|
||||||
|
{
|
||||||
|
const char *orig;
|
||||||
|
char *fix;
|
||||||
|
|
||||||
|
orig = edje_edit_program_api_name_get(ed, program);
|
||||||
|
fix = _api_name_fix(orig);
|
||||||
|
edje_edit_string_free(orig);
|
||||||
|
|
||||||
|
return fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_programs_parse(Evas_Object *ed)
|
||||||
|
{
|
||||||
|
Eina_Bool ret = EINA_TRUE;
|
||||||
|
Eina_List *programs, *l;
|
||||||
|
const char *name, *source, *signal, *description;
|
||||||
|
char *apiname;
|
||||||
|
Edje_Action_Type type;
|
||||||
|
|
||||||
|
programs = edje_edit_programs_list_get(ed);
|
||||||
|
EINA_LIST_FOREACH(programs, l, name)
|
||||||
|
{
|
||||||
|
if (!(apiname = _program_api_name_get(ed, name)))
|
||||||
|
{
|
||||||
|
DBG("filter out program '%s': not API.", name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal = edje_edit_program_signal_get(ed, name);
|
||||||
|
if (!signal) signal = eina_stringshare_add("");
|
||||||
|
|
||||||
|
source = edje_edit_program_source_get(ed, name);
|
||||||
|
if (!source) source = eina_stringshare_add("");
|
||||||
|
|
||||||
|
description = edje_edit_program_api_description_get(ed, name);
|
||||||
|
if (strlen (signal))
|
||||||
|
{
|
||||||
|
if (!_program_emit_write(apiname, source, signal, description))
|
||||||
|
{
|
||||||
|
ret = EINA_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type = edje_edit_program_action_get(ed, name);
|
||||||
|
if (type == EDJE_ACTION_TYPE_SIGNAL_EMIT)
|
||||||
|
{
|
||||||
|
const char *str, *str2;
|
||||||
|
str = edje_edit_program_state_get(ed, name);
|
||||||
|
str2 = edje_edit_program_state2_get(ed, name);
|
||||||
|
|
||||||
|
if (!_program_add_write(apiname, str2, str, description))
|
||||||
|
{
|
||||||
|
ret = EINA_FALSE;
|
||||||
|
edje_edit_string_free(str);
|
||||||
|
edje_edit_string_free(str2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
edje_edit_string_free(str);
|
||||||
|
edje_edit_string_free(str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
edje_edit_string_free(description);
|
||||||
|
edje_edit_string_free(signal);
|
||||||
|
edje_edit_string_free(source);
|
||||||
|
free(apiname);
|
||||||
|
}
|
||||||
|
|
||||||
|
edje_edit_string_list_free(programs);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
edje_edit_string_free(description);
|
||||||
|
edje_edit_string_free(signal);
|
||||||
|
edje_edit_string_free(source);
|
||||||
|
free(apiname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_parse(void)
|
||||||
|
{
|
||||||
|
Evas_Object *ed;
|
||||||
|
Eina_Bool ret;
|
||||||
|
|
||||||
|
ed = edje_edit_object_add(ecore_evas_get(ee));
|
||||||
|
if (!edje_object_file_set(ed, file, group))
|
||||||
|
{
|
||||||
|
Edje_Load_Error err = edje_object_load_error_get(ed);
|
||||||
|
const char *errmsg = edje_load_error_str(err);
|
||||||
|
ERR("could not load group '%s' from file '%s': %s",
|
||||||
|
group, file, errmsg);
|
||||||
|
evas_object_del(ed);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _parts_parse(ed) && _programs_parse(ed);
|
||||||
|
|
||||||
|
evas_object_del(ed);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
Eina_Bool quit_option = EINA_FALSE;
|
||||||
|
char *source, *header;
|
||||||
|
int arg_index, ret = 0;
|
||||||
|
Ecore_Getopt_Value values[] = {
|
||||||
|
ECORE_GETOPT_VALUE_STR(prefix),
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option),
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option),
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option),
|
||||||
|
ECORE_GETOPT_VALUE_BOOL(quit_option),
|
||||||
|
ECORE_GETOPT_VALUE_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
setlocale(LC_NUMERIC, "C");
|
||||||
|
|
||||||
|
eina_init();
|
||||||
|
ecore_init();
|
||||||
|
ecore_evas_init();
|
||||||
|
edje_init();
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Missing action. See '--help or -h'.\n");
|
||||||
|
ret = 1;
|
||||||
|
goto error_log;
|
||||||
|
}
|
||||||
|
|
||||||
|
_log_dom = eina_log_domain_register("elementary_codegen", EINA_COLOR_YELLOW);
|
||||||
|
if (_log_dom < 0)
|
||||||
|
{
|
||||||
|
EINA_LOG_CRIT("could not register log domain 'elementary_codegen'");
|
||||||
|
ret = 1;
|
||||||
|
goto error_log;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
|
||||||
|
if (arg_index < 0)
|
||||||
|
{
|
||||||
|
ERR("could not parse arguments.");
|
||||||
|
ret = 1;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
else if (quit_option) goto error_getopt;
|
||||||
|
else if (arg_index != argc - 4)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Incorrect number of parameters. Requires " \
|
||||||
|
"fours arguments, an edje, the group, " \
|
||||||
|
"the source output (foo.c) and the header(foo.h).\n" \
|
||||||
|
"See %s --help\n", argv[0]);
|
||||||
|
ret = 1;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = argv[arg_index++];
|
||||||
|
|
||||||
|
// check if the file is accessible
|
||||||
|
if (access(file, R_OK) == -1)
|
||||||
|
{
|
||||||
|
ERR("File '%s' not accessible, error %d (%s).\n",
|
||||||
|
file, errno, strerror(errno));
|
||||||
|
ret = 1;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
group = argv[arg_index++];
|
||||||
|
source = argv[arg_index++];
|
||||||
|
header = argv[arg_index++];
|
||||||
|
|
||||||
|
if (!edje_file_group_exists(file, group))
|
||||||
|
{
|
||||||
|
ERR("The group %s not exists", group);
|
||||||
|
ret = 2;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ee = ecore_evas_buffer_new(1, 1);
|
||||||
|
if (!ee)
|
||||||
|
{
|
||||||
|
ERR("could not create ecore_evas_buffer");
|
||||||
|
ret = 3;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_file_descriptors_open(source, header))
|
||||||
|
{
|
||||||
|
ERR("Could not create the source files, error %d (%s)",
|
||||||
|
errno, strerror(errno));
|
||||||
|
ret = 4;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_headers_write(header))
|
||||||
|
{
|
||||||
|
ERR("Could not write the header, error %d (%s)",
|
||||||
|
errno, strerror(errno));
|
||||||
|
ret = 5;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_theme_set_write())
|
||||||
|
WRN("Theme set getter/setter not created. Group name: %s invalid.", group);
|
||||||
|
|
||||||
|
if (!_parse())
|
||||||
|
{
|
||||||
|
ERR("Could not parsing the EDJE");
|
||||||
|
ret = 6;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_footer_write(header))
|
||||||
|
{
|
||||||
|
ERR("Could not write the footer, error %d (%s)",
|
||||||
|
errno, strerror(errno));
|
||||||
|
ret = 7;
|
||||||
|
goto error_getopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_file_descriptors_close())
|
||||||
|
{
|
||||||
|
ERR("Could not close the source files, error %d (%s)",
|
||||||
|
errno, strerror(errno));
|
||||||
|
ret = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_getopt:
|
||||||
|
if (ee)
|
||||||
|
ecore_evas_free(ee);
|
||||||
|
|
||||||
|
error_log:
|
||||||
|
edje_shutdown();
|
||||||
|
ecore_evas_shutdown();
|
||||||
|
ecore_shutdown();
|
||||||
|
eina_log_domain_unregister(_log_dom);
|
||||||
|
eina_shutdown();
|
||||||
|
|
||||||
|
if (ret > 4)
|
||||||
|
{
|
||||||
|
unlink(header);
|
||||||
|
unlink(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue