Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 3479689 New internal routine TclJoinPath(). Refactor all the *Join*Path* routines to give them more useful interfaces that are easier to manage getting the refcounts right. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
55c8c6c1552f0cd51a3b76c0ca7a6ddf |
User & Date: | dgp 2012-01-27 21:56:52 |
References
2023-07-25
| ||
20:57 | • New ticket [a97680cbed] Tcl_FSJoinToPath(): outdated comment. artifact: 8cadf12d2f user: chrstphrchvz | |
Context
2012-01-30
| ||
15:43 |
* generic/tclCompCmds.c (TclCompileCatchCmd): Added a more efficient bytecode generator for the ca...check-in: c7bbf49644 user: dkf tags: trunk | |
2012-01-27
| ||
21:56 | 3479689 New internal routine TclJoinPath(). Refactor all the *Join*Path* routines to give them more... check-in: 55c8c6c155 user: dgp tags: trunk | |
18:44 | 3480599 Make [source] and [load] order of multi-file package happen in sorted order of the file name... check-in: d17bc3040a user: dgp tags: trunk | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2012-01-26 Don Porter <[email protected]> * generic/tclPathObj.c: [Bug 3475569]: Add checks for unshared values before calls demanding them. [Bug 3479689]: Stop memory corruption when shimmering 0-refCount value to "path" type. 2012-01-25 Donal K. Fellows <[email protected]> | > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 2012-01-26 Don Porter <[email protected]> * generic/tclCmdAH.c: New internal routine TclJoinPath(). * generic/tclFCmd.c: Refactor all the *Join*Path* routines * generic/tclFileName.c: to give them more useful interfaces * generic/tclInt.h: that are easier to manage getting the * generic/tclPathObj.c: refcounts right. [Bug 3479689] 2012-01-26 Don Porter <[email protected]> * generic/tclPathObj.c: [Bug 3475569]: Add checks for unshared values before calls demanding them. [Bug 3479689]: Stop memory corruption when shimmering 0-refCount value to "path" type. 2012-01-25 Donal K. Fellows <[email protected]> |
︙ | ︙ |
Changes to generic/tclCmdAH.c.
︙ | ︙ | |||
1837 1838 1839 1840 1841 1842 1843 | int objc, Tcl_Obj *const objv[]) { if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?"); return TCL_ERROR; } | | | 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 | int objc, Tcl_Obj *const objv[]) { if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?"); return TCL_ERROR; } Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1)); return TCL_OK; } /* *---------------------------------------------------------------------- * * PathNativeNameCmd -- |
︙ | ︙ |
Changes to generic/tclFCmd.c.
︙ | ︙ | |||
173 174 175 176 177 178 179 | * Move each source file into target directory. Extract the basename from * each source, and append it to the end of the target path. */ for ( ; i<objc-1 ; i++) { Tcl_Obj *jargv[2]; Tcl_Obj *source, *newFileName; | < < | < | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | * Move each source file into target directory. Extract the basename from * each source, and append it to the end of the target path. */ for ( ; i<objc-1 ; i++) { Tcl_Obj *jargv[2]; Tcl_Obj *source, *newFileName; source = FileBasename(interp, objv[i]); if (source == NULL) { result = TCL_ERROR; break; } jargv[0] = objv[objc - 1]; jargv[1] = source; newFileName = TclJoinPath(2, jargv); Tcl_IncrRefCount(newFileName); result = CopyRenameOneFile(interp, objv[i], newFileName, copyFlag, force); Tcl_DecrRefCount(newFileName); Tcl_DecrRefCount(source); if (result == TCL_ERROR) { break; } } return result; |
︙ | ︙ |
Changes to generic/tclFileName.c.
︙ | ︙ | |||
783 784 785 786 787 788 789 | Tcl_Obj * Tcl_FSJoinToPath( Tcl_Obj *pathPtr, /* Valid path or NULL. */ int objc, /* Number of array elements to join */ Tcl_Obj *const objv[]) /* Path elements to join. */ { | < < < | < < > > | | | | > > | | > | < < < < < < > | | | | > | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 | Tcl_Obj * Tcl_FSJoinToPath( Tcl_Obj *pathPtr, /* Valid path or NULL. */ int objc, /* Number of array elements to join */ Tcl_Obj *const objv[]) /* Path elements to join. */ { if (pathPtr == NULL) { return TclJoinPath(objc, objv); } if (objc == 0) { return TclJoinPath(1, &pathPtr); } if (objc == 1) { Tcl_Obj *pair[2]; pair[0] = pathPtr; pair[1] = objv[0]; return TclJoinPath(2, pair); } else { int elemc = objc + 1; Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj **)); elemv[0] = pathPtr; memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj **)); ret = TclJoinPath(elemc, elemv); ckfree(elemv); return ret; } } /* *--------------------------------------------------------------------------- * * TclpNativeJoinPath -- * |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 | MODULE_SCOPE void TclInitNamespaceSubsystem(void); MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, int indexCount, Tcl_Obj *const indexArray[]); /* TIP #280 */ | > | 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 | MODULE_SCOPE void TclInitNamespaceSubsystem(void); MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, int indexCount, Tcl_Obj *const indexArray[]); /* TIP #280 */ |
︙ | ︙ |
Changes to generic/tclPathObj.c.
︙ | ︙ | |||
834 835 836 837 838 839 840 | Tcl_Obj * Tcl_FSJoinPath( Tcl_Obj *listObj, /* Path elements to join, may have a zero * reference count. */ int elements) /* Number of elements to use (-1 = all) */ { | | | | < | | | < < < < < | > | > > | | < < > > | < > | | | > | < < < | | | < | 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 | Tcl_Obj * Tcl_FSJoinPath( Tcl_Obj *listObj, /* Path elements to join, may have a zero * reference count. */ int elements) /* Number of elements to use (-1 = all) */ { Tcl_Obj *copy, *res; int objc; Tcl_Obj **objv; if (Tcl_ListObjLength(NULL, listObj, &objc) != TCL_OK) { return NULL; } elements = ((elements >= 0) && (elements <= objc)) ? elements : objc; copy = TclListObjCopy(NULL, listObj); Tcl_ListObjGetElements(NULL, listObj, &objc, &objv); res = TclJoinPath(elements, objv); Tcl_DecrRefCount(copy); return res; } Tcl_Obj * TclJoinPath( int elements, Tcl_Obj * const objv[]) { Tcl_Obj *res; int i; const Tcl_Filesystem *fsPtr = NULL; 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]; /* * This is a special case where we can be much more efficient, where * we are joining a single relative path onto an object that is * already of path type. The 'TclNewFSPathObj' call below creates an * 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. */ if ((i == (elements-2)) && (i == 0) && (elt->typePtr == &tclFsPathType) && !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))) { Tcl_Obj *tailObj = objv[i+1]; type = TclGetPathType(tailObj, NULL, NULL, NULL); if (type == TCL_PATH_RELATIVE) { const char *str; int len; str = Tcl_GetStringFromObj(tailObj, &len); if (len == 0) { |
︙ | ︙ | |||
1385 1386 1387 1388 1389 1390 1391 | /* * This is likely buggy when dealing with virtual filesystem drivers * that use some character other than "/" as a path separator. I know * of no evidence that such a foolish thing exists. This solution was * chosen so that "JoinPath" operations that pass through either path * intrep produce the same results; that is, bugward compatibility. If | | | 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 | /* * This is likely buggy when dealing with virtual filesystem drivers * that use some character other than "/" as a path separator. I know * of no evidence that such a foolish thing exists. This solution was * chosen so that "JoinPath" operations that pass through either path * intrep produce the same results; that is, bugward compatibility. If * we need to fix that bug here, it needs fixing in TclJoinPath() too. */ bytes = Tcl_GetStringFromObj(tail, &numBytes); if (numBytes == 0) { Tcl_AppendToObj(copy, "/", 1); } else { TclpNativeJoinPath(copy, bytes); } |
︙ | ︙ | |||
2495 2496 2497 2498 2499 2500 2501 | joined = Tcl_FSJoinToPath(transPtr, 1, &rest); TclDecrRefCount(transPtr); transPtr = joined; } } Tcl_DStringFree(&temp); } else { | < < | < | 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 | joined = Tcl_FSJoinToPath(transPtr, 1, &rest); TclDecrRefCount(transPtr); transPtr = joined; } } Tcl_DStringFree(&temp); } else { transPtr = TclJoinPath(1, &pathPtr); } #if defined(__CYGWIN__) && defined(__WIN32__) { char winbuf[MAX_PATH+1]; /* |
︙ | ︙ |