[vala] D-Bus: Support marshalling enumerations as strings
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] D-Bus: Support marshalling enumerations as strings
- Date: Sat, 26 Sep 2009 15:00:07 +0000 (UTC)
commit d4dace4197a5ee01a73516fd3fde8c56c12561c3
Author: Didier 'Ptitjes <ptitjes free fr>
Date: Fri Sep 18 12:01:08 2009 +0200
D-Bus: Support marshalling enumerations as strings
Fixes bug 580984.
codegen/valaccodebasemodule.vala | 8 +-
codegen/valadbusmodule.vala | 192 ++++++++++++++++++++++++++++++++++++--
2 files changed, 190 insertions(+), 10 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index e12e2bc..a00bd24 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -714,9 +714,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
return define.str;
}
- public void generate_enum_declaration (Enum en, CCodeDeclarationSpace decl_space) {
+ public virtual bool generate_enum_declaration (Enum en, CCodeDeclarationSpace decl_space) {
if (decl_space.add_symbol_declaration (en, en.get_cname ())) {
- return;
+ return false;
}
var cenum = new CCodeEnum (en.get_cname ());
@@ -734,7 +734,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
decl_space.add_type_definition (new CCodeNewline ());
if (!en.has_type_id) {
- return;
+ return true;
}
decl_space.add_type_declaration (new CCodeNewline ());
@@ -750,6 +750,8 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
decl_space.add_type_member_declaration (regfun);
+
+ return true;
}
public override void visit_enum (Enum en) {
diff --git a/codegen/valadbusmodule.vala b/codegen/valadbusmodule.vala
index 44018f9..1fbd473 100644
--- a/codegen/valadbusmodule.vala
+++ b/codegen/valadbusmodule.vala
@@ -49,6 +49,27 @@ internal class Vala.DBusModule : GAsyncModule {
base (codegen, next);
}
+ static bool is_string_marshalled_enum (TypeSymbol? symbol) {
+ if (symbol != null && symbol is Enum) {
+ var dbus = symbol.get_attribute ("DBus");
+ return dbus != null && dbus.get_bool ("use_string_marshalling");
+ }
+ return false;
+ }
+
+ string get_dbus_value (EnumValue value, string default_value) {
+ var dbus = value.get_attribute ("DBus");
+ if (dbus == null) {
+ return default_value;
+ }
+
+ string dbus_value = dbus.get_string ("value");
+ if (dbus_value == null) {
+ return default_value;
+ }
+ return dbus_value;
+ }
+
public string? get_dbus_name (TypeSymbol symbol) {
var dbus = symbol.get_attribute ("DBus");
if (dbus == null) {
@@ -78,7 +99,35 @@ internal class Vala.DBusModule : GAsyncModule {
}
public static string get_type_signature (DataType datatype) {
- return datatype.get_type_signature ();
+ if (is_string_marshalled_enum (datatype.data_type)) {
+ return "s";
+ } else {
+ return datatype.get_type_signature ();
+ }
+ }
+
+ public override void visit_enum (Enum en) {
+ base.visit_enum (en);
+
+ if (is_string_marshalled_enum (en)) {
+ // strcmp
+ source_declarations.add_include ("string.h");
+ source_declarations.add_include ("dbus/dbus-glib.h");
+
+ source_type_member_definition.append (generate_enum_from_string_function (en));
+ source_type_member_definition.append (generate_enum_to_string_function (en));
+ }
+ }
+
+ public override bool generate_enum_declaration (Enum en, CCodeDeclarationSpace decl_space) {
+ if (base.generate_enum_declaration (en, decl_space)) {
+ if (is_string_marshalled_enum (en)) {
+ decl_space.add_type_member_declaration (generate_enum_from_string_function_declaration (en));
+ decl_space.add_type_member_declaration (generate_enum_to_string_function_declaration (en));
+ }
+ return true;
+ }
+ return false;
}
CCodeExpression? get_array_length (CCodeExpression expr, int dim) {
@@ -92,7 +141,81 @@ internal class Vala.DBusModule : GAsyncModule {
return null;
}
- CCodeExpression read_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression iter_expr) {
+ CCodeExpression? generate_enum_value_from_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) {
+ var en = type.type_symbol as Enum;
+ var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null));
+
+ var from_string_call = new CCodeFunctionCall (new CCodeIdentifier (from_string_name));
+ from_string_call.add_argument (expr);
+ from_string_call.add_argument (new CCodeConstant ("NULL"));
+
+ return from_string_call;
+ }
+
+ public CCodeFunction generate_enum_from_string_function_declaration (Enum en) {
+ var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null));
+
+ var from_string_func = new CCodeFunction (from_string_name, en.get_cname ());
+ from_string_func.add_parameter (new CCodeFormalParameter ("str", "const char*"));
+ from_string_func.add_parameter (new CCodeFormalParameter ("error", "GError**"));
+
+ return from_string_func;
+ }
+
+ public CCodeFunction generate_enum_from_string_function (Enum en) {
+ var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null));
+
+ var from_string_func = new CCodeFunction (from_string_name, en.get_cname ());
+ from_string_func.add_parameter (new CCodeFormalParameter ("str", "const char*"));
+ from_string_func.add_parameter (new CCodeFormalParameter ("error", "GError**"));
+
+ var from_string_block = new CCodeBlock ();
+ from_string_func.block = from_string_block;
+
+ var cdecl = new CCodeDeclaration (en.get_cname ());
+ cdecl.add_declarator (new CCodeVariableDeclarator ("value"));
+ from_string_block.add_statement (cdecl);
+
+ CCodeStatement if_else_if = null;
+ CCodeIfStatement last_statement = null;
+ foreach (EnumValue enum_value in en.get_values ()) {
+ var true_block = new CCodeBlock ();
+ true_block.suppress_newline = true;
+ true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("value"), new CCodeIdentifier (enum_value.get_cname ()))));
+
+ string dbus_value = get_dbus_value (enum_value, enum_value.name);
+ var string_comparison = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
+ string_comparison.add_argument (new CCodeIdentifier ("str"));
+ string_comparison.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_value)));
+ var stmt = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, string_comparison, new CCodeConstant ("0")), true_block);
+
+ if (last_statement != null) {
+ last_statement.false_statement = stmt;
+ } else {
+ if_else_if = stmt;
+ }
+ last_statement = stmt;
+ }
+
+ var error_block = new CCodeBlock ();
+ error_block.suppress_newline = true;
+
+ var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error_literal"));
+ set_error_call.add_argument (new CCodeIdentifier ("error"));
+ set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR"));
+ set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_INVALID_ARGS"));
+ set_error_call.add_argument (new CCodeConstant ("\"Invalid enumeration value\""));
+ error_block.add_statement (new CCodeExpressionStatement (set_error_call));
+
+ last_statement.false_statement = error_block;
+ from_string_block.add_statement (if_else_if);
+
+ from_string_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("value")));
+
+ return from_string_func;
+ }
+
+ CCodeExpression read_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression iter_expr, bool transfer = false) {
string temp_name = "_tmp%d_".printf (next_temp_var_id++);
var cdecl = new CCodeDeclaration (basic_type.cname);
@@ -106,9 +229,10 @@ internal class Vala.DBusModule : GAsyncModule {
var temp_result = new CCodeIdentifier (temp_name);
- if (basic_type.signature == "s"
- || basic_type.signature == "o"
- || basic_type.signature == "g") {
+ if (!transfer
+ && (basic_type.signature == "s"
+ || basic_type.signature == "o"
+ || basic_type.signature == "g")) {
var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup"));
dup_call.add_argument (temp_result);
return dup_call;
@@ -388,7 +512,11 @@ internal class Vala.DBusModule : GAsyncModule {
public CCodeExpression? read_expression (CCodeFragment fragment, DataType type, CCodeExpression iter_expr, CCodeExpression? expr) {
BasicTypeInfo basic_type;
CCodeExpression result = null;
- if (get_basic_type_info (get_type_signature (type), out basic_type)) {
+ if (is_string_marshalled_enum (type.data_type)) {
+ get_basic_type_info ("s", out basic_type);
+ result = read_basic (fragment, basic_type, iter_expr, true);
+ result = generate_enum_value_from_string (fragment, type as EnumValueType, result);
+ } else if (get_basic_type_info (get_type_signature (type), out basic_type)) {
result = read_basic (fragment, basic_type, iter_expr);
} else if (type is ArrayType) {
result = read_array (fragment, (ArrayType) type, iter_expr, expr);
@@ -423,6 +551,52 @@ internal class Vala.DBusModule : GAsyncModule {
return result;
}
+ CCodeExpression? generate_enum_value_to_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) {
+ var en = type.type_symbol as Enum;
+ var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null));
+
+ var to_string_call = new CCodeFunctionCall (new CCodeIdentifier (to_string_name));
+ to_string_call.add_argument (expr);
+
+ return to_string_call;
+ }
+
+ public CCodeFunction generate_enum_to_string_function_declaration (Enum en) {
+ var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null));
+
+ var to_string_func = new CCodeFunction (to_string_name, "const char*");
+ to_string_func.add_parameter (new CCodeFormalParameter ("value", en.get_cname ()));
+
+ return to_string_func;
+ }
+
+ public CCodeFunction generate_enum_to_string_function (Enum en) {
+ var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null));
+
+ var to_string_func = new CCodeFunction (to_string_name, "const char*");
+ to_string_func.add_parameter (new CCodeFormalParameter ("value", en.get_cname ()));
+
+ var to_string_block = new CCodeBlock ();
+ to_string_func.block = to_string_block;
+
+ var cdecl = new CCodeDeclaration ("const char *");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("str"));
+ to_string_block.add_statement (cdecl);
+
+ var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("value"));
+ foreach (EnumValue enum_value in en.get_values ()) {
+ string dbus_value = get_dbus_value (enum_value, enum_value.name);
+ cswitch.add_statement (new CCodeCaseStatement (new CCodeIdentifier (enum_value.get_cname ())));
+ cswitch.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("str"), new CCodeConstant ("\"%s\"".printf (dbus_value)))));
+ cswitch.add_statement (new CCodeBreakStatement ());
+ }
+ to_string_block.add_statement (cswitch);
+
+ to_string_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("str")));
+
+ return to_string_func;
+ }
+
void write_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression iter_expr, CCodeExpression expr) {
string temp_name = "_tmp%d_".printf (next_temp_var_id++);
@@ -657,7 +831,11 @@ internal class Vala.DBusModule : GAsyncModule {
public void write_expression (CCodeFragment fragment, DataType type, CCodeExpression iter_expr, CCodeExpression expr) {
BasicTypeInfo basic_type;
- if (get_basic_type_info (get_type_signature (type), out basic_type)) {
+ if (is_string_marshalled_enum (type.data_type)) {
+ get_basic_type_info ("s", out basic_type);
+ var result = generate_enum_value_to_string (fragment, type as EnumValueType, expr);
+ write_basic (fragment, basic_type, iter_expr, result);
+ } else if (get_basic_type_info (get_type_signature (type), out basic_type)) {
write_basic (fragment, basic_type, iter_expr, expr);
} else if (type is ArrayType) {
write_array (fragment, (ArrayType) type, iter_expr, expr);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]