Tcl Source Code

Artifact [c926614270]
Login

Artifact c92661427061f6b1e76b251571c76d3b9397dc0f:

Attachment "1725186-2.patch" to ticket [1725186fff] added by dgp 2007-05-30 23:15:18.
? 1578344-2.patch
? 1578344-3.patch
? 1578344.patch
? 1588842.patch
? 1655305.patch
? 1661637.patch
? 1686862.patch
? 1701202.patch
? 1706140-2.patch
? 1706140.patch
? 1710709.patch
? 1725185-2.patch
? 1725186.patch
? bc84.diff
? comment.patch
? compList.patch
? debug
? ep.patch
? exam
? execEnv.patch
? export.patch
? ip.patch
? kevinleaks1.txt
? kevinleaks3.txt
? kevinleaks4.txt
? leakfs.txt
? legacy.patch
? mathop.patch
? results.leaks
? results2.leaks
? rev
? solaris
? soldebug
? solthread
? thread
? tip174.patch
? undo.patch
? doc/file.n.dos
? generic/dodo
? generic/exam
? generic/lindex.ip
? generic/sdfsdf
? generic/sdfsdfsdf
? generic/searchme
? generic/sift
? generic/sift2
? generic/tclBasic.c.ip
? generic/tclCkalloc.c.hacked
? generic/tclIOUtil.c.hacked
? generic/tclLink.c.hacked
? generic/tclMain.c.hacked
? generic/tclTrace.c.hacked
? generic/tclVar.c.1.56
? generic/tclVar.c.1.57
? generic/tclVar.c.hacked
? unix/bg.tcl
? unix/demo.tcl
? unix/dgp.test
? unix/dltest.marker
? unix/du.tcl
? unix/ens.tcl
? unix/fe.tcl
? unix/lr.tcl
? unix/stXXXXTPhUss
? unix/stXXXXyGEyfD
? unix/tclUnixFile.c.hacked
? unix/tclshCopy
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.244
diff -u -r1.244 tclBasic.c
--- generic/tclBasic.c	20 Apr 2007 05:51:08 -0000	1.244
+++ generic/tclBasic.c	30 May 2007 16:13:42 -0000
@@ -3926,14 +3926,6 @@
     CmdFrame eeFrame;		/* TIP #280 Structures for tracking of command
 				 * locations. */
 
-    /*
-     * TIP #280. The array 'expand' has become tri-valued.
-     * 0 =     No expansion
-     * 1 =     Expansion, value is dynamically constructed ($var, [cmd]).
-     * 2 = NEW Expansion of a literal value. Here the system determines the
-     *         actual line numbers within the literal.
-     */
-
     if (numBytes < 0) {
 	numBytes = strlen(script);
     }
@@ -4074,9 +4066,7 @@
 		TclAdvanceLines(&wordLine, wordStart, tokenPtr->start);
 		wordStart = tokenPtr->start;
 
-		lines[objectsUsed] =
-			(TclWordKnownAtCompileTime(tokenPtr, NULL)
-				|| TclWordSimpleExpansion(tokenPtr))
+		lines[objectsUsed] = TclWordKnownAtCompileTime(tokenPtr, NULL)
 			? wordLine : -1;
 
 		if (eeFrame.type == TCL_LOCATION_SOURCE) {
@@ -4109,8 +4099,7 @@
 			goto error;
 		    }
 		    expandRequested = 1;
-		    expand[objectsUsed] =
-			    TclWordSimpleExpansion(tokenPtr) ? 2 : 1;
+		    expand[objectsUsed] = 1;
 
 		    objectsNeeded += (numElements ? numElements : 1);
 		} else {
@@ -4138,36 +4127,7 @@
 
 		objectsUsed = 0;
 		while (wordIdx--) {
-		    if (expand[wordIdx] == 2) {
-			/*
-			 * TIP #280. The expansion is for a simple literal.
-			 * Not only crack the list into its elements,
-			 * determine the line numbers within it as well.
-			 *
-			 * The qualification of 'simple' ensures that the word
-			 * does not contain backslash-subst, no way to get
-			 * thrown off by embedded \n sequnces.
-			 */
-
-			int numElements;
-			Tcl_Obj **elements, *temp = copy[wordIdx];
-			int *eline;
-
-			Tcl_ListObjGetElements(NULL, temp, &numElements,
-				&elements);
-			eline = (int *) ckalloc(numElements * sizeof(int));
-			TclListLines(TclGetString(temp),lcopy[wordIdx],
-				numElements, eline);
-
-			objectsUsed += numElements;
-			while (numElements--) {
-			    lines[objIdx] = eline[numElements];
-			    objv[objIdx--] = elements[numElements];
-			    Tcl_IncrRefCount(elements[numElements]);
-			}
-			Tcl_DecrRefCount(temp);
-			ckfree((char *) eline);
-		    } else if (expand[wordIdx]) {
+		    if (expand[wordIdx]) {
 			int numElements;
 			Tcl_Obj **elements, *temp = copy[wordIdx];
 
Index: generic/tclCompile.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.c,v
retrieving revision 1.117
diff -u -r1.117 tclCompile.c
--- generic/tclCompile.c	23 Apr 2007 20:33:56 -0000	1.117
+++ generic/tclCompile.c	30 May 2007 16:13:43 -0000
@@ -1077,29 +1077,6 @@
     return 1;
 }
 
-int
-TclWordSimpleExpansion(
-    Tcl_Token *tokenPtr)	/* Points to Tcl_Token we should check */
-{
-    int numComponents = tokenPtr->numComponents;
-
-    if (tokenPtr->type != TCL_TOKEN_EXPAND_WORD) {
-	return 0;
-    }
-    tokenPtr++;
-    while (numComponents--) {
-	switch (tokenPtr->type) {
-	case TCL_TOKEN_TEXT:
-	    break;
-
-	default:
-	    return 0;
-	}
-	tokenPtr++;
-    }
-    return 1;
-}
-
 /*
  *----------------------------------------------------------------------
  *
@@ -1224,23 +1201,6 @@
 	if (parse.numWords > 0) {
 	    int expand = 0;		/* Set if there are dynamic expansions
 					 * to handle */
-	    int eliterals = 0;		/* Set if there are literal expansions
-					 * to handle. Actually the number of
-					 * words in the expanded literals. */
-	    int *exp = NULL;		/* For literal expansions, #words in
-					 * the expansion. Only valid if the
-					 * associated expLen[] value is not
-					 * NULL. Can be 0, expansion to
-					 * nothing. */
-	    int **expLen = NULL;	/* Array of array of integers. Each
-					 * array holds the lengths of the
-					 * items in the expanded list. NULL
-					 * indicates unexpanded words, or
-					 * dynamically expanded words. */
-	    char ***expItem = NULL;	/* Array of arrays of strings, holding
-					 * pointers to the list elements,
-					 * inside of the parsed script. No
-					 * copies. For NULL, see expLen. */
 
 	    /*
 	     * If not the first command, pop the previous command's result
@@ -1286,127 +1246,18 @@
 
 	    /*
 	     * Check whether expansion has been requested for any of the
-	     * words. NOTE: If a word to be expanded is actually a literal
-	     * list we will do the expansion here, directly manipulating the
-	     * token array.
-	     *
-	     * Due to the search for literal expansions it is not possible
-	     * (anymore) to abort when a dynamic expansion is found. There
-	     * might be a literal one coming after.
+	     * words.
 	     */
 
-	    exp = (int *) TclStackAlloc(interp, sizeof(int) * parse.numWords);
-	    expLen = (int **) TclStackAlloc(interp,
-		    sizeof(int *) * parse.numWords);
-	    expItem = (char ***) TclStackAlloc(interp,
-		    sizeof(char **) * parse.numWords);
-
 	    for (wordIdx = 0, tokenPtr = parse.tokenPtr;
 		    wordIdx < parse.numWords;
 		    wordIdx++, tokenPtr += (tokenPtr->numComponents + 1)) {
-		exp[wordIdx] = -1;
-		expLen[wordIdx] = NULL;
-		expItem[wordIdx] = NULL;
-
 		if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
-		    if (TclWordSimpleExpansion(tokenPtr)) {
-			const char *start = (tokenPtr+1)->start;
-			const char *end =
-				(tokenPtr+tokenPtr->numComponents)->start +
-				(tokenPtr+tokenPtr->numComponents)->size;
-
-			if (TclMarkList(NULL, start, end, exp+wordIdx,
-				(const int **)(expLen+wordIdx),
-				(const char ***)(expItem+wordIdx)) != TCL_OK) {
-			    /*
-			     * We're trying to expand a literal that is not a
-			     * well-formed list. No option but to punt the
-			     * problem to run-time; arrange for compilation of
-			     * this term as an expansion.
-			     */
-
-			    expand = 1;
-			} else {
-			    eliterals += exp[wordIdx] ? exp[wordIdx] : 1;
-			}
-		    } else {
-			expand = 1;
-		    }
+		    expand = 1;
+		    break;
 		}
 	    }
 
-	    if (eliterals) {
-		Tcl_Token *copy = parse.tokenPtr;
-		int new;
-		int objIdx;
-
-		parse.tokensAvailable += eliterals + eliterals;
-
-		/*
-		 * eliterals times 2 - simple_word, and text tokens.
-		 */
-
-		parse.tokenPtr = (Tcl_Token *)
-			ckalloc(sizeof(Tcl_Token) * parse.tokensAvailable);
-		parse.numTokens = 0;
-
-		for (objIdx=0, wordIdx=0, tokenPtr=copy, new=0;
-			wordIdx < parse.numWords;
-			wordIdx++, tokenPtr += tokenPtr->numComponents+1) {
-		    if (expLen[wordIdx]) {
-			/*
-			 * Expansion of a simple literal. We already have the
-			 * list elements which become the words. Now we `just`
-			 * have to create their tokens. The token array
-			 * already has the proper size to contain them all.
-			 */
-
-			int k;
-			for (k = 0; k < exp[wordIdx]; k++) {
-			    Tcl_Token *t = &parse.tokenPtr[objIdx];
-
-			    t->type = TCL_TOKEN_SIMPLE_WORD;
-			    t->start = expItem[wordIdx][k];
-			    t->size = expLen[wordIdx][k];
-			    t->numComponents = 1;
-			    t++;
-
-			    t->type = TCL_TOKEN_TEXT;
-			    t->start = expItem[wordIdx][k];
-			    t->size = expLen[wordIdx][k];
-			    t->numComponents = 0;
-
-			    objIdx += 2;
-			    new ++;
-			}
-
-			ckfree((char *) expLen[wordIdx]);
-			ckfree((char *) expItem[wordIdx]);
-		    } else {
-			/*
-			 * Regular word token. Copy as is, including subtree.
-			 */
-
-			int k;
-
-			new++;
-			for (k=0 ; k<=tokenPtr->numComponents ; k++) {
-			    parse.tokenPtr[objIdx++] = tokenPtr[k];
-			}
-		    }
-		}
-		parse.numTokens = objIdx;
-		parse.numWords = new;
-
-		if (copy != parse.staticTokens) {
-		    ckfree((char *) copy);
-		}
-	    }
-
-	    TclStackFree(interp);	/* expItem */
-	    TclStackFree(interp);	/* expLen */
-	    TclStackFree(interp);	/* exp */
-
 	    envPtr->numCommands++;
 	    currCmdIndex = (envPtr->numCommands - 1);
 	    lastTopLevelCmdIndex = currCmdIndex;
Index: generic/tclCompile.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.h,v
retrieving revision 1.70
diff -u -r1.70 tclCompile.h
--- generic/tclCompile.h	3 Apr 2007 01:34:37 -0000	1.70
+++ generic/tclCompile.h	30 May 2007 16:13:43 -0000
@@ -915,7 +915,6 @@
 #endif
 MODULE_SCOPE int	TclWordKnownAtCompileTime(Tcl_Token *tokenPtr,
 			    Tcl_Obj *valuePtr);
-MODULE_SCOPE int	TclWordSimpleExpansion(Tcl_Token *tokenPtr);
 
 /*
  *----------------------------------------------------------------
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.310
diff -u -r1.310 tclInt.h
--- generic/tclInt.h	11 May 2007 20:59:13 -0000	1.310
+++ generic/tclInt.h	30 May 2007 16:13:43 -0000
@@ -3397,10 +3397,6 @@
 #include "tclIntPlatDecls.h"
 #include "tclTomMathDecls.h"
 
-
-
-MODULE_SCOPE void TclPrintTokens (Tcl_Token* token, int words, int level);
-
 #endif /* _TCLINT */
 
 /*
Index: generic/tclParse.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclParse.c,v
retrieving revision 1.52
diff -u -r1.52 tclParse.c
--- generic/tclParse.c	18 May 2007 18:39:30 -0000	1.52
+++ generic/tclParse.c	30 May 2007 16:13:44 -0000
@@ -414,13 +414,74 @@
 	tokenPtr = &parsePtr->tokenPtr[wordIndex];
 	tokenPtr->size = src - tokenPtr->start;
 	tokenPtr->numComponents = parsePtr->numTokens - (wordIndex + 1);
-	if ((tokenPtr->numComponents == 1)
+	if (expandWord) {
+	    int i, isLiteral = 1;
+	    for (i = 1; i <= tokenPtr->numComponents; i++) {
+		if (tokenPtr[i].type != TCL_TOKEN_TEXT) {
+		    isLiteral = 0;
+		    break;
+		}
+	    }
+	    if (isLiteral) {
+		int elemCount = 0, code = TCL_OK;
+		const char *nextElem, *listEnd, *elemStart;
+
+		listEnd = (tokenPtr[tokenPtr->numComponents].start +
+			tokenPtr[tokenPtr->numComponents].size);
+		nextElem = tokenPtr[1].start;
+		while ((code == TCL_OK) && (nextElem < listEnd)) {
+		    code = TclFindElement(NULL, nextElem, listEnd - nextElem,
+			    &elemStart, &nextElem, NULL, NULL);
+		    if (elemStart < listEnd) {
+			elemCount++;
+		    }
+		}
+		if (code != TCL_OK) {
+		    tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
+		} else if (elemCount == 0) {
+		    parsePtr->numWords--;
+		    parsePtr->numTokens = wordIndex;
+		} else {
+		    parsePtr->numWords += elemCount - 1;
+		    parsePtr->numTokens = wordIndex + 2*elemCount;
+		    nextElem = tokenPtr[1].start;
+		    while (parsePtr->numTokens >= parsePtr->tokensAvailable) {
+			TclExpandTokenArray(parsePtr);
+		    }
+		    tokenPtr = &parsePtr->tokenPtr[wordIndex];
+		    while (isspace(UCHAR(*nextElem))) {
+			nextElem++;
+		    }
+		    while (nextElem < listEnd) {
+			tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
+			tokenPtr->numComponents = 1;
+			tokenPtr->start = nextElem;
+
+			tokenPtr++;
+			tokenPtr->type = TCL_TOKEN_TEXT;
+			tokenPtr->numComponents = 0;
+			TclFindElement(NULL, nextElem, listEnd - nextElem,
+				&(tokenPtr->start), &nextElem,
+				&(tokenPtr->size), NULL);
+			if (tokenPtr->start + tokenPtr->size == listEnd) {
+			    tokenPtr[-1].size = listEnd - tokenPtr[-1].start;
+			} else {
+			    tokenPtr[-1].size = tokenPtr->start
+				    + tokenPtr->size - tokenPtr[-1].start;
+			    tokenPtr[-1].size += (isspace(UCHAR(
+				tokenPtr->start[tokenPtr->size])) == 0);
+			}
+
+			tokenPtr++;
+		    }
+		}
+	    } else {
+		tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
+	    }
+	} else if ((tokenPtr->numComponents == 1)
 		&& (tokenPtr[1].type == TCL_TOKEN_TEXT)) {
 	    tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
 	}
-	if (expandWord) {
-	    tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
-	}
 
 	/*
 	 * Do two additional checks: (a) make sure we're really at the end of
@@ -2351,54 +2412,6 @@
     return 1;
 }
 
-#define TCL_TOKEN_WORD		1
-#define TCL_TOKEN_SIMPLE_WORD	2
-#define TCL_TOKEN_TEXT		4
-#define TCL_TOKEN_BS		8
-#define TCL_TOKEN_COMMAND	16
-#define TCL_TOKEN_VARIABLE	32
-#define TCL_TOKEN_SUB_EXPR	64
-#define TCL_TOKEN_OPERATOR	128
-#define TCL_TOKEN_EXPAND_WORD	256
-
-static void
-TclPrintToken(
-    Tcl_Token *token,
-    int idx,
-    int level)
-{
-    int i;
-
-    for (i=0 ; i<level ; i++) {
-	fprintf(stdout, " ");
-    }
-    level++;
-
-    fprintf(stdout, "[%3d] @%p/%4d", idx, token->start, token->size);
-    if (token->numComponents == 0) {
-	fprintf(stdout," <%.*s>\n", token->size, token->start);
-    } else {
-	fprintf(stdout,"\n");
-    }
-    fflush(stdout);
-    if (token->numComponents > 0) {
-	TclPrintTokens(token+1,token->numComponents, level);
-    }
-}
-
-void
-TclPrintTokens(
-    Tcl_Token *token,
-    int words,
-    int level)
-{
-    int k;
-
-    for (k=0 ; k<words ; k++, token += (1+token->numComponents)) {
-	TclPrintToken(token, k, level);
-    }
-}
-
 /*
  * Local Variables:
  * mode: c
Index: tests/parse.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/parse.test,v
retrieving revision 1.27
diff -u -r1.27 parse.test
--- tests/parse.test	15 Mar 2007 22:05:21 -0000	1.27
+++ tests/parse.test	30 May 2007 16:13:46 -0000
@@ -217,7 +217,7 @@
 } {- {{*} } 1 simple {{*}} 1 text * 0 {}}
 test parse-5.24 {Tcl_ParseCommand: {*} parsing} testparser {
     testparser {{*}x} 0
-} {- {{*}x} 1 expand {{*}x} 1 text x 0 {}}
+} {- {{*}x} 1 simple x 1 text x 0 {}}
 test parse-5.25 {Tcl_ParseCommand: {*} parsing} testparser {
     testparser {{*}
 } 0