From 236570f0308763b7305fcff43431ac39f7e2d835 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Fri, 2 Jul 2004 16:52:17 +0000 Subject: backport of recent fs fixes from cvs head --- ChangeLog | 5 ++++ tests/fileSystem.test | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ win/tclWin32Dll.c | 10 ++++++- win/tclWinFile.c | 63 ++++++++++++++++++++++++++++----------- 4 files changed, 141 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2cc050c..461fae7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2004-07-02 Vince Darley + + * tests/fileSystem.test: new tests backported + * win/tclWin32Dll.c: compilation fix for VC++5.2 + 2004-06-29 Donal K. Fellows * library/safe.tcl: Make sure that the temporary variable is diff --git a/tests/fileSystem.test b/tests/fileSystem.test index b934aed..7febfcd 100644 --- a/tests/fileSystem.test +++ b/tests/fileSystem.test @@ -473,6 +473,87 @@ test filesystem-8.3 {path objects and empty string} { lappend res $dst $yyy } {foo foo {}} +proc TestFind1 {d f} { + set r1 [file exists [file join $d $f]] + lappend res "[file join $d $f] found: $r1" + lappend res "is dir a dir? [file isdirectory $d]" + set r2 [file exists [file join $d $f]] + lappend res "[file join $d $f] found: $r2" + set res +} +proc TestFind2 {d f} { + set r1 [file exists [file join $d $f]] + lappend res "[file join $d $f] found: $r1" + lappend res "is dir a dir? [file isdirectory [file join $d]]" + set r2 [file exists [file join $d $f]] + lappend res "[file join $d $f] found: $r2" + set res +} + +test filesystem-9.1 {path objects and join and object rep} { + set origdir [pwd] + cd [tcltest::temporaryDirectory] + file mkdir [file join a b c] + set res [TestFind1 a [file join b . c]] + file delete -force a + cd $origdir + set res +} {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}} + +test filesystem-9.2 {path objects and join and object rep} { + set origdir [pwd] + cd [tcltest::temporaryDirectory] + file mkdir [file join a b c] + set res [TestFind2 a [file join b . c]] + file delete -force a + cd $origdir + set res +} {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}} + +test filesystem-9.2.1 {path objects and join and object rep} { + set origdir [pwd] + cd [tcltest::temporaryDirectory] + file mkdir [file join a b c] + set res [TestFind2 a [file join b .]] + file delete -force a + cd $origdir + set res +} {{a/b/. found: 1} {is dir a dir? 1} {a/b/. found: 1}} + +test filesystem-9.3 {path objects and join and object rep} { + set origdir [pwd] + cd [tcltest::temporaryDirectory] + file mkdir [file join a b c] + set res [TestFind1 a [file join b .. b c]] + file delete -force a + cd $origdir + set res +} {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}} + +test filesystem-9.4 {path objects and join and object rep} { + set origdir [pwd] + cd [tcltest::temporaryDirectory] + file mkdir [file join a b c] + set res [TestFind2 a [file join b .. b c]] + file delete -force a + cd $origdir + set res +} {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}} + +test filesystem-9.5 {path objects and file tail and object rep} { + set origdir [pwd] + cd [tcltest::temporaryDirectory] + file mkdir dgp + close [open dgp/test w] + foreach relative [glob -nocomplain [file join * test]] { + set absolute [file join [pwd] $relative] + set res [list [file tail $absolute] "test"] + } + file delete -force dgp + cd $origdir + set res +} {test test} + cleanupTests } namespace delete ::tcl::test::fileSystem diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 78d8bc5..f30b764 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWin32Dll.c,v 1.24.2.4 2004/06/21 22:07:32 mdejong Exp $ + * RCS: @(#) $Id: tclWin32Dll.c,v 1.24.2.5 2004/07/02 16:52:19 vincentdarley Exp $ */ #include "tclWinInt.h" @@ -79,6 +79,14 @@ _except_TclWinCPUID_detach_handler( /* + * VC++ 5.x has no 'cpuid' assembler instruction, so we + * must emulate it + */ +#if defined(_MSC_VER) && ( _MSC_VER <= 1100 ) +#define cpuid __asm __emit 0fh __asm __emit 0a2h +#endif + +/* * The following function tables are used to dispatch to either the * wide-character or multi-byte versions of the operating system calls, * depending on whether the Unicode calls are available. diff --git a/win/tclWinFile.c b/win/tclWinFile.c index b29e9d1..574577e 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinFile.c,v 1.44.2.8 2004/05/19 22:50:23 dkf Exp $ + * RCS: @(#) $Id: tclWinFile.c,v 1.44.2.9 2004/07/02 16:52:20 vincentdarley Exp $ */ //#define _WIN32_WINNT 0x0500 @@ -2263,26 +2263,55 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint) } Tcl_DStringAppend(&dsNorm,nativePath,Tcl_DStringLength(&ds)); } else { - WIN32_FIND_DATAW fData; - HANDLE handle; + char *checkDots = NULL; - handle = FindFirstFileW((WCHAR*)nativePath, &fData); - if (handle == INVALID_HANDLE_VALUE) { - /* This is usually the '/' in 'c:/' at end of string */ - Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", - sizeof(WCHAR)); + if (lastValidPathEnd[1] == '.') { + checkDots = lastValidPathEnd + 1; + while (checkDots < currentPathEndPosition) { + if (*checkDots != '.') { + checkDots = NULL; + break; + } + checkDots++; + } + } + if (checkDots != NULL) { + int dotLen = currentPathEndPosition - lastValidPathEnd; + /* + * Path is just dots. We shouldn't really + * ever see a path like that. However, to be + * nice we at least don't mangle the path -- + * we just add the dots as a path segment and + * continue + */ + Tcl_DStringAppend(&dsNorm, + (TCHAR*)((WCHAR*)(nativePath + + Tcl_DStringLength(&ds)) + - dotLen), + (int)(dotLen * sizeof(WCHAR))); } else { - WCHAR *nativeName; - if (fData.cFileName[0] != '\0') { - nativeName = fData.cFileName; + /* Normal path */ + WIN32_FIND_DATAW fData; + HANDLE handle; + + handle = FindFirstFileW((WCHAR*)nativePath, &fData); + if (handle == INVALID_HANDLE_VALUE) { + /* This is usually the '/' in 'c:/' at end of string */ + Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", + sizeof(WCHAR)); } else { - nativeName = fData.cAlternateFileName; + WCHAR *nativeName; + if (fData.cFileName[0] != '\0') { + nativeName = fData.cFileName; + } else { + nativeName = fData.cAlternateFileName; + } + FindClose(handle); + Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", + sizeof(WCHAR)); + Tcl_DStringAppend(&dsNorm,(TCHAR*)nativeName, + (int) (wcslen(nativeName)*sizeof(WCHAR))); } - FindClose(handle); - Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", - sizeof(WCHAR)); - Tcl_DStringAppend(&dsNorm,(TCHAR*)nativeName, - (int) (wcslen(nativeName)*sizeof(WCHAR))); } } Tcl_DStringFree(&ds); -- cgit v0.12