libftdi-git Archives

Subject: A library to talk to FTDI chips branch, master, updated. v1.0-8-gc528532

From: libftdi-git@xxxxxxxxxxxxxxxxxxxxxxx
To: libftdi-git@xxxxxxxxxxxxxxxxxxxxxxx
Date: Wed, 27 Feb 2013 09:08:03 +0100 (CET)
The branch, master has been updated
       via  c5285326555f088e7626dfa67ea7059e094d6e73 (commit)
       via  602adb256f131ef673adb18f8581ff249b356077 (commit)
      from  afb9082460cf8602b1843e1a698ec498e3d38d7b (commit)


- Log -----------------------------------------------------------------
commit c5285326555f088e7626dfa67ea7059e094d6e73
Author: Michel Zou <xantares09@xxxxxxxxxxx>
Date:   Tue Feb 19 10:59:42 2013 +0100

    Moved python stuff to own directory
    (was 'bindings' before)

commit 602adb256f131ef673adb18f8581ff249b356077
Author: Michel Zou <xantares09@xxxxxxxxxxx>
Date:   Tue Feb 19 10:44:32 2013 +0100

    Added confuse script and moved cmake files

-----------------------------------------------------------------------

Summary of changes:
 CMakeLists.txt                 |    4 +-
 FindUSB1.cmake                 |   38 ----
 bindings/CMakeLists.txt        |   62 ------
 bindings/doxy2swig.py          |  451 ----------------------------------------
 bindings/ftdi1.i               |  138 ------------
 cmake/FindConfuse.cmake        |   74 +++++++
 cmake/FindUSB1.cmake           |   38 ++++
 examples/python/complete.py    |  115 ----------
 examples/python/simple.py      |   33 ---
 ftdi_eeprom/CMakeLists.txt     |   56 +++---
 python/CMakeLists.txt          |   64 ++++++
 python/doxy2swig.py            |  451 ++++++++++++++++++++++++++++++++++++++++
 python/examples/CMakeLists.txt |    5 +
 python/examples/complete.py    |  115 ++++++++++
 python/examples/simple.py      |   33 +++
 python/ftdi1.i                 |  138 ++++++++++++
 16 files changed, 946 insertions(+), 869 deletions(-)
 delete mode 100644 FindUSB1.cmake
 delete mode 100644 bindings/CMakeLists.txt
 delete mode 100644 bindings/doxy2swig.py
 delete mode 100644 bindings/ftdi1.i
 create mode 100644 cmake/FindConfuse.cmake
 create mode 100644 cmake/FindUSB1.cmake
 delete mode 100644 examples/python/complete.py
 delete mode 100644 examples/python/simple.py
 create mode 100644 python/CMakeLists.txt
 create mode 100644 python/doxy2swig.py
 create mode 100644 python/examples/CMakeLists.txt
 create mode 100644 python/examples/complete.py
 create mode 100644 python/examples/simple.py
 create mode 100644 python/ftdi1.i

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3616c66..e7127f7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@ set(MINOR_VERSION 0)
 set(PACKAGE libftdi1)
 set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
 set(VERSION ${VERSION_STRING})
-SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
+set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake )
 
 # CMake
 if("${CMAKE_BUILD_TYPE}" STREQUAL "")
@@ -141,7 +141,7 @@ endif(DOCUMENTATION AND DOXYGEN_FOUND)
 
 add_subdirectory(src)
 add_subdirectory(ftdipp)
-add_subdirectory(bindings)
+add_subdirectory(python)
 add_subdirectory(ftdi_eeprom)
 add_subdirectory(examples)
 add_subdirectory(packages)
diff --git a/FindUSB1.cmake b/FindUSB1.cmake
deleted file mode 100644
index ebcac99..0000000
--- a/FindUSB1.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
-# - Try to find the freetype library
-# Once done this defines
-#
-#  LIBUSB_FOUND - system has libusb
-#  LIBUSB_INCLUDE_DIR - the libusb include directory
-#  LIBUSB_LIBRARIES - Link these to use libusb
-
-# Copyright (c) 2006, 2008  Laurent Montel, <montel@xxxxxxx>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-
-if (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
-
-  # in cache already
-  set(LIBUSB_FOUND TRUE)
-
-else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
-  IF (NOT WIN32)
-    # use pkg-config to get the directories and then use these values
-    # in the FIND_PATH() and FIND_LIBRARY() calls
-    find_package(PkgConfig)
-    pkg_check_modules(PC_LIBUSB libusb-1.0)
-  ENDIF(NOT WIN32)
-
-  FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
-    PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
-
-  FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0
-    PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
-
-  include(FindPackageHandleStandardArgs)
-  FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES 
LIBUSB_INCLUDE_DIR)
-
-  MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
-
-endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt
deleted file mode 100644
index 0c335c8..0000000
--- a/bindings/CMakeLists.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-option ( PYTHON_BINDINGS "Build python bindings via swig" ON )
-
-if ( PYTHON_BINDINGS )
-  find_package ( SWIG )
-  find_package ( PythonLibs )
-  find_package ( PythonInterp )
-endif ()
-
-if ( SWIG_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND )
-  include ( UseSWIG )
-  include_directories ( BEFORE ${CMAKE_SOURCE_DIR}/src )
-  include_directories ( ${PYTHON_INCLUDE_DIRS} )
-  link_directories ( ${CMAKE_CURRENT_BINARY_DIR}/../src )
-
-  swig_add_module ( ftdi1 python ftdi1.i )
-  swig_link_libraries ( ftdi1 ftdi1 )
-
-  # do not link python modules on debian
-  # 
http://www.debian.org/doc/packaging-manuals/python-policy/ch-module_packages.html
-  if ( NOT UNIX OR ( UNIX AND NOT EXISTS "/etc/debian_version" ) )
-    swig_link_libraries ( ftdi1 ${PYTHON_LIBRARIES} )
-  endif ()
-
-  execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import sys; print( 
'%d.%d' % ( sys.version_info[0], sys.version_info[1] ) )"
-                    OUTPUT_VARIABLE PYTHON_VERSION
-                    OUTPUT_STRIP_TRAILING_WHITESPACE )
-
-  set ( SITEPACKAGE lib${LIB_SUFFIX}/python${PYTHON_VERSION}/site-packages )
-
-  INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/_ftdi1.so DESTINATION 
${SITEPACKAGE} )
-  INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/ftdi1.py DESTINATION 
${SITEPACKAGE} )
-
-  if ( DOCUMENTATION AND DOXYGEN_FOUND )
-
-      set(CMAKE_SWIG_FLAGS -DDOXYGEN=${DOXYGEN_FOUND})
-
-      # Run doxygen to only generate the xml
-      add_custom_command ( OUTPUT ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml
-          COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc
-          COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile.xml
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          DEPENDS ${c_headers};${c_sources};${cpp_sources};${cpp_headers}
-      )
-
-      # generate .i from doxygen .xml
-      add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i
-          COMMAND ${PYTHON_EXECUTABLE} 
${CMAKE_CURRENT_SOURCE_DIR}/doxy2swig.py -n
-              ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml
-              ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i
-          DEPENDS ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml
-      )
-      add_custom_target ( doc_i DEPENDS 
${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i )
-      add_dependencies( ${SWIG_MODULE_ftdi1_REAL_NAME} doc_i )
-
-  endif ()
-  
-  set ( LIBFTDI_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX}/${SITEPACKAGE} )
-  set ( LIBFTDI_PYTHON_MODULE_PATH ${LIBFTDI_PYTHON_MODULE_PATH} PARENT_SCOPE 
) # for ftdiconfig.cmake
-  message(STATUS "Building python bindings via swig. Will be installed under 
${LIBFTDI_PYTHON_MODULE_PATH}")
-else ()
-  message(STATUS "Not building python bindings")
-endif ()
diff --git a/bindings/doxy2swig.py b/bindings/doxy2swig.py
deleted file mode 100644
index cf4c52b..0000000
--- a/bindings/doxy2swig.py
+++ /dev/null
@@ -1,451 +0,0 @@
-#!/usr/bin/env python
-"""Doxygen XML to SWIG docstring converter.
-
-Usage:
-
-  doxy2swig.py [options] input.xml output.i
-
-Converts Doxygen generated XML files into a file containing docstrings
-that can be used by SWIG-1.3.x.  Note that you need to get SWIG
-version > 1.3.23 or use Robin Dunn's docstring patch to be able to use
-the resulting output.
-
-input.xml is your doxygen generated XML file and output.i is where the
-output will be written (the file will be clobbered).
-
-"""
-######################################################################
-#
-# This code is implemented using Mark Pilgrim's code as a guideline:
-#   http://www.faqs.org/docs/diveintopython/kgp_divein.html
-#
-# Author: Prabhu Ramachandran
-# License: BSD style
-#
-# Thanks:
-#   Johan Hake:  the include_function_definition feature
-#   Bill Spotz:  bug reports and testing.
-#   Sebastian Henschel:   Misc. enhancements.
-#
-######################################################################
-
-from xml.dom import minidom
-import re
-import textwrap
-import sys
-import os.path
-import optparse
-
-
-def my_open_read(source):
-    if hasattr(source, "read"):
-        return source
-    else:
-        return open(source)
-
-def my_open_write(dest):
-    if hasattr(dest, "write"):
-        return dest
-    else:
-        return open(dest, 'w')
-
-
-class Doxy2SWIG:    
-    """Converts Doxygen generated XML files into a file containing
-    docstrings that can be used by SWIG-1.3.x that have support for
-    feature("docstring").  Once the data is parsed it is stored in
-    self.pieces.
-
-    """    
-    
-    def __init__(self, src, include_function_definition=True, quiet=False):
-        """Initialize the instance given a source object.  `src` can
-        be a file or filename.  If you do not want to include function
-        definitions from doxygen then set
-        `include_function_definition` to `False`.  This is handy since
-        this allows you to use the swig generated function definition
-        using %feature("autodoc", [0,1]).
-
-        """
-        f = my_open_read(src)
-        self.my_dir = os.path.dirname(f.name)
-        self.xmldoc = minidom.parse(f).documentElement
-        f.close()
-
-        self.pieces = []
-        self.pieces.append('\n// File: %s\n'%\
-                           os.path.basename(f.name))
-
-        self.space_re = re.compile(r'\s+')
-        self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)')
-        self.multi = 0
-        self.ignores = ['inheritancegraph', 'param', 'listofallmembers',
-                        'innerclass', 'name', 'declname', 'incdepgraph',
-                        'invincdepgraph', 'programlisting', 'type',
-                        'references', 'referencedby', 'location',
-                        'collaborationgraph', 'reimplements',
-                        'reimplementedby', 'derivedcompoundref',
-                        'basecompoundref']
-        #self.generics = []
-        self.include_function_definition = include_function_definition
-        if not include_function_definition:
-            self.ignores.append('argsstring')
-
-        self.quiet = quiet
-            
-        
-    def generate(self):
-        """Parses the file set in the initialization.  The resulting
-        data is stored in `self.pieces`.
-
-        """
-        self.parse(self.xmldoc)
-    
-    def parse(self, node):
-        """Parse a given node.  This function in turn calls the
-        `parse_<nodeType>` functions which handle the respective
-        nodes.
-
-        """
-        pm = getattr(self, "parse_%s"%node.__class__.__name__)
-        pm(node)
-
-    def parse_Document(self, node):
-        self.parse(node.documentElement)
-
-    def parse_Text(self, node):
-        txt = node.data
-        txt = txt.replace('\\', r'\\\\')
-        txt = txt.replace('"', r'\"')
-        # ignore pure whitespace
-        m = self.space_re.match(txt)
-        if m and len(m.group()) == len(txt):
-            pass
-        else:
-            self.add_text(textwrap.fill(txt, break_long_words=False))
-
-    def parse_Element(self, node):
-        """Parse an `ELEMENT_NODE`.  This calls specific
-        `do_<tagName>` handers for different elements.  If no handler
-        is available the `generic_parse` method is called.  All
-        tagNames specified in `self.ignores` are simply ignored.
-        
-        """
-        name = node.tagName
-        ignores = self.ignores
-        if name in ignores:
-            return
-        attr = "do_%s" % name
-        if hasattr(self, attr):
-            handlerMethod = getattr(self, attr)
-            handlerMethod(node)
-        else:
-            self.generic_parse(node)
-            #if name not in self.generics: self.generics.append(name)
-
-    def parse_Comment(self, node):
-        """Parse a `COMMENT_NODE`.  This does nothing for now."""
-        return
-
-    def add_text(self, value):
-        """Adds text corresponding to `value` into `self.pieces`."""
-        if isinstance(value, (list, tuple)):
-            self.pieces.extend(value)
-        else:
-            self.pieces.append(value)
-
-    def get_specific_nodes(self, node, names):
-        """Given a node and a sequence of strings in `names`, return a
-        dictionary containing the names as keys and child
-        `ELEMENT_NODEs`, that have a `tagName` equal to the name.
-
-        """
-        nodes = [(x.tagName, x) for x in node.childNodes \
-                 if x.nodeType == x.ELEMENT_NODE and \
-                 x.tagName in names]
-        return dict(nodes)
-
-    def generic_parse(self, node, pad=0):
-        """A Generic parser for arbitrary tags in a node.
-
-        Parameters:
-
-         - node:  A node in the DOM.
-         - pad: `int` (default: 0)
-
-           If 0 the node data is not padded with newlines.  If 1 it
-           appends a newline after parsing the childNodes.  If 2 it
-           pads before and after the nodes are processed.  Defaults to
-           0.
-
-        """
-        npiece = 0
-        if pad:
-            npiece = len(self.pieces)
-            if pad == 2:
-                self.add_text('\n')                
-        for n in node.childNodes:
-            self.parse(n)
-        if pad:
-            if len(self.pieces) > npiece:
-                self.add_text('\n')
-
-    def space_parse(self, node):
-        self.add_text(' ')
-        self.generic_parse(node)
-
-    do_ref = space_parse
-    do_emphasis = space_parse
-    do_bold = space_parse
-    do_computeroutput = space_parse
-    do_formula = space_parse
-
-    def do_compoundname(self, node):
-        self.add_text('\n\n')
-        data = node.firstChild.data
-        self.add_text('%%feature("docstring") %s "\n'%data)
-
-    def do_compounddef(self, node):
-        kind = node.attributes['kind'].value
-        if kind in ('class', 'struct'):
-            prot = node.attributes['prot'].value
-            if prot != 'public':
-                return
-            names = ('compoundname', 'briefdescription',
-                     'detaileddescription', 'includes')
-            first = self.get_specific_nodes(node, names)
-            for n in names:
-                if first.has_key(n):
-                    self.parse(first[n])
-            self.add_text(['";','\n'])
-            for n in node.childNodes:
-                if n not in first.values():
-                    self.parse(n)
-        elif kind in ('file', 'namespace'):
-            nodes = node.getElementsByTagName('sectiondef')
-            for n in nodes:
-                self.parse(n)
-
-    def do_includes(self, node):
-        self.add_text('C++ includes: ')
-        self.generic_parse(node, pad=1)
-
-    def do_parameterlist(self, node):
-        text='unknown'
-        for key, val in node.attributes.items():
-            if key == 'kind':
-                if val == 'param': text = 'Parameters'
-                elif val == 'exception': text = 'Exceptions'
-                elif val == 'retval': text = 'Returns'
-                else: text = val
-                break
-        self.add_text(['\n', '\n', text, ':', '\n'])
-        self.generic_parse(node, pad=1)
-
-    def do_para(self, node):
-        self.add_text('\n')
-        self.generic_parse(node, pad=1)
-
-    def do_parametername(self, node):
-        self.add_text('\n')
-        try:
-            data=node.firstChild.data
-        except AttributeError: # perhaps a <ref> tag in it
-            data=node.firstChild.firstChild.data
-        if data.find('Exception') != -1:
-            self.add_text(data)
-        else:
-            self.add_text("%s: "%data)
-
-    def do_parameterdefinition(self, node):
-        self.generic_parse(node, pad=1)
-
-    def do_detaileddescription(self, node):
-        self.generic_parse(node, pad=1)
-
-    def do_briefdescription(self, node):
-        self.generic_parse(node, pad=1)
-
-    def do_memberdef(self, node):
-        prot = node.attributes['prot'].value
-        id = node.attributes['id'].value
-        kind = node.attributes['kind'].value
-        tmp = node.parentNode.parentNode.parentNode
-        compdef = tmp.getElementsByTagName('compounddef')[0]
-        cdef_kind = compdef.attributes['kind'].value
-        
-        if prot == 'public':
-            first = self.get_specific_nodes(node, ('definition', 'name'))
-            name = first['name'].firstChild.data
-            if name[:8] == 'operator': # Don't handle operators yet.
-                return
-
-            if not 'definition' in first or \
-                   kind in ['variable', 'typedef']:
-                return
-
-            if self.include_function_definition:
-                defn = first['definition'].firstChild.data
-            else:
-                defn = ""
-            self.add_text('\n')
-            self.add_text('%feature("docstring") ')
-            
-            anc = node.parentNode.parentNode
-            if cdef_kind in ('file', 'namespace'):
-                ns_node = anc.getElementsByTagName('innernamespace')
-                if not ns_node and cdef_kind == 'namespace':
-                    ns_node = anc.getElementsByTagName('compoundname')
-                if ns_node:
-                    ns = ns_node[0].firstChild.data
-                    self.add_text(' %s::%s "\n%s'%(ns, name, defn))
-                else:
-                    self.add_text(' %s "\n%s'%(name, defn))
-            elif cdef_kind in ('class', 'struct'):
-                # Get the full function name.
-                anc_node = anc.getElementsByTagName('compoundname')
-                cname = anc_node[0].firstChild.data
-                self.add_text(' %s::%s "\n%s'%(cname, name, defn))
-
-            for n in node.childNodes:
-                if n not in first.values():
-                    self.parse(n)
-            self.add_text(['";', '\n'])
-        
-    def do_definition(self, node):
-        data = node.firstChild.data
-        self.add_text('%s "\n%s'%(data, data))
-
-    def do_sectiondef(self, node):
-        kind = node.attributes['kind'].value
-        if kind in ('public-func', 'func', 'user-defined', ''):
-            self.generic_parse(node)
-
-    def do_header(self, node):
-        """For a user defined section def a header field is present
-        which should not be printed as such, so we comment it in the
-        output."""
-        data = node.firstChild.data
-        self.add_text('\n/*\n %s \n*/\n'%data)
-        # If our immediate sibling is a 'description' node then we
-        # should comment that out also and remove it from the parent
-        # node's children.
-        parent = node.parentNode
-        idx = parent.childNodes.index(node)
-        if len(parent.childNodes) >= idx + 2:
-            nd = parent.childNodes[idx+2]
-            if nd.nodeName == 'description':
-                nd = parent.removeChild(nd)
-                self.add_text('\n/*')
-                self.generic_parse(nd)
-                self.add_text('\n*/\n')
-
-    def do_simplesect(self, node):
-        kind = node.attributes['kind'].value
-        if kind in ('date', 'rcs', 'version'):
-            pass
-        elif kind == 'warning':
-            self.add_text(['\n', 'WARNING: '])
-            self.generic_parse(node)
-        elif kind == 'see':
-            self.add_text('\n')
-            self.add_text('See: ')
-            self.generic_parse(node)
-        else:
-            self.generic_parse(node)
-
-    def do_argsstring(self, node):
-        self.generic_parse(node, pad=1)
-
-    def do_member(self, node):
-        kind = node.attributes['kind'].value
-        refid = node.attributes['refid'].value
-        if kind == 'function' and refid[:9] == 'namespace':
-            self.generic_parse(node)
-
-    def do_doxygenindex(self, node):
-        self.multi = 1
-        comps = node.getElementsByTagName('compound')
-        for c in comps:
-            refid = c.attributes['refid'].value
-            fname = refid + '.xml'
-            if not os.path.exists(fname):
-                fname = os.path.join(self.my_dir,  fname)
-            if not self.quiet:
-                print( "parsing file: %s"%fname )
-            p = Doxy2SWIG(fname, self.include_function_definition, self.quiet)
-            p.generate()
-            self.pieces.extend(self.clean_pieces(p.pieces))
-
-    def write(self, fname):
-        o = my_open_write(fname)
-        if self.multi:
-            o.write("".join(self.pieces))
-        else:
-            o.write("".join(self.clean_pieces(self.pieces)))
-        o.close()
-
-    def clean_pieces(self, pieces):
-        """Cleans the list of strings given as `pieces`.  It replaces
-        multiple newlines by a maximum of 2 and returns a new list.
-        It also wraps the paragraphs nicely.
-        
-        """
-        ret = []
-        count = 0
-        for i in pieces:
-            if i == '\n':
-                count = count + 1
-            else:
-                if i == '";':
-                    if count:
-                        ret.append('\n')
-                elif count > 2:
-                    ret.append('\n\n')
-                elif count:
-                    ret.append('\n'*count)
-                count = 0
-                ret.append(i)
-
-        _data = "".join(ret)
-        ret = []
-        for i in _data.split('\n\n'):
-            if i == 'Parameters:' or i == 'Exceptions:' or i == 'Returns:':
-                ret.extend([i, '\n'+'-'*len(i), '\n\n'])
-            elif i.find('// File:') > -1: # leave comments alone.
-                ret.extend([i, '\n'])
-            else:
-                _tmp = textwrap.fill(i.strip(), break_long_words=False)
-                _tmp = self.lead_spc.sub(r'\1"\2', _tmp)
-                ret.extend([_tmp, '\n\n'])
-        return ret
-
-
-def convert(input, output, include_function_definition=True, quiet=False):
-    p = Doxy2SWIG(input, include_function_definition, quiet)
-    p.generate()
-    p.write(output)
-
-def main():
-    usage = __doc__
-    parser = optparse.OptionParser(usage)
-    parser.add_option("-n", '--no-function-definition',
-                      action='store_true',
-                      default=False,
-                      dest='func_def',
-                      help='do not include doxygen function definitions')
-    parser.add_option("-q", '--quiet',
-                      action='store_true',
-                      default=False,
-                      dest='quiet',
-                      help='be quiet and minimize output')
-    
-    options, args = parser.parse_args()
-    if len(args) != 2:
-        parser.error("error: no input and output specified")
-
-    convert(args[0], args[1], not options.func_def, options.quiet)
-    
-
-if __name__ == '__main__':
-    main()
diff --git a/bindings/ftdi1.i b/bindings/ftdi1.i
deleted file mode 100644
index 1e820dd..0000000
--- a/bindings/ftdi1.i
+++ /dev/null
@@ -1,138 +0,0 @@
-/* File: ftdi1.i */
-
-%module(docstring="Python interface to libftdi1") ftdi1
-%feature("autodoc","1");
-
-#ifdef DOXYGEN
-%include "ftdi1_doc.i"
-#endif
-
-%{
-#include "Python.h"
-
-PyObject* convertString( const char *v, Py_ssize_t len )
-{
-#if PY_MAJOR_VERSION >= 3
-  return PyBytes_FromStringAndSize(v, len);
-#else
-  return PyString_FromStringAndSize(v, len);
-#endif
-}
-%}
-
-%include <typemaps.i>
-%include <cstring.i>
-
-%typemap(in) unsigned char* = char*;
-
-%immutable ftdi_version_info::version_str;
-%immutable ftdi_version_info::snapshot_str;
-
-%rename("%(strip:[ftdi_])s") "";
-
-%newobject ftdi_new;
-%typemap(newfree) struct ftdi_context *ftdi "ftdi_free($1);";
-%delobject ftdi_free;
-
-%define ftdi_usb_find_all_docstring
-"usb_find_all(context, vendor, product) -> (return_code, devlist)"
-%enddef
-%feature("autodoc", ftdi_usb_find_all_docstring) ftdi_usb_find_all;
-%typemap(in,numinputs=0) SWIGTYPE** OUTPUT ($*ltype temp) %{ $1 = &temp; %}
-%typemap(argout) SWIGTYPE** OUTPUT %{ $result = 
SWIG_Python_AppendOutput($result, 
SWIG_NewPointerObj((void*)*$1,$*descriptor,0)); %}
-%apply SWIGTYPE** OUTPUT { struct ftdi_device_list **devlist };
-    int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list 
**devlist,
-                          int vendor, int product);
-%clear struct ftdi_device_list **devlist;
-
-%define ftdi_usb_get_strings_docstring
-"usb_get_strings(context, device) -> (return_code, manufacturer, description, 
serial)"
-%enddef
-%feature("autodoc", ftdi_usb_get_strings_docstring) ftdi_usb_get_strings;
-%apply char *OUTPUT { char * manufacturer, char * description, char * serial };
-%cstring_bounded_output( char * manufacturer, 256 );
-%cstring_bounded_output( char * description, 256 );
-%cstring_bounded_output( char * serial, 256 );
-%typemap(default,noblock=1) int mnf_len, int desc_len, int serial_len { $1 = 
256; }
-    int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct libusb_device 
*dev,
-                             char * manufacturer, int mnf_len,
-                             char * description, int desc_len,
-                             char * serial, int serial_len);
-%clear char * manufacturer, char * description, char * serial;
-%clear int mnf_len, int desc_len, int serial_len;
-
-%define ftdi_read_data_docstring
-"read_data(context) -> (return_code, buf)"
-%enddef
-%feature("autodoc", ftdi_read_data_docstring) ftdi_read_data;
-%typemap(in,numinputs=1) (unsigned char *buf, int size) %{ $2 = 
PyInt_AsLong($input);$1 = (unsigned char*)malloc($2*sizeof(char)); %}
-%typemap(argout) (unsigned char *buf, int size) %{ if(result<0) $2=0; $result 
= SWIG_Python_AppendOutput($result, convertString((char*)$1, $2)); free($1); %}
-    int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int 
size);
-%clear (unsigned char *buf, int size);
-
-%apply int *OUTPUT { unsigned int *chunksize };
-    int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int 
*chunksize);
-    int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int 
*chunksize);
-%clear unsigned int *chunksize;
-
-%define ftdi_read_pins_docstring
-"read_pins(context) -> (return_code, pins)"
-%enddef
-%feature("autodoc", ftdi_read_pins_docstring) ftdi_read_pins;
-%typemap(in,numinputs=0) unsigned char *pins ($*ltype temp) %{ $1 = &temp; %}
-%typemap(argout) (unsigned char *pins) %{ $result = 
SWIG_Python_AppendOutput($result, convertString((char*)$1, 1)); %}
-    int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins);
-%clear unsigned char *pins;
-
-%typemap(in,numinputs=0) unsigned char *latency ($*ltype temp) %{ $1 = &temp; 
%}
-%typemap(argout) (unsigned char *latency) %{ $result = 
SWIG_Python_AppendOutput($result, convertString((char*)$1, 1)); %}
-    int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char 
*latency);
-%clear unsigned char *latency;
-
-%apply short *OUTPUT { unsigned short *status };
-    int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short 
*status);
-%clear unsigned short *status;
-
-%apply int *OUTPUT { int* value };
-    int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum 
ftdi_eeprom_value value_name, int* value);
-%clear int* value;
-
-%typemap(in,numinputs=1) (unsigned char *buf, int size) %{ $2 = 
PyInt_AsLong($input);$1 = (unsigned char*)malloc($2*sizeof(char)); %}
-%typemap(argout) (unsigned char *buf, int size) %{ if(result<0) $2=0; $result 
= SWIG_Python_AppendOutput($result, convertString((char*)$1, $2)); free($1); %}
-    int ftdi_get_eeprom_buf(struct ftdi_context *ftdi, unsigned char * buf, 
int size);
-%clear (unsigned char *buf, int size);
-
-%define ftdi_read_eeprom_location_docstring
-"read_eeprom_location(context, eeprom_addr) -> (return_code, eeprom_val)"
-%enddef
-%feature("autodoc", ftdi_read_eeprom_location_docstring) 
ftdi_read_eeprom_location;
-%apply short *OUTPUT { unsigned short *eeprom_val };
-    int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, 
unsigned short *eeprom_val);
-%clear unsigned short *eeprom_val;
-
-%define ftdi_read_eeprom_docstring
-"read_eeprom(context) -> (return_code, eeprom)"
-%enddef
-%feature("autodoc", ftdi_read_eeprom_docstring) ftdi_read_eeprom;
-
-%define ftdi_read_chipid_docstring
-"ftdi_read_chipid(context) -> (return_code, chipid)"
-%enddef
-%feature("autodoc", ftdi_read_chipid_docstring) ftdi_read_chipid;
-%apply int *OUTPUT { unsigned int *chipid };
-    int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid);
-%clear unsigned int *chipid;
-
-%include ftdi.h
-%{
-#include <ftdi.h>
-%}
-
-%include ftdi_i.h
-%{
-#include <ftdi_i.h>
-%}
-
-%pythoncode %{
-__version__ = get_library_version().version_str
-%}
diff --git a/cmake/FindConfuse.cmake b/cmake/FindConfuse.cmake
new file mode 100644
index 0000000..ab25eef
--- /dev/null
+++ b/cmake/FindConfuse.cmake
@@ -0,0 +1,74 @@
+# libConfuse is a configuration file parser library
+# available at http://www.nongnu.org/confuse/
+#
+# The module defines the following variables:
+#  CONFUSE_FOUND - the system has Confuse
+#  CONFUSE_INCLUDE_DIR - where to find confuse.h
+#  CONFUSE_INCLUDE_DIRS - confuse includes
+#  CONFUSE_LIBRARY - where to find the Confuse library
+#  CONFUSE_LIBRARIES - aditional libraries
+#  CONFUSE_ROOT_DIR - root dir (ex. /usr/local)
+
+#=============================================================================
+# Copyright 2010-2013, Julien Schueller
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met: 
+# 
+# 1. Redistributions of source code must retain the above copyright notice, 
this
+#    list of conditions and the following disclaimer. 
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# The views and conclusions contained in the software and documentation are 
those
+# of the authors and should not be interpreted as representing official 
policies, 
+# either expressed or implied, of the FreeBSD Project.
+#=============================================================================
+
+
+find_path ( CONFUSE_INCLUDE_DIR
+  NAMES confuse.h
+)
+
+set ( CONFUSE_INCLUDE_DIRS ${CONFUSE_INCLUDE_DIR} )
+
+find_library ( CONFUSE_LIBRARY
+  NAMES confuse
+)
+
+set ( CONFUSE_LIBRARIES ${CONFUSE_LIBRARY} )
+
+
+# try to guess root dir from include dir
+if ( CONFUSE_INCLUDE_DIR )
+  string ( REGEX REPLACE "(.*)/include.*" "\\1" CONFUSE_ROOT_DIR 
${CONFUSE_INCLUDE_DIR} )
+# try to guess root dir from library dir
+elseif ( CONFUSE_LIBRARY )
+  string ( REGEX REPLACE "(.*)/lib[/|32|64].*" "\\1" CONFUSE_ROOT_DIR 
${CONFUSE_LIBRARY} )
+endif ()
+
+
+# handle the QUIETLY and REQUIRED arguments
+include ( FindPackageHandleStandardArgs )
+find_package_handle_standard_args( Confuse DEFAULT_MSG CONFUSE_LIBRARY 
CONFUSE_INCLUDE_DIR  )
+
+mark_as_advanced (
+  CONFUSE_LIBRARY 
+  CONFUSE_LIBRARIES
+  CONFUSE_INCLUDE_DIR
+  CONFUSE_INCLUDE_DIRS
+  CONFUSE_ROOT_DIR
+)
diff --git a/cmake/FindUSB1.cmake b/cmake/FindUSB1.cmake
new file mode 100644
index 0000000..ebcac99
--- /dev/null
+++ b/cmake/FindUSB1.cmake
@@ -0,0 +1,38 @@
+# - Try to find the freetype library
+# Once done this defines
+#
+#  LIBUSB_FOUND - system has libusb
+#  LIBUSB_INCLUDE_DIR - the libusb include directory
+#  LIBUSB_LIBRARIES - Link these to use libusb
+
+# Copyright (c) 2006, 2008  Laurent Montel, <montel@xxxxxxx>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+if (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
+
+  # in cache already
+  set(LIBUSB_FOUND TRUE)
+
+else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
+  IF (NOT WIN32)
+    # use pkg-config to get the directories and then use these values
+    # in the FIND_PATH() and FIND_LIBRARY() calls
+    find_package(PkgConfig)
+    pkg_check_modules(PC_LIBUSB libusb-1.0)
+  ENDIF(NOT WIN32)
+
+  FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
+    PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
+
+  FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0
+    PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
+
+  include(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES 
LIBUSB_INCLUDE_DIR)
+
+  MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
+
+endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
diff --git a/examples/python/complete.py b/examples/python/complete.py
deleted file mode 100644
index afa59fa..0000000
--- a/examples/python/complete.py
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""Python example program.
-
-Complete program to demonstrate the usage
-of the swig generated python wrapper
-
-You need to build and install the wrapper first"""
-
-import os
-import sys
-import ftdi1 as ftdi
-import time
-
-# version
-print ( 'version: %s\n' % ftdi.__version__  )
-
-# initialize
-ftdic = ftdi.new()
-if ftdic == 0:
-    print( 'new failed: %d' % ret )
-    os._exit( 1 )
-
-# try to list ftdi devices 0x6010 or 0x6001
-ret, devlist = ftdi.usb_find_all( ftdic, 0x0403, 0x6010 )
-if ret <= 0:
-    ret, devlist = ftdi.usb_find_all( ftdic, 0x0403, 0x6001)
-
-if ret < 0:
-    print( 'ftdi_usb_find_all failed: %d (%s)' % ( ret, ftdi.get_error_string( 
ftdic ) ) )
-    os._exit( 1 )
-print( 'devices: %d' % ret )
-curnode = devlist
-i = 0
-while( curnode != None ):
-    ret, manufacturer, description, serial = ftdi.usb_get_strings( ftdic, 
curnode.dev )
-    if ret < 0:
-        print( 'ftdi_usb_get_strings failed: %d (%s)' % ( ret, 
ftdi.get_error_string( ftdic ) ) )
-        os._exit( 1 )
-    print( '#%d: manufacturer="%s" description="%s" serial="%s"\n' % ( i, 
manufacturer, description, serial ) )
-    curnode = curnode.next
-    i += 1
-
-# open usb
-ret = ftdi.usb_open( ftdic, 0x0403, 0x6001 )
-if ret < 0:
-    print( 'unable to open ftdi device: %d (%s)' % ( ret, 
ftdi.get_error_string( ftdic ) ) )
-    os._exit( 1 )
-
-
-# bitbang
-ret = ftdi.set_bitmode( ftdic, 0xff, ftdi.BITMODE_BITBANG )
-if ret < 0:
-    print( 'Cannot enable bitbang' )
-    os._exit( 1 )
-print( 'turning everything on' )
-ftdi.write_data( ftdic, chr(0xff), 1 )
-time.sleep( 1 )
-print( 'turning everything off\n' )
-ftdi.write_data( ftdic, chr(0x00), 1 )
-time.sleep( 1 )
-for i in range( 8 ):
-    val = 2**i
-    print( 'enabling bit #%d (0x%02x)' % (i, val) )
-    ftdi.write_data( ftdic, chr(val), 1 )
-    time.sleep ( 1 )
-ftdi.disable_bitbang( ftdic )
-print( '' )
-
-
-# read pins
-ret, pins = ftdi.read_pins( ftdic )
-if ( ret == 0 ):
-    if sys.version_info[0] < 3: # python 2
-        pins = ord( pins )
-    else:
-        pins = pins[0]
-    print( 'pins: 0x%x' % pins )
-              
-
-# read chip id
-ret, chipid = ftdi.read_chipid( ftdic )
-if (ret==0):
-    print( 'chip id: %x\n' % chipid )
-
-
-# read eeprom
-eeprom_addr = 1
-ret, eeprom_val = ftdi.read_eeprom_location( ftdic, eeprom_addr )
-if (ret==0):
-    print( 'eeprom @ %d: 0x%04x\n' % ( eeprom_addr, eeprom_val ) )
-
-print( 'eeprom:' )
-ret = ftdi.read_eeprom( ftdic )
-size = 128
-ret, eeprom = ftdi.get_eeprom_buf ( ftdic, size )
-if ( ret == 0 ):
-    for i in range( size ):
-        octet = eeprom[i]
-        if sys.version_info[0] < 3: # python 2
-            octet = ord( octet )
-        sys.stdout.write( '%02x ' % octet )
-        if ( i % 8 == 7 ):
-            print( '' )
-print( '' )
-            
-# close usb
-ret = ftdi.usb_close( ftdic )
-if ret < 0:
-    print( 'unable to close ftdi device: %d (%s)' % ( ret, 
ftdi.get_error_string( ftdic ) ) )
-    os._exit( 1 )
-    
-print ('device closed')    
-ftdi.free( ftdic )
diff --git a/examples/python/simple.py b/examples/python/simple.py
deleted file mode 100644
index 9298c24..0000000
--- a/examples/python/simple.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""Python example program.
-
-Small program to demonstrate the usage
-of the swig generated python wrapper
-
-You need to build and install the wrapper first"""
-
-import ftdi1 as ftdi
-
-def main():
-    """Main program"""
-    context = ftdi.new()
-
-    version_info = ftdi.get_library_version()
-    print("[FTDI version] major: %d, minor: %d, micro: %d" \
-               ", version_str: %s, snapshot_str: %s" %
-               (version_info.major, version_info.minor, version_info.micro,
-               version_info.version_str, version_info.snapshot_str))
-
-    # try to open an ftdi 0x6010 or 0x6001
-    ret = ftdi.usb_open(context, 0x0403, 0x6010)
-    if ret < 0:
-        ret = ftdi.usb_open(context, 0x0403, 0x6001)
-        
-    print("ftdi.usb_open(): %d" % ret)
-    print("ftdi.set_baudrate(): %d" % ftdi.set_baudrate(context, 9600))
-
-    ftdi.free(context)
-
-main()
diff --git a/ftdi_eeprom/CMakeLists.txt b/ftdi_eeprom/CMakeLists.txt
index a843b8e..573b8ec 100644
--- a/ftdi_eeprom/CMakeLists.txt
+++ b/ftdi_eeprom/CMakeLists.txt
@@ -1,43 +1,39 @@
-set(FTDI_BUILD_EEPROM False PARENT_SCOPE)
 
 option(FTDI_EEPROM "Build ftdi_eeprom" ON)
 
-if (FTDI_EEPROM)
-    include(FindPkgConfig)
-    pkg_check_modules(Confuse libconfuse)
-    INCLUDE_DIRECTORIES(${Confuse_INCLUDE_DIRS})
-    LINK_DIRECTORIES(${Confuse_LIBRARY_DIRS})
-    SET(libs ${libs} ${Confuse_LIBRARIES})
+if ( FTDI_EEPROM )
+  find_package ( Confuse )
+else(FTDI_EEPROM)
+  message(STATUS "ftdi_eeprom build is disabled")
+endif ()
 
-    if(Confuse_FOUND)
-        set(FTDI_BUILD_EEPROM True PARENT_SCOPE)
-        message(STATUS "Building ftdi_eeprom")
 
-        # Version defines
-        set(EEPROM_MAJOR_VERSION 0)
-        set(EEPROM_MINOR_VERSION 17)
-        set(EEPROM_VERSION_STRING 
${EEPROM_MAJOR_VERSION}.${EEPROM_MINOR_VERSION})
+if ( CONFUSE_FOUND )
+  message(STATUS "Building ftdi_eeprom")
 
-        include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src)
-        include_directories(BEFORE ${CMAKE_BINARY_DIR}/ftdi_eeprom)
+  include_directories ( ${CONFUSE_INCLUDE_DIRS} )
 
-        configure_file(
-          "ftdi_eeprom_version.h.in"
-          "${CMAKE_BINARY_DIR}/ftdi_eeprom/ftdi_eeprom_version.h"
-        )
+  list ( APPEND libs ${CONFUSE_LIBRARIES} )
 
-        add_executable(ftdi_eeprom main.c)
-        target_link_libraries(ftdi_eeprom ftdi1)
-        target_link_libraries(ftdi_eeprom ${Confuse_LIBRARIES})
+  # Version defines
+  set ( EEPROM_MAJOR_VERSION 0 )
+  set ( EEPROM_MINOR_VERSION 17 )
+  set ( EEPROM_VERSION_STRING ${EEPROM_MAJOR_VERSION}.${EEPROM_MINOR_VERSION} )
 
-        install(TARGETS ftdi_eeprom DESTINATION bin)
+  include_directories ( BEFORE ${CMAKE_SOURCE_DIR}/src )
+  include_directories ( BEFORE ${CMAKE_CURRENT_BINARY_DIR} )
 
-    else(Confuse_FOUND)
-        message(STATUS "libConfuse not found, won't build ftdi_eeprom")
-    endif(Confuse_FOUND)
+  configure_file(
+    ftdi_eeprom_version.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/ftdi_eeprom_version.h
+  )
 
-else(FTDI_EEPROM)
+  add_executable ( ftdi_eeprom main.c )
+  target_link_libraries ( ftdi_eeprom ftdi1 )
+  target_link_libraries ( ftdi_eeprom ${CONFUSE_LIBRARIES} )
 
-    message(STATUS "ftdi_eeprom build is disabled")
+  install ( TARGETS ftdi_eeprom DESTINATION bin )
+else ()
+  message ( STATUS "libConfuse not found, won't build ftdi_eeprom" )
+endif ()
 
-endif(FTDI_EEPROM)
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
new file mode 100644
index 0000000..5a61bc1
--- /dev/null
+++ b/python/CMakeLists.txt
@@ -0,0 +1,64 @@
+option ( PYTHON_BINDINGS "Build python bindings via swig" ON )
+
+if ( PYTHON_BINDINGS )
+  find_package ( SWIG )
+  find_package ( PythonLibs )
+  find_package ( PythonInterp )
+endif ()
+
+if ( SWIG_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND )
+  include ( UseSWIG )
+  include_directories ( BEFORE ${CMAKE_SOURCE_DIR}/src )
+  include_directories ( ${PYTHON_INCLUDE_DIRS} )
+  link_directories ( ${CMAKE_CURRENT_BINARY_DIR}/../src )
+
+  swig_add_module ( ftdi1 python ftdi1.i )
+  swig_link_libraries ( ftdi1 ftdi1 )
+
+  # do not link python modules on debian
+  # 
http://www.debian.org/doc/packaging-manuals/python-policy/ch-module_packages.html
+  if ( NOT UNIX OR ( UNIX AND NOT EXISTS "/etc/debian_version" ) )
+    swig_link_libraries ( ftdi1 ${PYTHON_LIBRARIES} )
+  endif ()
+
+  execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import sys; print( 
'%d.%d' % ( sys.version_info[0], sys.version_info[1] ) )"
+                    OUTPUT_VARIABLE PYTHON_VERSION
+                    OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+  set ( SITEPACKAGE lib${LIB_SUFFIX}/python${PYTHON_VERSION}/site-packages )
+
+  INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/_ftdi1.so DESTINATION 
${SITEPACKAGE} )
+  INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/ftdi1.py DESTINATION 
${SITEPACKAGE} )
+
+  if ( DOCUMENTATION AND DOXYGEN_FOUND )
+
+      set(CMAKE_SWIG_FLAGS -DDOXYGEN=${DOXYGEN_FOUND})
+
+      # Run doxygen to only generate the xml
+      add_custom_command ( OUTPUT ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml
+          COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc
+          COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile.xml
+          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+          DEPENDS ${c_headers};${c_sources};${cpp_sources};${cpp_headers}
+      )
+
+      # generate .i from doxygen .xml
+      add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i
+          COMMAND ${PYTHON_EXECUTABLE} 
${CMAKE_CURRENT_SOURCE_DIR}/doxy2swig.py -n
+              ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml
+              ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i
+          DEPENDS ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml
+      )
+      add_custom_target ( doc_i DEPENDS 
${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i )
+      add_dependencies( ${SWIG_MODULE_ftdi1_REAL_NAME} doc_i )
+
+  endif ()
+  
+  set ( LIBFTDI_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX}/${SITEPACKAGE} )
+  set ( LIBFTDI_PYTHON_MODULE_PATH ${LIBFTDI_PYTHON_MODULE_PATH} PARENT_SCOPE 
) # for ftdiconfig.cmake
+  message(STATUS "Building python bindings via swig. Will be installed under 
${LIBFTDI_PYTHON_MODULE_PATH}")
+
+  add_subdirectory ( examples )
+else ()
+  message(STATUS "Not building python bindings")
+endif ()
diff --git a/python/doxy2swig.py b/python/doxy2swig.py
new file mode 100644
index 0000000..cf4c52b
--- /dev/null
+++ b/python/doxy2swig.py
@@ -0,0 +1,451 @@
+#!/usr/bin/env python
+"""Doxygen XML to SWIG docstring converter.
+
+Usage:
+
+  doxy2swig.py [options] input.xml output.i
+
+Converts Doxygen generated XML files into a file containing docstrings
+that can be used by SWIG-1.3.x.  Note that you need to get SWIG
+version > 1.3.23 or use Robin Dunn's docstring patch to be able to use
+the resulting output.
+
+input.xml is your doxygen generated XML file and output.i is where the
+output will be written (the file will be clobbered).
+
+"""
+######################################################################
+#
+# This code is implemented using Mark Pilgrim's code as a guideline:
+#   http://www.faqs.org/docs/diveintopython/kgp_divein.html
+#
+# Author: Prabhu Ramachandran
+# License: BSD style
+#
+# Thanks:
+#   Johan Hake:  the include_function_definition feature
+#   Bill Spotz:  bug reports and testing.
+#   Sebastian Henschel:   Misc. enhancements.
+#
+######################################################################
+
+from xml.dom import minidom
+import re
+import textwrap
+import sys
+import os.path
+import optparse
+
+
+def my_open_read(source):
+    if hasattr(source, "read"):
+        return source
+    else:
+        return open(source)
+
+def my_open_write(dest):
+    if hasattr(dest, "write"):
+        return dest
+    else:
+        return open(dest, 'w')
+
+
+class Doxy2SWIG:    
+    """Converts Doxygen generated XML files into a file containing
+    docstrings that can be used by SWIG-1.3.x that have support for
+    feature("docstring").  Once the data is parsed it is stored in
+    self.pieces.
+
+    """    
+    
+    def __init__(self, src, include_function_definition=True, quiet=False):
+        """Initialize the instance given a source object.  `src` can
+        be a file or filename.  If you do not want to include function
+        definitions from doxygen then set
+        `include_function_definition` to `False`.  This is handy since
+        this allows you to use the swig generated function definition
+        using %feature("autodoc", [0,1]).
+
+        """
+        f = my_open_read(src)
+        self.my_dir = os.path.dirname(f.name)
+        self.xmldoc = minidom.parse(f).documentElement
+        f.close()
+
+        self.pieces = []
+        self.pieces.append('\n// File: %s\n'%\
+                           os.path.basename(f.name))
+
+        self.space_re = re.compile(r'\s+')
+        self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)')
+        self.multi = 0
+        self.ignores = ['inheritancegraph', 'param', 'listofallmembers',
+                        'innerclass', 'name', 'declname', 'incdepgraph',
+                        'invincdepgraph', 'programlisting', 'type',
+                        'references', 'referencedby', 'location',
+                        'collaborationgraph', 'reimplements',
+                        'reimplementedby', 'derivedcompoundref',
+                        'basecompoundref']
+        #self.generics = []
+        self.include_function_definition = include_function_definition
+        if not include_function_definition:
+            self.ignores.append('argsstring')
+
+        self.quiet = quiet
+            
+        
+    def generate(self):
+        """Parses the file set in the initialization.  The resulting
+        data is stored in `self.pieces`.
+
+        """
+        self.parse(self.xmldoc)
+    
+    def parse(self, node):
+        """Parse a given node.  This function in turn calls the
+        `parse_<nodeType>` functions which handle the respective
+        nodes.
+
+        """
+        pm = getattr(self, "parse_%s"%node.__class__.__name__)
+        pm(node)
+
+    def parse_Document(self, node):
+        self.parse(node.documentElement)
+
+    def parse_Text(self, node):
+        txt = node.data
+        txt = txt.replace('\\', r'\\\\')
+        txt = txt.replace('"', r'\"')
+        # ignore pure whitespace
+        m = self.space_re.match(txt)
+        if m and len(m.group()) == len(txt):
+            pass
+        else:
+            self.add_text(textwrap.fill(txt, break_long_words=False))
+
+    def parse_Element(self, node):
+        """Parse an `ELEMENT_NODE`.  This calls specific
+        `do_<tagName>` handers for different elements.  If no handler
+        is available the `generic_parse` method is called.  All
+        tagNames specified in `self.ignores` are simply ignored.
+        
+        """
+        name = node.tagName
+        ignores = self.ignores
+        if name in ignores:
+            return
+        attr = "do_%s" % name
+        if hasattr(self, attr):
+            handlerMethod = getattr(self, attr)
+            handlerMethod(node)
+        else:
+            self.generic_parse(node)
+            #if name not in self.generics: self.generics.append(name)
+
+    def parse_Comment(self, node):
+        """Parse a `COMMENT_NODE`.  This does nothing for now."""
+        return
+
+    def add_text(self, value):
+        """Adds text corresponding to `value` into `self.pieces`."""
+        if isinstance(value, (list, tuple)):
+            self.pieces.extend(value)
+        else:
+            self.pieces.append(value)
+
+    def get_specific_nodes(self, node, names):
+        """Given a node and a sequence of strings in `names`, return a
+        dictionary containing the names as keys and child
+        `ELEMENT_NODEs`, that have a `tagName` equal to the name.
+
+        """
+        nodes = [(x.tagName, x) for x in node.childNodes \
+                 if x.nodeType == x.ELEMENT_NODE and \
+                 x.tagName in names]
+        return dict(nodes)
+
+    def generic_parse(self, node, pad=0):
+        """A Generic parser for arbitrary tags in a node.
+
+        Parameters:
+
+         - node:  A node in the DOM.
+         - pad: `int` (default: 0)
+
+           If 0 the node data is not padded with newlines.  If 1 it
+           appends a newline after parsing the childNodes.  If 2 it
+           pads before and after the nodes are processed.  Defaults to
+           0.
+
+        """
+        npiece = 0
+        if pad:
+            npiece = len(self.pieces)
+            if pad == 2:
+                self.add_text('\n')                
+        for n in node.childNodes:
+            self.parse(n)
+        if pad:
+            if len(self.pieces) > npiece:
+                self.add_text('\n')
+
+    def space_parse(self, node):
+        self.add_text(' ')
+        self.generic_parse(node)
+
+    do_ref = space_parse
+    do_emphasis = space_parse
+    do_bold = space_parse
+    do_computeroutput = space_parse
+    do_formula = space_parse
+
+    def do_compoundname(self, node):
+        self.add_text('\n\n')
+        data = node.firstChild.data
+        self.add_text('%%feature("docstring") %s "\n'%data)
+
+    def do_compounddef(self, node):
+        kind = node.attributes['kind'].value
+        if kind in ('class', 'struct'):
+            prot = node.attributes['prot'].value
+            if prot != 'public':
+                return
+            names = ('compoundname', 'briefdescription',
+                     'detaileddescription', 'includes')
+            first = self.get_specific_nodes(node, names)
+            for n in names:
+                if first.has_key(n):
+                    self.parse(first[n])
+            self.add_text(['";','\n'])
+            for n in node.childNodes:
+                if n not in first.values():
+                    self.parse(n)
+        elif kind in ('file', 'namespace'):
+            nodes = node.getElementsByTagName('sectiondef')
+            for n in nodes:
+                self.parse(n)
+
+    def do_includes(self, node):
+        self.add_text('C++ includes: ')
+        self.generic_parse(node, pad=1)
+
+    def do_parameterlist(self, node):
+        text='unknown'
+        for key, val in node.attributes.items():
+            if key == 'kind':
+                if val == 'param': text = 'Parameters'
+                elif val == 'exception': text = 'Exceptions'
+                elif val == 'retval': text = 'Returns'
+                else: text = val
+                break
+        self.add_text(['\n', '\n', text, ':', '\n'])
+        self.generic_parse(node, pad=1)
+
+    def do_para(self, node):
+        self.add_text('\n')
+        self.generic_parse(node, pad=1)
+
+    def do_parametername(self, node):
+        self.add_text('\n')
+        try:
+            data=node.firstChild.data
+        except AttributeError: # perhaps a <ref> tag in it
+            data=node.firstChild.firstChild.data
+        if data.find('Exception') != -1:
+            self.add_text(data)
+        else:
+            self.add_text("%s: "%data)
+
+    def do_parameterdefinition(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_detaileddescription(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_briefdescription(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_memberdef(self, node):
+        prot = node.attributes['prot'].value
+        id = node.attributes['id'].value
+        kind = node.attributes['kind'].value
+        tmp = node.parentNode.parentNode.parentNode
+        compdef = tmp.getElementsByTagName('compounddef')[0]
+        cdef_kind = compdef.attributes['kind'].value
+        
+        if prot == 'public':
+            first = self.get_specific_nodes(node, ('definition', 'name'))
+            name = first['name'].firstChild.data
+            if name[:8] == 'operator': # Don't handle operators yet.
+                return
+
+            if not 'definition' in first or \
+                   kind in ['variable', 'typedef']:
+                return
+
+            if self.include_function_definition:
+                defn = first['definition'].firstChild.data
+            else:
+                defn = ""
+            self.add_text('\n')
+            self.add_text('%feature("docstring") ')
+            
+            anc = node.parentNode.parentNode
+            if cdef_kind in ('file', 'namespace'):
+                ns_node = anc.getElementsByTagName('innernamespace')
+                if not ns_node and cdef_kind == 'namespace':
+                    ns_node = anc.getElementsByTagName('compoundname')
+                if ns_node:
+                    ns = ns_node[0].firstChild.data
+                    self.add_text(' %s::%s "\n%s'%(ns, name, defn))
+                else:
+                    self.add_text(' %s "\n%s'%(name, defn))
+            elif cdef_kind in ('class', 'struct'):
+                # Get the full function name.
+                anc_node = anc.getElementsByTagName('compoundname')
+                cname = anc_node[0].firstChild.data
+                self.add_text(' %s::%s "\n%s'%(cname, name, defn))
+
+            for n in node.childNodes:
+                if n not in first.values():
+                    self.parse(n)
+            self.add_text(['";', '\n'])
+        
+    def do_definition(self, node):
+        data = node.firstChild.data
+        self.add_text('%s "\n%s'%(data, data))
+
+    def do_sectiondef(self, node):
+        kind = node.attributes['kind'].value
+        if kind in ('public-func', 'func', 'user-defined', ''):
+            self.generic_parse(node)
+
+    def do_header(self, node):
+        """For a user defined section def a header field is present
+        which should not be printed as such, so we comment it in the
+        output."""
+        data = node.firstChild.data
+        self.add_text('\n/*\n %s \n*/\n'%data)
+        # If our immediate sibling is a 'description' node then we
+        # should comment that out also and remove it from the parent
+        # node's children.
+        parent = node.parentNode
+        idx = parent.childNodes.index(node)
+        if len(parent.childNodes) >= idx + 2:
+            nd = parent.childNodes[idx+2]
+            if nd.nodeName == 'description':
+                nd = parent.removeChild(nd)
+                self.add_text('\n/*')
+                self.generic_parse(nd)
+                self.add_text('\n*/\n')
+
+    def do_simplesect(self, node):
+        kind = node.attributes['kind'].value
+        if kind in ('date', 'rcs', 'version'):
+            pass
+        elif kind == 'warning':
+            self.add_text(['\n', 'WARNING: '])
+            self.generic_parse(node)
+        elif kind == 'see':
+            self.add_text('\n')
+            self.add_text('See: ')
+            self.generic_parse(node)
+        else:
+            self.generic_parse(node)
+
+    def do_argsstring(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_member(self, node):
+        kind = node.attributes['kind'].value
+        refid = node.attributes['refid'].value
+        if kind == 'function' and refid[:9] == 'namespace':
+            self.generic_parse(node)
+
+    def do_doxygenindex(self, node):
+        self.multi = 1
+        comps = node.getElementsByTagName('compound')
+        for c in comps:
+            refid = c.attributes['refid'].value
+            fname = refid + '.xml'
+            if not os.path.exists(fname):
+                fname = os.path.join(self.my_dir,  fname)
+            if not self.quiet:
+                print( "parsing file: %s"%fname )
+            p = Doxy2SWIG(fname, self.include_function_definition, self.quiet)
+            p.generate()
+            self.pieces.extend(self.clean_pieces(p.pieces))
+
+    def write(self, fname):
+        o = my_open_write(fname)
+        if self.multi:
+            o.write("".join(self.pieces))
+        else:
+            o.write("".join(self.clean_pieces(self.pieces)))
+        o.close()
+
+    def clean_pieces(self, pieces):
+        """Cleans the list of strings given as `pieces`.  It replaces
+        multiple newlines by a maximum of 2 and returns a new list.
+        It also wraps the paragraphs nicely.
+        
+        """
+        ret = []
+        count = 0
+        for i in pieces:
+            if i == '\n':
+                count = count + 1
+            else:
+                if i == '";':
+                    if count:
+                        ret.append('\n')
+                elif count > 2:
+                    ret.append('\n\n')
+                elif count:
+                    ret.append('\n'*count)
+                count = 0
+                ret.append(i)
+
+        _data = "".join(ret)
+        ret = []
+        for i in _data.split('\n\n'):
+            if i == 'Parameters:' or i == 'Exceptions:' or i == 'Returns:':
+                ret.extend([i, '\n'+'-'*len(i), '\n\n'])
+            elif i.find('// File:') > -1: # leave comments alone.
+                ret.extend([i, '\n'])
+            else:
+                _tmp = textwrap.fill(i.strip(), break_long_words=False)
+                _tmp = self.lead_spc.sub(r'\1"\2', _tmp)
+                ret.extend([_tmp, '\n\n'])
+        return ret
+
+
+def convert(input, output, include_function_definition=True, quiet=False):
+    p = Doxy2SWIG(input, include_function_definition, quiet)
+    p.generate()
+    p.write(output)
+
+def main():
+    usage = __doc__
+    parser = optparse.OptionParser(usage)
+    parser.add_option("-n", '--no-function-definition',
+                      action='store_true',
+                      default=False,
+                      dest='func_def',
+                      help='do not include doxygen function definitions')
+    parser.add_option("-q", '--quiet',
+                      action='store_true',
+                      default=False,
+                      dest='quiet',
+                      help='be quiet and minimize output')
+    
+    options, args = parser.parse_args()
+    if len(args) != 2:
+        parser.error("error: no input and output specified")
+
+    convert(args[0], args[1], not options.func_def, options.quiet)
+    
+
+if __name__ == '__main__':
+    main()
diff --git a/python/examples/CMakeLists.txt b/python/examples/CMakeLists.txt
new file mode 100644
index 0000000..bca7daf
--- /dev/null
+++ b/python/examples/CMakeLists.txt
@@ -0,0 +1,5 @@
+install ( FILES simple.py complete.py
+          DESTINATION share/libftdi/examples
+          PERMISSIONS OWNER_READ GROUP_READ WORLD_READ 
+        )
+
diff --git a/python/examples/complete.py b/python/examples/complete.py
new file mode 100644
index 0000000..afa59fa
--- /dev/null
+++ b/python/examples/complete.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""Python example program.
+
+Complete program to demonstrate the usage
+of the swig generated python wrapper
+
+You need to build and install the wrapper first"""
+
+import os
+import sys
+import ftdi1 as ftdi
+import time
+
+# version
+print ( 'version: %s\n' % ftdi.__version__  )
+
+# initialize
+ftdic = ftdi.new()
+if ftdic == 0:
+    print( 'new failed: %d' % ret )
+    os._exit( 1 )
+
+# try to list ftdi devices 0x6010 or 0x6001
+ret, devlist = ftdi.usb_find_all( ftdic, 0x0403, 0x6010 )
+if ret <= 0:
+    ret, devlist = ftdi.usb_find_all( ftdic, 0x0403, 0x6001)
+
+if ret < 0:
+    print( 'ftdi_usb_find_all failed: %d (%s)' % ( ret, ftdi.get_error_string( 
ftdic ) ) )
+    os._exit( 1 )
+print( 'devices: %d' % ret )
+curnode = devlist
+i = 0
+while( curnode != None ):
+    ret, manufacturer, description, serial = ftdi.usb_get_strings( ftdic, 
curnode.dev )
+    if ret < 0:
+        print( 'ftdi_usb_get_strings failed: %d (%s)' % ( ret, 
ftdi.get_error_string( ftdic ) ) )
+        os._exit( 1 )
+    print( '#%d: manufacturer="%s" description="%s" serial="%s"\n' % ( i, 
manufacturer, description, serial ) )
+    curnode = curnode.next
+    i += 1
+
+# open usb
+ret = ftdi.usb_open( ftdic, 0x0403, 0x6001 )
+if ret < 0:
+    print( 'unable to open ftdi device: %d (%s)' % ( ret, 
ftdi.get_error_string( ftdic ) ) )
+    os._exit( 1 )
+
+
+# bitbang
+ret = ftdi.set_bitmode( ftdic, 0xff, ftdi.BITMODE_BITBANG )
+if ret < 0:
+    print( 'Cannot enable bitbang' )
+    os._exit( 1 )
+print( 'turning everything on' )
+ftdi.write_data( ftdic, chr(0xff), 1 )
+time.sleep( 1 )
+print( 'turning everything off\n' )
+ftdi.write_data( ftdic, chr(0x00), 1 )
+time.sleep( 1 )
+for i in range( 8 ):
+    val = 2**i
+    print( 'enabling bit #%d (0x%02x)' % (i, val) )
+    ftdi.write_data( ftdic, chr(val), 1 )
+    time.sleep ( 1 )
+ftdi.disable_bitbang( ftdic )
+print( '' )
+
+
+# read pins
+ret, pins = ftdi.read_pins( ftdic )
+if ( ret == 0 ):
+    if sys.version_info[0] < 3: # python 2
+        pins = ord( pins )
+    else:
+        pins = pins[0]
+    print( 'pins: 0x%x' % pins )
+              
+
+# read chip id
+ret, chipid = ftdi.read_chipid( ftdic )
+if (ret==0):
+    print( 'chip id: %x\n' % chipid )
+
+
+# read eeprom
+eeprom_addr = 1
+ret, eeprom_val = ftdi.read_eeprom_location( ftdic, eeprom_addr )
+if (ret==0):
+    print( 'eeprom @ %d: 0x%04x\n' % ( eeprom_addr, eeprom_val ) )
+
+print( 'eeprom:' )
+ret = ftdi.read_eeprom( ftdic )
+size = 128
+ret, eeprom = ftdi.get_eeprom_buf ( ftdic, size )
+if ( ret == 0 ):
+    for i in range( size ):
+        octet = eeprom[i]
+        if sys.version_info[0] < 3: # python 2
+            octet = ord( octet )
+        sys.stdout.write( '%02x ' % octet )
+        if ( i % 8 == 7 ):
+            print( '' )
+print( '' )
+            
+# close usb
+ret = ftdi.usb_close( ftdic )
+if ret < 0:
+    print( 'unable to close ftdi device: %d (%s)' % ( ret, 
ftdi.get_error_string( ftdic ) ) )
+    os._exit( 1 )
+    
+print ('device closed')    
+ftdi.free( ftdic )
diff --git a/python/examples/simple.py b/python/examples/simple.py
new file mode 100644
index 0000000..9298c24
--- /dev/null
+++ b/python/examples/simple.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""Python example program.
+
+Small program to demonstrate the usage
+of the swig generated python wrapper
+
+You need to build and install the wrapper first"""
+
+import ftdi1 as ftdi
+
+def main():
+    """Main program"""
+    context = ftdi.new()
+
+    version_info = ftdi.get_library_version()
+    print("[FTDI version] major: %d, minor: %d, micro: %d" \
+               ", version_str: %s, snapshot_str: %s" %
+               (version_info.major, version_info.minor, version_info.micro,
+               version_info.version_str, version_info.snapshot_str))
+
+    # try to open an ftdi 0x6010 or 0x6001
+    ret = ftdi.usb_open(context, 0x0403, 0x6010)
+    if ret < 0:
+        ret = ftdi.usb_open(context, 0x0403, 0x6001)
+        
+    print("ftdi.usb_open(): %d" % ret)
+    print("ftdi.set_baudrate(): %d" % ftdi.set_baudrate(context, 9600))
+
+    ftdi.free(context)
+
+main()
diff --git a/python/ftdi1.i b/python/ftdi1.i
new file mode 100644
index 0000000..1e820dd
--- /dev/null
+++ b/python/ftdi1.i
@@ -0,0 +1,138 @@
+/* File: ftdi1.i */
+
+%module(docstring="Python interface to libftdi1") ftdi1
+%feature("autodoc","1");
+
+#ifdef DOXYGEN
+%include "ftdi1_doc.i"
+#endif
+
+%{
+#include "Python.h"
+
+PyObject* convertString( const char *v, Py_ssize_t len )
+{
+#if PY_MAJOR_VERSION >= 3
+  return PyBytes_FromStringAndSize(v, len);
+#else
+  return PyString_FromStringAndSize(v, len);
+#endif
+}
+%}
+
+%include <typemaps.i>
+%include <cstring.i>
+
+%typemap(in) unsigned char* = char*;
+
+%immutable ftdi_version_info::version_str;
+%immutable ftdi_version_info::snapshot_str;
+
+%rename("%(strip:[ftdi_])s") "";
+
+%newobject ftdi_new;
+%typemap(newfree) struct ftdi_context *ftdi "ftdi_free($1);";
+%delobject ftdi_free;
+
+%define ftdi_usb_find_all_docstring
+"usb_find_all(context, vendor, product) -> (return_code, devlist)"
+%enddef
+%feature("autodoc", ftdi_usb_find_all_docstring) ftdi_usb_find_all;
+%typemap(in,numinputs=0) SWIGTYPE** OUTPUT ($*ltype temp) %{ $1 = &temp; %}
+%typemap(argout) SWIGTYPE** OUTPUT %{ $result = 
SWIG_Python_AppendOutput($result, 
SWIG_NewPointerObj((void*)*$1,$*descriptor,0)); %}
+%apply SWIGTYPE** OUTPUT { struct ftdi_device_list **devlist };
+    int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list 
**devlist,
+                          int vendor, int product);
+%clear struct ftdi_device_list **devlist;
+
+%define ftdi_usb_get_strings_docstring
+"usb_get_strings(context, device) -> (return_code, manufacturer, description, 
serial)"
+%enddef
+%feature("autodoc", ftdi_usb_get_strings_docstring) ftdi_usb_get_strings;
+%apply char *OUTPUT { char * manufacturer, char * description, char * serial };
+%cstring_bounded_output( char * manufacturer, 256 );
+%cstring_bounded_output( char * description, 256 );
+%cstring_bounded_output( char * serial, 256 );
+%typemap(default,noblock=1) int mnf_len, int desc_len, int serial_len { $1 = 
256; }
+    int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct libusb_device 
*dev,
+                             char * manufacturer, int mnf_len,
+                             char * description, int desc_len,
+                             char * serial, int serial_len);
+%clear char * manufacturer, char * description, char * serial;
+%clear int mnf_len, int desc_len, int serial_len;
+
+%define ftdi_read_data_docstring
+"read_data(context) -> (return_code, buf)"
+%enddef
+%feature("autodoc", ftdi_read_data_docstring) ftdi_read_data;
+%typemap(in,numinputs=1) (unsigned char *buf, int size) %{ $2 = 
PyInt_AsLong($input);$1 = (unsigned char*)malloc($2*sizeof(char)); %}
+%typemap(argout) (unsigned char *buf, int size) %{ if(result<0) $2=0; $result 
= SWIG_Python_AppendOutput($result, convertString((char*)$1, $2)); free($1); %}
+    int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int 
size);
+%clear (unsigned char *buf, int size);
+
+%apply int *OUTPUT { unsigned int *chunksize };
+    int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int 
*chunksize);
+    int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int 
*chunksize);
+%clear unsigned int *chunksize;
+
+%define ftdi_read_pins_docstring
+"read_pins(context) -> (return_code, pins)"
+%enddef
+%feature("autodoc", ftdi_read_pins_docstring) ftdi_read_pins;
+%typemap(in,numinputs=0) unsigned char *pins ($*ltype temp) %{ $1 = &temp; %}
+%typemap(argout) (unsigned char *pins) %{ $result = 
SWIG_Python_AppendOutput($result, convertString((char*)$1, 1)); %}
+    int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins);
+%clear unsigned char *pins;
+
+%typemap(in,numinputs=0) unsigned char *latency ($*ltype temp) %{ $1 = &temp; 
%}
+%typemap(argout) (unsigned char *latency) %{ $result = 
SWIG_Python_AppendOutput($result, convertString((char*)$1, 1)); %}
+    int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char 
*latency);
+%clear unsigned char *latency;
+
+%apply short *OUTPUT { unsigned short *status };
+    int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short 
*status);
+%clear unsigned short *status;
+
+%apply int *OUTPUT { int* value };
+    int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum 
ftdi_eeprom_value value_name, int* value);
+%clear int* value;
+
+%typemap(in,numinputs=1) (unsigned char *buf, int size) %{ $2 = 
PyInt_AsLong($input);$1 = (unsigned char*)malloc($2*sizeof(char)); %}
+%typemap(argout) (unsigned char *buf, int size) %{ if(result<0) $2=0; $result 
= SWIG_Python_AppendOutput($result, convertString((char*)$1, $2)); free($1); %}
+    int ftdi_get_eeprom_buf(struct ftdi_context *ftdi, unsigned char * buf, 
int size);
+%clear (unsigned char *buf, int size);
+
+%define ftdi_read_eeprom_location_docstring
+"read_eeprom_location(context, eeprom_addr) -> (return_code, eeprom_val)"
+%enddef
+%feature("autodoc", ftdi_read_eeprom_location_docstring) 
ftdi_read_eeprom_location;
+%apply short *OUTPUT { unsigned short *eeprom_val };
+    int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, 
unsigned short *eeprom_val);
+%clear unsigned short *eeprom_val;
+
+%define ftdi_read_eeprom_docstring
+"read_eeprom(context) -> (return_code, eeprom)"
+%enddef
+%feature("autodoc", ftdi_read_eeprom_docstring) ftdi_read_eeprom;
+
+%define ftdi_read_chipid_docstring
+"ftdi_read_chipid(context) -> (return_code, chipid)"
+%enddef
+%feature("autodoc", ftdi_read_chipid_docstring) ftdi_read_chipid;
+%apply int *OUTPUT { unsigned int *chipid };
+    int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid);
+%clear unsigned int *chipid;
+
+%include ftdi.h
+%{
+#include <ftdi.h>
+%}
+
+%include ftdi_i.h
+%{
+#include <ftdi_i.h>
+%}
+
+%pythoncode %{
+__version__ = get_library_version().version_str
+%}


hooks/post-receive
-- 
A library to talk to FTDI chips

--
libftdi-git - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi-git+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread
  • A library to talk to FTDI chips branch, master, updated. v1.0-8-gc528532, libftdi-git <=