Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Define and use macros that test whether a Tcl list value is canonical. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-5-branch |
Files: | files | file ages | folders |
SHA1: |
13ac6c8c7b55fc9a2bdfb05efdca8545 |
User & Date: | dgp 2011-04-18 18:31:18 |
Context
2011-04-18
| ||
21:24 | Use ListRepPtr(.) and other cleanup. check-in: 3dba2563a1 user: dgp tags: core-8-5-branch | |
18:50 | Define and use macros that test whether a Tcl list value is canonical. check-in: 4b0bb72cb3 user: dgp tags: trunk | |
18:31 | Define and use macros that test whether a Tcl list value is canonical. check-in: 13ac6c8c7b user: dgp tags: core-8-5-branch | |
08:22 | fix for [Bug 3288345]: Wrong Tcl_StatBuf used on MinGW check-in: 4f729efe4c user: jan.nijtmans tags: core-8-5-branch | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2011-04-18 Jan Nijtmans <[email protected]> * generic/tcl.h: fix for [Bug 3288345]: Wrong Tcl_StatBuf used on MinGW. 2011-04-16 Donal K. Fellows <[email protected]> | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | 2011-04-18 Don Porter <[email protected]> * generic/tclInt.h: Define and use macros that test whether * generic/tclBasic.c: a Tcl list value is canonical. * generic/tclUtil.c: 2011-04-18 Jan Nijtmans <[email protected]> * generic/tcl.h: fix for [Bug 3288345]: Wrong Tcl_StatBuf used on MinGW. 2011-04-16 Donal K. Fellows <[email protected]> |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
4896 4897 4898 4899 4900 4901 4902 | /* * An object which either has no string rep or else is a canonical list is * guaranteed to have been generated dynamically: bail out, this cannot * have a usable absolute location. _Do not touch_ the information the set * up by the caller. It knows better than us. */ | | < | 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 | /* * An object which either has no string rep or else is a canonical list is * guaranteed to have been generated dynamically: bail out, this cannot * have a usable absolute location. _Do not touch_ the information the set * up by the caller. It knows better than us. */ if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) { return; } /* * First look for location information recorded in the argument * stack. That is nearest. */ |
︙ | ︙ | |||
5079 5080 5081 5082 5083 5084 5085 | * * This restriction has been relaxed a bit by storing in lists whether * they are "canonical" or not (a canonical list being one that is either * pure or that has its string rep derived by UpdateStringOfList from the * internal rep). */ | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | < | | | | < < < < < | | 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 | * * This restriction has been relaxed a bit by storing in lists whether * they are "canonical" or not (a canonical list being one that is either * pure or that has its string rep derived by UpdateStringOfList from the * internal rep). */ if (TclListObjIsCanonical(objPtr)) { /* * TIP #280 Structures for tracking lines. As we know that this is * dynamic execution we ignore the invoker, even if known. */ int nelements; Tcl_Obj **elements, *copyPtr = TclListObjCopy(NULL, objPtr); CmdFrame *eoFramePtr = (CmdFrame *) TclStackAlloc(interp, sizeof(CmdFrame)); eoFramePtr->type = TCL_LOCATION_EVAL_LIST; eoFramePtr->level = (iPtr->cmdFramePtr == NULL? 1 : iPtr->cmdFramePtr->level + 1); eoFramePtr->framePtr = iPtr->framePtr; eoFramePtr->nextPtr = iPtr->cmdFramePtr; eoFramePtr->nline = 0; eoFramePtr->line = NULL; eoFramePtr->cmd.listPtr = objPtr; Tcl_IncrRefCount(eoFramePtr->cmd.listPtr); eoFramePtr->data.eval.path = NULL; /* * TIP #280 We do _not_ compute all the line numbers for the words * in the command. For the eval of a pure list the most sensible * choice is to put all words on line 1. Given that we neither * need memory for them nor compute anything. 'line' is left * NULL. The two places using this information (TclInfoFrame, and * TclInitCompileEnv), are special-cased to use the proper line * number directly instead of accessing the 'line' array. */ Tcl_ListObjGetElements(NULL, copyPtr, &nelements, &elements); iPtr->cmdFramePtr = eoFramePtr; result = Tcl_EvalObjv(interp, nelements, elements, flags); Tcl_DecrRefCount(copyPtr); iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr; Tcl_DecrRefCount(eoFramePtr->cmd.listPtr); TclStackFree(interp, eoFramePtr); } else if (flags & TCL_EVAL_DIRECT) { /* * We're not supposed to use the compiler or byte-code interpreter. * Let Tcl_EvalEx evaluate the command directly (and probably more * slowly). */ /* |
︙ | ︙ | |||
5293 5294 5295 5296 5297 5298 5299 | Tcl_LogCommandInfo(interp, script, script, numSrcBytes); } } iPtr->evalFlags = 0; iPtr->varFramePtr = savedVarFramePtr; } | < | 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 | Tcl_LogCommandInfo(interp, script, script, numSrcBytes); } } iPtr->evalFlags = 0; iPtr->varFramePtr = savedVarFramePtr; } TclDecrRefCount(objPtr); return result; } /* *---------------------------------------------------------------------- * |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 | #define ListObjGetElements(listPtr, objc, objv) \ ((objv) = &(ListRepPtr(listPtr)->elements), \ (objc) = ListRepPtr(listPtr)->elemCount) #define ListObjLength(listPtr, len) \ ((len) = ListRepPtr(listPtr)->elemCount) #define TclListObjGetElements(interp, listPtr, objcPtr, objvPtr) \ (((listPtr)->typePtr == &tclListType) \ ? ((ListObjGetElements((listPtr), *(objcPtr), *(objvPtr))), TCL_OK)\ : Tcl_ListObjGetElements((interp), (listPtr), (objcPtr), (objvPtr))) #define TclListObjLength(interp, listPtr, lenPtr) \ (((listPtr)->typePtr == &tclListType) \ ? ((ListObjLength((listPtr), *(lenPtr))), TCL_OK)\ : Tcl_ListObjLength((interp), (listPtr), (lenPtr))) /* * Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere, * Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints. * * WARNING: these macros eval their args more than once. */ | > > > > > > | 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 | #define ListObjGetElements(listPtr, objc, objv) \ ((objv) = &(ListRepPtr(listPtr)->elements), \ (objc) = ListRepPtr(listPtr)->elemCount) #define ListObjLength(listPtr, len) \ ((len) = ListRepPtr(listPtr)->elemCount) #define ListObjIsCanonical(listPtr) \ (((listPtr)->bytes == NULL) || ListRepPtr(listPtr)->canonicalFlag) #define TclListObjGetElements(interp, listPtr, objcPtr, objvPtr) \ (((listPtr)->typePtr == &tclListType) \ ? ((ListObjGetElements((listPtr), *(objcPtr), *(objvPtr))), TCL_OK)\ : Tcl_ListObjGetElements((interp), (listPtr), (objcPtr), (objvPtr))) #define TclListObjLength(interp, listPtr, lenPtr) \ (((listPtr)->typePtr == &tclListType) \ ? ((ListObjLength((listPtr), *(lenPtr))), TCL_OK)\ : Tcl_ListObjLength((interp), (listPtr), (lenPtr))) #define TclListObjIsCanonical(listPtr) \ (((listPtr)->typePtr == &tclListType) ? ListObjIsCanonical((listPtr)) : 0) /* * Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere, * Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints. * * WARNING: these macros eval their args more than once. */ |
︙ | ︙ |
Changes to generic/tclUtil.c.
︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 | /* * Check first to see if all the items are of list type or empty. If so, * we will concat them together as lists, and return a list object. This * is only valid when the lists are in canonical form. */ for (i = 0; i < objc; i++) { | | | < < < < | | < < | > | | 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 | /* * Check first to see if all the items are of list type or empty. If so, * we will concat them together as lists, and return a list object. This * is only valid when the lists are in canonical form. */ for (i = 0; i < objc; i++) { int length; objPtr = objv[i]; if (TclListObjIsCanonical(objPtr)) { continue; } Tcl_GetStringFromObj(objPtr, &length); if (length > 0) { break; } } if (i == objc) { Tcl_Obj **listv; int listc; resPtr = NULL; for (i = 0; i < objc; i++) { /* * Tcl_ListObjAppendList could be used here, but this saves us a * bit of type checking (since we've already done it). Use of * INT_MAX tells us to always put the new stuff on the end. It * will be set right in Tcl_ListObjReplace. * Note that all objs at this point are either lists or have an * empty string rep. */ objPtr = objv[i]; if (objPtr->bytes && objPtr->length == 0) { continue; } TclListObjGetElements(NULL, objPtr, &listc, &listv); if (listc) { if (resPtr) { Tcl_ListObjReplace(NULL, resPtr, INT_MAX, 0, listc, listv); } else { |
︙ | ︙ |