diff options
author | vincentdarley <vincentdarley> | 2004-03-30 15:35:45 (GMT) |
---|---|---|
committer | vincentdarley <vincentdarley> | 2004-03-30 15:35:45 (GMT) |
commit | 5b3cf09d56c6bccfa2d2d4ffcedab7afa9738188 (patch) | |
tree | e1181b1465473c4ac32033533ed4cf3cfec67c39 /generic/tclFileName.c | |
parent | e7a7c5a2234e5cee662915660923c347b6a5d07d (diff) | |
download | tcl-5b3cf09d56c6bccfa2d2d4ffcedab7afa9738188.zip tcl-5b3cf09d56c6bccfa2d2d4ffcedab7afa9738188.tar.gz tcl-5b3cf09d56c6bccfa2d2d4ffcedab7afa9738188.tar.bz2 |
fix to glob with volume relative paths, bug 898238
Diffstat (limited to 'generic/tclFileName.c')
-rw-r--r-- | generic/tclFileName.c | 52 |
1 files changed, 50 insertions, 2 deletions
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 |