prettyprint (fwd)
Daniel Reed
n at ml.org
Fri Mar 4 09:21:38 PST 2005
I haven't seen any work lately on the pretty printer used in dbus-send and
dbus-monitor, so hopefully I'm not stepping on anyone's toes.
Attached is a new pretty printer that supports simple array recursion and
includes a couple example output styles. Right now it handles a "classic"
style by calling into tools/dbus-print-message.c's print_message(), but it
shouldn't be too hard to rewrite that to take advantage of recursion.
Messages like:
dbus-send --session --dest=org.ml.n.naim.ConnectionManager --type=method_call --print-reply /org/ml/n/naim/Connection org.ml.n.naim.ConnectionManager.EnumerateConnections
method return sender=:1.4 -> dest=:1.8
(dbus-monitor too dumb to decipher arg type 'a')
show up now using the "C decl" style, like:
dbus-send --session --dest=org.ml.n.naimng.x_connections --type=method_call --print-reply /org/ml/n/naimng/x_connections org.ml.n.naimng.x_connections.list
message = {
type: 1 /* method_call */,
method: "list",
target interface: "org.ml.n.naimng.x_connections",
target service: "org.ml.n.naimng.x_connections",
path: "/org/ml/n/naimng/x_connections",
};
message = {
type: 2 /* method_return */,
target service: ":1.261" /* me */,
sender service: ":1.257",
sender uid: 500,
signature: as,
args: {
{
"dummy1",
"dummy2"
}
}
};
whereas:
dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.RequestName string:org.example.DBus uint32:0
message = {
type: 1 /* method_call */,
method: "RequestName",
target interface: "org.freedesktop.DBus",
target service: "org.freedesktop.DBus",
path: "/org/freedesktop/DBus",
signature: su,
args: {
"org.example.DBus",
(uint32)0
}
};
message = {
type: 2 /* method_return */,
target service: ":1.263" /* me */,
sender service: "org.freedesktop.DBus",
signature: u,
args: {
(uint32)1
}
};
Messages in dbus-monitor use the more-compact "CIDL call" style, like:
org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged (":1.263", "", ":1.263")
:1.263 /org/freedesktop/DBus org.freedesktop.DBus.Hello ()
org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged ("org.example.DBus", "", ":1.263")
:1.263 /org/freedesktop/DBus org.freedesktop.DBus.RequestName ("org.example.DBus", (uint32)0)
org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged ("org.example.DBus", ":1.263", "")
org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged (":1.263", ":1.263", "")
(And I won't orphan the code if anyone is interested in using and extending it.)
--
Daniel Reed <n at ml.org> http://naim-users.org/nmlorg/ http://naim.n.ml.org/
I don't like sending my conversation hundreds of miles where a lot
of people can read it o_0 even if I am just talking about cheese. --
Avatar214, re: encryption in naim
-------------- next part --------------
Index: tools/Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/tools/Makefile.am,v
retrieving revision 1.11
diff -u -r1.11 Makefile.am
--- tools/Makefile.am 13 Feb 2005 17:16:25 -0000 1.11
+++ tools/Makefile.am 3 Mar 2005 06:43:40 -0000
@@ -15,14 +15,18 @@
bin_PROGRAMS=dbus-send $(GLIB_TOOLS) dbus-launch dbus-cleanup-sockets $(GTK_TOOLS)
dbus_send_SOURCES= \
+ dbus-prettyprint.c \
+ dbus-prettyprint.h \
dbus-print-message.c \
dbus-print-message.h \
dbus-send.c
dbus_monitor_SOURCES= \
- dbus-monitor.c \
+ dbus-prettyprint.c \
+ dbus-prettyprint.h \
dbus-print-message.c \
- dbus-print-message.h
+ dbus-print-message.h \
+ dbus-monitor.c
dbus_launch_SOURCES= \
dbus-launch.c
Index: tools/dbus-monitor.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-monitor.c,v
retrieving revision 1.13
diff -u -r1.13 dbus-monitor.c
--- tools/dbus-monitor.c 17 Feb 2005 21:19:48 -0000 1.13
+++ tools/dbus-monitor.c 3 Mar 2005 06:43:40 -0000
@@ -25,14 +25,20 @@
#include <glib.h>
#include <dbus/dbus-glib-lowlevel.h>
-#include "dbus-print-message.h"
+#include "dbus-prettyprint.h"
+
+typedef struct _dbus_monitor_data {
+ DBusMessagePrintStyle style;
+} _dbus_monitor_data;
static DBusHandlerResult
filter_func (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
- print_message (message);
+ _dbus_monitor_data *data = (_dbus_monitor_data *)user_data;
+
+ dbus_message_prettyprint (connection, message, data->style);
if (dbus_message_is_signal (message,
DBUS_INTERFACE_LOCAL,
@@ -61,6 +67,9 @@
DBusBusType type = DBUS_BUS_SESSION;
GMainLoop *loop;
int i;
+ _dbus_monitor_data data = {
+ style: DBUS_MESSAGE_PRINT_STYLE_CIDL_CALL
+ };
for (i = 1; i < argc; i++)
{
@@ -116,7 +125,7 @@
&error);
if (dbus_error_is_set (&error))
goto lose;
- if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
+ if (!dbus_connection_add_filter (connection, filter_func, &data, NULL)) {
fprintf (stderr, "Couldn't add filter!\n");
exit (1);
}
Index: tools/dbus-send.1
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-send.1,v
retrieving revision 1.6
diff -u -r1.6 dbus-send.1
--- tools/dbus-send.1 18 Jan 2005 20:42:15 -0000 1.6
+++ tools/dbus-send.1 3 Mar 2005 06:43:40 -0000
@@ -9,7 +9,7 @@
.PP
.B dbus-send
[\-\-system | \-\-session] [\-\-dest=NAME] [\-\-print-reply]
-[\-\-type=TYPE] <destination object path> <message name> [contents ...]
+[\-\-type=TYPE] [\-\-style=STYLE] <destination object path> <message name> [contents ...]
.SH DESCRIPTION
@@ -70,6 +70,9 @@
.TP
.I "--type=TYPE"
Specify "method_call" or "signal" (defaults to "signal").
+.TP
+.I "--style=STYLE"
+Specify "cdecl", "ccall", "cxxcall", "cidlcall", or "classic" (defaults to "cdecl").
.SH AUTHOR
dbus-send was written by Philip Blundell.
Index: tools/dbus-send.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-send.c,v
retrieving revision 1.13
diff -u -r1.13 dbus-send.c
--- tools/dbus-send.c 18 Jan 2005 20:42:15 -0000 1.13
+++ tools/dbus-send.c 3 Mar 2005 06:43:43 -0000
@@ -25,12 +25,12 @@
#include <dbus/dbus.h>
-#include "dbus-print-message.h"
+#include "dbus-prettyprint.h"
static void
usage (char *name, int ecode)
{
- fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", name);
+ fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--style=STYLE] [--print-reply] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", name);
exit (ecode);
}
@@ -50,7 +50,8 @@
const char *path = NULL;
int message_type = DBUS_MESSAGE_TYPE_SIGNAL;
const char *type_str = NULL;
-
+ DBusMessagePrintStyle style = DBUS_MESSAGE_PRINT_STYLE_C_DECLARATION;
+
if (argc < 3)
usage (argv[0], 1);
@@ -79,6 +80,8 @@
dest = strchr (arg, '=') + 1;
else if (strstr (arg, "--type=") == arg)
type_str = strchr (arg, '=') + 1;
+ else if (strstr (arg, "--style=") == arg)
+ style = dbus_message_prettyprint_str_to_style (strchr (arg, '=') + 1);
else if (!strcmp(arg, "--help"))
usage (argv[0], 0);
else if (arg[0] == '-')
@@ -262,6 +265,8 @@
}
}
+ dbus_message_prettyprint (connection, message, style);
+
if (print_reply)
{
DBusMessage *reply;
@@ -279,7 +284,8 @@
if (reply)
{
- print_message (reply);
+ printf("\n");
+ dbus_message_prettyprint (connection, reply, style);
dbus_message_unref (reply);
}
}
-------------- next part --------------
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-prettyprint.h Message argument pretty printer
*
* Copyright 2005 Daniel Reed <n at ml.org>
*
* Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef DBUS_PRETTYPRINT_H
#define DBUS_PRETTYPRINT_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <dbus/dbus.h>
typedef enum DBusMessagePrintStyle {
DBUS_MESSAGE_PRINT_STYLE_CLASSIC,
DBUS_MESSAGE_PRINT_STYLE_C_DECLARATION,
DBUS_MESSAGE_PRINT_STYLE_C_CALL,
DBUS_MESSAGE_PRINT_STYLE_CXX_CALL,
DBUS_MESSAGE_PRINT_STYLE_CIDL_CALL,
} DBusMessagePrintStyle;
dbus_bool_t dbus_message_iter_print (DBusMessageIter *iter, int tablen);
dbus_bool_t dbus_path_foreign_interface (char **pathar, const char *interface);
DBusMessagePrintStyle dbus_message_prettyprint_str_to_style (const char *str);
void dbus_message_prettyprint (DBusConnection *connection, DBusMessage *message, DBusMessagePrintStyle style);
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
#endif /* DBUS_PRETTYPRINT_H */
-------------- next part --------------
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-prettyprint.c Message argument pretty printer
*
* Copyright 2005 Daniel Reed <n at ml.org>
*
* Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "dbus-prettyprint.h"
#include "dbus-print-message.h"
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
static dbus_bool_t
_dbus_message_iter_print (DBusMessageIter * iter, int tablen)
{
int type;
int i;
type = dbus_message_iter_get_arg_type (iter);
if (type == DBUS_TYPE_INVALID)
return (FALSE);
for (i = 0; i < tablen; i++)
printf ("\t");
switch (type)
{
case DBUS_TYPE_ARRAY:
{
DBusMessageIter array_iter;
printf ("{\n");
dbus_message_iter_recurse (iter, &array_iter);
while (_dbus_message_iter_print (&array_iter, tablen+1))
printf (",\n");
printf("\n");
for (i = 0; i < tablen; i++)
printf("\t");
printf ("}");
break;
}
case DBUS_TYPE_BYTE:
{
unsigned char val;
dbus_message_iter_get_basic (iter, &val);
printf ("0x%02X", val);
break;
}
case DBUS_TYPE_BOOLEAN:
{
unsigned char val;
printf ("(bool)");
dbus_message_iter_get_basic (iter, &val);
printf ("%s", val ? "TRUE" : "FALSE");
break;
}
case DBUS_TYPE_INT32:
{
dbus_int32_t val;
printf ("(int32)");
dbus_message_iter_get_basic (iter, &val);
if (sizeof (val) <= sizeof (int))
printf ("%i", (int) val);
else if (sizeof (val) == sizeof (long int))
printf ("%li", (long int) val);
else if (sizeof (val) == sizeof (long long int))
printf ("%lli", (long long int) val);
break;
}
case DBUS_TYPE_UINT32:
{
dbus_uint32_t val;
printf ("(uint32)");
dbus_message_iter_get_basic (iter, &val);
if (sizeof (val) <= sizeof (unsigned int))
printf ("%u", (unsigned int) val);
else if (sizeof (val) == sizeof (unsigned long int))
printf ("%lu", (unsigned long int) val);
else if (sizeof (val) == sizeof (unsigned long long int))
printf ("%llu", (unsigned long long int) val);
break;
}
case DBUS_TYPE_INT64:
{
dbus_int64_t val;
printf ("(int64)");
dbus_message_iter_get_basic (iter, &val);
if (sizeof (val) <= sizeof (int))
printf ("%i", (int) val);
else if (sizeof (val) == sizeof (long int))
printf ("%li", (long int) val);
else if (sizeof (val) == sizeof (long long int))
printf ("%lli", (long long int) val);
break;
}
case DBUS_TYPE_UINT64:
{
dbus_uint64_t val;
printf ("(uint64)");
dbus_message_iter_get_basic (iter, &val);
if (sizeof (val) <= sizeof (unsigned int))
printf ("%u", (unsigned int) val);
else if (sizeof (val) == sizeof (unsigned long int))
printf ("%lu", (unsigned long int) val);
else if (sizeof (val) == sizeof (unsigned long long int))
printf ("%llu", (unsigned long long int) val);
break;
}
case DBUS_TYPE_DOUBLE:
{
double val;
printf ("(double)");
dbus_message_iter_get_basic (iter, &val);
printf ("%f", val);
break;
}
case DBUS_TYPE_STRING:
{
const char *val;
dbus_message_iter_get_basic (iter, &val);
printf ("\"%s\"", val);
break;
}
default:
if (isprint (type))
printf ("('%c')[unrepresentable]", type);
else
printf ("(%i)[unrepresentable]", type);
break;
}
if (!dbus_message_iter_next (iter))
return (FALSE);
return (TRUE);
}
dbus_bool_t
dbus_path_foreign_interface (char **pathar, const char *interface)
{
int i;
for (i = 0; pathar[i] != NULL; i++)
{
int len = strlen (pathar[i]);
if (strncmp (pathar[i], interface, len) != 0)
return (TRUE);
interface += len;
if (*interface == 0)
return (FALSE);
if (*interface != '.')
return (TRUE);
interface++;
}
if (*interface != 0)
return (TRUE);
return (FALSE);
}
static void
_dbus_message_prettyprint_classic (DBusConnection * connection, DBusMessage * message)
{
print_message (message);
}
static void
_dbus_message_prettyprint_cdecl (DBusConnection * connection, DBusMessage * message)
{
DBusMessageIter iter;
int type;
const char *base, *method, *error, *interface, *path, *destination, *sender,
*signature;
base = dbus_bus_get_unique_name (connection);
if (base == NULL)
base = "";
type = dbus_message_get_type (message);
method = dbus_message_get_member (message);
error = dbus_message_get_error_name (message);
interface = dbus_message_get_interface (message);
path = dbus_message_get_path (message);
destination = dbus_message_get_destination (message);
sender = dbus_message_get_sender (message);
signature = dbus_message_get_signature (message);
if ((method != NULL) && (interface != NULL) && (strcmp (method, "GetConnectionUnixUser") == 0) && (strcmp (interface, "org.freedesktop.DBus") == 0))
return;
printf ("message = {\n");
printf ("\ttype: %i /* %s */,\n", type,
dbus_message_type_to_string (type));
if (method != NULL)
printf ("\tmethod: \"%s\",\n", method);
if (error != NULL)
printf ("\terror: \"%s\",\n", error);
if (interface != NULL)
printf ("\ttarget interface: \"%s\",\n", interface);
if (destination != NULL)
printf ("\ttarget service: \"%s\"%s,\n", destination,
(strcmp (destination, base) == 0) ? " /* me */" : "");
if (path != NULL)
printf ("\tpath: \"%s\",\n", path);
if (sender != NULL)
{
unsigned long uid;
printf ("\tsender service: \"%s\"%s,\n", sender,
(strcmp (sender, base) == 0) ? " /* me */" : "");
uid = dbus_bus_get_unix_user (connection, sender, NULL);
if (uid != (unsigned long)-1)
printf ("\tsender uid: %lu,\n", uid);
}
if ((signature != NULL) && (*signature != 0))
{
printf ("\tsignature: %s,\n", signature);
printf ("\targs: {\n");
dbus_message_iter_init (message, &iter);
while (1)
{
if (_dbus_message_iter_print (&iter, 2)
&& (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID))
printf (",\n");
else
{
printf ("\n");
break;
}
}
printf ("\t}\n");
}
printf ("};\n");
}
static void
_dbus_message_prettyprint_ccall (DBusConnection * connection, DBusMessage * message)
{
DBusMessageIter iter;
const char *interface, *method;
char **pathar;
int i;
method = dbus_message_get_member (message);
interface = dbus_message_get_interface (message);
if ((method == NULL) || (interface == NULL)) {
_dbus_message_prettyprint_cdecl(connection, message);
return;
}
dbus_message_get_path_decomposed (message, &pathar);
for (i = 0; interface[i] != 0; i++)
if (interface[i] == '.')
printf ("_");
else
printf ("%c", interface[i]);
if (method != NULL)
printf ("_%s", method);
printf("(");
if (dbus_path_foreign_interface (pathar, interface))
{
printf ("%s", pathar[0]);
for (i = 1; pathar[i] != NULL; i++)
printf ("_%s", pathar[i]);
}
else
{
for (i = 0; pathar[i+1] != NULL; i++)
;
printf ("%s", pathar[i]);
}
dbus_message_iter_init (message, &iter);
while (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
{
printf (", ");
if (!_dbus_message_iter_print (&iter, 0))
break;
}
printf (")\n");
dbus_free_string_array (pathar);
}
static void
_dbus_message_prettyprint_cxxcall (DBusConnection * connection, DBusMessage * message)
{
DBusMessageIter iter;
const char *interface, *method;
char **pathar;
int i;
method = dbus_message_get_member (message);
interface = dbus_message_get_interface (message);
if ((method == NULL) || (interface == NULL)) {
_dbus_message_prettyprint_cdecl(connection, message);
return;
}
dbus_message_get_path_decomposed (message, &pathar);
printf ("%s", pathar[0]);
for (i = 1; pathar[i] != NULL; i++)
printf ("::%s", pathar[i]);
printf ("->");
if (dbus_path_foreign_interface (pathar, interface))
{
for (i = 0; interface[i] != 0; i++)
if (interface[i] == '.')
printf ("::");
else
printf ("%c", interface[i]);
printf ("::");
}
printf ("%s(", method);
dbus_message_iter_init (message, &iter);
while (_dbus_message_iter_print (&iter, 0))
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
printf (", ");
printf (")\n");
dbus_free_string_array (pathar);
}
static void
_dbus_message_prettyprint_cidl_call (DBusConnection * connection, DBusMessage * message)
{
DBusMessageIter iter;
const char *sender, *interface, *method, *path;
interface = dbus_message_get_interface (message);
method = dbus_message_get_member (message);
if ((method == NULL) || (interface == NULL)) {
_dbus_message_prettyprint_cdecl(connection, message);
return;
}
path = dbus_message_get_path (message);
sender = dbus_message_get_sender (message);
if (sender == NULL)
sender = "(me)";
printf ("%-25s", sender);
printf (" ");
printf ("%-25s", path);
printf (" ");
printf ("%25s", interface);
if (method != NULL)
printf (".%s", method);
printf (" (");
dbus_message_iter_init (message, &iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
_dbus_message_iter_print (&iter, 0);
while (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
{
printf (", ");
if (!_dbus_message_iter_print (&iter, 0))
break;
}
printf (")\n");
}
DBusMessagePrintStyle
dbus_message_prettyprint_str_to_style (const char *str)
{
if ((strcasecmp (str, "cdecl") == 0) || (strcasecmp (str, "c decl") == 0))
return (DBUS_MESSAGE_PRINT_STYLE_C_DECLARATION);
if ((strcasecmp (str, "ccall") == 0) || (strcasecmp (str, "c call") == 0))
return (DBUS_MESSAGE_PRINT_STYLE_C_CALL);
if ((strcasecmp (str, "cxxcall") == 0) || (strcasecmp (str, "cxx call") == 0))
return (DBUS_MESSAGE_PRINT_STYLE_CXX_CALL);
if ((strcasecmp (str, "cidlcall") == 0) || (strcasecmp (str, "cidl call") == 0))
return (DBUS_MESSAGE_PRINT_STYLE_CIDL_CALL);
return (DBUS_MESSAGE_PRINT_STYLE_CLASSIC);
}
void
dbus_message_prettyprint (DBusConnection * connection, DBusMessage * message, DBusMessagePrintStyle style)
{
switch (style) {
case DBUS_MESSAGE_PRINT_STYLE_CLASSIC:
_dbus_message_prettyprint_classic(connection, message);
break;
case DBUS_MESSAGE_PRINT_STYLE_C_DECLARATION:
_dbus_message_prettyprint_cdecl(connection, message);
break;
case DBUS_MESSAGE_PRINT_STYLE_C_CALL:
_dbus_message_prettyprint_ccall(connection, message);
break;
case DBUS_MESSAGE_PRINT_STYLE_CXX_CALL:
_dbus_message_prettyprint_cxxcall(connection, message);
break;
case DBUS_MESSAGE_PRINT_STYLE_CIDL_CALL:
_dbus_message_prettyprint_cidl_call(connection, message);
break;
}
}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
More information about the dbus
mailing list