diff options
author | David Zeuthen <davidz@redhat.com> | 2009-05-19 15:46:04 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2009-05-19 15:46:04 -0400 |
commit | 3eeaca43b2eb2fbc5c2e22fffdff74b946dc2a0b (patch) | |
tree | 6571417b46e3fc4343a387baf266b3441c537dea | |
parent | 7dc2e9b3e4a4233e142801014abc51478b55ebd6 (diff) |
Add dbus-idl-to-xml and rework struct handling
-rw-r--r-- | src/Makefile.am | 26 | ||||
-rw-r--r-- | src/dbusidl.c | 496 | ||||
-rw-r--r-- | src/dbusidl.h | 19 | ||||
-rw-r--r-- | src/dbusidlprivate.h | 19 | ||||
-rw-r--r-- | src/didl2docbook.c | 62 | ||||
-rw-r--r-- | src/didl2xml.c | 628 | ||||
-rw-r--r-- | src/idllexer.l | 1 | ||||
-rw-r--r-- | src/idlparser.y | 49 | ||||
-rw-r--r-- | src/org.freedesktop.DBus.Idl.Tests1.didl | 56 |
9 files changed, 890 insertions, 466 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 3c8ae67..b0f5810 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,6 +3,11 @@ NULL = INCLUDES = -DDBUS_IDL_I_UNDERSTAND_THAT_API_IS_UNSTABLE +bin_PROGRAMS = +noinst_PROGRAMS = + +# ---------------------------------------------------------------------------------------------------- + lib_LTLIBRARIES=libdbus-idl-1.la libdbus_idl_1_la_includedir = \ @@ -36,7 +41,7 @@ libdbus_idl_1_la_YFLAGS = -v -d # ---------------------------------------------------------------------------------------------------- -noinst_PROGRAMS = dbus-idl-test +noinst_PROGRAMS += dbus-idl-test pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA = dbus-idl-1.pc @@ -60,7 +65,7 @@ EXTRA_DIST = org.freedesktop.DBus.Idl.Tests1.didl # ---------------------------------------------------------------------------------------------------- -bin_PROGRAMS = dbus-idl-to-docbook +bin_PROGRAMS += dbus-idl-to-docbook dbus_idl_to_docbook_SOURCES = \ didl2docbook.c \ @@ -77,6 +82,23 @@ dbus_idl_to_docbook_LDADD = \ # ---------------------------------------------------------------------------------------------------- +bin_PROGRAMS += dbus-idl-to-xml + +dbus_idl_to_xml_SOURCES = \ + didl2xml.c \ + $(NULL) + +dbus_idl_to_xml_CFLAGS = \ + $(GLIB2_CFLAGS) \ + $(NULL) + +dbus_idl_to_xml_LDADD = \ + $(GLIB2_LIBS) \ + libdbus-idl-1.la \ + $(NULL) + +# ---------------------------------------------------------------------------------------------------- + clean-local: rm -f *~ libdbus_idl_1_la-* diff --git a/src/dbusidl.c b/src/dbusidl.c index e537ebf..e3ffad2 100644 --- a/src/dbusidl.c +++ b/src/dbusidl.c @@ -26,7 +26,10 @@ #include "idl.h" #include "dbusidl.h" -/* ---------------------------------------------------------------------------------------------------- */ +#define AN_DOC "org.freedesktop.DBus.Typelib.Doc" +#define AN_DOC_BRIEF "org.freedesktop.DBus.Typelib.DocBrief" +#define AN_COMPLETE_TYPE "org.freedesktop.DBus.TypeLib.CompleteType" + /* ---------------------------------------------------------------------------------------------------- */ static const gchar * @@ -36,13 +39,13 @@ di_base_type_to_string (DIBaseType type) ret = NULL; switch (type) { + case DI_BASE_TYPE_ARG: ret = "arg"; break; case DI_BASE_TYPE_METHOD: ret = "method"; break; case DI_BASE_TYPE_SIGNAL: ret = "signal"; break; case DI_BASE_TYPE_PROPERTY: ret = "property"; break; case DI_BASE_TYPE_INTERFACE: ret = "interface"; break; case DI_BASE_TYPE_STRUCT_MEMBER: ret = "struct_member"; break; case DI_BASE_TYPE_STRUCT: ret = "struct"; break; - case DI_BASE_TYPE_DYNAMIC_STRUCT: ret = "dynamic_struct"; break; case DI_BASE_TYPE_ENUM_MEMBER: ret = "enum_member"; break; case DI_BASE_TYPE_ENUM: ret = "enum"; break; case DI_BASE_TYPE_ERROR_MEMBER: ret = "error_member"; break; @@ -57,6 +60,20 @@ di_base_type_to_string (DIBaseType type) /* ---------------------------------------------------------------------------------------------------- */ +const gchar * +di_annotation_get_name (DIAnnotation *annotation) +{ + return annotation->name; +} + +const gchar * +di_annotation_get_value (DIAnnotation *annotation) +{ + return annotation->value; +} + +/* ---------------------------------------------------------------------------------------------------- */ + DIBaseType di_base_get_type (DIBase *base) { @@ -112,31 +129,13 @@ di_base_get_annotation_value (DIBase *base, const gchar * di_base_get_doc (DIBase *base) { - const gchar *doc; - const gchar *brief; - - doc = di_base_get_annotation_value (base, "Doc"); - brief = di_base_get_annotation_value (base, "DocBrief"); - - if (doc != NULL) - return doc; - else - return brief; + return di_base_get_annotation_value (base, AN_DOC); } const gchar * di_base_get_doc_brief (DIBase *base) { - const gchar *doc; - const gchar *brief; - - doc = di_base_get_annotation_value (base, "Doc"); - brief = di_base_get_annotation_value (base, "DocBrief"); - - if (brief != NULL) - return brief; - else - return doc; + return di_base_get_annotation_value (base, AN_DOC_BRIEF); } /* ---------------------------------------------------------------------------------------------------- */ @@ -185,6 +184,49 @@ get_typecode_for_primitive_type (const gchar *name) return -1; } +const gchar * +di_type_get_complete_signature (DIType *type) +{ + GString *s; + gint type_code; + + /* compute this value on demand */ + + if (type->complete_signature != NULL) + return type->complete_signature; + + s = g_string_new (NULL); + + type_code = get_typecode_for_primitive_type (type->name); + if (type_code != -1) + { + g_string_append_c (s, type_code); + goto out; + } + + if (g_strcmp0 (type->name, "array") == 0) + { + g_string_append (s, "a"); + g_string_append (s, di_type_get_complete_signature ((DIType *) type->inner_types->data)); + } + else if (g_strcmp0 (type->name, "dict") == 0) + { + g_string_append (s, "a{"); + g_string_append (s, di_type_get_complete_signature ((DIType *) type->inner_types->data)); + g_string_append (s, di_type_get_complete_signature ((DIType *) type->inner_types->next->data)); + g_string_append (s, "}"); + } + else + { + g_string_append_printf (s, "[%s]", type->fully_qualified_name); + } + + out: + type->complete_signature = g_string_free (s, FALSE); + + return type->complete_signature; +} + gint di_type_get_typecode (DIType *type) { @@ -368,37 +410,6 @@ di_struct_get_members (DIStruct *struct_) return struct_->members; } -const gchar * -di_struct_get_signature (DIStruct *struct_) -{ - return struct_->signature; -} - - -const gchar * -di_dynamic_struct_get_name (DIDynamicStruct *dynamic_struct) -{ - return dynamic_struct->name; -} - -const gchar * -di_dynamic_struct_get_fully_qualified_name (DIDynamicStruct *dynamic_struct) -{ - return dynamic_struct->fully_qualified_name; -} - -GList * -di_dynamic_struct_get_members (DIDynamicStruct *dynamic_struct) -{ - return dynamic_struct->members; -} - -const gchar * -di_dynamic_struct_get_signature (DIDynamicStruct *dynamic_struct) -{ - return "(sa{sv})"; -} - /* ---------------------------------------------------------------------------------------------------- */ const gchar * @@ -496,12 +507,6 @@ di_namespace_get_structs (DINamespace *namespace) } GList * -di_namespace_get_dynamic_structs (DINamespace *namespace) -{ - return namespace->dynamic_structs; -} - -GList * di_namespace_get_enums (DINamespace *namespace) { return namespace->enums; @@ -561,9 +566,6 @@ di_comment_get_symbol (DIComment *comment) case DI_BASE_TYPE_STRUCT: ret = di_struct_get_name ((DIStruct *) comment->link); break; - case DI_BASE_TYPE_DYNAMIC_STRUCT: - ret = di_dynamic_struct_get_name ((DIDynamicStruct *) comment->link); - break; case DI_BASE_TYPE_ENUM: ret = di_enum_get_name ((DIEnum *) comment->link); break; @@ -611,9 +613,6 @@ di_comment_get_fully_qualified_symbol (DIComment *comment) case DI_BASE_TYPE_STRUCT: ret = di_struct_get_fully_qualified_name ((DIStruct *) comment->link); break; - case DI_BASE_TYPE_DYNAMIC_STRUCT: - ret = di_dynamic_struct_get_fully_qualified_name ((DIDynamicStruct *) comment->link); - break; case DI_BASE_TYPE_ENUM: ret = di_enum_get_fully_qualified_name ((DIEnum *) comment->link); break; @@ -703,11 +702,6 @@ di_struct_free (DIStruct *struct_) } void -di_dynamic_struct_free (DIDynamicStruct *dynamic_struct) -{ -} - -void di_enum_member_free (DIEnumMember *enum_member) { } @@ -904,24 +898,6 @@ di_struct_new (gchar *decl_filename, return ret; } -DIDynamicStruct * -di_dynamic_struct_new (gchar *decl_filename, - guint decl_lineno, - gchar *name, - GList *members, - GList *annotations) -{ - DIDynamicStruct *ret; - ret = g_new0 (DIDynamicStruct, 1); - ret->base.type = DI_BASE_TYPE_DYNAMIC_STRUCT; - ret->base.decl_filename = decl_filename; - ret->base.decl_lineno = decl_lineno; - ret->name = name; - ret->members = members; - ret->base.annotations = annotations; - return ret; -} - DIEnumMember * di_enum_member_new (gchar *decl_filename, guint decl_lineno, @@ -1000,7 +976,6 @@ di_namespace_new (gchar *decl_filename, gchar *name, GList *interfaces, GList *structs, - GList *dynamic_structs, GList *enums, GList *error_domains, GList *annotations) @@ -1013,7 +988,6 @@ di_namespace_new (gchar *decl_filename, ret->name = name; ret->interfaces = interfaces; ret->structs = structs; - ret->dynamic_structs = dynamic_structs; ret->enums = enums; ret->error_domains = error_domains; ret->base.annotations = annotations; @@ -1042,7 +1016,7 @@ di_comment_new (gchar *decl_filename, text = g_string_new (NULL); - /* Simple gtkdoc-style comment parser */ + /* Simple gtkdoc-style comment parser that outputs XML */ /* process one line at a time */ lines = g_strsplit (comment->raw, "\n", 0); @@ -1061,10 +1035,8 @@ di_comment_new (gchar *decl_filename, line++; } - while (isspace (*line)) + if (isblank (*line)) line++; - if (*line == '\0') - continue; /* extract tag (TODO: handle tags spanning multiple lines) */ tag = NULL; @@ -1107,7 +1079,6 @@ di_comment_new (gchar *decl_filename, { g_string_append (text, line); g_string_append_c (text, '\n'); - //g_print ("line: '%s'\n", line); } } g_strfreev (lines); @@ -1115,6 +1086,9 @@ di_comment_new (gchar *decl_filename, comment->text = text->str; g_string_free (text, FALSE); + /* remove leading and trailing whitespace */ + g_strstrip (comment->text); + return comment; } @@ -1307,18 +1281,6 @@ di_struct_print (DIStruct *struct_, guint indent) } void -di_dynamic_struct_print (DIDynamicStruct *dynamic_struct, guint indent) -{ - GList *l; - - di_base_print_annotations ((DIBase *) dynamic_struct, indent); - g_print ("%*sdynamic_struct %s {\n", indent, "", dynamic_struct->name); - for (l = dynamic_struct->members; l != NULL; l = l->next) - di_struct_member_print (l->data, indent + 2); - g_print ("%*s};\n", indent, ""); -} - -void di_enum_member_print (DIEnumMember *enum_member, guint indent) { di_base_print_annotations ((DIBase *) enum_member, indent); @@ -1377,8 +1339,6 @@ di_namespace_print (DINamespace *namespace, guint indent) g_print ("%*snamespace %s {\n", indent, "", namespace->name); for (l = namespace->structs; l != NULL; l = l->next) di_struct_print (l->data, indent + 2); - for (l = namespace->dynamic_structs; l != NULL; l = l->next) - di_dynamic_struct_print (l->data, indent + 2); for (l = namespace->enums; l != NULL; l = l->next) di_enum_print (l->data, indent + 2); for (l = namespace->error_domains; l != NULL; l = l->next) @@ -1630,25 +1590,6 @@ build_symbol_table (DIParser *parser) } } - /* for all dynamic structs */ - for (ll = namespace->dynamic_structs; ll != NULL; ll = ll->next) - { - DIDynamicStruct *dynamic_struct = ll->data; - dynamic_struct->fully_qualified_name = g_strdup_printf ("%s.%s", - namespace->name, - dynamic_struct->name); - insert_and_check (parser, (DIBase *) dynamic_struct, dynamic_struct->fully_qualified_name); - for (lll = dynamic_struct->members; lll != NULL; lll = lll->next) - { - DIStructMember *struct_member = lll->data; - - /* make type name fully qualified */ - type_compute_fully_qualified_name (parser, - struct_member->type, - namespace); - } - } - /* for all enums */ for (ll = namespace->enums; ll != NULL; ll = ll->next) { @@ -1775,40 +1716,29 @@ visit_type (DIParser *parser, DIStruct *struct_; DIStructMember *struct_member; - g_string_append_c (s, '('); - struct_ = (DIStruct *) base; - for (l = struct_->members; l != NULL; l = l->next) + if (di_base_get_annotation (base, "org.freedesktop.DBus.Typelib.DynamicStruct") != NULL) { - struct_member = (DIStructMember *) l->data; - visit_type (parser, - struct_member->type, - base, - recursion_level + 1); - g_string_append (s, struct_member->type->signature); + g_string_append (s, "a{sv}"); } - g_string_append_c (s, ')'); - } - else if (base->type == DI_BASE_TYPE_DYNAMIC_STRUCT) - { - GList *l; - DIDynamicStruct *dynamic_struct; - DIStructMember *struct_member; - - dynamic_struct = (DIDynamicStruct *) base; - for (l = dynamic_struct->members; l != NULL; l = l->next) + else { - struct_member = (DIStructMember *) l->data; - visit_type (parser, - struct_member->type, - base, - recursion_level + 1); + g_string_append_c (s, '('); + struct_ = (DIStruct *) base; + for (l = struct_->members; l != NULL; l = l->next) + { + struct_member = (DIStructMember *) l->data; + visit_type (parser, + struct_member->type, + base, + recursion_level + 1); + g_string_append (s, struct_member->type->signature); + } + g_string_append_c (s, ')'); } - /* dynamic structs are always marshalled as a (string, dict:string->variant) structure */ - g_string_append (s, "(sa{sv})"); } else if (base->type == DI_BASE_TYPE_ENUM) { - /* we use uint32 for enums */ + /* use uint32 for enums */ g_string_append_c (s, 'u'); } else @@ -1847,7 +1777,6 @@ check_types (DIParser *parser) DISignal *signal; DIProperty *property; DIStruct *struct_; - DIDynamicStruct *dynamic_struct; DIStructMember *struct_member; /* here we ensure that all the user supplied types referenced actually exists. We also @@ -1871,6 +1800,16 @@ check_types (DIParser *parser) g_string_append (s1, arg->type->signature); else g_string_append (s2, arg->type->signature); + + if (g_strcmp0 (di_type_get_signature (arg->type), + di_type_get_complete_signature (arg->type)) != 0) + { + ((DIBase *) arg)->annotations = g_list_append (((DIBase *) arg)->annotations, + di_annotation_new (((DIBase *) arg)->decl_filename, + ((DIBase *) arg)->decl_lineno, + g_strdup (AN_COMPLETE_TYPE), + g_strdup (di_type_get_complete_signature (arg->type)))); + } } method->in_signature = g_string_free (s1, FALSE); method->out_signature = g_string_free (s2, FALSE); @@ -1884,6 +1823,16 @@ check_types (DIParser *parser) arg = l->data; visit_type (parser, arg->type, base, 0); g_string_append (s1, arg->type->signature); + + if (g_strcmp0 (di_type_get_signature (arg->type), + di_type_get_complete_signature (arg->type)) != 0) + { + ((DIBase *) arg)->annotations = g_list_append (((DIBase *) arg)->annotations, + di_annotation_new (((DIBase *) arg)->decl_filename, + ((DIBase *) arg)->decl_lineno, + g_strdup (AN_COMPLETE_TYPE), + g_strdup (di_type_get_complete_signature (arg->type)))); + } } signal->signature = g_string_free (s1, FALSE); break; @@ -1892,27 +1841,33 @@ check_types (DIParser *parser) property = (DIProperty *) base; visit_type (parser, property->type, base, 0); property->signature = g_strdup (property->type->signature); + if (g_strcmp0 (di_type_get_signature (property->type), + di_type_get_complete_signature (property->type)) != 0) + { + base->annotations = g_list_append (base->annotations, + di_annotation_new (base->decl_filename, + base->decl_lineno, + g_strdup (AN_COMPLETE_TYPE), + g_strdup (di_type_get_complete_signature (property->type)))); + } break; case DI_BASE_TYPE_STRUCT: - s1 = g_string_new ("("); struct_ = (DIStruct *) base; for (l = struct_->members; l != NULL; l = l->next) { struct_member = (DIStructMember *) l->data; visit_type (parser, struct_member->type, base, 0); - g_string_append (s1, struct_member->type->signature); - } - g_string_append_c (s1, ')'); - struct_->signature = g_string_free (s1, FALSE); - break; - case DI_BASE_TYPE_DYNAMIC_STRUCT: - dynamic_struct = (DIDynamicStruct *) base; - for (l = dynamic_struct->members; l != NULL; l = l->next) - { - struct_member = (DIStructMember *) l->data; - visit_type (parser, struct_member->type, base, 0); + if (g_strcmp0 (di_type_get_signature (struct_member->type), + di_type_get_complete_signature (struct_member->type)) != 0) + { + ((DIBase *) struct_member)->annotations = g_list_append (((DIBase *) struct_member)->annotations, + di_annotation_new (((DIBase *) struct_member)->decl_filename, + ((DIBase *) struct_member)->decl_lineno, + g_strdup (AN_COMPLETE_TYPE), + g_strdup (di_type_get_complete_signature (struct_member->type)))); + } } break; @@ -1952,7 +1907,7 @@ inject_gtkdoc_style_comments (DIParser *parser) { annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("Doc"), + g_strdup (AN_DOC), g_strdup (s)); ((DIBase *) arg)->annotations = g_list_append (((DIBase *) arg)->annotations, annotation); } @@ -1968,7 +1923,7 @@ inject_gtkdoc_style_comments (DIParser *parser) { annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("Doc"), + g_strdup (AN_DOC), g_strdup (s)); ((DIBase *) arg)->annotations = g_list_append (((DIBase *) arg)->annotations, annotation); } @@ -1984,23 +1939,7 @@ inject_gtkdoc_style_comments (DIParser *parser) { annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("Doc"), - g_strdup (s)); - ((DIBase *) member)->annotations = g_list_append (((DIBase *) member)->annotations, annotation); - } - } - break; - - case DI_BASE_TYPE_DYNAMIC_STRUCT: - for (ll = di_dynamic_struct_get_members ((DIDynamicStruct *) base); ll != NULL; ll = ll->next) - { - DIStructMember *member = ll->data; - s = di_comment_get_tag_value (comment, di_struct_member_get_name (member)); - if (s != NULL) - { - annotation = di_annotation_new (comment->base.decl_filename, - comment->base.decl_lineno, - g_strdup ("Doc"), + g_strdup (AN_DOC), g_strdup (s)); ((DIBase *) member)->annotations = g_list_append (((DIBase *) member)->annotations, annotation); } @@ -2016,7 +1955,7 @@ inject_gtkdoc_style_comments (DIParser *parser) { annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("Doc"), + g_strdup (AN_DOC), g_strdup (s)); ((DIBase *) member)->annotations = g_list_append (((DIBase *) member)->annotations, annotation); } @@ -2032,7 +1971,7 @@ inject_gtkdoc_style_comments (DIParser *parser) { annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("Doc"), + g_strdup (AN_DOC), g_strdup (s)); ((DIBase *) member)->annotations = g_list_append (((DIBase *) member)->annotations, annotation); } @@ -2054,7 +1993,7 @@ inject_gtkdoc_style_comments (DIParser *parser) annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("Doc"), + g_strdup (AN_DOC), g_strdup (comment->text)); base->annotations = g_list_append (base->annotations, annotation); @@ -2063,7 +2002,7 @@ inject_gtkdoc_style_comments (DIParser *parser) { annotation = di_annotation_new (comment->base.decl_filename, comment->base.decl_lineno, - g_strdup ("DocBrief"), + g_strdup (AN_DOC_BRIEF), g_strdup (s)); base->annotations = g_list_append (base->annotations, annotation); } @@ -2077,6 +2016,19 @@ inject_gtkdoc_style_comments (DIParser *parser) /* ---------------------------------------------------------------------------------------------------- */ static void +whine_about_comment (DIParser *parser, + DIBase *base, + gboolean brief) +{ + if (di_base_get_annotation_value (base, brief ? AN_DOC_BRIEF : AN_DOC) == NULL) + parser->warnings = g_list_append (parser->warnings, + g_strdup_printf ("%s:%d: warning: missing %s for %s.", + base->decl_filename, base->decl_lineno, + brief ? "brief docs" : "docs", + di_base_type_to_string (base->type))); +} + +static void whine_about_missing_comments (DIParser *parser) { GHashTableIter iter; @@ -2088,7 +2040,6 @@ whine_about_missing_comments (DIParser *parser) DISignal *signal; DIProperty *property; DIStruct *struct_; - DIDynamicStruct *dynamic_struct; DIStructMember *struct_member; DIErrorDomain *error_domain; DIErrorMember *error_member; @@ -2102,159 +2053,71 @@ whine_about_missing_comments (DIParser *parser) { case DI_BASE_TYPE_METHOD: method = (DIMethod *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for method %s.", - base->decl_filename, base->decl_lineno, - method->name)); + whine_about_comment (parser, base, FALSE); for (l = method->args; l != NULL; l = l->next) { arg = l->data; base = (DIBase *) arg; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for method arg %s.", - base->decl_filename, base->decl_lineno, - arg->name)); + whine_about_comment (parser, base, FALSE); } break; case DI_BASE_TYPE_SIGNAL: signal = (DISignal *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for signal %s.", - base->decl_filename, base->decl_lineno, - signal->name)); + whine_about_comment (parser, base, FALSE); for (l = signal->args; l != NULL; l = l->next) { arg = l->data; base = (DIBase *) arg; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for signal arg %s.", - base->decl_filename, base->decl_lineno, - arg->name)); + whine_about_comment (parser, base, FALSE); } break; case DI_BASE_TYPE_PROPERTY: property = (DIProperty *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for property %s.", - base->decl_filename, base->decl_lineno, - property->name)); + whine_about_comment (parser, base, FALSE); break; case DI_BASE_TYPE_STRUCT: struct_ = (DIStruct *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for struct %s.", - base->decl_filename, base->decl_lineno, - struct_->name)); - if (di_base_get_annotation_value (base, "DocBrief") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing brief docs for struct %s.", - base->decl_filename, base->decl_lineno, - struct_->name)); + whine_about_comment (parser, base, FALSE); + whine_about_comment (parser, base, TRUE); for (l = struct_->members; l != NULL; l = l->next) { struct_member = (DIStructMember *) l->data; base = (DIBase *) struct_member; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for struct member %s.", - base->decl_filename, base->decl_lineno, - struct_member->name)); - } - break; - - case DI_BASE_TYPE_DYNAMIC_STRUCT: - dynamic_struct = (DIDynamicStruct *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for dynamic_struct %s.", - base->decl_filename, base->decl_lineno, - dynamic_struct->name)); - if (di_base_get_annotation_value (base, "DocBrief") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing brief docs for dynamic_struct %s.", - base->decl_filename, base->decl_lineno, - dynamic_struct->name)); - for (l = dynamic_struct->members; l != NULL; l = l->next) - { - struct_member = (DIStructMember *) l->data; - base = (DIBase *) struct_member; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for dynamic_struct member %s.", - base->decl_filename, base->decl_lineno, - struct_member->name)); + whine_about_comment (parser, base, FALSE); } break; case DI_BASE_TYPE_ERROR_DOMAIN: error_domain = (DIErrorDomain *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for error_domain %s.", - base->decl_filename, base->decl_lineno, - error_domain->name)); - if (di_base_get_annotation_value (base, "DocBrief") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing brief docs for error_domain %s.", - base->decl_filename, base->decl_lineno, - error_domain->name)); + whine_about_comment (parser, base, FALSE); + whine_about_comment (parser, base, TRUE); for (l = error_domain->members; l != NULL; l = l->next) { error_member = (DIErrorMember *) l->data; base = (DIBase *) error_member; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for error_domain member %s.", - base->decl_filename, base->decl_lineno, - error_member->name)); + whine_about_comment (parser, base, FALSE); } break; case DI_BASE_TYPE_ENUM: enum_ = (DIEnum *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for enum %s.", - base->decl_filename, base->decl_lineno, - enum_->name)); - if (di_base_get_annotation_value (base, "DocBrief") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing brief docs for enum %s.", - base->decl_filename, base->decl_lineno, - enum_->name)); + whine_about_comment (parser, base, FALSE); + whine_about_comment (parser, base, TRUE); for (l = enum_->members; l != NULL; l = l->next) { enum_member = (DIEnumMember *) l->data; base = (DIBase *) enum_member; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for enum member %s.", - base->decl_filename, base->decl_lineno, - enum_member->name)); + whine_about_comment (parser, base, FALSE); } break; case DI_BASE_TYPE_INTERFACE: enum_ = (DIEnum *) base; - if (di_base_get_annotation_value (base, "Doc") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing docs for interface %s.", - base->decl_filename, base->decl_lineno, - enum_->name)); - if (di_base_get_annotation_value (base, "DocBrief") == NULL) - parser->warnings = g_list_append (parser->warnings, - g_strdup_printf ("%s:%d: warning: missing brief docs for interface %s.", - base->decl_filename, base->decl_lineno, - enum_->name)); + whine_about_comment (parser, base, FALSE); + whine_about_comment (parser, base, TRUE); break; default: @@ -2266,6 +2129,28 @@ whine_about_missing_comments (DIParser *parser) /* ---------------------------------------------------------------------------------------------------- */ +static void +check_doc_references (DIParser *parser) +{ + /* Check that all references in docs, e.g. + * + * org.example.AnInterface.MethodCall() + * #org.example.AnInterface::Signal + * #org.example.AnInterface:Property + * #org.example.AnEnum + * #org.example.AnEnum.AMember + * #org.example.AnErrorDomain + * #org.example.AnErrorDomain.AMember + * #org.example.AStruct + * + * are valid. Warn if they are not. + */ + + /* TODO */ +} + +/* ---------------------------------------------------------------------------------------------------- */ + DIParser * di_parser_new (const gchar *path) { @@ -2304,8 +2189,6 @@ di_parser_new (const gchar *path) * - properties * o structs * - struct members - * o dynamic structs - * - struct members * o enumerations * - enum members * o error domains @@ -2335,6 +2218,9 @@ di_parser_new (const gchar *path) /* Warn about missing comments */ whine_about_missing_comments (parser); + /* Check that all references in docs are valid. */ + check_doc_references (parser); + out: return parser; } @@ -2430,20 +2316,6 @@ di_namespace_lookup_struct (DINamespace *namespace, return NULL; } -DIDynamicStruct * -di_namespace_lookup_dynamic_struct (DINamespace *namespace, - const gchar *name) -{ - GList *l; - for (l = namespace->dynamic_structs; l != NULL; l = l->next) - { - DIDynamicStruct *dynamic_struct = l->data; - if (g_strcmp0 (dynamic_struct->name, name) == 0) - return dynamic_struct; - } - return NULL; -} - DIEnum * di_namespace_lookup_enum (DINamespace *namespace, const gchar *name) diff --git a/src/dbusidl.h b/src/dbusidl.h index bc21376..1e95bea 100644 --- a/src/dbusidl.h +++ b/src/dbusidl.h @@ -40,7 +40,6 @@ typedef enum DI_BASE_TYPE_INTERFACE, DI_BASE_TYPE_STRUCT_MEMBER, DI_BASE_TYPE_STRUCT, - DI_BASE_TYPE_DYNAMIC_STRUCT, DI_BASE_TYPE_ENUM_MEMBER, DI_BASE_TYPE_ENUM, DI_BASE_TYPE_ERROR_MEMBER, @@ -80,7 +79,6 @@ typedef struct _DIProperty DIProperty; typedef struct _DIInterface DIInterface; typedef struct _DIStructMember DIStructMember; typedef struct _DIStruct DIStruct; -typedef struct _DIDynamicStruct DIDynamicStruct; typedef struct _DIEnumMember DIEnumMember; typedef struct _DIEnum DIEnum; typedef struct _DIErrorMember DIErrorMember; @@ -90,6 +88,11 @@ typedef struct _DIComment DIComment; /* ---------------------------------------------------------------------------------------------------- */ +const gchar *di_annotation_get_name (DIAnnotation *annotation); +const gchar *di_annotation_get_value (DIAnnotation *annotation); + +/* ---------------------------------------------------------------------------------------------------- */ + DIBaseType di_base_get_type (DIBase *base); const gchar *di_base_get_decl_path (DIBase *base); guint di_base_get_decl_lineno (DIBase *base); @@ -105,6 +108,7 @@ const gchar *di_base_get_annotation_value (DIBase *base, const gchar *di_type_get_name (DIType *type); const gchar *di_type_get_signature (DIType *type); +const gchar *di_type_get_complete_signature (DIType *type); gint di_type_get_typecode (DIType *type); GList *di_type_get_inner_types (DIType *type); @@ -161,14 +165,6 @@ DIType *di_struct_member_get_type (DIStructMember *struct_member); const gchar *di_struct_get_name (DIStruct *struct_); const gchar *di_struct_get_fully_qualified_name (DIStruct *struct_); GList *di_struct_get_members (DIStruct *struct_); -const gchar *di_struct_get_signature (DIStruct *struct_); - -/* ---------------------------------------------------------------------------------------------------- */ - -const gchar *di_dynamic_struct_get_name (DIDynamicStruct *dynamic_struct); -const gchar *di_dynamic_struct_get_fully_qualified_name (DIDynamicStruct *dynamic_struct); -GList *di_dynamic_struct_get_members (DIDynamicStruct *dynamic_struct); -const gchar *di_dynamic_struct_get_signature (DIDynamicStruct *dynamic_struct); /* ---------------------------------------------------------------------------------------------------- */ @@ -199,15 +195,12 @@ GList *di_error_domain_get_members (DIErrorDomain *error_dom const gchar *di_namespace_get_name (DINamespace *namespace); GList *di_namespace_get_interfaces (DINamespace *namespace); GList *di_namespace_get_structs (DINamespace *namespace); -GList *di_namespace_get_dynamic_structs (DINamespace *namespace); GList *di_namespace_get_enums (DINamespace *namespace); GList *di_namespace_get_error_domains (DINamespace *namespace); DIInterface *di_namespace_lookup_interface (DINamespace *namespace, const gchar *name); DIStruct *di_namespace_lookup_struct (DINamespace *namespace, const gchar *name); -DIDynamicStruct *di_namespace_lookup_dynamic_struct (DINamespace *namespace, - const gchar *name); DIEnum *di_namespace_lookup_enum (DINamespace *namespace, const gchar *name); DIErrorDomain *di_namespace_lookup_error_domain (DINamespace *namespace, diff --git a/src/dbusidlprivate.h b/src/dbusidlprivate.h index 20477da..9649d4f 100644 --- a/src/dbusidlprivate.h +++ b/src/dbusidlprivate.h @@ -48,6 +48,8 @@ struct _DIType gchar *signature; + gchar *complete_signature; + /* only set if type is a user supplied type */ gchar *fully_qualified_name; }; @@ -119,14 +121,6 @@ struct _DIStruct gchar *signature; }; -struct _DIDynamicStruct -{ - DIBase base; - gchar *name; - gchar *fully_qualified_name; - GList *members; -}; - struct _DIEnumMember { DIBase base; @@ -165,7 +159,6 @@ struct _DINamespace gchar *name; GList *interfaces; GList *structs; - GList *dynamic_structs; GList *enums; GList *error_domains; }; @@ -244,11 +237,6 @@ DIStruct *di_struct_new (gchar *decl_filename, gchar *name, GList *members, GList *annotations); -DIDynamicStruct *di_dynamic_struct_new (gchar *decl_filename, - guint decl_lineno, - gchar *name, - GList *members, - GList *annotations); DIEnumMember *di_enum_member_new (gchar *decl_filename, guint decl_lineno, gchar *name, @@ -274,7 +262,6 @@ DINamespace *di_namespace_new (gchar *decl_filename, gchar *name, GList *interfaces, GList *structs, - GList *dynamic_structs, GList *enums, GList *error_domains, GList *annotations); @@ -298,7 +285,6 @@ void di_property_free (DIProperty *property); void di_interface_free (DIInterface *interface); void di_struct_member_free (DIStructMember *struct_member); void di_struct_free (DIStruct *struct_); -void di_dynamic_struct_free (DIDynamicStruct *dynamic_struct); void di_enum_member_free (DIEnumMember *enum_member); void di_enum_free (DIEnum *enum_); void di_error_member_free (DIErrorMember *error_member); @@ -317,7 +303,6 @@ void di_property_print (DIProperty *property, guint indent); void di_interface_print (DIInterface *interface, guint indent); void di_struct_member_print (DIStructMember *struct_member, guint indent); void di_struct_print (DIStruct *struct_, guint indent); -void di_dynamic_struct_print (DIDynamicStruct *struct_, guint indent); void di_enum_member_print (DIEnumMember *enum_member, guint indent); void di_enum_print (DIEnum *enum_, guint indent); void di_error_member_print (DIErrorMember *error_member, guint indent); diff --git a/src/didl2docbook.c b/src/didl2docbook.c index 827cb07..3d531b5 100644 --- a/src/didl2docbook.c +++ b/src/didl2docbook.c @@ -698,31 +698,6 @@ print_struct (DIStruct *struct_, s); } -static void -print_dynamic_struct (DIDynamicStruct *dynamic_struct, - GString *s) -{ - g_string_append_printf (s, - "<refentry id=\"didl-%s\">\n" - " <refmeta>\n" - " <refentrytitle role=\"top_of_page\">Dynamic Struct %s</refentrytitle>\n" - " </refmeta>\n" - " <refnamediv>\n" - " <refname>Dynamic Struct %s</refname>\n" - " <refpurpose>%s</refpurpose>\n" - " </refnamediv>\n", - di_dynamic_struct_get_fully_qualified_name (dynamic_struct), - di_dynamic_struct_get_fully_qualified_name (dynamic_struct), - di_dynamic_struct_get_fully_qualified_name (dynamic_struct), - get_doc (dynamic_struct, TRUE)); - - print_struct_members (di_dynamic_struct_get_members (dynamic_struct), - "dynamic_struct", - di_dynamic_struct_get_fully_qualified_name (dynamic_struct), - get_doc (dynamic_struct, FALSE), - s); -} - /* ---------------------------------------------------------------------------------------------------- */ static void @@ -1011,43 +986,6 @@ print_namespace (DINamespace *namespace, /* ---------------------------------------------------------------------------------------------------- */ - /* Print all dynamic structs in separate files */ - g_string_append_printf (sn, - " <chapter>\n" - " <title>Dynamic Structs</title>\n"); - for (l = di_namespace_get_dynamic_structs (namespace); l != NULL; l = l->next) - { - DIDynamicStruct *dynamic_struct = l->data; - GString *s; - - s = g_string_new (NULL); - g_string_append (s, "<?xml version=\"1.0\"?>\n" - "<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2 //EN\"\n" - "\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">\n"); - - print_dynamic_struct (dynamic_struct, s); - - filename = g_strdup_printf ("didl-%s.xml", - di_dynamic_struct_get_fully_qualified_name (dynamic_struct)); - if (!write_file (filename, s, error)) - { - g_free (filename); - g_string_free (s, TRUE); - goto out; - } - g_string_free (s, TRUE); - - g_string_append_printf (sn, - " <xi:include href=\"%s\"/>\n", - filename); - - g_free (filename); - } - g_string_append_printf (sn, - " </chapter>\n"); - - /* ---------------------------------------------------------------------------------------------------- */ - /* Print all enums in separate files */ g_string_append_printf (sn, " <chapter>\n" diff --git a/src/didl2xml.c b/src/didl2xml.c new file mode 100644 index 0000000..35ab8b2 --- /dev/null +++ b/src/didl2xml.c @@ -0,0 +1,628 @@ +/* Copyright (C) 2009 David Zeuthen <zeuthen@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <zeuthen@gmail.com> + */ + +#include "config.h" + +#include <string.h> + +#include "dbusidl.h" + +static gchar **opt_input_files; +static gchar *opt_output_dir; +static gchar **opt_namespaces; +static GOptionEntry entries[] = +{ + { "idl", 'i', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_input_files, "IDL files (may be used several times)", NULL }, + { "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_output_dir, "Directory for output", NULL }, + { "namespaces", 'n', 0, G_OPTION_ARG_STRING_ARRAY, &opt_namespaces, "Namespaces to consider (may be used several times)", NULL }, + { NULL } +}; + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +check_ignore_namespace (DINamespace *namespace, + gchar **namespaces_to_consider) +{ + guint n; + gboolean ret; + + ret = FALSE; + + for (n = 0; namespaces_to_consider[n] != NULL; n++) + { + if (g_strcmp0 (di_namespace_get_name (namespace), namespaces_to_consider[n]) == 0) + goto out; + } + + ret = TRUE; + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_annotations (DIBase *base, + guint indent, + GString *s) +{ + GList *l; + + for (l = di_base_get_annotations (base); l != NULL; l = l->next) + { + DIAnnotation *annotation = l->data; + const gchar *name; + const gchar *value; + gchar *escaped_name; + gchar *escaped_value; + gchar *t; + + name = di_annotation_get_name (annotation); + value = di_annotation_get_value (annotation); + t = g_strescape (name, NULL); + escaped_name = g_markup_escape_text (t, -1); + g_free (t); + if (value != NULL) + { + t = g_strescape (value, NULL); + escaped_value = g_markup_escape_text (t, -1); + g_free (t); + } + else + escaped_value = NULL; + + if (escaped_value != NULL) + { + g_string_append_printf (s, + "%*s<annotation name=\"%s\"\n" + "%*s value=\"%s\"/>\n", + indent, "", + escaped_name, + indent, "", + escaped_value); + } + else + { + g_string_append_printf (s, + "%*s<annotation name=\"%s\"/>\n", + indent, "", + escaped_name); + } + + g_free (escaped_name); + g_free (escaped_value); + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_arg (DIArg *arg, + guint indent, + GString *s) +{ + const gchar *direction; + + switch (di_arg_get_direction (arg)) + { + case DI_ARG_DIRECTION_NONE: + direction = NULL; + break; + case DI_ARG_DIRECTION_IN: + direction = "in"; + break; + case DI_ARG_DIRECTION_OUT: + direction = "out"; + break; + } + + g_string_append_printf (s, + "%*s<arg name=\"%s\" type=\"%s\"", + indent, "", + di_arg_get_name (arg), + di_type_get_signature (di_arg_get_type (arg))); + if (direction != NULL) + g_string_append_printf (s, " direction=\"%s\"", direction); + g_string_append_printf (s, ">\n"); + + print_annotations ((DIBase *) arg, indent + 2, s); + g_string_append_printf (s, "%*s</arg>\n", indent, ""); +} + +static void +print_method (DIMethod *method, + guint indent, + GString *s) +{ + GList *l; + guint n; + + g_string_append_printf (s, + "%*s<method name=\"%s\">\n", + indent, "", + di_method_get_name (method)); + print_annotations ((DIBase *) method, indent + 2, s); + for (l = di_method_get_args (method), n = 0; l != NULL; l = l->next, n++) + { + DIArg *arg = l->data; + + print_arg (arg, indent + 2, s); + } + g_string_append_printf (s, "%*s</method>\n", indent, ""); + +} + +static void +print_signal (DISignal *signal, + guint indent, + GString *s) +{ + GList *l; + guint n; + + g_string_append_printf (s, + "%*s<signal name=\"%s\">\n", + indent, "", + di_signal_get_name (signal)); + print_annotations ((DIBase *) signal, indent + 2, s); + for (l = di_signal_get_args (signal), n = 0; l != NULL; l = l->next, n++) + { + DIArg *arg = l->data; + + print_arg (arg, indent + 2, s); + } + g_string_append_printf (s, "%*s</signal>\n", indent, ""); + +} + +static void +print_property (DIProperty *property, + guint indent, + GString *s) +{ + const gchar *access; + + switch (di_property_get_flags (property)) + { + default: + case DI_PROPERTY_FLAGS_NONE: + access = ""; + break; + case DI_PROPERTY_FLAGS_READABLE: + access = "read"; + break; + case DI_PROPERTY_FLAGS_WRITABLE: + access = "write"; + break; + case DI_PROPERTY_FLAGS_READWRITE: + access = "readwrite"; + break; + } + + g_string_append_printf (s, + "%*s<property name=\"%s\" type=\"%s\" access=\"%s\">\n", + indent, "", + di_property_get_name (property), + di_type_get_signature (di_property_get_type (property)), + access); + print_annotations ((DIBase *) property, indent + 2, s); + g_string_append_printf (s, "%*s</property>\n", indent, ""); + +} + +static void +print_interface (DIInterface *iface, + guint indent, + GString *s) +{ + GList *l; + + g_string_append_printf (s, + "%*s<interface name=\"%s\">\n", + indent, "", + di_interface_get_fully_qualified_name (iface)); + print_annotations ((DIBase *) iface, indent + 2, s); + + g_string_append (s, "\n"); + + /* methods */ + g_string_append_printf (s, "%*s<!-- methods -->\n", indent + 2, ""); + for (l = di_interface_get_methods (iface); l != NULL; l = l->next) + { + DIMethod *method = l->data; + print_method (method, indent + 2, s); + } + g_string_append_printf (s, "\n"); + + /* signals */ + g_string_append_printf (s, "%*s<!-- signals -->\n", indent + 2, ""); + for (l = di_interface_get_signals (iface); l != NULL; l = l->next) + { + DISignal *signal = l->data; + print_signal (signal, indent + 2, s); + } + g_string_append_printf (s, "\n"); + + /* properties */ + g_string_append_printf (s, "%*s<!-- properties -->\n", indent + 2, ""); + for (l = di_interface_get_properties (iface); l != NULL; l = l->next) + { + DIProperty *property = l->data; + print_property (property, indent + 2, s); + } + g_string_append_printf (s, "\n"); + + g_string_append_printf (s, + "%*s</interface>\n", + indent, ""); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_struct (DIStruct *struct_, + guint indent, + GString *s) +{ + GList *l; + + g_string_append_printf (s, + "%*s<struct name=\"%s\">\n", + indent, "", + di_struct_get_fully_qualified_name (struct_)); + print_annotations ((DIBase *) struct_, indent + 2, s); + g_string_append (s, "\n"); + + for (l = di_struct_get_members (struct_); l != NULL; l = l->next) + { + DIStructMember *member = l->data; + + g_string_append_printf (s, "%*s<struct_member name=\"%s\" type=\"%s\">\n", + indent + 2, "", + di_struct_member_get_name (member), + di_type_get_signature (di_struct_member_get_type (member))); + print_annotations ((DIBase *) member, indent + 4, s); + g_string_append_printf (s, + "%*s</struct_member>\n", + indent + 2, ""); + } + + g_string_append_printf (s, + "\n" + "%*s</struct>\n", + indent, ""); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_enum (DIEnum *enum_, + guint indent, + GString *s) +{ + GList *l; + + g_string_append_printf (s, + "%*s<enum name=\"%s\">\n", + indent, "", + di_enum_get_fully_qualified_name (enum_)); + print_annotations ((DIBase *) enum_, indent + 2, s); + g_string_append (s, "\n"); + + for (l = di_enum_get_members (enum_); l != NULL; l = l->next) + { + DIEnumMember *member = l->data; + g_string_append_printf (s, "%*s<enum_member name=\"%s\" value=\"%d\">\n", + indent + 2, "", + di_enum_member_get_name (member), + di_enum_member_get_value (member)); + print_annotations ((DIBase *) member, indent + 4, s); + g_string_append_printf (s, + "%*s</enum_member>\n", + indent + 2, ""); + } + g_string_append_printf (s, + "\n" + "%*s</enum>\n", + indent, ""); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +print_error_domain (DIErrorDomain *error_domain, + guint indent, + GString *s) +{ + GList *l; + + g_string_append_printf (s, + "%*s<error_domain name=\"%s\">\n", + indent, "", + di_error_domain_get_fully_qualified_name (error_domain)); + print_annotations ((DIBase *) error_domain, indent + 2, s); + g_string_append (s, "\n"); + + for (l = di_error_domain_get_members (error_domain); l != NULL; l = l->next) + { + DIErrorMember *member = l->data; + g_string_append_printf (s, "%*s<error name=\"%s\">\n", + indent + 2, "", + di_error_member_get_name (member)); + print_annotations ((DIBase *) member, indent + 4, s); + g_string_append_printf (s, + "%*s</error>\n", + indent + 2, ""); + } + g_string_append_printf (s, + "\n" + "%*s</error_domain>\n", + indent, ""); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +append_dbus_xml_header (GString *s) +{ + g_string_append (s, + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Type Library 1.0//EN\"\n" + " \"http://www.freedesktop.org/standards/dbus/1.0/typelib.dtd\">\n" + "\n"); +} + +static gboolean +write_file (const gchar *filename, + GString *s, + GError **error) +{ + gboolean ret; + gchar *path; + + ret = FALSE; + path = NULL; + + if (opt_output_dir == NULL) + path = g_strdup (filename); + else + path = g_build_filename (opt_output_dir, filename, NULL); + + if (!g_file_set_contents (path, + s->str, + s->len, + error)) + goto out; + + ret = TRUE; + + out: + g_free (path); + return ret; +} + +static gboolean +print_namespace (DINamespace *namespace, + GError **error) +{ + GList *l; + gboolean ret; + gchar *filename; + + ret = FALSE; + + /* ---------------------------------------------------------------------------------------------------- */ + /* Print all interfaces in separate files */ + for (l = di_namespace_get_interfaces (namespace); l != NULL; l = l->next) + { + DIInterface *iface = l->data; + GString *s; + + s = g_string_new (NULL); + append_dbus_xml_header (s); + g_string_append (s, "<typelib>\n"); + + print_interface (iface, 2, s); + + g_string_append (s, "</typelib>\n"); + + filename = g_strdup_printf ("%s.xml", + di_interface_get_fully_qualified_name (iface)); + if (!write_file (filename, s, error)) + { + g_free (filename); + g_string_free (s, TRUE); + goto out; + } + g_string_free (s, TRUE); + g_free (filename); + } + + /* ---------------------------------------------------------------------------------------------------- */ + /* Print all structs in separate files */ + for (l = di_namespace_get_structs (namespace); l != NULL; l = l->next) + { + DIStruct *struct_ = l->data; + GString *s; + + s = g_string_new (NULL); + append_dbus_xml_header (s); + g_string_append (s, "<typelib>\n"); + + print_struct (struct_, 2, s); + + g_string_append (s, "</typelib>\n"); + + filename = g_strdup_printf ("%s.xml", + di_struct_get_fully_qualified_name (struct_)); + if (!write_file (filename, s, error)) + { + g_free (filename); + g_string_free (s, TRUE); + goto out; + } + g_string_free (s, TRUE); + g_free (filename); + } + + /* ---------------------------------------------------------------------------------------------------- */ + /* Print all enums in separate files */ + for (l = di_namespace_get_enums (namespace); l != NULL; l = l->next) + { + DIEnum *enum_ = l->data; + GString *s; + + s = g_string_new (NULL); + + append_dbus_xml_header (s); + + g_string_append (s, "<typelib>\n"); + + print_enum (enum_, 2, s); + + g_string_append (s, "</typelib>\n"); + + filename = g_strdup_printf ("%s.xml", + di_enum_get_fully_qualified_name (enum_)); + if (!write_file (filename, s, error)) + { + g_free (filename); + g_string_free (s, TRUE); + goto out; + } + g_string_free (s, TRUE); + g_free (filename); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /* Print all error domains in separate files */ + for (l = di_namespace_get_error_domains (namespace); l != NULL; l = l->next) + { + DIErrorDomain *error_domain = l->data; + GString *s; + + s = g_string_new (NULL); + append_dbus_xml_header (s); + + g_string_append (s, "<typelib>\n"); + + print_error_domain (error_domain, 2, s); + + g_string_append (s, "</typelib>\n"); + + filename = g_strdup_printf ("%s.xml", + di_error_domain_get_fully_qualified_name (error_domain)); + if (!write_file (filename, s, error)) + { + g_free (filename); + g_string_free (s, TRUE); + goto out; + } + g_string_free (s, TRUE); + g_free (filename); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + ret = TRUE; + + out: + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, char *argv[]) +{ + DIParser *parser; + GList *l; + gint ret; + gchar *s; + GError *error; + GOptionContext *context; + + opt_input_files = NULL; + opt_output_dir = NULL; + opt_namespaces = NULL; + + ret = 1; + + error = NULL; + context = g_option_context_new ("- D-Bus IDL to Docbook compiler"); + g_option_context_add_main_entries (context, entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_printerr ("option parsing failed: %s\n", error->message); + goto out; + } + + if (opt_input_files == NULL) + { + s = g_option_context_get_help (context, FALSE, NULL); + g_print ("%s\n", s); + g_free (s); + goto out; + } + + parser = di_parser_new (opt_input_files[0]); + for (l = di_parser_get_errors (parser); l != NULL; l = l->next) + { + g_printerr ("%s\n", (const gchar *) l->data); + } + for (l = di_parser_get_warnings (parser); l != NULL; l = l->next) + { + g_printerr ("%s\n", (const gchar *) l->data); + } + if (di_parser_get_errors (parser) != NULL) + goto out; + + for (l = di_parser_get_namespaces (parser); l != NULL; l = l->next) + { + DINamespace *namespace = l->data; + + if (opt_namespaces != NULL) + if (check_ignore_namespace (namespace, opt_namespaces)) + continue; + + error = NULL; + if (!print_namespace (namespace, &error)) + { + g_printerr ("Error writing file: %s", error->message); + g_error_free (error); + goto out; + } + } + + ret = 0; + + out: + if (parser != NULL) + di_parser_free (parser); + if (context != NULL) + g_option_context_free (context); + g_strfreev (opt_input_files); + g_free (opt_output_dir); + g_strfreev (opt_namespaces); + return ret;; +} diff --git a/src/idllexer.l b/src/idllexer.l index 5bbb886..e214c8b 100644 --- a/src/idllexer.l +++ b/src/idllexer.l @@ -50,7 +50,6 @@ stringtext ([^\\\"])|(\\.) "signal" {return SIGNAL;} "property" {return PROPERTY;} "struct" {return STRUCT;} -"dynamic_struct" {return DYNAMIC_STRUCT;} "enum" {return ENUM;} "error_domain" {return ERROR_DOMAIN;} "in" {return IN;} diff --git a/src/idlparser.y b/src/idlparser.y index 223633d..c31e643 100644 --- a/src/idlparser.y +++ b/src/idlparser.y @@ -67,7 +67,6 @@ int yywrap (void) gint property_flags; struct _GList *arg_list; struct _DIStruct *struct_; - struct _DIDynamicStruct *dynamic_struct; struct _DIStructMember *struct_member; struct _GList *struct_body; struct _DIEnum *enum_; @@ -86,7 +85,6 @@ int yywrap (void) { struct _GList *interfaces; struct _GList *structs; - struct _GList *dynamic_structs; struct _GList *enums; struct _GList *error_domains; } ns_body; @@ -120,9 +118,6 @@ int yywrap (void) %type <property> property2 %type <property_flags> property_flags -%type <dynamic_struct> dynamic_struct_decl -%type <dynamic_struct> dynamic_struct_decl2 - %type <struct_> struct_decl %type <struct_> struct_decl2 %type <struct_member> struct_member @@ -165,13 +160,11 @@ ns_decl $3, $5.interfaces, $5.structs, - $5.dynamic_structs, $5.enums, $5.error_domains, $1); parser->namespaces = g_list_append (parser->namespaces, namespace); $5.interfaces = NULL; - $5.dynamic_structs = NULL; $5.structs = NULL; $5.enums = NULL; $5.error_domains = NULL; @@ -182,7 +175,6 @@ ns_decls : iface_decl { $$.interfaces = g_list_append (NULL, $1); - $$.dynamic_structs = NULL; $$.structs = NULL; $$.enums = NULL; $$.error_domains = NULL; @@ -195,7 +187,6 @@ ns_decls { $$.interfaces = NULL; $$.structs = g_list_append (NULL, $1); - $$.dynamic_structs = NULL; $$.enums = NULL; $$.error_domains = NULL; } @@ -203,23 +194,10 @@ ns_decls { $$.structs = g_list_append ($1.structs, $2); } - | dynamic_struct_decl - { - $$.interfaces = NULL; - $$.structs = NULL; - $$.dynamic_structs = g_list_append (NULL, $1); - $$.enums = NULL; - $$.error_domains = NULL; - } - | ns_decls dynamic_struct_decl - { - $$.dynamic_structs = g_list_append ($1.dynamic_structs, $2); - } | enum_decl { $$.interfaces = NULL; $$.structs = NULL; - $$.dynamic_structs = NULL; $$.enums = g_list_append (NULL, $1); $$.error_domains = NULL; } @@ -231,7 +209,6 @@ ns_decls { $$.interfaces = NULL; $$.structs = NULL; - $$.dynamic_structs = NULL; $$.enums = NULL; $$.error_domains = g_list_append (NULL, $1); } @@ -413,30 +390,6 @@ numberexpr /* ---------------------------------------------------------------------------------------------------- */ -dynamic_struct_decl - : dynamic_struct_decl2 - { - $$ = $1; - } - | DOC_COMMENT dynamic_struct_decl2 - { - di_comment_set ($1, (DIBase *) $2); - $$ = $2; - } - -dynamic_struct_decl2 - : annotation_list DYNAMIC_STRUCT IDENTIFIER OBRACE struct_body EBRACE SEMICOLON - { - $$ = di_dynamic_struct_new (g_strdup (parser->path_to_current_file), - yylineno, - g_strdup ($3), - $5, - $1); - } - ; - -/* ---------------------------------------------------------------------------------------------------- */ - struct_decl : struct_decl2 { @@ -852,7 +805,7 @@ basic_type ; // keywords -%token INTERFACE SIGNAL PROPERTY STRUCT DYNAMIC_STRUCT ENUM FLAGS ERROR_DOMAIN NAMESPACE; +%token INTERFACE SIGNAL PROPERTY STRUCT ENUM FLAGS ERROR_DOMAIN NAMESPACE; %token IN OUT READONLY WRITEONLY; diff --git a/src/org.freedesktop.DBus.Idl.Tests1.didl b/src/org.freedesktop.DBus.Idl.Tests1.didl index c630bb9..afa4dad 100644 --- a/src/org.freedesktop.DBus.Idl.Tests1.didl +++ b/src/org.freedesktop.DBus.Idl.Tests1.didl @@ -1,3 +1,4 @@ + @Version("1.5") namespace org.freedesktop.DBus.Idl.Tests1 { @@ -7,7 +8,35 @@ namespace org.freedesktop.DBus.Idl.Tests1 * @Cancelled: The operation was cancelled. * @WouldBlock: The operation would block and non-blocking semantics was requested. * - * An example of an error domain. + * An example <literal>of</literal> an <emphasis>error</emphasis> domain. + * + * <programlisting> + * int foo; + * + * void + * bar (int baz) + * { + * do_stuff (); + * } + * </programlisting> + * + * Here is a paragraph that spans multiple lines. It is pretty + * long, on purpose. The quick brown fox jumped over the lazy dog. + * Ipsum lorem dolor sit amet. + * + * Check that references work... + * method: org.freedesktop.DBus.Idl.Tests1.Frobicable.VoidMethod(), + * signal: #org.freedesktop.DBus.Idl.Tests1.Frobicable::ArgSignal, + * property: #org.freedesktop.DBus.Idl.Tests1.Frobicable:RWProperty, + * struct: #org.freedesktop.DBus.Idl.Tests1.RealPoint, + * dynamic_struct: #org.freedesktop.DBus.Idl.Tests1.Struct2, + * enum: #org.freedesktop.DBus.Idl.Tests1.Enum2, + * enum member: #org.freedesktop.DBus.Idl.Tests1.Enum2.Replace, + * error domain: #org.freedesktop.DBus.Idl.Tests1.Error, + * error member: #org.freedesktop.DBus.Idl.Tests1.Error.Cancelled ... + * that's it! + * + * And here is a third paragraph. * * @brief: Error domain */ @@ -21,13 +50,13 @@ namespace org.freedesktop.DBus.Idl.Tests1 // An example of manual doc tags. - @Doc("Another Error Domain.") - @DocBrief("Another Error Domain") + @org.freedesktop.DBus.Typelib.Doc("Another Error Domain.") + @org.freedesktop.DBus.Typelib.DocBrief("Another Error Domain") error_domain Error2 { - @Doc("Parsing failed.") + @org.freedesktop.DBus.Typelib.Doc("Parsing failed.") ParsingFailed, - @Doc("Foo operation failed.") + @org.freedesktop.DBus.Typelib.Doc("Foo operation failed.") FooFailed }; @@ -38,6 +67,7 @@ namespace org.freedesktop.DBus.Idl.Tests1 * @something: Third member. * @lots_of_something: An array of #Variant<!-- -->s. * @property_bag: A property bag. + * @an_enum: An enum. * * A longer explanation of the example struct. * @@ -50,6 +80,7 @@ namespace org.freedesktop.DBus.Idl.Tests1 variant something; array<variant> lots_of_something; dict<string,variant> property_bag; + Enum1 an_enum; }; /** @@ -65,7 +96,8 @@ namespace org.freedesktop.DBus.Idl.Tests1 * * @brief: A Dynamic Struct */ - dynamic_struct Struct2 + @org.freedesktop.DBus.Typelib.DynamicStruct + struct Struct2 { uint64 a; uint64 b; @@ -123,7 +155,7 @@ namespace org.freedesktop.DBus.Idl.Tests1 * * @brief: Flags used for EnumMethod() */ - @Flags + @org.freedesktop.DBus.Typelib.FlagEnum enum Enum2 { None = 0, @@ -169,13 +201,13 @@ namespace org.freedesktop.DBus.Idl.Tests1 double y; }; - @Doc("A data type holding a pair of 32-bit integers.") - @DocBrief("Pair of integers") + @org.freedesktop.DBus.Typelib.Doc("A data type holding a pair of 32-bit integers.") + @org.freedesktop.DBus.Typelib.DocBrief("Pair of integers") struct Pair { - @Doc("First element in pair.") + @org.freedesktop.DBus.Typelib.Doc("First element in pair.") int32 first; - @Doc("Second element in pair.") + @org.freedesktop.DBus.Typelib.Doc("Second element in pair.") int32 second; }; @@ -204,6 +236,8 @@ namespace org.freedesktop.DBus.Idl.Tests1 * @a12: A parameter. * * Method taking primitive types. + * + * Here's another paragraph for this method! */ PrimitiveMethod (in byte a1, in boolean a2, |