summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--generic/tclIOUtil.c170
2 files changed, 99 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index 01c151a..b1f87d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,15 @@
2003-02-11 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIOUtil.c (Tcl_FSJoinPath, Tcl_FSGetNormalizedPath):
+ (UpdateStringOfFsPath): revert the cwdLen == 0 check and instead
+ follow a different code path in Tcl_FSJoinPath.
+ (Tcl_FSConvertToPathType, Tcl_FSGetNormalizedPath):
+ (Tcl_FSGetFileSystemForPath): Update string rep path objects
+ before freeing the internal object. (darley)
+
* tests/fileSystem.test: added test 8.3
* generic/tclIOUtil.c (Tcl_FSGetNormalizedPath):
- (Tcl_FSMatchInDirectory): handle the cwdLen == 0 case
+ (UpdateStringOfFsPath): handle the cwdLen == 0 case
* unix/tclUnixFile.c (TclpMatchInDirectory): simplify the hidden
file match check.
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index fd7aab3..da92683 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.74 2003/02/11 09:42:15 hobbs Exp $
+ * RCS: @(#) $Id: tclIOUtil.c,v 1.75 2003/02/11 11:07:04 hobbs Exp $
*/
#include "tclInt.h"
@@ -3233,7 +3233,8 @@ Tcl_FSJoinPath(listObj, elements)
* efficiency benefit elsewhere in the code (from re-using the
* normalized representation of the base object).
*/
- if (base->typePtr == &tclFsPathType) {
+ if (base->typePtr == &tclFsPathType
+ && !(base->bytes != NULL && base->bytes[0] == '\0')) {
Tcl_Obj *tail;
Tcl_PathType type;
Tcl_ListObjIndex(NULL, listObj, 1, &tail);
@@ -3855,12 +3856,19 @@ Tcl_FSConvertToPathType(interp, objPtr)
return Tcl_ConvertToType(interp, objPtr, &tclFsPathType);
}
return TCL_OK;
+ /*
+ * This code is intentionally never reached. Once fs-optimisation
+ * is complete, it will be removed/replaced
+ */
if (fsPathPtr->cwdPtr == NULL) {
return TCL_OK;
} else {
if (FsCwdPointerEquals(fsPathPtr->cwdPtr)) {
return TCL_OK;
} else {
+ if (objPtr->bytes == NULL) {
+ UpdateStringOfFsPath(objPtr);
+ }
FreeFsPathInternalRep(objPtr);
objPtr->typePtr = NULL;
return Tcl_ConvertToType(interp, objPtr, &tclFsPathType);
@@ -3942,38 +3950,36 @@ UpdateStringOfFsPath(objPtr)
/*
* Should we perhaps use 'Tcl_FSPathSeparator'?
* But then what about the Windows special case?
- * Perhaps we should just check if cwd is a root
- * volume.
+ * Perhaps we should just check if cwd is a root volume.
+ * We should never get cwdLen == 0 in this code path.
*/
- if (cwdLen) {
- switch (tclPlatform) {
- case TCL_PLATFORM_UNIX:
- if (cwdStr[cwdLen-1] != '/') {
+ switch (tclPlatform) {
+ case TCL_PLATFORM_UNIX:
+ if (cwdStr[cwdLen-1] != '/') {
+ Tcl_AppendToObj(copy, "/", 1);
+ cwdLen++;
+ }
+ break;
+ case TCL_PLATFORM_WINDOWS:
+ /*
+ * We need the extra 'cwdLen != 2', and ':' checks because
+ * a volume relative path doesn't get a '/'. For example
+ * 'glob C:*cat*.exe' will return 'C:cat32.exe'
+ */
+ if (cwdStr[cwdLen-1] != '/'
+ && cwdStr[cwdLen-1] != '\\') {
+ if (cwdLen != 2 || cwdStr[1] != ':') {
Tcl_AppendToObj(copy, "/", 1);
cwdLen++;
}
- break;
- case TCL_PLATFORM_WINDOWS:
- /*
- * We need the extra 'cwdLen != 2', and ':' checks because
- * a volume relative path doesn't get a '/'. For example
- * 'glob C:*cat*.exe' will return 'C:cat32.exe'
- */
- if (cwdStr[cwdLen-1] != '/'
- && cwdStr[cwdLen-1] != '\\') {
- if (cwdLen != 2 || cwdStr[1] != ':') {
- Tcl_AppendToObj(copy, "/", 1);
- cwdLen++;
- }
- }
- break;
- case TCL_PLATFORM_MAC:
- if (cwdStr[cwdLen-1] != ':') {
- Tcl_AppendToObj(copy, ":", 1);
- cwdLen++;
- }
- break;
- }
+ }
+ break;
+ case TCL_PLATFORM_MAC:
+ if (cwdStr[cwdLen-1] != ':') {
+ Tcl_AppendToObj(copy, ":", 1);
+ cwdLen++;
+ }
+ break;
}
Tcl_AppendObjToObj(copy, fsPathPtr->normPathPtr);
objPtr->bytes = Tcl_GetStringFromObj(copy, &cwdLen);
@@ -4625,8 +4631,11 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr)
}
fsPathPtr = (FsPath*) pathObjPtr->internalRep.otherValuePtr;
- /* Ensure cwd hasn't changed */
if (fsPathPtr->flags != 0) {
+ /*
+ * This is a special path object which is the result of
+ * something like 'file join'
+ */
Tcl_Obj *dir, *copy;
int cwdLen;
int pathType;
@@ -4649,31 +4658,29 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr)
/*
* Should we perhaps use 'Tcl_FSPathSeparator'?
* But then what about the Windows special case?
- * Perhaps we should just check if cwd is a root
- * volume.
+ * Perhaps we should just check if cwd is a root volume.
+ * We should never get cwdLen == 0 in this code path.
*/
- if (cwdLen) {
- switch (tclPlatform) {
- case TCL_PLATFORM_UNIX:
- if (cwdStr[cwdLen-1] != '/') {
- Tcl_AppendToObj(copy, "/", 1);
- cwdLen++;
- }
- break;
- case TCL_PLATFORM_WINDOWS:
- if (cwdStr[cwdLen-1] != '/'
- && cwdStr[cwdLen-1] != '\\') {
- Tcl_AppendToObj(copy, "/", 1);
- cwdLen++;
- }
- break;
- case TCL_PLATFORM_MAC:
- if (cwdStr[cwdLen-1] != ':') {
- Tcl_AppendToObj(copy, ":", 1);
- cwdLen++;
- }
- break;
- }
+ switch (tclPlatform) {
+ case TCL_PLATFORM_UNIX:
+ if (cwdStr[cwdLen-1] != '/') {
+ Tcl_AppendToObj(copy, "/", 1);
+ cwdLen++;
+ }
+ break;
+ case TCL_PLATFORM_WINDOWS:
+ if (cwdStr[cwdLen-1] != '/'
+ && cwdStr[cwdLen-1] != '\\') {
+ Tcl_AppendToObj(copy, "/", 1);
+ cwdLen++;
+ }
+ break;
+ case TCL_PLATFORM_MAC:
+ if (cwdStr[cwdLen-1] != ':') {
+ Tcl_AppendToObj(copy, ":", 1);
+ cwdLen++;
+ }
+ break;
}
Tcl_AppendObjToObj(copy, fsPathPtr->normPathPtr);
/*
@@ -4710,8 +4717,12 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr)
}
fsPathPtr->flags = 0;
}
+ /* Ensure cwd hasn't changed */
if (fsPathPtr->cwdPtr != NULL) {
if (!FsCwdPointerEquals(fsPathPtr->cwdPtr)) {
+ if (pathObjPtr->bytes == NULL) {
+ UpdateStringOfFsPath(pathObjPtr);
+ }
FreeFsPathInternalRep(pathObjPtr);
pathObjPtr->typePtr = NULL;
if (Tcl_ConvertToType(interp, pathObjPtr,
@@ -4730,31 +4741,29 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr)
/*
* Should we perhaps use 'Tcl_FSPathSeparator'?
* But then what about the Windows special case?
- * Perhaps we should just check if cwd is a root
- * volume.
+ * Perhaps we should just check if cwd is a root volume.
+ * We should never get cwdLen == 0 in this code path.
*/
- if (cwdLen) {
- switch (tclPlatform) {
- case TCL_PLATFORM_UNIX:
- if (cwdStr[cwdLen-1] != '/') {
- Tcl_AppendToObj(copy, "/", 1);
- cwdLen++;
- }
- break;
- case TCL_PLATFORM_WINDOWS:
- if (cwdStr[cwdLen-1] != '/'
- && cwdStr[cwdLen-1] != '\\') {
- Tcl_AppendToObj(copy, "/", 1);
- cwdLen++;
- }
- break;
- case TCL_PLATFORM_MAC:
- if (cwdStr[cwdLen-1] != ':') {
- Tcl_AppendToObj(copy, ":", 1);
- cwdLen++;
- }
- break;
- }
+ switch (tclPlatform) {
+ case TCL_PLATFORM_UNIX:
+ if (cwdStr[cwdLen-1] != '/') {
+ Tcl_AppendToObj(copy, "/", 1);
+ cwdLen++;
+ }
+ break;
+ case TCL_PLATFORM_WINDOWS:
+ if (cwdStr[cwdLen-1] != '/'
+ && cwdStr[cwdLen-1] != '\\') {
+ Tcl_AppendToObj(copy, "/", 1);
+ cwdLen++;
+ }
+ break;
+ case TCL_PLATFORM_MAC:
+ if (cwdStr[cwdLen-1] != ':') {
+ Tcl_AppendToObj(copy, ":", 1);
+ cwdLen++;
+ }
+ break;
}
Tcl_AppendObjToObj(copy, pathObjPtr);
/*
@@ -5360,6 +5369,9 @@ Tcl_FSGetFileSystemForPath(pathObjPtr)
* We have to discard the stale representation and
* recalculate it
*/
+ if (pathObjPtr->bytes == NULL) {
+ UpdateStringOfFsPath(pathObjPtr);
+ }
FreeFsPathInternalRep(pathObjPtr);
pathObjPtr->typePtr = NULL;
if (SetFsPathFromAny(NULL, pathObjPtr) != TCL_OK) {