Import Tcl 8.6.12

This commit is contained in:
Steve Dower
2021-11-08 17:30:58 +00:00
parent 1aadb2455c
commit 674867e7e6
608 changed files with 78089 additions and 60360 deletions

View File

@@ -0,0 +1,259 @@
*** Now that tdbcpostgres is under Fossil control, the ChangeLog is
no longer being maintained. Please refer to the change history at
https://core.tcl-lang.org/tdbcpostgres/timeline/
2014-10-23 Don Porter <dgp@users.sourceforge.net>
* configure.in:
* README: Advanced version number to 1.0.2.
* configure: TEA update; autoconf 2.68
* Makefile.in: At some point docs we're written. Put them in dist.
* doc/*.n: [TDBC Bug 00b792] OpenBSD friendly docs.
2012-11-08 Don Porter <dgp@users.sourceforge.net>
* configure.in:
* README: Advanced version number to 1.0.1.
* configure: autoconf 2.68
2012-11-15 Kevin B. Kenny <kennykb@acm.org>
* configure.in: Made configurator changes so that tdbc::postgres
* Makefile.in: will `make test` correctly even when running against
an uninstalled TDBC.
* configure: autoconf 2.68
*** ADVANCED TO NEW VERSION OF AUTOCONF ***
2012-11-08 Don Porter <dgp@users.sourceforge.net>
* configure.in:
* README: Advanced version number to 1.0.0.
* configure: autoconf 2.59
2012-07-26 Jan Nijtmans <jan.nijtmans@gmail.com>
* generic/pqStubInit.s: Make some tables "const"
* tclconfig/install-sh: Update to latest TEA
* tclconfig/tcl.m4:
* configure: autoconf-2.59
2012-07-13 Kevin B. Kenny <kennykb@acm.org>
* generic/tdbcpostgres.c: Corrected a problem where PostgreSQL 9.0
and beyond return byte arrays in an
incompatible format, yielding silent
data corruption in SELECT operations.
(Bug [4357c31d89])
2012-07-10 Kevin B. Kenny <kennykb@acm.org>
* generic/tdbcpostgres.c: Fixed a non-static table argument to
Tcl_GetIndexFromObjStruct.
2012-06-10 Jan Nijtmans <jan.nijtmans@gmail.com>
* configure.in: make TDBC API functions MODULE_SCOPE
* configure: autoconf-2.59
2012-06-08 Jan Nijtmans <jan.nijtmans@gmail.com>
* tclconfig/ChangeLog:
* tclconfig/tcl.m4: Update to latest TEA
* configure: autoconf-2.59
2011-07-19 Kevin B. Kenny <kennykb@acm.org>
* configure.in:
* Makefile.in:
* README: Advanced version number to 1.0b17.
* configure: autoconf 2.59
2011-07-18 Don Porter <dgp@users.sourceforge.net>
* configure.in: Update to latest TEA 3.9 revisions.
* Makefile.in:
* tclconfig/*:
* configure: autoconf-2.59
2011-04-12 Kevin B. Kenny <kennybk@acm.org>
* generic/pqStubDefs.txt:
Added stubs for PQdescribePrepared, PQnparams and PQparamtype,
needed for correct parameter specification of prepared
statements.
* generic/pqStubInit.c:
* generic/pgStubs.h:
make genstubs
* generic/tdbcpostgres.c (PrepareStatement, StatementConstructor):
Changed statement preparation to *not* specify unknown
data types but to let the PostgreSQL server try to deduce
them all. Added code to report the deduced parameter types
back to the script in the 'params' method. Added code to
the statement constructor to accept PostgreSQL type cast
syntax as a way to make prepared statements work when they
otherwise would give 'could not determine data type' errors.
* tests/tdbcpostgres.test (tdbc::postgres-18.[45]):
Added test cases for correct reporting of deduced parameter
types and for PostgreSQL
2011-02-20 Kevin B. Kenny <kennykb@acm.org>
* generic/pqStubInit.c:
Revised code to look for libpq.so by SONAME as well
as directly, so that ABI version number is taken into
account and so that libpq-dev is not required.
* generic/pqStubs.h: make genstubs
2011-01-26 Kevin B. Kenny <kennykb@acm.org>
* doc/tdbc_postgres.n:
Added empty comment at the start of each manpage because 'man'
interprets comments there as directives. Thanks to Konstantin
Kohmoutov for reporting and diagnosing this error.
2011-01-23 Kevin B. Kenny <kennykb@acm.org>
* generic/tdbcpostgres.c: Modified to pass '@' through into the
native SQL to allow session variables.
Fixed a pointer smash if the argument
to "$connection prepare" includes no
SQL statement (e.g. contains only whitespace)
* library/tdbcpostgres.tcl: Added 'nextresults' method, which always
returns 0 since PostgreSQL calls return
single result sets.
* tests/tdbcpostgres.test: Added test cases (30.0 and 30.1) for the
above.
* configure.in: Added a missing stanza of code for finding the tdbc
library and include in the build dir when building
against an uninstalled tdbc. Thanks to Konstantin
Khomoutov for reporting this error.
* configure: autoconf2.59
2010-09-03 Kevin B. Kenny <kennykb@acm.org>
* generic/tdbcpostgres.c:
Made the '-port' option work. (Discovered bug when
testing on a machine where Postgres was listening
on 5433 but the client lib wanted 5432.)
* tests/tdbcpostgres.test:
Changed 'keySequence' in 'foreignkeys' to be
'ordinalPosition' for consistency with 'primaryKeys'.
* configure.in:
* Makefile.in:
* pkgIndex.tcl.in (new file):
* README:
* tclconfig/: Upgraded the build to use TEA 3.9. Changed the
approach to pkgIndex.tcl generation. (It's now built
at configure time, rather than from the Makefile.)
Advanced version number to 1.0b16.
* configure: autoconf 2.59
2010-06-19 Kevin B. Kenny <kennykb@acm.org>
* Makefile.in: Revised the code at the suggestion
* generic/tdbcpostgres.c: of Andreas Kupries to avoid using
* tests/all.tcl: 'tcl_findLibrary' and instead execute
* tests/tdbcpostgres.test: both 'source' and 'load' commands from
'pkgIndex.tcl'. Revised the 'make test'
rule, and the test scripts, to
test successfully under the new regime.
Thanks to Andreas for providing the
original patch, and to Joe English
for providing ideas for simplifying
and repairing 'make test' under the
new regime.
2010-05-24 Kevin B. Kenny <kennybk@acm.org>
* tests/tdbcpostgres.test: Added test cases for '$db primarykeys'
and '$db foreignkeys'
2010-05-12 Andreas Kupries <andreask@activestate.com>
* generic/tdbcpostgres.c: Moved the int32_t/int16_t types into the
_WIN32 conditional. Conflicted with HPUX own definitions of
these types and required only for windows.
2010-05-10 Kevin B. Kenny <kennykb@acm.org>
* aclocal.m4: Synchronized with tdbc.
* configure.in: Advanced version number to 1.0b15. Advanced TEA
version to 3.7. Corrected the way that stub libraries
are located on VC++.
* generic/tdbcpostgres.c:
Corrected a number of errors and warnings in the
VC++ build.
* README: Advanced to 1.0b15
* tclconfig/: Advanced to TEA 3.7
* configure: autoconf-2.59
2010-05-10 Andreas Kupries <andreask@activestate.com>
* generic/tdbcpostgres.c: Fixed violations of strict C89.
* Makefile.in: Removed attempt to generate a stub library. Drivers
do not export stub tables.
2010-05-07 Andreas Kupries <andreask@activestate.com>
* generic/fakehq.h: Fixed inclusion of pqstubs.h -> pqStubs.h.
2010-05-01 Kevin B. Kenny <kennykb@acm.org>
* configure.in:
* Makefile.in:
* generic/fakepq.h (new file):
* generic/pqStubDefs.txt (new file):
* generic/pqStubInit.c (new file):
* generic/pqStubs.h (new file):
* generic/tdbcpostgres.c:
Modified to load libpq using Tcl_LoadFile and not
link to its client library, nor include the standard
pq-fe headers. This change allows tdbc::postgres to
build when the build system lacks a PostgreSQL installation.
2010-04-25 Kevin B. Kenny <kennykb@acm.org>
* configure.in: Changed TDBC_* environment variables to tdbc_* for
* README: better TEA compatibility. Advanced version to 1.0b14.
* configure: autoconf 2.59
2009-09-29 Kevin B. Kenny <kennykb@acm.org>
* tests/tdbcpostgres.test: Changed all TEST_* environment variables
to TDBCPOSTGRES_* for easier scripting
of combined builds and tests.
2009-09-23 Kevin B. Kenny <kennykb@acm.org>
* generic/tdbcpostgres.c: Removed an ugly workaround for a
bug in Tcl_SubstObj.
* configure.in:
* README: Advanced version to 1.0b13
* configure: autoconf 2.59
2009-09-19 Kevin B. Kenny <kennykb@acm.org>
* configure (New file): autoconf 2.59
(Added pre-built 'configure' so that TEA users don't
need autoconf, m4 and all that stuff pre-installed)
* generic/tdbcpostgres.c: Many changes to upgrade to Tcl Engineering
* library/tdbcpostgres.tcl: Manual conventions and correct memory
* tests/current.test: mismanagement. Introduced a workaround
for a suspected bug in Tcl_SubstObj.
2009-09-01 Kevin B. Kenny <kennykb@acm.org>
Accepted tdbcpostgres from Slawomir Cygan for inclusion in
the standard tdbc driver distribution.
2009-06-22 Slawomir Cygan <slawomir.cygan@gmail.com>
Initial baseline of a TDBC driver for Postgres.

View File

@@ -0,0 +1,498 @@
# 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.
#========================================================================
# 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_LIB_FILE8 = @PKG_LIB_FILE8@
PKG_LIB_FILE9 = @PKG_LIB_FILE9@
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@
includedir = @includedir@
datarootdir = @datarootdir@
runstatedir = @runstatedir@
datadir = @datadir@
mandir = @mandir@
DESTDIR =
PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
top_builddir = @abs_top_builddir@
INSTALL_OPTIONS =
INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_LIBRARY = @INSTALL_LIBRARY@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
CC = @CC@
CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
CFLAGS_WARNING = @CFLAGS_WARNING@
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@
TDBC_VERSION = @TDBC_VERSION@
TDBC_SRC_DIR = @tdbc_SRC_DIR@
TDBC_BIN_DIR = @tdbc_BIN_DIR@
TDBC_LIB_FILE = @TDBC_LIB_FILE@
# 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) $(TDBC_BIN_DIR)
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
TDBCPOSTGRES_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@` \
TCLLIBPATH="$(TCLLIBPATH)"
TCLSH_PROG = @TCLSH_PROG@
TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_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.ac 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) -DTCL_NO_DEPRECATED=1
# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
CLEANFILES = @CLEANFILES@
CPPFLAGS = @CPPFLAGS@
LIBS = @PKG_LIBS@ @LIBS@
AR = @AR@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) \
$(CFLAGS_DEFAULT) $(CFLAGS_WARNING) $(SHLIB_CFLAGS) $(CFLAGS)
GDB = gdb
VALGRIND = valgrind
VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high \
--leak-check=yes --show-reachable=yes -v
.SUFFIXES: .c .$(OBJEXT)
#========================================================================
# Start of user-definable TARGETS section
#========================================================================
#========================================================================
# TEA TARGETS. Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target includes 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:
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
@$(INSTALL_DATA_DIR) "$(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
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(mandir)/mann"
@echo "Installing documentation in $(DESTDIR)$(mandir)"
@list='$(srcdir)/doc/*.n'; for i in $$list; do \
echo "Installing $$i"; \
$(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/mann" ; \
done
test: binaries libraries
$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::postgres $(PACKAGE_VERSION) \
[list source `@CYGPATH@ $(srcdir)/library/tdbcpostgres.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` [string totitle $(PACKAGE_NAME)]]"
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
$(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
gdb-test: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(GDB) \
--args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
$(TESTFLAGS) -singleproc 1 \
-load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
[list load `@CYGPATH@ $(PKG_LIB_FILE)` [string totitle $(PACKAGE_NAME)]]"
valgrind: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
valgrindshell: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(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 = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean
$(INSTALL_DATA_DIR) $(DIST_DIR)
# TEA files
$(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
$(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
$(DIST_DIR)/
$(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
$(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
$(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
$(DIST_DIR)/tclconfig/
# Extension files
$(DIST_INSTALL_DATA) \
$(srcdir)/ChangeLog \
$(srcdir)/license.terms \
$(srcdir)/README \
$(srcdir)/pkgIndex.tcl.in \
$(srcdir)/TODO \
$(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/doc
$(DIST_INSTALL_DATA) $(srcdir)/doc/tdbc_postgres.n $(DIST_DIR)/doc/
$(INSTALL_DATA_DIR) $(DIST_DIR)/generic
$(DIST_INSTALL_DATA) $(srcdir)/generic/fakepq.h $(srcdir)/generic/pqStubDefs.txt \
$(srcdir)/generic/pqStubInit.c $(srcdir)/generic/pqStubs.h \
$(srcdir)/generic/tdbcpostgres.c \
$(srcdir)/generic/int2ptr_ptr2int.h \
$(DIST_DIR)/generic/
$(INSTALL_DATA_DIR) $(DIST_DIR)/library
$(DIST_INSTALL_DATA) $(srcdir)/library/tdbcpostgres.tcl $(DIST_DIR)/library/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tests
$(DIST_INSTALL_DATA) $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcpostgres.test \
$(DIST_DIR)/tests/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tests/future
$(DIST_INSTALL_DATA) $(srcdir)/tests/future/tdbcpostgre.test.tcl \
$(DIST_DIR)/tests/future/
$(INSTALL_DATA_DIR) $(DIST_DIR)/win
$(DIST_INSTALL_DATA) $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
$(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
$(srcdir)/win/rules.vc $(DIST_DIR)/win/
(cd $(DIST_ROOT); $(COMPRESS);)
#========================================================================
# How to rebuild the package's stub table.
#========================================================================
genstubs: $(TDBC_SRC_DIR)/tools/genExtStubs.tcl $(srcdir)/generic/pqStubDefs.txt
@echo $(TCLSH_PROGRAM) $(TDBC_SRC_DIR)/tools/genExtStubs.tcl \
$(srcdir)/generic/pqStubDefs.txt \
$(srcdir)/generic/pqStubs.h \
$(srcdir)/generic/pqStubInit.c
@$(TCLSH) $(TDBC_SRC_DIR)/tools/genExtStubs.tcl \
$(srcdir)/generic/pqStubDefs.txt \
$(srcdir)/generic/pqStubs.h \
$(srcdir)/generic/pqStubInit.c
#========================================================================
# End of user-definable section
#========================================================================
#========================================================================
# Don't modify the file to clean here. Instead, set the "CLEANFILES"
# variable in configure.ac
#========================================================================
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
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(pkglibdir)"
@list='$(lib_BINARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p "$(DESTDIR)$(pkglibdir)/$$p"; \
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
@$(INSTALL_DATA_DIR) "$(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
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
.PHONY: gdb gdb-test valgrind valgrindshell
# 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:

View File

@@ -0,0 +1,49 @@
README: tdbcpostgres
This is the 1.1.3 source distribution of the driver for Tcl
Database Connectivity (TDBC) to access Postgres databases. TDBC and
its drivers are available from a Fossil version control repository
at http://tdbc.tcl.tk/
RCS: @(#) $Id: $
1. Introduction
This directory contains the source code, documentation, and test
scripts for the Postgres driver for Tcl Database Connectivity. This
module, plus TDBC itself, allow you to access Postgres databases using
a standard application programming interface (API) from a Tcl script.
This module is also available from http://tdbc.tcl.tk along with the
source code of TDBC itself. A bug database and Wiki are available at
the same location.
Tdbc::postgres is a freely-available open source package. You can do
virtually anything you like with it, such as modifying it,
redistributing it, and selling it either in whole or in part. See the
file "license.terms" for complete information.
2. Compilation and Installation
This module follows the general configuration and installation
rules described in the README file for tdbc. Prior to running
'configure', you should ensure that the directory that contains
the Postgres executables (specifically, pg_config) is on the PATH.
pg_config, in turn, will locate the necessary #include files and
libraries to build the module.
NOTE THAT ON WINDOWS, THE DLL's FOR THE POSTGRES LIBRARY MUST BE ON
THE PATH AT RUNTIME.
3. Documentation
The 'doc' subdirectory in this release contains a set of reference
manual entries for tdbc::postgres. Files with an extension '.n' are
for Tcl classes and commands; files with an extension '.3' are for C
library functions. The file, 'doc/tdbcpostgres.n' gives an overview,
listing the classes and functions
4. See also
More information about TDBC and its drivers are available in the
README file for TDBC itself; refer to that file for compilation and
installation instructions, and support information.

View File

@@ -0,0 +1,5 @@
Issues:
-timeout configuration option now only sets connect_timeout option for PGconnect(), so the value
has now nothing to do with timeouts during operation (only with connection process to server). It's left as
readonly for now, but needs some improval or renaming.

86
pkgs/tdbcpostgres1.1.3/aclocal.m4 vendored Normal file
View File

@@ -0,0 +1,86 @@
#
# Include the TEA standard macro set
#
builtin(include,tclconfig/tcl.m4)
#
# Add here whatever m4 macros you want to define for your package
#
dnl Helper macros
AC_DEFUN([TEAX_LAPPEND], [$1="[$]{$1} $2"])
AC_DEFUN([TEAX_FOREACH], [for $1 in $2; do $3; done])
AC_DEFUN([TEAX_IFEQ], [AS_IF([test "x$1" = "x$2"], [$3])])
AC_DEFUN([TEAX_IFNEQ], [AS_IF([test "x$1" != "x$2"], [$3])])
AC_DEFUN([TEAX_SWITCH], [case "$1" in TEAX_SWITCH_Cases(m4_shift($@)) esac])
AC_DEFUN([TEAX_SWITCH_Cases], [m4_if([$#],0,,[$#],1,,[TEAX_SWITCH_OneCase($1,$2)TEAX_SWITCH_Cases(m4_shift(m4_shift($@)))])])
AC_DEFUN([TEAX_SWITCH_OneCase],[ $1) $2;;])
AC_DEFUN([CygPath],[`${CYGPATH} $1`])
dnl Interesting macros
AC_DEFUN([TEAX_SUBST_RESOURCE], [
AC_REQUIRE([TEA_CONFIG_CFLAGS])dnl
TEAX_IFEQ($TEA_PLATFORM, windows, [
AC_CHECK_PROGS(RC_, 'windres -o' 'rc -nologo -fo', none)
TEAX_SWITCH($RC_,
windres*, [
rcdef_inc="--include "
rcdef_start="--define "
rcdef_q='\"'
AC_SUBST(RES_SUFFIX, [res.o])
TEAX_LAPPEND(PKG_OBJECTS, ${PACKAGE_NAME}.res.o)],
rc*, [
rcdef_inc="-i "
rcdef_start="-d "
rcdef_q='"'
AC_SUBST(RES_SUFFIX, [res])
TEAX_LAPPEND(PKG_OBJECTS, ${PACKAGE_NAME}.res)],
*, [
AC_MSG_WARN([could not find resource compiler])
RC_=: ])])
# This next line is because of the brokenness of TEA...
AC_SUBST(RC, $RC_)
TEAX_FOREACH(i, $1, [
TEAX_LAPPEND(RES_DEFS, ${rcdef_inc}\"CygPath($i)\")])
TEAX_FOREACH(i, $2, [
TEAX_LAPPEND(RES_DEFS, ${rcdef_start}$i='${rcdef_q}\$($i)${rcdef_q}')])
AC_SUBST(RES_DEFS)])
AC_DEFUN([TEAX_ADD_PRIVATE_HEADERS], [
TEAX_FOREACH(i, $@, [
# check for existence, be strict because it should be present!
AS_IF([test ! -f "${srcdir}/$i"], [
AC_MSG_ERROR([could not find header file '${srcdir}/$i'])])
TEAX_LAPPEND(PKG_PRIVATE_HEADERS, $i)])
AC_SUBST(PKG_PRIVATE_HEADERS)])
AC_DEFUN([TEAX_SDX], [
AC_PATH_PROG(SDX, sdx, none)
TEAX_IFEQ($SDX, none, [
AC_PATH_PROG(SDX_KIT, sdx.kit, none)
TEAX_IFNEQ($SDX_KIT, none, [
# We assume that sdx.kit is on the path, and that the default
# tclsh is activetcl
SDX="tclsh '${SDX_KIT}'"])])
TEAX_IFEQ($SDX, none, [
AC_MSG_WARN([cannot find sdx; building starkits will fail])
AC_MSG_NOTICE([building as a normal library still supported])])])
dnl TODO: Adapt this for OSX Frameworks...
dnl This next bit is a bit ugly, but it makes things for tclooConfig.sh...
AC_DEFUN([TEAX_PATH_LINE], [
eval "$1=\"[]CygPath($2)\""
AC_SUBST($1)])
AC_DEFUN([TEAX_INCLUDE_LINE], [
eval "$1=\"-I[]CygPath($2)\""
AC_SUBST($1)])
AC_DEFUN([TEAX_LINK_LINE], [
AS_IF([test ${TCL_LIB_VERSIONS_OK} = nodots], [
eval "$1=\"-L[]CygPath($2) -l$3${TCL_TRIM_DOTS}\""
], [
eval "$1=\"-L[]CygPath($2) -l$3${PACKAGE_VERSION}\""
])
AC_SUBST($1)])
dnl Local Variables:
dnl mode: autoconf
dnl End:

10926
pkgs/tdbcpostgres1.1.3/configure vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
#!/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.
#-----------------------------------------------------------------------
# Sample configure.ac 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.
# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
# so that we create the export library with the dll.
#-----------------------------------------------------------------------
AC_INIT([tdbcpostgres],[1.1.3])
#--------------------------------------------------------------------
# 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()
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
#--------------------------------------------------------------------
# Load the tclooConfig.sh file on Tcl versions where oo is an
# extension.
#--------------------------------------------------------------------
if test "${TCL_MAJOR_VERSION}" -lt 8 ; then
AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6 or newer.
Found configuration for Tcl ${TCL_VERSION}.])
fi
if test "${TCL_MAJOR_VERSION}" -eq 8 ; then
if test "${TCL_MINOR_VERSION}" -lt 6 ; then
AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6 or newer.
Found configuration for Tcl ${TCL_VERSION}.])
fi
TCLOO_CFLAGS=''
fi
TCL_VERSION_REQ=8.6; AC_SUBST(TCL_VERSION_REQ)
TEA_PATH_CONFIG(tdbc)
TEA_LOAD_CONFIG(tdbc)
# The next bit probably ought to be in TEA_LOAD_CONFIG
AC_MSG_WARN([Looking for "${tdbc_BIN_DIR}/Makefile"])
if test -f "${tdbc_BIN_DIR}/Makefile" ; then
AC_MSG_WARN([Found Makefile - using build include spec and lib specs for tdbc])
tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
tdbc_LIBRARY_PATH=${tdbc_BUILD_LIBRARY_PATH}
fi
AC_SUBST(tdbc_LIBRARY_PATH)
AC_SUBST(TDBC_VERSION)
AC_SUBST(tdbc_SRC_DIR)
AC_SUBST(tdbc_BIN_DIR)
AC_SUBST(TDBC_LIB_FILE)
#-----------------------------------------------------------------------
# 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 and a few others to create the basic setup
# necessary to compile executables.
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
#-----------------------------------------------------------------------
# Setup inlining if available. Check sizeof long long, long.
#-----------------------------------------------------------------------
AC_C_INLINE
AC_CHECK_TYPE([long long],[
AC_DEFINE([HAVE_LONG_LONG],[1])
AC_CHECK_SIZEOF([long long])
],[],[])
AC_CHECK_SIZEOF([long])
#-----------------------------------------------------------------------
# __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(generic/tdbcpostgres.c generic/pqStubInit.c)
TEA_ADD_HEADERS(generic/fakepq.h generic/pqStubs.h)
if test "${TCL_MAJOR_VERSION}" -eq 8 ; then
if test "${TCL_MINOR_VERSION}" -eq 5 ; then
TEA_ADD_INCLUDES([${TCLOO_INCLUDE_SPEC}])
TEA_ADD_LIBS([${TCLOO_STUB_LIB_SPEC}])
fi
fi
TEA_ADD_CFLAGS([${TCLOO_CFLAGS}])
TEA_ADD_INCLUDES([${tdbc_INCLUDE_SPEC}])
if test "x${TEA_PLATFORM}" = "xwindows" -a "x${GCC}" != "xyes" ; then
TEA_ADD_LIBS([\"`${CYGPATH} ${tdbc_STUB_LIB_PATH}`\"])
else
TEA_ADD_LIBS([${tdbc_STUB_LIB_SPEC}])
fi
TEA_ADD_CFLAGS([${tdbc_CFLAGS}])
TEA_ADD_STUB_SOURCES()
TEA_ADD_TCL_SOURCES([library/tdbcpostgres.tcl])
#--------------------------------------------------------------------
# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
# A few miscellaneous platform-specific items:
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
# Ensure no empty if clauses
:
#TEA_ADD_SOURCES([win/winFile.c])
#TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
# Ensure no empty else clauses
:
#TEA_ADD_SOURCES([unix/unixFile.c])
#TEA_ADD_LIBS([-lsuperfly])
fi
#--------------------------------------------------------------------
# __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
#--------------------------------------------------------------------
# Integer pointer types used by the (U)INT2PTR / PTR2(U)INT macros.
#--------------------------------------------------------------------
AC_TYPE_INTPTR_T
AC_TYPE_UINTPTR_T
#--------------------------------------------------------------------
# Locate the ws2_32 library; we need it for ntohs and friends
#--------------------------------------------------------------------
AC_CHECK_LIB(ws2_32,main,TEA_ADD_LIBS([-lws2_32]),[
AC_CHECK_LIB(winsock,main,TEA_ADD_LIBS([-lwinsock]))
])
#--------------------------------------------------------------------
# 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 the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_CONFIG_FILES([Makefile pkgIndex.tcl])
AC_OUTPUT

View File

@@ -0,0 +1,157 @@
'\"
.\" tdbc_postgres.n --
.\"
.\" Copyright (c) 2009 by Slawomir Cygan
.\"
.\" See the file "license.terms" for information on usage and redistribution of
.\" this file, and for a DISCLAIMER OF ALL WARRANTIES.
.TH "tdbc::postgres" n 8.6 Tcl "Tcl Database Connectivity"
.\" .so man.macros
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.\" # BS - start boxed text
.\" # ^y = starting y location
.\" # ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.\" # BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\" Draw four-sided box normally, but don't draw top of
.\" box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.\" # CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
.\" # CE - end code excerpt
.de CE
.fi
.RE
..
.BS
.SH "NAME"
tdbc::postgres \- TDBC-POSTGRES bridge
.SH "SYNOPSIS"
package require \fBtdbc::postgres 1.0\fR
.sp
\fBtdbc::postgres::connection create\fR \fIdb\fR ?\fI-option value...\fR?
.br
\fBtdbc::postgres::connection new\fR ?\fI-option value...\fR?
.BE
.SH "DESCRIPTION"
.PP
The \fBtdbc::postgres\fR driver provides a database interface that conforms
to Tcl DataBase Connectivity (TDBC) and allows a Tcl script to connect
to a Postgres database.
.PP
Connection to a POSTGRES database is established by invoking
\fBtdbc::postgres::connection create\fR, passing it the name to give the
database handle and a set of \fI-option-value\fR pairs. The available
options are enumerated under CONNECTION OPTIONS below.
As an alternative, \fBtdbc::postgres::connection new\fR may be used to create
a database connection with an automatically assigned name. The return value
from \fBtdbc::postgres::connection new\fR is the name that was chosen for the
connection handle.
.PP
The side effect of \fBtdbc::postgres::connection create\fR is to create a
new database connection.. See \fBtdbc::connection(n)\fR for the
details of how to use the connection to manipulate a database.
.SH "CONNECTION OPTIONS"
.PP
The \fBtdbc::postgres::connection create\fR object command supports the
\fB-encoding\fR, \fB-isolation\fR, \fB-readonly\fR and \fB-timeout\fR
options common to all TDBC drivers. The \fB-timeout\fR option will
only affect connection process, once connected this value will be
ignored and cannot be changed after connecting.
.PP
In addition, the following options are recognized (these options must be
set on the initial creation of the connection; they cannot be changed
after connecting) :
.IP "\fB-host\fR \fIhostname\fR"
Connects to the host specified by \fIhostname\fR. Default is to connect using a local Unix domain socket.
.IP "\fB-hostaddr\fR \fIaddress\fR"
Connects to the host specified by given IP \fIaddress\fR. If both \fB-host\fR and \fB-hostaddr\fR are given, the value
of \fB-host\fR is ignored. Default is to connect using a local Unix domain socket.
.IP "\fB-port\fR \fInumber\fR"
Connects to a Postgres server listening on the port specified by \fInumber\fR.
It is used only when \fIhost\fR or \fIhostaddr\fR is specified.
.IP "\fB-user\fR \fIname\fR"
Presents \fIname\fR as the user name to the Postgres server. Default is the
current user ID.
.IP "\fB-passwd\fR \fIpassword\fR"
.IP "\fB-password\fR \fIpassword\fR"
These two options are synonymous. They present the given \fIpassword\fR as
the user's password to the Postgres server. Default is not to present a password.
.IP "\fB-database\fR \fIname\fR"
.IP "\fB-db\fR \fIname\fR"
These two options are synonymous. They present the given \fIname\fR as the
name of the default database to use in Postgres queries. If not specified,
the default database for the current user is used.
.IP "\fB-options\fR \fIopts\fR"
This sets \fIopts\fR as additional command line options send to the server.
.IP "\fB-tty\fR \fIfile\fR"
This option is ignored on never servers. Formerly this specified where to send debug
output. This option is left for compatibility with older servers.
.IP "\fB-sslmode\fR \fImode\fR"
This option determines whether or with what priority an SSL connection will be negotiated with
the server. There are four \fImodes\fR: \fBdisable\fR will attempt only an unencrypted SSL connection;
\fBallow\fR will negotiate, trying first a non-SSL connection, then if that fails, trying an SSL
connection; \fBprefer\fR (the default) will negotiate, trying first an SSL connection,
then if that fails, trying a regular non-SSL connection; \fBrequire\fR will try only an SSL connection.
If PostgreSQL is compiled without SSL support, using option \fBrequire\fR will cause an error,
and options \fBallow\fR and \fBprefer\fR will be tolerated but the driver will be unable to negotiate
an SSL connection.
.IP \fB-requiressl\fR \fIflag\fR
This option is deprecated in favor of the \fB-sslmode\fR setting.
The \fIflag\fR value must be a Boolean value. If it is \fBtrue\fR (or
any equivalent), driver will then refuse to connect if the server does
not accept an SSL connection. The default value is \fBfalse\fR (or any
equivalent), and acts the same like \fB-sslmode\fR \fBpreffered\fR
.IP \fB-service\fR \fIname\fR
It specifies a service \fIname\fR in pg_service.conf file that holds additional connection parameters.
This allows applications to specify only a service name so connection parameters can be
centrally maintained. Refer to PostgreSQL Documentation or PREFIX/share/pg_service.conf.sample file
for details.
.SH EXAMPLES
.PP
.CS
tdbc::postgres::connection -user joe -passwd sesame -db joes_database
.CE
Connects to the Postgres server on the local host using the default
connection method, presenting user ID 'joe' and password 'sesame'.
Uses 'joes_database' as the default database name.
.SH "SEE ALSO"
tdbc(n), tdbc::connection(n), tdbc::resultset(n), tdbc::statement(n)
.SH "KEYWORDS"
TDBC, SQL, Postgres, database, connectivity, connection
.SH "COPYRIGHT"
Copyright (c) 2009 by Slawomir Cygan
.\" Local Variables:
.\" mode: nroff
.\" End:
.\"

View File

@@ -0,0 +1,46 @@
/*
* fakepq.h --
*
* Minimal replacement for 'pq-fe.h' in the PostgreSQL client
* without having a PostgreSQL installation on the build system.
* This file comprises only data type, constant and function definitions.
*
* The programmers of this file believe that it contains material not
* subject to copyright under the doctrines of scenes a faire and
* of merger of idea and expression. Accordingly, this file is in the
* public domain.
*
*-----------------------------------------------------------------------------
*/
#ifndef FAKEPQ_H_INCLUDED
#define FAKEPQ_H_INCLUDED
#ifndef MODULE_SCOPE
#define MODULE_SCOPE extern
#endif
MODULE_SCOPE Tcl_LoadHandle PostgresqlInitStubs(Tcl_Interp*);
typedef enum {
CONNECTION_OK=0,
} ConnStatusType;
typedef enum {
PGRES_EMPTY_QUERY=0,
PGRES_BAD_RESPONSE=5,
PGRES_NONFATAL_ERROR=6,
PGRES_FATAL_ERROR=7,
} ExecStatusType;
typedef unsigned int Oid;
typedef struct pg_conn PGconn;
typedef struct pg_result PGresult;
typedef void (*PQnoticeProcessor)(void*, const PGresult*);
#define PG_DIAG_SQLSTATE 'C'
#define PG_DIAG_MESSAGE_PRIMARY 'M'
#include "pqStubs.h"
MODULE_SCOPE const pqStubDefs* pqStubs;
#endif

View File

@@ -0,0 +1,24 @@
/*
* Macros used to cast between pointers and integers (e.g. when storing an int
* in ClientData), on 64-bit architectures they avoid gcc warning about "cast
* to/from pointer from/to integer of different size".
*/
#if !defined(INT2PTR) && !defined(PTR2INT)
# if defined(HAVE_INTPTR_T) || defined(intptr_t)
# define INT2PTR(p) ((void *)(intptr_t)(p))
# define PTR2INT(p) ((int)(intptr_t)(p))
# else
# define INT2PTR(p) ((void *)(p))
# define PTR2INT(p) ((int)(p))
# endif
#endif
#if !defined(UINT2PTR) && !defined(PTR2UINT)
# if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
# define UINT2PTR(p) ((void *)(uintptr_t)(p))
# define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
# else
# define UINT2PTR(p) ((void *)(p))
# define PTR2UINT(p) ((unsigned int)(p))
# endif
#endif

View File

@@ -0,0 +1,50 @@
# pqStubDefs.txt --
#
# Definitions of routines in the PostgreSQL libraries that will be
# resolved and imported at run time.
#
# This file contains only function declarations necessary to
# interoperability with the PostgreSQL application programming
# interface. The programmers believe that the material in this file is
# not subject to copyright, under the doctrines of scenes a faire and
# of the merger of idea and expression. Accordingly, this file is in
# the public domain.
#
#-----------------------------------------------------------------------------
* STUBSTRUCT: pqStubs
* LIBRARY: pq
const char* pg_encoding_to_char(int);
void PQclear(PGresult*);
int PQclientEncoding(const PGconn*);
char* PQcmdTuples(PGresult*);
PGconn* PQconnectdb(const char*);
char* PQerrorMessage(const PGconn*);
PGresult* PQdescribePrepared(PGconn*, const char*);
PGresult* PQexec(PGconn*, const char*);
PGresult* PQexecPrepared(PGconn*, const char*, int, const char *const*, const int*, const int*, int);
char* PQdb(const PGconn *);
void PQfinish(PGconn*);
char* PQfname(PGresult*, int);
int PQfnumber(const PGresult*, const char*);
Oid PQftype(const PGresult*, int);
int PQgetisnull(const PGresult*, int, int);
int PQgetlength(const PGresult*, int, int);
char* PQgetvalue(const PGresult*, int, int);
char* PQhost(const PGconn*);
int PQnfields(const PGresult*);
int PQnparams(const PGresult*);
int PQntuples(const PGresult*);
char* PQoptions(const PGconn*);
Oid PQparamtype(const PGresult*, int);
char* PQpass(const PGconn*);
char* PQport(const PGconn*);
PGresult* PQprepare(PGconn*, const char*, const char*, int, const Oid*);
char* PQresultErrorField(const PGresult*, int);
ExecStatusType PQresultStatus(const PGresult*);
int PQsetClientEncoding(PGconn*, const char*);
PQnoticeProcessor PQsetNoticeProcessor(PGconn*, PQnoticeProcessor, void*);
ConnStatusType PQstatus(PGconn*);
char* PQuser(const PGconn*);
char* PQtty(const PGconn*);

View File

@@ -0,0 +1,170 @@
/*
* pqStubInit.c --
*
* Stubs tables for the foreign PostgreSQL libraries so that
* Tcl extensions can use them without the linker's knowing about them.
*
* @CREATED@ 2015-06-26 12:55:15Z by genExtStubs.tcl from ../generic/pqStubDefs.txt
*
* Copyright (c) 2010 by Kevin B. Kenny.
*
* Please refer to the file, 'license.terms' for the conditions on
* redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES.
*
*-----------------------------------------------------------------------------
*/
#include <tcl.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include "fakepq.h"
/*
* Static data used in this file
*/
/*
* Names of the libraries that might contain the PostgreSQL API
*/
#if defined(__CYGWIN__) && !defined(LIBPREFIX)
# define LIBPREFIX "cyg"
#else
# define LIBPREFIX "lib"
#endif
static const char *const pqStubLibNames[] = {
/* @LIBNAMES@: DO NOT EDIT THESE NAMES */
"pq", NULL
/* @END@ */
};
/* ABI Version numbers of the PostgreSQL API that we can cope with */
static const char pqSuffixes[][4] = {
"", ".5"
};
/* Names of the functions that we need from PostgreSQL */
static const char *const pqSymbolNames[] = {
/* @SYMNAMES@: DO NOT EDIT THESE NAMES */
"pg_encoding_to_char",
"PQclear",
"PQclientEncoding",
"PQcmdTuples",
"PQconnectdb",
"PQerrorMessage",
"PQdescribePrepared",
"PQexec",
"PQexecPrepared",
"PQdb",
"PQfinish",
"PQfname",
"PQfnumber",
"PQftype",
"PQgetisnull",
"PQgetlength",
"PQgetvalue",
"PQhost",
"PQnfields",
"PQnparams",
"PQntuples",
"PQoptions",
"PQparamtype",
"PQpass",
"PQport",
"PQprepare",
"PQresultErrorField",
"PQresultStatus",
"PQsetClientEncoding",
"PQsetNoticeProcessor",
"PQstatus",
"PQuser",
"PQtty",
NULL
/* @END@ */
};
/*
* Table containing pointers to the functions named above.
*/
static pqStubDefs pqStubsTable;
const pqStubDefs* pqStubs = &pqStubsTable;
/*
*-----------------------------------------------------------------------------
*
* PQInitStubs --
*
* Initialize the Stubs table for the PostgreSQL API
*
* Results:
* Returns the handle to the loaded PostgreSQL client library, or NULL
* if the load is unsuccessful. Leaves an error message in the
* interpreter.
*
*-----------------------------------------------------------------------------
*/
MODULE_SCOPE Tcl_LoadHandle
PostgresqlInitStubs(Tcl_Interp* interp)
{
int i;
size_t j;
int status; /* Status of Tcl library calls */
Tcl_Obj* path; /* Path name of a module to be loaded */
Tcl_Obj* shlibext; /* Extension to use for load modules */
Tcl_LoadHandle handle = NULL;
/* Handle to a load module */
/* Determine the shared library extension */
status = Tcl_EvalEx(interp, "::info sharedlibextension", -1,
TCL_EVAL_GLOBAL);
if (status != TCL_OK) return NULL;
shlibext = Tcl_GetObjResult(interp);
Tcl_IncrRefCount(shlibext);
/* Walk the list of possible library names to find an PostgreSQL client */
status = TCL_ERROR;
for (i = 0; status == TCL_ERROR && pqStubLibNames[i] != NULL; ++i) {
for (j = 0; status == TCL_ERROR && (j < sizeof(pqSuffixes)/sizeof(pqSuffixes[0])); ++j) {
path = Tcl_NewStringObj(LIBPREFIX, -1);
Tcl_AppendToObj(path, pqStubLibNames[i], -1);
#ifdef __CYGWIN__
if (*pqSuffixes[j]) {
Tcl_AppendToObj(path, "-", -1);
Tcl_AppendToObj(path, pqSuffixes[j]+1, -1);
}
#endif
Tcl_AppendObjToObj(path, shlibext);
#ifndef __CYGWIN__
Tcl_AppendToObj(path, pqSuffixes[j], -1);
#endif
Tcl_IncrRefCount(path);
/* Try to load a client library and resolve symbols within it. */
Tcl_ResetResult(interp);
status = Tcl_LoadFile(interp, path, pqSymbolNames, 0,
&pqStubsTable, &handle);
Tcl_DecrRefCount(path);
}
}
/*
* Either we've successfully loaded a library (status == TCL_OK),
* or we've run out of library names (in which case status==TCL_ERROR
* and the error message reflects the last unsuccessful load attempt).
*/
Tcl_DecrRefCount(shlibext);
if (status != TCL_OK) {
return NULL;
}
return handle;
}

View File

@@ -0,0 +1,85 @@
/*
*-----------------------------------------------------------------------------
*
* ../generic/pqStubs.h --
*
* Stubs for procedures in pqStubDefs.txt
*
* Generated by genExtStubs.tcl: DO NOT EDIT
* 2015-06-26 12:55:15Z
*
*-----------------------------------------------------------------------------
*/
typedef struct pqStubDefs {
/* Functions from libraries: pq */
const char* (*pg_encoding_to_charPtr)(int);
void (*PQclearPtr)(PGresult*);
int (*PQclientEncodingPtr)(const PGconn*);
char* (*PQcmdTuplesPtr)(PGresult*);
PGconn* (*PQconnectdbPtr)(const char*);
char* (*PQerrorMessagePtr)(const PGconn*);
PGresult* (*PQdescribePreparedPtr)(PGconn*, const char*);
PGresult* (*PQexecPtr)(PGconn*, const char*);
PGresult* (*PQexecPreparedPtr)(PGconn*, const char*, int, const char *const*, const int*, const int*, int);
char* (*PQdbPtr)(const PGconn *);
void (*PQfinishPtr)(PGconn*);
char* (*PQfnamePtr)(PGresult*, int);
int (*PQfnumberPtr)(const PGresult*, const char*);
Oid (*PQftypePtr)(const PGresult*, int);
int (*PQgetisnullPtr)(const PGresult*, int, int);
int (*PQgetlengthPtr)(const PGresult*, int, int);
char* (*PQgetvaluePtr)(const PGresult*, int, int);
char* (*PQhostPtr)(const PGconn*);
int (*PQnfieldsPtr)(const PGresult*);
int (*PQnparamsPtr)(const PGresult*);
int (*PQntuplesPtr)(const PGresult*);
char* (*PQoptionsPtr)(const PGconn*);
Oid (*PQparamtypePtr)(const PGresult*, int);
char* (*PQpassPtr)(const PGconn*);
char* (*PQportPtr)(const PGconn*);
PGresult* (*PQpreparePtr)(PGconn*, const char*, const char*, int, const Oid*);
char* (*PQresultErrorFieldPtr)(const PGresult*, int);
ExecStatusType (*PQresultStatusPtr)(const PGresult*);
int (*PQsetClientEncodingPtr)(PGconn*, const char*);
PQnoticeProcessor (*PQsetNoticeProcessorPtr)(PGconn*, PQnoticeProcessor, void*);
ConnStatusType (*PQstatusPtr)(PGconn*);
char* (*PQuserPtr)(const PGconn*);
char* (*PQttyPtr)(const PGconn*);
} pqStubDefs;
#define pg_encoding_to_char (pqStubs->pg_encoding_to_charPtr)
#define PQclear (pqStubs->PQclearPtr)
#define PQclientEncoding (pqStubs->PQclientEncodingPtr)
#define PQcmdTuples (pqStubs->PQcmdTuplesPtr)
#define PQconnectdb (pqStubs->PQconnectdbPtr)
#define PQerrorMessage (pqStubs->PQerrorMessagePtr)
#define PQdescribePrepared (pqStubs->PQdescribePreparedPtr)
#define PQexec (pqStubs->PQexecPtr)
#define PQexecPrepared (pqStubs->PQexecPreparedPtr)
#define PQdb (pqStubs->PQdbPtr)
#define PQfinish (pqStubs->PQfinishPtr)
#define PQfname (pqStubs->PQfnamePtr)
#define PQfnumber (pqStubs->PQfnumberPtr)
#define PQftype (pqStubs->PQftypePtr)
#define PQgetisnull (pqStubs->PQgetisnullPtr)
#define PQgetlength (pqStubs->PQgetlengthPtr)
#define PQgetvalue (pqStubs->PQgetvaluePtr)
#define PQhost (pqStubs->PQhostPtr)
#define PQnfields (pqStubs->PQnfieldsPtr)
#define PQnparams (pqStubs->PQnparamsPtr)
#define PQntuples (pqStubs->PQntuplesPtr)
#define PQoptions (pqStubs->PQoptionsPtr)
#define PQparamtype (pqStubs->PQparamtypePtr)
#define PQpass (pqStubs->PQpassPtr)
#define PQport (pqStubs->PQportPtr)
#define PQprepare (pqStubs->PQpreparePtr)
#define PQresultErrorField (pqStubs->PQresultErrorFieldPtr)
#define PQresultStatus (pqStubs->PQresultStatusPtr)
#define PQsetClientEncoding (pqStubs->PQsetClientEncodingPtr)
#define PQsetNoticeProcessor (pqStubs->PQsetNoticeProcessorPtr)
#define PQstatus (pqStubs->PQstatusPtr)
#define PQuser (pqStubs->PQuserPtr)
#define PQtty (pqStubs->PQttyPtr)
MODULE_SCOPE const pqStubDefs *pqStubs;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
# tdbcpostgres.tcl --
#
# Class definitions and Tcl-level methods for the tdbc::postgres bridge.
#
# Copyright (c) 2009 by Slawomir Cygan
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------------
package require tdbc
::namespace eval ::tdbc::mypostgres {
namespace export connection datasources drivers
}
#------------------------------------------------------------------------------
#
# tdbc::postgres::connection --
#
# Class representing a connection to a Postgres database.
#
#-------------------------------------------------------------------------------
::oo::class create ::tdbc::postgres::connection {
superclass ::tdbc::connection
# The constructor is written in C. It takes alternating keywords
# and values pairs as its arguments. (See the manual page for the
# available options.)
# The 'statementCreate' method delegates to the constructor of the
# statement class
forward statementCreate ::tdbc::postgres::statement create
# The 'prepareCall' method gives a portable interface to prepare
# calls to stored procedures. It delegates to 'prepare' to do the
# actual work.
method preparecall {call} {
regexp {^[[:space:]]*(?:([A-Za-z_][A-Za-z_0-9]*)[[:space:]]*=)?(.*)} \
$call -> varName rest
if {$varName eq {}} {
my prepare \\{$rest\\}
} else {
my prepare \\{:$varName=$rest\\}
}
}
# The 'init', 'begintransaction', 'commit, 'rollback', 'tables'
# and 'columns' methods are implemented in C.
}
#------------------------------------------------------------------------------
#
# tdbc::postgres::statement --
#
# The class 'tdbc::postgres::statement' models one statement against a
# database accessed through a Postgres connection
#
#------------------------------------------------------------------------------
::oo::class create ::tdbc::postgres::statement {
superclass ::tdbc::statement
# The 'resultSetCreate' method forwards to the constructor of the
# result set.
forward resultSetCreate ::tdbc::postgres::resultset create
# Methods implemented in C:
#
# constructor connection SQLCode
# The constructor accepts the handle to the connection and the SQL code
# for the statement to prepare. It creates a subordinate namespace to
# hold the statement's active result sets, and then delegates to the
# 'init' method, written in C, to do the actual work of preparing the
# statement.
# params
# Returns descriptions of the parameters of a statement.
# paramtype paramname ?direction? type ?precision ?scale??
# Declares the type of a parameter in the statement
}
#------------------------------------------------------------------------------
#
# tdbc::postgres::resultset --
#
# The class 'tdbc::postgres::resultset' models the result set that is
# produced by executing a statement against a Postgres database.
#
#------------------------------------------------------------------------------
::oo::class create ::tdbc::postgres::resultset {
superclass ::tdbc::resultset
# The 'nextresults' method is stubbed out; tdbcpostgres does not
# allow a single call to return multiple results.
method nextresults {} {
while {[my nextdict rubbish]} {}
return 0
}
# Methods implemented in C include:
# constructor statement ?dictionary?
# -- Executes the statement against the database, optionally providing
# a dictionary of substituted parameters (default is to get params
# from variables in the caller's scope).
# columns
# -- Returns a list of the names of the columns in the result.
# nextdict
# -- Stores the next row of the result set in the given variable in
# the caller's scope as a dictionary whose keys are
# column names and whose values are column values, or else
# as a list of cells.
# nextlist
# -- Stores the next row of the result set in the given variable in
# the caller's scope as a list of cells.
# rowcount
# -- Returns a count of rows affected by the statement, or -1
# if the count of rows has not been determined.
}

View File

@@ -0,0 +1,38 @@
This software is copyrighted by Slawomir Cygan, and by other parties.
The following terms apply to all files associated with the software
unless explicitly disclaimed in individual files.
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors
and need not follow the licensing terms described here, provided that
the new terms are clearly indicated on the first page of each file where
they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights"
in the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
are acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.

View File

@@ -0,0 +1,14 @@
# Index file to load the TDBC Postgres package.
if {![package vsatisfies [package provide Tcl] 8.6-]} {
return
}
if {[package vsatisfies [package provide Tcl] 9.0-]} {
package ifneeded tdbc::postgres @PACKAGE_VERSION@ \
"[list source [file join $dir @PACKAGE_NAME@.tcl]]\;\
[list load [file join $dir @PKG_LIB_FILE9@] [string totitle @PACKAGE_NAME@]]"
} else {
package ifneeded tdbc::postgres @PACKAGE_VERSION@ \
"[list source [file join $dir @PACKAGE_NAME@.tcl]]\;\
[list load [file join $dir @PKG_LIB_FILE8@] [string totitle @PACKAGE_NAME@]]"
}

View File

@@ -0,0 +1,26 @@
These files comprise the basic building blocks for a Tcl Extension
Architecture (TEA) extension. For more information on TEA see:
http://www.tcl.tk/doc/tea/
This package is part of the Tcl project at SourceForge, but sources
and bug/patch database are hosted on fossil here:
https://core.tcl-lang.org/tclconfig
This package is a freely available open source package. You can do
virtually anything you like with it, such as modifying it, redistributing
it, and selling it either in whole or in part.
CONTENTS
========
The following is a short description of the files you will find in
the sample extension.
README.txt This file
install-sh Program used for copying binaries and script files
to their install locations.
tcl.m4 Collection of Tcl autoconf macros. Included by a package's
aclocal.m4 to define TEA_* macros.

View File

@@ -0,0 +1,518 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2020-07-26.22; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-S OPTION $stripprog installed files using OPTION.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-S) stripcmd="$stripprog $2"
shift;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
# The $RANDOM variable is not portable (e.g., dash). Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap '
ret=$?
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
exit $ret
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
# all.tcl --
#
# This file contains a top-level script to run all of the Tcl
# tests. Execute it by invoking "source all.test" when running tcltest
# in this directory.
#
# Copyright (c) 1998-2000 by Scriptics Corporation.
# All rights reserved.
#
# RCS: @(#) $Id: all.tcl,v 1.4 2004/07/04 22:04:20 patthoyts Exp $
package require Tcl 8.6-
package require tcltest 2.2
::tcltest::configure \
-testdir [file dirname [file normalize [info script]]] \
{*}$argv
::tcltest::runAllTests

View File

@@ -0,0 +1,203 @@
#this test was abandonded, because no flags are used as for now
test tdbc::postgres-1.4 {create a connection, bad flag} {*}{
-body {
tdbc::postgres::connection create db -interactive rubbish
}
-returnCodes error
-result {expected boolean value but got "rubbish"}
}
#"-timeout" option cannot be changed dynamically
test tdbc::postgres-19.15 {$connection configure - -timeout} {*}{
-body {
set x [::db configure -timeout]
list [::db configure -timeout 5000] [::db configure -timeout] \
[::db configure -timeout $x]
}
-result {{} 5000 {}}
}
############### FUTURE tests:
test tdbc::postgres-20.2 {direct value transfers} {*}{
-setup {
set bigtext [string repeat a 200]
set bigbinary [string repeat \xc2\xa1 100]
catch {db allrows {DROP TABLE typetest}}
db allrows {
CREATE TABLE typetest (
xtiny1 TINYINT,
xsmall1 SMALLINT,
xint1 INTEGER,
xfloat1 FLOAT,
xdouble1 DOUBLE,
xtimestamp1 TIMESTAMP,
xbig1 BIGINT,
xmed1 MEDIUMINT,
xdate1 DATE,
xtime1 TIME,
xdatetime1 DATETIME,
xyear1 YEAR,
xbit1 BIT(14),
xdec1 DECIMAL(10),
xtinyt1 TINYTEXT,
xtinyb1 TINYBLOB,
xmedt1 MEDIUMTEXT,
xmedb1 MEDIUMBLOB,
xlongt1 LONGTEXT,
xlongb1 LONGBLOB,
xtext1 TEXT,
xblob1 BLOB,
xvarb1 VARBINARY(256),
xvarc1 VARCHAR(256),
xbin1 BINARY(20),
xchar1 CHAR(20)
)
}
set stmt [db prepare {
INSERT INTO typetest(
xtiny1, xsmall1, xint1, xfloat1,
xdouble1, xtimestamp1, xbig1, xmed1,
xdate1, xtime1, xdatetime1, xyear1,
xbit1, xdec1, xtinyt1, xtinyb1,
xmedt1, xmedb1, xlongt1, xlongb1,
xtext1, xblob1, xvarb1, xvarc1,
xbin1, xchar1
) values (
:xtiny1, :xsmall1, :xint1, :xfloat1,
:xdouble1, :xtimestamp1, :xbig1, :xmed1,
:xdate1, :xtime1, :xdatetime1, :xyear1,
:xbit1, :xdec1, :xtinyt1, :xtinyb1,
:xmedt1, :xmedb1, :xlongt1, :xlongb1,
:xtext1, :xblob1, :xvarb1, :xvarc1,
:xbin1, :xchar1
)
}]
$stmt paramtype xtiny1 tinyint
$stmt paramtype xsmall1 smallint
$stmt paramtype xint1 integer
$stmt paramtype xfloat1 float
$stmt paramtype xdouble1 double
$stmt paramtype xtimestamp1 timestamp
$stmt paramtype xbig1 bigint
$stmt paramtype xmed1 mediumint
$stmt paramtype xdate1 date
$stmt paramtype xtime1 time
$stmt paramtype xdatetime1 datetime
$stmt paramtype xyear1 year
$stmt paramtype xbit1 bit 14
$stmt paramtype xdec1 decimal 10 0
$stmt paramtype xtinyt1 tinytext
$stmt paramtype xtinyb1 tinyblob
$stmt paramtype xmedt1 mediumtext
$stmt paramtype xmedb1 mediumblob
$stmt paramtype xlongt1 longtext
$stmt paramtype xlongb1 longblob
$stmt paramtype xtext1 text
$stmt paramtype xblob1 blob
$stmt paramtype xvarb1 varbinary
$stmt paramtype xvarc1 varchar
$stmt paramtype xbin1 binary 20
$stmt paramtype xchar1 char 20
}
-body {
set trouble {}
set xtiny1 0x14
set xsmall1 0x3039
set xint1 0xbc614e
set xfloat1 1.125
set xdouble1 1.125
set xtimestamp1 {2001-02-03 04:05:06}
set xbig1 0xbc614e
set xmed1 0x3039
set xdate1 2001-02-03
set xtime1 04:05:06
set xdatetime1 {2001-02-03 04:05:06}
set xyear1 2001
set xbit1 0b11010001010110
set xdec1 0xbc614e
set xtinyt1 $bigtext
set xtinyb1 $bigbinary
set xmedt1 $bigtext
set xmedb1 $bigbinary
set xlongt1 $bigtext
set xlongb1 $bigbinary
set xtext1 $bigtext
set xblob1 $bigbinary
set xvarb1 $bigbinary
set xvarc1 $bigtext
set xbin1 [string repeat \xc2\xa1 10]
set xchar1 [string repeat a 20]
$stmt allrows
db foreach row {select * from typetest} {
foreach v {
xtiny1 xsmall1 xint1 xfloat1
xdouble1 xtimestamp1 xbig1 xmed1
xdate1 xtime1 xdatetime1 xyear1
xbit1 xdec1 xtinyt1 xtinyb1
xmedt1 xmedb1 xlongt1 xlongb1
xtext1 xblob1 xvarb1 xvarc1
xbin1 xchar1
} {
if {![dict exists $row $v]} {
append trouble $v " did not appear in result set\n"
} elseif {[set $v] != [dict get $row $v]} {
append trouble [list $v is [dict get $row $v] \
should be [set $v]] \n
}
}
}
set trouble
}
-result {}
-cleanup {
$stmt close
db allrows {
DROP TABLE typetest
}
}
}
test tdbc::postgres-21.2 {transfers of binary data} {*}{
-setup {
catch {
db allrows {DROP TABLE bintest}
}
db allrows {
CREATE TABLE bintest (
xint1 INTEGER PRIMARY KEY,
xbin VARBINARY(256)
)
}
set stmt1 [db prepare {
INSERT INTO bintest (xint1, xbin)
VALUES(:i1, :b1)
}]
$stmt1 paramtype i1 integer
$stmt1 paramtype b1 varbinary 256
set stmt2 [db prepare {
SELECT xbin FROM bintest WHERE xint1 = :i1
}]
$stmt2 paramtype i1 integer
}
-body {
set listdata {}
for {set i 0} {$i < 256} {incr i} {
lappend listdata $i
}
set b1 [binary format c* $listdata]
set i1 123
$stmt1 allrows
$stmt2 foreach -as lists row { set b2 [lindex $row 0] }
list [string length $b2] [string compare $b1 $b2]
}
-result {256 0}
-cleanup {
$stmt1 close
$stmt2 close
db allrows {DROP TABLE bintest}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
#------------------------------------------------------------- -*- makefile -*-
#
# Makefile for TBDC Postgres interface
#
# Basic build, test and install
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
#
# For other build options (debug, static etc.)
# See TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------------
PROJECT = tdbcpostgres
# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
# without -DUNICODE. Keep that behaviour.
USE_WIDECHAR_API = 0
!include "rules-ext.vc"
# nmakehelp -V <file> <tag> will search the file for tag, skips until a
# number and returns all character until a character not in [0-9.ab]
# is read.
!if [echo REM = This file is generated from Makefile.vc > versions.vc]
!endif
!if [echo TCL_VERSION_REQ = \>> versions.vc] \
&& [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
!endif
!include "versions.vc"
PRJ_OBJS = \
$(TMP_DIR)\tdbcpostgres.obj \
$(TMP_DIR)\pqStubInit.obj
# Uncomment the following line if you want to build and install stubs
# PRJ_STUBOBJS = $(TMP_DIR)\pqStubInit.obj
PRJ_HEADERS = \
$(GENERICDIR)\fakepq.h \
$(GENERICDIR)\pqStubs.h
# Locate TDBC headers and libraries.
# In principle, we don't need the TDBC source directory, and an installed
# TDBC should suffice. But that needs additional machinery not implemented
# yet.
!if [echo TDBC_DIR = \> nmakehlp.out] \
|| [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
!error Could not locate TDBC source directory.
!endif
!include nmakehlp.out
# Get the TDBC version from its configure.ac
!if [echo TDBC_DOTVERSION = \> versions.vc] \
&& [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
!error Could not retrieve TDBC version.
!endif
!include versions.vc
TDBC_VERSION = $(TDBC_DOTVERSION:.=)
TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
!if !$(STATIC_BUILD)
PRJ_LIBS = $(TDBCSTUBLIB)
!endif
# Disable standard test target because we have a custom one
DISABLE_TARGET_test = 1
!include "$(_RULESDIR)\targets.vc"
# Additional default actions for install
install: default-install-docs-n
# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
# all replacements below so define our own target.
pkgindex: $(OUT_DIR)\pkgIndex.tcl
$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
@nmakehlp -s << $** > $@
@PACKAGE_NAME@ $(PROJECT)
@PACKAGE_VERSION@ $(DOTVERSION)
@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
@PKG_LIB_FILE@ $(PRJLIBNAME)
@PKG_LIB_FILE8@ $(PRJLIBNAME8)
@PKG_LIB_FILE9@ $(PRJLIBNAME9)
<<
test: setup $(PROJECT)
@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
@set TCLLIBPATH=$(OUT_DIR:\=/)
@set TDBC_LIBRARY=$(LIBDIR:\=/)
@$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
!if $(TCLINSTALL)
@set PATH=$(_TCLDIR)\bin;$(PATH)
$(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
!else
@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
$(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
-load "package ifneeded tdbc::postgres $(DOTVERSION) \
{source {$(LIBDIR:\=/)/tdbcpostgres.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
package ifneeded tdbc $(TDBC_DOTVERSION) \
{source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
!endif

View File

@@ -0,0 +1,815 @@
/*
* ----------------------------------------------------------------------------
* nmakehlp.c --
*
* This is used to fix limitations within nmake and the environment.
*
* Copyright (c) 2002 by David Gravereaux.
* Copyright (c) 2006 by Pat Thoyts
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
* ----------------------------------------------------------------------------
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#include <stdio.h>
#include <math.h>
/*
* This library is required for x64 builds with _some_ versions of MSVC
*/
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif
/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
/* protos */
static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(const char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
#define CHUNK 25
#define STATICBUFFERSIZE 1000
typedef struct {
HANDLE pipe;
char buffer[STATICBUFFERSIZE];
} pipeinfo;
pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
/*
* exitcodes: 0 == no, 1 == yes, 2 == error
*/
int
main(
int argc,
char *argv[])
{
char msg[300];
DWORD dwWritten;
int chars;
const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
*/
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
/*
* Make sure the compiler and linker aren't effected by the outside world.
*/
SetEnvironmentVariable("CL", "");
SetEnvironmentVariable("LINK", "");
if (argc > 1 && *argv[1] == '-') {
switch (*(argv[1]+1)) {
case 'c':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -c <compiler option>\n"
"Tests for whether cl.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForCompilerFeature(argv[2]);
case 'l':
if (argc < 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -l <linker option> ?<mandatory option> ...?\n"
"Tests for whether link.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForLinkerFeature(&argv[2], argc-2);
case 'f':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -f <string> <substring>\n"
"Find a substring within another\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
} else if (argc == 3) {
/*
* If the string is blank, there is no match.
*/
return 0;
} else {
return IsIn(argv[2], argv[3]);
}
case 's':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -s <substitutions file> <file>\n"
"Perform a set of string map type substutitions on a file\n"
"exitcodes: 0\n",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return SubstituteFile(argv[2], argv[3]);
case 'V':
if (argc != 4) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -V filename matchstring\n"
"Extract a version from a file:\n"
"eg: pkgIndex.tcl \"package ifneeded http\"",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 0;
}
s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
if (s && *s) {
printf("%s\n", s);
return 0;
} else
return 1; /* Version not found. Return non-0 exit code */
case 'Q':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -Q path\n"
"Emit the fully qualified path\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return QualifyPath(argv[2]);
case 'L':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -L keypath\n"
"Emit the fully qualified path of directory containing keypath\n"
"exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return LocateDependency(argv[2]);
}
}
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -c|-f|-l|-Q|-s|-V ...\n"
"This is a little helper app to equalize shell differences between WinNT and\n"
"Win9x and get nmake.exe to accomplish its job.\n",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
return 2;
}
static int
CheckForCompilerFeature(
const char *option)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD threadID;
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
char cmdline[100];
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
/*
* Create a non-inheritible pipe.
*/
CreatePipe(&Out.pipe, &h, &sa, 0);
/*
* Dupe the write side, make it inheritible, and close the original.
*/
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Same as above, but for the error side.
*/
CreatePipe(&Err.pipe, &h, &sa, 0);
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Base command line.
*/
lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
/*
* Append our option for testing
*/
lstrcat(cmdline, option);
/*
* Filename to compile, which exists, but is nothing and empty.
*/
lstrcat(cmdline, " .\\nul");
ok = CreateProcess(
NULL, /* Module name. */
cmdline, /* Command line. */
NULL, /* Process handle not inheritable. */
NULL, /* Thread handle not inheritable. */
TRUE, /* yes, inherit handles. */
DETACHED_PROCESS, /* No console for you. */
NULL, /* Use parent's environment block. */
NULL, /* Use parent's starting directory. */
&si, /* Pointer to STARTUPINFO structure. */
&pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) {
DWORD err = GetLastError();
int chars = snprintf(msg, sizeof(msg) - 1,
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
/*
* Close our references to the write handles that have now been inherited.
*/
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000);
CloseHandle(pi.hThread);
/*
* Start the pipe reader threads.
*/
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/*
* Block waiting for the process to end.
*/
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
/*
* Wait for our pipe to get done reading, should it be a little slow.
*/
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
CloseHandle(pipeThreads[0]);
CloseHandle(pipeThreads[1]);
/*
* Look for the commandline warning code in both streams.
* - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
*/
return !(strstr(Out.buffer, "D4002") != NULL
|| strstr(Err.buffer, "D4002") != NULL
|| strstr(Out.buffer, "D9002") != NULL
|| strstr(Err.buffer, "D9002") != NULL
|| strstr(Out.buffer, "D2021") != NULL
|| strstr(Err.buffer, "D2021") != NULL);
}
static int
CheckForLinkerFeature(
const char **options,
int count)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD threadID;
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
int i;
char cmdline[255];
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
/*
* Create a non-inheritible pipe.
*/
CreatePipe(&Out.pipe, &h, &sa, 0);
/*
* Dupe the write side, make it inheritible, and close the original.
*/
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Same as above, but for the error side.
*/
CreatePipe(&Err.pipe, &h, &sa, 0);
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Base command line.
*/
lstrcpy(cmdline, "link.exe -nologo ");
/*
* Append our option for testing.
*/
for (i = 0; i < count; i++) {
lstrcat(cmdline, " \"");
lstrcat(cmdline, options[i]);
lstrcat(cmdline, "\"");
}
ok = CreateProcess(
NULL, /* Module name. */
cmdline, /* Command line. */
NULL, /* Process handle not inheritable. */
NULL, /* Thread handle not inheritable. */
TRUE, /* yes, inherit handles. */
DETACHED_PROCESS, /* No console for you. */
NULL, /* Use parent's environment block. */
NULL, /* Use parent's starting directory. */
&si, /* Pointer to STARTUPINFO structure. */
&pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) {
DWORD err = GetLastError();
int chars = snprintf(msg, sizeof(msg) - 1,
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
/*
* Close our references to the write handles that have now been inherited.
*/
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000);
CloseHandle(pi.hThread);
/*
* Start the pipe reader threads.
*/
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/*
* Block waiting for the process to end.
*/
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
/*
* Wait for our pipe to get done reading, should it be a little slow.
*/
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
CloseHandle(pipeThreads[0]);
CloseHandle(pipeThreads[1]);
/*
* Look for the commandline warning code in the stderr stream.
*/
return !(strstr(Out.buffer, "LNK1117") != NULL ||
strstr(Err.buffer, "LNK1117") != NULL ||
strstr(Out.buffer, "LNK4044") != NULL ||
strstr(Err.buffer, "LNK4044") != NULL ||
strstr(Out.buffer, "LNK4224") != NULL ||
strstr(Err.buffer, "LNK4224") != NULL);
}
static DWORD WINAPI
ReadFromPipe(
LPVOID args)
{
pipeinfo *pi = (pipeinfo *) args;
char *lastBuf = pi->buffer;
DWORD dwRead;
BOOL ok;
again:
if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
CloseHandle(pi->pipe);
return (DWORD)-1;
}
ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
if (!ok || dwRead == 0) {
CloseHandle(pi->pipe);
return 0;
}
lastBuf += dwRead;
goto again;
return 0; /* makes the compiler happy */
}
static int
IsIn(
const char *string,
const char *substring)
{
return (strstr(string, substring) != NULL);
}
/*
* GetVersionFromFile --
* Looks for a match string in a file and then returns the version
* following the match where a version is anything acceptable to
* package provide or package ifneeded.
*/
static const char *
GetVersionFromFile(
const char *filename,
const char *match,
int numdots)
{
size_t cbBuffer = 100;
static char szBuffer[100];
char *szResult = NULL;
FILE *fp = fopen(filename, "rt");
if (fp != NULL) {
/*
* Read data until we see our match string.
*/
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
LPSTR p, q;
p = strstr(szBuffer, match);
if (p != NULL) {
/*
* Skip to first digit after the match.
*/
p += strlen(match);
while (*p && !isdigit(*p)) {
++p;
}
/*
* Find ending whitespace.
*/
q = p;
while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
&& (!strchr("ab", q[-1])) || --numdots))) {
++q;
}
memcpy(szBuffer, p, q - p);
szBuffer[q-p] = 0;
szResult = szBuffer;
break;
}
}
fclose(fp);
}
return szResult;
}
/*
* List helpers for the SubstituteFile function
*/
typedef struct list_item_t {
struct list_item_t *nextPtr;
char * key;
char * value;
} list_item_t;
/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
list_item_t *itemPtr = malloc(sizeof(list_item_t));
if (itemPtr) {
itemPtr->key = strdup(key);
itemPtr->value = strdup(value);
itemPtr->nextPtr = NULL;
while(*listPtrPtr) {
listPtrPtr = &(*listPtrPtr)->nextPtr;
}
*listPtrPtr = itemPtr;
}
return itemPtr;
}
static void
list_free(list_item_t **listPtrPtr)
{
list_item_t *tmpPtr, *listPtr = *listPtrPtr;
while (listPtr) {
tmpPtr = listPtr;
listPtr = listPtr->nextPtr;
free(tmpPtr->key);
free(tmpPtr->value);
free(tmpPtr);
}
}
/*
* SubstituteFile --
* As windows doesn't provide anything useful like sed and it's unreliable
* to use the tclsh you are building against (consider x-platform builds -
* eg compiling AMD64 target from IX86) we provide a simple substitution
* option here to handle autoconf style substitutions.
* The substitution file is whitespace and line delimited. The file should
* consist of lines matching the regular expression:
* \s*\S+\s+\S*$
*
* Usage is something like:
* nmakehlp -S << $** > $@
* @PACKAGE_NAME@ $(PACKAGE_NAME)
* @PACKAGE_VERSION@ $(PACKAGE_VERSION)
* <<
*/
static int
SubstituteFile(
const char *substitutions,
const char *filename)
{
size_t cbBuffer = 1024;
static char szBuffer[1024], szCopy[1024];
char *szResult = NULL;
list_item_t *substPtr = NULL;
FILE *fp, *sp;
fp = fopen(filename, "rt");
if (fp != NULL) {
/*
* Build a list of substutitions from the first filename
*/
sp = fopen(substitutions, "rt");
if (sp != NULL) {
while (fgets(szBuffer, cbBuffer, sp) != NULL) {
unsigned char *ks, *ke, *vs, *ve;
ks = (unsigned char*)szBuffer;
while (ks && *ks && isspace(*ks)) ++ks;
ke = ks;
while (ke && *ke && !isspace(*ke)) ++ke;
vs = ke;
while (vs && *vs && isspace(*vs)) ++vs;
ve = vs;
while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
*ke = 0, *ve = 0;
list_insert(&substPtr, (char*)ks, (char*)vs);
}
fclose(sp);
}
/* debug: dump the list */
#ifndef NDEBUG
{
int n = 0;
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
}
}
#endif
/*
* Run the substitutions over each line of the input
*/
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr) {
char *m = strstr(szBuffer, p->key);
if (m) {
char *cp, *op, *sp;
cp = szCopy;
op = szBuffer;
while (op != m) *cp++ = *op++;
sp = p->value;
while (sp && *sp) *cp++ = *sp++;
op += strlen(p->key);
while (*op) *cp++ = *op++;
*cp = 0;
memcpy(szBuffer, szCopy, sizeof(szCopy));
}
}
printf(szBuffer);
}
list_free(&substPtr);
}
fclose(fp);
return 0;
}
BOOL FileExists(LPCTSTR szPath)
{
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
DWORD pathAttr = GetFileAttributes(szPath);
return (pathAttr != INVALID_FILE_ATTRIBUTES &&
!(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
}
/*
* QualifyPath --
*
* This composes the current working directory with a provided path
* and returns the fully qualified and normalized path.
* Mostly needed to setup paths for testing.
*/
static int
QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
printf("%s\n", szCwd);
return 0;
}
/*
* Implements LocateDependency for a single directory. See that command
* for an explanation.
* Returns 0 if found after printing the directory.
* Returns 1 if not found but no errors.
* Returns 2 on any kind of error
* Basically, these are used as exit codes for the process.
*/
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
HANDLE hSearch;
char path[MAX_PATH+1];
int dirlen, keylen, ret;
WIN32_FIND_DATA finfo;
if (dir == NULL || keypath == NULL)
return 2; /* Have no real error reporting mechanism into nmake */
dirlen = strlen(dir);
if ((dirlen + 3) > sizeof(path))
return 2;
strncpy(path, dir, dirlen);
strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
keylen = strlen(keypath);
#if 0 /* This function is not available in Visual C++ 6 */
/*
* Use numerics 0 -> FindExInfoStandard,
* 1 -> FindExSearchLimitToDirectories,
* as these are not defined in Visual C++ 6
*/
hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
hSearch = FindFirstFile(path, &finfo);
#endif
if (hSearch == INVALID_HANDLE_VALUE)
return 1; /* Not found */
/* Loop through all subdirs checking if the keypath is under there */
ret = 1; /* Assume not found */
do {
int sublen;
/*
* We need to check it is a directory despite the
* FindExSearchLimitToDirectories in the above call. See SDK docs
*/
if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
continue;
sublen = strlen(finfo.cFileName);
if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
continue; /* Path does not fit, assume not matched */
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
ret = 0;
break;
}
} while (FindNextFile(hSearch, &finfo));
FindClose(hSearch);
return ret;
}
/*
* LocateDependency --
*
* Locates a dependency for a package.
* keypath - a relative path within the package directory
* that is used to confirm it is the correct directory.
* The search path for the package directory is currently only
* the parent and grandparent of the current working directory.
* If found, the command prints
* name_DIRPATH=<full path of located directory>
* and returns 0. If not found, does not print anything and returns 1.
*/
static int LocateDependency(const char *keypath)
{
int i, ret;
static const char *paths[] = {"..", "..\\..", "..\\..\\.."};
for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
ret = LocateDependencyHelper(paths[i], keypath);
if (ret == 0)
return ret;
}
return ret;
}
/*
* Local variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* indent-tabs-mode: t
* tab-width: 8
* End:
*/

View File

@@ -0,0 +1,118 @@
# This file should only be included in makefiles for Tcl extensions,
# NOT in the makefile for Tcl itself.
!ifndef _RULES_EXT_VC
# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""
!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""
!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif
!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif
# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
!endif
# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""
_RULESDIR = $(TCLDIR:/=\)
!else
# If an installation path is specified, that is also the Tcl directory.
# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
# Locate Tcl sources
!if [echo _RULESDIR = \> nmakehlp.out] \
|| [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
!else
!include nmakehlp.out
!endif
!endif # defined(INSTALLDIR)....
!endif # ifndef TCLDIR
# Now look for the targets.vc file under the Tcl root. Note we check this
# file and not rules.vc because the latter also exists on older systems.
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
_RULESDIR = $(_RULESDIR)\lib\nmake
!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
_RULESDIR = $(_RULESDIR)\win
!else
# If we have not located Tcl's targets file, most likely we are compiling
# against an older version of Tcl and so must use our own support files.
_RULESDIR = .
!endif
!if "$(_RULESDIR)" != "."
# Potentially using Tcl's support files. If this extension has its own
# nmake support files, need to compare the versions and pick newer.
!if exist("rules.vc") # The extension has its own copy
!if [echo TCL_RULES_MAJOR = \> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
&& [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
&& [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!include versions.vc
# We have a newer version of the support files, use them
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
_RULESDIR = .
!endif
!endif # if exist("rules.vc")
!endif # if $(_RULESDIR) != "."
# Let rules.vc know what copy of nmakehlp.c to use.
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
# Get rid of our internal defines before calling rules.vc
!undef TCL_RULES_MAJOR
!undef TCL_RULES_MINOR
!undef OUR_RULES_MAJOR
!undef OUR_RULES_MINOR
!if exist("$(_RULESDIR)\rules.vc")
!message *** Using $(_RULESDIR)\rules.vc
!include "$(_RULESDIR)\rules.vc"
!else
!error *** Could not locate rules.vc in $(_RULESDIR)
!endif
!endif # _RULES_EXT_VC

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.
$(PROJECT): setup pkgindex $(PRJLIB)
!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
$(LIBCMD) $**
$(PRJ_STUBOBJS):
$(CCSTUBSCMD) %s
!endif # PRJ_STUBOBJS
!ifdef PRJ_MANIFEST
$(PROJECT): $(PRJLIB).manifest
$(PRJLIB).manifest: $(PRJ_MANIFEST)
@nmakehlp -s << $** >$@
@MACHINE@ $(MACHINE:IX86=X86)
<<
!endif
!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
!if $(STATIC_BUILD)
$(LIBCMD) $**
!else
$(DLLCMD) $**
$(_VC_MANIFEST_EMBED_DLL)
!endif
-@del $*.exp
!endif
!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
$(PRJ_OBJS): $(PRJ_HEADERS)
!endif
# If parent makefile has defined stub objects, add their installation
# to the default install
!if "$(PRJ_STUBOBJS)" != ""
default-install: default-install-stubs
!endif
# Unlike the other default targets, these cannot be in rules.vc because
# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
# that the parent makefile will not define until after including rules-ext.vc
!if "$(PRJ_HEADERS_PUBLIC)" != ""
default-install: default-install-headers
default-install-headers:
@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif
!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif
!if "$(DISABLE_TARGET_setup)" == ""
DISABLE_TARGET_setup = 0
!endif
!if "$(DISABLE_TARGET_install)" == ""
DISABLE_TARGET_install = 0
!endif
!if "$(DISABLE_TARGET_clean)" == ""
DISABLE_TARGET_clean = 0
!endif
!if "$(DISABLE_TARGET_test)" == ""
DISABLE_TARGET_test = 0
!endif
!if "$(DISABLE_TARGET_shell)" == ""
DISABLE_TARGET_shell = 0
!endif
!if !$(DISABLE_STANDARD_TARGETS)
!if !$(DISABLE_TARGET_setup)
setup: default-setup
!endif
!if !$(DISABLE_TARGET_install)
install: default-install
!endif
!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
!endif
!if !$(DISABLE_TARGET_test)
test: default-test
!endif
!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
!endif # DISABLE_STANDARD_TARGETS