Tk
view release on metacpan or search on metacpan
pTk/mTk/tclGeneric/tclIOUtil.c view on Meta::CPAN
/*
* Modify the list of entries in place, by removing '.', and
* removing '..' and the entry before -- unless that entry before
* is the top-level entry, i.e. the name of a volume.
*/
nplen = 0;
for (i = 0; i < splen; i++) {
Tcl_ListObjIndex(NULL, split, nplen, &elt);
eltName = Tcl_GetStringFromObj(elt, &eltLen);
if ((eltLen == 1) && (eltName[0] == '.')) {
Tcl_ListObjReplace(NULL, split, nplen, 1, 0, NULL);
} else if ((eltLen == 2)
&& (eltName[0] == '.') && (eltName[1] == '.')) {
if (nplen > 1) {
nplen--;
Tcl_ListObjReplace(NULL, split, nplen, 2, 0, NULL);
} else {
Tcl_ListObjReplace(NULL, split, nplen, 1, 0, NULL);
}
} else {
nplen++;
}
}
if (nplen > 0) {
ClientData clientData = NULL;
retVal = Tcl_FSJoinPath(split, nplen);
/*
* Now we have an absolute path, with no '..', '.' sequences,
* but it still may not be in 'unique' form, depending on the
* platform. For instance, Unix is case-sensitive, so the
* path is ok. Windows is case-insensitive, and also has the
* weird 'longname/shortname' thing (e.g. C:/Program Files/ and
* C:/Progra~1/ are equivalent). MacOS is case-insensitive.
*
* Virtual file systems which may be registered may have
* other criteria for normalizing a path.
*/
Tcl_IncrRefCount(retVal);
TclFSNormalizeToUniquePath(interp, retVal, 0, &clientData);
/*
* Since we know it is a normalized path, we can
* actually convert this object into an "path" object for
* greater efficiency
*/
TclFSMakePathFromNormalized(interp, retVal, clientData);
if (clientDataPtr != NULL) {
*clientDataPtr = clientData;
}
} else {
/* Init to an empty string */
retVal = Tcl_NewStringObj("",0);
Tcl_IncrRefCount(retVal);
}
/*
* We increment and then decrement the refCount of split to free
* it. We do this right at the end, in case there are
* optimisations in Tcl_FSJoinPath(split, nplen) above which would
* let it make use of split more effectively if it has a refCount
* of zero. Also we can't just decrement the ref count, in case
* 'split' was actually returned by the join call above, in a
* single-element optimisation when nplen == 1.
*/
Tcl_IncrRefCount(split);
Tcl_DecrRefCount(split);
/* This has a refCount of 1 for the caller */
return retVal;
}
/*
*---------------------------------------------------------------------------
*
* TclFSNormalizeToUniquePath --
*
* Description:
* Takes a path specification containing no ../, ./ sequences,
* and converts it into a unique path for the given platform.
* On MacOS, Unix, this means the path must be free of
* symbolic links/aliases, and on Windows it means we want the
* long form, with that long form's case-dependence (which gives
* us a unique, case-dependent path).
*
* Results:
* The pathPtr is modified in place. The return value is
* the last byte offset which was recognised in the path
* string.
*
* Side effects:
* None (beyond the memory allocation for the result).
*
* Special notes:
* If the filesystem-specific normalizePathProcs can re-introduce
* ../, ./ sequences into the path, then this function will
* not return the correct result. This may be possible with
* symbolic links on unix/macos.
*
* Important assumption: if startAt is non-zero, it must point
* to a directory separator that we know exists and is already
* normalized (so it is important not to point to the char just
* after the separator).
*---------------------------------------------------------------------------
*/
int
TclFSNormalizeToUniquePath(interp, pathPtr, startAt, clientDataPtr)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
int startAt;
ClientData *clientDataPtr;
{
FilesystemRecord *fsRecPtr, *firstFsRecPtr;
/* Ignore this variable */
(void)clientDataPtr;
/*
* Call each of the "normalise path" functions in succession. This is
* a special case, in which if we have a native filesystem handler,
* we call it first. This is because the root of Tcl's filesystem
* is always a native filesystem (i.e. '/' on unix is native).
( run in 1.396 second using v1.01-cache-2.11-cpan-71847e10f99 )