This is a revision to a patch I posted earlier this year, adding python 
language bindings for liburjtag.

- tested with python 2.7 and 3.1 on fedora 14

- code formatting much closer to the style of the rest of urjtag (but
claiming perfection)

- some non-python-related routines factored out into files 
urj_helpers.[ch].  these routines provide cleaner access to the
liburjtag library, and might be considered for inclusion in the core.

- includes additions by Jonathan Stroud, which provide bindings for more
methods, including those needed for burning (some?) flash devices.

Steve
[email protected]

---
  urjtag/Makefile.am                       |    3 +-
  urjtag/bindings/Makefile.am              |   30 +
  urjtag/bindings/python/Makefile.am       |   36 ++
  urjtag/bindings/python/chain.c           |  901 ++++++++++++++++++++++++++++++
  urjtag/bindings/python/pycompat23.h      |   38 ++
  urjtag/bindings/python/setup.py          |   12 +
  urjtag/bindings/python/t_srst.py         |   49 ++
  urjtag/bindings/python/t_urjtag_chain.py |   81 +++
  urjtag/bindings/python/urj_helpers.c     |  161 ++++++
  urjtag/bindings/python/urj_helpers.h     |   34 ++
  urjtag/configure.ac                      |   25 +
  11 files changed, 1369 insertions(+), 1 deletions(-)
  create mode 100644 urjtag/bindings/Makefile.am
  create mode 100644 urjtag/bindings/python/Makefile.am
  create mode 100644 urjtag/bindings/python/chain.c
  create mode 100644 urjtag/bindings/python/pycompat23.h
  create mode 100644 urjtag/bindings/python/setup.py
  create mode 100644 urjtag/bindings/python/t_srst.py
  create mode 100644 urjtag/bindings/python/t_urjtag_chain.py
  create mode 100644 urjtag/bindings/python/urj_helpers.c
  create mode 100644 urjtag/bindings/python/urj_helpers.h

diff --git a/urjtag/Makefile.am b/urjtag/Makefile.am
index 7998707..e7c0200 100644
--- a/urjtag/Makefile.am
+++ b/urjtag/Makefile.am
@@ -28,7 +28,8 @@ SUBDIRS = \
        include/urjtag \
        data \
        src \
-       po
+       po \
+       bindings

  if ENABLE_APPS
  SUBDIRS += \
diff --git a/urjtag/bindings/Makefile.am b/urjtag/bindings/Makefile.am
new file mode 100644
index 0000000..363d334
--- /dev/null
+++ b/urjtag/bindings/Makefile.am
@@ -0,0 +1,30 @@
+#
+# $Id$
+#
+# Copyright (C) 2002,2011 ETC s.r.o.
+#
+# 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.
+#
+# Written by Steve Tell <[email protected]> 2011
+#
+
+SUBDIRS = $(PYTHON_SUBDIR)
+
+if BIND_PYTHON
+PYTHON_SUBDIR=python
+else
+PYTHON_SUBDIR=
+endif
diff --git a/urjtag/bindings/python/Makefile.am 
b/urjtag/bindings/python/Makefile.am
new file mode 100644
index 0000000..87f64c2
--- /dev/null
+++ b/urjtag/bindings/python/Makefile.am
@@ -0,0 +1,36 @@
+#
+# $Id$
+#
+# Copyright (C) 2002,2011 ETC s.r.o.
+#
+# 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.
+#
+# Written by Steve Tell <[email protected]> 2011
+#
+
+EXTRA_DIST =  setup.py chain.c pycompat23.h t_urjtag_chain.py
+
+all-local: build
+
+build: chain.c
+       -{ $(PYTHON) setup.py build && touch build; } || { $(RM) -r build; exit 
1; }
+
+install-data-local:
+       -$(PYTHON) setup.py install --prefix=$(DESTDIR)$(prefix)
+
+clean-local:
+       -$(RM) -r build
+
diff --git a/urjtag/bindings/python/chain.c b/urjtag/bindings/python/chain.c
new file mode 100644
index 0000000..1911daa
--- /dev/null
+++ b/urjtag/bindings/python/chain.c
@@ -0,0 +1,901 @@
+/* 
+ * $Id$
+ *
+ * Copyright (C) 2011 
+ *
+ * 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.
+ *
+ * Python bindings for urjtag intially written by Steve Tell.
+ * Additional methods by Jonathan Stroud.
+ *
+ */
+#include <Python.h>
+#include "structmember.h"
+#include "pycompat23.h"
+
+#include <urjtag.h>
+#include <chain.h>
+#include <cmd.h>
+#include <assert.h>
+#include <sys/mman.h>
+
+#include "urj_helpers.h"
+
+/* missing from urjtag headers */
+extern int      urj_cmd_get_number (const char *s, long unsigned *i);
+extern int      urj_cmd_test_cable (urj_chain_t * chain);
+
+static PyObject *UrjtagError;
+
+typedef struct {
+    PyObject_HEAD urj_chain_t * urchain;
+} Chain;
+
+static void
+Chain_dealloc (Chain * self)
+{
+    //printf ("in Chain_dealloc urc=%p\n", self);
+    urj_tap_chain_free (self->urchain);
+    Py_TYPE(self)->tp_free ((PyObject *) self);
+}
+
+static PyObject *
+Chain_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
+{
+    Chain          *self;
+
+    self = (Chain *) type->tp_alloc (type, 0);
+    if (self != NULL)
+    {
+       self->urchain = urj_tap_chain_alloc ();
+       if (self->urchain == NULL)
+       {
+           Py_DECREF (self);
+           return PyErr_NoMemory ();
+       }
+       self->urchain->main_part = 0;
+    }
+    return (PyObject *) self;
+}
+
+
+/* methods */
+
+static PyObject *
+Chain_cable (Chain * self, PyObject * args)
+{
+    char           *cable_params[5] = { NULL, NULL, NULL, NULL, NULL };
+    urj_chain_t    *urc = self->urchain;
+
+    assert (self->urchain == g_tstptr);
+    if (urc == NULL)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (!PyArg_ParseTuple (args, "s|sss",
+                          &cable_params[0],
+                          &cable_params[1],
+                          &cable_params[2], &cable_params[3]))
+    {
+       return NULL;
+    }
+    if (urj_chain_cable (urc, cable_params) != URJ_STATUS_OK)
+    {
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in cable()");
+
+       }
+       return NULL;
+    }
+    //printf ("Chain_cable: cable=%p %s\n", urc->cable, cable_params[0]);
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_disconnect (Chain * self)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (urc == NULL)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    urj_tap_chain_disconnect (urc);
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_test_cable (Chain * self)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (urc == NULL)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in test_cable()");
+       }
+       return NULL;
+    }
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_tap_detect (Chain * self)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (urc == NULL)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    // printf("_tap_detect: urchain=%p cable=%p\n", urc, urc->cable); 
+
+    if (urj_tap_detect (urc) != URJ_STATUS_OK)
+    {
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in detect()");
+       }
+       return NULL;
+    }
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_len (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (urc->parts == NULL)
+    {
+       PyErr_SetString (PyExc_RuntimeError,
+                        "detect not called on this chain");
+       return NULL;
+    }
+
+    return Py_BuildValue ("i", urc->parts->len);
+}
+
+static PyObject *
+Chain_partid (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    int             partno;
+    if (!PyArg_ParseTuple (args, "i", &partno))
+       return NULL;
+
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (urc->parts == NULL)
+    {
+       PyErr_SetString (PyExc_RuntimeError,
+                        "detect not called on this chain");
+       return NULL;
+    }
+    if (partno >= urc->parts->len)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "part number out of range");
+       return NULL;
+    }
+    else
+    {
+       urj_part_t     *p;
+       uint32_t        id;
+
+       p = urc->parts->parts[partno];
+       id = urj_tap_register_get_value (p->id);
+       return Py_BuildValue ("i", id);
+    }
+}
+
+static PyObject *
+Chain_reset (Chain * self)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+
+    if (urj_tap_reset_bypass (urc) != URJ_STATUS_OK)
+    {
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in dereset_bypass()");
+       }
+       return NULL;
+    }
+    urj_tap_chain_flush (urc);
+    return Py_BuildValue ("");
+}
+
+
+static PyObject *
+Chain_set_trst (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    int             trstval;
+    if (!PyArg_ParseTuple (args, "i", &trstval))
+       return NULL;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    urj_tap_chain_set_trst (urc, trstval);
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_get_trst (Chain * self)
+{
+    int             trstval;
+    urj_chain_t    *urc = self->urchain;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+
+    trstval = urj_tap_chain_get_trst (urc);
+    return Py_BuildValue ("i", trstval);
+}
+
+static PyObject *
+Chain_set_pod_signal (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    uint32_t        mask,
+                    val,
+                    oldval;
+    if (!PyArg_ParseTuple (args, "ii", &mask, &val))
+       return NULL;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    oldval = urj_tap_chain_set_pod_signal (urc, mask, val);
+    return Py_BuildValue ("i", oldval);        // None
+}
+
+static PyObject *
+Chain_get_pod_signal (Chain * self, PyObject * args)
+{
+    uint32_t        sig;
+    uint32_t        val;
+    urj_chain_t    *urc = self->urchain;
+    if (!PyArg_ParseTuple (args, "i", &sig))
+       return NULL;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+
+    val = urj_tap_chain_get_pod_signal (urc, sig);
+    // printf("_get_pod_signal(sig=%x result=%x)\n", sig, val);
+    return Py_BuildValue ("i", val);
+}
+
+static PyObject *
+Chain_set_frequency (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    uint32_t        freq;
+    if (!PyArg_ParseTuple (args, "i", &freq))
+       return NULL;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    } 
+    urj_tap_cable_set_frequency (urc->cable, freq);
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_get_frequency (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    unsigned long        freq;
+    freq = urj_tap_cable_get_frequency (urc->cable);
+
+    return Py_BuildValue ("i", (uint32_t) freq);
+}
+
+// set instruction for the active part
+static PyObject *
+Chain_set_instruction (Chain * self, PyObject * args)
+{
+    char           *instname;
+    urj_part_t     *part;
+    urj_chain_t    *urc = self->urchain;
+    if (!PyArg_ParseTuple (args, "s", &instname))
+       return NULL;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    part = urj_tap_chain_active_part (urc);
+    if (part == NULL)
+    {
+       PyErr_SetString (UrjtagError, "No active part on chain");
+       return NULL;
+    }
+    urj_part_set_instruction (part, instname);
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_shift_ir (Chain * self)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+       PyErr_SetString (UrjtagError, "cable() has not been called");
+       return NULL;
+    }
+
+    if (urj_tap_chain_shift_instructions (urc) != URJ_STATUS_OK)
+    {
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in deshift_ir");
+       }
+       return NULL;
+    }
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_shift_dr (Chain * self)
+{
+    urj_chain_t    *urc = self->urchain;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+       PyErr_SetString (UrjtagError, "cable() has not been called");
+       return NULL;
+    }
+    // TODO: need a way to not capture the TDO output
+    if (urj_tap_chain_shift_data_registers (urc, 1) != URJ_STATUS_OK)
+    {
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in deshift_dr");
+       }
+       return NULL;
+    }
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_get_dr (Chain * self, int in)
+{
+    urj_chain_t    *urc = self->urchain;
+    urj_part_t     *part;
+    urj_tap_register_t *r;
+    urj_data_register_t *dr;
+    urj_part_instruction_t *active_ir;
+
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+    {
+       PyErr_SetString (UrjtagError, "cable() has not been called");
+       return NULL;
+    }
+    part = urj_tap_chain_active_part (urc);
+    if (part == NULL)
+    {
+       PyErr_SetString (UrjtagError, "no active part in chain");
+       return NULL;
+    }
+    active_ir = part->active_instruction;
+    if (active_ir == NULL)
+    {
+       PyErr_SetString (UrjtagError, "part without active instruction");
+       return NULL;
+    }
+    dr = active_ir->data_register;
+    if (dr == NULL)
+    {
+       PyErr_SetString (UrjtagError,
+                        "instruction without active data register");
+       return NULL;
+    }
+
+    if (in)
+       r = dr->in;             // input buffer for next shift_dr
+    else
+       r = dr->out;            // recently captured+scanned-out values
+                               // TODO: input buffer
+    // for now: use ascii bitstrings
+    return Py_BuildValue ("s", urj_tap_register_get_string (r));
+}
+
+static PyObject *
+Chain_get_dr_out (Chain * self)
+{
+    return Chain_get_dr (self, 0);
+}
+
+static PyObject *
+Chain_get_dr_in (Chain * self)
+{
+    return Chain_get_dr (self, 1);
+}
+
+static PyObject *
+Chain_run_svf (Chain * self, PyObject * args)
+{
+    urj_chain_t    *urc = self->urchain;
+    char           *fname;
+    int             stop = 0;
+    unsigned long   ref_freq = 0;
+    FILE           *svf_file;
+
+    if (!PyArg_ParseTuple (args, "s|iI", &fname, &stop, &ref_freq))
+       return NULL;
+    if (!urc)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    svf_file = fopen (fname, "rb");
+    if (!svf_file)
+    {
+       PyErr_SetString (PyExc_RuntimeError, "error opening svf file"); // 
TODO: 
+                                                                       // fix 
+                                                                       // 
error 
+                                                                       // type
+       return NULL;
+    }
+    if (urj_svf_run (urc, svf_file, stop, ref_freq) != URJ_STATUS_OK)
+    {
+       if (urj_error_get ())
+       {
+           PyErr_SetString (UrjtagError, urj_error_describe ());
+           urj_error_reset ();
+       }
+       else
+       {
+           PyErr_SetString (UrjtagError,
+                            "unknown urjtag error in desvf_run");
+       }
+       return NULL;
+    }
+    fclose (svf_file);
+    return Py_BuildValue (""); // None
+}
+
+static PyObject *
+Chain_addpart(Chain* self, PyObject *args)
+{
+    urj_chain_t *urc = self->urchain;
+    long unsigned len;
+
+    if(!PyArg_ParseTuple(args, "i", &len))
+       return NULL;
+
+    if (urj_cmd_test_cable (urc) != URJ_STATUS_OK)
+        return NULL; 
+
+    if (urj_tap_manual_add (urc, len) == -1)
+        return NULL; 
+
+    // @@@@ RFHH this cannot be
+    if (urc->parts == NULL)
+        return NULL; 
+
+    // @@@@ RFHH this cannot be
+    if (urc->parts->len == 0)
+    {
+        urj_part_parts_free (urc->parts);
+        self->urchain->parts = NULL;
+        return NULL; 
+    }
+
+    urj_part_parts_set_instruction (urc->parts, "BYPASS");
+    urj_tap_chain_shift_instructions (urc);
+    return Py_BuildValue(""); // None
+}
+
+static PyObject *
+Chain_setpart (Chain * self, PyObject * args)
+{
+    urj_chain_t *urc = self->urchain;
+    int part;
+    if(!PyArg_ParseTuple(args, "i", &part))
+       return NULL;
+    if(!urc) {
+       PyErr_SetString(PyExc_RuntimeError, "null chain");
+       return NULL; 
+    }
+    urc->active_part = part;
+    return Py_BuildValue(""); // None
+}
+
+static PyObject *
+Chain_initbus (Chain * self, PyObject * args)
+{
+    char *bus_params[5] = {NULL,NULL,NULL,NULL,NULL};
+    urj_chain_t *urc = self->urchain;
+
+    assert(self->urchain == g_tstptr);
+    if (urc == NULL) {
+       PyErr_SetString(PyExc_RuntimeError, "null chain");
+       return NULL;
+    }
+    if(!PyArg_ParseTuple(args, "s|sss", 
+                        &bus_params[0], 
+                        &bus_params[1], 
+                        &bus_params[2], 
+                        &bus_params[3])) {
+       return NULL;
+    }
+    return Py_BuildValue("i", urj_initbus(urc, bus_params));
+}
+
+static PyObject *
+Chain_detectflash (Chain * self, PyObject * args)
+{
+    urj_chain_t *urc = self->urchain;
+    int adr;
+    if(!PyArg_ParseTuple(args, "i", &adr))
+       return NULL;
+    if(!urc) {
+       PyErr_SetString(PyExc_RuntimeError, "null chain");
+       return NULL; 
+    }
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus missing");
+        return NULL; 
+    }
+
+    return Py_BuildValue("i", urj_flash_detectflash (URJ_LOG_LEVEL_NORMAL, 
urj_bus, adr));
+}
+
+static PyObject *
+Chain_peek (Chain * self, PyObject * args)
+{
+    long unsigned adr;
+    uint32_t val;
+    urj_bus_area_t area;
+
+    if(!PyArg_ParseTuple(args, "i", &adr))
+       return NULL;
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus missing");
+        return NULL;
+    }
+    if (!urj_bus->driver)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus driver missing");
+        return NULL;
+    }
+
+    URJ_BUS_PREPARE (urj_bus);
+    URJ_BUS_AREA (urj_bus, adr, &area);
+    val = URJ_BUS_READ (urj_bus, adr);
+
+    switch (area.width)
+    {
+    case 8:
+       val &= 0xff;
+       break;
+    case 16:
+       val &= 0xffff;
+       break;
+    default:
+       break;
+    }
+    return Py_BuildValue("i", val); // None
+}
+
+static PyObject *
+Chain_poke (Chain * self, PyObject * args)
+{
+    long unsigned adr, val;
+    urj_bus_area_t area;
+
+    if(!PyArg_ParseTuple(args, "ii", &adr, &val))
+       return NULL;
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus missing");
+        return NULL; 
+    }
+    if (!urj_bus->driver)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus driver missing");
+        return NULL; 
+    }
+
+    URJ_BUS_PREPARE (urj_bus);
+
+    URJ_BUS_AREA (urj_bus, adr, &area);
+    URJ_BUS_WRITE (urj_bus, adr, val);
+    return Py_BuildValue(""); // None
+}
+
+static PyObject *
+Chain_flashmem (Chain * self, PyObject * args)
+{
+    int msbin;
+    int noverify = 0;
+    long unsigned adr = 0;
+    FILE *f;
+    char *params[2] = {NULL,NULL};
+    int r;
+
+    if (!urj_bus)
+    {
+        urj_error_set (URJ_ERROR_ILLEGAL_STATE, "Bus driver missing");
+        return NULL; 
+    }
+
+    if(!PyArg_ParseTuple(args, "ss|i", &params[0], &params[1], &noverify))
+       return NULL;
+
+    msbin = strcasecmp ("msbin", params[0]) == 0;
+    if (!msbin && urj_cmd_get_number (params[0], &adr) != URJ_STATUS_OK)
+        return NULL;
+
+    f = fopen (params[1], "rb");
+    if (!f)
+    {
+        urj_error_IO_set ("Unable to open file `%s'", params[2]);
+        return NULL; 
+    }
+    //printf("msbin = %d, file = %s, noverify = %d\n", msbin, params[1], 
noverify);
+
+    if (msbin)
+        r = urj_flashmsbin (urj_bus, f, noverify);
+    else
+        r = urj_flashmem (urj_bus, f, adr, noverify);
+
+    fclose (f);
+    return Py_BuildValue("i", r); // None
+}
+
+static PyMethodDef Chain_methods[] = {
+    {"cable", (PyCFunction) Chain_cable, METH_VARARGS,
+     "Connect to the jtag hardware cable of the specified name and type."},
+    {"test_cable", (PyCFunction) Chain_test_cable, METH_NOARGS,
+     "check that the jtag cable is connected to a valid chain"},
+    {"disconnect", (PyCFunction) Chain_disconnect, METH_NOARGS,
+     "Disconnect from the jtag hardware cable"},
+    {"tap_detect", (PyCFunction) Chain_tap_detect, METH_NOARGS,
+     "Identify the chips on the chain"},
+    {"len", (PyCFunction) Chain_len, METH_NOARGS,
+     "Return the length of the TAP chain"},
+    {"reset", (PyCFunction) Chain_reset, METH_NOARGS,
+     "Perform jtag reset using TMS"},
+    {"partid", (PyCFunction) Chain_partid, METH_VARARGS,
+     "Return the IDCODE for the indicated part number in the chain"},
+    {"set_trst", (PyCFunction) Chain_set_trst, METH_VARARGS,
+     "set the TRST output of the cable"},
+    {"get_trst", (PyCFunction) Chain_get_trst, METH_NOARGS,
+     "get the current value of the TRST output of the cable"},
+    {"set_pod_signal", (PyCFunction) Chain_set_pod_signal, METH_VARARGS,
+     "set an auxiliary pod signal"},
+    {"get_pod_signal", (PyCFunction) Chain_get_pod_signal, METH_VARARGS,
+     "get the current value of an auxiliary pod signal"},
+    {"set_frequency", (PyCFunction) Chain_set_frequency, METH_VARARGS,
+     "Change the TCK frequency to be at most the specified value in Hz"},
+    {"get_frequency", (PyCFunction) Chain_get_frequency, METH_NOARGS,
+     "get the current TCK frequency"},
+    {"set_instruction", (PyCFunction) Chain_set_instruction, METH_VARARGS,
+     "Set values in the instruction register holding buffer"},
+    {"shift_ir", (PyCFunction) Chain_shift_ir, METH_NOARGS,
+     "scan values through the instruction register"},
+    {"shift_dr", (PyCFunction) Chain_shift_dr, METH_NOARGS,
+     "scan values through the data register"},
+    {"get_dr_in", (PyCFunction) Chain_get_dr_in, METH_NOARGS,
+     "get bits that will be scanned in on next shiftdr"},
+    {"get_dr_out", (PyCFunction) Chain_get_dr_out, METH_NOARGS,
+     "retrieve values scanned out from the data registers"},
+    {"run_svf", (PyCFunction) Chain_run_svf, METH_VARARGS,
+     "Play a named SVF file; optionally setting stop-on-mismatch and runtest 
frequency"},
+    {"addpart", (PyCFunction)Chain_addpart, METH_VARARGS,
+     "manually adds parts on the JTAG chain"},
+    {"part", (PyCFunction)Chain_setpart, METH_VARARGS,
+     "change active part for current JTAG chain"},
+    {"initbus", (PyCFunction)Chain_initbus, METH_VARARGS,
+     "initialize bus driver for active part"},
+    {"detectflash", (PyCFunction)Chain_detectflash, METH_VARARGS,
+     "Detect parameters of flash chips attached to a part"},
+    {"peek", (PyCFunction)Chain_peek, METH_VARARGS,
+     "read a single word"},
+    {"poke", (PyCFunction)Chain_poke, METH_VARARGS,
+     "write a single word"},
+    {"flashmem", (PyCFunction)Chain_flashmem, METH_VARARGS,
+     "burn flash memory with data from a file"},
+    {NULL}                     /* Sentinel */
+};
+
+static PyTypeObject ChainType = {
+//    PyObject_HEAD_INIT (NULL) 0,     /* ob_size */
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "urjtag.chain",            /* tp_name */
+    sizeof (Chain),            /* tp_basicsize */
+    0,                         /* tp_itemsize */
+    (destructor) Chain_dealloc,        /* tp_dealloc */
+    0,                         /* tp_print */
+    0,                         /* tp_getattr */
+    0,                         /* tp_setattr */
+    0,                         /* tp_compare */
+    0,                         /* tp_repr */
+    0,                         /* tp_as_number */
+    0,                         /* tp_as_sequence */
+    0,                         /* tp_as_mapping */
+    0,                         /* tp_hash */
+    0,                         /* tp_call */
+    0,                         /* tp_str */
+    0,                         /* tp_getattro */
+    0,                         /* tp_setattro */
+    0,                         /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+    "JTAG chain objects",      /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    Chain_methods,             /* tp_methods */
+    0,                         /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    0,                         /* tp_init */
+    0,                         /* tp_alloc */
+    Chain_new,                 /* tp_new */
+};
+
+/************************************************************************
+ * module methods that are not part of any type 
+ */
+
+static PyObject *
+urjtag_loglevel (PyObject * self, PyObject * args)
+{
+    int             loglevel;  // TODO: accept string and map to the
+                               // enum.
+    if (!PyArg_ParseTuple (args, "i", &loglevel))
+       return NULL;
+    urj_log_state.level = loglevel;
+    return Py_BuildValue (""); // None
+}
+
+static PyMethodDef module_methods[] = {
+    {"loglevel", urjtag_loglevel, METH_VARARGS,
+     "Set log level of the urjtag library"},
+    {NULL}                     /* Sentinel */
+};
+
+static struct PyModuleDef chain_moduledef = { 
+    PyModuleDef_HEAD_INIT,
+    "urjtag", 
+    "Python extension module for urjtag", 
+    -1, 
+    module_methods, 
+};
+
+MODINIT_DECL(urjtag)
+{
+    PyObject       *m;
+
+    if (PyType_Ready (&ChainType) < 0)
+       return MODINIT_ERROR_VAL;
+
+    m = PyModule_Create(&chain_moduledef);
+
+    if (m == NULL)
+       return MODINIT_ERROR_VAL;
+
+    UrjtagError = PyErr_NewException ("urjtag.error", NULL, NULL);
+    Py_INCREF (UrjtagError);
+    PyModule_AddObject (m, "error", UrjtagError);
+
+
+    Py_INCREF (&ChainType);
+    PyModule_AddObject (m, "chain", (PyObject *) & ChainType);
+
+    return MODINIT_SUCCESS_VAL(m);
+}
+
+/* Local Variables: */
+/* mode:c */
+/* comment-column:0 */
+/* c-basic-offset:4 */
+/* space-before-funcall:t */
+/* End: */
diff --git a/urjtag/bindings/python/pycompat23.h 
b/urjtag/bindings/python/pycompat23.h
new file mode 100644
index 0000000..35f322f
--- /dev/null
+++ b/urjtag/bindings/python/pycompat23.h
@@ -0,0 +1,38 @@
+/*
+ * some compatibility macros for python 2  / python 3
+ * by Steve Tell
+ * 
+ * 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.
+ *
+ */
+
+#if PY_MAJOR_VERSION >= 3
+
+#define MODINIT_ERROR_VAL NULL
+#define MODINIT_SUCCESS_VAL(val) val
+#define MODINIT_DECL(name) PyMODINIT_FUNC PyInit_##name(void)
+
+#else  /* assume python 2 */
+
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC void
+#endif
+
+#define MODINIT_ERROR_VAL
+#define MODINIT_SUCCESS_VAL(val)
+#define MODINIT_DECL(name) PyMODINIT_FUNC init##name(void)
+
+struct PyModuleDef {
+    int dc1;
+    const char *name;
+    const char *doc;
+    int dc2;
+    PyMethodDef *methods;
+};
+#define PyModuleDef_HEAD_INIT 0
+#define PyModule_Create(dp) Py_InitModule3((dp)->name, (dp)->methods, 
(dp)->doc)
+
+#endif
diff --git a/urjtag/bindings/python/setup.py b/urjtag/bindings/python/setup.py
new file mode 100644
index 0000000..8848af4
--- /dev/null
+++ b/urjtag/bindings/python/setup.py
@@ -0,0 +1,12 @@
+# python extension setup script for urjtag 
+
+from distutils.core import setup, Extension
+setup(name="urjtag", 
+      version="1.0",
+      description="urJtag Python Bindings",
+      ext_modules=[
+        Extension("urjtag", ["chain.c", "urj_helpers.c"],
+                  include_dirs=['../../include/urjtag'],
+                  library_dirs=['../../src/.libs'],
+                  libraries=['urjtag'])
+         ])
diff --git a/urjtag/bindings/python/t_srst.py b/urjtag/bindings/python/t_srst.py
new file mode 100644
index 0000000..5f86950
--- /dev/null
+++ b/urjtag/bindings/python/t_srst.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+# works in both python 2 and 3
+def printf(format, *args):
+     """Format args with the first argument as format string, and print.
+     If the format is not a string, it is converted to one with str.
+     You must use printf('%s', x) instead of printf(x) if x might
+     contain % or backslash characters."""
+     sys.stdout.write(str(format) % args)
+
+import sys
+sys.path.append( "." )
+
+import urjtag
+
+#urjtag.loglevel(0) # ALL
+
+urc = urjtag.chain()
+printf("%s\n", urc);
+
+urc.cable("JTAGKey")
+printf("urc.cable done %s\n", urc)
+
+urc.test_cable()
+printf("urc.test_cable done\n")
+
+# trst = urc.get_trst()
+# printf("TRST=%d\n", trst)
+# urc.set_trst(0)
+# trst = urc.get_trst()
+# printf( "TRST set 0 -> %d\n", trst)
+
+# urc.set_trst(1)
+# trst = urc.get_trst()
+# printf("TRST set 1 -> %d\n", trst)
+
+srstbit = 0x10
+srstval = urc.get_pod_signal(srstbit)
+printf( "srstval -> %s\n", srstval);
+
+urc.set_pod_signal(srstbit, 0)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 0 -> %s\n", srstval)
+urc.set_pod_signal(srstbit, 1)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 1 -> %s\n", srstval)
+ 
+
+
diff --git a/urjtag/bindings/python/t_urjtag_chain.py 
b/urjtag/bindings/python/t_urjtag_chain.py
new file mode 100644
index 0000000..d0eaf61
--- /dev/null
+++ b/urjtag/bindings/python/t_urjtag_chain.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+
+#
+# A general test and demonstration of several urjtag operations from python.
+#
+
+# works in both python 2 and 3
+def printf(format, *args):
+     """Format args with the first argument as format string, and print.
+     If the format is not a string, it is converted to one with str.
+     You must use printf('%s', x) instead of printf(x) if x might
+     contain % or backslash characters."""
+     sys.stdout.write(str(format) % args)
+
+import sys
+sys.path.append( "." )
+
+import urjtag
+
+#urjtag.loglevel(0) # ALL
+
+urc = urjtag.chain()
+printf("%s\n", urc);
+
+urc.cable("JTAGKey")
+printf("urc.cable done %s\n", urc)
+
+urc.test_cable()
+printf("urc.test_cable done\n")
+
+f = urc.get_frequency()
+printf("frequency was %d Hz\n", f)
+urc.set_frequency(10000)
+f = urc.get_frequency()
+printf("frequency readback = %d Hz\n", f)
+
+trst = urc.get_trst()
+printf("TRST=%d\n", trst)
+urc.set_trst(0)
+trst = urc.get_trst()
+printf( "TRST set 0 -> %d\n", trst)
+urc.set_trst(1)
+trst = urc.get_trst()
+printf("TRST set 1 -> %d\n", trst)
+
+urc.reset();
+
+urc.tap_detect()
+printf("urc.detect done\n")
+printf("chainlength=%d\n", urc.len())
+
+printf("id[0]=%08x\n", urc.partid(0) );
+
+srstbit = 0x10
+srstval = urc.get_pod_signal(srstbit)
+printf( "srstval -> %s\n", srstval);
+
+urc.set_pod_signal(srstbit, 0)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 0 -> %s\n", srstval)
+urc.set_pod_signal(srstbit, 1)
+srstval = urc.get_pod_signal(srstbit)
+printf("srstval set 1 -> %s\n", srstval)
+ 
+urc.set_instruction("SAMPLE/PRELOAD")
+urc.shift_ir()
+drval = urc.get_dr_in()
+printf("BSR dr_in result: %s\n", drval)
+urc.shift_dr()
+drval = urc.get_dr_out()
+printf("BSR dr_out result: %s\n", drval)
+
+urc.set_instruction("IDCODE")
+urc.shift_ir()
+urc.shift_dr()
+drval = urc.get_dr_out()
+printf("IDREG dr result: %s\n", drval)
+
+urc.set_instruction("BYPASS")
+urc.shift_ir()
+
diff --git a/urjtag/bindings/python/urj_helpers.c 
b/urjtag/bindings/python/urj_helpers.c
new file mode 100644
index 0000000..c4d4cac
--- /dev/null
+++ b/urjtag/bindings/python/urj_helpers.c
@@ -0,0 +1,161 @@
+
+/*
+ * Additional urjtag cain operations. 
+ * These are not language-binding specific, but do help in writing of concise
+ * language bindings.  In theory, this code could someday be merged into 
+ * the core urjtag library.
+ *
+ *
+ * Copyright (C) 2011 
+ *
+ * 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 <urjtag.h>
+#include <chain.h>
+#include <cmd.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/mman.h>
+
+extern int      urj_cmd_test_cable (urj_chain_t * chain);
+extern int      urj_cmd_params (char *params[]);
+
+int
+urj_chain_cable (urj_chain_t * chain, char *params[])
+{
+    urj_cable_t    *cable = NULL;
+    int             i;
+    int             j;
+    int             paramc = urj_cmd_params (params);
+    const urj_param_t **cable_params;
+    urj_cable_parport_devtype_t devtype = -1;
+    const char     *devname = NULL;
+    int             param_start = 1;
+    const urj_cable_driver_t *driver;
+
+    /* search cable driver list */
+    for (i = 0; urj_tap_cable_drivers[i]; i++)
+       if (strcasecmp (params[0], urj_tap_cable_drivers[i]->name) == 0)
+           break;
+    driver = urj_tap_cable_drivers[i];
+    if (!driver)
+    {
+       urj_error_set (URJ_ERROR_INVALID,
+                      "unknown cable driver '%s'", params[0]);
+       return URJ_STATUS_FAIL;
+    }
+
+    if (driver->device_type == URJ_CABLE_DEVICE_PARPORT)
+    {
+       if (paramc < 4)
+       {
+           urj_error_set (URJ_ERROR_SYNTAX,
+                          "parallel cable requires >= 4 parameters");
+           return URJ_STATUS_FAIL;
+       }
+       for (j = 0; j < URJ_CABLE_PARPORT_N_DEVS; j++)
+           if (strcasecmp (params[1],
+                           urj_cable_parport_devtype_string (j)) == 0)
+               break;
+       if (j == URJ_CABLE_PARPORT_N_DEVS)
+       {
+           urj_error_set (URJ_ERROR_INVALID,
+                          "unknown parallel port device type '%s'",
+                          params[1]);
+           return URJ_STATUS_FAIL;
+       }
+
+       devtype = j;
+       devname = params[2];
+       param_start = 3;
+    }
+
+    urj_param_init (&cable_params);
+    for (j = param_start; params[j] != NULL; j++)
+       if (urj_param_push (&urj_cable_param_list, &cable_params,
+                           params[j]) != URJ_STATUS_OK)
+       {
+           urj_param_clear (&cable_params);
+           return URJ_STATUS_FAIL;
+       }
+
+    switch (driver->device_type)
+    {
+    case URJ_CABLE_DEVICE_PARPORT:
+       cable =
+           urj_tap_cable_parport_connect (chain, driver, devtype, devname,
+                                          cable_params);
+       break;
+    case URJ_CABLE_DEVICE_USB:
+       cable = urj_tap_cable_usb_connect (chain, driver, cable_params);
+       break;
+    case URJ_CABLE_DEVICE_OTHER:
+       cable = urj_tap_cable_other_connect (chain, driver, cable_params);
+       break;
+    }
+
+    urj_param_clear (&cable_params);
+
+    if (cable == NULL)
+    {
+       return URJ_STATUS_FAIL;
+    }
+
+    chain->cable->chain = chain;
+    return URJ_STATUS_OK;
+}
+
+int urj_initbus (urj_chain_t *chain, char *params[])
+{
+    int drv, i;
+    const urj_param_t **bus_params;
+
+    if (urj_cmd_test_cable (chain) != URJ_STATUS_OK)
+        return URJ_STATUS_FAIL;
+
+    if (urj_tap_chain_active_part (chain) == NULL)
+        return URJ_STATUS_FAIL;
+
+    for (drv = 0; urj_bus_drivers[drv] != NULL; drv++)
+        if (strcasecmp (urj_bus_drivers[drv]->name, params[0]) == 0)
+            break;
+
+    if (urj_bus_drivers[drv] == NULL)
+    {
+        urj_error_set (URJ_ERROR_NOTFOUND, "Unknown bus: %s", params[0]);
+        return URJ_STATUS_FAIL;
+    }
+
+    urj_param_init (&bus_params);
+    for (i = 1; params[i] != NULL; i++)
+        if (urj_param_push (&urj_bus_param_list, &bus_params,
+                            params[i]) != URJ_STATUS_OK)
+        {
+            urj_param_clear (&bus_params);
+            return URJ_STATUS_FAIL;
+        }
+
+    if (urj_bus_init_bus(chain, urj_bus_drivers[drv], bus_params) == NULL)
+    {
+        urj_param_clear (&bus_params);
+        return URJ_STATUS_FAIL;
+    }
+
+    urj_param_clear (&bus_params);
+    return URJ_STATUS_OK;
+}
diff --git a/urjtag/bindings/python/urj_helpers.h 
b/urjtag/bindings/python/urj_helpers.h
new file mode 100644
index 0000000..cc81a8e
--- /dev/null
+++ b/urjtag/bindings/python/urj_helpers.h
@@ -0,0 +1,34 @@
+
+/*
+ * Additional urjtag cain operations. 
+ * These are not language-binding specific, but do help in writing of concise
+ * language bindings.  In theory, this code could someday be merged into 
+ * the core urjtag library.
+ *
+ *
+ * Copyright (C) 2011 
+ *
+ * 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.
+ *
+ */
+
+
+int urj_chain_cable (urj_chain_t * chain, char *params[]);
+int urj_initbus (urj_chain_t *chain, char *params[]);
+
+
+
+
diff --git a/urjtag/configure.ac b/urjtag/configure.ac
index 52d5d4c..806fd05 100644
--- a/urjtag/configure.ac
+++ b/urjtag/configure.ac
@@ -86,6 +86,8 @@ AC_CONFIG_FILES(
        src/apps/bsdl2jtag/Makefile
        src/bfin/Makefile
        po/Makefile.in
+       bindings/Makefile
+       bindings/python/Makefile
  )

  AM_MAINTAINER_MODE
@@ -358,6 +360,26 @@ AS_IF([test "x$enable_apps" = xyes], [
    AM_CONDITIONAL(ENABLE_APPS, false)
  ])

+AC_ARG_ENABLE([python], 
+   [AS_HELP_STRING([--enable-python], [build python language bindings for 
liburjtag])], 
+ [BIND_PYTHON="yes"],[BIND_PYTHON="no"])
+
+if test "$BIND_PYTHON" == "yes"; then
+        AM_PATH_PYTHON()
+        PYTHON_MAJOR_VERSION=$(echo $PYTHON_VERSION | cut -d. -f1 )
+        PYTHON_MINOR_VERSION=$(echo $PYTHON_VERSION | cut -d. -f2 )
+        if (( $PYTHON_MAJOR_VERSION < 2 )); then
+                AC_MSG_WARN([python version less than 2.0, disabling python 
binding])
+                BIND_PYTHON="no"
+        fi
+fi
+if test "$BIND_PYTHON" == "yes"; then
+   AM_CHECK_PYTHON_HEADERS([],[BIND_PYTHON=no;AC_MSG_NOTICE([python headers 
not found, disabling python binding])])
+fi
+AM_CONDITIONAL([BIND_PYTHON], [test "$BIND_PYTHON" == "yes"])
+
+# for future use
+#AM_CONDITIONAL([BIND_TCL], false)

  # check for lex/flex
  AC_PROG_LEX
@@ -748,4 +770,7 @@ jtag is now configured for
    Bus drivers          : $enabled_bus_drivers
    Cable drivers        : $enabled_cable_drivers
    Lowlevel drivers     : $enabled_lowlevel_drivers
+  Python binding       : $BIND_PYTHON
  ])
+
+
-- 
1.7.4


------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
UrJTAG-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/urjtag-development

Reply via email to