--- /dev/null
+#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;
+}
--- /dev/null
+#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);
+}