Tidied up the tests so they run all the way through and added lots of zipfs tests.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 22 Jan 2009 14:36:58 +0000 (14:36 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 22 Jan 2009 14:36:58 +0000 (14:36 +0000)
Updated windows nmake build files.

ChangeLog
tests/vfs.test
tests/vfsArchive.test
tests/vfsFtp.test
tests/vfsTar.test
tests/vfsUrl.test
tests/vfsZip.test
win/makefile.vc
win/nmakehlp.c
win/rules.vc

index 16dcd5972763fc07023b75c6b20f7e15beb67464..4a9899f8d50c1b5e76332821d38a9fffd2f8df0b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2009-01-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
 
+       * win/makefile.vc:  Updated windows build files
+       * win/rules.vc:
+       * win/nmakehlp.c:
+
+       * tests/*.test: Tidied up the tests. Added lots of zipfs tests.
+       
        * library/zipvfs.tcl: Applied patch from [Bug 1011492] to ensure
        we handle zipfiles with a prefix block robustly.
 
index 9ec9b8c0720399e64e666e34cdeb5c720c0526d2..fbc91d63eaae7af8dba2b6e66bc0df5e83ab2705 100644 (file)
@@ -155,7 +155,6 @@ test vfs-3.4 {vfs helpers: zip} {
 test vfs-4.1 {vfs glob with .. [Bug 2378350]} -setup {
     package require vfs::ns 0.5.1
 } -body {
-    namespace eval ::test {}
     namespace eval ::test {}
     namespace eval ::test::bar {}
     namespace eval ::test::baz {}
@@ -176,6 +175,36 @@ test vfs-4.1 {vfs glob with .. [Bug 2378350]} -setup {
               0 {nstest/test/bar/../baz/noz} \
               ]
 
+test vfs-4.2 {Test MatchInDirectory fix} -setup {
+    package require vfs::ns 0.5.1
+} -body {
+    namespace eval ::test {}
+    namespace eval ::test::quux {}
+    proc ::test::waz {args} { blah blah}
+    vfs::ns::Mount :: nstest
+    set res [list]
+    lappend res \
+           [catch {lsort [glob nstest/test/*]} msg] $msg \
+           [catch {lsort [glob nstest/test/quux/*]} msg] $msg \
+           [catch {lsort [glob -nocomplain nstest/test/quux/*]} msg] $msg \
+           [catch {lsort [glob nstest/test/quux/nothingthere/*]} msg] $msg \
+           [catch {lsort [glob -nocomplain nstest/test/quux/nothingthere/*]} msg] $msg \
+} -cleanup {
+    catch {vfs::unmount nstest}
+    catch {namespace delete ::test}
+} -result [list \
+              0 {nstest/test/quux nstest/test/waz} \
+               1 {no files matched glob pattern "nstest/test/quux/*"} \
+               0 {} \
+               1 {no files matched glob pattern "nstest/test/quux/nothingthere/*"} \
+               0 {} \
+              ]
+
+
 # cleanup
 ::tcltest::cleanupTests
 return
+
+# Local variables:
+# mode: tcl
+# End:
\ No newline at end of file
index f8090e99bda8bd410b17d39219ac447cd44ca9e6..a135d78550c08fc97bd0f5fc12a59c831573bff2 100644 (file)
@@ -1,4 +1,6 @@
-# Commands covered: running our tests from inside a 'zip' vfs.
+# vfsArchive.test                                               -*- tcl -*-
+#
+#      Commands covered: running our tests from inside a 'zip' vfs.
 #
 # This file contains a collection of tests for one or more of the Tcl
 # built-in commands.  Sourcing this file into Tcl runs the tests and
@@ -15,6 +17,14 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
     namespace import ::tcltest::*
 }
 
+# -------------------------------------------------------------------------
+# This file really buggers up the normal test suite run.
+# Comment this return if you really want to run this.
+#
+return
+#
+# -------------------------------------------------------------------------
+
 tcltest::testConstraint nativefs \
   [string equal [lindex [file system [info script]] 0] "native"]
 
@@ -114,5 +124,6 @@ test vfsArchive-1.2 {run tests in mk4 archive} {nativefs} {
     set res
 } {ok}
 
-
-
+# cleanup
+::tcltest::cleanupTests
+return
index f815c8b80282b246969a807990cc2c7fbbbfe907..27cba1258fc7232427ab0156f979be45c9a25624 100644 (file)
@@ -1,4 +1,6 @@
-# Commands covered:  vfs::ftp::Mount and friends.
+# vfsFtp.test                                                   -*- tcl -*-
+#
+#      Commands covered:  vfs::ftp::Mount and friends.
 #
 # This file contains a collection of tests for one or more of the Tcl
 # built-in commands.  Sourcing this file into Tcl runs the tests and
 #
 
 if {[lsearch [namespace children] ::tcltest] == -1} {
-    package require tcltest
+    package require tcltest 2
     namespace import ::tcltest::*
 }
 
-package require vfs::ftp
-
-puts stdout "These tests require an internet connection, and might"
-puts stdout "take a long time to complete."
+testConstraint ftp [expr {![catch {package require vfs::ftp}]}]
 
-set dir [pwd]
+if {[testConstraint ftp]} {
+    puts stdout "These tests require an internet connection, and might"
+    puts stdout "take a long time to complete."
+}
 
-test vfsFtp-1.1 {mount and cd} {
-    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ localmount
-    cd localmount
+test vfsFtp-1.1 {mount and cd} -constraints {ftp} -setup {
+    set cwd [pwd]
+} -body {
+    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+    cd local
     cd tcl
-    file tail [pwd]
-} {tcl}
-
-test vfsFtp-1.2 {mount and glob} {
-    glob -nocomplain vfsTest.tcl
-} {vfsTest.tcl}
-
-test vfsFtp-1.3 {mount and source} {
-    source vfsTest.tcl
-} {This was returned from a remote file}
+    set result [file tail [pwd]]
+    vfs::unmount local
+    set result
+} -cleanup {
+    cd $pwd
+} -result {tcl}
+
+test vfsFtp-1.2 {mount and glob} -constraints {ftp} -setup {
+    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+} -body {
+    glob -nocomplain -directory local/tcl vfsTest.tcl
+} -cleanup {
+    vfs::unmount local
+} -result {vfsTest.tcl}
+
+test vfsFtp-1.3 {mount and source} -constraints {ftp} -setup {
+    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+} -body {
+    set f [open local/tcl/vfsTest.tcl r]
+    set data [read $f]
+    close $f
+    set data
+} -cleanup {
+    vfs::unmount local
+} -result {This was returned from a remote file}
 
 # cleanup
-cd $dir
-catch {vfs::unmount localmount}
-
 ::tcltest::cleanupTests
 return
index 28a7bddadb9dee693f9b4dca7a1f3f779cccc508..bf74703ef5c272a1084f6d0615a1b8ea4a8f4f54 100644 (file)
Binary files a/tests/vfsTar.test and b/tests/vfsTar.test differ
index 098a5859b7648f0a34abfe4d7b7918b68751b393..3716ae52f89b57b3baac43a542472e42e6bda239 100644 (file)
@@ -1,4 +1,6 @@
-# Commands covered:  vfs::urltype::Mount and friends.
+# vfsZip.test                                                   -*- tcl -*-
+#
+#      Commands covered:  vfs::urltype::Mount and friends.
 #
 # This file contains a collection of tests for one or more of the Tcl
 # built-in commands.  Sourcing this file into Tcl runs the tests and
index b32132338b31555f0a2f8c942343f4e37b86a0ec..7411b665d1af6962edbe4ee51c275bba87c376c0 100644 (file)
-# Commands covered:  the 'zip' vfs.
+# vfsZip.test                                                   -*- tcl -*-
+#
+#      Commands covered:  the 'zip' vfs.
 #
 # This file contains a collection of tests for one or more of the Tcl
 # built-in commands.  Sourcing this file into Tcl runs the tests and
 # generates output for errors.  No output means no errors were found.
 #
 # Copyright (c) 2001-2002 by Vince Darley.
+# Copyright (c) 2009 by Pat Thoyts <patthoyts@users.sourceforge.net>
 #
 # See the file "license.terms" for information on usage and redistribution
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 #
 
 if {[lsearch [namespace children] ::tcltest] == -1} {
-    package require tcltest
+    package require tcltest 2
     namespace import ::tcltest::*
 }
 
-package require vfs::zip
+testConstraint zipfs [expr {![catch {package require vfs::zip}]}]
+
+# To test this properly we require a zip file. If a zip
+# executable can be found then we will create one.
+#
+testConstraint zipexe [expr {[auto_execok zip] ne ""}]
+if {[testConstraint zipfs] && [testConstraint zipexe]} {
+    file mkdir zipfs.test
+    makeFile {File one} zipfs.test/One.txt
+    makeFile {File two} zipfs.test/Two.txt
+    file mkdir zipfs.test/Aleph
+    makeFile {File aleph one} zipfs.test/Aleph/One.txt
+    makeFile {File aleph two} zipfs.test/Aleph/Two.txt
+    eval exec [auto_execok zip] [list -r zipfs.zip zipfs.test]
+    eval exec [auto_execok zip] [list zipnest.zip zipfs.zip]
+}
+
+test vfsZip-1.1 "mount non-existent zip file" -constraints {zipfs} -setup {
+    set file [makeFile {} vfszip.zip]
+} -body {
+    set mnt [vfs::zip::Mount $file localmount]
+} -cleanup {
+    removeFile $file
+} -returnCodes {error} -result {no header found}
+
+test vfsZip-1.2 "mount invalid zip file"  -constraints {zipfs} -setup {
+    set file [makeFile {random text} vfszip.zip]
+} -body {
+    set mnt [vfs::zip::Mount $file localmount]
+} -cleanup {
+    removeFile $file
+} -returnCodes {error} -result {no header found}
+
+test vfsZip-1.3 "mount zipfile" -constraints {zipfs zipexe} -body {
+    vfs::zip::Mount zipfs.zip local
+    vfs::unmount local
+} -result {}
+
+test vfsZip-1.4 "glob" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    glob -directory local *
+} -cleanup {
+    vfs::unmount local
+} -result {local/zipfs.test}
+
+test vfsZip-1.5 "glob files" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    lsort [glob -directory local/zipfs.test -tails *]
+} -cleanup {
+    vfs::unmount local
+} -result {Aleph One.txt Two.txt}
+
+test vfsZip-1.6 "glob non-present files" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    lsort [glob -directory local/zipfs.test -tails ridikulus.txt]
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {error} -result {no files matched glob pattern "ridikulus.txt"}
+
+test vfsZip-1.7 "glob non-present directory" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    lsort [glob -directory local/zipfs.test/ridikulus -tails *]
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {error} -result {no files matched glob pattern "*"}
+
+test vfsZip-1.8 "read file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    set f [open local/zipfs.test/One.txt r]
+    set data [string trim [read $f]]
+    close $f
+    set data
+} -cleanup {
+    vfs::unmount local
+} -result {File one}
+
+test vfsZip-1.9 "stat file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat local/zipfs.test/One.txt stat
+    lappend result type $stat(type) size [expr {$stat(size) > 8}]
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount local
+} -result {type file size 1}
+
+test vfsZip-1.10 "stat directory" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat local/zipfs.test/Aleph stat
+    lappend result type $stat(type) size $stat(size)
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount local
+} -result {type directory size 0}
+
+test vfsZip-1.11 "cd directory" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+    set cwd [pwd]
+} -body {
+    cd local/zipfs.test/Aleph
+    lsort [glob *]
+} -cleanup {
+    cd $cwd
+    vfs::unmount local
+} -result {One.txt Two.txt}
 
-test vfsZip-1.1 {mount with error} {
-    set f [file join [temporaryDirectory] vfszip.zip]
-    close [open $f w]
-    set res [catch {vfs::zip::Mount $f localmount} err]
-    #lappend res $err
-    lappend res [catch {file delete $f}]
-    set res
-} {1 0}
+test vfsZip-2.0 "nested stat file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat local/zipfs.zip stat
+    lappend result type $stat(type) size [expr {$stat(size) != 0}]
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount local
+} -result {type file size 1}
+
+test vfsZip-2.1 "nested mount" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+} -body {
+    vfs::zip::Mount local/zipfs.zip nested
+    vfs::unmount nested
+} -cleanup {
+    vfs::unmount local
+} -result {}
+
+test vfsZip-2.2 "stat mountpoint" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+    vfs::zip::Mount local/zipfs.zip nested
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat nested stat
+    lappend result type $stat(type) size $stat(size)
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount nested
+    vfs::unmount local
+} -result {type directory size 0}
+
+test vfsZip-2.3 "stat nested file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+    vfs::zip::Mount local/zipfs.zip nested
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat nested/zipfs.test/One.txt stat
+    lappend result type $stat(type) size [expr {$stat(size) > 0}]
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount nested
+    vfs::unmount local
+} -result {type file size 1}
+
+test vfsZip-2.4 "nested self-mount" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+} -body {
+    vfs::zip::Mount local/zipfs.zip local/zipfs.zip
+    set r [file isdirectory local/zipfs.zip]
+    vfs::unmount local/zipfs.zip
+    set r
+} -cleanup {
+    vfs::unmount local
+} -result {1}
+
+test vfsZip-2.5 "nested cwd" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip vfszip25
+    vfs::zip::Mount vfszip25/zipfs.zip vfszip25/zipfs.zip
+    set cwd [pwd]
+} -body {
+    cd vfszip25/zipfs.zip/zipfs.test/Aleph
+    lsort [glob *]
+} -cleanup {
+    cd $cwd
+    vfs::unmount vfszip25/zipfs.zip
+    vfs::unmount vfszip25
+} -result {One.txt Two.txt}
+
+# NOTE: this test issues an error, it should probably be a nicer error though if
+#       someone unmounts while using the vfs. At the moment the message is garbage.
+#
+test vfsZip-2.6 "nested cwd, umount in use" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip vfszip26
+    set cwd [pwd]
+} -body {
+    vfs::zip::Mount vfszip26/zipfs.zip vfszip26/zipfs.zip
+    cd vfszip26/zipfs.zip/zipfs.test/Aleph
+    vfs::unmount vfszip26/zipfs.zip
+    pwd
+} -cleanup {
+    cd $cwd
+    vfs::unmount vfszip26/zipfs.zip
+    vfs::unmount vfszip26
+} -returnCodes {error} -match glob -result {*}
+
+
+test vfsZip-2.7 "nested mount mis-ordered unmounts" -constraints {zipfs zipexe} -setup {
+} -body {
+    vfs::zip::Mount zipnest.zip vfszip27
+    vfs::zip::Mount vfszip27/zipfs.zip vfszip27/zipfs.zip
+    set r [file isdirectory vfszip27/zipfs.zip]
+    vfs::unmount vfszip27
+    vfs::unmount vfszip27/zipfs.zip
+    set r
+} -cleanup {
+} -result {1}
+
+testConstraint bug1533748 [file exists [file join [testsDirectory] bug1533748.zip]]
+
+test vfsZip-3.0 "bug #: ./ prefixed filenames" -constraints {zipfs zipexe bug1533748} -setup {
+    vfs::zip::Mount [file join [testsDirectory] bug1533748.zip] vfszip30
+} -body {
+    list [glob -nocomplain -directory vfszip30 -tails *] \
+        [glob -nocomplain -directory vfszip30/articles -tails *] \
+} -cleanup {
+    vfs::unmount vfszip30
+} -result {articles c_5498.xml}
+
+test vfsZip-3.1 "bug #: ./ prefixed filenames" -constraints {zipfs zipexe bug1533748} -setup {
+    vfs::zip::Mount [file join [testsDirectory] bug1533748.zip] vfszip31
+} -body {
+    set f [open vfszip31/articles/c_5498.xml r]
+    fconfigure $f -translation binary
+    set data [read $f]
+    close $f
+    expr {[string length $data] == [file size vfszip31/articles/c_5498.xml]}
+} -cleanup {
+    vfs::unmount vfszip31
+} -result {1}
+
+test vfsZip-9.0 "attempt to delete mounted file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    file delete zipfs.zip
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {error} -result {error deleting "zipfs.zip": permission denied}
+
+# cleanup
+if {[testConstraint zipfs] && [testConstraint zipexe]} {
+    file delete -force zipfs.test
+    file delete zipfs.zip
+    file delete zipnest.zip
+}
+tcltest::cleanupTests
+return
index a3dc5e3a782cd2fa1d555021d09dc67f5b369567..2080b0cce2a5b1c2a60a0540a6bac79721c2b00a 100644 (file)
@@ -15,7 +15,7 @@
 # Copyright (c) 1998-2000 Ajuba Solutions.
 # Copyright (c) 2001 ActiveState Corporation.
 # Copyright (c) 2001-2002 David Gravereaux.
-# Copyright (c) 2003-2006 Pat Thoyts
+# Copyright (c) 2003-2008 Pat Thoyts
 #
 #-------------------------------------------------------------------------
 # RCS: @(#)$Id$
@@ -278,12 +278,15 @@ TCL_CFLAGS        = -DPACKAGE_NAME="\"$(PROJECT)\"" \
                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
                   -DBUILD_$(PROJECT) $(BASE_CFLAGS) $(OPTDEFINES)
 
+### Stubs files should not be compiled with -GL
+STUB_CFLAGS     = $(cflags) $(cdebug:-GL=) #$(TK_DEFINES)
+
 #---------------------------------------------------------------------
 # Link flags
 #---------------------------------------------------------------------
 
 !if $(DEBUG)
-ldebug = -debug:full -debugtype:cv
+ldebug = -debug
 !if $(MSVCRT)
 ldebug = $(ldebug) -nodefaultlib:msvcrt
 !endif
@@ -328,13 +331,19 @@ baselibs   = $(baselibs) bufferoverflowU.lib
 !endif
 !endif
 
+!if exist("$(TCLDIR)\win\coffbase.txt")
+dllbase        = -base:@$(TCLDIR)\win\coffbase.txt,tdbc
+!else
+dllbase = -base:0x10A70000 
+!endif
+
 #---------------------------------------------------------------------
 # TclTest flags
 #---------------------------------------------------------------------
 
-!IF "$(TESTPAT)" != ""
+!if "$(TESTPAT)" != ""
 TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!ENDIF
+!endif
 
 #---------------------------------------------------------------------
 # Project specific targets (EDIT)
@@ -346,9 +355,9 @@ install:    install-binaries install-libraries install-docs
 pkgIndex:   setup $(OUT_DIR)\pkgIndex.tcl
 
 test: setup $(PROJECT)
-       @set VFS_LIBRARY=$(LIBDIR:\=/)
        @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
-       @set TCLLIBPATH=$(OUT_DIR:\=/)
+        @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+       @set VFS_LIBRARY=$(LIBDIR:\=/)
 !if $(TCLINSTALL)
        @set PATH=$(_TCLDIR)\bin;$(PATH)
 !else
@@ -363,9 +372,9 @@ test: setup $(PROJECT)
 !endif
 
 shell: setup $(PROJECT)
-       @set VFS_LIBRARY=$(LIBDIR:\=/)
        @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
-       @set TCLLIBPATH=$(OUT_DIR:\=/)
+        @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+       @set VFS_LIBRARY=$(LIBDIR:\=/)
 !if $(TCLINSTALL)
        @set PATH=$(_TCLDIR)\bin;$(PATH)
 !else
@@ -383,14 +392,13 @@ setup:
        @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
        @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
 
-# See <tcl>/win/coffbase.txt for extension base addresses.
 $(PRJLIB): $(DLLOBJS)
 !if $(STATIC_BUILD)
        $(lib32) -nologo -out:$@ @<<
 $**
 <<
 !else
-       $(link32) $(dlllflags) -base:0x10A70000 -out:$@ $(baselibs) @<<
+       $(link32) $(dlllflags) $(dllbase) -out:$@ $(baselibs) @<<
 $**
 <<
        $(_VC_MANIFEST_EMBED_DLL)
@@ -481,7 +489,7 @@ install-docs:
 
 clean:
        @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
-       @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+       @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
        @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
        @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
        @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
index 35b35e505fbf6d3d667ca54fa66a9bf7f047ca52..39e3e709e4a6daba59a5af73867431d3704581a4 100644 (file)
 
 #define _CRT_SECURE_NO_DEPRECATE
 #include <windows.h>
+#define NO_SHLWAPI_GDI
+#define NO_SHLWAPI_STREAM
+#define NO_SHLWAPI_REG
+#include <shlwapi.h>
 #pragma comment (lib, "user32.lib")
 #pragma comment (lib, "kernel32.lib")
+#pragma comment (lib, "shlwapi.lib")
 #include <stdio.h>
 #include <math.h>
 
@@ -45,6 +50,7 @@ int           CheckForLinkerFeature(const char *option);
 int            IsIn(const char *string, const char *substring);
 int            GrepForDefine(const char *file, const char *string);
 int            SubstituteFile(const char *substs, const char *filename);
+int            QualifyPath(const char *path);
 const char *    GetVersionFromFile(const char *filename, const char *match);
 DWORD WINAPI   ReadFromPipe(LPVOID args);
 
@@ -165,10 +171,21 @@ main(
            }
            printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
            return 0;
+       case 'Q':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -q path\n"
+                   "Emit the fully qualified path\n"
+                   "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 2;
+           }
+           return QualifyPath(argv[2]);
        }
     }
     chars = snprintf(msg, sizeof(msg) - 1,
-           "usage: %s -c|-l|-f|-g|-V ...\n"
+           "usage: %s -c|-l|-f|-g|-V|-s|-Q ...\n"
            "This is a little helper app to equalize shell differences between WinNT and\n"
            "Win9x and get nmake.exe to accomplish its job.\n",
            argv[0]);
@@ -714,6 +731,30 @@ SubstituteFile(
     fclose(fp);
     return 0;
 }
+\f
+/*
+ * QualifyPath --
+ *
+ *     This composes the current working directory with a provided path
+ *     and returns the fully qualified and normalized path.
+ *     Mostly needed to setup paths for testing.
+ */
+
+int
+QualifyPath(
+    const char *szPath)
+{
+    char szCwd[MAX_PATH + 1];
+    char szTmp[MAX_PATH + 1];
+    char *p;
+    GetCurrentDirectory(MAX_PATH, szCwd);
+    while ((p = strchr(szPath, '/')) && *p)
+       *p = '\\';
+    PathCombine(szTmp, szCwd, szPath);
+    PathCanonicalize(szCwd, szTmp);
+    printf("%s\n", szCwd);
+    return 0;
+}
 
 /*
  * Local variables:
index 8a2d227e5901f9f40744a4e8a3b18bad20cef3aa..3a4264380a927f47342551b9506539e87d4902a6 100644 (file)
@@ -1,4 +1,4 @@
-#------------------------------------------------------------------------------
+#------------------------------------------------------------- -*- Makefile -*-
 # rules.vc --
 #
 #      Microsoft Visual C++ makefile include for decoding the commandline
@@ -35,7 +35,7 @@ _INSTALLDIR   = $(INSTALLDIR:/=\)
 
 !ifndef MACHINE
 !if "$(CPU)" == "" || "$(CPU)" == "i386"
-MACHINE         = IX86
+MACHINE                = IX86
 !else
 MACHINE         = $(CPU)
 !endif
@@ -95,7 +95,7 @@ OPTIMIZING    = 1
 OPTIMIZING     = 0
 !endif
 
-OPTIMIZATIONS  =
+OPTIMIZATIONS   =
 
 !if [nmakehlp -c -Ot]
 OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
@@ -192,6 +192,8 @@ VCVER=0
 !if ![echo VCVERSION=_MSC_VER > vercl.x] \
     && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
 !include vercl.i
+!if ![del /q vercl.x vercl.i $(ERRNULL)]
+!endif
 !if $(VCVERSION) >= 1500
 VCVER=9
 !elseif $(VCVERSION) >= 1400
@@ -461,10 +463,14 @@ OPTDEFINES        = $(OPTDEFINES) -DTCL_CFG_DO64BIT
 
 
 #----------------------------------------------------------
-# Get common info used when building extensions.
+# Locate the Tcl headers to build against
 #----------------------------------------------------------
 
-!if "$(PROJECT)" != "tcl"
+!if "$(PROJECT)" == "tcl"
+
+_TCL_H          = ..\generic\tcl.h
+
+!else
 
 # If INSTALLDIR set to tcl root dir then reset to the lib dir.
 !if exist("$(_INSTALLDIR)\include\tcl.h")
@@ -496,46 +502,101 @@ Failed to find tcl.h.  The TCLDIR macro does not appear correct.
 !error $(MSG)
 !endif
 !endif
+!endif
+
+#--------------------------------------------------------------
+# Extract various version numbers from tcl headers
+# The generated file is then included in the makefile.
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
 
-!if [echo REM = This file is generated from rules.vc > version.vc]
+# If building the tcl core then we need additional package versions
+!if "$(PROJECT)" == "tcl"
+!if [echo PKG_HTTP_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
+!endif
+!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
 !endif
-!if exist("$(_TCL_H)")
-!if [echo TCL_DOTVERSION = \>> version.vc] \
-   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
+!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
 !endif
+!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
+!endif
+!if [echo PKG_SHELL_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
+!endif
+!endif
+
+!include versions.vc
+
+#--------------------------------------------------------------
+# Setup tcl version dependent stuff headers
+#--------------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+TCL_VERSION    = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+
+!if $(TCL_VERSION) < 81
+TCL_DOES_STUBS = 0
+!else
+TCL_DOES_STUBS = 1
 !endif
-!include version.vc
-TCL_VERSION    = $(TCL_DOTVERSION:.=)
 
 !if $(TCLINSTALL)
-TCLSH          = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
+_TCLBINDIR      = "$(_TCLDIR)\bin"
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe"
 !if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
+TCLSH           = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe"
 !endif
 TCLSTUBLIB     = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
 TCLIMPLIB      = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
 TCL_LIBRARY    = $(_TCLDIR)\lib
+TCLREGLIB      = "$(_TCLDIR)\lib\tclreg11$(SUFX:t=).lib"
+TCLDDELIB      = "$(_TCLDIR)\lib\tcldde12$(SUFX:t=).lib"
+COFFBASE       = \must\have\tcl\sources\to\build\this\target
+TCLTOOLSDIR    = \must\have\tcl\sources\to\build\this\target
 TCL_INCLUDES    = -I"$(_TCLDIR)\include"
 !else
-TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
+_TCLBINDIR      = $(_TCLDIR)\win\$(BUILDDIRTOP)
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe"
 !if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe"
 !endif
 TCLSTUBLIB     = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
 TCLIMPLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
 TCL_LIBRARY    = $(_TCLDIR)\library
+TCLREGLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg11$(SUFX:t=).lib"
+TCLDDELIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde12$(SUFX:t=).lib"
+COFFBASE       = "$(_TCLDIR)\win\coffbase.txt"
+TCLTOOLSDIR    = $(_TCLDIR)\tools
 TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
 !endif
 
 !endif
 
-#----------------------------------------------------------
-# Optionally check for Tk info for building extensions.
-#----------------------------------------------------------
+#-------------------------------------------------------------------------
+# Locate the Tk headers to build against
+#-------------------------------------------------------------------------
 
-!ifdef PROJECT_REQUIRES_TK
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+!if "$(PROJECT)" == "tk"
+_TK_H          = ..\generic\tk.h
+!endif
 
+!ifdef PROJECT_REQUIRES_TK
 !if !defined(TKDIR)
 !if exist("$(_INSTALLDIR)\..\include\tk.h")
 TKINSTALL      = 1
@@ -562,40 +623,61 @@ Failed to find tk.h. The TKDIR macro does not appear correct.
 !error $(MSG)
 !endif
 !endif
+!endif
+
+#-------------------------------------------------------------------------
+# Extract Tk version numbers
+#-------------------------------------------------------------------------
 
-!if defined(TKDIR)
-TK_DOTVERSION = 8.4
-!if exist("$(_TK_H)")
-!if [echo TK_DOTVERSION = \>> version.vc] \
-   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
+!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
 !endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
 !endif
-!include version.vc
-TK_VERSION = $(TK_DOTVERSION:.=)
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+
+!include versions.vc
 
+TK_DOTVERSION  = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+TK_VERSION     = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+
+!if "$(PROJECT)" != "tk"
 !if $(TKINSTALL)
-WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
+_TKBINDIR       = $(_TKDIR)\bin
+WISH           = "$(_TKBINDIR)\wish$(TK_VERSION)$(SUFX).exe"
 !if !exist($(WISH)) && $(TCL_THREADS)
-WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)t$(SUFX).exe"
+WISH           = "$(_TKBINDIR)\wish$(TK_VERSION)t$(SUFX).exe"
 !endif
 TKSTUBLIB      = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TK_LIBRARY     = $(_TKDIR)\lib
 TKIMPLIB       = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
 TK_INCLUDES     = -I"$(_TKDIR)\include"
-TK_LIBRARY     = $(_TKDIR)\lib
 !else
-WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
+_TKBINDIR       = $(_TKDIR)\win\$(BUILDDIRTOP)
+WISH           = "$(_TKBINDIR)\wish$(TCL_VERSION)$(SUFX).exe"
 !if !exist($(WISH)) && $(TCL_THREADS)
-WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)t$(SUFX).exe"
+WISH           = "$(_TKBINDIR)\wish$(TCL_VERSION)t$(SUFX).exe"
 !endif
 TKSTUBLIB      = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
 TKIMPLIB       = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
-TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
 TK_LIBRARY     = $(_TKDIR)\library
+TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
 !endif
-
 !endif
+
 !endif
+
+#----------------------------------------------------------
+# Setup the fully qualified OUT_DIR path as OUT_DIR_PATH
+#----------------------------------------------------------
+!if [echo OUT_DIR_PATH = \>> versions.vc] \
+    && [nmakehlp -Q "$(OUT_DIR)" >> versions.vc]
 !endif
+!include versions.vc
 
 #----------------------------------------------------------
 # Display stats being used.