Tcl Source Code

Artifact [feaa7c2cbd]
Login

Artifact feaa7c2cbd1106d8c4e3744bd58b9e7afd892173:

Attachment "vfsGlobVol.patch" to ticket [943995ffff] added by vincentdarley 2004-05-07 02:18:06.
? vfsGlobVol.patch
Index: generic/tclFileName.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclFileName.c,v
retrieving revision 1.53
diff -b -u -r1.53 tclFileName.c
--- generic/tclFileName.c	6 Apr 2004 22:25:51 -0000	1.53
+++ generic/tclFileName.c	6 May 2004 19:15:38 -0000
@@ -1696,6 +1696,20 @@
     }
     
     /* 
+     * Finally if we still haven't managed to generate a path
+     * prefix, check if the path starts with a current volume.
+     */
+    if (pathPrefix == NULL) {
+	int driveNameLen;
+	Tcl_Obj *driveName;
+	if (TclFSNonnativePathType(tail, strlen(tail), NULL, &driveNameLen, 
+				   &driveName) == TCL_PATH_ABSOLUTE) {
+	    pathPrefix = driveName;
+	    tail += driveNameLen;
+	}
+    }
+    
+    /* 
      * We need to get the old result, in case it is over-written
      * below when we still need it.
      */
@@ -1852,7 +1866,10 @@
  *	path name to be globbed and the pattern.  The directory and
  *	remainder are assumed to be native format paths.  The prefix
  *	contained in 'pathPtr' is either a directory or path from which
- *	to start the search (or NULL).
+ *	to start the search (or NULL).  If pathPtr is NULL, then the
+ *	pattern must not start with an absolute path specification
+ *	(that case should be handled by moving the absolute path
+ *	prefix into pathPtr before calling DoGlob).
  *	
  * Results:
  *	The return value is a standard Tcl result indicating whether
Index: generic/tclFileSystem.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclFileSystem.h,v
retrieving revision 1.6
diff -b -u -r1.6 tclFileSystem.h
--- generic/tclFileSystem.h	21 Jan 2004 19:59:33 -0000	1.6
+++ generic/tclFileSystem.h	6 May 2004 19:15:38 -0000
@@ -86,11 +86,15 @@
 extern Tcl_ThreadDataKey tclFsDataKey;
 
 /* 
- * Private shared functions for use by tclIOUtil.c and tclPathObj.c
+ * Private shared functions for use by tclIOUtil.c, tclPathObj.c
+ * and tclFileName.c
  */
 Tcl_PathType     TclFSGetPathType  _ANSI_ARGS_((Tcl_Obj *pathPtr, 
 			    Tcl_Filesystem **filesystemPtrPtr, 
 			    int *driveNameLengthPtr));
+Tcl_PathType     TclFSNonnativePathType  _ANSI_ARGS_((CONST char *pathPtr, 
+			    int pathLen, Tcl_Filesystem **filesystemPtrPtr, 
+			    int *driveNameLengthPtr, Tcl_Obj **driveNameRef));
 Tcl_PathType     TclGetPathType  _ANSI_ARGS_((Tcl_Obj *pathPtr, 
 			    Tcl_Filesystem **filesystemPtrPtr, 
 			    int *driveNameLengthPtr, Tcl_Obj **driveNameRef));
Index: generic/tclIOUtil.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIOUtil.c,v
retrieving revision 1.101
diff -b -u -r1.101 tclIOUtil.c
--- generic/tclIOUtil.c	23 Apr 2004 12:09:37 -0000	1.101
+++ generic/tclIOUtil.c	6 May 2004 19:15:50 -0000
@@ -3469,13 +3469,70 @@
                                          * the path, already with a
                                          * refCount for the caller.  */
 {
-    FilesystemRecord *fsRecPtr;
     int pathLen;
     char *path;
-    Tcl_PathType type = TCL_PATH_RELATIVE;
+    Tcl_PathType type;
     
     path = Tcl_GetStringFromObj(pathPtr, &pathLen);
 
+    type = TclFSNonnativePathType(path, pathLen, filesystemPtrPtr, 
+				  driveNameLengthPtr, driveNameRef);
+    
+    if (type != TCL_PATH_ABSOLUTE) {
+	type = TclpGetNativePathType(pathPtr, driveNameLengthPtr, 
+				     driveNameRef);
+	if ((type == TCL_PATH_ABSOLUTE) && (filesystemPtrPtr != NULL)) {
+	    *filesystemPtrPtr = &tclNativeFilesystem;
+	}
+    }
+    return type;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFSNonnativePathType --
+ *
+ *	Helper function used by TclGetPathType.  Its purpose is to
+ *	check whether the given path starts with a string which
+ *	corresponds to a file volume in any registered filesystem
+ *	except the native one.  For speed and historical reasons the
+ *	native filesystem has special hard-coded checks dotted here
+ *	and there in the filesystem code.
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE or TCL_PATH_RELATIVE.
+ *	The filesystem reference will be set if and only if it is
+ *	non-NULL and the function's return value is TCL_PATH_ABSOLUTE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+TclFSNonnativePathType(path, pathLen, filesystemPtrPtr, 
+		       driveNameLengthPtr, driveNameRef)
+    CONST char *path;                   /* Path to determine type for */
+    int pathLen;                        /* Length of the path */
+    Tcl_Filesystem **filesystemPtrPtr;  /* If absolute path and this is
+					 * non-NULL, then set to the
+					 * filesystem which claims this
+					 * path */  
+    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;
+    Tcl_PathType type = TCL_PATH_RELATIVE;
+
     /*
      * Call each of the "listVolumes" function in succession, checking
      * whether the given path is an absolute path on any of the volumes
@@ -3557,14 +3614,6 @@
 	}
 	fsRecPtr = fsRecPtr->nextPtr;
     }
-    
-    if (type != TCL_PATH_ABSOLUTE) {
-	type = TclpGetNativePathType(pathPtr, driveNameLengthPtr, 
-				     driveNameRef);
-	if ((type == TCL_PATH_ABSOLUTE) && (filesystemPtrPtr != NULL)) {
-	    *filesystemPtrPtr = &tclNativeFilesystem;
-	}
-    }
     return type;
 }
 
Index: tests/fileSystem.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/fileSystem.test,v
retrieving revision 1.40
diff -b -u -r1.40 fileSystem.test
--- tests/fileSystem.test	4 May 2004 22:31:10 -0000	1.40
+++ tests/fileSystem.test	6 May 2004 19:15:52 -0000
@@ -728,6 +728,57 @@
     set res
 } {simplefs:/simpledir/simplefile}
 
+test filesystem-7.3.1 {glob in simplefs: no path/dir} \
+  {testsimplefilesystem} {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    set res [glob -nocomplain simplefs:/simpledir/*]
+    eval lappend res [glob -nocomplain simplefs:/simpledir]
+    testsimplefilesystem 0
+    file delete -force simpledir
+    cd $dir
+    set res
+} {simplefs:/simpledir/simplefile simplefs:/simpledir}
+
+test filesystem-7.3.2 {glob in simplefs: no path/dir, no subdirectory} \
+  {testsimplefilesystem} {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    set res [glob -nocomplain simplefs:/s*]
+    testsimplefilesystem 0
+    file delete -force simpledir
+    cd $dir
+    if {[llength $res] > 0} {
+	set res "ok"
+    } else {
+        set res "no files found with 'glob -nocomplain simplefs:/s*'"
+    }
+} {ok}
+
+test filesystem-7.3.3 {glob in simplefs: pattern is a volume} \
+  {testsimplefilesystem} {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    set res [glob -nocomplain simplefs:/*]
+    testsimplefilesystem 0
+    file delete -force simpledir
+    cd $dir
+    if {[llength $res] > 0} {
+	set res "ok"
+    } else {
+	set res "no files found with 'glob -nocomplain simplefs:/*'"
+    }
+} {ok}
+
 test filesystem-7.4 {cross-filesystem file copy with -force} \
   {testsimplefilesystem} {
     set dir [pwd]