Stephen Warren wrote:
> Attached is an updated version
Attached is another (final) updated version that removes a debug print I
was using. Sigh.
? concordance/.deps
? concordance/.libs
? concordance/Makefile
? concordance/Makefile.in
? concordance/aclocal.m4
? concordance/autom4te.cache
? concordance/concordance
? concordance/config.guess
? concordance/config.h
? concordance/config.h.in
? concordance/config.log
? concordance/config.status
? concordance/config.sub
? concordance/configure
? concordance/depcomp
? concordance/install-sh
? concordance/libtool
? concordance/ltmain.sh
? concordance/missing
? concordance/stamp-h1
? libconcord/.deps
? libconcord/.libconcord.cpp.swp
? libconcord/.libs
? libconcord/.remote.h.swp
? libconcord/Makefile
? libconcord/Makefile.in
? libconcord/aclocal.m4
? libconcord/autom4te.cache
? libconcord/binaryfile.lo
? libconcord/config.guess
? libconcord/config.h
? libconcord/config.h.in
? libconcord/config.log
? libconcord/config.status
? libconcord/config.sub
? libconcord/configure
? libconcord/depcomp
? libconcord/install-sh
? libconcord/libconcord.la
? libconcord/libconcord.lo
? libconcord/libtool
? libconcord/libusbhid.lo
? libconcord/ltmain.sh
? libconcord/missing
? libconcord/remote.lo
? libconcord/remote_z.lo
? libconcord/stamp-h1
? libconcord/usblan.lo
? libconcord/web.lo
? libconcord/bindings/python/.README.swp
? libconcord/bindings/python/.libconcord.py.swp
? libconcord/bindings/python/build
? libconcord/bindings/python/libconcord.pyc
Index: libconcord/bindings/python/README
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/bindings/python/README,v
retrieving revision 1.1
diff -u -p -r1.1 README
--- libconcord/bindings/python/README 15 Apr 2008 02:34:08 -0000 1.1
+++ libconcord/bindings/python/README 28 Jun 2008 05:55:29 -0000
@@ -32,3 +32,14 @@ the bindings to your PYTHONPATH. For exa
export PYTHONPATH=/path/to/libconcord/bindings/python
+Debugging
+====================
+
+If you set the environment variable LIBCONCORD_PY_TRACE to string "1", then
+libconcord.py will trace all function calls. This may prove helpful when
+debugging client applications.
+
+For example, in bash:
+
+LIBCONCORD_PY_TRACE=1 ./congruity /path/to/Connectivity.EZHex
+
Index: libconcord/bindings/python/libconcord.py
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/bindings/python/libconcord.py,v
retrieving revision 1.1
diff -u -p -r1.1 libconcord.py
--- libconcord/bindings/python/libconcord.py 8 Apr 2008 09:50:29 -0000 1.1
+++ libconcord/bindings/python/libconcord.py 28 Jun 2008 05:55:29 -0000
@@ -1,5 +1,5 @@
#
-# vi: formatoptions+=tc textwidth=80 tabstop=8 shiftwidth=8 noexpandtab:
+# vi: formatoptions+=tc textwidth=80 tabstop=8 shiftwidth=4 expandtab:
#
# $Id: libconcord.py,v 1.1 2008/04/08 09:50:29 jaymzh Exp $
#
@@ -18,19 +18,37 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
-
from ctypes import *
import platform
+import os
import sys
+import traceback
+
+# Debug request parsing
+
+debug = (os.environ.get("LIBCONCORD_PY_TRACE", "0") == "1")
+
+# Define the libconcord ABI this libconcord.py corresponds to
+# Bump this when the .so file version gets bumped
+
+ABI_VERSION = 0
+
+# Load the DLL
-# Internal DLL handle
if platform.system() == 'Windows':
_dll = cdll.LoadLibrary('libconcord.dll')
else:
- _dll = cdll.LoadLibrary('libconcord.so.0')
+ _dll = cdll.LoadLibrary('libconcord.so.' + str(ABI_VERSION))
+
+# Public libconcord API: Custom types
+
+# typedef void (*lc_callback)(uint32_t, uint32_t, uint32_t, void*);
+callback_type = CFUNCTYPE(None, c_uint, c_uint, c_uint, py_object)
+
+# Exception types
-# This exception may be raised by any function that returns an LC_ERROR_*.
class LibConcordException(Exception):
+ """This exception may be raised by any function that returns an LC_ERROR_*."""
def __init__(self, func, result):
self.func = func
self.result = result
@@ -46,7 +64,48 @@ class LibConcordException(Exception):
repr(self.result_str)
)
+# Helpers for parameter prototyping
+
+class _param(object):
+ def __init__(self, name, ctypes_type):
+ self.name = name
+ self.ctypes_type = ctypes_type
+
+class _in(_param):
+ def real_ctypes_type(self):
+ return self.ctypes_type
+
+class _out(_param):
+ def real_ctypes_type(self):
+ return POINTER(self.ctypes_type)
+
+# Helpers for parameter tracing
+
+def _dump_simple(type):
+ def _dump_simple_imp(value):
+ if not isinstance(value, type):
+ value = type(value)
+ return repr(value.value)
+ return _dump_simple_imp
+
+def _dump_pointer(name):
+ def _dump_pointer_imp(value):
+ return "<<%s @0x%08x>>" % (name, addressof(value))
+ return _dump_pointer_imp
+
+_dumpers = {
+ c_char_p: _dump_simple(c_char_p),
+ c_int: _dump_simple(c_int),
+ c_long: _dump_simple(c_long),
+ c_uint: _dump_simple(c_uint),
+ c_ulong: _dump_simple(c_ulong),
+ POINTER(c_ubyte): _dump_pointer('buffer'),
+ callback_type: _dump_pointer('function'),
+ py_object: _dump_simple(py_object),
+}
+
# Internal function result checking functionality
+
class _CheckRetCode(object):
def __init__(self, func_name):
self.func_name = func_name
@@ -55,21 +114,88 @@ class _CheckRetCode(object):
result = args[0]
if result != 0:
raise LibConcordException(self.func_name, result)
-
+
+# Internal function tracing functionality
+
+_byref_type = type(byref(c_int()))
+def from_param(obj):
+ if type(obj) == _byref_type:
+ return obj._obj
+ if isinstance(obj, _Pointer):
+ return obj.contents
+ raise TypeError, "Output parameters should be byref/pointers"
+
+class _DebugWrapper(object):
+ def __init__(self, callable):
+ self.callable = callable
+
+ def __call__(self, *args):
+ sys.stdout.write("libconcord." + self.callable.__name__ + "(")
+ delim = ""
+ for (val, proto) in zip(args, self.callable._lcpy_protos):
+ if isinstance(proto, _param):
+ name = proto.name
+ if isinstance(proto, _in):
+ try:
+ type = proto.ctypes_type
+ value = _dumpers[type](val)
+ except:
+ value = "???"
+ else:
+ value = "<<out>>"
+ else:
+ name = "???"
+ value = "???"
+ sys.stdout.write("%s%s=%s" % (delim, name, value))
+ delim = ", "
+ print ")"
+ try:
+ ret = self.callable(*args)
+ print " Returned: " + repr(ret)
+ for (val, proto) in zip(args, self.callable._lcpy_protos):
+ if not isinstance(proto, _out):
+ continue
+ name = proto.name
+ type = proto.ctypes_type
+ try:
+ value = _dumpers[type](from_param(val))
+ except:
+ value = "???"
+ print " <<out>> %s=%s" % (name, value)
+ return ret
+ except:
+ print " Threw: "
+ s = traceback.format_exc()
+ for sl in s.split('\n'):
+ print " " + sl
+ raise
+
# Internal ctypes function wrapper creation
+
def _create_func(
func_name,
error_checker,
- *args
+ rettype,
+ *protos
):
- ftype = CFUNCTYPE(*args)
+ def real_ctypes_type(type):
+ if not isinstance(type, _param):
+ return type
+ return type.real_ctypes_type()
+ real_protos = [real_ctypes_type(x) for x in protos]
+ ftype = CFUNCTYPE(rettype, *real_protos)
f = ftype((func_name, _dll))
+ f._lcpy_rettype = rettype
+ f._lcpy_protos = protos
+ f.__name__ = func_name
if error_checker:
f.errcheck = error_checker(func_name)
+ if debug:
+ f = _DebugWrapper(f)
+ f.__name__ = func_name
return f
-# typedef void (*lc_callback)(uint32_t, uint32_t, uint32_t, void*);
-callback_type = CFUNCTYPE(None, c_uint, c_uint, c_uint, py_object)
+# Public libconcord API: Function prototypes
# const char *get_mfg();
get_mfg = _create_func(
@@ -241,7 +367,7 @@ get_serial = _create_func(
'get_serial',
None,
c_char_p,
- c_int
+ _in('p', c_int)
)
# int get_config_bytes_used();
@@ -326,7 +452,7 @@ delete_block = _create_func(
'delete_blob',
_CheckRetCode,
c_int,
- POINTER(c_ubyte)
+ _in('ptr', POINTER(c_ubyte))
);
LC_FILE_TYPE_CONNECTIVITY = 0
@@ -339,9 +465,9 @@ identify_file = _create_func(
'identify_file',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- POINTER(c_int)
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _out('type', c_int)
)
# int init_concord();
@@ -363,8 +489,8 @@ get_identity = _create_func(
'get_identity',
_CheckRetCode,
c_int,
- callback_type,
- py_object
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int reset_remote();
@@ -393,8 +519,8 @@ post_connect_test_success = _create_func
'post_connect_test_success',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint
+ _in('data', POINTER(c_ubyte)),
+ _in('size', c_uint)
)
# int post_preconfig(uint8_t *data, uint32_t size);
@@ -402,8 +528,8 @@ post_preconfig = _create_func(
'post_preconfig',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint
+ _in('data', POINTER(c_ubyte)),
+ _in('size', c_uint)
)
# int post_postconfig(uint8_t *data, uint32_t size);
@@ -411,8 +537,8 @@ post_postconfig = _create_func(
'post_postconfig',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint
+ _in('data', POINTER(c_ubyte)),
+ _in('size', c_uint)
)
# int post_postfirmware(uint8_t *data, uint32_t size);
@@ -420,8 +546,8 @@ post_postfirmware = _create_func(
'post_postfirmware',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint
+ _in('data', POINTER(c_ubyte)),
+ _in('size', c_uint)
)
# int invalidate_flash();
@@ -437,10 +563,10 @@ read_config_from_remote = _create_func(
'read_config_from_remote',
_CheckRetCode,
c_int,
- POINTER(POINTER(c_ubyte)),
- POINTER(c_uint),
- callback_type,
- py_object
+ _out('out', POINTER(c_ubyte)),
+ _out('size', c_uint),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int write_config_to_remote(uint8_t *in, uint32_t size,
@@ -449,10 +575,10 @@ write_config_to_remote = _create_func(
'write_config_to_remote',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- callback_type,
- py_object
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int read_file(char *file_name, uint8_t **out, uint32_t *size);
@@ -460,9 +586,9 @@ read_file = _create_func(
'read_file',
_CheckRetCode,
c_int,
- c_char_p,
- POINTER(POINTER(c_ubyte)),
- POINTER(c_uint)
+ _in('file_name', c_char_p),
+ _out('out', POINTER(c_ubyte)),
+ _out('size', c_uint)
)
# int write_config_to_file(uint8_t *in, uint32_t size, char *file_name,
@@ -471,10 +597,10 @@ write_config_to_file = _create_func(
'write_config_to_file',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- c_char_p,
- c_int
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('file_name', c_char_p),
+ _in('binary', c_int)
)
# int verify_remote_config(uint8_t *in, uint32_t size, lc_callback cb,
@@ -483,10 +609,10 @@ verify_remote_config = _create_func(
'verify_remote_config',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- callback_type,
- py_object
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int erase_config(uint32_t size, lc_callback cb, void *cb_arg);
@@ -494,9 +620,9 @@ erase_config = _create_func(
'erase_config',
_CheckRetCode,
c_int,
- c_uint,
- callback_type,
- py_object
+ _in('size', c_uint),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int find_config_binary(uint8_t *config, uint32_t config_size,
@@ -505,10 +631,10 @@ find_config_binary = _create_func(
'find_config_binary',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- POINTER(POINTER(c_ubyte)),
- POINTER(c_uint)
+ _in('config', POINTER(c_ubyte)),
+ _in('config_size', c_uint),
+ _out('binary_ptr', POINTER(c_ubyte)),
+ _out('binary_size', c_uint)
)
# int erase_safemode(lc_callback cb, void *cb_arg);
@@ -516,8 +642,8 @@ erase_safemode = _create_func(
'erase_safemode',
_CheckRetCode,
c_int,
- callback_type,
- py_object
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int read_safemode_from_remote(uint8_t **out, uint32_t *size, lc_callback cb,
@@ -526,20 +652,20 @@ read_safemode_from_remote = _create_func
'read_safemode_from_remote',
_CheckRetCode,
c_int,
- POINTER(POINTER(c_ubyte)),
- POINTER(c_ubyte),
- callback_type,
- py_object
+ _out('out', POINTER(c_ubyte)),
+ _out('size', c_ubyte),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
-# int write_safemode_to_file(uint8_t *in, uint32_t size,char *file_name);
+# int write_safemode_to_file(uint8_t *in, uint32_t size, char *file_name);
write_safemode_to_file = _create_func(
'write_safemode_to_file',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- c_char_p
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('file_name', c_char_p)
)
# int is_fw_update_supported(int direct);
@@ -547,7 +673,7 @@ is_fw_update_supported = _create_func(
'is_fw_update_supported',
None,
c_int,
- c_int
+ _in('direct', c_int)
)
# int is_config_safe_after_fw();
@@ -576,9 +702,9 @@ erase_firmware = _create_func(
'erase_firmware',
_CheckRetCode,
c_int,
- c_int,
- callback_type,
- py_object
+ _in('direct', c_int),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int read_firmware_from_remote(uint8_t **out, uint32_t *size, lc_callback cb,
@@ -587,10 +713,10 @@ read_firmware_from_remote = _create_func
'read_firmware_from_remote',
_CheckRetCode,
c_int,
- POINTER(POINTER(c_ubyte)),
- POINTER(c_uint),
- callback_type,
- py_object
+ _out('out', POINTER(c_ubyte)),
+ _out('size', c_uint),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int write_firmware_to_remote(uint8_t *in, uint32_t size, int direct,
@@ -599,11 +725,11 @@ write_firmware_to_remote = _create_func(
'write_firmware_to_remote',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- c_int,
- callback_type,
- py_object
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('direct', c_int),
+ _in('cb', callback_type),
+ _in('cb_arg', py_object)
)
# int write_firmware_to_file(uint8_t *in, uint32_t size, char *file_name,
@@ -612,10 +738,10 @@ write_firmware_to_file = _create_func(
'write_firmware_to_file',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- c_char_p,
- c_int
+ _in('in', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('file_name', c_char_p),
+ _in('binary', c_int)
)
# int extract_firmware_binary(uint8_t *xml, uint32_t xml_size, uint8_t **out,
@@ -624,10 +750,10 @@ extract_firmware_binary = _create_func(
'extract_firmware_binary',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- POINTER(POINTER(c_ubyte)),
- POINTER(c_uint)
+ _in('xml', POINTER(c_ubyte)),
+ _in('xml_size', c_uint),
+ _out('out', POINTER(c_ubyte)),
+ _out('size', c_uint)
)
# int learn_ir_commands(uint8_t *data, uint32_t size, int post);
@@ -635,8 +761,8 @@ learn_ir_commands = _create_func(
'learn_ir_commands',
_CheckRetCode,
c_int,
- POINTER(c_ubyte),
- c_uint,
- c_int
+ _in('data', POINTER(c_ubyte)),
+ _in('size', c_uint),
+ _in('post', c_int)
)
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel