summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--generic/tclFileName.c52
-rw-r--r--generic/tclIOUtil.c13
-rw-r--r--tests/fileName.test9
-rw-r--r--tests/fileSystem.test22
5 files changed, 100 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index d6dc060..fc42294 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2004-03-30 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclFileName.c: Fix to Windows glob where the pattern is
+ * generic/tclIOUtil.c: a volume relative path or a network
+ * tests/fileName.test: share [Bug 898238]. On windows 'glob'
+ * tests/fileSystem.test: will now return the results of
+ 'glob /foo/bar' and 'glob \\foo\\bar' as 'C:/foo/bar', i.e. a
+ correct absolute path (rather than a volume relative path).
+
+ Note that the test suite does not test commands like
+ 'glob //Machine/Shared/*' (on a network share).
+
+2004-03-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
* generic/tclPathObj.c: Fix to filename bugs recently
* tests/fileName.test: introduced [Bug 918320].
diff --git a/generic/tclFileName.c b/generic/tclFileName.c
index 563357a..b056ca3 100644
--- a/generic/tclFileName.c
+++ b/generic/tclFileName.c
@@ -10,12 +10,13 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclFileName.c,v 1.50 2004/03/17 18:14:13 das Exp $
+ * RCS: @(#) $Id: tclFileName.c,v 1.51 2004/03/30 15:35:46 vincentdarley Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
#include "tclRegexp.h"
+#include "tclFilesystem.h" /* For TclGetPathType() */
/*
* The following variable is set in the TclPlatformInit call to one
@@ -253,7 +254,7 @@ Tcl_GetPathType(path)
Tcl_PathType
TclpGetNativePathType(pathPtr, driveNameLengthPtr, driveNameRef)
- Tcl_Obj *pathPtr; /* Native path of interest */
+ Tcl_Obj *pathPtr; /* Native path of interest */
int *driveNameLengthPtr; /* Returns length of drive, if non-NULL
* and path was absolute */
Tcl_Obj **driveNameRef;
@@ -1634,6 +1635,53 @@ TclGlob(interp, pattern, pathPrefix, globFlags, types)
}
tail = p;
Tcl_IncrRefCount(pathPrefix);
+ } else if (pathPrefix == NULL && (tail[0] == '/'
+ || (tail[0] == '\\' && tail[1] == '\\'))) {
+ int driveNameLen;
+ Tcl_Obj *driveName;
+ Tcl_Obj *temp = Tcl_NewStringObj(tail, -1);
+ Tcl_IncrRefCount(temp);
+
+ switch (TclGetPathType(temp, NULL, &driveNameLen, &driveName)) {
+ case TCL_PATH_VOLUME_RELATIVE: {
+ /*
+ * Volume relative path which is equivalent to a path in
+ * the root of the cwd's volume. We will actually return
+ * non-volume-relative paths here. i.e. 'glob /foo*' will
+ * return 'C:/foobar'. This is much the same as globbing
+ * for a path with '\\' will return one with '/' on Windows.
+ */
+ Tcl_Obj *cwd = Tcl_FSGetCwd(interp);
+ if (cwd == NULL) {
+ Tcl_DecrRefCount(temp);
+ if (globFlags & TCL_GLOBMODE_NO_COMPLAIN) {
+ return TCL_OK;
+ } else {
+ return TCL_ERROR;
+ }
+ }
+ pathPrefix = Tcl_NewStringObj(Tcl_GetString(cwd), 3);
+ Tcl_DecrRefCount(cwd);
+ if (tail[0] == '/') {
+ tail++;
+ } else {
+ tail+=2;
+ }
+ Tcl_IncrRefCount(pathPrefix);
+ break;
+ }
+ case TCL_PATH_ABSOLUTE: {
+ /*
+ * Absolute, possibly network path //Machine/Share.
+ * Use that as the path prefix (it already has a
+ * refCount).
+ */
+ pathPrefix = driveName;
+ tail += driveNameLen;
+ break;
+ }
+ }
+ Tcl_DecrRefCount(temp);
}
/*
* ':' no longer needed as a separator. It is only relevant
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index a65971f..52bec32 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -17,7 +17,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIOUtil.c,v 1.96 2004/03/17 18:14:13 das Exp $
+ * RCS: @(#) $Id: tclIOUtil.c,v 1.97 2004/03/30 15:35:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -3442,8 +3442,15 @@ TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr, driveNameRef)
* non-NULL, then set to the
* filesystem which claims this
* path */
- int *driveNameLengthPtr;
- Tcl_Obj **driveNameRef;
+ int *driveNameLengthPtr; /* If the path is absolute, and
+ * this is non-NULL, then set to
+ * the length of the driveName */
+ Tcl_Obj **driveNameRef; /* If the path is absolute, and
+ * this is non-NULL, then set to
+ * the name of the drive,
+ * network-volume which contains
+ * the path, already with a
+ * refCount for the caller. */
{
FilesystemRecord *fsRecPtr;
int pathLen;
diff --git a/tests/fileName.test b/tests/fileName.test
index 6168f6f..791b69d 100644
--- a/tests/fileName.test
+++ b/tests/fileName.test
@@ -10,7 +10,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: fileName.test,v 1.39 2004/03/30 09:56:33 vincentdarley Exp $
+# RCS: @(#) $Id: fileName.test,v 1.40 2004/03/30 15:35:47 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -1312,12 +1312,15 @@ test filename-14.21 {asterisks, question marks, and brackets} {
test filename-14.22 {asterisks, question marks, and brackets} {
list [catch {glob goo/* x*z foo?q} msg] $msg
} {1 {no files matched glob patterns "goo/* x*z foo?q"}}
-test filename-14.23 {slash globbing} {unixOrPc} {
+test filename-14.23 {slash globbing} {unixOnly} {
glob /
} /
+test filename-14.23.2 {slash globbing} {pcOnly} {
+ glob /
+} [file norm /]
test filename-14.24 {slash globbing} {pcOnly} {
glob {\\}
-} /
+} [file norm /]
test filename-14.25 {type specific globbing} {unixOnly} {
list [catch {lsort [glob -dir globTest -types f *]} msg] $msg
} [list 0 [lsort [list \
diff --git a/tests/fileSystem.test b/tests/fileSystem.test
index 5f8105d..a619929 100644
--- a/tests/fileSystem.test
+++ b/tests/fileSystem.test
@@ -400,6 +400,28 @@ test filesystem-1.39 {file normalisation with volume relative} {winOnly} {
}
} {ok}
+test filesystem-1.40 {file normalisation with repeated separators} {
+ set a [file norm foo////bar]
+ set b [file norm foo/bar]
+
+ if {![string equal $a $b]} {
+ set res "Paths should be equal: $a , $b"
+ } else {
+ set res "ok"
+ }
+} {ok}
+
+test filesystem-1.41 {file normalisation with repeated separators} {winOnly} {
+ set a [file norm foo\\\\\\bar]
+ set b [file norm foo/bar]
+
+ if {![string equal $a $b]} {
+ set res "Paths should be equal: $a , $b"
+ } else {
+ set res "ok"
+ }
+} {ok}
+
test filesystem-2.0 {new native path} {unixOnly} {
foreach f [lsort [glob -nocomplain /usr/bin/c*]] {
catch {file readlink $f}