diff options
| -rw-r--r-- | ChangeLog | 25 | ||||
| -rw-r--r-- | Makefile.am | 5 | ||||
| -rw-r--r-- | acinclude.m4 | 26 | ||||
| -rw-r--r-- | configure.in | 40 | ||||
| -rw-r--r-- | python/.cvsignore | 8 | ||||
| -rw-r--r-- | python/Makefile.am | 28 | ||||
| -rw-r--r-- | python/dbus.py | 196 | ||||
| -rw-r--r-- | python/dbus_bindings.pyx.in | 900 | ||||
| -rw-r--r-- | python/dbus_h_wrapper.h | 3 | ||||
| -rw-r--r-- | python/extract.py | 237 | ||||
| -rw-r--r-- | test/test-service.c | 5 | 
11 files changed, 1471 insertions, 2 deletions
| @@ -1,3 +1,28 @@ +2003-09-21  Seth Nickell  <seth@gnome.org> + +        First checkin of the Python bindings. +	 +	* python/.cvsignore: +	* python/Makefile.am: +	* python/dbus_bindings.pyx.in: +	* python/dbus_h_wrapper.h: + +	Pieces for Pyrex to operate on, building a dbus_bindings.so +	python module for low-level access to the DBus APIs. +	 +	* python/dbus.py: + +	High-level Python module for accessing DBus objects. + +	* configure.in: +	* Makefile.am: + +	Build stuff for the python bindings. + +	* acinclude.m4: + +	Extra macro needed for finding the Python C header files. +  2003-09-21  Havoc Pennington  <hp@pobox.com>  	* glib/dbus-gproxy.c (dbus_gproxy_manager_new): start diff --git a/Makefile.am b/Makefile.am index 5bb5ae6a..47329972 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,8 +16,11 @@ if DBUS_USE_MCS     MONO_SUBDIR=mono  endif +if HAVE_PYTHON +   PYTHON_SUBDIR=python +endif -SUBDIRS=dbus bus doc $(GLIB_SUBDIR) $(GCJ_SUBDIR) $(MONO_SUBDIR) $(QT_SUBDIR) test tools +SUBDIRS=dbus bus doc $(GLIB_SUBDIR) $(GCJ_SUBDIR) $(MONO_SUBDIR) $(QT_SUBDIR) $(PYTHON_SUBDIR) test tools  pkgconfigdir = $(libdir)/pkgconfig  pkgconfig_DATA = dbus-1.pc $(GLIB_PC) diff --git a/acinclude.m4 b/acinclude.m4 index c80e0acf..27da0a4c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -55,3 +55,29 @@ AC_DEFUN(PKG_CHECK_MODULES, [  ]) + +dnl a macro to check for ability to create python extensions +dnl  AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) +dnl function also defines PYTHON_INCLUDES +AC_DEFUN([AM_CHECK_PYTHON_HEADERS], +[AC_REQUIRE([AM_PATH_PYTHON]) +AC_MSG_CHECKING(for headers required to compile python extensions) +dnl deduce PYTHON_INCLUDES +py_prefix=`$PYTHON -c "import sys; print sys.prefix"` +py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` +PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" +if test "$py_prefix" != "$py_exec_prefix"; then +  PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" +fi +AC_SUBST(PYTHON_INCLUDES) +dnl check if the headers exist: +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" +AC_TRY_CPP([#include <Python.h>],dnl +[AC_MSG_RESULT(found) +$1],dnl +[AC_MSG_RESULT(not found) +$2]) +CPPFLAGS="$save_CPPFLAGS" +]) + diff --git a/configure.in b/configure.in index e81a8d6a..6cf4accb 100644 --- a/configure.in +++ b/configure.in @@ -35,6 +35,8 @@ AC_ARG_ENABLE(gcov,             [  --enable-gcov         compile with coverage p  AC_ARG_ENABLE(abstract-sockets, [  --enable-abstract-sockets  use abstract socket namespace (linux only)],enable_abstract_sockets=$enableval,enable_abstract_sockets=auto)  AC_ARG_ENABLE(gcj,              [  --enable-gcj          build gcj bindings],enable_gcj=$enableval,enable_gcj=no)  AC_ARG_ENABLE(mono,             [  --enable-mono         build mono bindings],enable_mono=$enableval,enable_mono=no) +AC_ARG_ENABLE(python,           [  --enable-python       build python bindings],enable_python=$enableval,enable_python=auto) +  AC_ARG_WITH(xml,                [  --with-xml=[libxml/expat]           XML library to use])  AC_ARG_WITH(init-scripts,       [  --with-init-scripts=[redhat]        Style of init scripts to install]) @@ -834,6 +836,42 @@ fi  AC_DEFINE_UNQUOTED(DBUS_SESSION_SOCKET_DIR, "$DBUS_SESSION_SOCKET_DIR", [Where per-session bus puts its sockets])  AC_SUBST(DBUS_SESSION_SOCKET_DIR) +# Detect if we can build Python bindings (need python, python headers, and pyrex) +if test x$enable_python = xno; then +    have_python=no +else +    AC_MSG_NOTICE([Checking to see if we can build Python bindings]) +    have_python=no +    AM_PATH_PYTHON(2.2) + +    if test -z "$PYTHON" ; then +        AC_MSG_WARN([Python not found]) +    else +        AC_CHECK_PROGS(PYREX, pyrexc) + +        if test -z "$PYREX" ; then +            have_pyrex=no +        else +            have_pyrex=yes +        fi + +        AM_CHECK_PYTHON_HEADERS(have_python_headers=yes,have_python_headers=no) + +	if test x$have_pyrex = xyes -a x$have_python_headers = xyes ; then +	    have_python=yes +        fi +    fi + +    if test x$have_python = xno ; then +        if test x$enable_python = xyes ; then +            AC_MSG_ERROR([Building python explicitly requested, but can't build python bindings]) +        else +            AC_MSG_WARN([Couldn't find either Pyrex or the Python headers, not building Python bindings]) +        fi +    fi                +fi + +AM_CONDITIONAL(HAVE_PYTHON, test x$have_python = xyes)  AC_OUTPUT([ @@ -846,6 +884,7 @@ bus/dbus-daemon-1.1  Makefile  dbus/Makefile  glib/Makefile +python/Makefile  qt/Makefile  gcj/Makefile  gcj/org/Makefile @@ -914,6 +953,7 @@ echo "          Building checks:          ${enable_checks}          Building Qt bindings:     ${have_qt}          Building GLib bindings:   ${have_glib} +        Building Python bindings: ${have_python}          Building GTK+ tools:      ${have_gtk}          Building X11 code:        ${enable_x11}          Building documentation:   ${enable_docs} diff --git a/python/.cvsignore b/python/.cvsignore new file mode 100644 index 00000000..8902bbe5 --- /dev/null +++ b/python/.cvsignore @@ -0,0 +1,8 @@ +*.pyc +*.pyo +Makefile +Makefile.in +build +*.la +*.lo +*.o
\ No newline at end of file diff --git a/python/Makefile.am b/python/Makefile.am new file mode 100644 index 00000000..792dc477 --- /dev/null +++ b/python/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES=-I$(top_builddir) -I$(top_builddir)/glib $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GLIB_TOOL_CFLAGS) $(PYTHON_INCLUDES) + +dbusdir = $(pythondir) +dbus_PYTHON = dbus.py + +dbusbindingsdir = $(pythondir) +dbusbindings_LTLIBRARIES = dbus_bindings.la + +dbus_bindings_la_LDFLAGS = -module -avoid-version -fPIC -export-symbols-regex initdbus_bindings +dbus_bindings_la_LIBADD = $(top_builddir)/dbus/libdbus-1.la $(top_builddir)/glib/libdbus-glib-1.la +dbus_bindings_la_SOURCES = dbus_bindings.c + +EXTRA_DIST = 			\ +	dbus_bindings.pyx.in	\ +	extract.py		\ +	setup.py		\ +	test.py + +CLEANFILES =			\ +	dbus_bindings.pyx	\ +	dbus_bindings.c + + +dbus_bindings.pyx: dbus_bindings.pyx.in extract.py +	-$(PYTHON) extract.py dbus_bindings.pyx.in -I$(top_builddir)  > dbus_bindings.pyx + +dbus_bindings.c: dbus_bindings.pyx +	-pyrexc dbus_bindings.pyx diff --git a/python/dbus.py b/python/dbus.py new file mode 100644 index 00000000..a7cca56a --- /dev/null +++ b/python/dbus.py @@ -0,0 +1,196 @@ + +"""Module for high-level communication over the FreeDesktop.org Bus (DBus) + +DBus allows you to share and access remote objects between processes +running on the desktop, and also to access system services (such as +the print spool). + +To use DBus, first get a Bus object, which provides a connection to one +of a few standard dbus-daemon instances that might be running. From the +Bus you can get a RemoteService. A service is provided by an application or +process connected to the Bus, and represents a set of objects. Once you +have a RemoteService you can get a RemoteObject that implements a specific interface +(an interface is just a standard group of member functions). Then you can call +those member functions directly. + +You can think of a complete method call as looking something like: + +Bus:SESSION -> Service:org.gnome.Evolution -> Object:/org/gnome/Evolution/Inbox -> Interface: org.gnome.Evolution.MailFolder -> Method: Forward('message1', 'seth@gnome.org') + +This communicates over the SESSION Bus to the org.gnome.Evolution process to call the +Forward method of the /org/gnome/Evolution/Inbox object (which provides the +org.gnome.Evolution.MailFolder interface) with two string arguments. + +For example, the dbus-daemon itself provides a service and some objects: + +# Get a connection to the desktop-wide SESSION bus +bus = dbus.Bus(dbus.Bus.TYPE_SESSION) + +# Get the service provided by the dbus-daemon named org.freedesktop.DBus +dbus_service = bus.get_service('org.freedesktop.DBus') + +# Get a reference to the desktop bus' standard object, denoted +# by the path /org/freedesktop/DBus. The object /org/freedesktop/DBus +# implements the 'org.freedesktop.DBus' interface +dbus_object = dbus_service.get_object('/org/freedesktop/DBus', +                                       'org.freedesktop.DBus') + +# One of the member functions in the org.freedesktop.DBus interface +# is ListServices(), which provides a list of all the other services +# registered on this bus. Call it, and print the list. +print(dbus_object.ListServices()) +""" + +import dbus_bindings + +class Bus: +    """A connection to a DBus daemon. + +    One of three possible standard buses, the SESSION, SYSTEM, +    or ACTIVATION bus +    """ +    TYPE_SESSION    = dbus_bindings.BUS_SESSION +    TYPE_SYSTEM     = dbus_bindings.BUS_SYSTEM +    TYPE_ACTIVATION = dbus_bindings.BUS_ACTIVATION + +    def __init__(self, bus_type=TYPE_SESSION, glib_mainloop=True): +        self._connection = dbus_bindings.bus_get(bus_type) + +        if (glib_mainloop): +            self._connection.setup_with_g_main() + +    def get_service(self, service_name="org.freedesktop.Broadcast"): +        """Get one of the RemoteServices connected to this Bus. service_name +        is just a string of the form 'com.widgetcorp.MyService' +        """ +        return RemoteService(self._connection, service_name) + +    def get_connection(self): +        """Get the dbus_bindings.Connection object associated with this Bus""" +        return self._connection + + +class RemoteObject: +    """A remote Object. + +    A RemoteObject is provided by a RemoteService on a particular Bus. RemoteObjects +    have member functions, and can be called like normal Python objects. +    """ +    def __init__(self, connection, service_name, object_path, interface): +        self._connection   = connection +        self._service_name = service_name +        self._object_path  = object_path +        self._interface    = interface + +    def __getattr__(self, member): +        if member == '__call__': +            return object.__call__ +        else: +            return RemoteMethod(self._connection, self._service_name, +                                self._object_path, self._interface, member) + + +class RemoteMethod: +    """A remote Method. + +    Typically a member of a RemoteObject. Calls to the +    method produce messages that travel over the Bus and are routed +    to a specific Service. +    """ +    def __init__(self, connection, service_name, object_path, interface, method_name): +        self._connection   = connection +        self._service_name = service_name +        self._object_path  = object_path +        self._interface    = interface +        self._method_name  = method_name + +    def __call__(self, *args): +        print ("Going to call object(%s).interface(%s).method(%s)" +               % (self._object_path, self._interface, self._method_name)) + +        message = dbus_bindings.MethodCall(self._object_path, self._interface, self._method_name) +        message.set_destination(self._service_name) +         +        # Add the arguments to the function +        iter = message.get_iter() +        for arg in args: +            print ("Adding arg %s" % (arg)) +            print ("Append success is %d" % (iter.append(arg))) +            print ("Args now %s" % (message.get_args_list()))             + +        reply_message = self._connection.send_with_reply_and_block(message, 5000) + +        args_tuple = reply_message.get_args_list() +        if (len(args_tuple) == 0): +            return +        elif (len(args_tuple) == 1): +            return args_tuple[0] +        else: +            return args_tuple + +class Service: +    """A base class for exporting your own Services across the Bus + +    Just inherit from Service, providing the name of your service +    (e.g. org.designfu.SampleService). +    """ +    def __init__(self, service_name, bus=None): +        self._service_name = service_name +                              +        if bus == None: +            # Get the default bus +            self._bus = Bus() +        else: +            self._bus = bus + +        dbus_bindings.bus_acquire_service(self._bus.get_connection(), service_name) + +    def get_bus(self): +        """Get the Bus this Service is on""" +        return self._bus + +class Object: +    """A base class for exporting your own Objects across the Bus. + +    Just inherit from Object and provide a list of methods to share +    across the Bus. These will appear as member functions of your +    ServiceObject. +    """ +    def __init__(self, object_path, methods_to_share, service): +        self._object_path = object_path +        self._service = service +        self._object_methods = methods_to_share +        self._bus = service.get_bus() +        self._connection = self._bus.get_connection() +         +        self._connection.register_object_path(object_path, self._unregister_cb, self._message_cb) + +    def _unregister_cb(self, connection): +        print ("Unregister") +         +    def message_cb(self, connection, message): +        print ("Message %s received" % (message)) +        print ("MethodCall %s" % (message.get_member())) +         +class RemoteService: +    """A remote service providing objects. + +    A service is typically a process or application that provides +    remote objects, but can also be the broadcast service that +    receives signals from all applications on the Bus. +    """ +     +    def __init__(self, connection, service_name): +        self._connection     = connection +        self._service_name   = service_name + +    def get_object(self, object_path, interface): +        """Get an object provided by this Service that implements a +        particular interface. object_path is a string of the form +        '/com/widgetcorp/MyService/MyObject1'. interface looks a lot +        like a service_name (they're often the same) and is of the form, +        'com.widgetcorp.MyInterface', and mostly just defines the +        set of member functions that will be present in the object. +        """ +        return RemoteObject(self._connection, self._service_name, object_path, interface) +                              diff --git a/python/dbus_bindings.pyx.in b/python/dbus_bindings.pyx.in new file mode 100644 index 00000000..2e575edc --- /dev/null +++ b/python/dbus_bindings.pyx.in @@ -0,0 +1,900 @@ +# -*- Mode: Python -*- + +#include "dbus_h_wrapper.h" + +cdef extern from "stdlib.h": +    cdef void *malloc(size_t size) +    cdef void free(void *ptr) + +cdef extern from "dbus-glib.h": +    ctypedef struct GMainContext +    cdef void dbus_connection_setup_with_g_main (DBusConnection *connection, +                                                 GMainContext   *context) +    cdef void dbus_server_setup_with_g_main     (DBusServer     *server, +                                                 GMainContext   *context) + +cdef extern from "Python.h": +    void Py_XINCREF (object) +    void Py_XDECREF (object) + + +ctypedef struct DBusError: +    char *name +    char *message +    unsigned int dummy1  +    unsigned int dummy2 +    unsigned int dummy3 +    unsigned int dummy4 +    unsigned int dummy5 +    void *padding1 +     +ctypedef struct DBusMessageIter: +    void *dummy1 +    void *dummy2 +    dbus_uint32_t dummy3 +    int dummy4 +    int dummy5 +    int dummy6 +    int dummy7 +    int dummy8 +    int dummy9 +    int dummy10 +    int dummy11 +    int pad1 +    int pad2 +    void *pad3 + +ctypedef struct DBusObjectPathVTable: +  DBusObjectPathUnregisterFunction   unregister_function +  DBusObjectPathMessageFunction      message_function +  void (* dbus_internal_pad1) (void *) +  void (* dbus_internal_pad2) (void *) +  void (* dbus_internal_pad3) (void *) +  void (* dbus_internal_pad4) (void *) + + +class DBusException(Exception): +    pass + +class ConnectionError(Exception): +    pass + +cdef void cunregister_function_handler (DBusConnection *connection, +                                        void *user_data): +    print ("cunregister_function_handler() called") +    tup = <object>user_data +    function = tup[0] +    args = [Connection(_conn=<object>connection)] +    function(*args) + +cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection, +                                                  DBusMessage *msg, +                                                  void *user_data): +    print ("cmessage_function_handler() called") +    tup = <object>user_data +    print (tup) +    function = tup[1] +    message = Message(_create=0) +    message._set_msg(<object>msg) +    args = [Connection(_conn=<object>connection), +            message] +    retval = function(*args) +    if (retval == None): +        retval = DBUS_HANDLER_RESULT_HANDLED +    return retval + +cdef DBusHandlerResult chandle_message_function_handler (DBusConnection *connection, +                                                        DBusMessage *msg, +                                                        void *user_data): +    function = <object>user_data +    messagein = Message(_create=0) +    messagein._set_msg(<object>msg) +    args = [Connection(_conn=<object>connection), +            messagein] +    retval = function(*args) +    if (retval == None): +        retval = DBUS_HANDLER_RESULT_HANDLED +    return retval     + +cdef class Connection: +    cdef DBusConnection *conn +     +    # FIXME: this is a major major hack. We use this because casting values to +    # python objects and returning seemed to be corrupting them. This is a "global variable" :-( +    cdef char **_parsed_path +     +    def __init__(self, address=None, _conn=None): +        cdef DBusError error +        dbus_error_init(&error) +        if <DBusConnection*>_conn != NULL: +            self.conn = <DBusConnection*>_conn +            dbus_connection_ref(self.conn) +        else: +            self.conn = dbus_connection_open(address, +                                             &error) +            if dbus_error_is_set(&error): +                raise DBusException, error.message +             +        dbus_connection_ref(self.conn) + +    def _set_conn(self, conn): +        self.conn = <DBusConnection*>conn +         +    def _get_conn(self): +        return <object>self.conn +     +    #FIXME: this is totally busted, don't use a class shared member like parsed_path +    def _build_parsed_path(self, path_element_list): +        cdef char **cpatharray         +        size = len(path_element_list) +        cpatharray = <char **>malloc(sizeof(char*) * (size + 1)) + +        for i in range(size): +            path_element = path_element_list[i] +            cpatharray[i] = path_element +             +        cpatharray[size] = NULL + +        self._parsed_path = cpatharray + +    def get_base_service(self): +        return bus_get_base_service(self) + +    def setup_with_g_main(self): +        dbus_connection_setup_with_g_main(self.conn, NULL) + +    def disconnect(self): +        dbus_connection_disconnect(self.conn) + +    def get_is_connected(self): +        return dbus_connection_get_is_connected(self.conn) +     +    def get_is_authenticated(self): +        return dbus_connection_get_is_authenticated(self.conn) + +    def flush(self): +        dbus_connection_flush(self.conn) + +    def borrow_message(self): +        m = Message(_create=0) +        m._set_msg(<object>dbus_connection_borrow_message(self.conn)) +        return m +     +    def return_message(self, message): +        msg = message._get_msg() +        dbus_connection_return_message(self.conn, <DBusMessage*>msg) + +    def steal_borrowed_message(self, message): +        msg = message._get_msg() +        dbus_connection_steal_borrowed_message(self.conn, +                                               <DBusMessage*>msg) +     +    def pop_message(self): +        cdef DBusMessage *msg +        msg = dbus_connection_pop_message(self.conn) +        if msg != NULL: +            m = Message(_create=0) +            m._set_msg(<object>msg) +        else: +            m = None +        return m         + +    def get_dispatch_status(self): +        return dbus_connection_get_dispatch_status(self.conn) +     +    def dispatch(self): +        return dbus_connection_dispatch(self.conn) + +    def send(self, message): +        #cdef dbus_uint32_t client_serial +        #if type(message) != Message: +        #    raise TypeError +         +        msg = message._get_msg() +        retval = dbus_connection_send(self.conn, +                                      <DBusMessage*>msg, +                                      NULL) +        return retval + +    def send_with_reply(self, message, timeout_milliseconds): +        cdef dbus_bool_t retval +        cdef DBusPendingCall *cpending_call +        cdef DBusError error +        dbus_error_init(&error) + +        cpending_call = NULL +         +        msg = message._get_msg() + +        retval = dbus_connection_send_with_reply(self.conn, +                                                 <DBusMessage*>msg, +                                                 &cpending_call, +                                                 timeout_milliseconds) + +        if dbus_error_is_set(&error): +            raise DBusException, error.message + +        if (cpending_call != NULL): +            pending_call = PendingCall(<object>cpending_call) +        else: +            pending_call = None + +        return (retval, pending_call) +                                 +    def send_with_reply_and_block(self, message, +                                  timeout_milliseconds=0): +        cdef DBusMessage * retval +        cdef DBusError error +        dbus_error_init(&error) + +        msg = message._get_msg() + +        print ("About to block") + +        retval = dbus_connection_send_with_reply_and_block( +            <DBusConnection*>self.conn, +            <DBusMessage*>msg, +            <int>timeout_milliseconds, +            &error) + +        print ("done") + +        if dbus_error_is_set(&error): +            raise DBusException, error.message + +        if retval == NULL: +            raise AssertionError +         +        m = Message(_create=0) +        m._set_msg(<object>retval) +        return m + +    def set_watch_functions(self, add_function, remove_function, data): +        pass + +    def set_timeout_functions(self, add_function, remove_function, data): +        pass + +    def set_wakeup_main_function(self, wakeup_main_function, data): +        pass + +    # FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function + +    def add_filter(self, function): +        return dbus_connection_add_filter(self.conn, +                                          chandle_message_function_handler, +                                          <void*>function, +                                          NULL) + + +    #FIXME: remove_filter +    #       this is pretty tricky, we want to only remove the filter +    #       if we truly have no more calls to our message_function_handler...ugh + +    def set_data(self, slot, data): +        pass + +    def get_data(self, slot): +        pass + +    def set_max_message_size(self, size): +        dbus_connection_set_max_message_size(self.conn, size) + +    def get_max_message_size(self): +        return dbus_connection_get_max_message_size(self.conn) + +    def set_max_received_size(self, size): +        dbus_connection_set_max_received_size(self.conn, size) + +    def get_max_received_size(self): +        return dbus_connection_get_max_received_size(self.conn) + +    def get_outgoing_size(self): +        return dbus_connection_get_outgoing_size(self.conn)     + +    # preallocate_send, free_preallocated_send, send_preallocated + +    def register_object_path(self, path, unregister_cb, message_cb): +        cdef DBusObjectPathVTable cvtable +         +        cvtable.unregister_function = cunregister_function_handler  +        cvtable.message_function    = cmessage_function_handler + +        user_data = [unregister_cb, message_cb] +        #Py_XINCREF(user_data) +         +        path_element_list = path[1:].split('/') +        self._build_parsed_path(path_element_list) +         +        return dbus_connection_register_object_path(self.conn, self._parsed_path, &cvtable, +                                                    <void*>user_data)  + +    def register_fallback(self, path, unregister_cb, message_cb): +        cdef DBusObjectPathVTable cvtable + +        cvtable.unregister_function = cunregister_function_handler  +        cvtable.message_function    = cmessage_function_handler + +        user_data = [unregister_cb, message_cb] +        Py_XINCREF(user_data) + +        print ("Ref inced") +         +        path_element_list = path[1:].split('/') +        self._build_parsed_path(path_element_list) +         +        return dbus_connection_register_fallback(self.conn, self._parsed_path, &cvtable, +                                                 <void*>user_data)  + +    #FIXME: unregister_object_path , see problems with remove_filter + +    def list_registered (self, parent_path): +        cdef char **cchild_entries +        cdef dbus_bool_t retval +         +        path_element_list = parent_path[1:].split('/') +        self._build_parsed_path(path_element_list) +         +        retval = dbus_connection_list_registered(self.conn, self._parsed_path, &cchild_entries) + +        if (not retval): +            #FIXME: raise out of memory exception? +            return None + +        i = 0 +        child_entries = [] +        print ("cchild_entries[0] is %d" % (<int>cchild_entries[0])) +        while (cchild_entries[i] != NULL): +            child_entries.append(cchild_entries[i]) +            i = i + 1 + +        dbus_free_string_array(cchild_entries) + +        return child_entries + +     +cdef class PendingCall: +    cdef DBusPendingCall *pending_call + +    def __init__(self, _pending_call): +        self.pending_call = <DBusPendingCall*>_pending_call +        dbus_pending_call_ref(self.pending_call) +         +    def _get_pending_call(self): +        return <object>self.pending_call + +    def cancel(self): +        dbus_pending_call_cancel(self.pending_call) + +    def get_completed(self): +        return dbus_pending_call_get_completed(self.pending_call) + +    def get_reply(self): +        message = Message(_create=0) +        message._set_msg(<object>dbus_pending_call_get_reply(self.pending_call)) +        return message + +    def block(self): +        dbus_pending_call_block(self.pending_call) + +cdef class Watch: +    cdef DBusWatch* watch +    def __init__(self, cwatch): +        self.watch = <DBusWatch*>cwatch + +    def get_fd(self): +        return dbus_watch_get_fd(self.watch) + +    # FIXME: not picked up correctly by extract.py +    #def get_flags(self): +    #    return dbus_watch_get_flags(self.watch) + +    def handle(self, flags): +        return dbus_watch_handle(self.watch, flags) + +    def get_enabled(self): +        return dbus_watch_get_enabled(self.watch) +     +cdef class MessageIter: +    cdef DBusMessageIter *iter +    cdef DBusMessageIter real_iter + + +    def __init__(self, message): +        self.iter = &self.real_iter +        msg = message._get_msg() +        dbus_message_iter_init(<DBusMessage*>msg, self.iter) +     +    def get_iter(self): +        return <object>self.iter + +    def has_next(self): +        return dbus_message_iter_has_next(self.iter) +     +    def next(self): +        return dbus_message_iter_next(self.iter) + +    def get(self): +        arg_type = self.get_arg_type() + +        if arg_type == TYPE_INVALID: +            raise TypeError, 'Invalid arg type in MessageIter' +        elif arg_type == TYPE_STRING: +            retval = self.get_string() +        elif arg_type == TYPE_INT32: +            retval = self.get_int32() +        elif arg_type == TYPE_UINT32: +            retval = self.get_uint32() +        elif arg_type == TYPE_DOUBLE: +            retval = self.get_double() +        elif arg_type == TYPE_BYTE: +            retval = self.get_byte() +        elif arg_type == TYPE_BOOLEAN: +            retval = self.get_boolean() +        elif arg_type == TYPE_ARRAY: +            array_type = self.get_array_type() + +            if array_type == TYPE_STRING: +                retval = self.get_string_array() +            elif array_type == TYPE_BOOLEAN: +                retval = self.get_boolean_array() +            else: +                raise TypeError, "Unknown array type %d in MessageIter" % (array_type) +        else: +            raise TypeError, 'Unknown arg type %d in MessageIter' % (argtype) + +        return retval +     +    def get_arg_type(self): +        return dbus_message_iter_get_arg_type(self.iter) + +    def get_array_type(self): +        return dbus_message_iter_get_array_type(self.iter) + +    #FIXME: implement get_byte +    #def get_byte(self): +    #    return dbus_message_iter_get_byte(self.iter) + +    def get_boolean(self): +        return dbus_message_iter_get_boolean(self.iter) +     +    def get_int32(self): +        return dbus_message_iter_get_int32(self.iter) + +    def get_uint32(self): +        return dbus_message_iter_get_uint32(self.iter) + +    def get_double(self): +        return dbus_message_iter_get_double(self.iter) + +    def get_string(self): +        return dbus_message_iter_get_string(self.iter) + +    def get_dict_key(self): +        return dbus_message_iter_get_dict_key(self.iter) + +    # FIXME: implement dbus_message_iter_get_named +    #                  dbus_message_iter_init_array_iterator +     +    def get_byte_array(self): +        cdef int len +        cdef unsigned char *retval +        dbus_message_iter_get_byte_array(self.iter, &retval, <int*>&len) +        list = [] +        for i from 0 <= i < len: +            list.append(chr(retval[i])) +        return list + +    # FIXME: implement dbus_message_iter_get_boolean_array +    #                  dbus_message_iter_get_int32_array +    #                  dbus_message_iter_get_uint32_array +    #                  dbus_message_iter_get_double_array + +    def get_string_array(self): +        cdef int len +        cdef char **retval +         +        dbus_message_iter_get_string_array(self.iter, &retval, <int*>&len) +        list = [] +        for i from 0 <= i < len: +            list.append(retval[i]) +        return list + +    # dbus_message_append_iter_init included in class Message + +    #FIXME: handle all the different types? +    def append(self, value): +        value_type = type(value) + +        if value_type == bool: +            retval = self.append_boolean(value) +        elif value_type == int: +            retval = self.append_int32(value) +        elif value_type == float: +            retval = self.append_double(value) +        elif value_type == str: +            retval = self.append_string(value) +        elif value_type == list: +            if (len(list) == 1): +                raise TypeError, "Empty list" +            list_type = type(list[0]) +            if list_type == str: +                self.append_string_array(list) +            else: +                raise TypeError, "List of unknown type '%s'" % (list_type) +        else: +            raise TypeError, "Argument of unknown type '%s'" % (value_type) + +        return retval + +    def append_nil(self): +        return dbus_message_iter_append_nil(self.iter) +     +    def append_boolean(self, value): +        return dbus_message_iter_append_boolean(self.iter, value) + +    def append_byte(self, value): +        return dbus_message_iter_append_byte(self.iter, value) +     +    def append_int32(self, value): +        return dbus_message_iter_append_int32(self.iter, value) + +    def append_uint32(self, value): +        return dbus_message_iter_append_uint32(self.iter, value) + +    def append_double(self, value): +        return dbus_message_iter_append_double(self.iter, value) + +    def append_string(self, value): +        return dbus_message_iter_append_string(self.iter, value)     + +    # FIXME: dbus_message_iter_append_named + +    def append_dict_key(self, value): +        return dbus_message_iter_append_dict_key(self.iter, value) + +    # FIXME: append_array, append_dict_array, append_boolean_array, append_int32_array, append_uint32_array, append_double_array + +    def append_byte_array(self, list): +        cdef unsigned char * value +        cdef int length +        length = len(list) +        value = <unsigned char*>malloc(length) +        for i from 0 <= i < length: +            item = list[i] +            if type(item) != str or len(item) != 1: +                raise TypeError +            value[i] = ord(item) +        return dbus_message_iter_append_byte_array(self.iter, value, length) +     +    def append_string_array(self, list): +        cdef char **value +        cdef int length +        length = len(list) +        value = <char**>malloc(length) +        for i from 0 <= i < length: +            item = list[i] +            if type(item) != str: +                raise TypeError +            value[i] = item +        return dbus_message_iter_append_string_array(self.iter, value, length) + +     +(MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5) +(TYPE_INVALID, TYPE_NIL, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_NAMED, TYPE_ARRAY, TYPE_DICT, TYPE_OBJECT_PATH) = range(14) +     +cdef class Message: +    cdef DBusMessage *msg + +    def __init__(self, message_type=MESSAGE_TYPE_INVALID, service=None, path=None, interface=None, +                 method=None, name=None, reply_to=None, error_name=None, error_message=None, +                 _create=1): +        cdef char *cservice +        if (service == None): +            cservice = NULL +        else: +            cservice = service +             +        if not _create: +            return 0 + +        if message_type == MESSAGE_TYPE_METHOD_CALL: +            self.msg = dbus_message_new_method_call(cservice, path, interface, method) +        elif message_type == MESSAGE_TYPE_METHOD_RETURN: +            msg = method_call._get_msg() +            self.msg = dbus_message_new_method_return(<DBusMessage*>msg) +        elif message_type == MESSAGE_TYPE_SIGNAL: +            self.msg = dbus_message_new_signal(path, interface, name) +        elif message_type == MESSAGE_TYPE_ERROR: +            msg = reply_to._get_msg() +            self.msg = dbus_message_new_error(<DBusMessage*>msg, error_name, error_message) +             +    def type_to_name(self, type): +        if type == MESSAGE_TYPE_SIGNAL: +            return "signal" +        elif type == MESSAGE_TYPE_METHOD_CALL: +            return "method call" +        elif type == MESSAGE_TYPE_METHOD_RETURN: +            return "method return" +        elif type == MESSAGE_TYPE_ERROR: +            return "error" +        else: +            return "(unknown message type)" +         +    def __str__(self): +        message_type = self.get_type() +        sender = self.get_sender() + +        if sender == None: +            sender = "(no sender)" + +        if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL): +            retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type), +                                                                self.get_interface(), +                                                                self.get_member(), +                                                                sender) +        elif message_type == MESSAGE_TYPE_METHOD_RETURN: +            retval = '%s sender=%s' % (self.type_to_name(message_type), +                                        sender) +        elif message_type == MESSAGE_TYPE_ERROR: +            retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type), +                                                self.get_error_name(), +                                                sender) +        else: +            retval = "Message of unknown type %d" % (message_type) + + +        # FIXME: should really use self.convert_to_tuple() here +         +        iter = self.get_iter() +        value_at_iter = True +         +        while (value_at_iter): +            type = iter.get_arg_type() + +            if type == TYPE_INVALID: +                break +            elif type == TYPE_STRING: +                str = iter.get_string() +                arg = 'string:%s\n' % (str) +            elif type == TYPE_INT32: +                num = iter.get_int32() +                arg = 'int32:%d\n' % (num) +            elif type == TYPE_UINT32: +                num = iter.get_uint32() +                arg = 'uint32:%u\n' % (num) +            elif type == TYPE_DOUBLE: +                num = iter.get_double() +                arg = 'double:%f\n' % (num) +            elif type == TYPE_BYTE: +                num = iter.get_byte() +                arg = 'byte:%d\n' % (num) +            elif type == TYPE_BOOLEAN: +                bool = iter.get_boolean() +                if (bool): +                    str = "true" +                else: +                    str = "false" +                arg = 'boolean:%s\n' % (str) +            else: +                arg = '(unknown arg type %d)\n' % type + +            retval = retval + arg +            value_at_iter = iter.next() + +        return retval +     +    def _set_msg(self, msg): +        self.msg = <DBusMessage*>msg + +    def _get_msg(self): +        return <object>self.msg + +    def get_iter(self): +        return MessageIter(self) + +    def get_args_list(self): +        retval = [ ] + +        iter = self.get_iter() +        try: +            retval.append(iter.get()) +        except TypeError, e: +            return [ ] +             +        value_at_iter = iter.next() +        while (value_at_iter): +            retval.append(iter.get()) +            value_at_iter = iter.next()         + +        return retval +             +    # FIXME: implement dbus_message_copy? + +    def get_type(self): +        return dbus_message_get_type(self.msg) + +    def set_path(self, object_path): +        return dbus_message_set_path(self.msg, object_path) +     +    def get_path(self): +        return dbus_message_get_path(self.msg) +     +    def set_interface(self, interface): +        return dbus_message_set_interface(self.msg, interface) + +    def get_interface(self): +        return dbus_message_get_interface(self.msg)     + +    def set_member(self, member): +        return dbus_message_set_member(self.msg, member) + +    def get_member(self): +        return dbus_message_get_member(self.msg) + +    def set_error_name(self, name): +        return dbus_message_set_error_name(self.msg, name) + +    def get_error_name(self): +        return dbus_message_get_error_name(self.msg) + +    def set_destination(self, destination): +        return dbus_message_set_destination(self.msg, destination) + +    def get_destination(self): +        return dbus_message_get_destination(self.msg) + +    def set_sender(self, sender): +        return dbus_message_set_sender(self.msg, sender) +     +    def get_sender(self): +        cdef char *sender +        sender = dbus_message_get_sender(self.msg) +        if (sender == NULL): +            return None +        else: +            return sender + +    def set_no_reply(self, no_reply): +        dbus_message_set_no_reply(self.msg, no_reply) + +    def get_no_reply(self): +        return dbus_message_get_no_reply(self.msg) + +    def is_method_call(self, interface, method): +        return dbus_message_is_method_call(self.msg, interface, method) + +    def is_signal(self, interface, signal_name): +        return dbus_message_is_signal(self.msg, interface, signal_name) + +    def is_error(self, error_name): +        return dbus_message_is_error(self.msg, error_name) + +    def has_destination(self, service): +        return dbus_message_has_destination(self.msg, service) + +    def has_sender(self, service): +        return dbus_message_has_sender(self.msg, service) + +    def get_serial(self): +        return dbus_message_get_serial(self.msg) + +    def set_reply_serial(self, reply_serial): +        return dbus_message_set_reply_serial(self.msg, reply_serial) + +    def get_reply_serial(self): +        return dbus_message_get_reply_serial(self.msg)     + +    #FIXME: dbus_message_get_path_decomposed +     +    # FIXME: all the different dbus_message_*args* methods + +class Signal(Message): +    def __init__(self, spath, sinterface, sname): +        Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, interface=sinterface, name=sname) + +class MethodCall(Message): +    def __init__(self, mpath, minterface, mmethod): +        Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, interface=minterface, method=mmethod) + +cdef class Server: +    cdef DBusServer *server +    def __init__(self, address): +        cdef DBusError error +        dbus_error_init(&error) +        self.server = dbus_server_listen(address, +                                         &error) +        if dbus_error_is_set(&error): +            raise DBusException, error.message + +    def setup_with_g_main (self): +        dbus_server_setup_with_g_main(self.server, NULL) + +    def disconnect(self): +        dbus_server_disconnect(self.server) + +    def get_is_connected(self): +        return dbus_server_get_is_connected(self.server) + +#    def set_new_connection_function(self, function, data): +#        dbus_server_set_new_connection_function(self.conn, function, +#                                                data, NULL) +         +#    def set_watch_functions(self, add_function, remove_function, data): +#        dbus_server_set_watch_functions(self.server, +#                                        add_function, remove_function, +#                                        data, NULL) +         +#    def set_timeout_functions(self, add_function, remove_function, data): +#        dbus_server_set_timeout_functions(self.server, +#                                          add_function, remove_function, +#                                          data, NULL) +         +#    def handle_watch(self, watch, condition): +#        dbus_server_handle_watch(self.conn, watch, condition) + +BUS_SESSION = DBUS_BUS_SESSION +BUS_SYSTEM = DBUS_BUS_SYSTEM +BUS_ACTIVATION = DBUS_BUS_ACTIVATION + +def bus_get (bus_type): +    cdef DBusError error +    dbus_error_init(&error) +    cdef DBusConnection *connection + +    connection = dbus_bus_get(bus_type, +                              &error) + +    if dbus_error_is_set(&error): +        raise DBusException, error.message + +    return Connection(_conn=<object>connection) + +def bus_get_base_service(connection): +    conn = connection._get_conn() +    return dbus_bus_get_base_service(<DBusConnection*>conn) + +def bus_register(connection): +    cdef DBusError error +    dbus_error_init(&error) +    cdef dbus_bool_t retval + +    conn = connection._get_conn() +    retval = dbus_bus_register(<DBusConnection*>conn, +                               &error) +    if dbus_error_is_set(&error): +        raise DBusException, error.message + +    return retval + +SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1 +SERVICE_FLAG_REPLACE_EXISTING     = 0x2 + +def bus_acquire_service(connection, service_name, flags=0): +    cdef DBusError error +    dbus_error_init(&error) +    cdef int retval + +    conn = connection._get_conn() +    retval = dbus_bus_acquire_service(<DBusConnection*>conn, +                                      service_name, +                                      flags, +                                      &error) +    if dbus_error_is_set(&error): +        raise DBusException, error.message +    return retval +     +def bus_service_exists(connection, service_name): +    cdef DBusError error +    dbus_error_init(&error) +    cdef dbus_bool_t retval + +    conn = connection._get_conn() +    retval = dbus_bus_service_exists(<DBusConnection*>conn, +                                     service_name, +                                     &error) +    if dbus_error_is_set(&error): +        raise DBusException, error.message +    return retval + + diff --git a/python/dbus_h_wrapper.h b/python/dbus_h_wrapper.h new file mode 100644 index 00000000..2e218c8c --- /dev/null +++ b/python/dbus_h_wrapper.h @@ -0,0 +1,3 @@ +#define DBUS_API_SUBJECT_TO_CHANGE 1 +#include <dbus/dbus.h> + diff --git a/python/extract.py b/python/extract.py new file mode 100644 index 00000000..460af5ab --- /dev/null +++ b/python/extract.py @@ -0,0 +1,237 @@ +import commands +import glob +import re +import os +import string +import sys + +def clean_func(buf): +    buf = strip_comments(buf) +    pat = re.compile(r"""\\\n""", re.MULTILINE)  +    buf = pat.sub('',buf) +    pat = re.compile(r"""^[#].*?$""", re.MULTILINE)  +    buf = pat.sub('',buf) +    pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE)  +    buf = pat.sub('',buf) +    pat = re.compile(r"""\s+""", re.MULTILINE)  +    buf = pat.sub(' ',buf) +    pat = re.compile(r""";\s*""", re.MULTILINE)  +    buf = pat.sub('\n',buf) +    buf = buf.lstrip() +    #pat=re.compile(r'\s+([*|&]+)\s*(\w+)') +    pat = re.compile(r' \s+ ([*|&]+) \s* (\w+)',re.VERBOSE) +    buf = pat.sub(r'\1 \2', buf) +    pat = re.compile(r'\s+ (\w+) \[ \s* \]',re.VERBOSE) +    buf = pat.sub(r'[] \1', buf) +#    buf = string.replace(buf, 'G_CONST_RETURN ', 'const-') +    buf = string.replace(buf, 'const ', '') +    return buf + +def strip_comments(buf): +    parts = [] +    lastpos = 0 +    while 1: +        pos = string.find(buf, '/*', lastpos) +        if pos >= 0: +            parts.append(buf[lastpos:pos]) +            pos = string.find(buf, '*/', pos) +            if pos >= 0: +                lastpos = pos + 2 +            else: +                break +        else: +            parts.append(buf[lastpos:]) +            break +    return string.join(parts, '') + +def find_enums(buf): +    enums = []     +    buf = strip_comments(buf) +    buf = re.sub('\n', ' ', buf) +     +    enum_pat = re.compile(r'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)') +    splitter = re.compile(r'\s*,\s', re.MULTILINE) +    pos = 0 +    while pos < len(buf): +        m = enum_pat.search(buf, pos) +        if not m: break + +        name = m.group(2) +        vals = m.group(1) +        isflags = string.find(vals, '<<') >= 0 +        entries = [] +        for val in splitter.split(vals): +            if not string.strip(val): continue +            entries.append(string.split(val)[0]) +        enums.append((name, isflags, entries)) +         +        pos = m.end() +    return enums + +#typedef unsigned int   dbus_bool_t; +#typedef struct { +# +# } +#typedef struct FooStruct FooStruct; +# typedef void (* DBusAddWatchFunction)      (DBusWatch      *watch, +#					    void           *data); + +def find_typedefs(buf): +    typedefs = [] +    buf = re.sub('\n', ' ', strip_comments(buf)) +    typedef_pat = re.compile( +        r"""typedef\s*(?P<type>\w*) +            \s* +            ([(]\s*\*\s*(?P<callback>[\w* ]*)[)]|{([^}]*)}|) +            \s* +            (?P<args1>[(](?P<args2>[\s\w*,_]*)[)]|[\w ]*)""", +        re.MULTILINE | re.VERBOSE) +    pat = re.compile(r"""\s+""", re.MULTILINE)  +    pos = 0 +    while pos < len(buf): +        m = typedef_pat.search(buf, pos) +        if not m: +            break +        if m.group('type') == 'enum': +            pos = m.end() +            continue +        if m.group('args2') != None: +            args = pat.sub(' ', m.group('args2')) +             +            current = '%s (* %s) (%s)' % (m.group('type'), +                                          m.group('callback'), +                                          args) +        else: +            current = '%s %s' % (m.group('type'), m.group('args1')) +        typedefs.append(current) +        pos = m.end() +    return typedefs + +proto_pat = re.compile(r""" +(?P<ret>(-|\w|\&|\*)+\s*)      # return type +\s+                            # skip whitespace +(?P<func>\w+)\s*[(]  # match the function name until the opening ( +(?P<args>.*?)[)]               # group the function arguments +""", re.IGNORECASE|re.VERBOSE) +arg_split_pat = re.compile("\s*,\s*") + + +def find_functions(buf): +    functions = [] +    buf = clean_func(buf) +    buf = string.split(buf,'\n') +    for p in buf: +        if len(p) == 0: +            continue +         +        m = proto_pat.match(p) +        if m == None: +            continue +         +        func = m.group('func') +        ret = m.group('ret') +        args = m.group('args') +        args = arg_split_pat.split(args) +#        for i in range(len(args)): +#            spaces = string.count(args[i], ' ') +#            if spaces > 1: +#                args[i] = string.replace(args[i], ' ', '-', spaces - 1) + +        functions.append((func, ret, args)) +    return functions + +class Writer: +    def __init__(self, filename, enums, typedefs, functions): +        if not (enums or typedefs or functions): +            return +        print 'cdef extern from "%s":' % filename + +        self.output_enums(enums) +        self.output_typedefs(typedefs) +        self.output_functions(functions)         +         +        print '    pass' +        print +         +    def output_enums(self, enums): +        for enum in enums: +            print '    ctypedef enum %s:' % enum[0] +            if enum[1] == 0: +                for item in enum[2]: +                    print '        %s' % item +            else: +                i = 0 +                for item in enum[2]: +                    print '        %s' % item                     +#                    print '        %s = 1 << %d' % (item, i) +                    i += 1 +            print +    def output_typedefs(self, typedefs): +        for typedef in typedefs: +            if typedef.find('va_list') != -1: +                continue +             +            parts = typedef.split() +            if parts[0] == 'struct': +                if parts[-2] == parts[-1]: +                    parts = parts[:-1] +                print '    ctypedef %s' % ' '.join(parts) +            else: +                print '    ctypedef %s' % typedef + +    def output_functions(self, functions): +        for func, ret, args in functions: +            if func[0] == '_': +                continue + +            str = ', '.join(args) +            if str.find('...') != -1: +                continue +            if str.find('va_list') != -1: +                continue +            if str.strip() == 'void': +                continue +            print '    %-20s %s (%s)' % (ret, func, str) + +def do_buffer(name, buffer): +    functions = find_functions(buffer) +    typedefs = find_typedefs(buffer) +    enums = find_enums(buffer) + +    Writer(name, enums, typedefs, functions) +     +def do_header(filename, name=None): +    if name == None: +        name = filename +         +    buffer = "" +    for line in open(filename).readlines(): +        if line[0] == '#': +            continue +        buffer += line + +    print '# -- %s -- ' % filename +    do_buffer(name, buffer) +     +filename = sys.argv[1] + +if filename.endswith('.h'): +    do_header(filename) +    raise SystemExit + +cppflags = "" + +for flag in sys.argv[2:]: +    cppflags = cppflags + " " + flag + +fd = open(filename) + +for line in fd.readlines(): +    if line.startswith('#include'): +        filename = line.split(' ')[1][1:-2] +        command = "echo '%s'|cpp %s" % (line, cppflags) +        sys.stderr.write('running %s' % (command)) +        output = commands.getoutput(command) +        do_buffer(filename, output) +    else: +        print line[:-1] diff --git a/test/test-service.c b/test/test-service.c index f22b1753..d07575e2 100644 --- a/test/test-service.c +++ b/test/test-service.c @@ -106,7 +106,7 @@ main (int    argc,    int result;    dbus_error_init (&error); -  connection = dbus_bus_get (DBUS_BUS_ACTIVATION, &error); +  connection = dbus_bus_get (DBUS_BUS_SESSION, &error);    if (connection == NULL)      {        _dbus_verbose ("*** Failed to open connection to activating message bus: %s\n", @@ -126,10 +126,13 @@ main (int    argc,                                     filter_func, NULL, NULL))      die ("No memory"); +  printf ("Acquiring service\n"); +    result = dbus_bus_acquire_service (connection, "org.freedesktop.DBus.TestSuiteEchoService",                                       0, &error);    if (dbus_error_is_set (&error))      { +      printf ("Error %s", error.message);        _dbus_verbose ("*** Failed to acquire service: %s\n",                       error.message);        dbus_error_free (&error); | 
