summaryrefslogtreecommitdiffstats
path: root/generic/tclListObj.c
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2007-04-24 22:31:39 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2007-04-24 22:31:39 (GMT)
commit3db7ba34d45ae329be55c4212d3bc6d0fe7c04ce (patch)
tree249e9ab9bd91c3e7f7a9233f655b2e00e56d1f4a /generic/tclListObj.c
parentcbcca850953622453b3b1d1d1e115027338c0e66 (diff)
downloadtcl-3db7ba34d45ae329be55c4212d3bc6d0fe7c04ce.zip
tcl-3db7ba34d45ae329be55c4212d3bc6d0fe7c04ce.tar.gz
tcl-3db7ba34d45ae329be55c4212d3bc6d0fe7c04ce.tar.bz2
* generic/tclListObj.c: reverting [Patch 738900] (committed on
2007-04-20). Causes some Tk test breakage of unknown importance, but the impact of the patch itself is likely to be so small that it does not warrant investigation at this time.
Diffstat (limited to 'generic/tclListObj.c')
-rw-r--r--generic/tclListObj.c162
1 files changed, 56 insertions, 106 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index 4332492..170831f 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.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: tclListObj.c,v 1.45 2007/04/24 22:07:53 kennykb Exp $
+ * RCS: @(#) $Id: tclListObj.c,v 1.46 2007/04/24 22:31:39 msofer Exp $
*/
#include "tclInt.h"
@@ -1634,65 +1634,34 @@ SetListFromAny(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr) /* The object to convert. */
{
- char *string = NULL, *s;
+ char *string, *s;
const char *elemStart, *nextElem;
int lenRemain, length, estCount, elemSize, hasBrace, i, j, result;
- const char *limit = NULL; /* Points just after string's last byte. */
+ const char *limit; /* Points just after string's last byte. */
register const char *p;
register Tcl_Obj **elemPtrs;
register Tcl_Obj *elemPtr;
List *listRepPtr;
- Tcl_ObjType *typePtr = objPtr->typePtr;
- int avoidParse;
- estCount = 1;
- avoidParse = 1;
- i = 1;
- if (objPtr->bytes && (objPtr->length == 0)) {
- i = 0;
- } else if ((typePtr != &tclIntType)
-#ifndef NO_WIDE_TYPE
- && (typePtr != &tclWideIntType)
-#endif
- && (typePtr != &tclDoubleType)
- && (typePtr != &tclBignumType)) {
-
- /*
- * Get the string representation. Make it up-to-date if necessary.
- */
+ /*
+ * Get the string representation. Make it up-to-date if necessary.
+ */
- string = Tcl_GetStringFromObj(objPtr, &length);
-
- /*
- * Get an overestimate of the number of elements by counting
- * whitespaces; force a thorough parsing of the list if the string
- * contains whitespaces or backslashes.
- */
-
- limit = string + length;
- for (p = string; p < limit; p++) {
- if (isspace(UCHAR(*p))) { /* INTL: ISO space. */
- estCount++;
- avoidParse = 0;
- }
- if (*p == '\\') {
- avoidParse = 0;
- }
- }
+ string = Tcl_GetStringFromObj(objPtr, &length);
- if (avoidParse) {
- /*
- * It is a single element without braces or spaces: check
- * that is a valid one-element list, and force full parsing if it
- * contains braces.
- */
-
- result = TclFindElement(interp, string, length, &elemStart,
- &nextElem, &elemSize, &hasBrace);
- if (result != TCL_OK) {
- return result;
- }
- avoidParse = !hasBrace;
+ /*
+ * Parse the string into separate string objects, and create a List
+ * structure that points to the element string objects. We use a modified
+ * version of Tcl_SplitList's implementation to avoid one malloc and a
+ * string copy for each list element. First, estimate the number of
+ * elements by counting the number of space characters in the list.
+ */
+
+ limit = string + length;
+ estCount = 1;
+ for (p = string; p < limit; p++) {
+ if (isspace(UCHAR(*p))) { /* INTL: ISO space. */
+ estCount++;
}
}
@@ -1711,73 +1680,54 @@ SetListFromAny(
}
elemPtrs = &listRepPtr->elements;
-
- if (avoidParse) {
- if (i) {
- /*
- * Single element list containing a duplicate of objPtr.
- */
-
- elemPtr = Tcl_DuplicateObj(objPtr);
- elemPtrs[0] = elemPtr;
- Tcl_IncrRefCount(elemPtr);
+ for (p=string, lenRemain=length, i=0;
+ lenRemain > 0;
+ p=nextElem, lenRemain=limit-nextElem, i++) {
+ result = TclFindElement(interp, p, lenRemain, &elemStart, &nextElem,
+ &elemSize, &hasBrace);
+ if (result != TCL_OK) {
+ for (j = 0; j < i; j++) {
+ elemPtr = elemPtrs[j];
+ Tcl_DecrRefCount(elemPtr);
+ }
+ ckfree((char *) listRepPtr);
+ return result;
}
- } else {
+ if (elemStart >= limit) {
+ break;
+ }
+ if (i > estCount) {
+ Tcl_Panic("SetListFromAny: bad size estimate for list");
+ }
+
/*
- * Parse the string into separate string objects, create a string
- * object for each element, and insert it into the List structure. We
- * use a modified version of Tcl_SplitList's implementation to avoid
- * one malloc and a string copy for each list element.
+ * Allocate a Tcl object for the element and initialize it from the
+ * "elemSize" bytes starting at "elemStart".
*/
- for (p=string, lenRemain=length, i=0;
- lenRemain > 0;
- p=nextElem, lenRemain=limit-nextElem, i++) {
- result = TclFindElement(interp, p, lenRemain, &elemStart, &nextElem,
- &elemSize, &hasBrace);
- if (result != TCL_OK) {
- for (j = 0; j < i; j++) {
- elemPtr = elemPtrs[j];
- Tcl_DecrRefCount(elemPtr);
- }
- ckfree((char *) listRepPtr);
- return result;
- }
- if (elemStart >= limit) {
- break;
- }
- if (i > estCount) {
- Tcl_Panic("SetListFromAny: bad size estimate for list");
- }
-
- /*
- * Allocate a Tcl object for the element and initialize it from
- * the "elemSize" bytes starting at "elemStart".
- */
-
- s = ckalloc((unsigned) elemSize + 1);
- if (hasBrace) {
- memcpy(s, elemStart, (size_t) elemSize);
- s[elemSize] = 0;
- } else {
- elemSize = TclCopyAndCollapse(elemSize, elemStart, s);
- }
-
- TclNewObj(elemPtr);
- elemPtr->bytes = s;
- elemPtr->length = elemSize;
- elemPtrs[i] = elemPtr;
- Tcl_IncrRefCount(elemPtr); /* Since list now holds ref to it. */
+ s = ckalloc((unsigned) elemSize + 1);
+ if (hasBrace) {
+ memcpy(s, elemStart, (size_t) elemSize);
+ s[elemSize] = 0;
+ } else {
+ elemSize = TclCopyAndCollapse(elemSize, elemStart, s);
}
+
+ TclNewObj(elemPtr);
+ elemPtr->bytes = s;
+ elemPtr->length = elemSize;
+ elemPtrs[i] = elemPtr;
+ Tcl_IncrRefCount(elemPtr); /* Since list now holds ref to it. */
}
+ listRepPtr->elemCount = i;
+
/*
* Free the old internalRep before setting the new one. We do this as late
* as possible to allow the conversion code, in particular
- * Tcl_GetStringFromObj, to use that old internalRep.
+ * Tcl_GetStringFromObj, to use that old internalRep.
*/
- listRepPtr->elemCount = i;
listRepPtr->refCount++;
TclFreeIntRep(objPtr);
objPtr->internalRep.twoPtrValue.ptr1 = (void *) listRepPtr;