Tcl Source Code

Artifact [0d639bdcd9]
Login

Artifact 0d639bdcd9e7c8d21176ba5e0c521df30410a2fe:

Attachment "1165695.patch" to ticket [1165695fff] added by dgp 2005-04-30 03:34:05.
Index: doc/lindex.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/lindex.n,v
retrieving revision 1.9
diff -u -r1.9 lindex.n
--- doc/lindex.n	6 Apr 2005 20:55:23 -0000	1.9
+++ doc/lindex.n	29 Apr 2005 20:30:38 -0000
@@ -46,9 +46,11 @@
 If \fIindex\fR is negative or greater than or equal to the number
 of elements in \fIvalue\fR, then an empty
 string is returned.
-If \fIindex\fR has the value \fBend\fR, it refers to the last element
-in the list, and \fBend\-\fIinteger\fR refers to the last element in
-the list minus the specified integer offset.
+.VS 8.5
+The interpretation of each simple \fIindex\fR value is the same as 
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE 8.5
 .PP
 If additional \fIindex\fR arguments are supplied, then each argument is
 used in turn to select an element from the previous indexing operation,
@@ -79,7 +81,10 @@
 .CE
 .SH "SEE ALSO"
 list(n), lappend(n), linsert(n), llength(n), lsearch(n), 
-lset(n), lsort(n), lrange(n), lreplace(n)
+lset(n), lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
+.VE
 
 .SH KEYWORDS
 element, index, list
Index: doc/linsert.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/linsert.n,v
retrieving revision 1.11
diff -u -r1.11 linsert.n
--- doc/linsert.n	6 Apr 2005 20:55:23 -0000	1.11
+++ doc/linsert.n	29 Apr 2005 20:30:38 -0000
@@ -24,11 +24,12 @@
 \fIelement\fR arguments just before the \fIindex\fR'th element of
 \fIlist\fR.  Each \fIelement\fR argument will become a separate element of
 the new list.  If \fIindex\fR is less than or equal to zero, then the new
-elements are inserted at the beginning of the list.  If \fIindex\fR has the
-value \fBend\fR, or if it is greater than or equal to the number of
-elements in the list, then the new elements are appended to the list.
-\fBend\-\fIinteger\fR refers to the last element in the list minus the
-specified integer offset.
+elements are inserted at the beginning of the list.  
+.VS 8.5
+The interpretation of the \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE
 .SH EXAMPLE
 Putting some values into a list, first indexing from the start and
 then indexing from the end, and then chaining them together:
@@ -42,7 +43,10 @@
 
 .SH "SEE ALSO"
 list(n), lappend(n), lindex(n), llength(n), lsearch(n), 
-lset(n), lsort(n), lrange(n), lreplace(n)
+lset(n), lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
+.VE
 
 .SH KEYWORDS
 element, insert, list
Index: doc/lrange.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/lrange.n,v
retrieving revision 1.10
diff -u -r1.10 lrange.n
--- doc/lrange.n	6 Apr 2005 20:55:23 -0000	1.10
+++ doc/lrange.n	29 Apr 2005 20:30:38 -0000
@@ -23,9 +23,12 @@
 \fIList\fR must be a valid Tcl list.  This command will
 return a new list consisting of elements
 \fIfirst\fR through \fIlast\fR, inclusive.
-\fIFirst\fR or \fIlast\fR
-may be \fBend\fR (or any abbreviation of it) to refer to the last
-element of the list.
+.VS 8.5
+The index values \fIfirst\fR and \fIlast\fR are interpreted
+the same as index values for the command \fBstring index\fR,
+supporting simple index arithmetic and indices relative to the
+end of the list.
+.VE
 If \fIfirst\fR is less than zero, it is treated as if it were zero.
 If \fIlast\fR is greater than or equal to the number of elements
 in the list, then it is treated as if it were \fBend\fR.
@@ -67,7 +70,10 @@
 
 .SH "SEE ALSO"
 list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), 
-lset(n), lreplace(n), lsort(n)
+lset(n), lreplace(n), lsort(n),
+.VS 8.5
+string(n)
+.VE
 
 .SH KEYWORDS
 element, list, range, sublist
Index: doc/lreplace.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/lreplace.n,v
retrieving revision 1.11
diff -u -r1.11 lreplace.n
--- doc/lreplace.n	6 Apr 2005 20:55:23 -0000	1.11
+++ doc/lreplace.n	29 Apr 2005 20:30:38 -0000
@@ -22,11 +22,17 @@
 .PP
 \fBlreplace\fR returns a new list formed by replacing one or more elements of
 \fIlist\fR with the \fIelement\fR arguments.
-\fIfirst\fR and \fIlast\fR specify the first and last index of the
-range of elements to replace.  0 refers to the first element of the
-list, and \fBend\fR (or any abbreviation of it) may be used to refer
-to the last element of the list.  If \fIlist\fR is empty, then
-\fIfirst\fR and \fIlast\fR are ignored.
+.VS 8.5
+\fIfirst\fR and \fIlast\fR are index values specifying the first and
+last elements of the range to replace.  
+The index values \fIfirst\fR and \fIlast\fR are interpreted
+the same as index values for the command \fBstring index\fR,
+supporting simple index arithmetic and indices relative to the
+end of the list.
+0 refers to the first element of the
+list, and \fBend\fR refers to the last element of the list.
+If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored.
+.VE
 
 If \fIfirst\fR is less than zero, it is considered to refer to the
 first element of the list.  For non-empty lists, the element indicated
@@ -66,7 +72,11 @@
 
 .SH "SEE ALSO"
 list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), 
-lset(n), lrange(n), lsort(n)
+lset(n), lrange(n), lsort(n),
+.VS 8.5
+string(n)
+.VE
+
 
 .SH KEYWORDS
 element, list, replace
Index: doc/lsearch.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/lsearch.n,v
retrieving revision 1.22
diff -u -r1.22 lsearch.n
--- doc/lsearch.n	5 Jan 2005 16:38:54 -0000	1.22
+++ doc/lsearch.n	29 Apr 2005 20:30:38 -0000
@@ -70,10 +70,12 @@
 non-matching value in the list.
 .TP
 \fB\-start\fR\0\fIindex\fR
-The list is searched starting at position \fIindex\fR.  If \fIindex\fR
-has the value \fBend\fR, it refers to the last element in the list,
-and \fBend\-\fIinteger\fR refers to the last element in the list minus
-the specified integer offset.
+The list is searched starting at position \fIindex\fR.  
+.VS 8.5
+The interpretation of the \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE 8.5
 .SS "CONTENTS DESCRIPTION OPTIONS"
 These options describe how to interpret the items in the list being
 searched.  They are only meaningful when used with the \fB\-exact\fR
@@ -166,7 +168,11 @@
 
 .SH "SEE ALSO"
 foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n), 
-lset(n), lsort(n), lrange(n), lreplace(n)
+lset(n), lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
+.VE
+
 
 .SH KEYWORDS
 list, match, pattern, regular expression, search, string
Index: doc/lset.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/lset.n,v
retrieving revision 1.7
diff -u -r1.7 lset.n
--- doc/lset.n	1 Dec 2003 21:27:14 -0000	1.7
+++ doc/lset.n	29 Apr 2005 20:30:38 -0000
@@ -52,9 +52,11 @@
 If \fIindex\fR is negative or greater than or equal to the number
 of elements in \fI$varName\fR, then an error occurs.
 .PP
-If \fIindex\fR has the value \fBend\fR, it refers to the last element
-in the list, and \fBend\-\fIinteger\fR refers to the last element in
-the list minus the specified integer offset.
+.VS 8.5
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE 8.5
 .PP
 If additional \fIindex\fR arguments are supplied, then each argument is
 used in turn to address an element within a sublist designated
@@ -107,7 +109,11 @@
 .CE
 .SH "SEE ALSO"
 list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), 
-lsort(n), lrange(n), lreplace(n)
+lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
+.VE
+
 
 .SH KEYWORDS
 element, index, list, replace, set
Index: doc/lsort.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/lsort.n,v
retrieving revision 1.18
diff -u -r1.18 lsort.n
--- doc/lsort.n	27 Oct 2004 12:53:22 -0000	1.18
+++ doc/lsort.n	29 Apr 2005 20:30:38 -0000
@@ -78,10 +78,7 @@
 each sublist
 .VS 8.5
 (as if the overall element and the \fIindexList\fR were passed to
-\fBlindex\fR) and sort based on the given element.  The keyword
-\fBend\fP is allowed for each element of the \fIindexList\fR to sort
-on the last sublist element, and \fBend-\fIindex\fR sorts on a sublist
-element offset from the end.
+\fBlindex\fR) and sort based on the given element.  
 .VE 8.5
 For example,
 .RS
Index: doc/regexp.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/regexp.n,v
retrieving revision 1.17
diff -u -r1.17 regexp.n
--- doc/regexp.n	6 Apr 2005 20:55:23 -0000	1.17
+++ doc/regexp.n	29 Apr 2005 20:30:38 -0000
@@ -107,7 +107,12 @@
 .TP 15
 \fB\-start\fR \fIindex\fR
 Specifies a character index offset into the string to start
-matching the regular expression at.  When using this switch, `^'
+matching the regular expression at.  
+.VS 8.5
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+.VE 8.5
+When using this switch, `^'
 will not match the beginning of the line, and \\A will still
 match the start of the string at \fIindex\fR.  If \fB\-indices\fR
 is specified, the indices will be indexed starting from the
@@ -153,7 +158,11 @@
 .CE
 
 .SH "SEE ALSO"
-re_syntax(n), regsub(n)
+re_syntax(n), regsub(n),
+.VS 8.5
+string(n)
+.VE
+
 
 .SH KEYWORDS
 match, regular expression, string
Index: doc/regsub.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/regsub.n,v
retrieving revision 1.13
diff -u -r1.13 regsub.n
--- doc/regsub.n	6 Apr 2005 20:55:24 -0000	1.13
+++ doc/regsub.n	29 Apr 2005 20:30:38 -0000
@@ -92,7 +92,12 @@
 .TP 10
 \fB\-start\fR \fIindex\fR
 Specifies a character index offset into the string to start
-matching the regular expression at.  When using this switch, `^'
+matching the regular expression at.  
+.VS 8.5
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+.VE 8.5
+When using this switch, `^'
 will not match the beginning of the line, and \\A will still
 match the start of the string at \fIindex\fR.
 \fIindex\fR will be constrained to the bounds of the input string.
@@ -134,7 +139,11 @@
 .CE
 
 .SH "SEE ALSO"
-regexp(n), re_syntax(n), subst(n)
+regexp(n), re_syntax(n), subst(n),
+.VS 8.5
+string(n)
+.VE
+
 
 .SH KEYWORDS
 match, pattern, regular expression, substitute
Index: doc/string.n
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/string.n,v
retrieving revision 1.26
diff -u -r1.26 string.n
--- doc/string.n	7 Mar 2005 21:38:10 -0000	1.26
+++ doc/string.n	29 Apr 2005 20:30:38 -0000
@@ -72,18 +72,38 @@
 Returns the \fIcharIndex\fR'th character of the \fIstring\fR argument.
 A \fIcharIndex\fR of 0 corresponds to the first character of the
 string.  \fIcharIndex\fR may be specified as follows:
+.VS 8.5
 .RS
 .IP \fIinteger\fR 10
-The char specified at this integral index.
+For any index value that passes \fBstring is integer -strict\fR,
+the char specified at this integral index
+(e.g. \fB2\fR would refer to the "c" in "abcd").
 .IP \fBend\fR 10
-The last char of the string.
-.IP \fBend\-\fIinteger\fR 10
-The last char of the string minus the specified integer offset
+The last char of the string
+(e.g. \fBend\fR would refer to the "d" in "abcd").
+.IP \fBend\-\fIN\fR 10
+The last char of the string minus the specified integer offset \fIN\fR
 (e.g. \fBend\-1\fR would refer to the "c" in "abcd").
+.IP \fBend\+\fIN\fR 10
+The last char of the string plus the specified integer offset \fIN\fR
+(e.g. \fBend\+\-1\fR would refer to the "c" in "abcd").
+.IP \fIM\fR\+\fIN\fR 10
+The char specified at the integral index that is the sum of 
+integer values \fIM\fR and \fIN\fR
+(e.g. \fB1\+1\fR would refer to the "c" in "abcd").
+.IP \fIM\fR\-\fIN\fR 10
+The char specified at the integral index that is the difference of 
+integer values \fIM\fR and \fIN\fR
+(e.g. \fB2\-1\fR would refer to the "b" in "abcd").
+.PP
+In the specifications above, the integer value \fIM\fR contains no
+trailing whitespace and the integer value \fIN\fR contains no
+leading whitespace.
 .PP
 If \fIcharIndex\fR is less than 0 or greater than or equal to the
-length of the string then an empty string is returned.
+length of the string then this command returns an empty string.
 .RE
+.VE
 .TP
 \fBstring is \fIclass\fR ?\fB\-strict\fR? ?\fB\-failindex \fIvarname\fR? \fIstring\fR
 Returns 1 if \fIstring\fR is a valid member of the specified character
Index: generic/tclCmdMZ.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCmdMZ.c,v
retrieving revision 1.116
diff -u -r1.116 tclCmdMZ.c
--- generic/tclCmdMZ.c	8 Apr 2005 10:42:51 -0000	1.116
+++ generic/tclCmdMZ.c	29 Apr 2005 20:30:39 -0000
@@ -90,7 +90,7 @@
     int i, indices, match, about, offset, all, doinline, numMatchesSaved;
     int cflags, eflags, stringLength;
     Tcl_RegExp regExpr;
-    Tcl_Obj *objPtr, *resultPtr = NULL;
+    Tcl_Obj *objPtr, *startIndex = NULL, *resultPtr = NULL;
     Tcl_RegExpInfo info;
     static CONST char *options[] = {
 	"-all",		"-about",	"-indices",	"-inline",
@@ -121,7 +121,7 @@
 	}
 	if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
 		&index) != TCL_OK) {
-	    return TCL_ERROR;
+	    goto optionError;
 	}
 	switch ((enum options) index) {
 	    case REGEXP_ALL: {
@@ -161,15 +161,18 @@
 		break;
 	    }
 	    case REGEXP_START: {
+		int temp;
 		if (++i >= objc) {
 		    goto endOfForLoop;
 		}
-		if (Tcl_GetIntFromObj(interp, objv[i], &offset) != TCL_OK) {
-		    return TCL_ERROR;
+		if (TclGetIntForIndex(interp, objv[i], 0, &temp) != TCL_OK) {
+		    goto optionError;
 		}
-		if (offset < 0) {
-		    offset = 0;
+		if (startIndex) {
+		    Tcl_DecrRefCount(startIndex);
 		}
+		startIndex = objv[i];
+		Tcl_IncrRefCount(startIndex);
 		break;
 	    }
 	    case REGEXP_LAST: {
@@ -183,7 +186,7 @@
     if ((objc - i) < (2 - about)) {
 	Tcl_WrongNumArgs(interp, 1, objv, 
 	  "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
-	return TCL_ERROR;
+	goto optionError;
     }
     objc -= i;
     objv += i;
@@ -194,7 +197,7 @@
 	 */
 	Tcl_AppendResult(interp, "regexp match variables not allowed",
 		" when using -inline", (char *) NULL);
-	return TCL_ERROR;
+	goto optionError;
     }
 
     /*
@@ -203,6 +206,10 @@
     if (about) {
 	regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
 	if ((regExpr == NULL) || (TclRegAbout(interp, regExpr) < 0)) {
+optionError:
+	    if (startIndex) {
+		Tcl_DecrRefCount(startIndex);
+	    }
 	    return TCL_ERROR;
 	}
 	return TCL_OK;
@@ -216,6 +223,14 @@
     objPtr = objv[1];
     stringLength = Tcl_GetCharLength(objPtr);
 
+    if (startIndex) {
+	TclGetIntForIndex(NULL, startIndex, stringLength, &offset);
+	Tcl_DecrRefCount(startIndex);
+	if (offset < 0) {
+	    offset = 0;
+	}
+    }
+
     regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
     if (regExpr == NULL) {
 	return TCL_ERROR;
@@ -426,7 +441,7 @@
     int start, end, subStart, subEnd, match;
     Tcl_RegExp regExpr;
     Tcl_RegExpInfo info;
-    Tcl_Obj *resultPtr, *subPtr, *objPtr;
+    Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
     Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
 
     static CONST char *options[] = {
@@ -455,7 +470,7 @@
 	}
 	if (Tcl_GetIndexFromObj(interp, objv[idx], options, "switch",
 		TCL_EXACT, &index) != TCL_OK) {
-	    return TCL_ERROR;
+	    goto optionError;
 	}
 	switch ((enum options) index) {
 	    case REGSUB_ALL: {
@@ -483,15 +498,18 @@
 		break;
 	    }
 	    case REGSUB_START: {
+		int temp;
 		if (++idx >= objc) {
 		    goto endOfForLoop;
 		}
-		if (Tcl_GetIntFromObj(interp, objv[idx], &offset) != TCL_OK) {
-		    return TCL_ERROR;
+		if (TclGetIntForIndex(interp, objv[idx], 0, &temp) != TCL_OK) {
+		    goto optionError;
 		}
-		if (offset < 0) {
-		    offset = 0;
+		if (startIndex) {
+		    Tcl_DecrRefCount(startIndex);
 		}
+		startIndex = objv[idx];
+		Tcl_IncrRefCount(startIndex);
 		break;
 	    }
 	    case REGSUB_LAST: {
@@ -504,12 +522,25 @@
     if (objc-idx < 3 || objc-idx > 4) {
 	Tcl_WrongNumArgs(interp, 1, objv,
 		"?switches? exp string subSpec ?varName?");
-	return TCL_ERROR;
+optionError:
+	    if (startIndex) {
+		Tcl_DecrRefCount(startIndex);
+	    }
+	    return TCL_ERROR;
     }
 
     objc -= idx;
     objv += idx;
 
+    if (startIndex) {
+	int stringLength = Tcl_GetCharLength(objv[1]);
+	TclGetIntForIndex(NULL, startIndex, stringLength, &offset);
+	Tcl_DecrRefCount(startIndex);
+	if (offset < 0) {
+	    offset = 0;
+	}
+    }
+
     if (all && (offset == 0)
 	    && (strpbrk(TclGetString(objv[2]), "&\\") == NULL)
 	    && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
Index: generic/tclUtil.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclUtil.c,v
retrieving revision 1.55
diff -u -r1.55 tclUtil.c
--- generic/tclUtil.c	12 Apr 2005 20:28:48 -0000	1.55
+++ generic/tclUtil.c	29 Apr 2005 20:30:39 -0000
@@ -2269,15 +2269,14 @@
  *
  *	This procedure returns an integer corresponding to the list index
  *	held in a Tcl object. The Tcl object's value is expected to be
- *	either an integer or a string of the form "end([+-]integer)?". 
+ *	in the format integer([+-]integer)? or the format end([+-]integer)?. 
  *
  * Results:
  *	The return value is normally TCL_OK, which means that the index was
  *	successfully stored into the location referenced by "indexPtr".  If
  *	the Tcl object referenced by "objPtr" has the value "end", the
- *	value stored is "endValue". If "objPtr"s values is not of the form
- *	"end([+-]integer)?" and
- *	can not be converted to an integer, TCL_ERROR is returned and, if
+ *	value stored is "endValue". If "objPtr"s values is not of one
+ *	of the expected formats, TCL_ERROR is returned and, if
  *	"interp" is non-NULL, an error message is left in the interpreter's
  *	result object.
  *
@@ -2313,10 +2312,51 @@
 	*indexPtr = endValue + objPtr->internalRep.longValue;
 
     } else {
+	int opIdx, length;
+	char *bytes = Tcl_GetStringFromObj(objPtr, &length);
+	char *p = bytes;
+
+	while (length && isspace(UCHAR(*p))) { /* INTL: ISO space. */
+	    length--; p++;
+	}
+	if (length == 0) {
+            goto parseError;
+	}
+	if ((*p == '+') || (*p == '-')) {
+	    p++; length--;
+	}
+	opIdx = TclParseInteger(p, length) + (int) (p-bytes);
+	if (opIdx) {
+	    int code, first, second;
+	    char savedOp = bytes[opIdx];
+	    if ((savedOp != '+') && (savedOp != '-')) {
+		goto parseError;
+	    }
+	    if (isspace(UCHAR(bytes[opIdx+1]))) {
+		goto parseError;
+	    }
+	    bytes[opIdx] = '\0';
+	    code = Tcl_GetInt(interp, bytes, &first);
+	    bytes[opIdx] = savedOp;
+	    if (code == TCL_ERROR)  {
+		goto parseError;
+	    }
+	    if (TCL_ERROR == Tcl_GetInt(interp, bytes+opIdx+1, &second))  {
+		goto parseError;
+	    }
+	    if (savedOp == '+') {
+		*indexPtr = first + second;
+	    } else {
+		*indexPtr = first - second;
+	    }
+	    return TCL_OK;
+	}
+
 	/*
 	 * Report a parse error.
 	 */
 
+parseError:
 	if (interp != NULL) {
 	    char *bytes = Tcl_GetString(objPtr);
 	    /*
@@ -2326,7 +2366,8 @@
 	     */
 	    Tcl_ResetResult(interp);
 	    Tcl_AppendResult(interp, "bad index \"", bytes,
-		    "\": must be integer or end?-integer?", (char *) NULL);
+		    "\": must be integer?[+-]integer? or end?[+-]integer?",
+		    (char *) NULL);
 	    if (!strncmp(bytes, "end-", 3)) {
 		bytes += 3;
 	    }
@@ -2383,7 +2424,7 @@
  *
  * SetEndOffsetFromAny --
  *
- *	Look for a string of the form "end-offset" and convert it
+ *	Look for a string of the form "end[+-]offset" and convert it
  *	to an internal representation holding the offset.
  *
  * Results:
@@ -2419,7 +2460,7 @@
 	if (interp != NULL) {
 	    Tcl_ResetResult(interp);
 	    Tcl_AppendResult(interp, "bad index \"", bytes,
-		    "\": must be end?-integer?", (char*) NULL);
+		    "\": must be end?[+-]integer?", (char*) NULL);
 	}
 	return TCL_ERROR;
     }
@@ -2428,15 +2469,20 @@
 
     if (length <= 3) {
 	offset = 0;
-    } else if ((length > 4) && (bytes[3] == '-')) {
+    } else if ((length > 4) && ((bytes[3] == '-') || (bytes[3] == '+'))) {
 	/*
 	 * This is our limited string expression evaluator.  Pass everything
 	 * after "end-" to Tcl_GetInt, then reverse for offset.
 	 */
+	if (isspace(UCHAR(bytes[4]))) {
+	    return TCL_ERROR;
+	}
 	if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) {
 	    return TCL_ERROR;
 	}
-	offset = -offset;
+	if (bytes[3] == '-') {
+	    offset = -offset;
+	}
     } else {
 	/*
 	 * Conversion failed.  Report the error.
@@ -2444,7 +2490,7 @@
 	if (interp != NULL) {
 	    Tcl_ResetResult(interp);
 	    Tcl_AppendResult(interp, "bad index \"", bytes,
-		    "\": must be integer or end?-integer?", (char *) NULL);
+		    "\": must be end?[+-]integer?", (char *) NULL);
 	}
 	return TCL_ERROR;
     }
Index: tests/cmdIL.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/cmdIL.test,v
retrieving revision 1.23
diff -u -r1.23 cmdIL.test
--- tests/cmdIL.test	14 Oct 2004 17:20:11 -0000	1.23
+++ tests/cmdIL.test	29 Apr 2005 20:30:41 -0000
@@ -59,7 +59,7 @@
 } {1 {"-index" option must be followed by list index}}
 test cmdIL-1.12 {Tcl_LsortObjCmd procedure, -index option} {
     list [catch {lsort -index foo {1 3 2 5}} msg] $msg
-} {1 {bad index "foo": must be integer or end?-integer?}}
+} {1 {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}}
 test cmdIL-1.13 {Tcl_LsortObjCmd procedure, -index option} {
     lsort -index end -integer {{2 25} {10 20 50 100} {3 16 42} 1}
 } {1 {2 25} {3 16 42} {10 20 50 100}}
Index: tests/compile.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/compile.test,v
retrieving revision 1.36
diff -u -r1.36 compile.test
--- tests/compile.test	14 Jan 2005 15:27:53 -0000	1.36
+++ tests/compile.test	29 Apr 2005 20:30:41 -0000
@@ -236,15 +236,15 @@
 	lindex a bogus
     }
     list [catch {p} msg] $msg
-} {1 {bad index "bogus": must be integer or end?-integer?}}
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
 test compile-11.2 {Tcl_Append*: ensure Tcl_ResetResult is used properly} {
     proc p {} { set r [list foobar] ; string index a bogus }
     list [catch {p} msg] $msg
-} {1 {bad index "bogus": must be integer or end?-integer?}}
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
 test compile-11.3 {Tcl_Append*: ensure Tcl_ResetResult is used properly} {
     proc p {} { set r [list foobar] ; string index a 09 }
     list [catch {p} msg] $msg
-} {1 {bad index "09": must be integer or end?-integer? (looks like invalid octal number)}}
+} {1 {bad index "09": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 test compile-11.4 {Tcl_Append*: ensure Tcl_ResetResult is used properly} {
     proc p {} { set r [list foobar] ; array set var {one two many} }
     list [catch {p} msg] $msg
Index: tests/lindex.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/lindex.test,v
retrieving revision 1.11
diff -u -r1.11 lindex.test
--- tests/lindex.test	14 Nov 2003 20:44:46 -0000	1.11
+++ tests/lindex.test	29 Apr 2005 20:30:41 -0000
@@ -49,7 +49,7 @@
 test lindex-2.4 {malformed index list} testevalex {
     set x \{
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} {1 bad\ index\ \"\{\":\ must\ be\ integer\ or\ end?-integer?}
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
 
 # Indices that are integers or convertible to integers
 
@@ -76,12 +76,12 @@
 test lindex-3.5 {bad octal} testevalex {
     set x 08
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} "1 {bad index \"08\": must be integer or end?-integer? (looks like invalid octal number)}"
+} {1 {bad index "08": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 
 test lindex-3.6 {bad octal} testevalex {
     set x -09
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} "1 {bad index \"-09\": must be integer or end?-integer? (looks like invalid octal number)}"
+} {1 {bad index "-09": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 
 test lindex-3.7 {indexes don't shimmer wide ints} {
     set x [expr {(wide(1)<<31) - 2}]
@@ -118,31 +118,31 @@
 test lindex-4.6 {bad octal} testevalex {
     set x end-08
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} "1 {bad index \"end-08\": must be integer or end?-integer? (looks like invalid octal number)}"
+} {1 {bad index "end-08": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 
 test lindex-4.7 {bad octal} testevalex {
     set x end--09
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} "1 {bad index \"end--09\": must be integer or end?-integer?}"
+} {1 {bad index "end--09": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lindex-4.8 {bad integer, not octal} testevalex {
     set x end-0a2
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} "1 {bad index \"end-0a2\": must be integer or end?-integer?}"
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
-test lindex-4.9 {incomplete end} testevalex {
-    set x en
+test lindex-4.9 {obsolete test} testevalex {
+    set x end
     list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
 } {c c}
 
 test lindex-4.10 {incomplete end-} testevalex {
     set x end-
     list [catch { testevalex {lindex {a b c} $x} } result] $result
-} "1 {bad index \"end-\": must be integer or end?-integer?}"
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lindex-5.1 {bad second index} testevalex {
     list [catch { testevalex {lindex {a b c} 0 0a2} } result] $result
-} "1 {bad index \"0a2\": must be integer or end?-integer?}"
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lindex-5.2 {good second index} testevalex {
     testevalex {lindex {{a b c} {d e f} {g h i}} 1 2}
@@ -245,7 +245,7 @@
 test lindex-10.4 {malformed index list} {
     set x \{
     list [catch { lindex {a b c} $x } result] $result
-} {1 bad\ index\ \"\{\":\ must\ be\ integer\ or\ end?-integer?}
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
 
 # Indices that are integers or convertible to integers
 
@@ -284,12 +284,12 @@
 test lindex-11.5 {bad octal} {
     set x 08
     list [catch { lindex {a b c} $x } result] $result
-} "1 {bad index \"08\": must be integer or end?-integer? (looks like invalid octal number)}"
+} {1 {bad index "08": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 
 test lindex-11.6 {bad octal} {
     set x -09
     list [catch { lindex {a b c} $x } result] $result
-} "1 {bad index \"-09\": must be integer or end?-integer? (looks like invalid octal number)}"
+} {1 {bad index "-09": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 
 # Indices relative to end
 
@@ -336,20 +336,20 @@
 test lindex-12.6 {bad octal} {
     set x end-08
     list [catch { lindex {a b c} $x } result] $result
-} "1 {bad index \"end-08\": must be integer or end?-integer? (looks like invalid octal number)}"
+} {1 {bad index "end-08": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 
 test lindex-12.7 {bad octal} {
     set x end--09
     list [catch { lindex {a b c} $x } result] $result
-} "1 {bad index \"end--09\": must be integer or end?-integer?}"
+} {1 {bad index "end--09": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lindex-12.8 {bad integer, not octal} {
     set x end-0a2
     list [catch { lindex {a b c} $x } result] $result
-} "1 {bad index \"end-0a2\": must be integer or end?-integer?}"
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
-test lindex-12.9 {incomplete end} {
-    set x en
+test lindex-12.9 {obsolete test} {
+    set x end
     catch {
 	list [lindex {a b c} $x] [lindex {a b c} $x]
     } result
@@ -359,11 +359,11 @@
 test lindex-12.10 {incomplete end-} {
     set x end-
     list [catch { lindex {a b c} $x } result] $result
-} "1 {bad index \"end-\": must be integer or end?-integer?}"
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lindex-13.1 {bad second index} {
     list [catch { lindex {a b c} 0 0a2 } result] $result
-} "1 {bad index \"0a2\": must be integer or end?-integer?}"
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lindex-13.2 {good second index} {
     catch {
Index: tests/linsert.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/linsert.test,v
retrieving revision 1.8
diff -u -r1.8 linsert.test
--- tests/linsert.test	10 Apr 2000 17:19:01 -0000	1.8
+++ tests/linsert.test	29 Apr 2005 20:30:41 -0000
@@ -90,7 +90,7 @@
 } {1 {wrong # args: should be "linsert list index element ?element ...?"}}
 test linsert-2.3 {linsert errors} {
     list [catch {linsert a 12x 2} msg] $msg
-} {1 {bad index "12x": must be integer or end?-integer?}}
+} {1 {bad index "12x": must be integer?[+-]integer? or end?[+-]integer?}}
 test linsert-2.4 {linsert errors} {
     list [catch {linsert \{ 12 2} msg] $msg
 } {1 {unmatched open brace in list}}
Index: tests/lrange.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/lrange.test,v
retrieving revision 1.7
diff -u -r1.7 lrange.test
--- tests/lrange.test	10 Apr 2000 17:19:01 -0000	1.7
+++ tests/lrange.test	29 Apr 2005 20:30:41 -0000
@@ -43,7 +43,7 @@
     lrange {a b c d e} -2 -1
 } {}
 test lrange-1.9 {range of list elements} {
-    lrange {a b c d e} -2 e
+    lrange {a b c d e} -2 end
 } {a b c d e}
 test lrange-1.10 {range of list elements} {
     lrange "a b\{c d" 1 2
@@ -55,7 +55,7 @@
     lrange "a b c d" end 100000
 } d
 test lrange-1.13 {range of list elements} {
-    lrange "a b c d" e 3
+    lrange "a b c d" end 3
 } d
 test lrange-1.14 {range of list elements} {
     lrange "a b c d" end 2
@@ -75,10 +75,10 @@
 } {1 {wrong # args: should be "lrange list first last"}}
 test lrange-2.3 {error conditions} {
     list [catch {lrange a b 6} msg] $msg
-} {1 {bad index "b": must be integer or end?-integer?}}
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
 test lrange-2.4 {error conditions} {
     list [catch {lrange a 0 enigma} msg] $msg
-} {1 {bad index "enigma": must be integer or end?-integer?}}
+} {1 {bad index "enigma": must be integer?[+-]integer? or end?[+-]integer?}}
 test lrange-2.5 {error conditions} {
     list [catch {lrange "a \{b c" 3 4} msg] $msg
 } {1 {unmatched open brace in list}}
Index: tests/lreplace.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/lreplace.test,v
retrieving revision 1.7
diff -u -r1.7 lreplace.test
--- tests/lreplace.test	10 Apr 2000 17:19:01 -0000	1.7
+++ tests/lreplace.test	29 Apr 2005 20:30:41 -0000
@@ -110,13 +110,13 @@
 } {1 {wrong # args: should be "lreplace list first last ?element element ...?"}}
 test lreplace-2.3 {lreplace errors} {
     list [catch {lreplace x a 10} msg] $msg
-} {1 {bad index "a": must be integer or end?-integer?}}
+} {1 {bad index "a": must be integer?[+-]integer? or end?[+-]integer?}}
 test lreplace-2.4 {lreplace errors} {
     list [catch {lreplace x 10 x} msg] $msg
-} {1 {bad index "x": must be integer or end?-integer?}}
+} {1 {bad index "x": must be integer?[+-]integer? or end?[+-]integer?}}
 test lreplace-2.5 {lreplace errors} {
     list [catch {lreplace x 10 1x} msg] $msg
-} {1 {bad index "1x": must be integer or end?-integer?}}
+} {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}}
 test lreplace-2.6 {lreplace errors} {
     list [catch {lreplace x 3 2} msg] $msg
 } {1 {list doesn't contain element 3}}
Index: tests/lsearch.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/lsearch.test,v
retrieving revision 1.13
diff -u -r1.13 lsearch.test
--- tests/lsearch.test	15 Oct 2003 13:15:45 -0000	1.13
+++ tests/lsearch.test	29 Apr 2005 20:30:41 -0000
@@ -284,7 +284,7 @@
 } 3
 test lsearch-10.4 {offset searching} {
     list [catch {lsearch -start foobar {a b c a b c} a} msg] $msg
-} {1 {bad index "foobar": must be integer or end?-integer?}}
+} {1 {bad index "foobar": must be integer?[+-]integer? or end?[+-]integer?}}
 test lsearch-10.5 {offset searching} {
     list [catch {lsearch -start 1 2} msg] $msg
 } {1 {missing starting index}}
@@ -415,7 +415,7 @@
 } {1 {element 2 missing from sublist "a c"}}
 test lsearch-20.2 {lsearch -index option, malformed index} {
     list [catch {lsearch -index foo {{a c} {a b} {a a}} a} msg] $msg
-} {1 {bad index "foo": must be integer or end?-integer?}}
+} {1 {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}}
 test lsearch-20.3 {lsearch -index option, malformed index} {
     list [catch {lsearch -index \{ {{a c} {a b} {a a}} a} msg] $msg
 } {1 {unmatched open brace in list}}
Index: tests/lset.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/lset.test,v
retrieving revision 1.4
diff -u -r1.4 lset.test
--- tests/lset.test	14 Nov 2003 20:44:46 -0000	1.4
+++ tests/lset.test	29 Apr 2005 20:30:41 -0000
@@ -51,7 +51,7 @@
     list [catch {
 	testevalex {lset x {{bad}1} 3}
     } msg] $msg
-} "1 {bad index \"{bad}1\": must be integer or end?-integer?}"
+} {1 {bad index "{bad}1": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lset-3.1 {lset, not compiled, 3 args, data duplicated} testevalex {
     set x {0 1 2}
@@ -99,7 +99,7 @@
     list [catch {
 	testevalex {lset a [list 2a2] w}
     } msg] $msg
-} {1 {bad index "2a2": must be integer or end?-integer?}}
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lset-4.3 {lset, not compiled, 3 args, index out of range} testevalex {
     set a {x y z}
@@ -141,7 +141,7 @@
     list [catch {
 	testevalex {lset a 2a2 w}
     } msg] $msg
-} {1 {bad index "2a2": must be integer or end?-integer?}}
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lset-4.9 {lset, not compiled, 3 args, index out of range} testevalex {
     set a {x y z}
@@ -300,12 +300,12 @@
 test lset-8.3 {lset, not compiled, bad second index} testevalex {
     set a {{b c} {d e}}
     list [catch {testevalex {lset a 0 2a2 f}} msg] $msg
-} {1 {bad index "2a2": must be integer or end?-integer?}}
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lset-8.4 {lset, not compiled, bad second index} testevalex {
     set a {{b c} {d e}}
     list [catch {testevalex {lset a {0 2a2} f}} msg] $msg
-} {1 {bad index "2a2": must be integer or end?-integer?}}
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test lset-8.5 {lset, not compiled, second index out of range} testevalex {
     set a {{b c} {d e} {f g}}
Index: tests/regexp.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/regexp.test,v
retrieving revision 1.25
diff -u -r1.25 regexp.test
--- tests/regexp.test	14 Oct 2003 18:23:31 -0000	1.25
+++ tests/regexp.test	29 Apr 2005 20:30:41 -0000
@@ -220,7 +220,7 @@
 } {1 {couldn't set variable "f1(f2)"}}
 test regexp-6.9 {regexp errors, -start bad int check} {
     list [catch {regexp -start bogus {^$} {}} msg] $msg
-} {1 {expected integer but got "bogus"}}
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test regexp-7.1 {basic regsub operation} {
     list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
@@ -377,7 +377,7 @@
 } {1 {couldn't set variable "f1(f2)"}}
 test regexp-11.8 {regsub errors, -start bad int check} {
     list [catch {regsub -start bogus pattern string rep var} msg] $msg
-} {1 {expected integer but got "bogus"}}
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
 test regexp-11.9 {regsub without final variable name returns value} {
     regsub b abaca X
 } {aXaca}
@@ -467,6 +467,20 @@
 test regexp-15.6 {regexp -start, loss of ^$ behavior} {
     list [regexp -start 2 {^$} {}]
 } {0}
+test regexp-15.7 {regexp -start, double option} {
+    regexp -start 2 -start 0 a abc
+} 1
+test regexp-15.8 {regexp -start, double option} {
+    regexp -start 0 -start 2 a abc
+} 0
+test regexp-15.9 {regexp -start, end relative index} {
+    catch {unset x}
+    list [regexp -start end {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.10 {regexp -start, end relative index} {
+    catch {unset x}
+    list [regexp -start end-1 {\d} 1abc2de3 x] [info exists x] $x
+} {1 1 3}
 
 test regexp-16.1 {regsub -start} {
     catch {unset x}
@@ -485,6 +499,18 @@
     lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
     lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
 } {5 /a/b/c/d/e 3 ab/c/d/e}
+test regexp-16.5 {regsub -start, double option} {
+    list [regsub -start 2 -start 0 a abc c x] $x
+} {1 cbc}
+test regexp-16.6 {regsub -start, double option} {
+    list [regsub -start 0 -start 2 a abc c x] $x
+} {0 abc}
+test regexp-16.7 {regexp -start, end relative index} {
+    list [regsub -start end a aaa b x] $x
+} {0 aaa}
+test regexp-16.8 {regexp -start, end relative index} {
+    list [regsub -start end-1 a aaa b x] $x
+} {1 aab}
 
 test regexp-17.1 {regexp -inline} {
     regexp -inline b ababa
Index: tests/regexpComp.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/regexpComp.test,v
retrieving revision 1.9
diff -u -r1.9 regexpComp.test
--- tests/regexpComp.test	25 May 2004 18:58:05 -0000	1.9
+++ tests/regexpComp.test	29 Apr 2005 20:30:41 -0000
@@ -301,7 +301,7 @@
     evalInProc {
 	list [catch {regexp -start bogus {^$} {}} msg] $msg
     }
-} {1 {expected integer but got "bogus"}}
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
 
 test regexpComp-7.1 {basic regsub operation} {
     evalInProc {
@@ -542,7 +542,7 @@
     evalInProc {
 	list [catch {regsub -start bogus pattern string rep var} msg] $msg
     }
-} {1 {expected integer but got "bogus"}}
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
 
 # This test crashes on the Mac unless you increase the Stack Space to about 1
 # Meg.  This is probably bigger than most users want... 
Index: tests/string.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/string.test,v
retrieving revision 1.45
diff -u -r1.45 string.test
--- tests/string.test	22 Apr 2005 16:26:04 -0000	1.45
+++ tests/string.test	29 Apr 2005 20:30:41 -0000
@@ -176,7 +176,7 @@
 } {1 {wrong # args: should be "string first subString string ?startIndex?"}}
 test string-4.2 {string first, bad args} {
     list [catch {string first a b c} msg] $msg
-} {1 {bad index "c": must be integer or end?-integer?}}
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-4.3 {string first, too many args} {
     list [catch {string first a b 5 d} msg] $msg
 } {1 {wrong # args: should be "string first subString string ?startIndex?"}}
@@ -241,7 +241,7 @@
 } {0 {}}
 test string-5.7 {string index} {
     list [catch {string index a xyz} msg] $msg
-} {1 {bad index "xyz": must be integer or end?-integer?}}
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-5.8 {string index} {
     string index abc end
 } c
@@ -276,10 +276,10 @@
 } 0
 test string-5.17 {string index, bad integer} {
     list [catch {string index "abc" 08} msg] $msg
-} {1 {bad index "08": must be integer or end?-integer? (looks like invalid octal number)}}
+} {1 {bad index "08": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 test string-5.18 {string index, bad integer} {
     list [catch {string index "abc" end-00289} msg] $msg
-} {1 {bad index "end-00289": must be integer or end?-integer? (looks like invalid octal number)}}
+} {1 {bad index "end-00289": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 test string-5.19 {string index, bytearray object out of bounds} {
     string index [binary format I* {0x50515253 0x52}] -1
 } {}
@@ -667,7 +667,7 @@
 } {1 {wrong # args: should be "string last subString string ?startIndex?"}}
 test string-7.2 {string last, bad args} {
     list [catch {string last a b c} msg] $msg
-} {1 {bad index "c": must be integer or end?-integer?}}
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-7.3 {string last, too many args} {
     list [catch {string last a b c d} msg] $msg
 } {1 {wrong # args: should be "string last subString string ?startIndex?"}}
@@ -1022,7 +1022,7 @@
     string range abcdefghijklmnop 7 1000
 } {hijklmnop}
 test string-12.6 {string range} {
-    string range abcdefghijklmnop 10 e
+    string range abcdefghijklmnop 10 end
 } {klmnop}
 test string-12.7 {string range, last < first} {
     string range abcdefghijklmnop 10 9
@@ -1041,15 +1041,15 @@
 } {abcdefghijklmnop}
 test string-12.12 {string range} {
     list [catch {string range abc abc 1} msg] $msg
-} {1 {bad index "abc": must be integer or end?-integer?}}
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-12.13 {string range} {
     list [catch {string range abc 1 eof} msg] $msg
-} {1 {bad index "eof": must be integer or end?-integer?}}
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-12.14 {string range} {
     string range abcdefghijklmnop end-1 end
 } {op}
 test string-12.15 {string range} {
-    string range abcdefghijklmnop e 1000
+    string range abcdefghijklmnop end 1000
 } {p}
 test string-12.16 {string range} {
     string range abcdefghijklmnop end end-1
@@ -1132,7 +1132,7 @@
     string replace abcdefghijklmnop 7 1000
 } {abcdefg}
 test string-14.7 {string replace} {
-    string replace abcdefghijklmnop 10 e
+    string replace abcdefghijklmnop 10 end
 } {abcdefghij}
 test string-14.8 {string replace} {
     string replace abcdefghijklmnop 10 9
@@ -1151,15 +1151,15 @@
 } {}
 test string-14.13 {string replace} {
     list [catch {string replace abc abc 1} msg] $msg
-} {1 {bad index "abc": must be integer or end?-integer?}}
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-14.14 {string replace} {
     list [catch {string replace abc 1 eof} msg] $msg
-} {1 {bad index "eof": must be integer or end?-integer?}}
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-14.15 {string replace} {
     string replace abcdefghijklmnop end-10 end-2 NEW
 } {abcdeNEWop}
 test string-14.16 {string replace} {
-    string replace abcdefghijklmnop 0 e foo
+    string replace abcdefghijklmnop 0 end foo
 } {foo}
 test string-14.17 {string replace} {
     string replace abcdefghijklmnop end end-1
@@ -1170,7 +1170,7 @@
 } {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
 test string-15.2 {string tolower bad args} {
     list [catch {string tolower a b} msg] $msg
-} {1 {bad index "b": must be integer or end?-integer?}}
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-15.3 {string tolower too many args} {
     list [catch {string tolower ABC 1 end oops} msg] $msg
 } {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
@@ -1201,7 +1201,7 @@
 } {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
 test string-16.2 {string toupper} {
     list [catch {string toupper a b} msg] $msg
-} {1 {bad index "b": must be integer or end?-integer?}}
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-16.3 {string toupper} {
     list [catch {string toupper a 1 end oops} msg] $msg
 } {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
@@ -1232,7 +1232,7 @@
 } {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
 test string-17.2 {string totitle} {
     list [catch {string totitle a b} msg] $msg
-} {1 {bad index "b": must be integer or end?-integer?}}
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-17.3 {string totitle} {
     string totitle abCDEf
 } {Abcdef}
@@ -1314,7 +1314,7 @@
 } {1 {wrong # args: should be "string wordend string index"}}
 test string-21.3 {string wordend} {
     list [catch {string wordend a gorp} msg] $msg
-} {1 {bad index "gorp": must be integer or end?-integer?}}
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-21.4 {string wordend} {
     string wordend abc. -1
 } 3
@@ -1360,7 +1360,7 @@
 } {1 {wrong # args: should be "string wordstart string index"}}
 test string-22.4 {string wordstart} {
     list [catch {string wordstart a gorp} msg] $msg
-} {1 {bad index "gorp": must be integer or end?-integer?}}
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
 test string-22.5 {string wordstart} {
     string wordstart "one two three_words" 400
 } 8
Index: tests/stringComp.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/stringComp.test,v
retrieving revision 1.8
diff -u -r1.8 stringComp.test
--- tests/stringComp.test	25 May 2004 18:58:05 -0000	1.8
+++ tests/stringComp.test	29 Apr 2005 20:30:41 -0000
@@ -226,7 +226,7 @@
 test stringComp-4.2 {string first, bad args} {
     proc foo {} {string first a b c}
     list [catch {foo} msg] $msg
-} {1 {bad index "c": must be integer or end?-integer?}}
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
 test stringComp-4.3 {string first, too many args} {
     proc foo {} {string first a b 5 d}
     list [catch {foo} msg] $msg
@@ -303,7 +303,7 @@
 test stringComp-5.7 {string index} {
     proc foo {} {string index a xyz}
     list [catch {foo} msg] $msg
-} {1 {bad index "xyz": must be integer or end?-integer?}}
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
 test stringComp-5.8 {string index} {
     proc foo {} {string index abc end}
     foo
@@ -352,11 +352,11 @@
 test stringComp-5.17 {string index, bad integer} {
     proc foo {} {string index "abc" 08}
     list [catch {foo} msg] $msg
-} {1 {bad index "08": must be integer or end?-integer? (looks like invalid octal number)}}
+} {1 {bad index "08": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 test stringComp-5.18 {string index, bad integer} {
     proc foo {} {string index "abc" end-00289}
     list [catch {foo} msg] $msg
-} {1 {bad index "end-00289": must be integer or end?-integer? (looks like invalid octal number)}}
+} {1 {bad index "end-00289": must be integer?[+-]integer? or end?[+-]integer? (looks like invalid octal number)}}
 test stringComp-5.19 {string index, bytearray object out of bounds} {
     proc foo {} {string index [binary format I* {0x50515253 0x52}] -1}
     foo
Index: tests/util.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/util.test,v
retrieving revision 1.14
diff -u -r1.14 util.test
--- tests/util.test	19 May 2004 20:15:32 -0000	1.14
+++ tests/util.test	29 Apr 2005 20:30:42 -0000
@@ -388,6 +388,190 @@
     list [llength [testdstring get]] [string length [testdstring get]]
 } {2 9}
 
+test util-9.0.0 {TclGetIntForIndex} {
+    string index abcd 0
+} a
+test util-9.0.1 {TclGetIntForIndex} {
+    string index abcd 0x0
+} a
+test util-9.0.2 {TclGetIntForIndex} {
+    string index abcd -0x0
+} a
+test util-9.0.3 {TclGetIntForIndex} {
+    string index abcd { 0 }
+} a
+test util-9.0.4 {TclGetIntForIndex} {
+    string index abcd { 0x0 }
+} a
+test util-9.0.5 {TclGetIntForIndex} {
+    string index abcd { -0x0 }
+} a
+test util-9.0.6 {TclGetIntForIndex} {
+    string index abcd 01
+} b
+test util-9.0.7 {TclGetIntForIndex} {
+    string index abcd { 01 }
+} b
+test util-9.1.0 {TclGetIntForIndex} {
+    string index abcd 3
+} d
+test util-9.1.1 {TclGetIntForIndex} {
+    string index abcd { 3 }
+} d
+test util-9.1.2 {TclGetIntForIndex} {
+    string index abcdefghijk 0xa
+} k
+test util-9.1.3 {TclGetIntForIndex} {
+    string index abcdefghijk { 0xa }
+} k
+test util-9.2.0 {TclGetIntForIndex} {
+    string index abcd end
+} d 
+test util-9.2.1 {TclGetIntForIndex} -body {
+    string index abcd { end}
+} -returnCodes error -match glob -result *
+test util-9.2.2 {TclGetIntForIndex} -body {
+    string index abcd {end }
+} -returnCodes error -match glob -result *
+test util-9.3 {TclGetIntForIndex} {
+    # Deprecated
+    string index abcd en
+} d
+test util-9.4 {TclGetIntForIndex} {
+    # Deprecated
+    string index abcd e
+} d
+test util-9.5.0 {TclGetIntForIndex} {
+    string index abcd end-1
+} c
+test util-9.5.1 {TclGetIntForIndex} {
+    string index abcd {end-1 }
+} c
+test util-9.5.2 {TclGetIntForIndex} -body {
+    string index abcd { end-1}
+} -returnCodes error -match glob -result *
+test util-9.6 {TclGetIntForIndex} {
+    string index abcd end+-1
+} c
+test util-9.7 {TclGetIntForIndex} {
+    string index abcd end+1
+} {}
+test util-9.8 {TclGetIntForIndex} {
+    string index abcd end--1
+} {}
+test util-9.9.0 {TclGetIntForIndex} {
+    string index abcd 0+0
+} a
+test util-9.9.1 {TclGetIntForIndex} {
+    string index abcd { 0+0 }
+} a
+test util-9.10 {TclGetIntForIndex} {
+    string index abcd 0-0
+} a
+test util-9.11 {TclGetIntForIndex} {
+    string index abcd 1+0
+} b
+test util-9.12 {TclGetIntForIndex} {
+    string index abcd 1-0
+} b
+test util-9.13 {TclGetIntForIndex} {
+    string index abcd 1+1
+} c
+test util-9.14 {TclGetIntForIndex} {
+    string index abcd 1-1
+} a
+test util-9.15 {TclGetIntForIndex} {
+    string index abcd -1+2
+} b
+test util-9.16 {TclGetIntForIndex} {
+    string index abcd -1--2
+} b
+test util-9.17 {TclGetIntForIndex} {
+    string index abcd { -1+2 }
+} b
+test util-9.18 {TclGetIntForIndex} {
+    string index abcd { -1--2 }
+} b
+test util-9.19 {TclGetIntForIndex} -body {
+    string index a {}
+} -returnCodes error -match glob -result *
+test util-9.20 {TclGetIntForIndex} -body {
+    string index a { }
+} -returnCodes error -match glob -result *
+test util-9.21 {TclGetIntForIndex} -body {
+    string index a " \r\t\n"
+} -returnCodes error -match glob -result *
+test util-9.22 {TclGetIntForIndex} -body {
+    string index a +
+} -returnCodes error -match glob -result *
+test util-9.23 {TclGetIntForIndex} -body {
+    string index a -
+} -returnCodes error -match glob -result *
+test util-9.24 {TclGetIntForIndex} -body {
+    string index a x
+} -returnCodes error -match glob -result *
+test util-9.25 {TclGetIntForIndex} -body {
+    string index a +x
+} -returnCodes error -match glob -result *
+test util-9.26 {TclGetIntForIndex} -body {
+    string index a -x
+} -returnCodes error -match glob -result *
+test util-9.27 {TclGetIntForIndex} -body {
+    string index a 0y
+} -returnCodes error -match glob -result *
+test util-9.28 {TclGetIntForIndex} -body {
+    string index a 1*
+} -returnCodes error -match glob -result *
+test util-9.29 {TclGetIntForIndex} -body {
+    string index a 0+
+} -returnCodes error -match glob -result *
+test util-9.30 {TclGetIntForIndex} -body {
+    string index a {0+ }
+} -returnCodes error -match glob -result *
+test util-9.31 {TclGetIntForIndex} -body {
+    string index a 0x
+} -returnCodes error -match glob -result *
+test util-9.32 {TclGetIntForIndex} -body {
+    string index a 0x1FFFFFFFF+0
+} -returnCodes error -match glob -result *
+test util-9.33 {TclGetIntForIndex} -body {
+    string index a 100000000000+0
+} -returnCodes error -match glob -result *
+test util-9.34 {TclGetIntForIndex} -body {
+    string index a 1.0
+} -returnCodes error -match glob -result *
+test util-9.35 {TclGetIntForIndex} -body {
+    string index a 1e23
+} -returnCodes error -match glob -result *
+test util-9.36 {TclGetIntForIndex} -body {
+    string index a 1.5e2
+} -returnCodes error -match glob -result *
+test util-9.37 {TclGetIntForIndex} -body {
+    string index a 0+x
+} -returnCodes error -match glob -result *
+test util-9.38 {TclGetIntForIndex} -body {
+    string index a 0+0x
+} -returnCodes error -match glob -result *
+test util-9.39 {TclGetIntForIndex} -body {
+    string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.40 {TclGetIntForIndex} -body {
+    string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.41 {TclGetIntForIndex} -body {
+    string index a 0+1.0
+} -returnCodes error -match glob -result *
+test util-9.42 {TclGetIntForIndex} -body {
+    string index a 0+1e2
+} -returnCodes error -match glob -result *
+test util-9.43 {TclGetIntForIndex} -body {
+    string index a 0+1.5e1
+} -returnCodes error -match glob -result *
+test util-9.44 {TclGetIntForIndex} -body {
+    string index a 0+1000000000000
+} -returnCodes error -match glob -result *
+
+
 # cleanup
 ::tcltest::cleanupTests
 return