edbus codegen: Initial commit
authorJosé Roberto de Souza <zehortigoza@profusion.mobi>
Thu, 20 Dec 2012 21:47:20 +0000 (21:47 +0000)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Thu, 20 Dec 2012 21:47:20 +0000 (21:47 +0000)
Add codegen tool to generate client code.

Patch by: José Roberto de Souza  <zehortigoza@profusion.mobi>

SVN revision: 81492

legacy/edbus/.gitignore
legacy/edbus/Makefile.am
legacy/edbus/configure.ac
legacy/edbus/m4/efl_binary.m4 [new file with mode: 0644]
legacy/edbus/src/codegen/client.c [new file with mode: 0644]
legacy/edbus/src/codegen/codegen.h [new file with mode: 0644]
legacy/edbus/src/codegen/dbus.c [new file with mode: 0644]
legacy/edbus/src/codegen/parser.c [new file with mode: 0644]
legacy/edbus/src/codegen/source_client.c [new file with mode: 0644]
legacy/edbus/src/codegen/utils.c [new file with mode: 0644]

index 51ea75c..bcfa7a8 100644 (file)
@@ -44,3 +44,4 @@ doc/Doxyfile
 doc/html/
 doc/latex/
 doc/man/
+edbus_client_codegen
index c1ee20d..293c087 100644 (file)
@@ -129,6 +129,18 @@ src_examples_simple_signal_emit_LDADD = $(EXAMPLES_LIBS)
 src_examples_complex_types_client_eina_value_SOURCES = src/examples/complex_types_client_eina_value.c
 src_examples_complex_types_client_eina_value_LDADD = $(EXAMPLES_LIBS)
 
+if BUILD_EDBUS_CODEGEN
+bin_PROGRAMS = edbus_client_codegen
+edbus_client_codegen_SOURCES = \
+       src/codegen/utils.c \
+       src/codegen/parser.c \
+       src/codegen/dbus.c \
+       src/codegen/source_client.c \
+       src/codegen/client.c
+edbus_client_codegen_CFLAGS = -I$(top_srcdir)/src/codegen @EDBUS_CODEGEN_CFLAGS@ @ECORE_CFLAGS@
+edbus_client_codegen_LDADD = @EDBUS_CODEGEN_LIBS@ @ECORE_LIBS@
+endif
+
 .PHONY: doc examples
 
 examples: $(EXAMPLES)
index eb863d1..4b2c038 100644 (file)
@@ -105,6 +105,16 @@ VMIN=v_min
 AC_SUBST(VMAJ)
 AC_SUBST(VMIN)
 
+EFL_ENABLE_BIN([edbus-codegen], ["yes"])
+
+if test "x${have_edbus_codegen}" = "xyes" ; then
+       PKG_CHECK_MODULES([EDBUS_CODEGEN],
+               [eina >= 1.6.99],
+               [ecore >= 1.6.99],
+               [have_edbus_codegen="yes"],
+               [have_edbus_codegen="no"])
+fi
+
 AC_CONFIG_FILES([
 Makefile
 edbus.spec
diff --git a/legacy/edbus/m4/efl_binary.m4 b/legacy/edbus/m4/efl_binary.m4
new file mode 100644 (file)
index 0000000..0ad38ce
--- /dev/null
@@ -0,0 +1,78 @@
+dnl Copyright (C) 2010 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+
+dnl Macro that checks if a binary is built or not
+
+dnl Usage: EFL_ENABLE_BIN(binary, dep[, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl Call AC_SUBST(BINARY_PRG) (BINARY is the uppercase of binary, - being transformed into _)
+dnl Define have_binary (- is transformed into _)
+dnl Define conditional BUILD_BINARY (BINARY is the uppercase of binary, - being transformed into _)
+
+AC_DEFUN([EFL_ENABLE_BIN],
+[
+
+m4_pushdef([UP], m4_translit([[$1]], [-a-z], [_A-Z]))dnl
+m4_pushdef([DOWN], m4_translit([[$1]], [-A-Z], [_a-z]))dnl
+
+dnl configure option
+
+AC_ARG_ENABLE([$1],
+   [AC_HELP_STRING([--disable-$1], [disable building of ]DOWN)],
+   [
+    if test "x${enableval}" = "xyes" ; then
+       have_[]m4_defn([DOWN])="yes"
+    else
+       have_[]m4_defn([DOWN])="no"
+    fi
+   ],
+   [have_[]m4_defn([DOWN])=$2])
+
+AC_MSG_CHECKING([whether to build ]DOWN[ binary])
+AC_MSG_RESULT([$have_[]m4_defn([DOWN])])
+
+if test "x$have_[]m4_defn([DOWN])" = "xyes"; then
+   UP[]_PRG=DOWN[${EXEEXT}]
+fi
+
+AC_SUBST(UP[]_PRG)
+
+AM_CONDITIONAL(BUILD_[]UP, test "x$have_[]m4_defn([DOWN])" = "xyes")
+
+AS_IF([test "x$have_[]m4_defn([DOWN])" = "xyes"], [$3], [$4])
+
+])
+
+dnl Macro that specifies the binary to be used
+
+dnl Usage: EFL_WITH_BIN(binary, package, msg)
+dnl Call AC_SUBST(BINARY_PRG) (BINARY is the uppercase of binary, - being transformed into _)
+dnl Define with_binary (- is transformed into _)
+dnl Define conditional BUILD_BINARY (BINARY is the uppercase of binary, - being transformed into _)
+
+AC_DEFUN([EFL_WITH_BIN],
+[
+
+m4_pushdef([UP], m4_translit([[$1]], [-a-z], [_A-Z]))dnl
+m4_pushdef([DOWN], m4_translit([[$1]], [-A-Z], [_a-z]))dnl
+
+AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+AC_MSG_NOTICE([$PKG_CONFIG])
+
+with_[]m4_defn([DOWN])=m4_esyscmd($PKG_CONFIG --variable=prefix $2)/bin/m4_defn([DOWN])
+
+dnl configure option
+
+AC_ARG_WITH([$1],
+   [AC_HELP_STRING([--with-$1-bin=PATH], [specify a specific path to ]DOWN)],
+   [
+    with_[]m4_defn([DOWN])=$withval
+    _efl_msg="( explicitely set)"
+   ])
+
+AC_MSG_NOTICE([$msg: ]m4_defn([DOWN])[$_efl_msg])
+
+AC_SUBST(with_[]m4_defn([DOWN]))
+
+AS_IF([test "x$have_[]m4_defn([DOWN])" = "xyes"], [$4], [$5])
+
+])
diff --git a/legacy/edbus/src/codegen/client.c b/legacy/edbus/src/codegen/client.c
new file mode 100644 (file)
index 0000000..742a294
--- /dev/null
@@ -0,0 +1,81 @@
+#include "codegen.h"
+
+static const Ecore_Getopt optdesc = {
+  "edbus_codegen",
+  "%prog [options] <file.xml>",
+  "1.0",
+  "(C) 2012 - The Enlightenment Project",
+  "BSD",
+  "Generate DBUS code, making write DBus client applications easy\n",
+  0,
+  {
+    ECORE_GETOPT_STORE_STR('p', "prefix", "The prefix for the generated code."),
+    ECORE_GETOPT_STORE_STR('i', "interface", "To generate code of only one interface of xml."),
+    ECORE_GETOPT_STORE_STR('o', "output file name", "The name of output files, only used if a interface is selected."),
+    ECORE_GETOPT_LICENSE('L', "license"),
+    ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+    ECORE_GETOPT_VERSION('V', "version"),
+    ECORE_GETOPT_HELP('h', "help"),
+    ECORE_GETOPT_SENTINEL
+  }
+};
+
+int
+main(int argc, char **argv)
+{
+   char *xml_buf = NULL;
+   DBus_Object *obj = NULL;
+   char *prefix = NULL, *interface = NULL, *output = NULL;
+   Eina_Bool quit_option = EINA_FALSE;
+   int arg_index;
+   Ecore_Getopt_Value values[] = {
+      ECORE_GETOPT_VALUE_STR(prefix),
+      ECORE_GETOPT_VALUE_STR(interface),
+      ECORE_GETOPT_VALUE_STR(output),
+      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
+   };
+
+   eina_init();
+
+   arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
+   if (arg_index == -1)
+     {
+        printf("Error: parsing arguments.\n");
+        return -1;
+     }
+   if (quit_option)
+     return 0;
+   if (argc <= arg_index)
+     {
+        printf("Error: Missing file name.\n");
+        return -1;
+     }
+
+   if (!file_read(argv[arg_index], &xml_buf))
+     {
+        printf("Error reading file.\n");
+        goto end;
+     }
+
+   if (!eina_simple_xml_parse(xml_buf, strlen(xml_buf), EINA_TRUE,
+                              parser, &obj))
+     {
+        printf("Error: could not parse XML\n");
+        goto end;
+     }
+
+   source_client_generate(obj, prefix, interface, output);
+   util_h_write();
+
+end:
+   if (obj)
+     object_free(obj);
+
+   free(xml_buf);
+   eina_shutdown();
+   return 0;
+}
diff --git a/legacy/edbus/src/codegen/codegen.h b/legacy/edbus/src/codegen/codegen.h
new file mode 100644 (file)
index 0000000..ffcaf99
--- /dev/null
@@ -0,0 +1,112 @@
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+#include <ctype.h>
+
+#define ACCESS_READ 1 << 0
+#define ACCESS_WRITE 1 << 1
+
+typedef struct _DBus_Object
+{
+   char *name;
+   char *c_name;
+   Eina_Inlist *ifaces;
+} DBus_Object;
+
+typedef struct _DBus_Interface
+{
+   EINA_INLIST;
+   char *name;
+   char *c_name;
+   Eina_Inlist *methods;
+   Eina_Inlist *signals;
+   Eina_Inlist *properties;
+   DBus_Object *obj;
+} DBus_Interface;
+
+typedef struct _DBus_Signal
+{
+   EINA_INLIST;
+   char *name;
+   char *c_name;
+   char *cb_name;
+   char *struct_name;
+   char *free_function;
+   Eina_Inlist *args;
+   unsigned int arg_without_name;
+   DBus_Interface *iface;
+   Eina_Bool complex;
+   char *signal_event;
+} DBus_Signal;
+
+typedef struct _DBus_Arg
+{
+   EINA_INLIST;
+   char *type;
+   char direction;
+   char *name;
+   char *c_name;
+} DBus_Arg;
+
+typedef enum
+{
+   NO_REPLY = 0,
+   INVALID
+} DBus_Annotation_Type;
+
+typedef struct _DBus_Annotation
+{
+   DBus_Annotation_Type type;
+   char *value;
+} DBus_Annotation;
+
+typedef struct _DBus_Method
+{
+   EINA_INLIST;
+   char *name;
+   char *c_name;
+   char *cb_name;
+   char *function_cb;
+   Eina_Inlist *args;
+   unsigned int arg_without_name;
+   DBus_Interface *iface;
+   Eina_Bool in_complex:1;
+   Eina_Bool out_complex:1;
+   Eina_Bool no_reply:1;
+} DBus_Method;
+
+typedef struct _DBus_Property
+{
+   EINA_INLIST;
+   char *name;
+   char *c_name;
+   char *cb_name;
+   char *type;
+   char access;
+   DBus_Interface *iface;
+   Eina_Bool complex;
+} DBus_Property;
+
+Eina_Bool parser(void *data, Eina_Simple_XML_Type type, const char *content, unsigned offset, unsigned length);
+
+void object_free(DBus_Object *obj);
+DBus_Interface *interface_new(DBus_Object *obj);
+void interface_free(DBus_Interface *iface);
+DBus_Signal *signal_new(DBus_Interface *iface);
+void signal_free(DBus_Signal *signal);
+void arg_free(DBus_Arg *arg);
+void method_free(DBus_Method *method);
+DBus_Method *method_new(DBus_Interface *iface);
+DBus_Property *property_new(DBus_Interface *iface);
+void property_free(DBus_Property *property);
+
+void source_client_generate(DBus_Object *path, const char *prefix, const char *interface_name, const char *output);
+
+//utils
+Eina_Bool file_read(const char *file_name, char **buffer);
+Eina_Bool file_write(const char *file_name, const char *buffer);
+Eina_Bool util_h_write(void);
+char *replace_string(const char *string, const char *substr, const char *replacement);
+char *dbus_name_to_c(const char *dbus);
+char *string_build(const char *fmt, ...);
+char *get_pieces(const char *string, char break_in, int amount);
diff --git a/legacy/edbus/src/codegen/dbus.c b/legacy/edbus/src/codegen/dbus.c
new file mode 100644 (file)
index 0000000..b05c760
--- /dev/null
@@ -0,0 +1,141 @@
+#include "codegen.h"
+
+void
+property_free(DBus_Property *property)
+{
+   property->iface->properties = eina_inlist_remove(property->iface->properties,
+                                                    EINA_INLIST_GET(property));
+   free(property->c_name);
+   free(property->cb_name);
+   free(property->name);
+   free(property->type);
+   free(property);
+}
+
+DBus_Property *
+property_new(DBus_Interface *iface)
+{
+   DBus_Property *prop = calloc(1, sizeof(DBus_Property));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(prop, NULL);
+   iface->properties = eina_inlist_append(iface->properties,
+                                          EINA_INLIST_GET(prop));
+   prop->iface = iface;
+   return prop;
+}
+
+DBus_Method *
+method_new(DBus_Interface *iface)
+{
+   DBus_Method *method = calloc(1, sizeof(DBus_Method));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(method, NULL);
+   iface->methods = eina_inlist_append(iface->methods, EINA_INLIST_GET(method));
+   method->iface = iface;
+   return method;
+}
+
+void
+method_free(DBus_Method *method)
+{
+   DBus_Arg *arg;
+   Eina_Inlist *inlist;
+
+   EINA_INLIST_FOREACH_SAFE(method->args, inlist, arg)
+     arg_free(arg);
+   method->iface->methods = eina_inlist_remove(method->iface->methods,
+                                               EINA_INLIST_GET(method));
+   free(method->c_name);
+   free(method->cb_name);
+   free(method->function_cb);
+   free(method->name);
+   free(method);
+}
+
+void
+arg_free(DBus_Arg *arg)
+{
+   free(arg->c_name);
+   free(arg->name);
+   free(arg->type);
+   free(arg);
+}
+
+DBus_Signal *
+signal_new(DBus_Interface *iface)
+{
+   DBus_Signal *signal = calloc(1, sizeof(DBus_Signal));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(signal, NULL);
+   iface->signals = eina_inlist_append(iface->signals, EINA_INLIST_GET(signal));
+   signal->iface = iface;
+   return signal;
+}
+
+void
+signal_free(DBus_Signal *signal)
+{
+   DBus_Arg *arg;
+   Eina_Inlist *inlist;
+
+   EINA_INLIST_FOREACH_SAFE(signal->args, inlist, arg)
+     arg_free(arg);
+   signal->iface->signals = eina_inlist_remove(signal->iface->signals,
+                                               EINA_INLIST_GET(signal));
+   free(signal->c_name);
+   free(signal->struct_name);
+   free(signal->free_function);
+   free(signal->cb_name);
+   free(signal->name);
+   free(signal->signal_event);
+   free(signal);
+}
+
+DBus_Interface *
+interface_new(DBus_Object *obj)
+{
+   DBus_Interface *iface = calloc(1, sizeof(DBus_Interface));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
+   obj->ifaces = eina_inlist_append(obj->ifaces, EINA_INLIST_GET(iface));
+   iface->obj = obj;
+   return iface;
+}
+
+void
+interface_free(DBus_Interface *iface)
+{
+   while (iface->signals)
+     {
+        DBus_Signal *signal = EINA_INLIST_CONTAINER_GET(iface->signals,
+                                                        DBus_Signal);
+        signal_free(signal);
+     }
+   while (iface->methods)
+     {
+        DBus_Method *method = EINA_INLIST_CONTAINER_GET(iface->methods,
+                                                        DBus_Method);
+        method_free(method);
+     }
+   while (iface->properties)
+     {
+        DBus_Property *property = EINA_INLIST_CONTAINER_GET(iface->properties,
+                                                            DBus_Property);
+        property_free(property);
+     }
+   iface->obj->ifaces = eina_inlist_remove(iface->obj->ifaces,
+                                           EINA_INLIST_GET(iface));
+   free(iface->c_name);
+   free(iface->name);
+   free(iface);
+}
+
+void
+object_free(DBus_Object *obj)
+{
+   while (obj->ifaces)
+     {
+        DBus_Interface *iface = EINA_INLIST_CONTAINER_GET(obj->ifaces,
+                                                          DBus_Interface);
+        interface_free(iface);
+     }
+   free(obj->c_name);
+   free(obj->name);
+   free(obj);
+}
diff --git a/legacy/edbus/src/codegen/parser.c b/legacy/edbus/src/codegen/parser.c
new file mode 100644 (file)
index 0000000..55bbab8
--- /dev/null
@@ -0,0 +1,482 @@
+#include "codegen.h"
+
+#define OBJECT_TAG "node"
+#define OBJECT_TAG_LENGHT strlen(OBJECT_TAG)
+#define INTERFACE_TAG "interface"
+#define INTERFACE_TAG_LENGHT strlen(INTERFACE_TAG)
+#define SIGNAL_TAG "signal"
+#define SIGNAL_TAG_LENGHT strlen(SIGNAL_TAG)
+#define METHOD_TAG "method"
+#define METHOD_TAG_LENGHT strlen(METHOD_TAG)
+#define PROPERTY_TAG "property"
+#define PROPERTY_TAG_LENGHT strlen(PROPERTY_TAG)
+#define ARG_TAG "arg"
+#define ARG_TAG_LENGHT strlen(ARG_TAG)
+#define ANNOTATION_TAG "annotation"
+#define ANNOTATION_TAG_LENGHT strlen(ANNOTATION_TAG)
+
+//attributes
+#define NAME_ATTR "name"
+#define TYPE_ATTR "type"
+#define DIRECTION_ATTR "direction"
+#define ACCESS_ATTR "access"
+#define VALUE_ATTR "value"
+
+#define ACCESS_ATTR_VALUE_WRITE "write"
+#define ACCESS_ATTR_VALUE_READ "read"
+
+#define DBUS_INTERFACE "org.freedesktop.DBus."
+
+static DBus_Interface *iface;
+static DBus_Signal *d_signal;
+static DBus_Method *method;
+static DBus_Property *property;
+
+static Eina_Bool attributes_parse(const char *content, unsigned length, Eina_Simple_XML_Attribute_Cb func, const void *data);
+
+static Eina_Bool
+obj_attributes_parser(void *data, const char *key, const char *value)
+{
+   DBus_Object *obj = data;
+
+   if (!strcmp(key, NAME_ATTR))
+     obj->name = strdup(value);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+iface_attributes_parser(void *data, const char *key, const char *value)
+{
+   if (!strcmp(key, NAME_ATTR))
+     iface->name = strdup(value);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+signal_attributes_parser(void *data, const char *key, const char *value)
+{
+   if (!strcmp(key, NAME_ATTR))
+     d_signal->name = strdup(value);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+arg_attributes_parser(void *data, const char *key, const char *value)
+{
+   DBus_Arg *arg = data;
+   if (!strcmp(key, NAME_ATTR))
+     arg->name = strdup(value);
+   else if (!strcmp(key, TYPE_ATTR))
+     arg->type = strdup(value);
+   else if (!strcmp(key, DIRECTION_ATTR))
+     arg->direction = value[0];
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+method_attributes_parser(void *data, const char *key, const char *value)
+{
+   if (!strcmp(key, NAME_ATTR))
+     method->name = strdup(value);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+property_attributes_parser(void *data, const char *key, const char *value)
+{
+   if (!strcmp(key, NAME_ATTR))
+     property->name = strdup(value);
+   else if (!strcmp(key, TYPE_ATTR))
+     {
+        property->type = strdup(value);
+        if (value[1] || value[0] == 'v')
+          property->complex = EINA_TRUE;
+     }
+   else if (!strcmp(key, ACCESS_ATTR))
+     {
+        if (!strcmp(value, ACCESS_ATTR_VALUE_READ))
+          property->access = ACCESS_READ;
+        else if (!strcmp(value, ACCESS_ATTR_VALUE_WRITE))
+          property->access = ACCESS_WRITE;
+        else
+          property->access = (ACCESS_WRITE | ACCESS_READ);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+open_object(const char *content, unsigned length, Eina_Bool is_open_empty, DBus_Object **ptr_obj)
+{
+   Eina_Bool r;
+   DBus_Object *obj = *ptr_obj;
+
+   if (is_open_empty) return EINA_TRUE;
+
+   if (obj)
+     {
+        printf("Only one object is supported per file.");
+        return EINA_FALSE;
+     }
+   obj = calloc(1, sizeof(DBus_Object));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
+
+   r = attributes_parse(content, length, obj_attributes_parser, obj);
+   if (!obj->name) obj->name = strdup("/");
+
+   obj->c_name = dbus_name_to_c(obj->name);
+
+   *ptr_obj = obj;
+   return r;
+}
+
+static Eina_Bool
+open_interface(const char *content, unsigned length, Eina_Bool is_open_empty, DBus_Object *obj)
+{
+   Eina_Bool r;
+   char *tmp_name;
+
+   iface = interface_new(obj);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
+
+   r = attributes_parse(content, length, iface_attributes_parser, NULL);
+   if (!iface->name)
+     {
+        interface_free(iface);
+        printf("Error interface without name.\n");
+        return EINA_FALSE;
+     }
+
+   tmp_name = get_pieces(iface->name, '.', 2);
+   iface->c_name = dbus_name_to_c(tmp_name);
+   free(tmp_name);
+
+   return r;
+}
+
+static Eina_Bool
+open_signal(const char *content, unsigned length, Eina_Bool is_open_empty)
+{
+   Eina_Bool r;
+   char *tmp;
+   int i;
+   Eina_Strbuf *buf = eina_strbuf_new();
+
+   d_signal = signal_new(iface);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(d_signal, EINA_FALSE);
+
+   r = attributes_parse(content, length, signal_attributes_parser, NULL);
+   if (!d_signal->name)
+     {
+        signal_free(d_signal);
+        d_signal = NULL;
+        printf("Error signal without name.\n");
+        return EINA_FALSE;
+     }
+
+   tmp = dbus_name_to_c(d_signal->name);
+   d_signal->c_name = string_build("%s_%s", iface->c_name, tmp);
+   free(tmp);
+   d_signal->cb_name = string_build("on_%s", d_signal->c_name);
+   d_signal->free_function = string_build("%s_data_free", d_signal->c_name);
+   d_signal->struct_name = string_build("%s_%s_Data", iface->c_name, d_signal->name);
+   d_signal->struct_name[0] = toupper(d_signal->struct_name[0]);
+   for (i = 0; d_signal->struct_name[i]; i++)
+     {
+        if (d_signal->struct_name[i] == '_' && d_signal->struct_name[i+1])
+          d_signal->struct_name[i+1] = toupper(d_signal->struct_name[i+1]);
+     }
+   for (i = 0; iface->c_name[i]; i++)
+     eina_strbuf_append_char(buf, toupper(iface->c_name[i]));
+   eina_strbuf_append_char(buf, '_');
+   for (i = 0; d_signal->name[i]; i++)
+     {
+        if (i && isupper(d_signal->name[i]) && !isupper(d_signal->name[i-1]))
+          eina_strbuf_append_char(buf, '_');
+        eina_strbuf_append_char(buf, toupper(d_signal->name[i]));
+     }
+   eina_strbuf_append(buf, "_EVENT");
+   d_signal->signal_event = strdup(eina_strbuf_string_get(buf));
+   eina_strbuf_free(buf);
+
+   return r;
+}
+
+#define ANNOTATION_NO_REPLY "org.freedesktop.DBus.Method.NoReply"
+
+static Eina_Bool
+annotation_attributes_parser(void *data, const char *key, const char *value)
+{
+   DBus_Annotation *annotation = data;
+   if (!strcmp(key, NAME_ATTR))
+     {
+        if (!strcmp(value, ANNOTATION_NO_REPLY))
+          annotation->type = NO_REPLY;
+     }
+   else if (!strcmp(key, VALUE_ATTR))
+     {
+        unsigned i;
+        annotation->value = strdup(value);
+        for (i = 0; annotation->value[i]; i++)
+          annotation->value[i] = tolower(annotation->value[i]);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+open_annotation(const char *content, unsigned length)
+{
+   DBus_Annotation annotation;
+   Eina_Bool r;
+
+   annotation.type = INVALID;
+   r = attributes_parse(content, length, annotation_attributes_parser, &annotation);
+
+   if (annotation.type == NO_REPLY)
+     {
+        Eina_Bool value = EINA_FALSE;
+        if (!strcmp(annotation.value, "true"))
+          value = EINA_TRUE;
+        free(annotation.value);
+
+        if (method)
+          method->no_reply = value;
+     }
+
+   return r;
+}
+
+static Eina_Bool
+open_arg(const char *content, unsigned length)
+{
+   Eina_Bool r;
+   unsigned int *without_name;
+   DBus_Arg *arg = calloc(1, sizeof(DBus_Arg));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(arg, EINA_FALSE);
+
+   r = attributes_parse(content, length, arg_attributes_parser, arg);
+   if (d_signal)
+     {
+        d_signal->args = eina_inlist_append(d_signal->args, EINA_INLIST_GET(arg));
+        without_name = &d_signal->arg_without_name;
+     }
+   else if (method)
+     {
+        method->args = eina_inlist_append(method->args, EINA_INLIST_GET(arg));
+        without_name = &method->arg_without_name;
+     }
+   else
+     {
+        printf("Error find an argument without any valid parent.\n");
+        return EINA_FALSE;
+     }
+
+   if (!arg->name)
+     {
+        arg->c_name = string_build("arg%d", *without_name);
+        (*without_name)++;
+     }
+   else
+     arg->c_name = dbus_name_to_c(arg->name);
+
+   return r;
+}
+
+static Eina_Bool
+open_method(const char *content, unsigned lenght)
+{
+   Eina_Bool r;
+   char *tmp;
+   int i;
+
+   method = method_new(iface);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(method, EINA_FALSE);
+
+   r = attributes_parse(content, lenght, method_attributes_parser, NULL);
+   if (!method->name)
+     {
+        method_free(method);
+        method = NULL;
+        printf("Error method without name.\n");
+        return EINA_FALSE;
+     }
+
+   tmp = dbus_name_to_c(method->name);
+   method->c_name = string_build("%s_%s", iface->c_name, tmp);
+   free(tmp);
+   method->cb_name = string_build("cb_%s", method->c_name);
+   method->function_cb = string_build("%s_Cb", method->c_name);
+   method->function_cb[0] = toupper(method->function_cb[0]);
+   for (i = 0; method->function_cb[i]; i++)
+     {
+        if (method->function_cb[i] == '_' && method->function_cb[i+1])
+           method->function_cb[i+1] = toupper(method->function_cb[i+1]);
+     }
+
+   return r;
+}
+
+static Eina_Bool
+open_property(const char *content, unsigned length, Eina_Bool is_open_empty)
+{
+   Eina_Bool r;
+   char *tmp;
+
+   property = property_new(iface);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(property, EINA_FALSE);
+
+   r = attributes_parse(content, length, property_attributes_parser, NULL);
+   if (!property->name)
+     {
+        property_free(property);
+        property = NULL;
+        printf("Error property without name.\n");
+        return EINA_FALSE;
+     }
+
+   tmp = dbus_name_to_c(property->name);
+   property->c_name = string_build("%s_%s", iface->c_name, tmp);
+   free(tmp);
+   property->cb_name = string_build("cb_%s", property->c_name);
+
+   return r;
+}
+
+static Eina_Bool
+open_tag(const char *content, unsigned length, Eina_Bool is_open_empty, DBus_Object **obj)
+{
+   unsigned int i;
+   if (!strncmp(content, OBJECT_TAG, OBJECT_TAG_LENGHT))
+     return open_object(content, length, is_open_empty, obj);
+   else if (!strncmp(content, INTERFACE_TAG, INTERFACE_TAG_LENGHT) && *obj)
+     return open_interface(content, length, is_open_empty, *obj);
+   else if (!strncmp(content, SIGNAL_TAG, SIGNAL_TAG_LENGHT) && iface)
+     return open_signal(content, length, is_open_empty);
+   else if (!strncmp(content, ARG_TAG, ARG_TAG_LENGHT) && iface)
+     return open_arg(content, length);
+   else if (!strncmp(content, ANNOTATION_TAG, ANNOTATION_TAG_LENGHT) && iface)
+     return open_annotation(content, length);
+   else if (!strncmp(content, METHOD_TAG, METHOD_TAG_LENGHT) && iface)
+     return open_method(content, length);
+   else if (!strncmp(content, PROPERTY_TAG, PROPERTY_TAG_LENGHT) && iface)
+     return open_property(content, length, is_open_empty);
+   else if (!strncmp(content, ANNOTATION_TAG, ANNOTATION_TAG_LENGHT) && iface)
+     return EINA_TRUE;
+
+   printf("Warning: Tag not handled:\n");
+   for (i = 0; i < length; i++)
+     printf("%c", content[i]);
+   printf("\n\n");
+
+   return EINA_TRUE;
+}
+
+static void
+interface_close(void)
+{
+   //its not necessary generate code to FreeDesktop interfaces
+   if (!strncmp(iface->name, DBUS_INTERFACE, strlen(DBUS_INTERFACE)))
+     interface_free(iface);
+   iface = NULL;
+}
+
+static void
+signal_close(void)
+{
+   DBus_Arg *arg;
+   EINA_INLIST_FOREACH(d_signal->args, arg)
+     {
+        if ((arg->type[1]) || (arg->type[0] == 'v'))
+          {
+             d_signal->complex = EINA_TRUE;
+             break;
+          }
+     }
+   d_signal = NULL;
+}
+
+static void
+method_close(void)
+{
+   DBus_Arg *arg;
+   EINA_INLIST_FOREACH(method->args, arg)
+     {
+        if ((arg->type[1]) || (arg->type[0] == 'v'))
+          {
+             if (arg->direction == 'o')
+               method->out_complex = EINA_TRUE;
+             else
+               method->in_complex = EINA_TRUE;
+          }
+     }
+   if (method->no_reply)
+     {
+        free(method->cb_name);
+        method->cb_name = strdup("NULL");
+     }
+   method = NULL;
+}
+
+static Eina_Bool
+close_tag(const char *content, unsigned length)
+{
+   if (!strncmp(content, INTERFACE_TAG, INTERFACE_TAG_LENGHT))
+     interface_close();
+   if (!strncmp(content, SIGNAL_TAG, SIGNAL_TAG_LENGHT))
+     signal_close();
+   else if (!strncmp(content, METHOD_TAG, METHOD_TAG_LENGHT))
+     method_close();
+   else if (!strncmp(content, PROPERTY_TAG, PROPERTY_TAG_LENGHT))
+     property = NULL;
+
+   return EINA_TRUE;
+}
+
+Eina_Bool
+parser(void *data, Eina_Simple_XML_Type type, const char *content, unsigned offset, unsigned length)
+{
+   Eina_Bool r = EINA_TRUE;
+   DBus_Object **obj = data;
+
+   switch (type)
+     {
+      case EINA_SIMPLE_XML_OPEN:
+      case EINA_SIMPLE_XML_OPEN_EMPTY:
+        {
+           r = open_tag(content, length, type == EINA_SIMPLE_XML_OPEN_EMPTY,
+                        obj);
+           break;
+        }
+      case EINA_SIMPLE_XML_CLOSE:
+        {
+           r = close_tag(content, length);
+           break;
+        }
+      default:
+        break;
+     }
+   return r;
+}
+
+static Eina_Bool
+attributes_parse(const char *content, unsigned length, Eina_Simple_XML_Attribute_Cb func, const void *data)
+{
+   const char *attrs = eina_simple_xml_tag_attributes_find(content, length);
+   unsigned attrslen = 0;
+   if (attrs)
+     {
+        attrslen = length - (attrs - content);
+        if (!eina_simple_xml_attributes_parse(attrs, attrslen, func, data))
+          {
+             printf("Parser error - attrs=%s | content=%s\n", attrs, content);
+             return EINA_FALSE;
+          }
+     }
+   return EINA_TRUE;
+}
diff --git a/legacy/edbus/src/codegen/source_client.c b/legacy/edbus/src/codegen/source_client.c
new file mode 100644 (file)
index 0000000..536b47d
--- /dev/null
@@ -0,0 +1,629 @@
+#include "codegen.h"
+
+static const char *code_prefix = NULL;
+static char buffer[4028];
+
+static const char *
+prefix_append(const char *text)
+{
+   if (code_prefix)
+     {
+        sprintf(buffer, "%s_%s", code_prefix, text);
+        return buffer;
+     }
+   return text;
+}
+
+static const char *
+dbus_type2c_type2(const char *dbus_type, Eina_Bool with_const)
+{
+   switch (dbus_type[0])
+     {
+      case 's'://string
+      case 'o'://object path
+      case 'g'://signature
+        {
+           if (with_const)
+             return "const char *";
+           else
+             return "char *";
+        }
+      case 'h'://file descriptor
+      case 'i'://int
+        return "int ";
+      case 'y'://byte
+        return "unsigned char ";
+      case 'b'://bool
+        return "Eina_Bool ";
+      case 'n'://int16
+        return "short int ";
+      case 'q'://uint16
+        return "unsigned short int ";
+      case 'u'://uint32
+        return "unsigned int ";
+      case 'x'://int64
+        return "int64_t ";
+      case 't'://uint64
+        return "uint64_t ";
+      case 'd'://double
+        return "double ";
+      case 'a'://array
+      case 'v'://variant
+      case '{'://dict
+      case '('://struct
+        return "EDBus_Message_Iter *";
+      default:
+        {
+           printf("Error type not handled: %c\n", dbus_type[0]);
+           return NULL;
+        }
+     }
+}
+
+static const char *
+dbus_type2c_type(const char *dbus_type)
+{
+   return dbus_type2c_type2(dbus_type, EINA_TRUE);
+}
+
+static void
+source_client_complex_method_call_generate(const DBus_Method *method, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   DBus_Arg *arg;
+   Eina_Strbuf *full_signature = eina_strbuf_new();
+
+   EINA_INLIST_FOREACH(method->args, arg)
+     {
+        if (arg->direction == 'o')
+          continue;
+        eina_strbuf_append(full_signature, arg->type);
+     }
+
+   if (method->no_reply)
+     {
+        eina_strbuf_append_printf(h, "void %s_call(EDBus_Proxy *proxy, Eina_Value *args);\n", prefix_append(method->c_name));
+
+        eina_strbuf_append_printf(c_code, "\nvoid \n%s_call(EDBus_Proxy *proxy, Eina_Value *args)\n{\n", prefix_append(method->c_name));
+        eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN(proxy);\n");
+        eina_strbuf_append_printf(c_code, "   EDBus_Message *msg = edbus_proxy_method_call_new(proxy, \"%s\");\n", method->name);
+        eina_strbuf_append_printf(c_code, "   if (!edbus_message_from_eina_value(\"%s\", msg, args))\n", eina_strbuf_string_get(full_signature));
+        eina_strbuf_append_printf(c_code, "     {\n");
+        eina_strbuf_append_printf(c_code, "        ERR(\"Error: Filling message from eina value.\");\n");
+        eina_strbuf_append_printf(c_code, "        return;\n");
+        eina_strbuf_append_printf(c_code, "     }\n");
+        eina_strbuf_append_printf(c_code, "   edbus_proxy_send(proxy, msg, %s, NULL, NULL, -1);\n", method->cb_name);
+        eina_strbuf_append_printf(c_code, "}\n");
+        goto end;
+     }
+
+   eina_strbuf_append_printf(h, "EDBus_Pending *%s_call", prefix_append(method->c_name));
+   eina_strbuf_append_printf(h, "(EDBus_Proxy *proxy, %s cb, const void *data, Eina_Value *args);\n", prefix_append(method->function_cb));
+
+   eina_strbuf_append_printf(c_code, "\nEDBus_Pending *\n%s_call(", prefix_append(method->c_name));
+   eina_strbuf_append_printf(c_code, "EDBus_Proxy *proxy, %s cb, const void *data, Eina_Value *args)\n{\n", prefix_append(method->function_cb));
+   eina_strbuf_append_printf(c_code, "   EDBus_Message *msg;\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Pending *p;\n");
+   eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);\n");
+   eina_strbuf_append_printf(c_code, "   msg = edbus_proxy_method_call_new(proxy, \"%s\");\n", method->name);
+   eina_strbuf_append_printf(c_code, "   if (!edbus_message_from_eina_value(\"%s\", msg, args))\n", eina_strbuf_string_get(full_signature));
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        ERR(\"Error: Filling message from eina value.\");\n");
+   eina_strbuf_append_printf(c_code, "        return NULL;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append_printf(c_code, "   p = edbus_proxy_send(proxy, msg, %s, cb, -1);\n", method->cb_name);
+   eina_strbuf_append_printf(c_code, "   if (data)\n");
+   eina_strbuf_append_printf(c_code, "     edbus_pending_data_set(p, \"__user_data\", data);\n");
+   eina_strbuf_append_printf(c_code, "   edbus_pending_data_set(p, \"__proxy\", proxy);\n");
+   eina_strbuf_append_printf(c_code, "   return p;\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+
+end:
+   eina_strbuf_free(full_signature);
+}
+
+static void
+source_client_simple_method_call_no_reply_generate(const DBus_Method *method, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   DBus_Arg *arg;
+   Eina_Strbuf *full_signature = eina_strbuf_new();
+   Eina_Strbuf *args_call = eina_strbuf_new();
+
+   eina_strbuf_append_printf(h, "void %s_call(EDBus_Proxy *proxy", prefix_append(method->c_name));
+   eina_strbuf_append_printf(c_code, "\nvoid\n%s_call(EDBus_Proxy *proxy", prefix_append(method->c_name));
+
+   EINA_INLIST_FOREACH(method->args, arg)
+     {
+        if (arg->direction == 'o')
+          continue;
+        eina_strbuf_append(full_signature, arg->type);
+        eina_strbuf_append_printf(h, ", %s%s", dbus_type2c_type(arg->type), arg->c_name);
+        eina_strbuf_append_printf(c_code, ", %s%s", dbus_type2c_type(arg->type), arg->c_name);
+        eina_strbuf_append_printf(args_call, ", %s", arg->c_name);
+     }
+   eina_strbuf_append_printf(h, ");\n");
+   eina_strbuf_append_printf(c_code, ")\n{\n");
+
+   eina_strbuf_append_printf(c_code, "   EDBus_Message *msg;\n");
+   eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN(proxy);\n");
+   eina_strbuf_append_printf(c_code, "   msg = edbus_proxy_method_call_new(proxy, \"%s\");\n", method->name);
+   eina_strbuf_append_printf(c_code, "   if (!edbus_message_arguments_append(msg, \"%s\"%s))\n", eina_strbuf_string_get(full_signature), eina_strbuf_string_get(args_call));
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        ERR(\"Error: Filling message.\");\n");
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append_printf(c_code, "   edbus_proxy_send(proxy, msg, NULL, NULL, -1);\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+
+   eina_strbuf_free(full_signature);
+   eina_strbuf_free(args_call);
+}
+
+static void
+source_client_simple_method_call_generate(const DBus_Method *method, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   DBus_Arg *arg;
+   Eina_Strbuf *full_signature = eina_strbuf_new();
+   Eina_Strbuf *args_call = eina_strbuf_new();
+
+   eina_strbuf_append_printf(h, "EDBus_Pending *%s_call", prefix_append(method->c_name));
+   eina_strbuf_append_printf(h, "(EDBus_Proxy *proxy, %s cb, const void *data", prefix_append(method->function_cb));
+   eina_strbuf_append_printf(c_code, "\nEDBus_Pending *\n%s_call", prefix_append(method->c_name));
+   eina_strbuf_append_printf(c_code, "(EDBus_Proxy *proxy, %s cb, const void *data", prefix_append(method->function_cb));
+
+   EINA_INLIST_FOREACH(method->args, arg)
+     {
+        if (arg->direction == 'o')
+          continue;
+        eina_strbuf_append(full_signature, arg->type);
+        eina_strbuf_append_printf(h, ", %s%s", dbus_type2c_type(arg->type), arg->c_name);
+        eina_strbuf_append_printf(c_code, ", %s%s", dbus_type2c_type(arg->type), arg->c_name);
+        eina_strbuf_append_printf(args_call, ", %s", arg->c_name);
+     }
+   eina_strbuf_append_printf(h, ");\n");
+   eina_strbuf_append_printf(c_code,")\n{\n");
+
+   eina_strbuf_append_printf(c_code, "   EDBus_Message *msg;\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Pending *p;\n");
+   eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);\n");
+   eina_strbuf_append_printf(c_code, "   msg = edbus_proxy_method_call_new(proxy, \"%s\");\n", method->name);
+   eina_strbuf_append_printf(c_code, "   if (!edbus_message_arguments_append(msg, \"%s\"%s))\n", eina_strbuf_string_get(full_signature), eina_strbuf_string_get(args_call));
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        ERR(\"Error: Filling message.\");\n");
+   eina_strbuf_append_printf(c_code, "        return NULL;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append_printf(c_code, "   p = edbus_proxy_send(proxy, msg, %s, cb, -1);\n", method->cb_name);
+   eina_strbuf_append_printf(c_code, "   if (data)\n");
+   eina_strbuf_append_printf(c_code, "     edbus_pending_data_set(p, \"__user_data\", data);\n");
+   eina_strbuf_append_printf(c_code, "   edbus_pending_data_set(p, \"__proxy\", proxy);\n");
+   eina_strbuf_append_printf(c_code, "   return p;\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+
+   eina_strbuf_free(full_signature);
+   eina_strbuf_free(args_call);
+}
+
+static void
+source_client_complex_method_callback_generate(const DBus_Method *method, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   eina_strbuf_append_printf(h, "typedef void (*%s)(EDBus_Proxy *proxy, void *data, EDBus_Pending *pending, EDBus_Error_Info *error, Eina_Value *args);\n", prefix_append(method->function_cb));
+
+   eina_strbuf_append_printf(c_code, "\nstatic void\n%s(void *data, const EDBus_Message *msg, EDBus_Pending *pending)\n{\n", method->cb_name);
+   eina_strbuf_append_printf(c_code, "   void *user_data = edbus_pending_data_del(pending, \"__user_data\");\n");
+   eina_strbuf_append_printf(c_code, "   %s cb = data;\n", prefix_append(method->function_cb));
+   eina_strbuf_append_printf(c_code, "   const char *error, *error_msg;\n");
+   eina_strbuf_append_printf(c_code, "   Eina_Value *value;\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Proxy *proxy = edbus_pending_data_del(pending, \"__proxy\");\n");
+   eina_strbuf_append_printf(c_code, "   if (edbus_message_error_get(msg, &error, &error_msg))\n");
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {error, error_msg};\n");
+   eina_strbuf_append_printf(c_code, "        cb(proxy, user_data, pending, &error_info, NULL);\n");
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append_printf(c_code, "   value = edbus_message_to_eina_value(msg);\n");
+   eina_strbuf_append_printf(c_code, "   cb(proxy, user_data, pending, NULL, value);\n");
+   eina_strbuf_append_printf(c_code, "   eina_value_free(value);\n");
+   eina_strbuf_append_printf(c_code, "   return;\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+}
+
+static void
+source_client_simple_method_callback_generate(const DBus_Method *method, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   Eina_Strbuf *full_signature = eina_strbuf_new();
+   DBus_Arg *arg;
+   Eina_Strbuf *end_cb = eina_strbuf_new();
+   Eina_Strbuf *arguments_get = eina_strbuf_new();
+
+   eina_strbuf_append_printf(h, "typedef void (*%s)(EDBus_Proxy *proxy, void *data, EDBus_Pending *pending, EDBus_Error_Info *error", prefix_append(method->function_cb));
+
+   eina_strbuf_append_printf(c_code, "\nstatic void\n%s(void *data, const EDBus_Message *msg, EDBus_Pending *pending)\n{\n", method->cb_name);
+   eina_strbuf_append_printf(c_code, "   void *user_data = edbus_pending_data_del(pending, \"__user_data\");\n");
+   eina_strbuf_append_printf(c_code, "   %s cb = data;\n", prefix_append(method->function_cb));
+   eina_strbuf_append_printf(c_code, "   const char *error, *error_msg;\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Proxy *proxy = edbus_pending_data_del(pending, \"__proxy\");\n");
+
+   EINA_INLIST_FOREACH(method->args, arg)
+     {
+        if (arg->direction != 'o')
+          continue;
+        eina_strbuf_append(full_signature, arg->type);
+        eina_strbuf_append_printf(h, ", %s%s", dbus_type2c_type(arg->type), arg->c_name);
+        eina_strbuf_append_printf(c_code, "   %s%s;\n", dbus_type2c_type(arg->type), arg->c_name);
+        eina_strbuf_append_printf(end_cb, ", %s", arg->c_name);
+        eina_strbuf_append_printf(arguments_get, ", &%s", arg->c_name);
+     }
+   eina_strbuf_append_printf(h, ");\n");
+
+   eina_strbuf_append_printf(c_code, "   if (edbus_message_error_get(msg, &error, &error_msg))\n");
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {error, error_msg};\n");
+   eina_strbuf_append_printf(c_code, "        cb(proxy, user_data, pending, &error_info%s);\n", eina_strbuf_string_get(end_cb));
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+
+   eina_strbuf_append_printf(c_code, "   if (!edbus_message_arguments_get(msg, \"%s\"%s))\n", eina_strbuf_string_get(full_signature), eina_strbuf_string_get(arguments_get));
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {\"\", \"\"};\n");
+   eina_strbuf_append_printf(c_code, "        ERR(\"Error: Getting arguments from message.\");\n");
+   eina_strbuf_append_printf(c_code, "        cb(proxy, user_data, pending, &error_info%s);\n", eina_strbuf_string_get(end_cb));
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append_printf(c_code, "   cb(proxy, user_data, pending, NULL%s);\n", eina_strbuf_string_get(end_cb));
+   eina_strbuf_append_printf(c_code, "   return;\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+
+   eina_strbuf_free(full_signature);
+   eina_strbuf_free(end_cb);
+   eina_strbuf_free(arguments_get);
+}
+
+static void
+source_client_method_generate(const DBus_Method *method, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   if (!method->no_reply)
+     {
+        if (method->out_complex)
+          source_client_complex_method_callback_generate(method, c_code, h);
+        else
+          source_client_simple_method_callback_generate(method, c_code, h);
+     }
+
+   if (method->in_complex)
+     source_client_complex_method_call_generate(method, c_code, h);
+   else
+     {
+        if (method->no_reply)
+          source_client_simple_method_call_no_reply_generate(method, c_code, h);
+        else
+          source_client_simple_method_call_generate(method, c_code, h);
+     }
+}
+
+static void
+source_client_signal_generate(const DBus_Signal *signal, Eina_Strbuf *c_code, Eina_Strbuf * h, Eina_Strbuf *c_init_function, Eina_Strbuf *c_header)
+{
+   DBus_Arg *arg;
+   Eina_Strbuf *full_signature = eina_strbuf_new();
+   Eina_Strbuf *parameters = eina_strbuf_new();
+   Eina_Strbuf *string_copy = eina_strbuf_new();
+   Eina_Strbuf *string_free = eina_strbuf_new();
+
+   eina_strbuf_append_printf(c_init_function, "   edbus_proxy_signal_handler_add(proxy, \"%s\", %s, proxy);\n", signal->name, signal->cb_name);
+   eina_strbuf_append_printf(c_header, "int %s;\n", signal->signal_event);
+   eina_strbuf_append_printf(h, "extern int %s;\n", signal->signal_event);
+   eina_strbuf_append_printf(c_init_function, "   if (!%s)\n", signal->signal_event);
+   eina_strbuf_append_printf(c_init_function, "     %s = ecore_event_type_new();\n", signal->signal_event);
+
+   eina_strbuf_append_printf(h, "typedef struct _%s\n", signal->struct_name);
+   eina_strbuf_append_printf(h, "{\n");
+   eina_strbuf_append_printf(h, "   EDBus_Proxy *proxy;\n");
+
+   if (signal->complex)
+     {
+        eina_strbuf_append_printf(h, "   Eina_Value *value;\n");
+        goto jump_simple_stuff;
+     }
+
+   EINA_INLIST_FOREACH(signal->args, arg)
+     {
+        eina_strbuf_append(full_signature, arg->type);
+        eina_strbuf_append_printf(parameters, ", &s_data->%s", arg->c_name);
+        eina_strbuf_append_printf(h, "   %s%s;\n", dbus_type2c_type2(arg->type, EINA_FALSE), arg->c_name);
+
+        if (!strcmp(arg->type, "s") || !strcmp(arg->type, "o"))
+          {
+             eina_strbuf_append_printf(string_copy, "   s_data->%s = strdup(s_data->%s);\n", arg->c_name, arg->c_name);
+             eina_strbuf_append_printf(string_free, "   free(s_data->%s);\n", arg->c_name);
+          }
+     }
+
+jump_simple_stuff:
+   eina_strbuf_append_printf(h, "} %s;\n", signal->struct_name);
+
+   //free function
+   eina_strbuf_append_printf(c_code, "\nstatic void\n%s(void *user_data, void *func_data)\n{\n", signal->free_function);
+   eina_strbuf_append_printf(c_code, "   %s *s_data = user_data;\n", signal->struct_name);
+   if (signal->complex)
+     eina_strbuf_append(c_code, "   eina_value_free(s_data->proxy);\n");
+   else
+     eina_strbuf_append(c_code, eina_strbuf_string_get(string_free));
+   eina_strbuf_append_printf(c_code, "   free(s_data);\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+
+   //cb function
+   eina_strbuf_append_printf(c_code, "\nstatic void\n%s(void *data, const EDBus_Message *msg)\n{\n", signal->cb_name);
+   eina_strbuf_append_printf(c_code, "   EDBus_Proxy *proxy = data;\n");
+   eina_strbuf_append_printf(c_code, "   %s *s_data = calloc(1, sizeof(%s));\n", signal->struct_name, signal->struct_name);
+   eina_strbuf_append_printf(c_code, "   s_data->proxy = proxy;\n");
+   if (signal->complex)
+     {
+        eina_strbuf_append_printf(c_code, "   s_data->value = edbus_message_to_eina_value(msg);\n");
+        goto end_signal;
+     }
+   eina_strbuf_append_printf(c_code, "   if (!edbus_message_arguments_get(msg, \"%s\"%s))\n", eina_strbuf_string_get(full_signature), eina_strbuf_string_get(parameters));
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        ERR(\"Error: Getting arguments from message.\");\n");
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append(c_code, eina_strbuf_string_get(string_copy));
+
+end_signal:
+   eina_strbuf_append_printf(c_code, "   ecore_event_add(%s, s_data, %s, NULL);\n", signal->signal_event, signal->free_function);
+   eina_strbuf_append_printf(c_code, "}\n");
+
+   eina_strbuf_free(full_signature);
+   eina_strbuf_free(parameters);
+   eina_strbuf_free(string_copy);
+   eina_strbuf_free(string_free);
+}
+
+static const char *
+prop_cb_get(const DBus_Property *prop)
+{
+   if (prop->complex)
+     return "EDBus_Codegen_Property_Complex_Get_Cb";
+   switch (prop->type[0])
+     {
+      case 's':
+      case 'o':
+        return "EDBus_Codegen_Property_String_Get_Cb";
+      case 'i':
+      case 'h':
+        return "EDBus_Codegen_Property_Int32_Get_Cb";
+      case 'y':
+         return "EDBus_Codegen_Property_Byte_Get_Cb";
+      case 'b':
+         return "EDBus_Codegen_Property_Bool_Get_Cb";
+      case 'n':
+         return "EDBus_Codegen_Property_Int16_Get_Cb";
+      case 'q':
+         return "EDBus_Codegen_Property_Uint16_Get_Cb";
+      case 'u':
+         return "EDBus_Codegen_Property_Uint32_Get_Cb";
+      case 'd':
+         return "EDBus_Codegen_Property_Double_Get_Cb";
+      case 'x':
+         return "EDBus_Codegen_Property_Int64_Get_Cb";
+      case 't':
+         return "EDBus_Codegen_Property_Uint64_Get_Cb";
+      default:
+         return "Unexpected_type";
+     }
+}
+
+static const char *
+null_or_zero(const char *type)
+{
+   if (type[0] == 's' || type[0] == 'o' || type[0] == 'v' || type[1])
+     return "NULL";
+   return "0";
+}
+
+static void
+source_client_property_generate_get(const DBus_Property *prop, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   //callback
+   eina_strbuf_append_printf(c_code, "\nstatic void\n%s(void *data, const EDBus_Message *msg, EDBus_Pending *pending)\n{\n", prop->cb_name);
+   eina_strbuf_append_printf(c_code, "   void *user_data = edbus_pending_data_del(pending, \"__user_data\");\n");
+   eina_strbuf_append_printf(c_code, "   const char *error, *error_msg;\n");
+   eina_strbuf_append_printf(c_code, "   %s cb = data;\n", prop_cb_get(prop));
+   eina_strbuf_append_printf(c_code, "   EDBus_Proxy *proxy = edbus_pending_data_del(pending, \"__proxy\");\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Message_Iter *variant;\n");
+   if (prop->complex)
+     eina_strbuf_append_printf(c_code, "   Eina_Value *v, stack_value;\n");
+   else
+     eina_strbuf_append_printf(c_code, "   %sv;\n", dbus_type2c_type(prop->type));
+   eina_strbuf_append_printf(c_code, "   if (edbus_message_error_get(msg, &error, &error_msg))\n");
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {error, error_msg};\n");
+   eina_strbuf_append_printf(c_code, "        cb(user_data, pending, \"%s\", proxy, &error_info, %s);\n", prop->name, null_or_zero(prop->type));
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+
+   eina_strbuf_append_printf(c_code, "   if (!edbus_message_arguments_get(msg, \"v\", &variant))\n");
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {\"\", \"\"};\n");
+   eina_strbuf_append_printf(c_code, "        cb(user_data, pending, \"%s\", proxy, &error_info, %s);\n", prop->name, null_or_zero(prop->type));
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+
+   if (prop->complex)
+     {
+        eina_strbuf_append_printf(c_code, "   v = edbus_message_iter_struct_like_to_eina_value(variant);\n");
+        eina_strbuf_append_printf(c_code, "   eina_value_struct_value_get(v, \"arg0\", &stack_value);\n");
+        eina_strbuf_append_printf(c_code, "   cb(user_data, pending, \"%s\", proxy, NULL, &stack_value);\n", prop->name);
+        eina_strbuf_append_printf(c_code, "   eina_value_flush(&stack_value);\n");
+        eina_strbuf_append_printf(c_code, "   eina_value_free(v);\n");
+     }
+   else
+     {
+        eina_strbuf_append_printf(c_code, "   if (!edbus_message_iter_arguments_get(variant, \"%s\", &v))\n", prop->type);
+        eina_strbuf_append_printf(c_code, "     {\n");
+        eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {\"\", \"\"};\n");
+        eina_strbuf_append_printf(c_code, "        cb(user_data, pending, \"%s\", proxy, &error_info, %s);\n", prop->name, null_or_zero(prop->type));
+        eina_strbuf_append_printf(c_code, "        return;\n");
+        eina_strbuf_append_printf(c_code, "     }\n");
+        eina_strbuf_append_printf(c_code, "   cb(user_data, pending, \"%s\", proxy, NULL, v);\n", prop->name);
+     }
+   eina_strbuf_append_printf(c_code, "}\n");
+
+   //call
+   eina_strbuf_append_printf(h, "EDBus_Pending *%s_propget(EDBus_Proxy *proxy, %s cb, const void *data);\n", prefix_append(prop->c_name), prop_cb_get(prop));
+
+   eina_strbuf_append_printf(c_code, "\nEDBus_Pending *\n%s_propget(EDBus_Proxy *proxy, %s cb, const void *data)\n{\n", prefix_append(prop->c_name), prop_cb_get(prop));
+   eina_strbuf_append_printf(c_code, "   EDBus_Pending *p;\n");
+   eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);\n");
+   eina_strbuf_append_printf(c_code, "   p = edbus_proxy_property_get(proxy, \"%s\", %s, cb);\n", prop->name, prop->cb_name);
+   eina_strbuf_append_printf(c_code, "   if (data)\n");
+   eina_strbuf_append_printf(c_code, "     edbus_pending_data_set(p, \"__user_data\", data);\n");
+   eina_strbuf_append_printf(c_code, "   edbus_pending_data_set(p, \"__proxy\", proxy);\n");
+   eina_strbuf_append_printf(c_code, "   return p;\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+}
+
+static void
+source_client_property_generate_set(const DBus_Property *prop, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   //callback
+   eina_strbuf_append_printf(c_code, "\nstatic void\n%s_set(void *data, const EDBus_Message *msg, EDBus_Pending *pending)\n{\n", prop->cb_name);
+   eina_strbuf_append_printf(c_code, "   const char *error, *error_msg;\n");
+   eina_strbuf_append_printf(c_code, "   void *user_data = edbus_pending_data_del(pending, \"__user_data\");\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Proxy *proxy = edbus_pending_data_del(pending, \"__proxy\");\n");
+   eina_strbuf_append_printf(c_code, "   EDBus_Codegen_Property_Set_Cb cb = data;\n");
+   eina_strbuf_append_printf(c_code, "   if (edbus_message_error_get(msg, &error, &error_msg))");
+   eina_strbuf_append_printf(c_code, "     {\n");
+   eina_strbuf_append_printf(c_code, "        EDBus_Error_Info error_info = {error, error_msg};\n\n");
+   eina_strbuf_append_printf(c_code, "        cb(user_data, \"%s\", proxy, pending, &error_info);\n", prop->name);
+   eina_strbuf_append_printf(c_code, "        return;\n");
+   eina_strbuf_append_printf(c_code, "     }\n");
+   eina_strbuf_append_printf(c_code, "   cb(user_data, \"%s\", proxy, pending, NULL);\n", prop->name);
+   eina_strbuf_append_printf(c_code, "}\n");
+
+    //call
+   eina_strbuf_append_printf(h, "EDBus_Pending *%s_propset(EDBus_Proxy *proxy, EDBus_Codegen_Property_Set_Cb cb, const void *data, const void *value);\n", prefix_append(prop->c_name));
+
+   eina_strbuf_append_printf(c_code, "\nEDBus_Pending *\n%s_propset(EDBus_Proxy *proxy, EDBus_Codegen_Property_Set_Cb cb, const void *data, const void *value)\n{\n", prop->c_name);
+   eina_strbuf_append_printf(c_code, "   EDBus_Pending *p;\n");
+   eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);\n");
+   eina_strbuf_append_printf(c_code, "   EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL);\n");
+   eina_strbuf_append_printf(c_code, "   p = edbus_proxy_property_set(proxy, \"%s\", \"%s\", value, %s_set, data);\n", prop->name, prop->type, prop->cb_name);
+   eina_strbuf_append_printf(c_code, "   edbus_pending_data_set(p, \"__user_data\", data);\n");
+   eina_strbuf_append_printf(c_code, "   edbus_pending_data_set(p, \"__proxy\", proxy);\n");
+   eina_strbuf_append_printf(c_code, "   return p;\n");
+   eina_strbuf_append_printf(c_code, "}\n");
+}
+
+static void
+source_client_property_generate(const DBus_Property *prop, Eina_Strbuf *c_code, Eina_Strbuf *h)
+{
+   if ((prop->access & ACCESS_READ) == ACCESS_READ)
+     source_client_property_generate_get(prop, c_code, h);
+   if ((prop->access & ACCESS_WRITE) == ACCESS_WRITE)
+     source_client_property_generate_set(prop, c_code, h);
+}
+
+void
+source_client_generate(DBus_Object *path, const char *prefix, const char *interface_name, const char *output_name)
+{
+   DBus_Interface *iface;
+   Eina_Bool found = EINA_FALSE;
+   code_prefix = prefix;
+   EINA_INLIST_FOREACH(path->ifaces, iface)
+     {
+        Eina_Strbuf *h, *c_init_function, *c_header, *c_code;
+        DBus_Method *method;
+        DBus_Signal *signal;
+        DBus_Property *prop;
+        char *file_name, *aux;
+        int i;
+
+        if (interface_name && strcmp(interface_name, iface->name))
+          continue;
+        found = EINA_TRUE;
+        h = eina_strbuf_new();//.h file
+        c_init_function = eina_strbuf_new();
+        c_header = eina_strbuf_new();
+        c_code = eina_strbuf_new();
+
+        aux = string_build("EDBUS_%s_H", iface->c_name);
+        for (i = 0; aux[i]; i++)
+          aux[i] = toupper(aux[i]);
+        eina_strbuf_append_printf(h, "#ifndef %s\n", aux);
+        eina_strbuf_append_printf(h, "#define %s\n\n", aux);
+        free(aux);
+
+        eina_strbuf_append_printf(h, "#include <Eina.h>\n");
+        eina_strbuf_append_printf(h, "#include <Ecore.h>\n");
+        eina_strbuf_append_printf(h, "#include <EDBus.h>\n");
+        eina_strbuf_append_printf(h, "#include \"edbus_utils.h\"\n\n");
+        eina_strbuf_append_printf(h, "EDBus_Proxy *%s_proxy_get(EDBus_Connection *conn, const char *bus, const char *path);\n", prefix_append(iface->c_name));
+        eina_strbuf_append_printf(h, "void %s_proxy_unref(EDBus_Proxy *proxy);\n", prefix_append(iface->c_name));
+        eina_strbuf_append_printf(h, "void %s_log_domain_set(int id);\n", prefix_append(iface->c_name));
+
+        if (interface_name && output_name)
+          eina_strbuf_append_printf(c_header, "#include \"%s.h\"\n\n", output_name);
+        else
+          eina_strbuf_append_printf(c_header, "#include \"edbus_%s.h\"\n\n", iface->c_name);
+
+        eina_strbuf_append_printf(c_header, "static int _log_main = -1;\n");
+        eina_strbuf_append_printf(c_header, "#undef ERR\n");
+        eina_strbuf_append_printf(c_header, "#define ERR(...) EINA_LOG_DOM_ERR(_log_main, __VA_ARGS__);\n");
+
+        eina_strbuf_append_printf(c_init_function, "void\n%s_log_domain_set(int id)\n{\n", prefix_append(iface->c_name));
+        eina_strbuf_append_printf(c_init_function, "   _log_main = id;\n");
+        eina_strbuf_append_printf(c_init_function, "}\n");
+
+        eina_strbuf_append_printf(c_init_function, "\nvoid\n%s_proxy_unref(EDBus_Proxy *proxy)\n{\n", prefix_append(iface->c_name));
+        eina_strbuf_append_printf(c_init_function, "   EDBus_Object *obj = edbus_proxy_object_get(proxy);\n");
+        eina_strbuf_append_printf(c_init_function, "   edbus_proxy_unref(proxy);\n");
+        eina_strbuf_append_printf(c_init_function, "   edbus_object_unref(obj);\n");
+        eina_strbuf_append_printf(c_init_function, "}\n");
+
+        eina_strbuf_append_printf(c_init_function, "\nEDBus_Proxy *\n%s_proxy_get(EDBus_Connection *conn, const char *bus, const char *path)\n{\n", prefix_append(iface->c_name));
+        eina_strbuf_append_printf(c_init_function, "   EDBus_Object *obj;\n");
+        eina_strbuf_append_printf(c_init_function, "   EDBus_Proxy *proxy;\n");
+        eina_strbuf_append_printf(c_init_function, "   EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);\n");
+        eina_strbuf_append_printf(c_init_function, "   EINA_SAFETY_ON_NULL_RETURN_VAL(bus, NULL);\n");
+        eina_strbuf_append_printf(c_init_function, "   if (!path) path = \"%s\";\n", path->name);
+        eina_strbuf_append_printf(c_init_function, "   obj = edbus_object_get(conn, bus, path);\n");
+        eina_strbuf_append_printf(c_init_function, "   proxy = edbus_proxy_get(obj, \"%s\");\n", iface->name);
+
+        EINA_INLIST_FOREACH(iface->methods, method)
+          source_client_method_generate(method, c_code, h);
+
+        EINA_INLIST_FOREACH(iface->signals, signal)
+          source_client_signal_generate(signal, c_code, h, c_init_function, c_header);
+
+        EINA_INLIST_FOREACH(iface->properties, prop)
+          source_client_property_generate(prop, c_code, h);
+
+        eina_strbuf_append_printf(c_init_function, "   return proxy;\n");
+        eina_strbuf_append_printf(c_init_function, "}\n");
+
+        eina_strbuf_append(h, "\n#endif");
+
+        if (interface_name && output_name)
+          file_name = string_build("%s.h", output_name);
+        else
+          file_name = string_build("edbus_%s.h", iface->c_name);
+        file_write(file_name, eina_strbuf_string_get(h));
+        eina_strbuf_free(h);
+        free(file_name);
+
+        eina_strbuf_append(c_header, eina_strbuf_string_get(c_code));
+        eina_strbuf_free(c_code);
+        eina_strbuf_append(c_header, "\n");
+        eina_strbuf_append(c_header, eina_strbuf_string_get(c_init_function));
+        eina_strbuf_free(c_init_function);
+        if (interface_name && output_name)
+          file_name = string_build("%s.c", output_name);
+        else
+          file_name = string_build("edbus_%s.c", iface->c_name);
+        file_write(file_name, eina_strbuf_string_get(c_header));
+        eina_strbuf_free(c_header);
+        free(file_name);
+     }
+
+   if (interface_name && !found)
+     printf("Error: Interface %s not found.\n", interface_name);
+}
diff --git a/legacy/edbus/src/codegen/utils.c b/legacy/edbus/src/codegen/utils.c
new file mode 100644 (file)
index 0000000..a7d6273
--- /dev/null
@@ -0,0 +1,166 @@
+#include "codegen.h"
+#include <ctype.h>
+
+Eina_Bool
+file_read(const char *file_name, char **buffer)
+{
+   FILE *xml_handler;
+   char data;
+   Eina_Strbuf *buf;
+
+   xml_handler = fopen(file_name, "rt");
+   if (!xml_handler)
+     {
+        printf("Error to read file: %s\n", file_name);
+        return EINA_FALSE;
+     }
+   buf = eina_strbuf_new();
+
+   while ((data = fgetc(xml_handler)) != EOF)
+     eina_strbuf_append_char(buf, data);
+
+   fclose(xml_handler);
+   *buffer = strdup(eina_strbuf_string_get(buf));
+   eina_strbuf_free(buf);
+
+   return EINA_TRUE;
+}
+
+Eina_Bool
+file_write(const char *file_name, const char *buffer)
+{
+   FILE *file_handler;
+
+   file_handler = fopen(file_name, "wt");
+   if (!file_handler)
+     {
+        printf("Error to write file: %s\n", file_name);
+        return EINA_FALSE;
+     }
+
+   fwrite(buffer, strlen(buffer), 1, file_handler);
+   fclose(file_handler);
+
+   return EINA_TRUE;
+}
+
+char *
+dbus_name_to_c(const char *dbus)
+{
+   char *str_cpy = strdup(dbus), *pch, *ret;
+   Eina_Strbuf *buffer = eina_strbuf_new();
+   unsigned i;
+
+   pch = strtok(str_cpy, "/.");
+   if (!pch)
+     {
+        ret = strdup("root");
+        goto end;
+     }
+   eina_strbuf_append(buffer, pch);
+
+   while ((pch = strtok(NULL, "/.")))
+     eina_strbuf_append_printf(buffer, "_%s",pch);
+
+   ret = strdup(eina_strbuf_string_get(buffer));
+   eina_strbuf_reset(buffer);
+   for (i = 0; ret[i]; i++)
+     {
+        if (i > 0 && ret[i-1] != '_' && ret[i] > '@' && ret[i] < '[')//upper case
+          eina_strbuf_append_printf(buffer, "_%c", tolower(ret[i]));
+        else
+          eina_strbuf_append_char(buffer, tolower(ret[i]));
+     }
+   free(ret);
+   ret = strdup(eina_strbuf_string_get(buffer));
+end:
+   free(str_cpy);
+   eina_strbuf_free(buffer);
+   return ret;
+}
+
+char *
+replace_string(const char *string, const char *substr, const char *replacement)
+{
+   char *str_cpy = strdup(string);
+   char *pch;
+   char *ret;
+   Eina_Strbuf *buffer = eina_strbuf_new();
+
+   pch = strtok(str_cpy, substr);
+   eina_strbuf_append(buffer, pch);
+
+   while ((pch = strtok(NULL, substr)))
+     eina_strbuf_append_printf(buffer, "%s%s", replacement, pch);
+
+   ret = strdup(eina_strbuf_string_get(buffer));
+   free(str_cpy);
+   eina_strbuf_free(buffer);
+   return ret;
+}
+
+char *
+get_pieces(const char *string, char break_in, int amount)
+{
+   int i;
+   int found = 0;
+
+   for (i = strlen(string) - 1; i && amount > found; i--)
+     if (string[i] == break_in)
+       found++;
+
+   if (found)
+     return strdup(string+i+2);
+   else
+     return strdup(string);
+}
+
+char *
+string_build(const char *fmt, ...)
+{
+   va_list ap;
+   Eina_Strbuf *buffer = eina_strbuf_new();
+   char *ret;
+
+   va_start(ap, fmt);
+   eina_strbuf_prepend_vprintf(buffer, fmt, ap);
+   va_end(ap);
+
+   ret = strdup(eina_strbuf_string_get(buffer));
+   eina_strbuf_free(buffer);
+
+   return ret;
+}
+
+#define UTIL_H "\
+#ifndef EDBUS_UTILS_H\n\
+#define EDBUS_UTILS_H 1\n\
+\n\
+typedef struct _EDBus_Error_Info\n\
+{\n\
+   const char *error;\n\
+   const char *message;\n\
+} EDBus_Error_Info;\n\
+\n\
+typedef void (*EDBus_Codegen_Property_Set_Cb)(void *data, const char *propname, EDBus_Proxy *proxy, EDBus_Pending *p, EDBus_Error_Info *error_info);\n\
+\n\
+typedef void (*EDBus_Codegen_Property_String_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, const char *value);\n\
+typedef void (*EDBus_Codegen_Property_Int32_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, int value);\n\
+typedef void (*EDBus_Codegen_Property_Byte_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, unsigned char value);\n\
+typedef void (*EDBus_Codegen_Property_Bool_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, Eina_Bool value);\n\
+typedef void (*EDBus_Codegen_Property_Int16_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, short int value);\n\
+typedef void (*EDBus_Codegen_Property_Uint16_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, unsigned short int value);\n\
+typedef void (*EDBus_Codegen_Property_Uint32_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, unsigned int value);\n\
+typedef void (*EDBus_Codegen_Property_Double_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, double value);\n\
+typedef void (*EDBus_Codegen_Property_Int64_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, int64_t value);\n\
+typedef void (*EDBus_Codegen_Property_Uint64_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, uint64_t value);\n\
+typedef void (*EDBus_Codegen_Property_Complex_Get_Cb)(void *data, EDBus_Pending *p, const char *propname, EDBus_Proxy *proxy, EDBus_Error_Info *error_info, Eina_Value *value);\n\
+\n\
+#endif\
+"
+
+Eina_Bool
+util_h_write(void)
+{
+   return file_write("edbus_utils.h", UTIL_H);
+}