Tcl Source Code

Check-in [a4d8498860]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Tighten up the patch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dgp-switch-compile
Files: files | file ages | folders
SHA1: a4d8498860652627f672e4ef3fd08f5c569ded5e
User & Date: dgp 2011-05-02 12:18:25
Context
2011-05-02
15:52
Replace TclCountSpaceRuns() with TclMaxListLength() which is the function we actually want. check-in: 056df6f608 user: dgp tags: dgp-switch-compile
12:18
Tighten up the patch. check-in: a4d8498860 user: dgp tags: dgp-switch-compile
2011-04-28
20:40
Rewrite of parts of the [switch] compiler to better use the powers of TclFindElement() and do less p... check-in: 5f8dcf50a2 user: dgp tags: dgp-switch-compile
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclCompCmds.c.

4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198





4199
4200
4201
4202

4203
4204
4205

4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
	    ckfree((char *) bodyToken);
	    ckfree((char *) bodyTokenArray);
	    ckfree((char *) bodyLines);
	    ckfree((char *) bodyNext);
	    return TCL_ERROR;
	}
#else
	CONST char *bytes, *p;
	int maxLen, braced, numBytes;
	int bline;		/* TIP #280: line of the pattern/action list,
				 * and start of list for when tracking the
				 * location. This list comes immediately after
				 * the value we switch on. */

	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
	    return TCL_ERROR;
	}
	bytes = tokenPtr[1].start;
	numBytes = tokenPtr[1].size;






	/*
	 * A list can have at most one more element than the number
	 * of runs of element-separating white space.

	 */

	maxLen = TclCountSpaceRuns(bytes, numBytes, NULL) + 1;

	if (maxLen < 2) {
	    return TCL_ERROR;
	}
	bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * maxLen);
	bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * maxLen);
	bodyLines = (int *) ckalloc(sizeof(int) * maxLen);
	bodyNext  = (int **) ckalloc(sizeof(int*) * maxLen);

	bline = mapPtr->loc[eclIndex].line[valueIndex+1];
	p = bytes;
	numWords = 0;

	while (numBytes > 0) {
	    CONST char *start, *prevBytes = bytes;
	    int size;

	    if (TCL_OK != TclFindElement(NULL, bytes, numBytes, &start,
		    &bytes, &size, &braced)) {
	    abort:
		ckfree((char *) bodyToken);
		ckfree((char *) bodyTokenArray);
		ckfree((char *) bodyLines);
		ckfree((char *) bodyNext);
		return TCL_ERROR;
	    }
	    numBytes -= (bytes - prevBytes);

	    if (numWords == 0 && numBytes == 0) {
		break;
	    }

	    bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
	    bodyTokenArray[numWords].start = start;
	    bodyTokenArray[numWords].size = size;
	    bodyTokenArray[numWords].numComponents = 0;
	    bodyToken[numWords] = bodyTokenArray + numWords;








|
|










>
>
>
>
>



|
>


|
>









<




|










<
<
<
<
<







4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221

4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236





4237
4238
4239
4240
4241
4242
4243
	    ckfree((char *) bodyToken);
	    ckfree((char *) bodyTokenArray);
	    ckfree((char *) bodyLines);
	    ckfree((char *) bodyNext);
	    return TCL_ERROR;
	}
#else
	CONST char *bytes;
	int maxLen, numBytes;
	int bline;		/* TIP #280: line of the pattern/action list,
				 * and start of list for when tracking the
				 * location. This list comes immediately after
				 * the value we switch on. */

	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
	    return TCL_ERROR;
	}
	bytes = tokenPtr[1].start;
	numBytes = tokenPtr[1].size;

	/* Smallest possible two-element list has 3 byte string rep */
	if (numBytes < 3) {
	    return TCL_ERROR;
	}

	/*
	 * A list can have at most one more element than the number
	 * of runs of (potentially) element-separating white space.
	 * And one less each if whitespace leads or trails.  
	 */

	maxLen = TclCountSpaceRuns(bytes, numBytes, NULL) + 1
		- TclIsSpaceProc(*bytes) - TclIsSpaceProc(bytes[numBytes-1]);
	if (maxLen < 2) {
	    return TCL_ERROR;
	}
	bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * maxLen);
	bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * maxLen);
	bodyLines = (int *) ckalloc(sizeof(int) * maxLen);
	bodyNext  = (int **) ckalloc(sizeof(int*) * maxLen);

	bline = mapPtr->loc[eclIndex].line[valueIndex+1];

	numWords = 0;

	while (numBytes > 0) {
	    CONST char *start, *prevBytes = bytes;
	    int size, braced;

	    if (TCL_OK != TclFindElement(NULL, bytes, numBytes, &start,
		    &bytes, &size, &braced)) {
	    abort:
		ckfree((char *) bodyToken);
		ckfree((char *) bodyTokenArray);
		ckfree((char *) bodyLines);
		ckfree((char *) bodyNext);
		return TCL_ERROR;
	    }






	    bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
	    bodyTokenArray[numWords].start = start;
	    bodyTokenArray[numWords].size = size;
	    bodyTokenArray[numWords].numComponents = 0;
	    bodyToken[numWords] = bodyTokenArray + numWords;

4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262

4263

4264
4265
4266
4267
4268
4269
4270

	    /*
	     * TIP #280: Now determine the line the list element starts on
	     * (there is no need to do it earlier, due to the possibility of
	     * aborting, see above).
	     */

	    TclAdvanceLines(&bline, p, bodyTokenArray[numWords].start);
	    TclAdvanceContinuations (&bline, &clNext,
		    bodyTokenArray[numWords].start - envPtr->source);
	    bodyLines[numWords] = bline;
	    bodyNext[numWords] = clNext;
	    p = bodyTokenArray[numWords].start;



	    numWords++;
	}
	if (numWords % 2) {
	    goto abort;
	}

#endif







|




|
>

>







4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273

	    /*
	     * TIP #280: Now determine the line the list element starts on
	     * (there is no need to do it earlier, due to the possibility of
	     * aborting, see above).
	     */

	    TclAdvanceLines(&bline, prevBytes, bodyTokenArray[numWords].start);
	    TclAdvanceContinuations (&bline, &clNext,
		    bodyTokenArray[numWords].start - envPtr->source);
	    bodyLines[numWords] = bline;
	    bodyNext[numWords] = clNext;
	    TclAdvanceLines(&bline, bodyTokenArray[numWords].start, bytes);
	    TclAdvanceContinuations (&bline, &clNext, bytes - envPtr->source);

	    numBytes -= (bytes - prevBytes);
	    numWords++;
	}
	if (numWords % 2) {
	    goto abort;
	}

#endif