? filedirname.diff
? winFile.patch
? win/a
? win/config.status.lineno
Index: tests/fileSystem.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/fileSystem.test,v
retrieving revision 1.42
diff -u -r1.42 fileSystem.test
--- tests/fileSystem.test	23 Jun 2004 15:36:56 -0000	1.42
+++ tests/fileSystem.test	29 Jun 2004 18:15:21 -0000
@@ -942,6 +942,73 @@
     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 [file join a b c]
+    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 [file join a b c]
+    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 [file join a b c]
+    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 [file join a b c]
+    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 [file join a b c]
+    cd $origdir
+    set res
+} {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+
 cleanupTests
 unset -nocomplain drive
 }
Index: win/tclWinFile.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinFile.c,v
retrieving revision 1.65
diff -u -r1.65 tclWinFile.c
--- win/tclWinFile.c	2 Jun 2004 23:29:30 -0000	1.65
+++ win/tclWinFile.c	29 Jun 2004 18:15:29 -0000
@@ -2366,29 +2366,56 @@
 		    }
 		    Tcl_DStringAppend(&dsNorm,nativePath,Tcl_DStringLength(&ds));
 		} else {
-		    WIN32_FIND_DATA fData;
-		    HANDLE handle;
+		    char *checkDots = NULL;
 		    
-		    handle = FindFirstFileA(nativePath, &fData);
-		    if (handle == INVALID_HANDLE_VALUE) {
-			if (GetFileAttributesA(nativePath) 
-			    == 0xffffffff) {
-			    /* File doesn't exist */
-			    Tcl_DStringFree(&ds);
-			    break;
+		    if (lastValidPathEnd[1] == '.') {
+			checkDots = lastValidPathEnd + 1;
+			while (checkDots < currentPathEndPosition) {
+			    if (*checkDots != '.') {
+				checkDots = NULL;
+				break;
+			    }
+			    checkDots++;
 			}
-			/* This is usually the '/' in 'c:/' at end of string */
-			Tcl_DStringAppend(&dsNorm,"/", 1);
+		    }
+		    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*)(nativePath 
+						   + Tcl_DStringLength(&ds)
+						   - dotLen), dotLen);
 		    } else {
-			char *nativeName;
-			if (fData.cFileName[0] != '\0') {
-			    nativeName = fData.cFileName;
+			/* Normal path */
+			WIN32_FIND_DATA fData;
+			HANDLE handle;
+			
+			handle = FindFirstFileA(nativePath, &fData);
+			if (handle == INVALID_HANDLE_VALUE) {
+			    if (GetFileAttributesA(nativePath) 
+				== 0xffffffff) {
+				/* File doesn't exist */
+				Tcl_DStringFree(&ds);
+				break;
+			    }
+			    /* This is usually the '/' in 'c:/' at end of string */
+			    Tcl_DStringAppend(&dsNorm,"/", 1);
 			} else {
-			    nativeName = fData.cAlternateFileName;
+			    char *nativeName;
+			    if (fData.cFileName[0] != '\0') {
+				nativeName = fData.cFileName;
+			    } else {
+				nativeName = fData.cAlternateFileName;
+			    }
+			    FindClose(handle);
+			    Tcl_DStringAppend(&dsNorm,"/", 1);
+			    Tcl_DStringAppend(&dsNorm,nativeName,-1);
 			}
-			FindClose(handle);
-			Tcl_DStringAppend(&dsNorm,"/", 1);
-			Tcl_DStringAppend(&dsNorm,nativeName,-1);
 		    }
 		}
 		Tcl_DStringFree(&ds);
@@ -2491,26 +2518,55 @@
 		    }
 		    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)));
 		    }
 		}
 #endif
