From 995406ac5bb7813c75343919fde68ba897545f06 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Fri, 23 Apr 2004 12:09:30 +0000 Subject: fix to two filesystem bugs: more consistent file separator proc and correct Tcl_FSJoinPath return values --- ChangeLog | 12 ++++++++++++ doc/FileSystem.3 | 13 ++++++++----- generic/tclIOUtil.c | 15 +++++++++++---- generic/tclPathObj.c | 12 ++++++++++-- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index a7dca74..a24aa50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-04-25 Vince Darley + + * generic/tclPathObj.c: fix to [Bug 940281]. Tcl_FSJoinPath + will now always return a valid Tcl_Obj when the input is valid. + * generic/tclIOUtil.c: fix to [Bug 931823] for a more consistent + Tcl_FSPathSeparator() implementation which allows filesystems + not to implement their Tcl_FSFilesystemSeparatorProc if they + wish to use the default '/'. Also fixed associated memory leak + seen with, e.g., tclvfs package. + * doc/FileSystem.3: documented Tcl_FSJoinPath return values + more clearly, and Tcl_FSFilesystemSeparatorProc requirements. + 2004-04-23 David Gravereaux * win/tclWin32Dll.c: Removed my mistake from 4/19 of adding an diff --git a/doc/FileSystem.3 b/doc/FileSystem.3 index e9d7fe7..74cdf01 100644 --- a/doc/FileSystem.3 +++ b/doc/FileSystem.3 @@ -4,7 +4,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: FileSystem.3,v 1.41 2004/04/16 17:33:32 vincentdarley Exp $ +'\" RCS: @(#) $Id: FileSystem.3,v 1.42 2004/04/23 12:09:37 vincentdarley Exp $ '\" .so man.macros .TH Filesystem 3 8.4 Tcl "Tcl Library Procedures" @@ -500,7 +500,7 @@ part of the path). The separator is returned as a Tcl_Obj containing a string of length 1. If the path is invalid, NULL is returned. .PP -\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which should be a valid +\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which must be a valid list (which is allowed to have a refCount of zero), and returns the path object given by considering the first 'elements' elements as valid path segments. If elements < 0, we use the entire list. @@ -510,6 +510,8 @@ under some conditions) , containing the joined path. The caller must add a refCount to the object before using it. In particular, the returned object could be an element of the given list, so freeing the list might free the object prematurely if no refCount has been taken. +If the number of elements is zero, then the returned object will be +an empty-string Tcl_Obj. .PP \fBTcl_FSSplitPath\fR takes the given Tcl_Obj, which should be a valid path, and returns a Tcl List object containing each segment of that path as @@ -944,9 +946,10 @@ typedef Tcl_Obj* Tcl_FSFilesystemPathTypeProc( .SH FILESYSTEMSEPARATORPROC .PP Function to return the separator character(s) for this filesystem. -Must be implemented, otherwise the \fBfile separator\fR command will not -function correctly. The usual return value will be a Tcl_Obj -containing the string "/". +This need only be implemented if the filesystem wishes to use a +different separator than the standard string "/". Amongst other +uses, it is returned by the \fBfile separator\fR command. The +return value should be an object with refCount of zero. .PP .CS typedef Tcl_Obj* Tcl_FSFilesystemSeparatorProc( diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 325f017..f526d40 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.100 2004/04/07 15:54:15 vincentdarley Exp $ + * RCS: @(#) $Id: tclIOUtil.c,v 1.101 2004/04/23 12:09:37 vincentdarley Exp $ */ #include "tclInt.h" @@ -3357,7 +3357,9 @@ Tcl_FSSplitPath(pathPtr, lenPtr) if (fsPtr->filesystemSeparatorProc != NULL) { Tcl_Obj *sep = (*fsPtr->filesystemSeparatorProc)(pathPtr); if (sep != NULL) { + Tcl_IncrRefCount(sep); separator = Tcl_GetString(sep)[0]; + Tcl_DecrRefCount(sep); } } @@ -4261,7 +4263,8 @@ Tcl_FSFileSystemInfo(pathPtr) * Results: * A Tcl object, with a refCount of zero. If the caller * needs to retain a reference to the object, it should - * call Tcl_IncrRefCount. + * call Tcl_IncrRefCount, and should otherwise free the + * object. * * Side effects: * The path object may be converted to a path type. @@ -4279,9 +4282,13 @@ Tcl_FSPathSeparator(pathPtr) } if (fsPtr->filesystemSeparatorProc != NULL) { return (*fsPtr->filesystemSeparatorProc)(pathPtr); + } else { + /* + * Allow filesystems not to provide a filesystemSeparatorProc + * if they wish to use the standard forward slash. + */ + return Tcl_NewStringObj("/", 1); } - - return NULL; } /* diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index daa9297..bcb1500 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -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: tclPathObj.c,v 1.29 2004/04/06 22:25:54 dgp Exp $ + * RCS: @(#) $Id: tclPathObj.c,v 1.30 2004/04/23 12:09:37 vincentdarley Exp $ */ #include "tclInt.h" @@ -672,7 +672,12 @@ GetExtension(pathPtr) * Results: * Returns object with refCount of zero, (or if non-zero, it has * references elsewhere in Tcl). Either way, the caller must - * increment its refCount before use. + * increment its refCount before use. Note that in the case where + * the caller has asked to join zero elements of the list, the + * return value will be an empty-string Tcl_Obj. + * + * If the given listObj was invalid, then the calling routine has + * a bug, and this function will just return NULL. * * Side effects: * None. @@ -918,6 +923,9 @@ Tcl_FSJoinPath(listObj, elements) Tcl_SetObjLength(res, length); } } + if (res == NULL) { + res = Tcl_NewObj(); + } return res; } -- cgit v0.12