summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2017-07-06 16:40:38 (GMT)
committerdgp <dgp@users.sourceforge.net>2017-07-06 16:40:38 (GMT)
commit651416ffcce971c426fc6d5b1a93e661f1e368c6 (patch)
tree2c51bc5a9174bdfbc7bfd0e1fa187c33ea868e0a /generic
parentc539c9c1cd9d62fc00b344cf920877725f32dd5c (diff)
parentdaaac6f4c23110b1489e943f514c4b8befc14b2d (diff)
downloadtcl-651416ffcce971c426fc6d5b1a93e661f1e368c6.zip
tcl-651416ffcce971c426fc6d5b1a93e661f1e368c6.tar.gz
tcl-651416ffcce971c426fc6d5b1a93e661f1e368c6.tar.bz2
merge 8.6
Diffstat (limited to 'generic')
-rw-r--r--generic/tclPathObj.c82
1 files changed, 43 insertions, 39 deletions
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c
index 211976e..49d62dc 100644
--- a/generic/tclPathObj.c
+++ b/generic/tclPathObj.c
@@ -13,6 +13,7 @@
#include "tclInt.h"
#include "tclFileSystem.h"
+#include <assert.h>
/*
* Prototypes for functions defined later in this file.
@@ -849,18 +850,20 @@ TclJoinPath(
int elements,
Tcl_Obj * const objv[])
{
- Tcl_Obj *res = NULL; /* Resulting path object (container of join) */
- Tcl_Obj *elt; /* Path part (result if returns part of path) */
+ Tcl_Obj *res = NULL;
int i;
const Tcl_Filesystem *fsPtr = NULL;
- for (i = 0; i < elements; i++) {
- int driveNameLength, strEltLen, length;
- Tcl_PathType type;
- char *strElt, *ptr;
- Tcl_Obj *driveName = NULL;
-
- elt = objv[i];
+ assert ( elements >= 0 );
+
+ if (elements == 0) {
+ return Tcl_NewObj();
+ }
+
+ assert ( elements > 0 );
+
+ if (elements == 2) {
+ Tcl_Obj *elt = objv[0];
/*
* This is a special case where we can be much more efficient, where
@@ -869,18 +872,17 @@ TclJoinPath(
* object which can be normalized more efficiently. Currently we only
* use the special case when we have exactly two elements, but we
* could expand that in the future.
- *
- * Bugfix [a47641a0]. TclNewFSPathObj requires first argument
- * to be an absolute path. Added a check for that elt is absolute.
+ *
+ * Bugfix [a47641a0]. TclNewFSPathObj requires first argument
+ * to be an absolute path. Added a check for that elt is absolute.
*/
- if ((i == (elements-2)) && (i == 0)
- && (elt->typePtr == &tclFsPathType)
+ if ((elt->typePtr == &tclFsPathType)
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
- Tcl_Obj *tailObj = objv[i+1];
+ Tcl_Obj *tailObj = objv[1];
+ Tcl_PathType type = TclGetPathType(tailObj, NULL, NULL, NULL);
- type = TclGetPathType(tailObj, NULL, NULL, NULL);
if (type == TCL_PATH_RELATIVE) {
const char *str;
int len;
@@ -893,7 +895,7 @@ TclJoinPath(
* the base itself is just fine!
*/
- goto partReturn; /* return elt; */
+ return elt;
}
/*
@@ -914,20 +916,17 @@ TclJoinPath(
*/
if ((tclPlatform != TCL_PLATFORM_WINDOWS)
- || (strchr(Tcl_GetString(elt), '\\') == NULL)
- ) {
+ || (strchr(Tcl_GetString(elt), '\\') == NULL)) {
+
if (PATHFLAGS(elt)) {
- elt = TclNewFSPathObj(elt, str, len);
- goto partReturn; /* return elt; */
+ return TclNewFSPathObj(elt, str, len);
}
if (TCL_PATH_ABSOLUTE != Tcl_FSGetPathType(elt)) {
- elt = TclNewFSPathObj(elt, str, len);
- goto partReturn; /* return elt; */
+ return TclNewFSPathObj(elt, str, len);
}
(void) Tcl_FSGetNormalizedPath(NULL, elt);
if (elt == PATHOBJ(elt)->normPathPtr) {
- elt = TclNewFSPathObj(elt, str, len);
- goto partReturn; /* return elt; */
+ return TclNewFSPathObj(elt, str, len);
}
}
}
@@ -937,19 +936,28 @@ TclJoinPath(
* more general code below handle things.
*/
} else if (tclPlatform == TCL_PLATFORM_UNIX) {
- elt = tailObj;
- goto partReturn; /* return elt; */
+ return tailObj;
} else {
const char *str = TclGetString(tailObj);
if (tclPlatform == TCL_PLATFORM_WINDOWS) {
if (strchr(str, '\\') == NULL) {
- elt = tailObj;
- goto partReturn; /* return elt; */
+ return tailObj;
}
}
}
}
+ }
+
+ assert ( res == NULL );
+
+ for (i = 0; i < elements; i++) {
+ int driveNameLength, strEltLen, length;
+ Tcl_PathType type;
+ char *strElt, *ptr;
+ Tcl_Obj *driveName = NULL;
+ Tcl_Obj *elt = objv[i];
+
strElt = TclGetStringFromObj(elt, &strEltLen);
driveNameLength = 0;
type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
@@ -1024,12 +1032,16 @@ TclJoinPath(
}
ptr++;
}
+ if (res != NULL) {
+ TclDecrRefCount(res);
+ }
+
/*
* This element is just what we want to return already; no further
* manipulation is requred.
*/
- goto partReturn; /* return elt; */
+ return elt;
}
/*
@@ -1110,16 +1122,8 @@ TclJoinPath(
Tcl_SetObjLength(res, length);
}
}
- if (res == NULL) {
- res = Tcl_NewObj();
- }
+ assert ( res != NULL );
return res;
-
-partReturn:
- if (res != NULL) {
- TclDecrRefCount(res);
- }
- return elt;
}
/*