├── pkgIndex.tcl.in ├── tests └── all.tcl ├── license.terms ├── generic ├── mysqlStubDefs.txt ├── mysqlStubInit.c ├── mysqlStubs.h └── fakemysql.h ├── README ├── aclocal.m4 ├── doc └── tdbc_mysql.n ├── library └── tdbcmysql.tcl ├── configure.in ├── ChangeLog ├── win ├── makefile.vc ├── nmakehlp.c └── rules.vc └── Makefile.in /pkgIndex.tcl.in: -------------------------------------------------------------------------------- 1 | # Package index file for tdbc::mysql 2 | 3 | if {[catch {package require Tcl @TCL_VERSION_REQ@}]} { 4 | return 5 | } 6 | package ifneeded tdbc::mysql @PACKAGE_VERSION@ \ 7 | "[list source [file join $dir @PACKAGE_NAME@.tcl]]\;\ 8 | [list load [file join $dir @PKG_LIB_FILE@] @PACKAGE_NAME@]" 9 | -------------------------------------------------------------------------------- /tests/all.tcl: -------------------------------------------------------------------------------- 1 | # all.tcl -- 2 | # 3 | # This file contains a top-level script to run all of the Tcl 4 | # tests. Execute it by invoking "source all.test" when running tcltest 5 | # in this directory. 6 | # 7 | # Copyright (c) 1998-2000 by Scriptics Corporation. 8 | # All rights reserved. 9 | # 10 | # RCS: @(#) $Id: all.tcl,v 1.4 2004/07/04 22:04:20 patthoyts Exp $ 11 | 12 | package require Tcl 8.6 13 | package require tcltest 2.2 14 | ::tcltest::configure \ 15 | -testdir [file dirname [file normalize [info script]]] \ 16 | {*}$argv 17 | ::tcltest::runAllTests 18 | rename exit {} 19 | -------------------------------------------------------------------------------- /license.terms: -------------------------------------------------------------------------------- 1 | This software is copyrighted by Kevin B. Kenny, and by other parties. 2 | The following terms apply to all files associated with the software 3 | unless explicitly disclaimed in individual files. 4 | 5 | The authors hereby grant permission to use, copy, modify, distribute, 6 | and license this software and its documentation for any purpose, provided 7 | that existing copyright notices are retained in all copies and that this 8 | notice is included verbatim in any distributions. No written agreement, 9 | license, or royalty fee is required for any of the authorized uses. 10 | Modifications to this software may be copyrighted by their authors 11 | and need not follow the licensing terms described here, provided that 12 | the new terms are clearly indicated on the first page of each file where 13 | they apply. 14 | 15 | IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 16 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 17 | ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 18 | DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 19 | POSSIBILITY OF SUCH DAMAGE. 20 | 21 | THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 24 | IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 25 | NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 26 | MODIFICATIONS. 27 | 28 | GOVERNMENT USE: If you are acquiring this software on behalf of the 29 | U.S. government, the Government shall have only "Restricted Rights" 30 | in the software and related documentation as defined in the Federal 31 | Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you 32 | are acquiring the software on behalf of the Department of Defense, the 33 | software shall be classified as "Commercial Computer Software" and the 34 | Government shall have only "Restricted Rights" as defined in Clause 35 | 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the 36 | authors grant the U.S. Government and others acting in its behalf 37 | permission to use and distribute the software in accordance with the 38 | terms specified in this license. 39 | -------------------------------------------------------------------------------- /generic/mysqlStubDefs.txt: -------------------------------------------------------------------------------- 1 | # mysqlStubDefs.txt -- 2 | # 3 | # Definitions of routines in the MySQL libraries that will be 4 | # resolved and imported at run time. 5 | # 6 | # This file contains only function declarations necessary to interoperability 7 | # with the SQL/CLI application programming interface. The programmers believe 8 | # that the material in this file is not subject to copyright, under the 9 | # doctrines of scenes a faire and of the merger of idea and expression. 10 | # Accordingly, this file is in the public domain. 11 | # 12 | #----------------------------------------------------------------------------- 13 | 14 | * STUBSTRUCT: mysqlStubs 15 | * LIBRARY: libmysqlclient_r libmysqlclient libmysql 16 | * CONVENTION: STDCALL 17 | 18 | int mysql_server_init(int, char**, char**); 19 | void mysql_server_end(void); 20 | my_ulonglong mysql_affected_rows(MYSQL*); 21 | my_bool mysql_autocommit(MYSQL*, my_bool); 22 | my_bool mysql_change_user(MYSQL*, const char*, const char*, const char*); 23 | my_bool mysql_close(MYSQL*); 24 | my_bool mysql_commit(MYSQL*); 25 | unsigned int mysql_errno(MYSQL*); 26 | const char* mysql_error(MYSQL*); 27 | MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES*); 28 | unsigned long* mysql_fetch_lengths(MYSQL_RES*); 29 | MYSQL_ROW mysql_fetch_row(MYSQL_RES*); 30 | unsigned int mysql_field_count(MYSQL*); 31 | void mysql_free_result(MYSQL_RES*); 32 | unsigned long mysql_get_client_version(void); 33 | MYSQL* mysql_init(MYSQL*); 34 | MYSQL_RES* mysql_list_fields(MYSQL*, const char*, const char*); 35 | MYSQL_RES* mysql_list_tables(MYSQL*, const char*); 36 | unsigned int mysql_num_fields(MYSQL_RES*); 37 | int mysql_options(MYSQL*, enum mysql_option, const void*); 38 | int mysql_query(MYSQL*, const char*); 39 | MYSQL* mysql_real_connect(MYSQL*, const char*, const char*, const char*, const char*, unsigned int, const char*, unsigned long); 40 | my_bool mysql_rollback(MYSQL*); 41 | int mysql_select_db(MYSQL*, const char*); 42 | const char* mysql_sqlstate(MYSQL*); 43 | my_bool mysql_ssl_set(MYSQL*, const char*, const char*, const char*, const char*, const char*); 44 | my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT*); 45 | my_bool mysql_stmt_bind_param(MYSQL_STMT*, MYSQL_BIND*); 46 | my_bool mysql_stmt_bind_result(MYSQL_STMT*, MYSQL_BIND*); 47 | my_bool mysql_stmt_close(MYSQL_STMT*); 48 | unsigned int mysql_stmt_errno(MYSQL_STMT*); 49 | const char* mysql_stmt_error(MYSQL_STMT*); 50 | int mysql_stmt_execute(MYSQL_STMT*); 51 | int mysql_stmt_fetch(MYSQL_STMT*); 52 | int mysql_stmt_fetch_column(MYSQL_STMT*, MYSQL_BIND*, unsigned int, unsigned long); 53 | MYSQL_STMT* mysql_stmt_init(MYSQL*); 54 | int mysql_stmt_prepare(MYSQL_STMT*, const char*, unsigned long); 55 | MYSQL_RES* mysql_stmt_result_metadata(MYSQL_STMT*); 56 | const char* mysql_stmt_sqlstate(MYSQL_STMT*); 57 | int mysql_stmt_store_result(MYSQL_STMT*); 58 | MYSQL_RES* mysql_store_result(MYSQL*); 59 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README: tdbcmysql 2 | 3 | This is the 1.0.0 source distribution of the driver for Tcl 4 | Database Connectivity (TDBC) to access MySQL databases.. TDBC and 5 | its drivers are available from a Fossil version control repository 6 | at http://tdbc.tcl.tk/ 7 | 8 | RCS: @(#) $Id: $ 9 | 10 | 1. Introduction 11 | 12 | This directory contains the source code, documentation, and test 13 | scripts for the MySQL driver for Tcl Database Connectivity. This 14 | module, plus TDBC itself, allow you to access MySQL databases using a 15 | standard application programming interface (API) from a Tcl script. 16 | This module is also available from http://tdbc.tcl.tk along with the 17 | source code of TDBC itself. A bug database and Wiki are available at 18 | the same location. 19 | 20 | Tdbc::mysql is a freely-available open source package. You can do 21 | virtually anything you like with it, such as modifying it, 22 | redistributing it, and selling it either in whole or in part. See the 23 | file "license.terms" for complete information. 24 | 25 | 2. Compilation and Installation 26 | 27 | This module follows the general configuration and installation 28 | rules described in the README file for tdbc. In addition to the 29 | options described there, the 'configure' script for tdbcmysql 30 | accepts the following two options: 31 | 32 | --with-mysql-includedir=PATH 33 | 34 | Specifies PATH as the path to the directory that contains 35 | 'mysql.h' and related header files. 36 | 37 | --with-mysql-libdir=PATH 38 | 39 | Specifies PATH as the path to the directory that contains 40 | the MySQL link libraries. 41 | 42 | Building on Windows is tested only with msys/mingw, and only with 43 | the version of MySQL present in XAMPP (https://sourceforge.net/projects/xampp) 44 | You need the 'xampp-win32-devel' package as well as the 'xampp-win32' 45 | package. 46 | 47 | In order to build the code under msys/mingw, you need to rebuild the 48 | import library for use by mingw. (This also requires the 'reimp' 49 | utility from mingw-utils.) The recipe for this step is: 50 | 51 | reimp -d drive:/path/to/xampp/lib/mysql/libmysql.lib 52 | dlltool -k -d libmysql.def -l libmysql.a 53 | cp libmysql.a drive:/path/to/mingw/lib 54 | 55 | It is also convenient to make sure that the MySQL headers are available 56 | without the --with option: 57 | 58 | cp -r drive:/path/to/xampp/include/mysql/* drive:/path/to/mingw/include/ 59 | 60 | Then an ordinary 'configure' and 'make' should function to build the 61 | load module. 62 | 63 | NOTE THAT ON WINDOWS, THE 'libmysql.dll' LIBRARY MUST BE ON THE PATH 64 | AT RUNTIME. Probably the easiest way to ensure this happens is to 65 | put it either in the Windows 'system32' directory or the 'bin' 66 | directory of your Tcl distribution. 67 | 68 | 3. Documentation 69 | 70 | The 'doc' subdirectory in this release contains a set of reference 71 | manual entries for tdbc::mysql. Files with an extension '.n' are for 72 | Tcl classes and commands; files with an extension '.3' are for C 73 | library functions. The file, 'doc/tdbcmysql.n' gives an overview, 74 | listing the classes and functions 75 | 76 | 4. See also 77 | 78 | More information about TDBC and its drivers are available in the 79 | README file for TDBC itself; refer to that file for compilation and 80 | installation instructions, and support information. 81 | -------------------------------------------------------------------------------- /aclocal.m4: -------------------------------------------------------------------------------- 1 | # 2 | # Include the TEA standard macro set 3 | # 4 | 5 | builtin(include,tclconfig/tcl.m4) 6 | 7 | # 8 | # Add here whatever m4 macros you want to define for your package 9 | # 10 | 11 | dnl Helper macros 12 | AC_DEFUN([TEAX_LAPPEND], [$1="[$]{$1} $2"]) 13 | AC_DEFUN([TEAX_FOREACH], [for $1 in $2; do $3; done]) 14 | AC_DEFUN([TEAX_IFEQ], [AS_IF([test "x$1" = "x$2"], [$3])]) 15 | AC_DEFUN([TEAX_IFNEQ], [AS_IF([test "x$1" != "x$2"], [$3])]) 16 | AC_DEFUN([TEAX_SWITCH], [case "$1" in TEAX_SWITCH_Cases(m4_shift($@)) esac]) 17 | AC_DEFUN([TEAX_SWITCH_Cases], [m4_if([$#],0,,[$#],1,,[TEAX_SWITCH_OneCase($1,$2)TEAX_SWITCH_Cases(m4_shift(m4_shift($@)))])]) 18 | AC_DEFUN([TEAX_SWITCH_OneCase],[ $1) $2;;]) 19 | AC_DEFUN([CygPath],[`${CYGPATH} $1`]) 20 | 21 | dnl Interesting macros 22 | AC_DEFUN([TEAX_SUBST_RESOURCE], [ 23 | AC_REQUIRE([TEA_CONFIG_CFLAGS])dnl 24 | TEAX_IFEQ($TEA_PLATFORM, windows, [ 25 | AC_CHECK_PROGS(RC_, 'windres -o' 'rc -nologo -fo', none) 26 | TEAX_SWITCH($RC_, 27 | windres*, [ 28 | rcdef_inc="--include " 29 | rcdef_start="--define " 30 | rcdef_q='\"' 31 | AC_SUBST(RES_SUFFIX, [res.o]) 32 | TEAX_LAPPEND(PKG_OBJECTS, ${PACKAGE_NAME}.res.o)], 33 | rc*, [ 34 | rcdef_inc="-i " 35 | rcdef_start="-d " 36 | rcdef_q='"' 37 | AC_SUBST(RES_SUFFIX, [res]) 38 | TEAX_LAPPEND(PKG_OBJECTS, ${PACKAGE_NAME}.res)], 39 | *, [ 40 | AC_MSG_WARN([could not find resource compiler]) 41 | RC_=: ])]) 42 | # This next line is because of the brokenness of TEA... 43 | AC_SUBST(RC, $RC_) 44 | TEAX_FOREACH(i, $1, [ 45 | TEAX_LAPPEND(RES_DEFS, ${rcdef_inc}\"CygPath($i)\")]) 46 | TEAX_FOREACH(i, $2, [ 47 | TEAX_LAPPEND(RES_DEFS, ${rcdef_start}$i='${rcdef_q}\$($i)${rcdef_q}')]) 48 | AC_SUBST(RES_DEFS)]) 49 | AC_DEFUN([TEAX_ADD_PRIVATE_HEADERS], [ 50 | TEAX_FOREACH(i, $@, [ 51 | # check for existence, be strict because it should be present! 52 | AS_IF([test ! -f "${srcdir}/$i"], [ 53 | AC_MSG_ERROR([could not find header file '${srcdir}/$i'])]) 54 | TEAX_LAPPEND(PKG_PRIVATE_HEADERS, $i)]) 55 | AC_SUBST(PKG_PRIVATE_HEADERS)]) 56 | 57 | dnl Extra magic to make things work with Vista and VC 58 | AC_DEFUN([TEAX_VC_MANIFEST], [ 59 | ADD_MANIFEST=":" 60 | AS_IF([test "$GCC" != yes \ 61 | -a ${TEA_PLATFORM} == "windows" \ 62 | -a "${SHARED_BUILD}" = "1"], [ 63 | # This refers to "Manifest Tool" not "Magnetic Tape utility" 64 | AC_CHECK_PROGS(MT, mt, none) 65 | AS_IF([test "$MT" != none], [ 66 | ADD_MANIFEST="${MT} -nologo -manifest [\$]@.manifest -outputresource:[\$]@\;2" 67 | CLEANFILES="$CLEANFILES ${PKG_LIB_FILE}.manifest"])]) 68 | AC_SUBST(ADD_MANIFEST)]) 69 | 70 | AC_DEFUN([TEAX_SDX], [ 71 | AC_PATH_PROG(SDX, sdx, none) 72 | TEAX_IFEQ($SDX, none, [ 73 | AC_PATH_PROG(SDX_KIT, sdx.kit, none) 74 | TEAX_IFNEQ($SDX_KIT, none, [ 75 | # We assume that sdx.kit is on the path, and that the default 76 | # tclsh is activetcl 77 | SDX="tclsh '${SDX_KIT}'"])]) 78 | TEAX_IFEQ($SDX, none, [ 79 | AC_MSG_WARN([cannot find sdx; building starkits will fail]) 80 | AC_MSG_NOTICE([building as a normal library still supported])])]) 81 | dnl TODO: Adapt this for OSX Frameworks... 82 | dnl This next bit is a bit ugly, but it makes things for tclooConfig.sh... 83 | AC_DEFUN([TEAX_PATH_LINE], [ 84 | eval "$1=\"[]CygPath($2)\"" 85 | AC_SUBST($1)]) 86 | AC_DEFUN([TEAX_INCLUDE_LINE], [ 87 | eval "$1=\"-I[]CygPath($2)\"" 88 | AC_SUBST($1)]) 89 | AC_DEFUN([TEAX_LINK_LINE], [ 90 | AS_IF([test ${TCL_LIB_VERSIONS_OK} = nodots], [ 91 | eval "$1=\"-L[]CygPath($2) -l$3${TCL_TRIM_DOTS}\"" 92 | ], [ 93 | eval "$1=\"-L[]CygPath($2) -l$3${PACKAGE_VERSION}\"" 94 | ]) 95 | AC_SUBST($1)]) 96 | 97 | dnl Local Variables: 98 | dnl mode: autoconf 99 | dnl End: 100 | -------------------------------------------------------------------------------- /generic/mysqlStubInit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mysqlStubInit.c -- 3 | * 4 | * Stubs tables for the foreign MySQL libraries so that 5 | * Tcl extensions can use them without the linker's knowing about them. 6 | * 7 | * @CREATED@ 2010-12-27 19:26:47Z by genExtStubs.tcl from ../generic/mysqlStubDefs.txt 8 | * 9 | * Copyright (c) 2010 by Kevin B. Kenny. 10 | * 11 | * Please refer to the file, 'license.terms' for the conditions on 12 | * redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES. 13 | * 14 | *----------------------------------------------------------------------------- 15 | */ 16 | 17 | #include 18 | #ifdef _WIN32 19 | #define WIN32_LEAN_AND_MEAN 20 | #include 21 | #endif 22 | #include "fakemysql.h" 23 | 24 | /* 25 | * Static data used in this file 26 | */ 27 | 28 | /* 29 | * Names of the libraries that might contain the MySQL API 30 | */ 31 | 32 | static const char *const mysqlStubLibNames[] = { 33 | /* @LIBNAMES@: DO NOT EDIT THESE NAMES */ 34 | "libmysqlclient_r", "libmysqlclient", "libmysql", NULL 35 | /* @END@ */ 36 | }; 37 | 38 | /* ABI Version numbers of the MySQL API that we can cope with */ 39 | 40 | static const char *const mysqlSuffixes[] = { 41 | "", ".18", ".17", ".16", ".15", NULL 42 | }; 43 | 44 | /* Names of the functions that we need from MySQL */ 45 | 46 | static const char *const mysqlSymbolNames[] = { 47 | /* @SYMNAMES@: DO NOT EDIT THESE NAMES */ 48 | "mysql_server_init", 49 | "mysql_server_end", 50 | "mysql_affected_rows", 51 | "mysql_autocommit", 52 | "mysql_change_user", 53 | "mysql_close", 54 | "mysql_commit", 55 | "mysql_errno", 56 | "mysql_error", 57 | "mysql_fetch_fields", 58 | "mysql_fetch_lengths", 59 | "mysql_fetch_row", 60 | "mysql_field_count", 61 | "mysql_free_result", 62 | "mysql_get_client_version", 63 | "mysql_init", 64 | "mysql_list_fields", 65 | "mysql_list_tables", 66 | "mysql_num_fields", 67 | "mysql_options", 68 | "mysql_query", 69 | "mysql_real_connect", 70 | "mysql_rollback", 71 | "mysql_select_db", 72 | "mysql_sqlstate", 73 | "mysql_ssl_set", 74 | "mysql_stmt_affected_rows", 75 | "mysql_stmt_bind_param", 76 | "mysql_stmt_bind_result", 77 | "mysql_stmt_close", 78 | "mysql_stmt_errno", 79 | "mysql_stmt_error", 80 | "mysql_stmt_execute", 81 | "mysql_stmt_fetch", 82 | "mysql_stmt_fetch_column", 83 | "mysql_stmt_init", 84 | "mysql_stmt_prepare", 85 | "mysql_stmt_result_metadata", 86 | "mysql_stmt_sqlstate", 87 | "mysql_stmt_store_result", 88 | "mysql_store_result", 89 | NULL 90 | /* @END@ */ 91 | }; 92 | 93 | /* 94 | * Table containing pointers to the functions named above. 95 | */ 96 | 97 | static mysqlStubDefs mysqlStubsTable; 98 | mysqlStubDefs* mysqlStubs = &mysqlStubsTable; 99 | 100 | /* 101 | *----------------------------------------------------------------------------- 102 | * 103 | * MysqlInitStubs -- 104 | * 105 | * Initialize the Stubs table for the MySQL API 106 | * 107 | * Results: 108 | * Returns the handle to the loaded MySQL client library, or NULL 109 | * if the load is unsuccessful. Leaves an error message in the 110 | * interpreter. 111 | * 112 | *----------------------------------------------------------------------------- 113 | */ 114 | 115 | MODULE_SCOPE Tcl_LoadHandle 116 | MysqlInitStubs(Tcl_Interp* interp) 117 | { 118 | int status; /* Status of Tcl library calls */ 119 | Tcl_Obj* path; /* Path name of a module to be loaded */ 120 | Tcl_Obj* shlibext; /* Extension to use for load modules */ 121 | Tcl_LoadHandle handle = NULL; 122 | /* Handle to a load module */ 123 | int i, j; 124 | 125 | /* Determine the shared library extension */ 126 | 127 | status = Tcl_EvalEx(interp, "::info sharedlibextension", -1, 128 | TCL_EVAL_GLOBAL); 129 | if (status != TCL_OK) return NULL; 130 | shlibext = Tcl_GetObjResult(interp); 131 | Tcl_IncrRefCount(shlibext); 132 | 133 | /* Walk the list of possible library names to find an MySQL client */ 134 | 135 | status = TCL_ERROR; 136 | for (i = 0; status == TCL_ERROR && mysqlStubLibNames[i] != NULL; ++i) { 137 | for (j = 0; status == TCL_ERROR && mysqlSuffixes[j] != NULL; ++j) { 138 | path = Tcl_NewStringObj(mysqlStubLibNames[i], -1); 139 | Tcl_AppendObjToObj(path, shlibext); 140 | Tcl_AppendToObj(path, mysqlSuffixes[j], -1); 141 | Tcl_IncrRefCount(path); 142 | 143 | /* Try to load a client library and resolve symbols within it. */ 144 | 145 | Tcl_ResetResult(interp); 146 | status = Tcl_LoadFile(interp, path, mysqlSymbolNames, 0, 147 | (void*)mysqlStubs, &handle); 148 | Tcl_DecrRefCount(path); 149 | } 150 | } 151 | 152 | /* 153 | * Either we've successfully loaded a library (status == TCL_OK), 154 | * or we've run out of library names (in which case status==TCL_ERROR 155 | * and the error message reflects the last unsuccessful load attempt). 156 | */ 157 | Tcl_DecrRefCount(shlibext); 158 | if (status != TCL_OK) { 159 | return NULL; 160 | } 161 | return handle; 162 | } 163 | -------------------------------------------------------------------------------- /generic/mysqlStubs.h: -------------------------------------------------------------------------------- 1 | /* 2 | *----------------------------------------------------------------------------- 3 | * 4 | * ../generic/mysqlStubs.h -- 5 | * 6 | * Stubs for procedures in mysqlStubDefs.txt 7 | * 8 | * Generated by genExtStubs.tcl: DO NOT EDIT 9 | * 2010-12-27 19:26:47Z 10 | * 11 | *----------------------------------------------------------------------------- 12 | */ 13 | 14 | typedef struct mysqlStubDefs { 15 | 16 | /* Functions from libraries: libmysqlclient_r libmysqlclient libmysql */ 17 | 18 | int (STDCALL*mysql_server_initPtr)(int, char**, char**); 19 | void (STDCALL*mysql_server_endPtr)(void); 20 | my_ulonglong (STDCALL*mysql_affected_rowsPtr)(MYSQL*); 21 | my_bool (STDCALL*mysql_autocommitPtr)(MYSQL*, my_bool); 22 | my_bool (STDCALL*mysql_change_userPtr)(MYSQL*, const char*, const char*, const char*); 23 | my_bool (STDCALL*mysql_closePtr)(MYSQL*); 24 | my_bool (STDCALL*mysql_commitPtr)(MYSQL*); 25 | unsigned int (STDCALL*mysql_errnoPtr)(MYSQL*); 26 | const char* (STDCALL*mysql_errorPtr)(MYSQL*); 27 | MYSQL_FIELD* (STDCALL*mysql_fetch_fieldsPtr)(MYSQL_RES*); 28 | unsigned long* (STDCALL*mysql_fetch_lengthsPtr)(MYSQL_RES*); 29 | MYSQL_ROW (STDCALL*mysql_fetch_rowPtr)(MYSQL_RES*); 30 | unsigned int (STDCALL*mysql_field_countPtr)(MYSQL*); 31 | void (STDCALL*mysql_free_resultPtr)(MYSQL_RES*); 32 | unsigned long (STDCALL*mysql_get_client_versionPtr)(void); 33 | MYSQL* (STDCALL*mysql_initPtr)(MYSQL*); 34 | MYSQL_RES* (STDCALL*mysql_list_fieldsPtr)(MYSQL*, const char*, const char*); 35 | MYSQL_RES* (STDCALL*mysql_list_tablesPtr)(MYSQL*, const char*); 36 | unsigned int (STDCALL*mysql_num_fieldsPtr)(MYSQL_RES*); 37 | int (STDCALL*mysql_optionsPtr)(MYSQL*, enum mysql_option, const void*); 38 | int (STDCALL*mysql_queryPtr)(MYSQL*, const char*); 39 | MYSQL* (STDCALL*mysql_real_connectPtr)(MYSQL*, const char*, const char*, const char*, const char*, unsigned int, const char*, unsigned long); 40 | my_bool (STDCALL*mysql_rollbackPtr)(MYSQL*); 41 | int (STDCALL*mysql_select_dbPtr)(MYSQL*, const char*); 42 | const char* (STDCALL*mysql_sqlstatePtr)(MYSQL*); 43 | my_bool (STDCALL*mysql_ssl_setPtr)(MYSQL*, const char*, const char*, const char*, const char*, const char*); 44 | my_ulonglong (STDCALL*mysql_stmt_affected_rowsPtr)(MYSQL_STMT*); 45 | my_bool (STDCALL*mysql_stmt_bind_paramPtr)(MYSQL_STMT*, MYSQL_BIND*); 46 | my_bool (STDCALL*mysql_stmt_bind_resultPtr)(MYSQL_STMT*, MYSQL_BIND*); 47 | my_bool (STDCALL*mysql_stmt_closePtr)(MYSQL_STMT*); 48 | unsigned int (STDCALL*mysql_stmt_errnoPtr)(MYSQL_STMT*); 49 | const char* (STDCALL*mysql_stmt_errorPtr)(MYSQL_STMT*); 50 | int (STDCALL*mysql_stmt_executePtr)(MYSQL_STMT*); 51 | int (STDCALL*mysql_stmt_fetchPtr)(MYSQL_STMT*); 52 | int (STDCALL*mysql_stmt_fetch_columnPtr)(MYSQL_STMT*, MYSQL_BIND*, unsigned int, unsigned long); 53 | MYSQL_STMT* (STDCALL*mysql_stmt_initPtr)(MYSQL*); 54 | int (STDCALL*mysql_stmt_preparePtr)(MYSQL_STMT*, const char*, unsigned long); 55 | MYSQL_RES* (STDCALL*mysql_stmt_result_metadataPtr)(MYSQL_STMT*); 56 | const char* (STDCALL*mysql_stmt_sqlstatePtr)(MYSQL_STMT*); 57 | int (STDCALL*mysql_stmt_store_resultPtr)(MYSQL_STMT*); 58 | MYSQL_RES* (STDCALL*mysql_store_resultPtr)(MYSQL*); 59 | } mysqlStubDefs; 60 | #define mysql_server_init (mysqlStubs->mysql_server_initPtr) 61 | #define mysql_server_end (mysqlStubs->mysql_server_endPtr) 62 | #define mysql_affected_rows (mysqlStubs->mysql_affected_rowsPtr) 63 | #define mysql_autocommit (mysqlStubs->mysql_autocommitPtr) 64 | #define mysql_change_user (mysqlStubs->mysql_change_userPtr) 65 | #define mysql_close (mysqlStubs->mysql_closePtr) 66 | #define mysql_commit (mysqlStubs->mysql_commitPtr) 67 | #define mysql_errno (mysqlStubs->mysql_errnoPtr) 68 | #define mysql_error (mysqlStubs->mysql_errorPtr) 69 | #define mysql_fetch_fields (mysqlStubs->mysql_fetch_fieldsPtr) 70 | #define mysql_fetch_lengths (mysqlStubs->mysql_fetch_lengthsPtr) 71 | #define mysql_fetch_row (mysqlStubs->mysql_fetch_rowPtr) 72 | #define mysql_field_count (mysqlStubs->mysql_field_countPtr) 73 | #define mysql_free_result (mysqlStubs->mysql_free_resultPtr) 74 | #define mysql_get_client_version (mysqlStubs->mysql_get_client_versionPtr) 75 | #define mysql_init (mysqlStubs->mysql_initPtr) 76 | #define mysql_list_fields (mysqlStubs->mysql_list_fieldsPtr) 77 | #define mysql_list_tables (mysqlStubs->mysql_list_tablesPtr) 78 | #define mysql_num_fields (mysqlStubs->mysql_num_fieldsPtr) 79 | #define mysql_options (mysqlStubs->mysql_optionsPtr) 80 | #define mysql_query (mysqlStubs->mysql_queryPtr) 81 | #define mysql_real_connect (mysqlStubs->mysql_real_connectPtr) 82 | #define mysql_rollback (mysqlStubs->mysql_rollbackPtr) 83 | #define mysql_select_db (mysqlStubs->mysql_select_dbPtr) 84 | #define mysql_sqlstate (mysqlStubs->mysql_sqlstatePtr) 85 | #define mysql_ssl_set (mysqlStubs->mysql_ssl_setPtr) 86 | #define mysql_stmt_affected_rows (mysqlStubs->mysql_stmt_affected_rowsPtr) 87 | #define mysql_stmt_bind_param (mysqlStubs->mysql_stmt_bind_paramPtr) 88 | #define mysql_stmt_bind_result (mysqlStubs->mysql_stmt_bind_resultPtr) 89 | #define mysql_stmt_close (mysqlStubs->mysql_stmt_closePtr) 90 | #define mysql_stmt_errno (mysqlStubs->mysql_stmt_errnoPtr) 91 | #define mysql_stmt_error (mysqlStubs->mysql_stmt_errorPtr) 92 | #define mysql_stmt_execute (mysqlStubs->mysql_stmt_executePtr) 93 | #define mysql_stmt_fetch (mysqlStubs->mysql_stmt_fetchPtr) 94 | #define mysql_stmt_fetch_column (mysqlStubs->mysql_stmt_fetch_columnPtr) 95 | #define mysql_stmt_init (mysqlStubs->mysql_stmt_initPtr) 96 | #define mysql_stmt_prepare (mysqlStubs->mysql_stmt_preparePtr) 97 | #define mysql_stmt_result_metadata (mysqlStubs->mysql_stmt_result_metadataPtr) 98 | #define mysql_stmt_sqlstate (mysqlStubs->mysql_stmt_sqlstatePtr) 99 | #define mysql_stmt_store_result (mysqlStubs->mysql_stmt_store_resultPtr) 100 | #define mysql_store_result (mysqlStubs->mysql_store_resultPtr) 101 | MODULE_SCOPE mysqlStubDefs *mysqlStubs; 102 | -------------------------------------------------------------------------------- /doc/tdbc_mysql.n: -------------------------------------------------------------------------------- 1 | '\" 2 | .\" tdbc_mysql.n -- 3 | .\" 4 | .\" Copyright (c) 2008 by Kevin B. Kenny. 5 | .\" 6 | .\" See the file "license.terms" for information on usage and redistribution of 7 | .\" this file, and for a DISCLAIMER OF ALL WARRANTIES. 8 | .\" .so man.macros 9 | .if t .wh -1.3i ^B 10 | .nr ^l \n(.l 11 | .ad b 12 | .\" # BS - start boxed text 13 | .\" # ^y = starting y location 14 | .\" # ^b = 1 15 | .de BS 16 | .br 17 | .mk ^y 18 | .nr ^b 1u 19 | .if n .nf 20 | .if n .ti 0 21 | .if n \l'\\n(.lu\(ul' 22 | .if n .fi 23 | .. 24 | .\" # BE - end boxed text (draw box now) 25 | .de BE 26 | .nf 27 | .ti 0 28 | .mk ^t 29 | .ie n \l'\\n(^lu\(ul' 30 | .el \{\ 31 | .\" Draw four-sided box normally, but don't draw top of 32 | .\" box if the box started on an earlier page. 33 | .ie !\\n(^b-1 \{\ 34 | \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' 35 | .\} 36 | .el \}\ 37 | \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' 38 | .\} 39 | .\} 40 | .fi 41 | .br 42 | .nr ^b 0 43 | .. 44 | .\" # CS - begin code excerpt 45 | .de CS 46 | .RS 47 | .nf 48 | .ta .25i .5i .75i 1i 49 | .. 50 | .\" # CE - end code excerpt 51 | .de CE 52 | .fi 53 | .RE 54 | .. 55 | .TH "tdbc::mysql" n 8.6 Tcl "Tcl Database Connectivity" 56 | .BS 57 | .SH "NAME" 58 | tdbc::mysql \- TDBC-MYSQL bridge 59 | .SH "SYNOPSIS" 60 | package require \fBtdbc::mysql 1.0\fR 61 | .sp 62 | \fBtdbc::mysql::connection create\fR \fIdb\fR ?\fI-option value...\fR? 63 | .br 64 | \fBtdbc::mysql::connection new\fR ?\fI-option value...\fR? 65 | .sp 66 | \fBtdbc::mysql::datasources\fR ?\fB-system\fR|\fB-user\fR? 67 | .sp 68 | \fBtdbc::mysql::drivers\fR 69 | .sp 70 | \fBtdbc::mysql::datasource\fR \fIcommand\fR \fIdriverName\fR ?\fIkeyword\fR-\fIvalue\fR?... 71 | .BE 72 | .SH "DESCRIPTION" 73 | .PP 74 | The \fBtdbc::mysql\fR driver provides a database interface that conforms 75 | to Tcl DataBase Connectivity (TDBC) and allows a Tcl script to connect 76 | to a MySQL database. 77 | .PP 78 | Connection to an MYSQL database is established by invoking 79 | \fBtdbc::mysql::connection create\fR, passing it the name to give the 80 | database handle and a set of \fI-option-value\fR pairs. The available 81 | options are enumerated under CONNECTION OPTIONS below. 82 | As an alternative, \fBtdbc::mysql::connection new\fR may be used to create 83 | a database connection with an automatically assigned name. The return value 84 | from \fBtdbc::mysql::connection new\fR is the name that was chosen for the 85 | connection handle. 86 | .PP 87 | The side effect of \fBtdbc::mysql::connection create\fR is to create a 88 | new database connection.. See \fBtdbc::connection(n)\fR for the 89 | details of how to use the connection to manipulate a database. 90 | .SH "CONNECTION OPTIONS" 91 | .PP 92 | The \fBtdbc::mysql::connection create\fR object command supports the 93 | \fB-encoding\fR, \fB-isolation\fR, \fB-readonly\fR and \fB-timeout\fR 94 | options common to all TDBC drivers. The \fB-encoding\fR option will 95 | always fail unless the encoding is \fButf-8\fR; the database connection 96 | always uses UTF-8 encoding to be able to transfer arbitrary Unicode 97 | characters. The \fB-readonly\fR option must be \fB0\fR, because 98 | MySQL does not offer read-only connections. 99 | .PP 100 | In addition, the following options are recognized: 101 | .IP "\fB-host\fR \fIhostname\fR" 102 | Connects to the host specified by \fIhostname\fR. This option must be 103 | set on the initial creation of the connection; it cannot be changed 104 | after connecting. Default is to connect to the local host. 105 | .IP "\fB-port\fR \fInumber\fR" 106 | Connects to a MySQL server listening on the port specified by \fInumber\fR. 107 | This option may not be changed after connecting. It is used only when 108 | \fIhost\fR is specified and is not \fBlocalhost\fR. 109 | .IP "\fB-socket\fR \fIpath\fR" 110 | Connects to a MySQL server listening on the Unix socket or named 111 | pipe specified by \fIpath\fR . This option may not be changed after connecting. 112 | It is used only when \fI-host\fR is not specified or is \fBlocalhost\fR. 113 | .IP "\fB-user\fR \fIname\fR" 114 | Presents \fIname\fR as the user name to the MySQL server. Default is the 115 | current user ID. 116 | .IP "\fB-passwd\fR \fIpassword\fR" 117 | .IP "\fB-password\fR \fIpassword\fR" 118 | These two options are synonymous. They present the given \fIpassword\fR as 119 | the user's password to the MySQL server. Default is not to present a password. 120 | .IP "\fB-database\fR \fIname\fR" 121 | .IP "\fB-db\fR \fIname\fR" 122 | These two options are synonymous. They present the given \fIname\fR as the 123 | name of the default database to use in MySQL queries. If not specified, 124 | the default database for the current user is used. 125 | .IP "\fB-interactive\fR \fIflag\fR" 126 | The \fIflag\fR value must be a Boolean value. If it is \fBtrue\fR (or 127 | any equivalent), the default timeout is set for an interactive user, 128 | otherwise, the default timeout is set for a batch user. This option 129 | is meaningful only on initial connection. When using the \fBconfigure\fR 130 | method on a MySQL connection use the \fB-timeout\fR option to set the 131 | timeout desired. 132 | .IP \fB-ssl_ca\fR \fIstring\fR 133 | .IP \fB-ssl_capath\fR \fIstring\fR 134 | .IP \fB-ssl_cert\fR \fIstring\fR 135 | .IP \fB-ssl_cipher\fR \fIstring\fR 136 | .IP \fB-ssl_key\fR \fIstring\fR 137 | These five options set the certificate authority, certificate authority 138 | search path, SSL certificate, transfer cipher, and SSL key to the 139 | given \fIstring\fR arguments. These options may be specified only 140 | on initial connection to a database, not in the \fBconfigure\fR method 141 | of an existing connection. Default is not to use SSL. 142 | .SH EXAMPLES 143 | .PP 144 | .CS 145 | tdbc::mysql::connection -user joe -passwd sesame -db joes_database 146 | .CE 147 | Connects to the MySQL server on the local host using the default 148 | connection method, presenting user ID 'joe' and password 'sesame'. 149 | Uses 'joes_database' as the default database name. 150 | .SH "ADDITIONAL CONNECTION METHODS" 151 | In addition to the usual methods on the tdbc::connection(n) object, 152 | connections to a MySQL database support one additional method: 153 | .IP "\fI$connection\fR \fBevaldirect\fR \fIsqlStatement\fR" 154 | This method takes the given \fIsqlStatement\fR and interprets as 155 | MySQL native SQL code and evaluates it without preparing it. The 156 | statement may not contain variable substitutions. The result set 157 | is returned as a list of lists, with each sublist being the list 158 | of columns of a result row formatted as character strings. Note that 159 | the string formatting is done by MySQL and not by Tcl, so details 160 | like the appearance of floating point numbers may differ. 161 | \fIThis command is not recommended\fR for anything where the usual 162 | \fIprepare\fR or \fIpreparecall\fR methods work correctly. It is 163 | provided so that data management language statements that are 164 | not implemented in MySQL's prepared statement API, such as 165 | \fBCREATE DATABASE\fR or \fBCREATE PROCEDURE\fR, can be executed. 166 | .SH "SEE ALSO" 167 | tdbc(n), tdbc::connection(n), tdbc::resultset(n), tdbc::statement(n) 168 | .SH "KEYWORDS" 169 | TDBC, SQL, MySQL, database, connectivity, connection 170 | .SH "COPYRIGHT" 171 | Copyright (c) 2009 by Kevin B. Kenny. 172 | .\" Local Variables: 173 | .\" mode: nroff 174 | .\" End: 175 | .\" 176 | -------------------------------------------------------------------------------- /library/tdbcmysql.tcl: -------------------------------------------------------------------------------- 1 | # tdbcmysql.tcl -- 2 | # 3 | # Class definitions and Tcl-level methods for the tdbc::mysql bridge. 4 | # 5 | # Copyright (c) 2008 by Kevin B. Kenny 6 | # See the file "license.terms" for information on usage and redistribution 7 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. 8 | # 9 | # RCS: @(#) $Id: tdbcmysql.tcl,v 1.47 2008/02/27 02:08:27 kennykb Exp $ 10 | # 11 | #------------------------------------------------------------------------------ 12 | 13 | package require tdbc 14 | 15 | ::namespace eval ::tdbc::mysql { 16 | 17 | namespace export connection datasources drivers 18 | 19 | } 20 | 21 | #------------------------------------------------------------------------------ 22 | # 23 | # tdbc::mysql::connection -- 24 | # 25 | # Class representing a connection to a database through MYSQL. 26 | # 27 | #------------------------------------------------------------------------------- 28 | 29 | ::oo::class create ::tdbc::mysql::connection { 30 | 31 | superclass ::tdbc::connection 32 | 33 | # The constructor is written in C. It takes alternating keywords 34 | # and values pairs as its argumenta. (See the manual page for the 35 | # available options.) 36 | 37 | variable foreignKeysStatement 38 | 39 | # The 'statementCreate' method delegates to the constructor of the 40 | # statement class 41 | 42 | forward statementCreate ::tdbc::mysql::statement create 43 | 44 | # The 'columns' method returns a dictionary describing the tables 45 | # in the database 46 | 47 | method columns {table {pattern %}} { 48 | 49 | # To return correct lengths of CHARACTER and BINARY columns, 50 | # we need to know the maximum lengths of characters in each 51 | # collation. We cache this information only once, on the first 52 | # call to 'columns'. 53 | 54 | if {[my NeedCollationInfo]} { 55 | my SetCollationInfo {*}[my allrows -as lists { 56 | SELECT coll.id, cs.maxlen 57 | FROM INFORMATION_SCHEMA.COLLATIONS coll, 58 | INFORMATION_SCHEMA.CHARACTER_SETS cs 59 | WHERE cs.CHARACTER_SET_NAME = coll.CHARACTER_SET_NAME 60 | ORDER BY coll.id DESC 61 | }] 62 | } 63 | 64 | return [my Columns $table $pattern] 65 | } 66 | 67 | # The 'preparecall' method gives a portable interface to prepare 68 | # calls to stored procedures. It delegates to 'prepare' to do the 69 | # actual work. 70 | 71 | method preparecall {call} { 72 | regexp {^[[:space:]]*(?:([A-Za-z_][A-Za-z_0-9]*)[[:space:]]*=)?(.*)} \ 73 | $call -> varName rest 74 | if {$varName eq {}} { 75 | my prepare "CALL $rest" 76 | } else { 77 | my prepare \\{:$varName=$rest\\} 78 | } 79 | } 80 | 81 | # The 'init', 'begintransaction', 'commit, 'rollback', 'tables' 82 | # 'NeedCollationInfo', 'SetCollationInfo', and 'Columns' methods 83 | # are implemented in C. 84 | 85 | # The 'BuildForeignKeysStatements' method builds a SQL statement to 86 | # retrieve the foreign keys from a database. (It executes once the 87 | # first time the 'foreignKeys' method is executed, and retains the 88 | # prepared statements for reuse.) It is slightly nonstandard because 89 | # MYSQL doesn't name the PRIMARY constraints uniquely. 90 | 91 | method BuildForeignKeysStatement {} { 92 | 93 | foreach {exists1 clause1} { 94 | 0 {} 95 | 1 { AND fkc.REFERENCED_TABLE_NAME = :primary} 96 | } { 97 | foreach {exists2 clause2} { 98 | 0 {} 99 | 1 { AND fkc.TABLE_NAME = :foreign} 100 | } { 101 | set stmt [my prepare " 102 | SELECT rc.CONSTRAINT_SCHEMA AS \"foreignConstraintSchema\", 103 | rc.CONSTRAINT_NAME AS \"foreignConstraintName\", 104 | rc.UPDATE_RULE AS \"updateAction\", 105 | rc.DELETE_RULE AS \"deleteAction\", 106 | fkc.REFERENCED_TABLE_SCHEMA AS \"primarySchema\", 107 | fkc.REFERENCED_TABLE_NAME AS \"primaryTable\", 108 | fkc.REFERENCED_COLUMN_NAME AS \"primaryColumn\", 109 | fkc.TABLE_SCHEMA AS \"foreignSchema\", 110 | fkc.TABLE_NAME AS \"foreignTable\", 111 | fkc.COLUMN_NAME AS \"foreignColumn\", 112 | fkc.ORDINAL_POSITION AS \"ordinalPosition\" 113 | FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc 114 | INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE fkc 115 | ON fkc.CONSTRAINT_NAME = rc.CONSTRAINT_NAME 116 | AND fkc.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA 117 | WHERE 1=1 118 | $clause1 119 | $clause2 120 | "] 121 | dict set foreignKeysStatement $exists1 $exists2 $stmt 122 | } 123 | } 124 | } 125 | } 126 | 127 | #------------------------------------------------------------------------------ 128 | # 129 | # tdbc::mysql::statement -- 130 | # 131 | # The class 'tdbc::mysql::statement' models one statement against a 132 | # database accessed through an MYSQL connection 133 | # 134 | #------------------------------------------------------------------------------ 135 | 136 | ::oo::class create ::tdbc::mysql::statement { 137 | 138 | superclass ::tdbc::statement 139 | 140 | # The 'resultSetCreate' method forwards to the constructor of the 141 | # result set. 142 | 143 | forward resultSetCreate ::tdbc::mysql::resultset create 144 | 145 | # Methods implemented in C: 146 | # 147 | # constructor connection SQLCode 148 | # The constructor accepts the handle to the connection and the SQL code 149 | # for the statement to prepare. It creates a subordinate namespace to 150 | # hold the statement's active result sets, and then delegates to the 151 | # 'init' method, written in C, to do the actual work of preparing the 152 | # statement. 153 | # params 154 | # Returns descriptions of the parameters of a statement. 155 | # paramtype paramname ?direction? type ?precision ?scale?? 156 | # Declares the type of a parameter in the statement 157 | 158 | } 159 | 160 | #------------------------------------------------------------------------------ 161 | # 162 | # tdbc::mysql::resultset -- 163 | # 164 | # The class 'tdbc::mysql::resultset' models the result set that is 165 | # produced by executing a statement against an MYSQL database. 166 | # 167 | #------------------------------------------------------------------------------ 168 | 169 | ::oo::class create ::tdbc::mysql::resultset { 170 | 171 | superclass ::tdbc::resultset 172 | 173 | # Methods implemented in C include: 174 | 175 | # constructor statement ?dictionary? 176 | # -- Executes the statement against the database, optionally providing 177 | # a dictionary of substituted parameters (default is to get params 178 | # from variables in the caller's scope). 179 | # columns 180 | # -- Returns a list of the names of the columns in the result. 181 | # nextdict 182 | # -- Stores the next row of the result set in the given variable in 183 | # the caller's scope as a dictionary whose keys are 184 | # column names and whose values are column values, or else 185 | # as a list of cells. 186 | # nextlist 187 | # -- Stores the next row of the result set in the given variable in 188 | # the caller's scope as a list of cells. 189 | # rowcount 190 | # -- Returns a count of rows affected by the statement, or -1 191 | # if the count of rows has not been determined. 192 | 193 | } 194 | -------------------------------------------------------------------------------- /configure.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash -norc 2 | dnl This file is an input file used by the GNU "autoconf" program to 3 | dnl generate the file "configure", which is run during Tcl installation 4 | dnl to configure the system for the local environment. 5 | # 6 | # RCS: @(#) $Id: configure.in,v 1.47 2007/02/09 19:06:47 hobbs Exp $ 7 | 8 | #----------------------------------------------------------------------- 9 | # Sample configure.in for Tcl Extensions. The only places you should 10 | # need to modify this file are marked by the string __CHANGE__ 11 | #----------------------------------------------------------------------- 12 | 13 | #----------------------------------------------------------------------- 14 | # Set your package name and version numbers here. 15 | # 16 | # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION 17 | # set as provided. These will also be added as -D defs in your Makefile 18 | # so you can encode the package version directly into the source files. 19 | #----------------------------------------------------------------------- 20 | 21 | AC_INIT([tdbcmysql], [1.0.0]) 22 | 23 | #-------------------------------------------------------------------- 24 | # Call TEA_INIT as the first TEA_ macro to set up initial vars. 25 | # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" 26 | # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. 27 | #-------------------------------------------------------------------- 28 | 29 | AC_CONFIG_AUX_DIR(tclconfig) 30 | TEA_INIT([3.9]) 31 | 32 | #-------------------------------------------------------------------- 33 | # Load the tclConfig.sh file 34 | #-------------------------------------------------------------------- 35 | 36 | TEA_PATH_TCLCONFIG 37 | TEA_LOAD_TCLCONFIG 38 | 39 | #-------------------------------------------------------------------- 40 | # Load the tkConfig.sh file if necessary (Tk extension) 41 | #-------------------------------------------------------------------- 42 | # 43 | #TEA_PATH_TKCONFIG 44 | #TEA_LOAD_TKCONFIG 45 | 46 | #-------------------------------------------------------------------- 47 | # Load the tclooConfig.sh file on Tcl versions where oo is an 48 | # extension. 49 | #-------------------------------------------------------------------- 50 | 51 | if test "${TCL_MAJOR_VERSION}" -lt 8 ; then 52 | AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6 or newer. 53 | Found configuration for Tcl ${TCL_VERSION}.]) 54 | fi 55 | if test "${TCL_MAJOR_VERSION}" -eq 8 ; then 56 | if test "${TCL_MINOR_VERSION}" -lt 6 ; then 57 | AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6 or newer. 58 | Found configuration for Tcl ${TCL_VERSION}.]) 59 | fi 60 | TCLOO_CFLAGS='' 61 | fi 62 | TCL_VERSION_REQ=8.6; AC_SUBST(TCL_VERSION_REQ) 63 | 64 | TEA_PATH_CONFIG(tdbc) 65 | TEA_LOAD_CONFIG(tdbc) 66 | # The next bit probably ought to be in TEA_LOAD_CONFIG 67 | AC_MSG_WARN([Looking for "${tdbc_BIN_DIR}/Makefile"]) 68 | if test -f "${tdbc_BIN_DIR}/Makefile" ; then 69 | AC_MSG_WARN([Found Makefile - using build include spec and lib specs for tdbc]) 70 | tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC} 71 | tdbc_LIBRARY_PATH=${tdbc_BUILD_LIBRARY_PATH} 72 | fi 73 | AC_SUBST(tdbc_LIBRARY_PATH) 74 | AC_SUBST(TDBC_VERSION) 75 | AC_SUBST(tdbc_BIN_DIR) 76 | AC_SUBST(TDBC_LIB_FILE) 77 | 78 | #----------------------------------------------------------------------- 79 | # Handle the --prefix=... option by defaulting to what Tcl gave. 80 | # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. 81 | #----------------------------------------------------------------------- 82 | 83 | TEA_PREFIX 84 | 85 | #----------------------------------------------------------------------- 86 | # Standard compiler checks. 87 | # This sets up CC by using the CC env var, or looks for gcc otherwise. 88 | # This also calls AC_PROG_CC and a few others to create the basic setup 89 | # necessary to compile executables. 90 | #----------------------------------------------------------------------- 91 | 92 | TEA_SETUP_COMPILER 93 | AC_C_INLINE 94 | AC_CHECK_TYPE([long long],[ 95 | AC_DEFINE([HAVE_LONG_LONG],[1]) 96 | AC_CHECK_SIZEOF([long long]) 97 | ],[],[]) 98 | AC_CHECK_SIZEOF([long]) 99 | AC_DEFINE([DONT_TD_VOID],[1]) 100 | 101 | #----------------------------------------------------------------------- 102 | # Specify the C source files to compile in TEA_ADD_SOURCES, 103 | # public headers that need to be installed in TEA_ADD_HEADERS, 104 | # stub library C source files to compile in TEA_ADD_STUB_SOURCES, 105 | # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. 106 | # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS 107 | # and PKG_TCL_SOURCES. 108 | #----------------------------------------------------------------------- 109 | 110 | TEA_ADD_SOURCES(generic/tdbcmysql.c generic/mysqlStubInit.c) 111 | TEA_ADD_HEADERS(generic/fakemysql.h generic/mysqlStubs.h) 112 | if test "${TCL_MAJOR_VERSION}" -eq 8 ; then 113 | if test "${TCL_MINOR_VERSION}" -eq 5 ; then 114 | TEA_ADD_INCLUDES([${TCLOO_INCLUDE_SPEC}]) 115 | TEA_ADD_LIBS([${TCLOO_STUB_LIB_SPEC}]) 116 | fi 117 | fi 118 | TEA_ADD_CFLAGS([${TCLOO_CFLAGS}]) 119 | TEA_ADD_INCLUDES([${tdbc_INCLUDE_SPEC}]) 120 | if test "x${TEA_PLATFORM}" = "xwindows" -a "x${GCC}" != "xyes" ; then 121 | TEA_ADD_LIBS([\"`${CYGPATH} ${tdbc_STUB_LIB_PATH}`\"]) 122 | else 123 | TEA_ADD_LIBS([${tdbc_STUB_LIB_SPEC}]) 124 | fi 125 | TEA_ADD_CFLAGS([${tdbc_CFLAGS}]) 126 | TEA_ADD_STUB_SOURCES() 127 | TEA_ADD_TCL_SOURCES([library/tdbcmysql.tcl]) 128 | 129 | #-------------------------------------------------------------------- 130 | # A few miscellaneous platform-specific items: 131 | # 132 | # Define a special symbol for Windows (BUILD_sample in this case) so 133 | # that we create the export library with the dll. 134 | # 135 | # Windows creates a few extra files that need to be cleaned up. 136 | # You can add more files to clean if your extension creates any extra 137 | # files. 138 | # 139 | # TEA_ADD_* any platform specific compiler/build info here. 140 | #-------------------------------------------------------------------- 141 | 142 | # Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure 143 | # and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var. 144 | 145 | if test "${TEA_PLATFORM}" = "windows" ; then 146 | AC_DEFINE(_WIN32) 147 | fi 148 | 149 | #-------------------------------------------------------------------- 150 | # Choose which headers you need. Extension authors should try very 151 | # hard to only rely on the Tcl public header files. Internal headers 152 | # contain private data structures and are subject to change without 153 | # notice. 154 | # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG 155 | #-------------------------------------------------------------------- 156 | 157 | TEA_PUBLIC_TCL_HEADERS 158 | 159 | #-------------------------------------------------------------------- 160 | # Check whether --enable-threads or --disable-threads was given. 161 | # This auto-enables if Tcl was compiled threaded. 162 | #-------------------------------------------------------------------- 163 | 164 | TEA_ENABLE_THREADS 165 | 166 | #-------------------------------------------------------------------- 167 | # The statement below defines a collection of symbols related to 168 | # building as a shared library instead of a static library. 169 | #-------------------------------------------------------------------- 170 | 171 | TEA_ENABLE_SHARED 172 | 173 | #-------------------------------------------------------------------- 174 | # This macro figures out what flags to use with the compiler/linker 175 | # when building shared/static debug/optimized objects. This information 176 | # can be taken from the tclConfig.sh file, but this figures it all out. 177 | #-------------------------------------------------------------------- 178 | 179 | TEA_CONFIG_CFLAGS 180 | 181 | #-------------------------------------------------------------------- 182 | # Set the default compiler switches based on the --enable-symbols option. 183 | #-------------------------------------------------------------------- 184 | 185 | TEA_ENABLE_SYMBOLS 186 | 187 | #-------------------------------------------------------------------- 188 | # Everyone should be linking against the Tcl stub library. If you 189 | # can't for some reason, remove this definition. If you aren't using 190 | # stubs, you also need to modify the SHLIB_LD_LIBS setting below to 191 | # link against the non-stubbed Tcl library. Add Tk too if necessary. 192 | #-------------------------------------------------------------------- 193 | 194 | AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) 195 | AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) 196 | 197 | #-------------------------------------------------------------------- 198 | # This macro generates a line to use when building a library. It 199 | # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, 200 | # and TEA_LOAD_TCLCONFIG macros above. 201 | #-------------------------------------------------------------------- 202 | 203 | TEA_MAKE_LIB 204 | TEAX_VC_MANIFEST 205 | 206 | #-------------------------------------------------------------------- 207 | # Determine the name of the tclsh and/or wish executables in the 208 | # Tcl and Tk build directories or the location they were installed 209 | # into. These paths are used to support running test cases only, 210 | # the Makefile should not be making use of these paths to generate 211 | # a pkgIndex.tcl file or anything else at extension build time. 212 | #-------------------------------------------------------------------- 213 | 214 | TEA_PROG_TCLSH 215 | 216 | #-------------------------------------------------------------------- 217 | # Finally, substitute all of the various values into the Makefile. 218 | # You may alternatively have a special pkgIndex.tcl.in or other files 219 | # which require substituting th AC variables in. Include these here. 220 | #-------------------------------------------------------------------- 221 | 222 | CONFIGURE_OUTPUTS="Makefile pkgIndex.tcl config.cache config.log config.status" 223 | AC_SUBST(CONFIGURE_OUTPUTS) 224 | 225 | AC_CONFIG_FILES([Makefile pkgIndex.tcl]) 226 | AC_OUTPUT 227 | 228 | # This is a comment added to force the 'execute' permission to update 229 | # in the Fossil repository. 230 | -------------------------------------------------------------------------------- /generic/fakemysql.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fakemysql.h -- 3 | * 4 | * Fake definitions of the MySQL API sufficient to build tdbc::mysql 5 | * without having an MySQL installation on the build system. This file 6 | * comprises only data type, constant and function definitions. 7 | * 8 | * The programmers of this file believe that it contains material not 9 | * subject to copyright under the doctrines of scenes a faire and 10 | * of merger of idea and expression. Accordingly, this file is in the 11 | * public domain. 12 | * 13 | *----------------------------------------------------------------------------- 14 | */ 15 | 16 | #ifndef FAKEMYSQL_H_INCLUDED 17 | #define FAKEMYSQL_H_INCLUDED 18 | 19 | #include 20 | 21 | #ifndef MODULE_SCOPE 22 | #define MODULE_SCOPE extern 23 | #endif 24 | 25 | MODULE_SCOPE Tcl_LoadHandle MysqlInitStubs(Tcl_Interp*); 26 | 27 | #ifdef _WIN32 28 | #define STDCALL __stdcall 29 | #else 30 | #define STDCALL /* nothing */ 31 | #endif 32 | 33 | enum enum_field_types { 34 | MYSQL_TYPE_DECIMAL=0, 35 | MYSQL_TYPE_TINY=1, 36 | MYSQL_TYPE_SHORT=2, 37 | MYSQL_TYPE_LONG=3, 38 | MYSQL_TYPE_FLOAT=4, 39 | MYSQL_TYPE_DOUBLE=5, 40 | MYSQL_TYPE_NULL=6, 41 | MYSQL_TYPE_TIMESTAMP=7, 42 | MYSQL_TYPE_LONGLONG=8, 43 | MYSQL_TYPE_INT24=9, 44 | MYSQL_TYPE_DATE=10, 45 | MYSQL_TYPE_TIME=11, 46 | MYSQL_TYPE_DATETIME=12, 47 | MYSQL_TYPE_YEAR=13, 48 | MYSQL_TYPE_NEWDATE=14, 49 | MYSQL_TYPE_VARCHAR=15, 50 | MYSQL_TYPE_BIT=16, 51 | MYSQL_TYPE_NEWDECIMAL=246, 52 | MYSQL_TYPE_ENUM=247, 53 | MYSQL_TYPE_SET=248, 54 | MYSQL_TYPE_TINY_BLOB=249, 55 | MYSQL_TYPE_MEDIUM_BLOB=250, 56 | MYSQL_TYPE_LONG_BLOB=251, 57 | MYSQL_TYPE_BLOB=252, 58 | MYSQL_TYPE_VAR_STRING=253, 59 | MYSQL_TYPE_STRING=254, 60 | MYSQL_TYPE_GEOMETRY=255 61 | }; 62 | 63 | enum mysql_option { 64 | MYSQL_SET_CHARSET_NAME=7, 65 | }; 66 | 67 | enum mysql_status { 68 | MYSQL_STATUS_READY=0, 69 | }; 70 | 71 | #define CLIENT_COMPRESS 32 72 | #define CLIENT_INTERACTIVE 1024 73 | #define MYSQL_DATA_TRUNCATED 101 74 | #define MYSQL_ERRMSG_SIZE 512 75 | #define MYSQL_NO_DATA 100 76 | #define SCRAMBLE_LENGTH 20 77 | #define SQLSTATE_LENGTH 5 78 | 79 | typedef struct st_list LIST; 80 | typedef struct st_mem_root MEM_ROOT; 81 | typedef struct st_mysql MYSQL; 82 | typedef struct st_mysql_bind MYSQL_BIND; 83 | typedef struct st_mysql_field MYSQL_FIELD; 84 | typedef struct st_mysql_res MYSQL_RES; 85 | typedef char** MYSQL_ROW; 86 | typedef struct st_mysql_stmt MYSQL_STMT; 87 | typedef char my_bool; 88 | #ifndef Socket_defined 89 | typedef int my_socket; 90 | #define INVALID_SOCKET -1 91 | #endif 92 | typedef Tcl_WideUInt my_ulonglong; 93 | typedef struct st_net NET; 94 | typedef struct st_used_mem USED_MEM; 95 | typedef struct st_vio Vio; 96 | 97 | struct st_mem_root { 98 | USED_MEM *free; 99 | USED_MEM *used; 100 | USED_MEM *pre_alloc; 101 | size_t min_malloc; 102 | size_t block_size; 103 | unsigned int block_num; 104 | unsigned int first_block_usage; 105 | void (*error_handler)(void); 106 | }; 107 | 108 | struct st_mysql_options { 109 | unsigned int connect_timeout; 110 | unsigned int read_timeout; 111 | unsigned int write_timeout; 112 | unsigned int port; 113 | unsigned int protocol; 114 | unsigned long client_flag; 115 | char *host; 116 | char *user; 117 | char *password; 118 | char *unix_socket; 119 | char *db; 120 | struct st_dynamic_array *init_commands; 121 | char *my_cnf_file; 122 | char *my_cnf_group; 123 | char *charset_dir; 124 | char *charset_name; 125 | char *ssl_key; 126 | char *ssl_cert; 127 | char *ssl_ca; 128 | char *ssl_capath; 129 | char *ssl_cipher; 130 | char *shared_memory_base_name; 131 | unsigned long max_allowed_packet; 132 | my_bool use_ssl; 133 | my_bool compress,named_pipe; 134 | my_bool rpl_probe; 135 | my_bool rpl_parse; 136 | my_bool no_master_reads; 137 | #if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) 138 | my_bool separate_thread; 139 | #endif 140 | enum mysql_option methods_to_use; 141 | char *client_ip; 142 | my_bool secure_auth; 143 | my_bool report_data_truncation; 144 | int (*local_infile_init)(void **, const char *, void *); 145 | int (*local_infile_read)(void *, char *, unsigned int); 146 | void (*local_infile_end)(void *); 147 | int (*local_infile_error)(void *, char *, unsigned int); 148 | void *local_infile_userdata; 149 | void *extension; 150 | }; 151 | 152 | struct st_net { 153 | #if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY) 154 | Vio *vio; 155 | unsigned char *buff; 156 | unsigned char *buff_end; 157 | unsigned char *write_pos; 158 | unsigned char *read_pos; 159 | my_socket fd; 160 | unsigned long remain_in_buf; 161 | unsigned long length; 162 | unsigned long buf_length; 163 | unsigned long where_b; 164 | unsigned long max_packet; 165 | unsigned long max_packet_size; 166 | unsigned int pkt_nr; 167 | unsigned int compress_pkt_nr; 168 | unsigned int write_timeout; 169 | unsigned int read_timeout; 170 | unsigned int retry_count; 171 | int fcntl; 172 | unsigned int *return_status; 173 | unsigned char reading_or_writing; 174 | char save_char; 175 | my_bool unused0; 176 | my_bool unused; 177 | my_bool compress; 178 | my_bool unused1; 179 | #endif 180 | unsigned char *query_cache_query; 181 | unsigned int last_errno; 182 | unsigned char error; 183 | my_bool unused2; 184 | my_bool return_errno; 185 | char last_error[MYSQL_ERRMSG_SIZE]; 186 | char sqlstate[SQLSTATE_LENGTH+1]; 187 | void *extension; 188 | #if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) 189 | my_bool skip_big_packet; 190 | #endif 191 | }; 192 | 193 | /* 194 | * st_mysql differs between 5.0 and 5.1, but the 5.0 version is a 195 | * strict subset, we don't use any of the 5.1 fields, and we don't 196 | * ever allocate the structure ourselves. 197 | */ 198 | 199 | struct st_mysql { 200 | NET net; 201 | unsigned char *connector_fd; 202 | char *host; 203 | char *user; 204 | char *passwd; 205 | char *unix_socket; 206 | char *server_version; 207 | char *host_info; 208 | char *info; 209 | char *db; 210 | struct charset_info_st *charset; 211 | MYSQL_FIELD *fields; 212 | MEM_ROOT field_alloc; 213 | my_ulonglong affected_rows; 214 | my_ulonglong insert_id; 215 | my_ulonglong extra_info; 216 | unsigned long thread_id; 217 | unsigned long packet_length; 218 | unsigned int port; 219 | unsigned long client_flag; 220 | unsigned long server_capabilities; 221 | unsigned int protocol_version; 222 | unsigned int field_count; 223 | unsigned int server_status; 224 | unsigned int server_language; 225 | unsigned int warning_count; 226 | struct st_mysql_options options; 227 | enum mysql_status status; 228 | my_bool free_me; 229 | my_bool reconnect; 230 | char scramble[SCRAMBLE_LENGTH+1]; 231 | my_bool rpl_pivot; 232 | struct st_mysql *master; 233 | struct st_mysql *next_slave; 234 | struct st_mysql* last_used_slave; 235 | struct st_mysql* last_used_con; 236 | LIST *stmts; 237 | const struct st_mysql_methods *methods; 238 | void *thd; 239 | my_bool *unbuffered_fetch_owner; 240 | char *info_buffer; 241 | }; 242 | 243 | /* 244 | * There are different version of the MYSQL_BIND structure before and after 245 | * MySQL 5.1. We go after the fields of the structure using accessor functions 246 | * so that the code in this file is compatible with both versions. 247 | */ 248 | 249 | struct st_mysql_bind_51 { /* Post-5.1 */ 250 | unsigned long* length; 251 | my_bool* is_null; 252 | void* buffer; 253 | my_bool* error; 254 | unsigned char* row_ptr; 255 | void (*store_param_func)(NET* net, MYSQL_BIND* param); 256 | void (*fetch_result)(MYSQL_BIND*, MYSQL_FIELD*, unsigned char**); 257 | void (*skip_result)(MYSQL_BIND*, MYSQL_FIELD*, unsigned char**); 258 | unsigned long buffer_length; 259 | unsigned long offset; 260 | unsigned long length_value; 261 | unsigned int param_number; 262 | unsigned int pack_length; 263 | enum enum_field_types buffer_type; 264 | my_bool error_value; 265 | my_bool is_unsigned; 266 | my_bool long_data_used; 267 | my_bool is_null_value; 268 | void* extension; 269 | }; 270 | 271 | struct st_mysql_bind_50 { /* Pre-5.1 */ 272 | unsigned long* length; 273 | my_bool* is_null; 274 | void* buffer; 275 | my_bool* error; 276 | enum enum_field_types buffer_type; 277 | unsigned long buffer_length; 278 | unsigned char* row_ptr; 279 | unsigned long offset; 280 | unsigned long length_value; 281 | unsigned int param_number; 282 | unsigned int pack_length; 283 | my_bool error_value; 284 | my_bool is_unsigned; 285 | my_bool long_data_used; 286 | my_bool is_null_value; 287 | void (*store_param_func)(NET* net, MYSQL_BIND* param); 288 | void (*fetch_result)(MYSQL_BIND*, MYSQL_FIELD*, unsigned char**); 289 | void (*skip_result)(MYSQL_BIND*, MYSQL_FIELD*, unsigned char**); 290 | }; 291 | 292 | /* 293 | * There are also different versions of the MYSQL_FIELD structure; fortunately, 294 | * the 5.1 version is a strict extension of the 5.0 version. 295 | */ 296 | 297 | struct st_mysql_field { 298 | char* name; 299 | char *org_name; 300 | char* table; 301 | char* org_table; 302 | char* db; 303 | char* catalog; 304 | char* def; 305 | unsigned long length; 306 | unsigned long max_length; 307 | unsigned int name_length; 308 | unsigned int org_name_length; 309 | unsigned int table_length; 310 | unsigned int org_table_length; 311 | unsigned int db_length; 312 | unsigned int catalog_length; 313 | unsigned int def_length; 314 | unsigned int flags; 315 | unsigned int decimals; 316 | unsigned int charsetnr; 317 | enum enum_field_types type; 318 | }; 319 | struct st_mysql_field_50 { 320 | struct st_mysql_field field; 321 | }; 322 | struct st_mysql_field_51 { 323 | struct st_mysql_field field; 324 | void* extension; 325 | }; 326 | #define NOT_NULL_FLAG 1 327 | 328 | #define IS_NUM(t) ((t) <= MYSQL_TYPE_INT24 || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) 329 | 330 | #define mysql_library_init mysql_server_init 331 | #define mysql_library_end mysql_server_end 332 | 333 | #include "mysqlStubs.h" 334 | 335 | #endif /* not FAKEMYSQL_H_INCLUDED */ 336 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2012-11-15 KevinB. Kenny 2 | 3 | * configure.in: Made change so that `make test` works even 4 | * Makefile.in: against an uninstalled version of tdbc. 5 | * configure: autoconf 2.68 6 | *** ADVANCED THE VERSION OF AUTOCONF IN USE *** 7 | 8 | 2012-11-08 Don Porter 9 | 10 | * configure.in: 11 | * README: Advanced version number to 1.0.0. 12 | * configure: autoconf 2.59 13 | 14 | 2012-07-26 Jan Nijtmans 15 | 16 | * generic/mysqlStubInit.c: Fix [14a8b7c3bd]: package tdbc::mysql fails 17 | to load under Fedora 17. Make some tables "const". 18 | * tclconfig/install-sh: Update to latest TEA 19 | * tclconfig/tcl.m4 20 | * configure: autoconf-2.59 21 | 22 | 2012-07-13 Kevin B. Kenny 23 | 24 | * test/tdbcmysql.test: Make functional tests refuse to run unless 25 | the environment variable TDBCMYSQL_TEST_DB 26 | explicitly designates a database. 27 | 28 | 2012-07-10 Kevin B. Kenny 29 | 30 | * generic/tdbcmysql.c: Fixed a non-static table argument to 31 | Tcl_GetIndexFromObjStruct. 32 | 33 | 2012-06-10 Jan Nijtmans 34 | 35 | * configure.in: make TDBC API functions MODULE_SCOPE 36 | * configure: autoconf-2.59 37 | 38 | 2012-06-08 Jan Nijtmans 39 | 40 | * tclconfig/tcl.m4: Update to latest TEA 41 | * configure: autoconf-2.59 42 | 43 | 2011-09-19 Kevin B. Kenny 44 | 45 | * Makefie.in: Added a 'valgrind' rule for memory leak checking. 46 | * tests/all.tcl: Changed behaviour to 'fall off the end' to 47 | facilitate 'valgrind. 48 | 49 | 2011-07-19 Kevin B. Kenny 50 | 51 | * configure.in: 52 | * Makefile.in: 53 | * README: Advanced version number to 1.0b17. 54 | 55 | * configure: autoconf 2.59 56 | 57 | 2011-07-18 Don Porter 58 | 59 | * configure.in: Update to latest TEA 3.9 revisions. 60 | * Makefile.in: 61 | * tclconfig/*: 62 | 63 | * configure: autoconf-2.59 64 | 65 | 2011-02-20 Kevin B. Kenny 66 | 67 | * tests/tdbcmysql.test: 68 | Added rudimentary test for 'nextresults' - the method 69 | is a dummy because the calls supported by tdbc::mysql 70 | do not allow for multiple result sets. 71 | 72 | 2011-01-26 Kevin B. Kenny 73 | 74 | * doc/tdbc_mysql.n: 75 | Added empty comment at the start of each manpage because 'man' 76 | interprets comments there as directives. Thanks to Konstantin 77 | Kohmoutov for reporting and diagnosing this error. 78 | 79 | 2011-01-25 Kevin B. Kenny 80 | 81 | * generic/tdbcmysql.c: Fixed a bug in data types of small integers 82 | on 64-bit machines. Who would have imagined 83 | that MSYQL_TYPE_LONG doesn't mean 'long' but 84 | rather 'int'? 85 | * tests/tdbcmysql.test (tdbc::mysql-1.6,24.[4567]): 86 | Quieted test cases on 64-bit machines and on MySQL earlier 87 | than 5.1.16, which is the first version on which 88 | 'foreignkeys' functions correctly. 89 | Thanks to Damon Courtney for reporting these bugs. 90 | 91 | 2010-12-28 Kevin B. Kenny 92 | 93 | * generic/fakemysql.h: Added the MYSQL data structure and the 94 | nest of other definitions that it depends on. 95 | * generic/mysqlStubDefs.txt: Added mysql_affected_rows and 96 | mysql_field_count. 97 | * generic/mysqlStubInit.c, generic/mysqlStubs.h: Regenerated. 98 | * generic/tdbcmysql.c: Added 'evaldirect' method that allows 99 | executing statements that are unimplemented 100 | in the MySQL prepared statement API. 101 | * generic/tdbcmysql.tcl: Did a rough (not really functional) hack 102 | at formatting prepared statements. 103 | * tests/tdbcmysql.test (tdbc::mysql-25.*): Added two tests for 104 | creating a (parameterless) stored procedure and executing it. 105 | 106 | 2010-09-03 Kevin B. Kenny 107 | 108 | * configure.in: Added missing TCLOO_CFLAGS because Windows build 109 | failed to link without it. 110 | * configure: autoconf 2-59 111 | 112 | * generic/mysqlStubInit.c: 113 | Made changes to attempt to open the 114 | MySQL client library by SONAME as well as 115 | pathname, in an effort to fit in better 116 | with systems where libmysqlclient-devel 117 | is not installed. 118 | 119 | * library/tdbcmysql.tcl: 120 | * tests/tdbcmysql.test: 121 | Changed 'keySequence' to 'ordinalPosition' in 122 | 'foreignkeys' for consistency with 'primarykeys'. 123 | 124 | * configure.in: 125 | * Makefile.in: 126 | * pkgIndex.tcl.in (new file): 127 | * README: 128 | * tclconfig/: Upgraded the build to use TEA 3.9. Changed the 129 | approach to pkgIndex.tcl generation. (It's now built 130 | at configure time, rather than from the Makefile.) 131 | Advanced version number to 1.0b16. 132 | 133 | * configure: autoconf 2.59 134 | 135 | 2010-06-19 Kevin B. Kenny 136 | 137 | * Makefile.in: Revised the code at the suggestion 138 | * generic/tdbcmysql.c: of Andreas Kupries to avoid using 139 | * tests/all.tcl: 'tcl_findLibrary' and instead execute 140 | * tests/tdbcmysql.test: both 'source' and 'load' commands from 141 | 'pkgIndex.tcl'. Revised the 'make test' 142 | rule, and the test scripts, to 143 | test successfully under the new regime. 144 | Thanks to Andreas for providing the 145 | original patch, and to Joe English 146 | for providing ideas for simplifying 147 | and repairing 'make test' under the 148 | new regime. 149 | 150 | 2010-05-23 Kevin B. Kenny 151 | 152 | * library/tdbcmysql.tcl: Added a 'BuildForeignKeysStatement' method 153 | to tdbcmysql::connection that overrides the 154 | one in the base class and accommodates the 155 | nonstandard INFORMATION_SCHEMA provided in 156 | MySQL. 157 | * tests/tdbcmysql.test: Added test cases for '$db primarykeys' 158 | and '$db foreignkeys' 159 | 160 | 2010-05-12 Kevin B. Kenny 161 | 162 | * generic/fakesql.h: 163 | Added dual definitions of data structures that change 164 | between MySQL 5.0 and 5.1. 165 | * generic/mysqlStubDefs.h: 166 | Added code to link to mysqlclient_r and mysqlclient 167 | as well as mysql so that client libs can be found 168 | on Unix. Added query of the client lib version. 169 | * generic/mysqlStubInit.c: 170 | Regenerate 171 | * generic/mysqlStubs.h: 172 | Regenerate 173 | * generic/tdbcmysql.c: 174 | Modified to make MYSQL_BIND and MYSQL_FIELD accesses 175 | go through accessor functions that hit the correct 176 | versions of the structures according to the client 177 | library version. (Tcl can provide ABI stability, 178 | even if MySQL can't!) 179 | * configure.in: Advance release to 1.0b15.1 180 | * README: Advance release to 1.0b15.1 181 | * configure: autoconf-2.59 182 | 183 | 2010-05-10 Kevin B. Kenny 184 | 185 | * aclocal.m4: Synchronize with tdbc. 186 | * configure.in: Advance TEA version to 3.7. Advance release to 1.0b15. 187 | Corrected the TDBC stub library specification so that 188 | it works under MSVC. 189 | * generic/mysqlStubDefs.txt: 190 | Split out the linkage convention so that 191 | genExtStubs.tcl can generate syntactically correct 192 | VC++ pointer-to-function declarations. 193 | * generic/mysqlStubInit.c: 194 | * generic/mysqlStubs.h: 195 | Regenerate 196 | * generic/tdbcmysql.c: 197 | Added code to silence VC++ warnings. 198 | * README: Advance release to 1.0b15 199 | * tclconfig/: Advance to TEA 3.7 200 | * configure: autoconf-2.59 201 | 202 | 2010-05-10 Andreas Kupries 203 | 204 | * generic/tdbcmysql.c: Fixed violations of strict C89. 205 | * Makefile.in: Removed attempt to generate a stub library. Drivers 206 | do not export stub tables. 207 | 208 | 2010-05-07 Andreas Kupries 209 | 210 | * configure.in: Disabled TEA_*_TKCONFIG. Code doesn't depend on Tk. 211 | * configure: Regenerated. 212 | 213 | 2010-04-30 Kevin B. Kenny 214 | 215 | * Makefile.in: Added explicit reference to the TDBC library in the 216 | TCLSH_ENV. Updated the 'dist' rule to include new files. 217 | Added a 'genstubs' rule to make the stubs to load 218 | the MySQL libraries at run time. 219 | * configure.in: Removed compile-time references to the MySQL headers 220 | and libraries. Added new files to SOURCES and HEADERS. 221 | * generic/fakemysql.h (new file): 222 | Minimal subset of mysql.h needed to make tdbc::mysql compile. 223 | * generic/mysqlStubDefs.txt (new file): 224 | Definitions of MySQL runtime library routines brought 225 | in by dynamic loading. 226 | * generic/mysqlStubInit.c (new file): 227 | Code to load the MySQL runtime library and build a stub 228 | table for it. 229 | * generic/mysqlStubDefs.txt (new file): 230 | Definitions of the routines to be resolved when loading 231 | the MySQL library at run time. 232 | * generic/tdbcmysql.c: 233 | Changed tdbc::mysql to load the MySQL library at run time 234 | and to have no compile-time dependencies on MySQL. 235 | * tests/tdbcodbc.test (tdbc::mysql-14.8): 236 | Corrected a misnamed test. 237 | 238 | 2010-04-25 Kevin B. Kenny 239 | 240 | * configure.in: Adjusted TDBC_* environment vars to be tdbc_* 241 | * README: for better TEA compatibility. Advanced version number 242 | to 1.0b14. 243 | * configure: autoconf-2.59 244 | 245 | 2009-09-29 Kevin B. Kenny 246 | 247 | * tests/tdbcmysql.test: Changed all TEST_* environment variables 248 | to TDBCMYSQL_* for easier high-level scripting 249 | of the tests. 250 | 251 | 2009-09-20 Kevin B. Kenny 252 | 253 | * README: 254 | * configure.in: Advance version number to 1.0b13 255 | * configure: autoconf-2.59 256 | 257 | 2009-07-03 Kevin B. Kenny 258 | 259 | * README: 260 | * configure.in: Advance version number to 1.0b12 261 | * configure: autoconf-2.59 262 | 263 | 2009-05-29 Kevin B. Kenny 264 | 265 | * README: 266 | * configure.in: Advance version number to 1.0b11 267 | * configure: autoconf-2.59 268 | 269 | 2009-04-19 Kevin B. Kenny 270 | 271 | * generic/tdbcmysql.c: Silenced a compiler warning about 'fields' 272 | being used uninitialized. 273 | * doc/tdbc_mysql.n: Added missing documentation for 'new' constructors. 274 | 275 | 2009-04-18 Kevin B. Kenny 276 | 277 | * generic/tdbcmysql.c: Changed so that an inappropriate access to 278 | an array or a failing read trace yields NULL. 279 | * tests/tdbcmysql.test: Revised test cases according to the above 280 | change. 281 | * doc/tdbc_mysql.n: Made changes so that NROFF formatting matches 282 | the Tcl standard. 283 | 284 | 2009-04-16 Kevin B. Kenny 285 | 286 | * README: 287 | * configure.in: Advance version number to 1.0b10 288 | * configure: autoconf-2.59 289 | 290 | * generic/tdbcmysql.c: Reworked the allocation of result buffers 291 | so that they belong to the result set and 292 | are not allocated per row. Pushed binding the 293 | results up before mysql_stmt_execute, 294 | avoiding a crash if the same statement handle 295 | has been used before [Ticket 39a78606aa]. 296 | No update made to test suite because 297 | valgrind detected the error with existing 298 | tests on a -DPURIFY build. 299 | 300 | 2009-03-03 Kevin B. Kenny 301 | 302 | * generic/tdbcmysql.c: 303 | * library/tdbcmysql.tcl: Replaced 'init' methods with constructors 304 | written in C. Added 'statementCreate' and 'resultSetCreate' forwarding 305 | in place of the 'statementClass' and 'resultSetClass' variables. 306 | Removed some classes that were the result of overeager copying 307 | from tclodbc. Replaced 'my variable' with variables declared at 308 | class level. 309 | 310 | 2009-02-14 Kevin B. Kenny 311 | 312 | * doc/tdbc_mysql.n: Many small format changes to make 'man2html' 313 | work. 314 | * README: 315 | * configure.in: Advance version number to 1.0b8 316 | * configure: autoconf-2.59 317 | 318 | 2009-02-01 Kevin B. Kenny 319 | 320 | * generic/tdbcmysql.c: 321 | * configure.in: Changed the tests to use the 322 | correct conditionals on mingw. 323 | * configure: Autoconf 2.59 324 | 325 | 2009-01-31 Kevin B. Kenny 326 | 327 | * README: 328 | * configure.in: Advanced version to 1.0b7. 329 | * configure: Regenerated. 330 | * generic/tdbcmysql.c: Revised errorCode generation to be 331 | more [try]-friendly. Changed include to so that 332 | the include path isn't necessary. 333 | * tests/tdbcmysql.test: Added test flags so that a nonstandard port 334 | or socket can be specified. Changed errorCode-dependent tests to 335 | look for the new form of errorCode. 336 | 337 | 2009-01-05 Kevin B. Kenny 338 | 339 | * README: Added a few more hints for building on Windows. 340 | * configure.in: Changes to make tdbcmysql build on Windows. 341 | * generic/tdbcmysql.c: Changed to #include on Windows. 342 | Advanced release to 1.0b6 343 | * configure: autoconf 2.59 344 | 345 | 2009-01-04 Kevin B. Kenny 346 | 347 | * README: 348 | * Makefile.in: 349 | * doc/tdbc_mysql.n: Updated so that files are no longer clones 350 | of the 'tdbcodbc' package. Added installation and distribution code. 351 | * configure.in: Advanced version to 1.0b5 352 | * generic/tdbcmysql.c: Added code to track the declared data types 353 | of parameters and the actual data types of results. Added code to 354 | do direct binary conversions of integers, floating point numbers, 355 | and bit strings. Added checks for binary data on results. 356 | Added disambiguation of duplicated colmn names. 357 | * tests/tdbcmysql.test: Revised test cases to include all the 358 | MySQL data types handled in this driver. Added a test case that 359 | column names are correctly disambiguated. 360 | * configure: autoconf 2.59 361 | 362 | 2009-01-02 Kevin B. Kenny 363 | 364 | Initial baseline of a TDBC driver for MySQL. 365 | -------------------------------------------------------------------------------- /win/makefile.vc: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------- -*- makefile -*- 2 | # makefile.vc -- 3 | # 4 | # Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) 5 | # 6 | # This makefile is based upon the Tcl 8.6 Makefile.vc and modified to 7 | # make it suitable as a general package makefile. Look for the word EDIT 8 | # which marks sections that may need modification. As a minumum you will 9 | # need to change the PROJECT, DOTVERSION and DLLOBJS variables to values 10 | # relevant to your package. 11 | # 12 | # See the file "license.terms" for information on usage and redistribution 13 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. 14 | # 15 | # Copyright (c) 1995-1996 Sun Microsystems, Inc. 16 | # Copyright (c) 1998-2000 Ajuba Solutions. 17 | # Copyright (c) 2001-2005 ActiveState Corporation. 18 | # Copyright (c) 2001-2004 David Gravereaux. 19 | # Copyright (c) 2003-2008 Pat Thoyts. 20 | #------------------------------------------------------------------------------ 21 | 22 | # Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or 23 | # VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) 24 | !if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR) 25 | MSG = ^ 26 | You need to run vcvars32.bat from Developer Studio or setenv.bat from the^ 27 | Platform SDK first to setup the environment. Jump to this line to read^ 28 | the build instructions. 29 | !error $(MSG) 30 | !endif 31 | 32 | #------------------------------------------------------------------------------ 33 | # HOW TO USE this makefile: 34 | # 35 | # 1) It is now necessary to have MSVCDir, MSDevDir or MSSDK set in the 36 | # environment. This is used as a check to see if vcvars32.bat had been 37 | # run prior to running nmake or during the installation of Microsoft 38 | # Visual C++, MSVCDir had been set globally and the PATH adjusted. 39 | # Either way is valid. 40 | # 41 | # You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin 42 | # directory to setup the proper environment, if needed, for your 43 | # current setup. This is a needed bootstrap requirement and allows the 44 | # swapping of different environments to be easier. 45 | # 46 | # 2) To use the Platform SDK (not expressly needed), run setenv.bat after 47 | # vcvars32.bat according to the instructions for it. This can also 48 | # turn on the 64-bit compiler, if your SDK has it. 49 | # 50 | # 3) Targets are: 51 | # all -- Builds everything. 52 | # -- Builds the project (eg: nmake sample) 53 | # test -- Builds and runs the test suite. 54 | # install -- Installs the built binaries and libraries to $(INSTALLDIR) 55 | # in an appropriate subdirectory. 56 | # clean/realclean/distclean -- varying levels of cleaning. 57 | # 58 | # 4) Macros usable on the commandline: 59 | # INSTALLDIR= 60 | # Sets where to install Tcl from the built binaries. 61 | # C:\Progra~1\Tcl is assumed when not specified. 62 | # 63 | # OPTS=loimpact,msvcrt,nothreads,pdbs,profile,static,symbols,unchecked,none 64 | # Sets special options for the core. The default is for none. 65 | # Any combination of the above may be used (comma separated). 66 | # 'none' will over-ride everything to nothing. 67 | # 68 | # loimpact = Adds a flag for how NT treats the heap to keep memory 69 | # in use, low. This is said to impact alloc performance. 70 | # msvcrt = Affects the static option only to switch it from 71 | # using libcmt(d) as the C runtime [by default] to 72 | # msvcrt(d). This is useful for static embedding 73 | # support. 74 | # nothreads = Turns off multithreading support (not recommended) 75 | # static = Builds a static library of the core instead of a 76 | # dll. The shell will be static (and large), as well. 77 | # pdbs = Build detached symbols for release builds. 78 | # profile = Adds profiling hooks. Map file is assumed. 79 | # symbols = Debug build. Links to the debug C runtime, disables 80 | # optimizations and creates pdb symbols files. 81 | # unchecked = Allows a symbols build to not use the debug 82 | # enabled runtime (msvcrt.dll not msvcrtd.dll 83 | # or libcmt.lib not libcmtd.lib). 84 | # 85 | # STATS=memdbg,compdbg,none 86 | # Sets optional memory and bytecode compiler debugging code added 87 | # to the core. The default is for none. Any combination of the 88 | # above may be used (comma separated). 'none' will over-ride 89 | # everything to nothing. 90 | # 91 | # memdbg = Enables the debugging memory allocator. 92 | # compdbg = Enables byte compilation logging. 93 | # 94 | # CHECKS=64bit,fullwarn,nodep,none 95 | # Sets special macros for checking compatability. 96 | # 97 | # 64bit = Enable 64bit portability warnings (if available) 98 | # fullwarn = Builds with full compiler and link warnings enabled. 99 | # Very verbose. 100 | # nodep = Turns off compatability macros to ensure Tk isn't 101 | # being built with deprecated functions. 102 | # 103 | # MACHINE=(ALPHA|AMD64|IA64|IX86) 104 | # Set the machine type used for the compiler, linker, and 105 | # resource compiler. This hook is needed to tell the tools 106 | # when alternate platforms are requested. IX86 is the default 107 | # when not specified. If the CPU environment variable has been 108 | # set (ie: recent Platform SDK) then MACHINE is set from CPU. 109 | # 110 | # TMP_DIR= 111 | # OUT_DIR= 112 | # Hooks to allow the intermediate and output directories to be 113 | # changed. $(OUT_DIR) is assumed to be 114 | # $(BINROOT)\(Release|Debug) based on if symbols are requested. 115 | # $(TMP_DIR) will de $(OUT_DIR)\ by default. 116 | # 117 | # TESTPAT= 118 | # Reads the tests requested to be run from this file. 119 | # 120 | # 5) Examples: 121 | # 122 | # Basic syntax of calling nmake looks like this: 123 | # nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]] 124 | # 125 | # Standard (no frills) 126 | # c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat 127 | # Setting environment for using Microsoft Visual C++ tools. 128 | # c:\tcl_src\win\>nmake -f makefile.vc all 129 | # c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl 130 | # 131 | # Building for Win64 132 | # c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat 133 | # Setting environment for using Microsoft Visual C++ tools. 134 | # c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL 135 | # Targeting Windows pre64 RETAIL 136 | # c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64 137 | # 138 | #------------------------------------------------------------------------------ 139 | #============================================================================== 140 | #------------------------------------------------------------------------------ 141 | 142 | !if !exist("makefile.vc") 143 | MSG = ^ 144 | You must run this makefile only from the directory it is in.^ 145 | Please `cd` to its location first. 146 | !error $(MSG) 147 | !endif 148 | 149 | #------------------------------------------------------------------------- 150 | # Project specific information (EDIT) 151 | # 152 | # You should edit this with the name and version of your project. This 153 | # information is used to generate the name of the package library and 154 | # it's install location. 155 | # 156 | # For example, the sample extension is going to build sample05.dll and 157 | # would install it into $(INSTALLDIR)\lib\sample05 158 | # 159 | # You need to specify the object files that need to be linked into your 160 | # binary here. 161 | # 162 | #------------------------------------------------------------------------- 163 | 164 | PROJECT = tdbcmysql 165 | 166 | # Uncomment the following line if this is a Tk extension. 167 | #PROJECT_REQUIRES_TK=1 168 | !include "rules.vc" 169 | 170 | # nmakehelp -V will search the file for tag, skips until a 171 | # number and returns all character until a character not in [0-9.ab] 172 | # is read. 173 | 174 | !if [echo REM = This file is generated from Makefile.vc > versions.vc] 175 | !endif 176 | # get project version from row AC_INIT([tdbcmysql], ...) 177 | !if [echo DOTVERSION = \>> versions.vc] \ 178 | && [nmakehlp -V ..\configure.in AC_INIT >> versions.vc] 179 | !endif 180 | !if [echo TCL_VERSION_REQ = \>> versions.vc] \ 181 | && [nmakehlp -V ..\configure.in TCL_VERSION_REQ >> versions.vc] 182 | !endif 183 | !include "versions.vc" 184 | 185 | VERSION = $(DOTVERSION:.=) 186 | STUBPREFIX = $(PROJECT)stub 187 | 188 | DLLOBJS = \ 189 | $(TMP_DIR)\tdbcmysql.obj \ 190 | $(TMP_DIR)\mysqlStubInit.obj 191 | 192 | 193 | PRJSTUBOBJS = \ 194 | $(TMP_DIR)\mysqlStubInit.obj 195 | 196 | PRJHEADERS = \ 197 | $(GENERICDIR)\fakemysql.h \ 198 | $(GENERICDIR)\mysqlStubs.h 199 | 200 | 201 | #------------------------------------------------------------------------- 202 | # Target names and paths ( shouldn't need changing ) 203 | #------------------------------------------------------------------------- 204 | 205 | BINROOT = $(MAKEDIR) 206 | ROOT = $(MAKEDIR)\.. 207 | 208 | PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib 209 | PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) 210 | PRJLIB = $(OUT_DIR)\$(PRJLIBNAME) 211 | 212 | PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib 213 | PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME) 214 | 215 | ### Make sure we use backslash only. 216 | PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION) 217 | LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR) 218 | BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR) 219 | DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR) 220 | SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR) 221 | INCLUDE_INSTALL_DIR = $(_TCLDIR)\include 222 | 223 | ### The following paths CANNOT have spaces in them. 224 | GENERICDIR = $(ROOT)\generic 225 | WINDIR = $(ROOT)\win 226 | LIBDIR = $(ROOT)\library 227 | DOCDIR = $(ROOT)\doc 228 | TOOLSDIR = $(ROOT)\tools 229 | COMPATDIR = $(ROOT)\compat 230 | 231 | ### tdbc 232 | TDBC_DOTVERSION = $(DOTVERSION) 233 | TDBC_VERSION = $(TDBC_DOTVERSION:.=) 234 | # tdbc source folder is "../tdbc" in source distribution and 235 | # "../tdbc1.0.0" in tcl8.6.0 bundeled distribution 236 | TDBC_DIR = $(ROOT)\..\tdbc 237 | !if !exist($(TDBC_DIR)) 238 | TDBC_DIR = $(ROOT)\..\tdbc$(TDBC_DOTVERSION) 239 | !endif 240 | TDBC_GENERIC_DIR = $(TDBC_DIR)\generic 241 | ### tdbc stub lib 242 | TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib 243 | TDBCSTUBLIB = "$(_TCLDIR)\lib\$(TDBCSTUBLIBNAME)" 244 | !if !exist($(TDBCSTUBLIB)) 245 | TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME) 246 | !endif 247 | TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll 248 | TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP) 249 | 250 | #--------------------------------------------------------------------- 251 | # Compile flags 252 | #--------------------------------------------------------------------- 253 | 254 | !if !$(DEBUG) 255 | !if $(OPTIMIZING) 256 | ### This cranks the optimization level to maximize speed 257 | cdebug = $(OPTIMIZATIONS) 258 | !else 259 | cdebug = 260 | !endif 261 | !else if "$(MACHINE)" == "IA64" 262 | ### Warnings are too many, can't support warnings into errors. 263 | cdebug = -Zi -Od $(DEBUGFLAGS) 264 | !else 265 | cdebug = -Zi -WX $(DEBUGFLAGS) 266 | !endif 267 | 268 | ### Declarations common to all compiler options 269 | cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE 270 | cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\ 271 | 272 | !if $(MSVCRT) 273 | !if $(DEBUG) && !$(UNCHECKED) 274 | crt = -MDd 275 | !else 276 | crt = -MD 277 | !endif 278 | !else 279 | !if $(DEBUG) && !$(UNCHECKED) 280 | crt = -MTd 281 | !else 282 | crt = -MT 283 | !endif 284 | !endif 285 | 286 | cflags = $(cflags) -DMODULE_SCOPE=extern 287 | 288 | !if !$(STATIC_BUILD) 289 | cflags = $(cflags) -DUSE_TCL_STUBS 290 | !if defined(TKSTUBLIB) 291 | cflags = $(cflags) -DUSE_TK_STUBS 292 | !endif 293 | !endif 294 | 295 | INCLUDES = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TDBC_GENERIC_DIR)" 296 | BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(INCLUDES) 297 | CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE 298 | TCL_CFLAGS = -DPACKAGE_NAME="\"$(PROJECT)\"" \ 299 | -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \ 300 | -DBUILD_$(PROJECT) \ 301 | $(BASE_CFLAGS) $(OPTDEFINES) \ 302 | -Dinline=__inline 303 | 304 | ### Stubs files should not be compiled with -GL 305 | STUB_CFLAGS = $(cflags) $(cdebug:-GL=) #$(TK_DEFINES) 306 | 307 | #--------------------------------------------------------------------- 308 | # Link flags 309 | #--------------------------------------------------------------------- 310 | 311 | !if $(DEBUG) 312 | ldebug = -debug 313 | !if $(MSVCRT) 314 | ldebug = $(ldebug) -nodefaultlib:msvcrt 315 | !endif 316 | !else 317 | ldebug = -release -opt:ref -opt:icf,3 318 | !endif 319 | 320 | ### Declarations common to all linker options 321 | lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug) 322 | 323 | !if $(PROFILE) 324 | lflags = $(lflags) -profile 325 | !endif 326 | 327 | !if $(ALIGN98_HACK) && !$(STATIC_BUILD) 328 | ### Align sections for PE size savings. 329 | lflags = $(lflags) -opt:nowin98 330 | !else if !$(ALIGN98_HACK) && $(STATIC_BUILD) 331 | ### Align sections for speed in loading by choosing the virtual page size. 332 | lflags = $(lflags) -align:4096 333 | !endif 334 | 335 | !if $(LOIMPACT) 336 | lflags = $(lflags) -ws:aggressive 337 | !endif 338 | 339 | dlllflags = $(lflags) -dll 340 | conlflags = $(lflags) -subsystem:console 341 | guilflags = $(lflags) -subsystem:windows 342 | !if !$(STATIC_BUILD) 343 | baselibs = $(TCLSTUBLIB) $(TDBCSTUBLIB) 344 | !if defined(TKSTUBLIB) 345 | baselibs = $(baselibs) $(TKSTUBLIB) 346 | !endif 347 | !endif 348 | 349 | # Avoid 'unresolved external symbol __security_cookie' errors. 350 | # c.f. http://support.microsoft.com/?id=894573 351 | !if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" 352 | !if $(VCVERSION) > 1399 && $(VCVERSION) < 1500 353 | baselibs = $(baselibs) bufferoverflowU.lib 354 | !endif 355 | !endif 356 | 357 | #--------------------------------------------------------------------- 358 | # TclTest flags 359 | #--------------------------------------------------------------------- 360 | 361 | !if "$(TESTPAT)" != "" 362 | TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) 363 | !endif 364 | 365 | #--------------------------------------------------------------------- 366 | # Project specific targets (EDIT) 367 | #--------------------------------------------------------------------- 368 | 369 | all: setup $(PROJECT) 370 | $(PROJECT): setup pkgIndex $(PRJLIB) 371 | install: install-binaries install-libraries install-docs 372 | pkgIndex: setup $(OUT_DIR)\pkgIndex.tcl 373 | 374 | !if !$(STATIC_BUILD) 375 | $(PROJECT): $(PRJSTUBLIB) 376 | !endif 377 | 378 | test: setup $(PROJECT) 379 | @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) 380 | @set TCLLIBPATH=$(OUT_DIR_PATH:\=/) 381 | @set TDBC_LIBRARY=$(LIBDIR:\=/) 382 | @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR) 383 | !if $(TCLINSTALL) 384 | @set PATH=$(_TCLDIR)\bin;$(PATH) 385 | $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) 386 | !else 387 | @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) 388 | $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \ 389 | -load "package ifneeded tdbc::mysql $(DOTVERSION) \ 390 | {source {$(LIBDIR:\=/)/tdbcmysql.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\ 391 | package ifneeded tdbc $(TDBC_DOTVERSION) \ 392 | {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}" 393 | !endif 394 | 395 | shell: setup $(PROJECT) 396 | @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) 397 | @set TDBC_LIBRARY=$(LIBDIR:\=/) 398 | !if $(TCLINSTALL) 399 | @set PATH=$(_TCLDIR)\bin;$(PATH) 400 | !else 401 | @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) 402 | !endif 403 | $(DEBUGGER) $(TCLSH) $(SCRIPT) 404 | 405 | setup: 406 | @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) 407 | @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) 408 | 409 | # See /win/coffbase.txt for extension base addresses. 410 | $(PRJLIB): $(DLLOBJS) 411 | $(link32) $(dlllflags) -base:@$(COFFBASE),tdbc -out:$@ $(baselibs) @<< 412 | $** 413 | << 414 | $(_VC_MANIFEST_EMBED_DLL) 415 | -@del $*.exp 416 | 417 | $(PRJSTUBLIB): $(PRJSTUBOBJS) 418 | $(lib32) -nologo -out:$@ $(PRJSTUBOBJS) 419 | 420 | 421 | #--------------------------------------------------------------------- 422 | # Implicit rules 423 | #--------------------------------------------------------------------- 424 | 425 | {$(WINDIR)}.c{$(TMP_DIR)}.obj:: 426 | $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< 427 | $< 428 | << 429 | 430 | {$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: 431 | $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< 432 | $< 433 | << 434 | 435 | {$(COMPATDIR)}.c{$(TMP_DIR)}.obj:: 436 | $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< 437 | $< 438 | << 439 | 440 | {$(WINDIR)}.rc{$(TMP_DIR)}.res: 441 | $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \ 442 | -DCOMMAVERSION=$(DOTVERSION:.=,),0 \ 443 | -DDOTVERSION=\"$(DOTVERSION)\" \ 444 | -DVERSION=\"$(VERSION)$(SUFX)\" \ 445 | !if $(DEBUG) 446 | -d DEBUG \ 447 | !endif 448 | !if $(TCL_THREADS) 449 | -d TCL_THREADS \ 450 | !endif 451 | !if $(STATIC_BUILD) 452 | -d STATIC_BUILD \ 453 | !endif 454 | $< 455 | 456 | .SUFFIXES: 457 | .SUFFIXES:.c .rc 458 | 459 | #------------------------------------------------------------------------- 460 | # Explicit dependency rules 461 | # 462 | #------------------------------------------------------------------------- 463 | .PHONY: $(OUT_DIR)\pkgIndex.tcl 464 | 465 | $(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in 466 | @nmakehlp -s << $** > $@ 467 | @PACKAGE_NAME@ $(PROJECT) 468 | @PACKAGE_VERSION@ $(DOTVERSION) 469 | @TCL_VERSION_REQ@ $(TCL_VERSION_REQ) 470 | @PKG_LIB_FILE@ $(PRJLIBNAME) 471 | << 472 | 473 | $(TMP_DIR)\mysqlStubInit.obj : $(GENERICDIR)\mysqlStubInit.c 474 | $(cc32) $(STUB_CFLAGS) $(TCL_INCLUDES) -Zl -DSTATIC_BUILD -Fo$@ $? 475 | 476 | #--------------------------------------------------------------------- 477 | # Installation. (EDIT) 478 | # 479 | # You may need to modify this section to reflect the final distribution 480 | # of your files and possibly to generate documentation. 481 | # 482 | #--------------------------------------------------------------------- 483 | 484 | install-binaries: 485 | @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)' 486 | @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)" 487 | @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL 488 | 489 | install-libraries: $(OUT_DIR)\pkgIndex.tcl 490 | @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)' 491 | @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)" 492 | @echo Installing package index in '$(SCRIPT_INSTALL_DIR)' 493 | @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)" 494 | 495 | install-docs: 496 | @echo Installing documentation files to '$(DOC_INSTALL_DIR)' 497 | @if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)" 498 | 499 | #--------------------------------------------------------------------- 500 | # Clean up 501 | #--------------------------------------------------------------------- 502 | 503 | clean: 504 | @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR) 505 | @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc 506 | @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i 507 | @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x 508 | @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch 509 | 510 | realclean: clean 511 | @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) 512 | 513 | distclean: realclean 514 | @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe 515 | @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj 516 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in -- 2 | # 3 | # This file is a Makefile for Sample TEA Extension. If it has the name 4 | # "Makefile.in" then it is a template for a Makefile; to generate the 5 | # actual Makefile, run "./configure", which is a configuration script 6 | # generated by the "autoconf" program (constructs like "@foo@" will get 7 | # replaced in the actual Makefile. 8 | # 9 | # Copyright (c) 1999 Scriptics Corporation. 10 | # Copyright (c) 2002-2005 ActiveState Corporation. 11 | # 12 | # See the file "license.terms" for information on usage and redistribution 13 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. 14 | # 15 | # RCS: @(#) $Id: Makefile.in,v 1.64 2007/10/23 22:08:06 hobbs Exp $ 16 | 17 | #======================================================================== 18 | # Add additional lines to handle any additional AC_SUBST cases that 19 | # have been added in a customized configure script. 20 | #======================================================================== 21 | 22 | #SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@ 23 | 24 | #======================================================================== 25 | # Nothing of the variables below this line should need to be changed. 26 | # Please check the TARGETS section below to make sure the make targets 27 | # are correct. 28 | #======================================================================== 29 | 30 | #======================================================================== 31 | # The names of the source files is defined in the configure script. 32 | # The object files are used for linking into the final library. 33 | # This will be used when a dist target is added to the Makefile. 34 | # It is not important to specify the directory, as long as it is the 35 | # $(srcdir) or in the generic, win or unix subdirectory. 36 | #======================================================================== 37 | 38 | PKG_SOURCES = @PKG_SOURCES@ 39 | PKG_OBJECTS = @PKG_OBJECTS@ 40 | 41 | #======================================================================== 42 | # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with 43 | # this package that need to be installed, if any. 44 | #======================================================================== 45 | 46 | PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ 47 | 48 | #======================================================================== 49 | # This is a list of public header files to be installed, if any. 50 | #======================================================================== 51 | 52 | PKG_HEADERS = @PKG_HEADERS@ 53 | 54 | #======================================================================== 55 | # "PKG_LIB_FILE" refers to the library (dynamic or static as per 56 | # configuration options) composed of the named objects. 57 | #======================================================================== 58 | 59 | PKG_LIB_FILE = @PKG_LIB_FILE@ 60 | 61 | lib_BINARIES = $(PKG_LIB_FILE) 62 | BINARIES = $(lib_BINARIES) 63 | 64 | SHELL = @SHELL@ 65 | 66 | srcdir = @srcdir@ 67 | prefix = @prefix@ 68 | exec_prefix = @exec_prefix@ 69 | 70 | bindir = @bindir@ 71 | libdir = @libdir@ 72 | includedir = @includedir@ 73 | datarootdir = @datarootdir@ 74 | datadir = @datadir@ 75 | mandir = @mandir@ 76 | 77 | DESTDIR = 78 | 79 | PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) 80 | pkgdatadir = $(datadir)/$(PKG_DIR) 81 | pkglibdir = $(libdir)/$(PKG_DIR) 82 | pkgincludedir = $(includedir)/$(PKG_DIR) 83 | 84 | top_builddir = . 85 | 86 | INSTALL_OPTIONS = 87 | INSTALL = $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS} 88 | INSTALL_DATA_DIR = ${INSTALL} -d -m 755 89 | INSTALL_PROGRAM = ${INSTALL} -m 755 90 | INSTALL_DATA = ${INSTALL} -m 444 91 | INSTALL_SCRIPT = ${INSTALL_PROGRAM} 92 | INSTALL_LIBRARY = ${INSTALL_DATA} 93 | 94 | PACKAGE_NAME = @PACKAGE_NAME@ 95 | PACKAGE_VERSION = @PACKAGE_VERSION@ 96 | CC = @CC@ 97 | CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ 98 | CFLAGS_WARNING = @CFLAGS_WARNING@ 99 | EXEEXT = @EXEEXT@ 100 | LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ 101 | MAKE_LIB = @MAKE_LIB@ 102 | MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ 103 | MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ 104 | MAKE_STUB_LIB = @MAKE_STUB_LIB@ 105 | ADD_MANIFEST = @ADD_MANIFEST@ 106 | OBJEXT = @OBJEXT@ 107 | RANLIB = @RANLIB@ 108 | RANLIB_STUB = @RANLIB_STUB@ 109 | SHLIB_CFLAGS = @SHLIB_CFLAGS@ 110 | SHLIB_LD = @SHLIB_LD@ 111 | SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ 112 | STLIB_LD = @STLIB_LD@ 113 | #TCL_DEFS = @TCL_DEFS@ 114 | TCL_BIN_DIR = @TCL_BIN_DIR@ 115 | TCL_SRC_DIR = @TCL_SRC_DIR@ 116 | #TK_BIN_DIR = @TK_BIN_DIR@ 117 | #TK_SRC_DIR = @TK_SRC_DIR@ 118 | 119 | TDBC_VERSION = @TDBC_VERSION@ 120 | TDBC_BIN_DIR = @tdbc_BIN_DIR@ 121 | TDBC_LIB_FILE = @TDBC_LIB_FILE@ 122 | 123 | # Not used, but retained for reference of what libs Tcl required 124 | #TCL_LIBS = @TCL_LIBS@ 125 | 126 | #======================================================================== 127 | # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our 128 | # package without installing. The other environment variables allow us 129 | # to test against an uninstalled Tcl. Add special env vars that you 130 | # require for testing here (like TCLX_LIBRARY). 131 | #======================================================================== 132 | 133 | EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) 134 | #EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) 135 | TCLLIBPATH = $(top_builddir) 136 | TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \ 137 | TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@` 138 | PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ 139 | PATH="$(EXTRA_PATH):$(PATH)" \ 140 | TCLLIBPATH="$(TCLLIBPATH)" \ 141 | TDBCMYSQL_LIBRARY=`@CYGPATH@ $(srcdir)/library` 142 | 143 | TCLSH_PROG = @TCLSH_PROG@ 144 | TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG) 145 | 146 | #WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` 147 | #WISH_PROG = @WISH_PROG@ 148 | #WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG) 149 | 150 | SHARED_BUILD = @SHARED_BUILD@ 151 | 152 | INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ 153 | # INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ 154 | 155 | PKG_CFLAGS = @PKG_CFLAGS@ 156 | 157 | # TCL_DEFS is not strictly need here, but if you remove it, then you 158 | # must make sure that configure.in checks for the necessary components 159 | # that your library may use. TCL_DEFS can actually be a problem if 160 | # you do not compile with a similar machine setup as the Tcl core was 161 | # compiled with. 162 | #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) 163 | DEFS = @DEFS@ $(PKG_CFLAGS) 164 | 165 | # Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile 166 | CONFIGURE_OUTPUTS = @CONFIGURE_OUTPUTS@ 167 | CLEANFILES = @CLEANFILES@ 168 | 169 | CPPFLAGS = @CPPFLAGS@ 170 | LIBS = @PKG_LIBS@ @LIBS@ 171 | AR = @AR@ 172 | CFLAGS = @CFLAGS@ 173 | COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 174 | 175 | VALGRIND = valgrind 176 | VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high --leak-check=yes --show-reachable=yes -v 177 | 178 | #======================================================================== 179 | # Start of user-definable TARGETS section 180 | #======================================================================== 181 | 182 | #======================================================================== 183 | # TEA TARGETS. Please note that the "libraries:" target refers to platform 184 | # independent files, and the "binaries:" target inclues executable programs and 185 | # platform-dependent libraries. Modify these targets so that they install 186 | # the various pieces of your package. The make and install rules 187 | # for the BINARIES that you specified above have already been done. 188 | #======================================================================== 189 | 190 | all: binaries libraries doc 191 | 192 | #======================================================================== 193 | # The binaries target builds executable programs, Windows .dll's, unix 194 | # shared/static libraries, and any other platform-dependent files. 195 | # The list of targets to build for "binaries:" is specified at the top 196 | # of the Makefile, in the "BINARIES" variable. 197 | #======================================================================== 198 | 199 | binaries: $(BINARIES) 200 | 201 | libraries: 202 | 203 | #======================================================================== 204 | # Your doc target should differentiate from doc builds (by the developer) 205 | # and doc installs (see install-doc), which just install the docs on the 206 | # end user machine when building from source. 207 | #======================================================================== 208 | 209 | doc: 210 | 211 | install: all install-binaries install-libraries install-doc 212 | 213 | install-binaries: binaries install-lib-binaries install-bin-binaries 214 | 215 | #======================================================================== 216 | # This rule installs platform-independent files, such as header files. 217 | # The list=...; for p in $$list handles the empty list case x-platform. 218 | #======================================================================== 219 | 220 | install-libraries: libraries 221 | @$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir) 222 | @echo "Installing header files in $(DESTDIR)$(includedir)" 223 | @list='$(PKG_HEADERS)'; for i in $$list; do \ 224 | echo "Installing $(srcdir)/$$i" ; \ 225 | $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \ 226 | done; 227 | 228 | #======================================================================== 229 | # Install documentation. Unix manpages should go in the $(mandir) 230 | # directory. 231 | #======================================================================== 232 | 233 | install-doc: doc 234 | @$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann 235 | @echo "Installing documentation in $(DESTDIR)$(mandir)" 236 | @list='$(srcdir)/doc/*.n'; for i in $$list; do \ 237 | echo "Installing $$i"; \ 238 | rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \ 239 | $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \ 240 | done 241 | 242 | test: binaries libraries 243 | $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \ 244 | -load "package ifneeded tdbc::mysql $(PACKAGE_VERSION) \ 245 | [list source `@CYGPATH@ $(srcdir)/library/tdbcmysql.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\ 246 | package ifneeded tdbc ${TDBC_VERSION} \ 247 | [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]" 248 | 249 | valgrind: binaries libraries 250 | $(PKG_ENV) $(TCLSH_ENV) \ 251 | LD_PRELOAD=$(PKG_LIB_FILE) \ 252 | $(VALGRIND) $(VALGRINDARGS) \ 253 | $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \ 254 | -load "package ifneeded tdbc::mysql ${PACKAGE_VERSION} \ 255 | [list source `@CYGPATH@ $(srcdir)/library/tdbcmysql.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]" 256 | 257 | 258 | shell: binaries libraries 259 | @$(TCLSH) $(SCRIPT) 260 | 261 | gdb: 262 | $(TCLSH_ENV) $(PKG_ENV) gdb $(TCLSH_PROG) $(SCRIPT) 263 | 264 | depend: 265 | 266 | #======================================================================== 267 | # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable 268 | # mentioned above. That will ensure that this target is built when you 269 | # run "make binaries". 270 | # 271 | # The $(PKG_OBJECTS) objects are created and linked into the final 272 | # library. In most cases these object files will correspond to the 273 | # source files above. 274 | #======================================================================== 275 | 276 | $(PKG_LIB_FILE): $(PKG_OBJECTS) 277 | -rm -f $(PKG_LIB_FILE) 278 | ${MAKE_LIB} 279 | $(ADD_MANIFEST) 280 | $(RANLIB) $(PKG_LIB_FILE) 281 | 282 | #======================================================================== 283 | # We need to enumerate the list of .c to .o lines here. 284 | # 285 | # In the following lines, $(srcdir) refers to the toplevel directory 286 | # containing your extension. If your sources are in a subdirectory, 287 | # you will have to modify the paths to reflect this: 288 | # 289 | # sample.$(OBJEXT): $(srcdir)/generic/sample.c 290 | # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@ 291 | # 292 | # Setting the VPATH variable to a list of paths will cause the makefile 293 | # to look into these paths when resolving .c to .obj dependencies. 294 | # As necessary, add $(srcdir):$(srcdir)/compat:.... 295 | #======================================================================== 296 | 297 | VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win 298 | 299 | .c.@OBJEXT@: 300 | $(COMPILE) -c `@CYGPATH@ $<` -o $@ 301 | 302 | #======================================================================== 303 | # Distribution creation 304 | # You may need to tweak this target to make it work correctly. 305 | #======================================================================== 306 | 307 | #COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar 308 | COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR) 309 | DIST_ROOT = /tmp/dist 310 | DIST_DIR = $(DIST_ROOT)/$(PKG_DIR) 311 | 312 | dist-clean: 313 | rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.* 314 | 315 | dist: dist-clean 316 | mkdir -p $(DIST_DIR) 317 | cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \ 318 | $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \ 319 | $(DIST_DIR)/ 320 | chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4 321 | chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in 322 | 323 | for i in $(srcdir)/*.[ch]; do \ 324 | if [ -f $$i ]; then \ 325 | cp -p $$i $(DIST_DIR)/ ; \ 326 | fi; \ 327 | done; 328 | 329 | mkdir $(DIST_DIR)/tclconfig 330 | cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \ 331 | $(DIST_DIR)/tclconfig/ 332 | chmod 664 $(DIST_DIR)/tclconfig/tcl.m4 333 | chmod +x $(DIST_DIR)/tclconfig/install-sh 334 | 335 | mkdir $(DIST_DIR)/doc 336 | cp -p $(srcdir)/doc/tdbc_mysql.n $(DIST_DIR)/doc/ 337 | 338 | mkdir $(DIST_DIR)/generic 339 | cp -p $(srcdir)/generic/fakemysql.h \ 340 | $(srcdir)/generic/mysqlStubDefs.txt \ 341 | $(srcdir)/generic/mysqlStubInit.c \ 342 | $(srcdir)/generic/mysqlStubs.h \ 343 | $(srcdir)/generic/tdbcmysql.c \ 344 | $(DIST_DIR)/generic/ 345 | 346 | mkdir $(DIST_DIR)/library 347 | cp -p $(srcdir)/library/tdbcmysql.tcl $(DIST_DIR)/library/ 348 | 349 | mkdir $(DIST_DIR)/tests 350 | cp -p $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcmysql.test \ 351 | $(DIST_DIR)/tests/ 352 | 353 | mkdir $(DIST_DIR)/win 354 | cp -p $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \ 355 | $(srcdir)/win/rules.vc $(DIST_DIR)/win/ 356 | 357 | (cd $(DIST_ROOT); $(COMPRESS);) 358 | 359 | #======================================================================== 360 | # How to rebuild the package's stub table. 361 | #======================================================================== 362 | 363 | genstubs: $(srcdir)/../tdbc/tools/genExtStubs.tcl $(srcdir)/generic/mysqlStubDefs.txt 364 | @echo $(TCLSH_PROGRAM) $(srcdir)/../tdbc/tools/genExtStubs.tcl \ 365 | $(srcdir)/generic/mysqlStubDefs.txt \ 366 | $(srcdir)/generic/mysqlStubs.h \ 367 | $(srcdir)/generic/mysqlStubInit.c 368 | @$(TCLSH) $(srcdir)/../tdbc/tools/genExtStubs.tcl \ 369 | $(srcdir)/generic/mysqlStubDefs.txt \ 370 | $(srcdir)/generic/mysqlStubs.h \ 371 | $(srcdir)/generic/mysqlStubInit.c 372 | 373 | #======================================================================== 374 | # End of user-definable section 375 | #======================================================================== 376 | 377 | #======================================================================== 378 | # Don't modify the file to clean here. Instead, set the "CLEANFILES" 379 | # variable in configure.in 380 | #======================================================================== 381 | 382 | clean: 383 | -test -z "$(BINARIES)" || rm -f $(BINARIES) 384 | -rm -f *.$(OBJEXT) core *.core 385 | -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) 386 | 387 | distclean: clean 388 | -rm -f *.tab.c 389 | -rm -f $(CONFIGURE_OUTPUTS) 390 | -rm -f config.cache config.log config.status 391 | 392 | #======================================================================== 393 | # Install binary object libraries. On Windows this includes both .dll and 394 | # .lib files. Because the .lib files are not explicitly listed anywhere, 395 | # we need to deduce their existence from the .dll file of the same name. 396 | # Library files go into the lib directory. 397 | # In addition, this will generate the pkgIndex.tcl 398 | # file in the install location (assuming it can find a usable tclsh shell) 399 | # 400 | # You should not have to modify this target. 401 | #======================================================================== 402 | 403 | install-lib-binaries: binaries 404 | @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir) 405 | @list='$(lib_BINARIES)'; for p in $$list; do \ 406 | if test -f $$p; then \ 407 | echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ 408 | $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \ 409 | stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ 410 | if test "x$$stub" = "xstub"; then \ 411 | echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \ 412 | $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \ 413 | else \ 414 | echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \ 415 | $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \ 416 | fi; \ 417 | ext=`echo $$p|sed -e "s/.*\.//"`; \ 418 | if test "x$$ext" = "xdll"; then \ 419 | lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ 420 | if test -f $$lib; then \ 421 | echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \ 422 | $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \ 423 | fi; \ 424 | fi; \ 425 | fi; \ 426 | done 427 | @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ 428 | if test -f $(srcdir)/$$p; then \ 429 | destp=`basename $$p`; \ 430 | echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ 431 | $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ 432 | fi; \ 433 | done 434 | @if test "x$(SHARED_BUILD)" = "x1"; then \ 435 | echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ 436 | $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \ 437 | fi 438 | 439 | #======================================================================== 440 | # Install binary executables (e.g. .exe files and dependent .dll files) 441 | # This is for files that must go in the bin directory (located next to 442 | # wish and tclsh), like dependent .dll files on Windows. 443 | # 444 | # You should not have to modify this target, except to define bin_BINARIES 445 | # above if necessary. 446 | #======================================================================== 447 | 448 | install-bin-binaries: binaries 449 | @$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir) 450 | @list='$(bin_BINARIES)'; for p in $$list; do \ 451 | if test -f $$p; then \ 452 | echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ 453 | $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ 454 | fi; \ 455 | done 456 | 457 | .SUFFIXES: .c .$(OBJEXT) 458 | 459 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 460 | cd $(top_builddir) \ 461 | && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status 462 | 463 | uninstall-binaries: 464 | list='$(lib_BINARIES)'; for p in $$list; do \ 465 | rm -f $(DESTDIR)$(pkglibdir)/$$p; \ 466 | done 467 | list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ 468 | p=`basename $$p`; \ 469 | rm -f $(DESTDIR)$(pkglibdir)/$$p; \ 470 | done 471 | list='$(bin_BINARIES)'; for p in $$list; do \ 472 | rm -f $(DESTDIR)$(bindir)/$$p; \ 473 | done 474 | 475 | .PHONY: all binaries clean depend distclean doc install libraries test 476 | 477 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 478 | # Otherwise a system limit (for SysV at least) may be exceeded. 479 | .NOEXPORT: 480 | -------------------------------------------------------------------------------- /win/nmakehlp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * nmakehlp.c -- 4 | * 5 | * This is used to fix limitations within nmake and the environment. 6 | * 7 | * Copyright (c) 2002 by David Gravereaux. 8 | * Copyright (c) 2006 by Pat Thoyts 9 | * 10 | * See the file "license.terms" for information on usage and redistribution of 11 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. 12 | * ---------------------------------------------------------------------------- 13 | */ 14 | 15 | #define _CRT_SECURE_NO_DEPRECATE 16 | #include 17 | #define NO_SHLWAPI_GDI 18 | #define NO_SHLWAPI_STREAM 19 | #define NO_SHLWAPI_REG 20 | #include 21 | #pragma comment (lib, "user32.lib") 22 | #pragma comment (lib, "kernel32.lib") 23 | #pragma comment (lib, "shlwapi.lib") 24 | #include 25 | #include 26 | 27 | /* 28 | * This library is required for x64 builds with _some_ versions of MSVC 29 | */ 30 | #if defined(_M_IA64) || defined(_M_AMD64) 31 | #if _MSC_VER >= 1400 && _MSC_VER < 1500 32 | #pragma comment(lib, "bufferoverflowU") 33 | #endif 34 | #endif 35 | 36 | /* ISO hack for dumb VC++ */ 37 | #ifdef _MSC_VER 38 | #define snprintf _snprintf 39 | #endif 40 | 41 | 42 | 43 | /* protos */ 44 | 45 | static int CheckForCompilerFeature(const char *option); 46 | static int CheckForLinkerFeature(const char *option); 47 | static int IsIn(const char *string, const char *substring); 48 | static int SubstituteFile(const char *substs, const char *filename); 49 | static int QualifyPath(const char *path); 50 | static const char *GetVersionFromFile(const char *filename, const char *match, int numdots); 51 | static DWORD WINAPI ReadFromPipe(LPVOID args); 52 | 53 | /* globals */ 54 | 55 | #define CHUNK 25 56 | #define STATICBUFFERSIZE 1000 57 | typedef struct { 58 | HANDLE pipe; 59 | char buffer[STATICBUFFERSIZE]; 60 | } pipeinfo; 61 | 62 | pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'}; 63 | pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'}; 64 | 65 | /* 66 | * exitcodes: 0 == no, 1 == yes, 2 == error 67 | */ 68 | 69 | int 70 | main( 71 | int argc, 72 | char *argv[]) 73 | { 74 | char msg[300]; 75 | DWORD dwWritten; 76 | int chars; 77 | 78 | /* 79 | * Make sure children (cl.exe and link.exe) are kept quiet. 80 | */ 81 | 82 | SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); 83 | 84 | /* 85 | * Make sure the compiler and linker aren't effected by the outside world. 86 | */ 87 | 88 | SetEnvironmentVariable("CL", ""); 89 | SetEnvironmentVariable("LINK", ""); 90 | 91 | if (argc > 1 && *argv[1] == '-') { 92 | switch (*(argv[1]+1)) { 93 | case 'c': 94 | if (argc != 3) { 95 | chars = snprintf(msg, sizeof(msg) - 1, 96 | "usage: %s -c \n" 97 | "Tests for whether cl.exe supports an option\n" 98 | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); 99 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, 100 | &dwWritten, NULL); 101 | return 2; 102 | } 103 | return CheckForCompilerFeature(argv[2]); 104 | case 'l': 105 | if (argc != 3) { 106 | chars = snprintf(msg, sizeof(msg) - 1, 107 | "usage: %s -l \n" 108 | "Tests for whether link.exe supports an option\n" 109 | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); 110 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, 111 | &dwWritten, NULL); 112 | return 2; 113 | } 114 | return CheckForLinkerFeature(argv[2]); 115 | case 'f': 116 | if (argc == 2) { 117 | chars = snprintf(msg, sizeof(msg) - 1, 118 | "usage: %s -f \n" 119 | "Find a substring within another\n" 120 | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); 121 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, 122 | &dwWritten, NULL); 123 | return 2; 124 | } else if (argc == 3) { 125 | /* 126 | * If the string is blank, there is no match. 127 | */ 128 | 129 | return 0; 130 | } else { 131 | return IsIn(argv[2], argv[3]); 132 | } 133 | case 's': 134 | if (argc == 2) { 135 | chars = snprintf(msg, sizeof(msg) - 1, 136 | "usage: %s -s \n" 137 | "Perform a set of string map type substutitions on a file\n" 138 | "exitcodes: 0\n", 139 | argv[0]); 140 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, 141 | &dwWritten, NULL); 142 | return 2; 143 | } 144 | return SubstituteFile(argv[2], argv[3]); 145 | case 'V': 146 | if (argc != 4) { 147 | chars = snprintf(msg, sizeof(msg) - 1, 148 | "usage: %s -V filename matchstring\n" 149 | "Extract a version from a file:\n" 150 | "eg: pkgIndex.tcl \"package ifneeded http\"", 151 | argv[0]); 152 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, 153 | &dwWritten, NULL); 154 | return 0; 155 | } 156 | printf("%s\n", GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0')); 157 | return 0; 158 | case 'Q': 159 | if (argc != 3) { 160 | chars = snprintf(msg, sizeof(msg) - 1, 161 | "usage: %s -Q path\n" 162 | "Emit the fully qualified path\n" 163 | "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); 164 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, 165 | &dwWritten, NULL); 166 | return 2; 167 | } 168 | return QualifyPath(argv[2]); 169 | } 170 | } 171 | chars = snprintf(msg, sizeof(msg) - 1, 172 | "usage: %s -c|-f|-l|-Q|-s|-V ...\n" 173 | "This is a little helper app to equalize shell differences between WinNT and\n" 174 | "Win9x and get nmake.exe to accomplish its job.\n", 175 | argv[0]); 176 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); 177 | return 2; 178 | } 179 | 180 | static int 181 | CheckForCompilerFeature( 182 | const char *option) 183 | { 184 | STARTUPINFO si; 185 | PROCESS_INFORMATION pi; 186 | SECURITY_ATTRIBUTES sa; 187 | DWORD threadID; 188 | char msg[300]; 189 | BOOL ok; 190 | HANDLE hProcess, h, pipeThreads[2]; 191 | char cmdline[100]; 192 | 193 | hProcess = GetCurrentProcess(); 194 | 195 | ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); 196 | ZeroMemory(&si, sizeof(STARTUPINFO)); 197 | si.cb = sizeof(STARTUPINFO); 198 | si.dwFlags = STARTF_USESTDHANDLES; 199 | si.hStdInput = INVALID_HANDLE_VALUE; 200 | 201 | ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); 202 | sa.nLength = sizeof(SECURITY_ATTRIBUTES); 203 | sa.lpSecurityDescriptor = NULL; 204 | sa.bInheritHandle = FALSE; 205 | 206 | /* 207 | * Create a non-inheritible pipe. 208 | */ 209 | 210 | CreatePipe(&Out.pipe, &h, &sa, 0); 211 | 212 | /* 213 | * Dupe the write side, make it inheritible, and close the original. 214 | */ 215 | 216 | DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, 217 | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 218 | 219 | /* 220 | * Same as above, but for the error side. 221 | */ 222 | 223 | CreatePipe(&Err.pipe, &h, &sa, 0); 224 | DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, 225 | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 226 | 227 | /* 228 | * Base command line. 229 | */ 230 | 231 | lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch "); 232 | 233 | /* 234 | * Append our option for testing 235 | */ 236 | 237 | lstrcat(cmdline, option); 238 | 239 | /* 240 | * Filename to compile, which exists, but is nothing and empty. 241 | */ 242 | 243 | lstrcat(cmdline, " .\\nul"); 244 | 245 | ok = CreateProcess( 246 | NULL, /* Module name. */ 247 | cmdline, /* Command line. */ 248 | NULL, /* Process handle not inheritable. */ 249 | NULL, /* Thread handle not inheritable. */ 250 | TRUE, /* yes, inherit handles. */ 251 | DETACHED_PROCESS, /* No console for you. */ 252 | NULL, /* Use parent's environment block. */ 253 | NULL, /* Use parent's starting directory. */ 254 | &si, /* Pointer to STARTUPINFO structure. */ 255 | &pi); /* Pointer to PROCESS_INFORMATION structure. */ 256 | 257 | if (!ok) { 258 | DWORD err = GetLastError(); 259 | int chars = snprintf(msg, sizeof(msg) - 1, 260 | "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); 261 | 262 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| 263 | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], 264 | (300-chars), 0); 265 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); 266 | return 2; 267 | } 268 | 269 | /* 270 | * Close our references to the write handles that have now been inherited. 271 | */ 272 | 273 | CloseHandle(si.hStdOutput); 274 | CloseHandle(si.hStdError); 275 | 276 | WaitForInputIdle(pi.hProcess, 5000); 277 | CloseHandle(pi.hThread); 278 | 279 | /* 280 | * Start the pipe reader threads. 281 | */ 282 | 283 | pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); 284 | pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID); 285 | 286 | /* 287 | * Block waiting for the process to end. 288 | */ 289 | 290 | WaitForSingleObject(pi.hProcess, INFINITE); 291 | CloseHandle(pi.hProcess); 292 | 293 | /* 294 | * Wait for our pipe to get done reading, should it be a little slow. 295 | */ 296 | 297 | WaitForMultipleObjects(2, pipeThreads, TRUE, 500); 298 | CloseHandle(pipeThreads[0]); 299 | CloseHandle(pipeThreads[1]); 300 | 301 | /* 302 | * Look for the commandline warning code in both streams. 303 | * - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002. 304 | */ 305 | 306 | return !(strstr(Out.buffer, "D4002") != NULL 307 | || strstr(Err.buffer, "D4002") != NULL 308 | || strstr(Out.buffer, "D9002") != NULL 309 | || strstr(Err.buffer, "D9002") != NULL 310 | || strstr(Out.buffer, "D2021") != NULL 311 | || strstr(Err.buffer, "D2021") != NULL); 312 | } 313 | 314 | static int 315 | CheckForLinkerFeature( 316 | const char *option) 317 | { 318 | STARTUPINFO si; 319 | PROCESS_INFORMATION pi; 320 | SECURITY_ATTRIBUTES sa; 321 | DWORD threadID; 322 | char msg[300]; 323 | BOOL ok; 324 | HANDLE hProcess, h, pipeThreads[2]; 325 | char cmdline[100]; 326 | 327 | hProcess = GetCurrentProcess(); 328 | 329 | ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); 330 | ZeroMemory(&si, sizeof(STARTUPINFO)); 331 | si.cb = sizeof(STARTUPINFO); 332 | si.dwFlags = STARTF_USESTDHANDLES; 333 | si.hStdInput = INVALID_HANDLE_VALUE; 334 | 335 | ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); 336 | sa.nLength = sizeof(SECURITY_ATTRIBUTES); 337 | sa.lpSecurityDescriptor = NULL; 338 | sa.bInheritHandle = TRUE; 339 | 340 | /* 341 | * Create a non-inheritible pipe. 342 | */ 343 | 344 | CreatePipe(&Out.pipe, &h, &sa, 0); 345 | 346 | /* 347 | * Dupe the write side, make it inheritible, and close the original. 348 | */ 349 | 350 | DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, 351 | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 352 | 353 | /* 354 | * Same as above, but for the error side. 355 | */ 356 | 357 | CreatePipe(&Err.pipe, &h, &sa, 0); 358 | DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, 359 | DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 360 | 361 | /* 362 | * Base command line. 363 | */ 364 | 365 | lstrcpy(cmdline, "link.exe -nologo "); 366 | 367 | /* 368 | * Append our option for testing. 369 | */ 370 | 371 | lstrcat(cmdline, option); 372 | 373 | ok = CreateProcess( 374 | NULL, /* Module name. */ 375 | cmdline, /* Command line. */ 376 | NULL, /* Process handle not inheritable. */ 377 | NULL, /* Thread handle not inheritable. */ 378 | TRUE, /* yes, inherit handles. */ 379 | DETACHED_PROCESS, /* No console for you. */ 380 | NULL, /* Use parent's environment block. */ 381 | NULL, /* Use parent's starting directory. */ 382 | &si, /* Pointer to STARTUPINFO structure. */ 383 | &pi); /* Pointer to PROCESS_INFORMATION structure. */ 384 | 385 | if (!ok) { 386 | DWORD err = GetLastError(); 387 | int chars = snprintf(msg, sizeof(msg) - 1, 388 | "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err); 389 | 390 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS| 391 | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars], 392 | (300-chars), 0); 393 | WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL); 394 | return 2; 395 | } 396 | 397 | /* 398 | * Close our references to the write handles that have now been inherited. 399 | */ 400 | 401 | CloseHandle(si.hStdOutput); 402 | CloseHandle(si.hStdError); 403 | 404 | WaitForInputIdle(pi.hProcess, 5000); 405 | CloseHandle(pi.hThread); 406 | 407 | /* 408 | * Start the pipe reader threads. 409 | */ 410 | 411 | pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); 412 | pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID); 413 | 414 | /* 415 | * Block waiting for the process to end. 416 | */ 417 | 418 | WaitForSingleObject(pi.hProcess, INFINITE); 419 | CloseHandle(pi.hProcess); 420 | 421 | /* 422 | * Wait for our pipe to get done reading, should it be a little slow. 423 | */ 424 | 425 | WaitForMultipleObjects(2, pipeThreads, TRUE, 500); 426 | CloseHandle(pipeThreads[0]); 427 | CloseHandle(pipeThreads[1]); 428 | 429 | /* 430 | * Look for the commandline warning code in the stderr stream. 431 | */ 432 | 433 | return !(strstr(Out.buffer, "LNK1117") != NULL || 434 | strstr(Err.buffer, "LNK1117") != NULL || 435 | strstr(Out.buffer, "LNK4044") != NULL || 436 | strstr(Err.buffer, "LNK4044") != NULL); 437 | } 438 | 439 | static DWORD WINAPI 440 | ReadFromPipe( 441 | LPVOID args) 442 | { 443 | pipeinfo *pi = (pipeinfo *) args; 444 | char *lastBuf = pi->buffer; 445 | DWORD dwRead; 446 | BOOL ok; 447 | 448 | again: 449 | if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) { 450 | CloseHandle(pi->pipe); 451 | return (DWORD)-1; 452 | } 453 | ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L); 454 | if (!ok || dwRead == 0) { 455 | CloseHandle(pi->pipe); 456 | return 0; 457 | } 458 | lastBuf += dwRead; 459 | goto again; 460 | 461 | return 0; /* makes the compiler happy */ 462 | } 463 | 464 | static int 465 | IsIn( 466 | const char *string, 467 | const char *substring) 468 | { 469 | return (strstr(string, substring) != NULL); 470 | } 471 | 472 | /* 473 | * GetVersionFromFile -- 474 | * Looks for a match string in a file and then returns the version 475 | * following the match where a version is anything acceptable to 476 | * package provide or package ifneeded. 477 | */ 478 | 479 | static const char * 480 | GetVersionFromFile( 481 | const char *filename, 482 | const char *match, 483 | int numdots) 484 | { 485 | size_t cbBuffer = 100; 486 | static char szBuffer[100]; 487 | char *szResult = NULL; 488 | FILE *fp = fopen(filename, "rt"); 489 | 490 | if (fp != NULL) { 491 | /* 492 | * Read data until we see our match string. 493 | */ 494 | 495 | while (fgets(szBuffer, cbBuffer, fp) != NULL) { 496 | LPSTR p, q; 497 | 498 | p = strstr(szBuffer, match); 499 | if (p != NULL) { 500 | /* 501 | * Skip to first digit after the match. 502 | */ 503 | 504 | p += strlen(match); 505 | while (*p && !isdigit(*p)) { 506 | ++p; 507 | } 508 | 509 | /* 510 | * Find ending whitespace. 511 | */ 512 | 513 | q = p; 514 | while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q) 515 | && (!strchr("ab", q[-1])) || --numdots))) { 516 | ++q; 517 | } 518 | 519 | memcpy(szBuffer, p, q - p); 520 | szBuffer[q-p] = 0; 521 | szResult = szBuffer; 522 | break; 523 | } 524 | } 525 | fclose(fp); 526 | } 527 | return szResult; 528 | } 529 | 530 | /* 531 | * List helpers for the SubstituteFile function 532 | */ 533 | 534 | typedef struct list_item_t { 535 | struct list_item_t *nextPtr; 536 | char * key; 537 | char * value; 538 | } list_item_t; 539 | 540 | /* insert a list item into the list (list may be null) */ 541 | static list_item_t * 542 | list_insert(list_item_t **listPtrPtr, const char *key, const char *value) 543 | { 544 | list_item_t *itemPtr = malloc(sizeof(list_item_t)); 545 | if (itemPtr) { 546 | itemPtr->key = strdup(key); 547 | itemPtr->value = strdup(value); 548 | itemPtr->nextPtr = NULL; 549 | 550 | while(*listPtrPtr) { 551 | listPtrPtr = &(*listPtrPtr)->nextPtr; 552 | } 553 | *listPtrPtr = itemPtr; 554 | } 555 | return itemPtr; 556 | } 557 | 558 | static void 559 | list_free(list_item_t **listPtrPtr) 560 | { 561 | list_item_t *tmpPtr, *listPtr = *listPtrPtr; 562 | while (listPtr) { 563 | tmpPtr = listPtr; 564 | listPtr = listPtr->nextPtr; 565 | free(tmpPtr->key); 566 | free(tmpPtr->value); 567 | free(tmpPtr); 568 | } 569 | } 570 | 571 | /* 572 | * SubstituteFile -- 573 | * As windows doesn't provide anything useful like sed and it's unreliable 574 | * to use the tclsh you are building against (consider x-platform builds - 575 | * eg compiling AMD64 target from IX86) we provide a simple substitution 576 | * option here to handle autoconf style substitutions. 577 | * The substitution file is whitespace and line delimited. The file should 578 | * consist of lines matching the regular expression: 579 | * \s*\S+\s+\S*$ 580 | * 581 | * Usage is something like: 582 | * nmakehlp -S << $** > $@ 583 | * @PACKAGE_NAME@ $(PACKAGE_NAME) 584 | * @PACKAGE_VERSION@ $(PACKAGE_VERSION) 585 | * << 586 | */ 587 | 588 | static int 589 | SubstituteFile( 590 | const char *substitutions, 591 | const char *filename) 592 | { 593 | size_t cbBuffer = 1024; 594 | static char szBuffer[1024], szCopy[1024]; 595 | char *szResult = NULL; 596 | list_item_t *substPtr = NULL; 597 | FILE *fp, *sp; 598 | 599 | fp = fopen(filename, "rt"); 600 | if (fp != NULL) { 601 | 602 | /* 603 | * Build a list of substutitions from the first filename 604 | */ 605 | 606 | sp = fopen(substitutions, "rt"); 607 | if (sp != NULL) { 608 | while (fgets(szBuffer, cbBuffer, sp) != NULL) { 609 | char *ks, *ke, *vs, *ve; 610 | ks = szBuffer; 611 | while (ks && *ks && isspace(*ks)) ++ks; 612 | ke = ks; 613 | while (ke && *ke && !isspace(*ke)) ++ke; 614 | vs = ke; 615 | while (vs && *vs && isspace(*vs)) ++vs; 616 | ve = vs; 617 | while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve; 618 | *ke = 0, *ve = 0; 619 | list_insert(&substPtr, ks, vs); 620 | } 621 | fclose(sp); 622 | } 623 | 624 | /* debug: dump the list */ 625 | #ifdef _DEBUG 626 | { 627 | int n = 0; 628 | list_item_t *p = NULL; 629 | for (p = substPtr; p != NULL; p = p->nextPtr, ++n) { 630 | fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value); 631 | } 632 | } 633 | #endif 634 | 635 | /* 636 | * Run the substitutions over each line of the input 637 | */ 638 | 639 | while (fgets(szBuffer, cbBuffer, fp) != NULL) { 640 | list_item_t *p = NULL; 641 | for (p = substPtr; p != NULL; p = p->nextPtr) { 642 | char *m = strstr(szBuffer, p->key); 643 | if (m) { 644 | char *cp, *op, *sp; 645 | cp = szCopy; 646 | op = szBuffer; 647 | while (op != m) *cp++ = *op++; 648 | sp = p->value; 649 | while (sp && *sp) *cp++ = *sp++; 650 | op += strlen(p->key); 651 | while (*op) *cp++ = *op++; 652 | *cp = 0; 653 | memcpy(szBuffer, szCopy, sizeof(szCopy)); 654 | } 655 | } 656 | printf(szBuffer); 657 | } 658 | 659 | list_free(&substPtr); 660 | } 661 | fclose(fp); 662 | return 0; 663 | } 664 | 665 | /* 666 | * QualifyPath -- 667 | * 668 | * This composes the current working directory with a provided path 669 | * and returns the fully qualified and normalized path. 670 | * Mostly needed to setup paths for testing. 671 | */ 672 | 673 | static int 674 | QualifyPath( 675 | const char *szPath) 676 | { 677 | char szCwd[MAX_PATH + 1]; 678 | char szTmp[MAX_PATH + 1]; 679 | char *p; 680 | GetCurrentDirectory(MAX_PATH, szCwd); 681 | while ((p = strchr(szPath, '/')) && *p) 682 | *p = '\\'; 683 | PathCombine(szTmp, szCwd, szPath); 684 | PathCanonicalize(szCwd, szTmp); 685 | printf("%s\n", szCwd); 686 | return 0; 687 | } 688 | 689 | /* 690 | * Local variables: 691 | * mode: c 692 | * c-basic-offset: 4 693 | * fill-column: 78 694 | * indent-tabs-mode: t 695 | * tab-width: 8 696 | * End: 697 | */ 698 | -------------------------------------------------------------------------------- /win/rules.vc: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------ 2 | # rules.vc -- 3 | # 4 | # Microsoft Visual C++ makefile include for decoding the commandline 5 | # macros. This file does not need editing to build Tcl. 6 | # 7 | # This version is modified from the Tcl source version to support 8 | # building extensions using nmake. 9 | # 10 | # See the file "license.terms" for information on usage and redistribution 11 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. 12 | # 13 | # Copyright (c) 2001-2003 David Gravereaux. 14 | # Copyright (c) 2003-2008 Patrick Thoyts 15 | #------------------------------------------------------------------------------ 16 | 17 | !ifndef _RULES_VC 18 | _RULES_VC = 1 19 | 20 | cc32 = $(CC) # built-in default. 21 | link32 = link 22 | lib32 = lib 23 | rc32 = $(RC) # built-in default. 24 | 25 | !ifndef INSTALLDIR 26 | ### Assume the normal default. 27 | _INSTALLDIR = C:\Program Files\Tcl 28 | !else 29 | ### Fix the path separators. 30 | _INSTALLDIR = $(INSTALLDIR:/=\) 31 | !endif 32 | 33 | #---------------------------------------------------------- 34 | # Set the proper copy method to avoid overwrite questions 35 | # to the user when copying files and selecting the right 36 | # "delete all" method. 37 | #---------------------------------------------------------- 38 | 39 | !if "$(OS)" == "Windows_NT" 40 | RMDIR = rmdir /S /Q 41 | ERRNULL = 2>NUL 42 | !if ![ver | find "4.0" > nul] 43 | CPY = echo y | xcopy /i >NUL 44 | COPY = copy >NUL 45 | !else 46 | CPY = xcopy /i /y >NUL 47 | COPY = copy /y >NUL 48 | !endif 49 | !else # "$(OS)" != "Windows_NT" 50 | CPY = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here. 51 | COPY = copy >_JUNK.OUT # On Win98 NUL does not work here. 52 | RMDIR = deltree /Y 53 | NULL = \NUL # Used in testing directory existence 54 | ERRNULL = >NUL # Win9x shell cannot redirect stderr 55 | !endif 56 | MKDIR = mkdir 57 | 58 | #------------------------------------------------------------------------------ 59 | # Determine the host and target architectures and compiler version. 60 | #------------------------------------------------------------------------------ 61 | 62 | _HASH=^# 63 | _VC_MANIFEST_EMBED_EXE= 64 | _VC_MANIFEST_EMBED_DLL= 65 | VCVER=0 66 | !if ![echo VCVERSION=_MSC_VER > vercl.x] \ 67 | && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \ 68 | && ![echo ARCH=IX86 >> vercl.x] \ 69 | && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \ 70 | && ![echo ARCH=AMD64 >> vercl.x] \ 71 | && ![echo $(_HASH)endif >> vercl.x] \ 72 | && ![cl -nologo -TC -P vercl.x $(ERRNULL)] 73 | !include vercl.i 74 | !if ![echo VCVER= ^\> vercl.vc] \ 75 | && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc] 76 | !include vercl.vc 77 | !endif 78 | !endif 79 | !if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc] 80 | !endif 81 | 82 | !if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86] 83 | NATIVE_ARCH=IX86 84 | !else 85 | NATIVE_ARCH=AMD64 86 | !endif 87 | 88 | # Since MSVC8 we must deal with manifest resources. 89 | !if $(VCVERSION) >= 1400 90 | _VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1 91 | _VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 92 | !endif 93 | 94 | !ifndef MACHINE 95 | MACHINE=$(ARCH) 96 | !endif 97 | 98 | !ifndef CFG_ENCODING 99 | CFG_ENCODING = \"cp1252\" 100 | !endif 101 | 102 | !message =============================================================================== 103 | 104 | #---------------------------------------------------------- 105 | # build the helper app we need to overcome nmake's limiting 106 | # environment. 107 | #---------------------------------------------------------- 108 | 109 | !if !exist(nmakehlp.exe) 110 | !if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul] 111 | !endif 112 | !endif 113 | 114 | #---------------------------------------------------------- 115 | # Test for compiler features 116 | #---------------------------------------------------------- 117 | 118 | ### test for optimizations 119 | !if [nmakehlp -c -Ot] 120 | !message *** Compiler has 'Optimizations' 121 | OPTIMIZING = 1 122 | !else 123 | !message *** Compiler does not have 'Optimizations' 124 | OPTIMIZING = 0 125 | !endif 126 | 127 | OPTIMIZATIONS = 128 | 129 | !if [nmakehlp -c -Ot] 130 | OPTIMIZATIONS = $(OPTIMIZATIONS) -Ot 131 | !endif 132 | 133 | !if [nmakehlp -c -Oi] 134 | OPTIMIZATIONS = $(OPTIMIZATIONS) -Oi 135 | !endif 136 | 137 | !if [nmakehlp -c -Op] 138 | OPTIMIZATIONS = $(OPTIMIZATIONS) -Op 139 | !endif 140 | 141 | !if [nmakehlp -c -fp:strict] 142 | OPTIMIZATIONS = $(OPTIMIZATIONS) -fp:strict 143 | !endif 144 | 145 | !if [nmakehlp -c -Gs] 146 | OPTIMIZATIONS = $(OPTIMIZATIONS) -Gs 147 | !endif 148 | 149 | !if [nmakehlp -c -GS] 150 | OPTIMIZATIONS = $(OPTIMIZATIONS) -GS 151 | !endif 152 | 153 | !if [nmakehlp -c -GL] 154 | OPTIMIZATIONS = $(OPTIMIZATIONS) -GL 155 | !endif 156 | 157 | DEBUGFLAGS = 158 | 159 | !if [nmakehlp -c -RTC1] 160 | DEBUGFLAGS = $(DEBUGFLAGS) -RTC1 161 | !elseif [nmakehlp -c -GZ] 162 | DEBUGFLAGS = $(DEBUGFLAGS) -GZ 163 | !endif 164 | 165 | COMPILERFLAGS =-W3 166 | 167 | # In v13 -GL and -YX are incompatible. 168 | !if [nmakehlp -c -YX] 169 | !if ![nmakehlp -c -GL] 170 | OPTIMIZATIONS = $(OPTIMIZATIONS) -YX 171 | !endif 172 | !endif 173 | 174 | !if "$(MACHINE)" == "IX86" 175 | ### test for pentium errata 176 | !if [nmakehlp -c -QI0f] 177 | !message *** Compiler has 'Pentium 0x0f fix' 178 | COMPILERFLAGS = $(COMPILERFLAGS) -QI0f 179 | !else 180 | !message *** Compiler does not have 'Pentium 0x0f fix' 181 | !endif 182 | !endif 183 | 184 | !if "$(MACHINE)" == "IA64" 185 | ### test for Itanium errata 186 | !if [nmakehlp -c -QIA64_Bx] 187 | !message *** Compiler has 'B-stepping errata workarounds' 188 | COMPILERFLAGS = $(COMPILERFLAGS) -QIA64_Bx 189 | !else 190 | !message *** Compiler does not have 'B-stepping errata workarounds' 191 | !endif 192 | !endif 193 | 194 | !if "$(MACHINE)" == "IX86" 195 | ### test for -align:4096, when align:512 will do. 196 | !if [nmakehlp -l -opt:nowin98] 197 | !message *** Linker has 'Win98 alignment problem' 198 | ALIGN98_HACK = 1 199 | !else 200 | !message *** Linker does not have 'Win98 alignment problem' 201 | ALIGN98_HACK = 0 202 | !endif 203 | !else 204 | ALIGN98_HACK = 0 205 | !endif 206 | 207 | LINKERFLAGS = 208 | 209 | !if [nmakehlp -l -ltcg] 210 | LINKERFLAGS =-ltcg 211 | !endif 212 | 213 | #---------------------------------------------------------- 214 | # Decode the options requested. 215 | #---------------------------------------------------------- 216 | 217 | !if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"] 218 | STATIC_BUILD = 0 219 | TCL_THREADS = 1 220 | DEBUG = 0 221 | SYMBOLS = 0 222 | PROFILE = 0 223 | PGO = 0 224 | MSVCRT = 0 225 | LOIMPACT = 0 226 | UNCHECKED = 0 227 | !else 228 | !if [nmakehlp -f $(OPTS) "static"] 229 | !message *** Doing static 230 | STATIC_BUILD = 1 231 | !else 232 | STATIC_BUILD = 0 233 | !endif 234 | !if [nmakehlp -f $(OPTS) "msvcrt"] 235 | !message *** Doing msvcrt 236 | MSVCRT = 1 237 | !else 238 | MSVCRT = 0 239 | !endif 240 | !if [nmakehlp -f $(OPTS) "nothreads"] 241 | !message *** Compile explicitly for non-threaded tcl 242 | TCL_THREADS = 0 243 | !else 244 | TCL_THREADS = 1 245 | !endif 246 | !if [nmakehlp -f $(OPTS) "symbols"] 247 | !message *** Doing symbols 248 | DEBUG = 1 249 | !else 250 | DEBUG = 0 251 | !endif 252 | !if [nmakehlp -f $(OPTS) "pdbs"] 253 | !message *** Doing pdbs 254 | SYMBOLS = 1 255 | !else 256 | SYMBOLS = 0 257 | !endif 258 | !if [nmakehlp -f $(OPTS) "profile"] 259 | !message *** Doing profile 260 | PROFILE = 1 261 | !else 262 | PROFILE = 0 263 | !endif 264 | !if [nmakehlp -f $(OPTS) "pgi"] 265 | !message *** Doing profile guided optimization instrumentation 266 | PGO = 1 267 | !elseif [nmakehlp -f $(OPTS) "pgo"] 268 | !message *** Doing profile guided optimization 269 | PGO = 2 270 | !else 271 | PGO = 0 272 | !endif 273 | !if [nmakehlp -f $(OPTS) "loimpact"] 274 | !message *** Doing loimpact 275 | LOIMPACT = 1 276 | !else 277 | LOIMPACT = 0 278 | !endif 279 | !if [nmakehlp -f $(OPTS) "unchecked"] 280 | !message *** Doing unchecked 281 | UNCHECKED = 1 282 | !else 283 | UNCHECKED = 0 284 | !endif 285 | !endif 286 | 287 | 288 | !if !$(STATIC_BUILD) 289 | # Make sure we don't build overly fat DLLs. 290 | MSVCRT = 1 291 | # We shouldn't statically put the extensions inside the shell when dynamic. 292 | TCL_USE_STATIC_PACKAGES = 0 293 | !endif 294 | 295 | 296 | #---------------------------------------------------------- 297 | # Figure-out how to name our intermediate and output directories. 298 | # We wouldn't want different builds to use the same .obj files 299 | # by accident. 300 | #---------------------------------------------------------- 301 | 302 | #---------------------------------------- 303 | # Naming convention: 304 | # t = full thread support. 305 | # s = static library (as opposed to an 306 | # import library) 307 | # g = linked to the debug enabled C 308 | # run-time. 309 | # x = special static build when it 310 | # links to the dynamic C run-time. 311 | #---------------------------------------- 312 | SUFX = sgx 313 | 314 | !if $(DEBUG) 315 | BUILDDIRTOP = Debug 316 | !else 317 | BUILDDIRTOP = Release 318 | !endif 319 | 320 | !if "$(MACHINE)" != "IX86" 321 | BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE) 322 | !endif 323 | !if $(VCVER) > 6 324 | BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER) 325 | !endif 326 | 327 | !if !$(DEBUG) || $(DEBUG) && $(UNCHECKED) 328 | SUFX = $(SUFX:g=) 329 | !endif 330 | 331 | TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX 332 | 333 | !if !$(STATIC_BUILD) 334 | TMP_DIRFULL = $(TMP_DIRFULL:Static=) 335 | SUFX = $(SUFX:s=) 336 | EXT = dll 337 | !if $(MSVCRT) 338 | TMP_DIRFULL = $(TMP_DIRFULL:X=) 339 | SUFX = $(SUFX:x=) 340 | !endif 341 | !else 342 | TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=) 343 | EXT = lib 344 | !if !$(MSVCRT) 345 | TMP_DIRFULL = $(TMP_DIRFULL:X=) 346 | SUFX = $(SUFX:x=) 347 | !endif 348 | !endif 349 | 350 | !if !$(TCL_THREADS) 351 | TMP_DIRFULL = $(TMP_DIRFULL:Threaded=) 352 | SUFX = $(SUFX:t=) 353 | !endif 354 | 355 | !ifndef TMP_DIR 356 | TMP_DIR = $(TMP_DIRFULL) 357 | !ifndef OUT_DIR 358 | OUT_DIR = .\$(BUILDDIRTOP) 359 | !endif 360 | !else 361 | !ifndef OUT_DIR 362 | OUT_DIR = $(TMP_DIR) 363 | !endif 364 | !endif 365 | 366 | 367 | #---------------------------------------------------------- 368 | # Decode the statistics requested. 369 | #---------------------------------------------------------- 370 | 371 | !if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"] 372 | TCL_MEM_DEBUG = 0 373 | TCL_COMPILE_DEBUG = 0 374 | !else 375 | !if [nmakehlp -f $(STATS) "memdbg"] 376 | !message *** Doing memdbg 377 | TCL_MEM_DEBUG = 1 378 | !else 379 | TCL_MEM_DEBUG = 0 380 | !endif 381 | !if [nmakehlp -f $(STATS) "compdbg"] 382 | !message *** Doing compdbg 383 | TCL_COMPILE_DEBUG = 1 384 | !else 385 | TCL_COMPILE_DEBUG = 0 386 | !endif 387 | !endif 388 | 389 | 390 | #---------------------------------------------------------- 391 | # Decode the checks requested. 392 | #---------------------------------------------------------- 393 | 394 | !if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"] 395 | TCL_NO_DEPRECATED = 0 396 | WARNINGS = -W3 397 | !else 398 | !if [nmakehlp -f $(CHECKS) "nodep"] 399 | !message *** Doing nodep check 400 | TCL_NO_DEPRECATED = 1 401 | !else 402 | TCL_NO_DEPRECATED = 0 403 | !endif 404 | !if [nmakehlp -f $(CHECKS) "fullwarn"] 405 | !message *** Doing full warnings check 406 | WARNINGS = -W4 407 | !if [nmakehlp -l -warn:3] 408 | LINKERFLAGS = $(LINKERFLAGS) -warn:3 409 | !endif 410 | !else 411 | WARNINGS = -W3 412 | !endif 413 | !if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64] 414 | !message *** Doing 64bit portability warnings 415 | WARNINGS = $(WARNINGS) -Wp64 416 | !endif 417 | !endif 418 | 419 | !if $(PGO) > 1 420 | !if [nmakehlp -l -ltcg:pgoptimize] 421 | LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize 422 | !else 423 | MSG=^ 424 | This compiler does not support profile guided optimization. 425 | !error $(MSG) 426 | !endif 427 | !elseif $(PGO) > 0 428 | !if [nmakehlp -l -ltcg:pginstrument] 429 | LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument 430 | !else 431 | MSG=^ 432 | This compiler does not support profile guided optimization. 433 | !error $(MSG) 434 | !endif 435 | !endif 436 | 437 | #---------------------------------------------------------- 438 | # Set our defines now armed with our options. 439 | #---------------------------------------------------------- 440 | 441 | OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS 442 | 443 | !if $(TCL_MEM_DEBUG) 444 | OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG 445 | !endif 446 | !if $(TCL_COMPILE_DEBUG) 447 | OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS 448 | !endif 449 | !if $(TCL_THREADS) 450 | OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1 451 | !endif 452 | !if $(STATIC_BUILD) 453 | OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD 454 | !endif 455 | !if $(TCL_NO_DEPRECATED) 456 | OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED 457 | !endif 458 | 459 | !if !$(DEBUG) 460 | OPTDEFINES = $(OPTDEFINES) -DNDEBUG 461 | !if $(OPTIMIZING) 462 | OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED 463 | !endif 464 | !endif 465 | !if $(PROFILE) 466 | OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED 467 | !endif 468 | !if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" 469 | OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT 470 | !endif 471 | 472 | 473 | #---------------------------------------------------------- 474 | # Get common info used when building extensions. 475 | #---------------------------------------------------------- 476 | 477 | !if "$(PROJECT)" != "tcl" 478 | 479 | # If INSTALLDIR set to tcl root dir then reset to the lib dir. 480 | !if exist("$(_INSTALLDIR)\include\tcl.h") 481 | _INSTALLDIR=$(_INSTALLDIR)\lib 482 | !endif 483 | 484 | !if !defined(TCLDIR) 485 | !if exist("$(_INSTALLDIR)\..\include\tcl.h") 486 | TCLINSTALL = 1 487 | _TCLDIR = $(_INSTALLDIR)\.. 488 | _TCL_H = $(_INSTALLDIR)\..\include\tcl.h 489 | TCLDIR = $(_INSTALLDIR)\.. 490 | !else 491 | MSG=^ 492 | Failed to find tcl.h. Set the TCLDIR macro. 493 | !error $(MSG) 494 | !endif 495 | !else 496 | _TCLDIR = $(TCLDIR:/=\) 497 | !if exist("$(_TCLDIR)\include\tcl.h") 498 | TCLINSTALL = 1 499 | _TCL_H = $(_TCLDIR)\include\tcl.h 500 | !elseif exist("$(_TCLDIR)\generic\tcl.h") 501 | TCLINSTALL = 0 502 | _TCL_H = $(_TCLDIR)\generic\tcl.h 503 | !else 504 | MSG =^ 505 | Failed to find tcl.h. The TCLDIR macro does not appear correct. 506 | !error $(MSG) 507 | !endif 508 | !endif 509 | !endif 510 | 511 | #-------------------------------------------------------------- 512 | # Extract various version numbers from tcl headers 513 | # The generated file is then included in the makefile. 514 | #-------------------------------------------------------------- 515 | 516 | !if [echo REM = This file is generated from rules.vc > versions.vc] 517 | !endif 518 | !if [echo TCL_MAJOR_VERSION = \>> versions.vc] \ 519 | && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc] 520 | !endif 521 | !if [echo TCL_MINOR_VERSION = \>> versions.vc] \ 522 | && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc] 523 | !endif 524 | !if [echo TCL_PATCH_LEVEL = \>> versions.vc] \ 525 | && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc] 526 | !endif 527 | 528 | # If building the tcl core then we need additional package versions 529 | !if "$(PROJECT)" == "tcl" 530 | !if [echo PKG_HTTP_VER = \>> versions.vc] \ 531 | && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc] 532 | !endif 533 | !if [echo PKG_TCLTEST_VER = \>> versions.vc] \ 534 | && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc] 535 | !endif 536 | !if [echo PKG_MSGCAT_VER = \>> versions.vc] \ 537 | && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc] 538 | !endif 539 | !if [echo PKG_PLATFORM_VER = \>> versions.vc] \ 540 | && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc] 541 | !endif 542 | !if [echo PKG_SHELL_VER = \>> versions.vc] \ 543 | && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc] 544 | !endif 545 | !endif 546 | 547 | !include versions.vc 548 | 549 | #-------------------------------------------------------------- 550 | # Setup tcl version dependent stuff headers 551 | #-------------------------------------------------------------- 552 | 553 | !if "$(PROJECT)" != "tcl" 554 | 555 | TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) 556 | 557 | !if $(TCL_VERSION) < 81 558 | TCL_DOES_STUBS = 0 559 | !else 560 | TCL_DOES_STUBS = 1 561 | !endif 562 | 563 | !if $(TCLINSTALL) 564 | _TCLBINDIR = "$(_TCLDIR)\bin" 565 | TCLSH = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe" 566 | !if !exist($(TCLSH)) && $(TCL_THREADS) 567 | TCLSH = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe" 568 | !endif 569 | TCLSTUBLIB = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib" 570 | TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib" 571 | TCL_LIBRARY = $(_TCLDIR)\lib 572 | COFFBASE = \must\have\tcl\sources\to\build\this\target 573 | TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target 574 | TCL_INCLUDES = -I"$(_TCLDIR)\include" 575 | !else 576 | _TCLBINDIR = $(_TCLDIR)\win\$(BUILDDIRTOP) 577 | TCLSH = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe" 578 | !if !exist($(TCLSH)) && $(TCL_THREADS) 579 | TCLSH = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe" 580 | !endif 581 | TCLSTUBLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib" 582 | TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib" 583 | TCL_LIBRARY = $(_TCLDIR)\library 584 | COFFBASE = "$(_TCLDIR)\win\coffbase.txt" 585 | TCLTOOLSDIR = $(_TCLDIR)\tools 586 | TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win" 587 | !endif 588 | 589 | !endif 590 | 591 | #---------------------------------------------------------- 592 | # Optionally check for Tk info for building extensions. 593 | #---------------------------------------------------------- 594 | 595 | !ifdef PROJECT_REQUIRES_TK 596 | !if !defined(TKDIR) 597 | !if exist("$(_INSTALLDIR)\..\include\tk.h") 598 | TKINSTALL = 1 599 | _TKDIR = $(_INSTALLDIR)\.. 600 | _TK_H = $(_TKDIR)\include\tk.h 601 | TKDIR = $(_TKDIR) 602 | !elseif exist("$(_TCLDIR)\include\tk.h") 603 | TKINSTALL = 1 604 | _TKDIR = $(_TCLDIR) 605 | _TK_H = $(_TKDIR)\include\tk.h 606 | TKDIR = $(_TKDIR) 607 | !endif 608 | !else 609 | _TKDIR = $(TKDIR:/=\) 610 | !if exist("$(_TKDIR)\include\tk.h") 611 | TKINSTALL = 1 612 | _TK_H = $(_TKDIR)\include\tk.h 613 | !elseif exist("$(_TKDIR)\generic\tk.h") 614 | TKINSTALL = 0 615 | _TK_H = $(_TKDIR)\generic\tk.h 616 | !else 617 | MSG =^ 618 | Failed to find tk.h. The TKDIR macro does not appear correct. 619 | !error $(MSG) 620 | !endif 621 | !endif 622 | !endif 623 | 624 | #------------------------------------------------------------------------- 625 | # Extract Tk version numbers 626 | #------------------------------------------------------------------------- 627 | 628 | !if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk" 629 | !if [echo TK_MAJOR_VERSION = \>> versions.vc] \ 630 | && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc] 631 | !endif 632 | !if [echo TK_MINOR_VERSION = \>> versions.vc] \ 633 | && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc] 634 | !endif 635 | !if [echo TK_PATCH_LEVEL = \>> versions.vc] \ 636 | && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc] 637 | !endif 638 | 639 | !include versions.vc 640 | 641 | TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION) 642 | TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION) 643 | 644 | !if "$(PROJECT)" != "tk" 645 | !if $(TKINSTALL) 646 | _TKBINDIR = $(_TKDIR)\bin 647 | WISH = "$(_TKBINDIR)\wish$(TK_VERSION)$(SUFX).exe" 648 | !if !exist($(WISH)) && $(TCL_THREADS) 649 | WISH = "$(_TKBINDIR)\wish$(TK_VERSION)t$(SUFX).exe" 650 | !endif 651 | TKSTUBLIB = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib" 652 | TK_LIBRARY = $(_TKDIR)\lib 653 | TKIMPLIB = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib" 654 | TK_INCLUDES = -I"$(_TKDIR)\include" 655 | !else 656 | _TKBINDIR = $(_TKDIR)\win\$(BUILDDIRTOP) 657 | WISH = "$(_TKBINDIR)\wish$(TCL_VERSION)$(SUFX).exe" 658 | !if !exist($(WISH)) && $(TCL_THREADS) 659 | WISH = "$(_TKBINDIR)\wish$(TCL_VERSION)t$(SUFX).exe" 660 | !endif 661 | TKSTUBLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib" 662 | TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib" 663 | TK_LIBRARY = $(_TKDIR)\library 664 | TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib" 665 | !endif 666 | !endif 667 | 668 | !endif 669 | 670 | #---------------------------------------------------------- 671 | # Setup the fully qualified OUT_DIR path as OUT_DIR_PATH 672 | #---------------------------------------------------------- 673 | !if [echo OUT_DIR_PATH = \>> versions.vc] \ 674 | && [nmakehlp -Q "$(OUT_DIR)" >> versions.vc] 675 | !endif 676 | !include versions.vc 677 | 678 | #---------------------------------------------------------- 679 | # Display stats being used. 680 | #---------------------------------------------------------- 681 | 682 | !message *** Intermediate directory will be '$(TMP_DIR)' 683 | !message *** Output directory will be '$(OUT_DIR)' 684 | !message *** Suffix for binaries will be '$(SUFX)' 685 | !message *** Optional defines are '$(OPTDEFINES)' 686 | !message *** Compiler version $(VCVER). Target machine is $(MACHINE) 687 | !message *** Host architecture is $(NATIVE_ARCH) 688 | !message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)' 689 | !message *** Link options '$(LINKERFLAGS)' 690 | 691 | !endif 692 | --------------------------------------------------------------------------------