From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Daiki Ueno Newsgroups: gmane.emacs.bugs Subject: bug#20193: 25.0.50; declarative type specification for D-Bus args Date: Thu, 27 Aug 2015 18:23:38 +0900 Message-ID: References: <87bnjgat6z.fsf@gmx.de> <874mp628is.fsf@gmx.de> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1440667498 6412 80.91.229.3 (27 Aug 2015 09:24:58 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 27 Aug 2015 09:24:58 +0000 (UTC) Cc: 20193@debbugs.gnu.org To: Michael Albinus Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Aug 27 11:24:47 2015 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZUtQH-0006S1-A6 for geb-bug-gnu-emacs@m.gmane.org; Thu, 27 Aug 2015 11:24:41 +0200 Original-Received: from localhost ([::1]:33776 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZUtQB-0003K8-I0 for geb-bug-gnu-emacs@m.gmane.org; Thu, 27 Aug 2015 05:24:35 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45027) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZUtPj-0002qL-9c for bug-gnu-emacs@gnu.org; Thu, 27 Aug 2015 05:24:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZUtPe-0002rX-Vp for bug-gnu-emacs@gnu.org; Thu, 27 Aug 2015 05:24:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:47469) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZUtPe-0002rH-Rp for bug-gnu-emacs@gnu.org; Thu, 27 Aug 2015 05:24:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1ZUtPe-0005Ij-Fc for bug-gnu-emacs@gnu.org; Thu, 27 Aug 2015 05:24:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Daiki Ueno Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 27 Aug 2015 09:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20193 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 20193-submit@debbugs.gnu.org id=B20193.144066743420364 (code B ref 20193); Thu, 27 Aug 2015 09:24:02 +0000 Original-Received: (at 20193) by debbugs.gnu.org; 27 Aug 2015 09:23:54 +0000 Original-Received: from localhost ([127.0.0.1]:39679 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZUtPV-0005IN-Su for submit@debbugs.gnu.org; Thu, 27 Aug 2015 05:23:54 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:34891) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZUtPT-0005IC-FU for 20193@debbugs.gnu.org; Thu, 27 Aug 2015 05:23:52 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZUtPN-0002gL-M1 for 20193@debbugs.gnu.org; Thu, 27 Aug 2015 05:23:51 -0400 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:51304) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZUtPN-0002gC-Ig; Thu, 27 Aug 2015 05:23:45 -0400 Original-Received: from du-a.org ([219.94.251.20]:50722 helo=dhcp-217-92.nrt.redhat.com) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1ZUtPM-0004gl-FI; Thu, 27 Aug 2015 05:23:45 -0400 In-Reply-To: <874mp628is.fsf@gmx.de> (Michael Albinus's message of "Fri, 27 Mar 2015 08:40:11 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:105867 Archived-At: --=-=-= Content-Type: text/plain Michael Albinus writes: > Daiki Ueno writes: > >> Certainly. Do you have any preference on the alternative form? My >> example used the `:type' keyword, but it was a tentative plan and might >> be too verbose for programmers. Reusing `:signature' might be a better >> idea as you mentioned (though it might be confusing with the current >> meaning of `:signature' as a D-Bus type "g"). > > I'm OK with :type, as you said it is similar to what defcustom > offers. :signature would be confusing indeed, when it means Lisp > objects instead of a signature string. Sorry for the long delay. I have tried to implement it (patch attached). It basically adds a couple of new functions: - xd_type_spec_to_signature(char *, Lisp_Object) - xd_append_arg_with_type_spec(Lisp_Object, Lisp_Object, DBusMessageIter *) which are similar to xd_signature and xd_append_arg, but take a Lisp_Object denoting an argument type. Comments appreciated. Regards, -- Daiki Ueno --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-dbusbind-Add-alternative-form-for-compound-args.patch >From 064aaaadd84310e4fd9beaa3d5c0fb74a70c4e92 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 27 Aug 2015 17:06:19 +0900 Subject: [PATCH] dbusbind: Add alternative form for compound args * src/dbusbind.c (xd_append_basic_arg): New function, split from xd_append_arg. (xd_append_arg): Use xd_append_arg. (xd_type_spec_to_signature): New function. (xd_append_arg_with_type_spec): New function. (Fdbus_message_internal): Use xd_append_arg_with_type_spec, instead of xd_append_arg. (syms_of_dbusbind): Provide subfeature `:type'. * doc/misc/dbus.texi (Type Conversion): Mention `:type' keyword. Fixes: debbugs:20193 --- doc/misc/dbus.texi | 17 ++++- src/dbusbind.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 204 insertions(+), 12 deletions(-) diff --git a/doc/misc/dbus.texi b/doc/misc/dbus.texi index 5dd8bf2..03feecc 100644 --- a/doc/misc/dbus.texi +++ b/doc/misc/dbus.texi @@ -1030,7 +1030,22 @@ corresponding D-Bus container. @code{:array} is optional, because this is the default compound D-Bus type for a list. The objects being elements of the list are checked according to the -D-Bus compound type rules. +D-Bus compound type rules. If those elements have a type different +from the default type, they need to be prefixed with a type symbol. + +@lisp +(dbus-call-method @dots{} :array '(:int32 @var{NAT-NUMBER} :int32 @var{NAT-NUMBER})) +@end lisp + +There is an alternative form to specify the type of the following +compound type argument, using the keyword @code{:type} followed by a +type specifier, which denotes a compound type as a list of type symbols. + +The above example is equivalent to: + +@lisp +(dbus-call-method @dots{} :type '(:array :int32) '(@var{NAT-NUMBER} @var{NAT-NUMBER})) +@end lisp @itemize @item An array must contain only elements of the same D-Bus type. It diff --git a/src/dbusbind.c b/src/dbusbind.c index be1b890..81b6c27 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -567,18 +567,9 @@ xd_extract_unsigned (Lisp_Object x, uintmax_t hi) args_out_of_range_3 (x, make_number (0), make_fixnum_or_float (hi)); } -/* Append C value, extracted from Lisp OBJECT, to iteration ITER. - DTYPE must be a valid DBusType. It is used to convert Lisp - objects, being arguments of `dbus-call-method' or - `dbus-send-signal', into corresponding C values appended as - arguments to a D-Bus message. */ static void -xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) +xd_append_basic_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) { - char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; - DBusMessageIter subiter; - - if (XD_BASIC_DBUS_TYPE (dtype)) switch (dtype) { case DBUS_TYPE_BYTE: @@ -703,7 +694,21 @@ xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) return; } } +} + +/* Append C value, extracted from Lisp OBJECT, to iteration ITER. + DTYPE must be a valid DBusType. It is used to convert Lisp + objects, being arguments of `dbus-call-method' or + `dbus-send-signal', into corresponding C values appended as + arguments to a D-Bus message. */ +static void +xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) +{ + char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; + DBusMessageIter subiter; + if (XD_BASIC_DBUS_TYPE (dtype)) + xd_append_basic_arg (dtype, object, iter); else /* Compound types. */ { @@ -792,6 +797,161 @@ xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) } } +static void +xd_type_spec_to_signature (char *signature, Lisp_Object spec) +{ + int dtype; + + if (SYMBOLP (spec)) + { + dtype = xd_symbol_to_dbus_type (spec); + if (!XD_BASIC_DBUS_TYPE (dtype)) + wrong_type_argument (intern ("D-Bus"), spec); + sprintf (signature, "%c", dtype); + } + else /* Compound types. */ + { + char *subsig; + char x[DBUS_MAXIMUM_SIGNATURE_LENGTH]; + Lisp_Object elt; + + CHECK_CONS (spec); + + dtype = xd_symbol_to_dbus_type (CAR (spec)); + elt = CDR_SAFE (spec); + + switch (dtype) + { + case DBUS_TYPE_ARRAY: + sprintf (signature, "%c", dtype); + if (NILP (elt)) + /* If the array is empty, DBUS_TYPE_STRING is the default + element type. */ + subsig = DBUS_TYPE_STRING_AS_STRING; + else + { + xd_type_spec_to_signature (x, CAR_SAFE (elt)); + subsig = x; + } + xd_signature_cat (signature, subsig); + break; + + case DBUS_TYPE_VARIANT: + sprintf (signature, "%c", dtype); + break; + + case DBUS_TYPE_STRUCT: + sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR); + while (!NILP (elt)) + { + xd_type_spec_to_signature (x, CAR_SAFE (elt)); + xd_signature_cat (signature, x); + elt = CDR_SAFE (elt); + } + xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); + break; + + case DBUS_TYPE_DICT_ENTRY: + sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR); + while (!NILP (elt)) + { + xd_type_spec_to_signature (x, CAR_SAFE (elt)); + xd_signature_cat (signature, x); + elt = CDR_SAFE (elt); + } + xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); + break; + + default: + wrong_type_argument (intern ("D-Bus"), spec); + } + } +} + +static void +xd_append_arg_with_type_spec (Lisp_Object spec, Lisp_Object object, + DBusMessageIter *iter) +{ + int dtype; + + if (SYMBOLP (spec)) + { + dtype = xd_symbol_to_dbus_type (spec); + if (!XD_BASIC_DBUS_TYPE (dtype)) + wrong_type_argument (intern ("D-Bus"), spec); + xd_append_basic_arg (dtype, object, iter); + } + else /* Compound types. */ + { + char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; + DBusMessageIter subiter; + int subtype; + Lisp_Object subspec; + Lisp_Object elt; + + CHECK_CONS (spec); + + dtype = xd_symbol_to_dbus_type (CAR (spec)); + elt = CDR_SAFE (spec); + + /* Open new subiteration. */ + switch (dtype) + { + case DBUS_TYPE_ARRAY: + if (NILP (elt)) + /* If the array is empty, DBUS_TYPE_STRING is the default + element type. */ + subspec = QCdbus_type_string; + else + subspec = CAR_SAFE (elt); + xd_type_spec_to_signature (signature, subspec); + if (!dbus_message_iter_open_container (iter, dtype, + signature, &subiter)) + XD_SIGNAL3 (build_string ("Cannot open container"), + make_number (dtype), build_string (signature)); + break; + + case DBUS_TYPE_VARIANT: + /* A variant has just one element. */ + subspec = CAR_SAFE (elt); + xd_type_spec_to_signature (signature, subspec); + + if (!dbus_message_iter_open_container (iter, dtype, + signature, &subiter)) + XD_SIGNAL3 (build_string ("Cannot open container"), + make_number (dtype), build_string (signature)); + break; + + case DBUS_TYPE_STRUCT: + case DBUS_TYPE_DICT_ENTRY: + /* These containers do not require a signature. */ + subspec = CAR_SAFE (elt); + xd_type_spec_to_signature (signature, subspec); + + if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter)) + XD_SIGNAL2 (build_string ("Cannot open container"), + make_number (dtype)); + break; + + default: + wrong_type_argument (intern ("D-Bus"), list2 (spec, object)); + } + + /* Loop over list elements. */ + while (!NILP (object)) + { + xd_append_arg_with_type_spec (subspec, CAR_SAFE (object), &subiter); + + object = CDR_SAFE (object); + } + + /* Close the subiteration. */ + if (!dbus_message_iter_close_container (iter, &subiter)) + XD_SIGNAL2 (build_string ("Cannot close container"), + make_number (dtype)); + } +} + /* Retrieve C value from a DBusMessageIter structure ITER, and return a converted Lisp object. The type DTYPE of the argument of the D-Bus message must be a valid DBusType. Compound D-Bus types @@ -1443,6 +1603,13 @@ usage: (dbus-message-internal &rest REST) */) /* Append parameters to the message. */ for (; count < nargs; ++count) { + if (EQ (args[count], QCdbus_type_type)) + { + xd_append_arg_with_type_spec (args[count+1], args[count+2], &iter); + count += 2; + } + else + { dtype = XD_OBJECT_TO_DBUS_TYPE (args[count]); if (XD_DBUS_TYPE_P (args[count])) { @@ -1466,6 +1633,7 @@ usage: (dbus-message-internal &rest REST) */) xd_append_arg (dtype, args[count], &iter); } + } if (!NILP (handler)) { @@ -1718,6 +1886,8 @@ init_dbusbind (void) void syms_of_dbusbind (void) { + Lisp_Object subfeatures = Qnil; + defsubr (&Sdbus__init_bus); defsubr (&Sdbus_get_unique_name); @@ -1759,6 +1929,9 @@ syms_of_dbusbind (void) DEFSYM (QCdbus_type_struct, ":struct"); DEFSYM (QCdbus_type_dict_entry, ":dict-entry"); + /* Lisp symbol to indicate explicit typing of the following parameter. */ + DEFSYM (QCdbus_type_type, ":type"); + /* Lisp symbols of objects in `dbus-registered-objects-table'. */ DEFSYM (QCdbus_registered_serial, ":serial"); DEFSYM (QCdbus_registered_method, ":method"); @@ -1866,7 +2039,11 @@ be called when the D-Bus reply message arrives. */); xd_registered_buses = Qnil; staticpro (&xd_registered_buses); - Fprovide (intern_c_string ("dbusbind"), Qnil); + /* Add subfeature `:type'. */ + subfeatures = pure_cons (pure_cons (QCdbus_type_type, pure_cons (Qt, Qnil)), + subfeatures); + + Fprovide (intern_c_string ("dbusbind"), subfeatures); } -- 2.4.3 --=-=-=--