tclusb: initial version listing devices and support opening a device master
authorPat Thoyts <patthoyts@users.sourceforge.net>
Fri, 22 Sep 2006 22:33:23 +0000 (23:33 +0100)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Sat, 2 Dec 2017 23:45:14 +0000 (23:45 +0000)
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Makefile.in [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
configure.in [new file with mode: 0644]
pkgIndex.tcl.in [new file with mode: 0644]
tclusb.c [new file with mode: 0644]

diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..788c1cf
--- /dev/null
@@ -0,0 +1,437 @@
+# Makefile.in --
+#
+#      This file is a Makefile for Sample TEA Extension.  If it has the name
+#      "Makefile.in" then it is a template for a Makefile;  to generate the
+#      actual Makefile, run "./configure", which is a configuration script
+#      generated by the "autoconf" program (constructs like "@foo@" will get
+#      replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: Makefile.in,v 1.61 2006/07/20 07:42:37 das Exp $
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR        = @SAMPLE_NEW_VAR@
+
+#========================================================================
+# Nothing of the variables below this line should need to be changed.
+# Please check the TARGETS section below to make sure the make targets
+# are correct.
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES    = @PKG_SOURCES@
+PKG_OBJECTS    = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS    = @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE   = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES   = $(PKG_LIB_FILE)
+BINARIES       = $(lib_BINARIES)
+
+SHELL          = @SHELL@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix    = @exec_prefix@
+
+bindir         = @bindir@
+libdir         = @libdir@
+datadir                = @datadir@
+mandir         = @mandir@
+includedir     = @includedir@
+
+DESTDIR                =
+
+PKG_DIR                = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir     = $(datadir)/$(PKG_DIR)
+pkglibdir      = $(libdir)/$(PKG_DIR)
+pkgincludedir  = $(includedir)/$(PKG_DIR)
+
+top_builddir   = .
+
+INSTALL                = @INSTALL@
+INSTALL_PROGRAM        = @INSTALL_PROGRAM@
+INSTALL_DATA   = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME   = @PACKAGE_NAME@
+PACKAGE_VERSION        = @PACKAGE_VERSION@
+CC             = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES     = @CLEANFILES@
+EXEEXT         = @EXEEXT@
+LDFLAGS_DEFAULT        = @LDFLAGS_DEFAULT@
+MAKE_LIB       = @MAKE_LIB@
+MAKE_SHARED_LIB        = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB        = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB  = @MAKE_STUB_LIB@
+OBJEXT         = @OBJEXT@
+RANLIB         = @RANLIB@
+RANLIB_STUB    = @RANLIB_STUB@
+SHLIB_CFLAGS   = @SHLIB_CFLAGS@
+SHLIB_LD       = @SHLIB_LD@
+SHLIB_LD_LIBS  = @SHLIB_LD_LIBS@
+STLIB_LD       = @STLIB_LD@
+#TCL_DEFS      = @TCL_DEFS@
+TCL_BIN_DIR    = @TCL_BIN_DIR@
+TCL_SRC_DIR    = @TCL_SRC_DIR@
+#TK_BIN_DIR    = @TK_BIN_DIR@
+#TK_SRC_DIR    = @TK_SRC_DIR@
+
+# Not used, but retained for reference of what libs Tcl required
+#TCL_LIBS      = @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing.  The other environment variables allow us
+# to test against an uninstalled Tcl.  Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR)
+#EXTRA_PATH    = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
+TCLLIBPATH     = $(top_builddir)
+TCLSH_ENV      = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+                 @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+                 PATH="$(EXTRA_PATH):$(PATH)" \
+                 TCLLIBPATH="$(TCLLIBPATH)"
+#                TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
+
+TCLSH_PROG     = @TCLSH_PROG@
+TCLSH          = $(TCLSH_ENV) $(TCLSH_PROG)
+
+#WISH_PROG     = @WISH_PROG@
+#WISH          = $(TCLSH_ENV) $(WISH_PROG)
+
+
+SHARED_BUILD   = @SHARED_BUILD@
+
+INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
+#INCLUDES      = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
+
+PKG_CFLAGS     = @PKG_CFLAGS@
+
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.in checks for the necessary components
+# that your library may use.  TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS          = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
+DEFS           = @DEFS@ $(PKG_CFLAGS)
+
+CONFIG_CLEAN_FILES = Makefile
+
+CPPFLAGS       = @CPPFLAGS@
+LIBS           = @PKG_LIBS@ @LIBS@
+AR             = @AR@
+CFLAGS         = @CFLAGS@
+COMPILE                = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS.  Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target inclues executable programs and
+# platform-dependent libraries.  Modify these targets so that they install
+# the various pieces of your package.  The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES)
+
+libraries:
+
+
+#========================================================================
+# Your doc target should differentiate from doc builds (by the developer)
+# and doc installs (see install-doc), which just install the docs on the
+# end user machine when building from source.
+#========================================================================
+
+doc:
+       @echo "If you have documentation to create, place the commands to"
+       @echo "build the docs in the 'doc:' target.  For example:"
+       @echo "        xml2nroff sample.xml > sample.n"
+       @echo "        xml2html sample.xml > sample.html"
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+# The list=...; for p in $$list handles the empty list case x-platform.
+#========================================================================
+
+install-libraries: libraries
+       @mkdir -p $(DESTDIR)$(includedir)
+       @echo "Installing header files in $(DESTDIR)$(includedir)"
+       @list='$(PKG_HEADERS)'; for i in $$list; do \
+           echo "Installing $(srcdir)/$$i" ; \
+           $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+       done;
+
+#========================================================================
+# Install documentation.  Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+       @mkdir -p $(DESTDIR)$(mandir)/mann
+       @echo "Installing documentation in $(DESTDIR)$(mandir)"
+       @list='$(srcdir)/doc/*.n'; for i in $$list; do \
+           echo "Installing $$i"; \
+           rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+           $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+       done
+
+test: binaries libraries
+       $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+shell: binaries libraries
+       @$(TCLSH) $(SCRIPT)
+
+gdb:
+       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above.  That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library.  In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+       -rm -f $(PKG_LIB_FILE)
+       ${MAKE_LIB}
+       $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+       -rm -f $(PKG_STUB_LIB_FILE)
+       ${MAKE_STUB_LIB}
+       $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension.  If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+#      $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
+
+.c.@OBJEXT@:
+       $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+#COMPRESS      = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS       = gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT      = /tmp/dist
+DIST_DIR       = $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+       rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean
+       mkdir -p $(DIST_DIR)
+       cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
+               $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
+               $(DIST_DIR)/
+       chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+       chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+       for i in $(srcdir)/*.[ch]; do \
+           if [ -f $$i ]; then \
+               cp -p $$i $(DIST_DIR)/ ; \
+           fi; \
+       done;
+
+       mkdir $(DIST_DIR)/tclconfig
+       cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+               $(DIST_DIR)/tclconfig/
+       chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+       chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+       list='demos doc generic library mac tests unix win'; \
+       for p in $$list; do \
+           if test -d $(srcdir)/$$p ; then \
+               mkdir $(DIST_DIR)/$$p; \
+               cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+           fi; \
+       done
+
+       (cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:  
+       -test -z "$(BINARIES)" || rm -f $(BINARIES)
+       -rm -f *.$(OBJEXT) core *.core
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+       -rm -f *.tab.c
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries.  On Windows this includes both .dll and
+# .lib files.  Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries: binaries
+       @mkdir -p $(DESTDIR)$(pkglibdir)
+       @list='$(lib_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+           stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+           if test "x$$stub" = "xstub"; then \
+               echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+           else \
+               echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+           fi; \
+           ext=`echo $$p|sed -e "s/.*\.//"`; \
+           if test "x$$ext" = "xdll"; then \
+               lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+               if test -f $$lib; then \
+                   echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+                   $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+               fi; \
+           fi; \
+         fi; \
+       done
+       @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         if test -f $(srcdir)/$$p; then \
+           destp=`basename $$p`; \
+           echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+           $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+         fi; \
+       done
+       @if test "x$(SHARED_BUILD)" = "x1"; then \
+           echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
+           $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
+       fi
+
+#========================================================================
+# Install binary executables (e.g. .exe files and dependent .dll files)
+# This is for files that must go in the bin directory (located next to
+# wish and tclsh), like dependent .dll files on Windows.
+#
+# You should not have to modify this target, except to define bin_BINARIES
+# above if necessary.
+#========================================================================
+
+install-bin-binaries: binaries
+       @mkdir -p $(DESTDIR)$(bindir)
+       @list='$(bin_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+         fi; \
+       done
+
+.SUFFIXES: .c .$(OBJEXT)
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+       list='$(lib_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         p=`basename $$p`; \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(bin_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/$$p; \
+       done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..0b05739
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Include the TEA standard macro set
+#
+
+builtin(include,tclconfig/tcl.m4)
+
+#
+# Add here whatever m4 macros you want to define for your package
+#
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..b2a872a
--- /dev/null
@@ -0,0 +1,187 @@
+#!/bin/bash -norc
+dnl    This file is an input file used by the GNU "autoconf" program to
+dnl    generate the file "configure", which is run during Tcl installation
+dnl    to configure the system for the local environment.
+#
+# RCS: @(#) $Id: configure.in,v 1.46 2006/01/23 19:18:55 hobbs Exp $
+
+#-----------------------------------------------------------------------
+# Sample configure.in for Tcl Extensions.  The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Set your package name and version numbers here.
+#
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided.  These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+#-----------------------------------------------------------------------
+
+AC_INIT([tclusb], [0.1])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.5])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+TEA_ADD_SOURCES([tclusb.c])
+TEA_ADD_HEADERS([])
+TEA_ADD_INCLUDES([])
+TEA_ADD_LIBS([-lusb])
+TEA_ADD_CFLAGS([])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([])
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_sample in this case) so
+# that we create the export library with the dll.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    AC_DEFINE(BUILD_sample, 1, [Build windows export dll])
+    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    CLEANFILES="pkgIndex.tcl"
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+AC_SUBST(CLEANFILES)
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/pkgIndex.tcl.in b/pkgIndex.tcl.in
new file mode 100644 (file)
index 0000000..cc105a1
--- /dev/null
@@ -0,0 +1 @@
+package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ [list load [file join $dir @PKG_LIB_FILE@]]
\ No newline at end of file
diff --git a/tclusb.c b/tclusb.c
new file mode 100644 (file)
index 0000000..c0f8ce9
--- /dev/null
+++ b/tclusb.c
@@ -0,0 +1,242 @@
+/*
+ * usb find_device vid pid
+ * usb devices
+ * $device select_configuration $config
+ * $device open
+ * $device close
+ */
+
+#include <tcl.h>
+#include <string.h>
+#include <usb.h>
+
+int DLLEXPORT Usb_Init(Tcl_Interp *interp);
+static Tcl_ObjCmdProc UsbEnsembleCmd;
+static Tcl_ObjCmdProc UsbDeviceEnsembleCmd;
+static Tcl_ObjCmdProc UsbDevicesCmd;
+static Tcl_ObjCmdProc UsbGetDeviceCmd;
+static Tcl_ObjCmdProc UsbSetConfigurationCmd;
+static Tcl_ObjCmdProc UsbClaimInterfaceCmd;
+static Tcl_CmdDeleteProc UsbDeviceCleanup;
+
+struct Ensemble {
+    const char *name;
+    Tcl_ObjCmdProc *command;
+    struct Ensemble *ensemble;
+};
+
+struct Ensemble UsbEnsemble[] = {
+    { "devices", UsbDevicesCmd, NULL },
+    { "get_device", UsbGetDeviceCmd, NULL},
+    { NULL, NULL, NULL },
+};
+
+struct Ensemble UsbDeviceEnsemble[] = {
+    { "set_configuration", UsbSetConfigurationCmd, NULL },
+    { "claim_interface", UsbClaimInterfaceCmd, NULL },
+    { NULL, NULL, NULL }
+};
+
+typedef struct Device {
+    struct usb_device *dev;
+    struct usb_dev_handle *handle;
+} Device;
+
+int
+UsbEnsembleCmd(ClientData clientData, Tcl_Interp *interp,
+          int objc, Tcl_Obj *const objv[]) 
+{
+    struct Ensemble *ensemble = UsbEnsemble;
+    int optPtr = 1, index = 0;
+
+    while (optPtr < objc) {
+        if (Tcl_GetIndexFromObjStruct(interp, objv[optPtr], ensemble,
+                                      sizeof(ensemble[0]),
+                                      "command", 0, &index) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        if (ensemble[index].command) {
+            return ensemble[index].command(clientData, interp, objc, objv);
+        }
+        ensemble = ensemble[index].ensemble;
+        ++optPtr;
+    }
+    Tcl_WrongNumArgs(interp, optPtr, objv, "subcommand ?arg arg...?");
+    return TCL_ERROR;    
+}
+
+int
+UsbDeviceEnsembleCmd(ClientData clientData, Tcl_Interp *interp,
+          int objc, Tcl_Obj *const objv[]) 
+{
+    struct Ensemble *ensemble = UsbDeviceEnsemble;
+    int optPtr = 1, index = 0;
+
+    while (optPtr < objc) {
+        if (Tcl_GetIndexFromObjStruct(interp, objv[optPtr], ensemble,
+                                      sizeof(ensemble[0]),
+                                      "command", 0, &index) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        if (ensemble[index].command) {
+            return ensemble[index].command(clientData, interp, objc, objv);
+        }
+        ensemble = ensemble[index].ensemble;
+        ++optPtr;
+    }
+    Tcl_WrongNumArgs(interp, optPtr, objv, "subcommand ?arg arg...?");
+    return TCL_ERROR;    
+}
+
+int
+UsbDevicesCmd(ClientData clientData, Tcl_Interp *interp,
+              int objc, Tcl_Obj *const objv[]) 
+{
+       struct usb_bus *bus = NULL;
+    Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+
+    usb_find_devices();
+       for (bus = usb_get_busses(); bus; bus = bus->next) {
+               struct usb_device *dev = NULL;
+               for (dev = bus->devices; dev != NULL; dev = dev->next) {
+            Tcl_Obj *elt[10], *deviceObj;
+            int n = 0;
+            elt[n++] = Tcl_NewStringObj("devnum", -1);
+            elt[n++] = Tcl_NewIntObj(dev->devnum);
+            elt[n++] = Tcl_NewStringObj("bDeviceClass", -1);
+            elt[n++] = Tcl_NewIntObj(dev->descriptor.bDeviceClass);
+            elt[n++] = Tcl_NewStringObj("idVendor", -1);
+            elt[n++] = Tcl_NewIntObj(dev->descriptor.idVendor);
+            elt[n++] = Tcl_NewStringObj("idProduct", -1);
+            elt[n++] = Tcl_NewIntObj(dev->descriptor.idProduct);
+            elt[n++] = Tcl_NewStringObj("path", -1);
+            elt[n] = Tcl_NewStringObj(bus->dirname, -1);
+            Tcl_AppendStringsToObj(elt[n++], "/", dev->filename, NULL);
+            deviceObj = Tcl_NewListObj(n, elt);
+            if (Tcl_ListObjAppendElement(interp, listObj, deviceObj) != TCL_OK)
+                return TCL_ERROR;
+               }
+       }
+    Tcl_SetObjResult(interp, listObj);
+    return TCL_OK;
+}
+
+void
+UsbDeviceCleanup(ClientData clientData)
+{
+    Device *devicePtr = (Device *)clientData;
+    usb_close(devicePtr->handle);
+    ckfree((char *)devicePtr);
+}
+
+int
+UsbGetDeviceCmd(ClientData clientData, Tcl_Interp *interp,
+                int objc, Tcl_Obj *const objv[]) 
+{
+    int num_parts = 0;
+    const char **path_parts;
+    char name[14];
+    struct usb_device *dev = NULL;
+       struct usb_bus *bus = NULL;
+    Device *devicePtr = NULL;
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "path");
+        return TCL_ERROR;
+    }
+
+    Tcl_SplitPath(Tcl_GetString(objv[2]), &num_parts, &path_parts);
+    if (num_parts != 2) {
+        Tcl_SetResult(interp, "error: path must be nnn/iii", TCL_STATIC);
+        return TCL_ERROR;
+    }
+
+    for (bus = usb_get_busses(); bus; bus = bus->next) {
+        if (strcmp(bus->dirname, path_parts[0]) == 0)
+            break;
+    }
+    if (bus == NULL) {
+        Tcl_SetResult(interp, "error: bus index invalid", TCL_STATIC);
+        return TCL_ERROR;
+    }
+    
+    for (dev = bus->devices; dev; dev = dev->next) {
+        if (strcmp(dev->filename, path_parts[1]) == 0)
+            break;
+    }
+    if (dev == NULL) {
+        Tcl_SetResult(interp, "error: device index invalid", TCL_STATIC);
+        return TCL_ERROR;
+    }
+    
+    snprintf(name, sizeof(name) - 1, "usb%04x%04x",
+             dev->descriptor.idVendor, dev->descriptor.idProduct);
+    name[sizeof(name)-1] = 0;
+
+    devicePtr = (Device *)ckalloc(sizeof(Device));
+    devicePtr->dev = dev;
+    devicePtr->handle = usb_open(dev);
+
+    Tcl_CreateObjCommand(interp, name, UsbDeviceEnsembleCmd, 
+                         devicePtr, UsbDeviceCleanup);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
+    return TCL_OK;
+}
+
+int
+UsbSetConfigurationCmd(ClientData clientData, Tcl_Interp *interp,
+                       int objc, Tcl_Obj *const objv[]) 
+{
+    Device *devicePtr = (Device *)clientData;
+    int r = TCL_OK, num = 0;
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "num");
+        return TCL_ERROR;
+    }
+    r = Tcl_GetIntFromObj(interp, objv[2], &num);
+    if (r == TCL_OK) {
+        int u = usb_set_configuration(devicePtr->handle, num);
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(u));
+    }
+    return r;
+}
+
+int
+UsbClaimInterfaceCmd(ClientData clientData, Tcl_Interp *interp,
+                     int objc, Tcl_Obj *const objv[]) 
+{
+    Device *devicePtr = (Device *)clientData;
+    int r = TCL_OK, num = 0;
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "num");
+        return TCL_ERROR;
+    }
+    r = Tcl_GetIntFromObj(interp, objv[2], &num);
+    if (r == TCL_OK) {
+        int u = usb_set_configuration(devicePtr->handle, num);
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(u));
+    }
+    return r;
+}
+
+#define TCL_VERSION_WRONG "8.0"
+
+int DLLEXPORT
+Tclusb_Init(Tcl_Interp *interp)
+{
+#ifdef USE_TCL_STUBS
+    if (Tcl_InitStubs(interp, TCL_VERSION_WRONG, 0) == NULL) {
+        return TCL_ERROR;
+    }
+#endif
+    
+    usb_init();
+    usb_find_busses();
+    usb_find_devices();
+
+    Tcl_CreateObjCommand(interp, "usb", UsbEnsembleCmd, NULL, NULL);
+    Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION);
+    return TCL_OK;
+}