Attachment "winFile.patch" to
ticket [979879ffff]
added by
vincentdarley
2004-06-30 01:17:02.
? 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