summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstanton <stanton>1999-05-06 18:46:42 (GMT)
committerstanton <stanton>1999-05-06 18:46:42 (GMT)
commitf832cd22b120385368e264c684cf8d874014bf3b (patch)
tree9c149c65795f698ce02226359670d8bc28d9895a
parenta23a8f73b3f2aba2722a1363e2d822018fbf504c (diff)
downloadtcl-f832cd22b120385368e264c684cf8d874014bf3b.zip
tcl-f832cd22b120385368e264c684cf8d874014bf3b.tar.gz
tcl-f832cd22b120385368e264c684cf8d874014bf3b.tar.bz2
* doc/string.n:
* tests/cmdIL.test: * tests/cmdMZ.test: * tests/error.test: * tests/ioCmd.test: * tests/lindex.test: * tests/linsert.test: * tests/lrange.test: * tests/lreplace.test: * tests/string.test: * tests/cmdIL.test: * generic/tclUtil.c: * generic/tclCmdMZ.c: Replaced "string icompare/iequal" with -nocase and -length switches to "string compare/equal". Added a -nocase option to "string map". Changed index syntax to allow integer or end?-integer? instead of a full expression. This is much simpler with safeTcl scripts since it avoids double substitution issues.
-rw-r--r--doc/string.n84
-rw-r--r--generic/tclCmdMZ.c466
-rw-r--r--generic/tclUtil.c29
-rw-r--r--tests/cmdIL.test16
-rw-r--r--tests/cmdMZ.test437
-rw-r--r--tests/error.test26
-rw-r--r--tests/ioCmd.test10
-rw-r--r--tests/lindex.test16
-rw-r--r--tests/linsert.test16
-rw-r--r--tests/lrange.test18
-rw-r--r--tests/lreplace.test20
-rw-r--r--tests/string.test1166
12 files changed, 1231 insertions, 1073 deletions
diff --git a/doc/string.n b/doc/string.n
index f93e551..183cc04 100644
--- a/doc/string.n
+++ b/doc/string.n
@@ -5,7 +5,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: string.n,v 1.6 1999/05/05 01:19:43 stanton Exp $
+'\" RCS: @(#) $Id: string.n,v 1.7 1999/05/06 18:46:42 stanton Exp $
'\"
.so man.macros
.TH string n 8.1 Tcl "Tcl Built-In Commands"
@@ -32,18 +32,19 @@ the byte length are rare. In almost all cases, you should use the
\fBstring length\fB operation. Refer to the \fBTcl_NumUtfChars\fR
manual entry for more details on the UTF-8 representation.
.TP
-\fBstring compare \fIstring1 string2\fR ?\fIlength\fR?
+\fBstring compare ?\fI-nocase\fR? ?\fI-length int\fR? \fIstring1 string2\fR
.VE 8.1
Perform a character-by-character comparison of strings \fIstring1\fR and
\fIstring2\fR in the same way as the C \fBstrcmp\fR procedure. Return
\-1, 0, or 1, depending on whether \fIstring1\fR is lexicographically
less than, equal to, or greater than \fIstring2\fR.
.VS 8.1
-If \fIlength\fR is
-specified, it works like C \fBstrncmp\fR, comparing only to the
-specified length. If \fIlength\fR is negative, it is ignored.
+If \fI-length\fR is specified, it works like C \fBstrncmp\fR,
+comparing only to the specified length. If \fI-length\fR is negative,
+it is ignored. If \fI-nocase\fR is specified, then the strings are
+compared in a case-insensitive manner.
.TP
-\fBstring equal \fIstring1 string2\fR ?\fIlength\fR?
+\fBstring equal ?\fI-nocase\fR? ?\fI-length int\fR? \fIstring1 string2\fR
.VE 8.1
Like the \fBcompare\fR method, but returns 1 when the strings
are equal, or 0 when not.
@@ -54,19 +55,6 @@ the characters in \fIstring1\fR. If found, return the index of the
first character in the first such match within \fIstring2\fR. If not
found, return \-1.
.TP
-\fBstring icompare \fIstring1 string2\fR ?\fIlength\fR?
-Perform a case-insensitive character-by-character comparison of strings
-\fIstring1\fR and
-\fIstring2\fR in the same way as the C \fBstrcasecmp\fR procedure. Return
-\-1, 0, or 1, depending on whether \fIstring1\fR is lexicographically
-less than, equal to, or greater than \fIstring2\fR. If length is
-specified, it works like C \fBstrncasecmp\fR, comparing only to the
-specified length.
-.TP
-\fBstring iequal \fIstring1 string2\fR ?\fIlength\fR?
-Like the \fBicompare\fR method, but returns 1 when the strings
-are equal, or 0 when not.
-.TP
\fBstring index \fIstring charIndex\fR
Returns the \fIcharIndex\fR'th character of the \fIstring\fR
argument. A \fIcharIndex\fR of 0 corresponds to the first
@@ -75,21 +63,69 @@ character of the string.
\fIcharIndex\fR may be specified as
follows:
.RS
-.IP \fB[\fInumber\fB]\fR 10
-The char specified at this numerical index
+.IP \fB[\fIinteger\fB]\fR 10
+The char specified at this integral index
.IP \fBend\fR 10
The last char of the string.
.IP \fIexpression\fR 10
A Tcl expression that returns a number.
-.IP \fBend[+-]\fIexpression\fR 10
-The last char of the string plus or minus the number specified
-in the expression (e.g. \fBend-1\fR).
+.IP \fBend-\fIinteger\fR 10
+The last char of the string minus the specified integer
+offset (e.g. \fBend-1\fR).
.PP
.VE 8.1
If \fIcharIndex\fR is less than 0 or greater than
or equal to the length of the string then an empty string is
returned.
.RE
+.VS 8.1
+.TP
+\fBstring is \fIclass\fR ?\fI-strict\fR? ?\fI-failindex varname\fR? \fIstring\fR
+See if \fIstring\fR is a valid form of the specified class. If
+\fI-strict\fR is specified, then an empty string returns 0, otherwise and
+empty string will return 1 on any class. If \fI-failindex\fR is specified,
+then if the function returns 0, the index in the string where the class was
+no longer valid will be stored in the variable named \fIvarname\fR. The
+\fIvarname\fR will not be set if the function returns 1. The following
+class definitions are allowed (the class name can be abbreviated):
+.RS
+.IP \fBalnum\fR 10
+Any Unicode alphabet or digit character.
+.IP \fBalpha\fR 10
+Any Unicode alphabet character.
+.IP \fBascii\fR 10
+Any character with a value less than \\u0080 (those that
+are in the 7-bit ascii range).
+.IP \fBboolean\fR 10
+Any of the forms allowed to Tcl_GetBoolean.
+.IP \fBdigit\fR 10
+Any Unicode digit character.
+.IP \fBdouble\fR 10
+Any of the valid forms for a double in Tcl, with optional surrounding
+whitespace. In case of under/overflow in the value, 0 is returned
+and the \fIvarname\fR will contain -1.
+.IP \fBfalse\fR 10
+Any of the forms allowed to Tcl_GetBoolean where the value is false.
+.IP \fBinteger\fR 10
+Any of the valid forms for an integer in Tcl, with optional surrounding
+whitespace. In case of under/overflow in the value, 0 is returned
+and the \fIvarname\fR will contain -1.
+.IP \fBlower\fR 10
+Any Unicode lower case alphabet character.
+.IP \fBspace\fR 10
+Any Unicode space character.
+.IP \fBtrue\fR 10
+Any of the forms allowed to Tcl_GetBoolean where the value is true.
+.IP \fBupper\fR 10
+Any upper case alphabet character in the Unicode character set.
+.IP \fBwordchar\fR 10
+Any Unicode word character. That is any alphanumeric character,
+and any Unicode connector punctuation characters (ie: underscore).
+.RE
+In the case of \fBboolean\fR, \fBtrue\fR and \fBfalse\fR, if the
+function will return 0, the \fIvarname\fR will always be set to 0,
+due to the varied nature of a valid boolean value.
+.VE 8.1
.TP
\fBstring last \fIstring1 string2\fR
Search \fIstring2\fR for a sequence of characters that exactly match
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 90b9687..5a3833b 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCmdMZ.c,v 1.5 1999/05/04 02:57:55 stanton Exp $
+ * RCS: @(#) $Id: tclCmdMZ.c,v 1.6 1999/05/06 18:46:42 stanton Exp $
*/
#include "tclInt.h"
@@ -807,23 +807,21 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
int length1, length2;
static char *options[] = {
"bytelength", "compare", "equal", "first",
- "icompare", "iequal", "index",
- "last", "length", "map",
- "match", "range", "repeat", "replace",
- "tolower", "toupper", "totitle",
+ "index", "is", "last", "length",
+ "map", "match", "range", "repeat",
+ "replace", "tolower", "toupper", "totitle",
"trim", "trimleft", "trimright",
"wordend", "wordstart", (char *) NULL
};
enum options {
STR_BYTELENGTH, STR_COMPARE, STR_EQUAL, STR_FIRST,
- STR_ICOMPARE, STR_IEQUAL, STR_INDEX,
- STR_LAST, STR_LENGTH, STR_MAP,
- STR_MATCH, STR_RANGE, STR_REPEAT, STR_REPLACE,
- STR_TOLOWER, STR_TOUPPER, STR_TOTITLE,
+ STR_INDEX, STR_IS, STR_LAST, STR_LENGTH,
+ STR_MAP, STR_MATCH, STR_RANGE, STR_REPEAT,
+ STR_REPLACE, STR_TOLOWER, STR_TOUPPER, STR_TOTITLE,
STR_TRIM, STR_TRIMLEFT, STR_TRIMRIGHT,
STR_WORDEND, STR_WORDSTART
};
-
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
return TCL_ERROR;
@@ -838,37 +836,73 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
switch ((enum options) index) {
case STR_EQUAL:
case STR_COMPARE: {
- int match, length, reqlength = -1;
+ int i, match, length, nocase = 0, reqlength = -1;
- if (!(objc == 4 || objc == 5)) {
- Tcl_WrongNumArgs(interp, 2, objv, "string1 string2 ?length?");
- return TCL_ERROR;
- }
- if ((objc == 5) &&
- Tcl_GetIntFromObj(interp, objv[4], &reqlength) != TCL_OK) {
+ if (objc < 4 || objc > 7) {
+ str_cmp_args:
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-nocase? ?-length int? string1 string2");
return TCL_ERROR;
}
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- string2 = Tcl_GetStringFromObj(objv[3], &length2);
+ for (i = 2; i < objc-2; i++) {
+ string2 = Tcl_GetStringFromObj(objv[i], &length2);
+ if ((length2 > 1)
+ && strncmp(string2, "-nocase", length2) == 0) {
+ nocase = 1;
+ } else if ((length2 > 1)
+ && strncmp(string2, "-length", length2) == 0) {
+ if (i+1 >= objc-2) {
+ goto str_cmp_args;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[++i],
+ &reqlength) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ Tcl_AppendStringsToObj(resultPtr, "bad option \"",
+ string2, "\": must be -nocase or -length",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+ string1 = Tcl_GetStringFromObj(objv[objc-2], &length1);
+ string2 = Tcl_GetStringFromObj(objv[objc-1], &length2);
+ /*
+ * This is the min length IN BYTES of the two strings
+ */
length = (length1 < length2) ? length1 : length2;
- if ((reqlength >= 0) && (reqlength < length)) {
- Tcl_UniChar ch1, ch2;
+ if (reqlength == 0) {
/*
- * reqlength must be interpreted as chars, not bytes
- * we will only enter here when both strings are of
- * at least reqlength chars long (no need for \0 check)
+ * Anything matches at 0 chars, right?
*/
match = 0;
- while (reqlength-- > 0) {
- string1 += Tcl_UtfToUniChar(string1, &ch1);
- string2 += Tcl_UtfToUniChar(string2, &ch2);
- if (ch1 != ch2) {
- match = ch1 - ch2;
- break;
- }
+ } else if (nocase || ((reqlength > 0) && (reqlength < length))) {
+ /*
+ * with -nocase or -length we have to check true char length
+ * as it could be smaller than expected
+ */
+ length1 = Tcl_NumUtfChars(string1, length1);
+ length2 = Tcl_NumUtfChars(string2, length2);
+ length = (length1 < length2) ? length1 : length2;
+ /*
+ * Do the reqlength check again, against 0 as well for
+ * the benfit of nocase
+ */
+ if ((reqlength > 0) && (reqlength < length)) {
+ length = reqlength;
+ }
+ if (nocase) {
+ match = Tcl_UtfNcasecmp(string1, string2,
+ (unsigned)length);
+ } else {
+ match = Tcl_UtfNcmp(string1, string2,
+ (unsigned) length);
+ }
+ if ((match == 0) && (reqlength >= length)) {
+ match = length1 - length2;
}
} else {
match = memcmp(string1, string2, (unsigned) length);
@@ -876,55 +910,8 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
match = length1 - length2;
}
}
- if ((enum options) index == STR_EQUAL) {
- Tcl_SetIntObj(resultPtr, (match) ? 0 : 1);
- } else {
- Tcl_SetIntObj(resultPtr, ((match > 0) ? 1 :
- (match < 0) ? -1 : 0));
- }
- break;
- }
- case STR_IEQUAL:
- case STR_ICOMPARE: {
- int match, length, reqlength = -1;
- Tcl_UniChar ch1, ch2;
-
- if (objc < 4 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "string1 string2 ?length?");
- return TCL_ERROR;
- }
- if ((objc == 5) &&
- Tcl_GetIntFromObj(interp, objv[4], &reqlength) != TCL_OK) {
- return TCL_ERROR;
- }
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- string2 = Tcl_GetStringFromObj(objv[3], &length2);
-
- length = (length1 < length2) ? length1 : length2;
- if ((reqlength >= 0) && (reqlength < length)) {
- length = reqlength;
- }
- /*
- * length must be interpreted as chars, not bytes
- * we will only enter here when both strings are of
- * at least length chars long (no need for \0 check)
- */
- match = 0;
- while (length-- > 0) {
- string1 += Tcl_UtfToUniChar(string1, &ch1);
- string2 += Tcl_UtfToUniChar(string2, &ch2);
- if ((ch1 != ch2) &&
- (Tcl_UniCharToLower(ch1) != Tcl_UniCharToLower(ch2))) {
- match = ch1 - ch2;
- break;
- }
- }
- if ((match == 0) && (reqlength >= length)) {
- match = length1 - length2;
- }
-
- if ((enum options) index == STR_IEQUAL) {
+ if ((enum options) index == STR_EQUAL) {
Tcl_SetIntObj(resultPtr, (match) ? 0 : 1);
} else {
Tcl_SetIntObj(resultPtr, ((match > 0) ? 1 :
@@ -1002,6 +989,253 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
}
break;
}
+ case STR_IS: {
+ char *end;
+ Tcl_UniChar ch;
+ int (*chcomp)(int) = NULL; /* The UniChar comparison function */
+ int i, failat = 0, result = 1, strict = 0;
+ Tcl_Obj *objPtr, *failVarObj = NULL;
+
+ static char *isOptions[] = {
+ "alnum", "alpha", "ascii",
+ "boolean", "digit", "double",
+ "false", "integer", "lower",
+ "space", "true", "upper",
+ "wordchar", (char *) NULL
+ };
+ enum isOptions {
+ STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII,
+ STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE,
+ STR_IS_FALSE, STR_IS_INT, STR_IS_LOWER,
+ STR_IS_SPACE, STR_IS_TRUE, STR_IS_UPPER,
+ STR_IS_WORD
+ };
+
+ if (objc < 4 || objc > 7) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "class ?-strict? ?-failindex var? str");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], isOptions, "class", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc != 4) {
+ for (i = 3; i < objc-1; i++) {
+ string2 = Tcl_GetStringFromObj(objv[i], &length2);
+ if ((length2 > 1) &&
+ strncmp(string2, "-strict", length2) == 0) {
+ strict = 1;
+ } else if ((length2 > 1) &&
+ strncmp(string2, "-failindex", length2) == 0) {
+ if (i+1 >= objc-1) {
+ Tcl_WrongNumArgs(interp, 3, objv,
+ "?-strict? ?-failindex var? str");
+ return TCL_ERROR;
+ }
+ failVarObj = objv[++i];
+ } else {
+ Tcl_AppendStringsToObj(resultPtr, "bad option \"",
+ string2, "\": must be -strict or -failindex",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ /*
+ * We get the objPtr so that we can short-cut for some classes
+ * by checking the object type (int and double), but we need
+ * the string otherwise, because we don't want any conversion
+ * of type occuring (as, for example, Tcl_Get*FromObj would do
+ */
+ objPtr = objv[objc-1];
+ string1 = Tcl_GetStringFromObj(objPtr, &length1);
+ if (length1 == 0) {
+ if (strict) {
+ result = 0;
+ }
+ goto str_is_done;
+ }
+ end = string1 + length1;
+
+ /*
+ * When entering here, result == 1 and failat == 0
+ */
+ switch ((enum isOptions) index) {
+ case STR_IS_ALNUM:
+ chcomp = Tcl_UniCharIsAlnum;
+ break;
+ case STR_IS_ALPHA:
+ chcomp = Tcl_UniCharIsAlpha;
+ break;
+ case STR_IS_ASCII:
+ for (; string1 < end; string1++, failat++) {
+ /*
+ * This is a valid check in unicode, because all
+ * bytes < 0xC0 are single byte chars (but isascii
+ * limits that def'n to 0x80).
+ */
+ if (*((unsigned char *)string1) >= 0x80) {
+ result = 0;
+ break;
+ }
+ }
+ break;
+ case STR_IS_BOOL:
+ case STR_IS_TRUE:
+ case STR_IS_FALSE:
+ if (objPtr->typePtr == &tclBooleanType) {
+ if ((((enum isOptions) index == STR_IS_TRUE) &&
+ objPtr->internalRep.longValue == 0) ||
+ (((enum isOptions) index == STR_IS_FALSE) &&
+ objPtr->internalRep.longValue != 0)) {
+ result = 0;
+ }
+ } else if ((Tcl_GetBoolean(NULL, string1, &i)
+ == TCL_ERROR) ||
+ (((enum isOptions) index == STR_IS_TRUE) &&
+ i == 0) ||
+ (((enum isOptions) index == STR_IS_FALSE) &&
+ i != 0)) {
+ result = 0;
+ }
+ break;
+ case STR_IS_DIGIT:
+ chcomp = Tcl_UniCharIsDigit;
+ break;
+ case STR_IS_DOUBLE: {
+ char *stop;
+
+ if ((objPtr->typePtr == &tclDoubleType) ||
+ (objPtr->typePtr == &tclIntType)) {
+ break;
+ }
+ /*
+ * This is adapted from Tcl_GetDouble
+ *
+ * The danger in this function is that
+ * "12345678901234567890" is an acceptable 'double',
+ * but will later be interp'd as an int by something
+ * like [expr]. Therefore, we check to see if it looks
+ * like an int, and if so we do a range check on it.
+ * If strtoul gets to the end, we know we either
+ * received an acceptable int, or over/underflow
+ */
+ if (TclLooksLikeInt(string1, length1)) {
+ errno = 0;
+ strtoul(string1, &stop, 0);
+ if (stop == end) {
+ if (errno == ERANGE) {
+ result = 0;
+ failat = -1;
+ }
+ break;
+ }
+ }
+ errno = 0;
+ strtod(string1, &stop); /* INTL: Tcl source. */
+ if (errno == ERANGE) {
+ /*
+ * if (errno == ERANGE), then it was an over/underflow
+ * problem, but in this method, we only want to know
+ * yes or no, so bad flow returns 0 (false) and sets
+ * the failVarObj to the string length.
+ */
+ result = 0;
+ failat = -1;
+ } else if (stop == string1) {
+ /*
+ * In this case, nothing like a number was found
+ */
+ result = 0;
+ failat = 0;
+ } else {
+ /*
+ * Assume we sucked up one char per byte
+ * and then we go onto SPACE, since we are
+ * allowed trailing whitespace
+ */
+ failat = stop - string1;
+ string1 = stop;
+ chcomp = Tcl_UniCharIsSpace;
+ }
+ break;
+ }
+ case STR_IS_INT: {
+ char *stop;
+
+ if ((objPtr->typePtr == &tclIntType) ||
+ (Tcl_GetInt(NULL, string1, &i) == TCL_OK)) {
+ break;
+ }
+ /*
+ * Like STR_IS_DOUBLE, but we don't use strtoul.
+ * Since Tcl_GetInt already failed, we set result to 0.
+ */
+ result = 0;
+ errno = 0;
+ strtoul(string1, &stop, 0); /* INTL: Tcl source. */
+ if (errno == ERANGE) {
+ /*
+ * if (errno == ERANGE), then it was an over/underflow
+ * problem, but in this method, we only want to know
+ * yes or no, so bad flow returns 0 (false) and sets
+ * the failVarObj to the string length.
+ */
+ failat = -1;
+ } else if (stop == string1) {
+ /*
+ * In this case, nothing like a number was found
+ */
+ failat = 0;
+ } else {
+ /*
+ * Assume we sucked up one char per byte
+ * and then we go onto SPACE, since we are
+ * allowed trailing whitespace
+ */
+ failat = stop - string1;
+ string1 = stop;
+ chcomp = Tcl_UniCharIsSpace;
+ }
+ break;
+ }
+ case STR_IS_LOWER:
+ chcomp = Tcl_UniCharIsLower;
+ break;
+ case STR_IS_SPACE:
+ chcomp = Tcl_UniCharIsSpace;
+ break;
+ case STR_IS_UPPER:
+ chcomp = Tcl_UniCharIsUpper;
+ break;
+ case STR_IS_WORD:
+ chcomp = Tcl_UniCharIsWordChar;
+ break;
+ }
+ if (chcomp != NULL) {
+ for (; string1 < end; string1 += length2, failat++) {
+ length2 = Tcl_UtfToUniChar(string1, &ch);
+ if (!chcomp(ch)) {
+ result = 0;
+ break;
+ }
+ }
+ }
+ str_is_done:
+ /*
+ * Only set the failVarObj when we will return 0
+ * and we have indicated a valid fail index (>= 0)
+ */
+ if ((result == 0) && (failVarObj != NULL) &&
+ Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(failat),
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetBooleanObj(resultPtr, result);
+ break;
+ }
case STR_LAST: {
register char *p;
int match;
@@ -1073,21 +1307,40 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
break;
}
case STR_MAP: {
- int mapElemc, len;
+ int uselen, mapElemc, len, nocase = 0;
Tcl_Obj **mapElemv;
char *end;
Tcl_UniChar ch;
+ int (*str_comp_fn)();
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "charMap string");
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-nocase? charMap string");
return TCL_ERROR;
}
+ if (objc == 5) {
+ string2 = Tcl_GetStringFromObj(objv[2], &length2);
+ if ((length2 > 1) &&
+ strncmp(string2, "-nocase", length2) == 0) {
+ nocase = 1;
+ } else {
+ Tcl_AppendStringsToObj(resultPtr, "bad option \"",
+ string2, "\": must be -nocase",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+
if (Tcl_ListObjGetElements(interp, objv[objc-2], &mapElemc,
&mapElemv) != TCL_OK) {
return TCL_ERROR;
}
- if (mapElemc & 1) {
+ if (mapElemc == 0) {
+ /*
+ * empty charMap, just return whatever string was given
+ */
+ Tcl_SetObjResult(interp, objv[objc-1]);
+ } else if (mapElemc & 1) {
/*
* The charMap must be an even number of key/value items
*/
@@ -1100,21 +1353,35 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
}
end = string1 + length1;
+ if (nocase) {
+ length1 = Tcl_NumUtfChars(string1, length1);
+ str_comp_fn = Tcl_UtfNcasecmp;
+ } else {
+ str_comp_fn = memcmp;
+ }
+
for ( ; string1 < end; string1 += len) {
len = Tcl_UtfToUniChar(string1, &ch);
for (index = 0; index < mapElemc; index +=2) {
/*
* Get the key string to match on
*/
- string2 = Tcl_GetStringFromObj(mapElemv[index], &length2);
- if ((*string2 == *string1) &&
- (memcmp(string2, string1, length2) == 0)) {
+ string2 = Tcl_GetStringFromObj(mapElemv[index],
+ &length2);
+ if (nocase) {
+ uselen = Tcl_NumUtfChars(string2, length2);
+ } else {
+ uselen = length2;
+ }
+ if ((uselen <= length1) &&
+ (str_comp_fn(string2, string1, uselen) == 0)) {
/*
* Adjust len to be full length of matched string
+ * it has to be the BYTE length
*/
len = length2;
/*
- * Change string2 and length2 to the replacement value
+ * Change string2 and length2 to the map value
*/
string2 = Tcl_GetStringFromObj(mapElemv[index+1],
&length2);
@@ -1128,6 +1395,15 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
*/
Tcl_AppendToObj(resultPtr, string1, len);
}
+ /*
+ * in nocase, length1 is in chars
+ * otherwise it is in bytes
+ */
+ if (nocase) {
+ length1--;
+ } else {
+ length1 -= len;
+ }
}
break;
}
@@ -1246,19 +1522,19 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
if (objc == 3) {
/*
- * Since the result object is not a shared object, it is
- * safe to copy the string into the result and do the
- * conversion in place. The conversion may change the length
- * of the string, so reset the length after conversion.
- */
+ * Since the result object is not a shared object, it is
+ * safe to copy the string into the result and do the
+ * conversion in place. The conversion may change the length
+ * of the string, so reset the length after conversion.
+ */
Tcl_SetStringObj(resultPtr, string1, length1);
if ((enum options) index == STR_TOLOWER) {
- length1 = Tcl_UtfToLower(Tcl_GetStringFromObj(resultPtr, NULL));
+ length1 = Tcl_UtfToLower(Tcl_GetString(resultPtr));
} else if ((enum options) index == STR_TOUPPER) {
- length1 = Tcl_UtfToUpper(Tcl_GetStringFromObj(resultPtr, NULL));
+ length1 = Tcl_UtfToUpper(Tcl_GetString(resultPtr));
} else {
- length1 = Tcl_UtfToTitle(Tcl_GetStringFromObj(resultPtr, NULL));
+ length1 = Tcl_UtfToTitle(Tcl_GetString(resultPtr));
}
Tcl_SetObjLength(resultPtr, length1);
} else {
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 2031ccd..16ec609 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.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: tclUtil.c,v 1.9 1999/05/04 01:33:11 stanton Exp $
+ * RCS: @(#) $Id: tclUtil.c,v 1.10 1999/05/06 18:46:42 stanton Exp $
*/
#include "tclInt.h"
@@ -2021,13 +2021,14 @@ TclLooksLikeInt(bytes, length)
*
* 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 the string "end".
+ * either an integer or a string of the form "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 "end" and
+ * 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
* "interp" is non-NULL, an error message is left in the interpreter's
* result object.
@@ -2052,8 +2053,7 @@ TclGetIntForIndex(interp, objPtr, endValue, indexPtr)
* representing an index. */
{
char *bytes;
- long longResult;
- int length;
+ int length, offset;
if (objPtr->typePtr == &tclIntType) {
*indexPtr = (int)objPtr->internalRep.longValue;
@@ -2064,28 +2064,29 @@ TclGetIntForIndex(interp, objPtr, endValue, indexPtr)
if ((*bytes != 'e') ||
(strncmp(bytes, "end", (length > 3) ? 3 : length) != 0)) {
- if (Tcl_ExprLongObj(interp, objPtr, &longResult) != TCL_OK) {
- return TCL_ERROR;
+ if (Tcl_GetIntFromObj(NULL, objPtr, &offset) != TCL_OK) {
+ goto intforindex_error;
}
- *indexPtr = longResult;
+ *indexPtr = offset;
return TCL_OK;
}
if (length <= 3) {
*indexPtr = endValue;
- } else if ((bytes[3] == '+') || (bytes[3] == '-')) {
+ } else if (bytes[3] == '-') {
/*
* This is our limited string expression evaluator
*/
- if (Tcl_ExprLong(interp, bytes+3, &longResult) != TCL_OK) {
+ if (Tcl_GetInt(interp, bytes+3, &offset) != TCL_OK) {
return TCL_ERROR;
}
- *indexPtr = endValue + longResult;
+ *indexPtr = endValue + offset;
} else {
- if (interp != NULL) {
+ intforindex_error:
+ if ((Interp *)interp != NULL) {
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "invalid index \"", bytes,
- "\": must be integer or ?end[+-]?expression",
+ "bad index \"", bytes,
+ "\": must be integer or end?-integer?",
(char *) NULL);
}
return TCL_ERROR;
diff --git a/tests/cmdIL.test b/tests/cmdIL.test
index 2f5d62e..6911da0 100644
--- a/tests/cmdIL.test
+++ b/tests/cmdIL.test
@@ -8,7 +8,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: cmdIL.test,v 1.7 1999/05/04 01:33:11 stanton Exp $
+# RCS: @(#) $Id: cmdIL.test,v 1.8 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -52,7 +52,7 @@ test cmdIL-1.11 {Tcl_LsortObjCmd procedure, -index option} {
} {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 {syntax error in expression "foo"}}
+} {1 {bad index "foo": must be 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}}
@@ -311,15 +311,3 @@ test cmdIL-4.27 {DictionaryCompare procedure, signed characters} {
# cleanup
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/cmdMZ.test b/tests/cmdMZ.test
index 285df0d..f533d6c 100644
--- a/tests/cmdMZ.test
+++ b/tests/cmdMZ.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: cmdMZ.test,v 1.4 1999/05/04 02:57:55 stanton Exp $
+# RCS: @(#) $Id: cmdMZ.test,v 1.5 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -152,426 +152,7 @@ test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
split "a\u4e4eb qw\u5e4e\x4e wq" " \u4e4e"
} "a b qw\u5e4eN wq"
-# Tcl_StringObjCmd
-
-test cmdMZ-5.1 {Tcl_StringObjCmd: error conditions} {
- list [catch {string} msg] $msg
-} {1 {wrong # args: should be "string option arg ?arg ...?"}}
-test cmdMZ-5.2 {Tcl_StringObjCmd: error conditions} {
- list [catch {string gorp a b} msg] $msg
-} {1 {bad option "gorp": must be bytelength, compare, equal, first, icompare, iequal, index, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
-
-test cmdMZ-6.1 {Tcl_StringObjCmd: string compare} {
- list [catch {string compare a} msg] $msg
-} {1 {wrong # args: should be "string compare string1 string2 ?length?"}}
-test cmdMZ-6.2 {Tcl_StringObjCmd: string compare} {
- list [catch {string compare a b c} msg] $msg
-} {1 {expected integer but got "c"}}
-test cmdMZ-6.3 {Tcl_StringObjCmd: string compare} {
- string compare abcde abdef
-} -1
-test cmdMZ-6.4 {Tcl_StringObjCmd: string compare} {
- string c abcde ABCDE
-} 1
-test cmdMZ-6.5 {Tcl_StringObjCmd: string compare} {
- string compare abcde abcde
-} 0
-test cmdMZ-6.6 {Tcl_StringObjCmd: string compare} {
- string compare ab abcde
-} -1
-test cmdMZ-6.7 {Tcl_StringObjCmd: string compare} {
- string compare abcde ab
-} 1
-test cmdMZ-6.8 {Tcl_StringObjCmd: string compare} {
- string compare cde ab
-} 1
-test cmdMZ-6.9 {Tcl_StringObjCmd: string compare} {
- string compare ab cde
-} -1
-test cmdMZ-6.10 {Tcl_StringObjCmd: string compare, unicode} {
- string compare ab\u7266 ab\u7267
-} -1
-test cmdMZ-6.11 {Tcl_StringObjCmd: string compare, high bit} {
- # This test will fail if the underlying comparaison
- # is using signed chars instead of unsigned chars.
- # (like SunOS's default memcmp thus the compat/memcmp.c)
- string compare "\x80" "@"
- # Nb this tests works also in utf8 space because \x80 is
- # translated into a 2 or more bytes but whose first byte has
- # the high bit set.
-} 1
-
-test cmdMZ-7.1 {Tcl_StringObjCmd: string first} {
- list [catch {string first a} msg] $msg
-} {1 {wrong # args: should be "string first string1 string2"}}
-test cmdMZ-7.2 {Tcl_StringObjCmd: string first} {
- list [catch {string first a b c} msg] $msg
-} {1 {wrong # args: should be "string first string1 string2"}}
-test cmdMZ-7.3 {Tcl_StringObjCmd: string first} {
- string first bq abcdefgbcefgbqrs
-} 12
-test cmdMZ-7.4 {Tcl_StringObjCmd: string first} {
- string fir bcd abcdefgbcefgbqrs
-} 1
-test cmdMZ-7.5 {Tcl_StringObjCmd: string first} {
- string f b abcdefgbcefgbqrs
-} 1
-test cmdMZ-7.6 {Tcl_StringObjCmd: string first} {
- string first xxx x123xx345xxx789xxx012
-} 9
-test cmdMZ-7.7 {Tcl_StringObjCmd: string first} {
- string first "" x123xx345xxx789xxx012
-} -1
-test cmdMZ-7.8 {Tcl_StringObjCmd: string first, unicode} {
- string first x abc\u7266x
-} 4
-test cmdMZ-7.9 {Tcl_StringObjCmd: string first, unicode} {
- string first \u7266 abc\u7266x
-} 3
-
-test cmdMZ-8.1 {Tcl_StringObjCmd: string index} {
- list [catch {string index} msg] $msg
-} {1 {wrong # args: should be "string index string charIndex"}}
-test cmdMZ-8.2 {Tcl_StringObjCmd: string index} {
- list [catch {string index a b c} msg] $msg
-} {1 {wrong # args: should be "string index string charIndex"}}
-test cmdMZ-8.3 {Tcl_StringObjCmd: string index} {
- list [catch {string index a xyz} msg] $msg
-} {1 {syntax error in expression "xyz"}}
-test cmdMZ-8.4 {Tcl_StringObjCmd: string index} {
- string index abcde 0
-} a
-test cmdMZ-8.5 {Tcl_StringObjCmd: string index} {
- string in abcde 4
-} e
-test cmdMZ-8.6 {Tcl_StringObjCmd: string index} {
- string index abcde 5
-} {}
-test cmdMZ-8.7 {Tcl_StringObjCmd: string index} {
- list [catch {string index abcde -10} msg] $msg
-} {0 {}}
-test cmdMZ-8.8 {Tcl_StringObjCmd: string index, unicode} {
- string index abc\u7266d 4
-} d
-test cmdMZ-8.9 {Tcl_StringObjCmd: string index, unicode} {
- string index abc\u7266d 3
-} \u7266
-
-test cmdMZ-9.1 {Tcl_StringObjCmd: string last} {
- list [catch {string last a} msg] $msg
-} {1 {wrong # args: should be "string last string1 string2"}}
-test cmdMZ-9.2 {Tcl_StringObjCmd: string last} {
- list [catch {string last a b c} msg] $msg
-} {1 {wrong # args: should be "string last string1 string2"}}
-test cmdMZ-9.3 {Tcl_StringObjCmd: string last} {
- string la xxx xxxx123xx345x678
-} 1
-test cmdMZ-9.4 {Tcl_StringObjCmd: string last} {
- string last xx xxxx123xx345x678
-} 7
-test cmdMZ-9.5 {Tcl_StringObjCmd: string last} {
- string las x xxxx123xx345x678
-} 12
-test cmdMZ-9.6 {Tcl_StringObjCmd: string last, unicode} {
- string las x xxxx12\u7266xx345x678
-} 12
-test cmdMZ-9.7 {Tcl_StringObjCmd: string last, unicode} {
- string las \u7266 xxxx12\u7266xx345x678
-} 6
-
-test cmdMZ-10.1 {Tcl_StringObjCmd: string bytelength} {
- list [catch {string bytelength} msg] $msg
-} {1 {wrong # args: should be "string bytelength string"}}
-test cmdMZ-10.2 {Tcl_StringObjCmd: string bytelength} {
- list [catch {string bytelength a b} msg] $msg
-} {1 {wrong # args: should be "string bytelength string"}}
-test cmdMZ-10.3 {Tcl_StringObjCmd: string bytelength} {
- string bytelength "\u00c7"
-} 2
-test cmdMZ-10.4 {Tcl_StringObjCmd: string bytelength} {
- string b ""
-} 0
-test cmdMZ-10.5 {Tcl_StringObjCmd: string length} {
- list [catch {string length} msg] $msg
-} {1 {wrong # args: should be "string length string"}}
-test cmdMZ-10.6 {Tcl_StringObjCmd: string length} {
- list [catch {string length a b} msg] $msg
-} {1 {wrong # args: should be "string length string"}}
-test cmdMZ-10.7 {Tcl_StringObjCmd: string length} {
- string length "a little string"
-} 15
-test cmdMZ-10.8 {Tcl_StringObjCmd: string length} {
- string le ""
-} 0
-test cmdMZ-10.9 {Tcl_StringObjCmd: string length, unicode} {
- string le "abcd\u7266"
-} 5
-test cmdMZ-10.10 {Tcl_StringObjCmd: string length, byte arrays} {
- string le [binary format B 1]
-} 1
-
-test cmdMZ-11.1 {Tcl_StringObjCmd: string match} {
- list [catch {string match a} msg] $msg
-} {1 {wrong # args: should be "string match pattern string"}}
-test cmdMZ-11.2 {Tcl_StringObjCmd: string match} {
- list [catch {string match a b c} msg] $msg
-} {1 {wrong # args: should be "string match pattern string"}}
-test cmdMZ-11.3 {Tcl_StringObjCmd: string match} {
- string match abc abc
-} 1
-test cmdMZ-11.4 {Tcl_StringObjCmd: string match} {
- string mat abc abd
-} 0
-
-test cmdMZ-12.1 {Tcl_StringObjCmd: string range} {
- list [catch {string range} msg] $msg
-} {1 {wrong # args: should be "string range string first last"}}
-test cmdMZ-12.2 {Tcl_StringObjCmd: string range} {
- list [catch {string range a 1} msg] $msg
-} {1 {wrong # args: should be "string range string first last"}}
-test cmdMZ-12.3 {Tcl_StringObjCmd: string range} {
- list [catch {string range a 1 2 3} msg] $msg
-} {1 {wrong # args: should be "string range string first last"}}
-test cmdMZ-12.4 {Tcl_StringObjCmd: string range} {
- list [catch {string range abc abc 1} msg] $msg
-} {1 {syntax error in expression "abc"}}
-test cmdMZ-12.5 {Tcl_StringObjCmd: string range} {
- list [catch {string range abc 1 eof} msg] $msg
-} {1 {syntax error in expression "eof"}}
-test cmdMZ-12.6 {Tcl_StringObjCmd: string range, first < 0} {
- string range abcdefghijklmnop -3 2
-} {abc}
-test cmdMZ-12.7 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop 2 14
-} {cdefghijklmno}
-test cmdMZ-12.8 {Tcl_StringObjCmd: string range, last > length} {
- string range abcdefghijklmnop 7 1000
-} {hijklmnop}
-test cmdMZ-12.9 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop 10 e
-} {klmnop}
-test cmdMZ-12.10 {Tcl_StringObjCmd: string range, last < first} {
- string range abcdefghijklmnop 10 9
-} {}
-test cmdMZ-12.11 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop -3 -2
-} {}
-test cmdMZ-12.12 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop 1000 1010
-} {}
-test cmdMZ-12.13 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop -100 end
-} {abcdefghijklmnop}
-test cmdMZ-12.14 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop end end
-} {p}
-test cmdMZ-12.15 {Tcl_StringObjCmd: string range} {
- string range abcdefghijklmnop e 1000
-} {p}
-test cmdMZ-12.16 {Tcl_StringObjCmd: string range, unicode} {
- string range ab\u7266cdefghijklmnop 5 5
-} e
-test cmdMZ-12.17 {Tcl_StringObjCmd: string range, unicode} {
- string range ab\u7266cdefghijklmnop 2 3
-} \u7266c
-
-test cmdMZ-13.1 {Tcl_StringObjCmd: string tolower} {
- list [catch {string tolower} msg] $msg
-} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
-test cmdMZ-13.2 {Tcl_StringObjCmd: string tolower} {
- list [catch {string tolower a b} msg] $msg
-} {1 {syntax error in expression "b"}}
-test cmdMZ-13.3 {Tcl_StringObjCmd: string tolower} {
- string tolower ABCDeF
-} {abcdef}
-test cmdMZ-13.4 {Tcl_StringObjCmd: string tolower} {
- string tolower "ABC XyZ"
-} {abc xyz}
-test cmdMZ-13.5 {Tcl_StringObjCmd: string tolower} {
- string tolower {123#$&*()}
-} {123#$&*()}
-test cmdMZ-13.6 {Tcl_StringObjCmd: string tolower, unicode} {
- string tolower ABCabc\xc7\xe7
-} "abcabc\xe7\xe7"
-
-test cmdMZ-14.1 {Tcl_StringObjCmd: string toupper} {
- list [catch {string toupper} msg] $msg
-} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
-test cmdMZ-14.2 {Tcl_StringObjCmd: string toupper} {
- list [catch {string toupper a b} msg] $msg
-} {1 {syntax error in expression "b"}}
-test cmdMZ-14.3 {Tcl_StringObjCmd: string toupper} {
- string toupper abCDEf
-} {ABCDEF}
-test cmdMZ-14.4 {Tcl_StringObjCmd: string toupper} {
- string toupper "abc xYz"
-} {ABC XYZ}
-test cmdMZ-14.5 {Tcl_StringObjCmd: string toupper} {
- string toupper {123#$&*()}
-} {123#$&*()}
-test cmdMZ-14.6 {Tcl_StringObjCmd: string toupper, unicode} {
- string toupper ABCabc\xc7\xe7
-} "ABCABC\xc7\xc7"
-
-test cmdMZ-15.1 {Tcl_StringObjCmd: string totitle} {
- list [catch {string totitle} msg] $msg
-} {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
-test cmdMZ-15.2 {Tcl_StringObjCmd: string totitle} {
- list [catch {string totitle a b} msg] $msg
-} {1 {syntax error in expression "b"}}
-test cmdMZ-15.3 {Tcl_StringObjCmd: string totitle} {
- string totitle abCDEf
-} {Abcdef}
-test cmdMZ-15.4 {Tcl_StringObjCmd: string totitle} {
- string totitle "abc xYz"
-} {Abc xyz}
-test cmdMZ-15.5 {Tcl_StringObjCmd: string totitle} {
- string totitle {123#$&*()}
-} {123#$&*()}
-test cmdMZ-15.6 {Tcl_StringObjCmd: string totitle, unicode} {
- string totitle ABCabc\xc7\xe7
-} "Abcabc\xe7\xe7"
-test cmdMZ-15.7 {Tcl_StringObjCmd: string totitle, unicode} {
- string totitle \u01f3BCabc\xc7\xe7
-} "\u01f2bcabc\xe7\xe7"
-
-test cmdMZ-16.1 {Tcl_StringObjCmd: string trim} {
- list [catch {string trim} msg] $msg
-} {1 {wrong # args: should be "string trim string ?chars?"}}
-test cmdMZ-16.2 {Tcl_StringObjCmd: string trim} {
- list [catch {string trim a b c} msg] $msg
-} {1 {wrong # args: should be "string trim string ?chars?"}}
-test cmdMZ-16.3 {Tcl_StringObjCmd: string trim} {
- string trim " XYZ "
-} {XYZ}
-test cmdMZ-16.4 {Tcl_StringObjCmd: string trim} {
- string trim "\t\nXYZ\t\n\r\n"
-} {XYZ}
-test cmdMZ-16.5 {Tcl_StringObjCmd: string trim} {
- string trim " A XYZ A "
-} {A XYZ A}
-test cmdMZ-16.6 {Tcl_StringObjCmd: string trim} {
- string trim "XXYYZZABC XXYYZZ" ZYX
-} {ABC }
-test cmdMZ-16.7 {Tcl_StringObjCmd: string trim} {
- string trim " \t\r "
-} {}
-test cmdMZ-16.8 {Tcl_StringObjCmd: string trim} {
- string trim {abcdefg} {}
-} {abcdefg}
-test cmdMZ-16.9 {Tcl_StringObjCmd: string trim} {
- string trim {}
-} {}
-test cmdMZ-16.10 {Tcl_StringObjCmd: string trim} {
- string trim ABC DEF
-} {ABC}
-test cmdMZ-16.11 {Tcl_StringObjCmd: string trim, unicode} {
- string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
-} " AB\xe7C "
-
-test cmdMZ-17.1 {Tcl_StringObjCmd: string trimleft} {
- string trimleft " XYZ "
-} {XYZ }
-test cmdMZ-17.2 {Tcl_StringObjCmd: string trimleft} {
- list [catch {string trimleft} msg] $msg
-} {1 {wrong # args: should be "string trimleft string ?chars?"}}
-test cmdMZ-17.3 {Tcl_StringObjCmd: string trimleft} {
- string length [string trimleft " "]
-} {0}
-
-test cmdMZ-18.1 {Tcl_StringObjCmd: string trimright} {
- string trimright " XYZ "
-} { XYZ}
-test cmdMZ-18.2 {Tcl_StringObjCmd: string trimright} {
- string trimright " "
-} {}
-test cmdMZ-18.3 {Tcl_StringObjCmd: string trimright} {
- string trimright ""
-} {}
-test cmdMZ-18.4 {Tcl_StringObjCmd: string trimright errors} {
- list [catch {string trimright} msg] $msg
-} {1 {wrong # args: should be "string trimright string ?chars?"}}
-test cmdMZ-18.5 {Tcl_StringObjCmd: string trimright errors} {
- list [catch {string trimg a} msg] $msg
-} {1 {bad option "trimg": must be bytelength, compare, equal, first, icompare, iequal, index, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
-
-test cmdMZ-19.1 {Tcl_StringObjCmd: string wordend} {
- list [catch {string wordend a} msg] $msg
-} {1 {wrong # args: should be "string wordend string index"}}
-test cmdMZ-19.2 {Tcl_StringObjCmd: string wordend} {
- list [catch {string wordend a b c} msg] $msg
-} {1 {wrong # args: should be "string wordend string index"}}
-test cmdMZ-19.3 {Tcl_StringObjCmd: string wordend} {
- list [catch {string wordend a gorp} msg] $msg
-} {1 {syntax error in expression "gorp"}}
-test cmdMZ-19.4 {Tcl_StringObjCmd: string wordend} {
- string wordend abc. -1
-} 3
-test cmdMZ-19.5 {Tcl_StringObjCmd: string wordend} {
- string wordend abc. 100
-} 4
-test cmdMZ-19.6 {Tcl_StringObjCmd: string wordend} {
- string wordend "word_one two three" 2
-} 8
-test cmdMZ-19.7 {Tcl_StringObjCmd: string wordend} {
- string wordend "one .&# three" 5
-} 6
-test cmdMZ-19.8 {Tcl_StringObjCmd: string wordend} {
- string worde "x.y" 0
-} 1
-test cmdMZ-19.9 {Tcl_StringObjCmd: string wordend, unicode} {
- string wordend "xyz\u00c7de fg" 0
-} 6
-test cmdMZ-19.10 {Tcl_StringObjCmd: string wordend, unicode} {
- string wordend "xyz\uc700de fg" 0
-} 6
-test cmdMZ-19.11 {Tcl_StringObjCmd: string wordend, unicode} {
- string wordend "xyz\u203fde fg" 0
-} 6
-test cmdMZ-19.12 {Tcl_StringObjCmd: string wordend, unicode} {
- string wordend "xyz\u2045de fg" 0
-} 3
-test cmdMZ-19.13 {Tcl_StringObjCmd: string wordend, unicode} {
- string wordend "\uc700\uc700 abc" 8
-} 6
-
-test cmdMZ-20.1 {Tcl_StringObjCmd: string wordstart} {
- list [catch {string word a} msg] $msg
-} {1 {ambiguous option "word": must be bytelength, compare, equal, first, icompare, iequal, index, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
-test cmdMZ-20.2 {Tcl_StringObjCmd: string wordstart} {
- list [catch {string wordstart a} msg] $msg
-} {1 {wrong # args: should be "string wordstart string index"}}
-test cmdMZ-20.3 {Tcl_StringObjCmd: string wordstart} {
- list [catch {string wordstart a b c} msg] $msg
-} {1 {wrong # args: should be "string wordstart string index"}}
-test cmdMZ-20.4 {Tcl_StringObjCmd: string wordstart} {
- list [catch {string wordstart a gorp} msg] $msg
-} {1 {syntax error in expression "gorp"}}
-test cmdMZ-20.5 {Tcl_StringObjCmd: string wordstart} {
- string wordstart "one two three_words" 400
-} 8
-test cmdMZ-20.6 {Tcl_StringObjCmd: string wordstart} {
- string wordstart "one two three_words" 2
-} 0
-test cmdMZ-20.7 {Tcl_StringObjCmd: string wordstart} {
- string wordstart "one two three_words" -2
-} 0
-test cmdMZ-20.8 {Tcl_StringObjCmd: string wordstart} {
- string wordstart "one .*&^ three" 6
-} 6
-test cmdMZ-20.9 {Tcl_StringObjCmd: string wordstart} {
- string wordstart "one two three" 4
-} 4
-test cmdMZ-20.10 {Tcl_StringObjCmd: string wordstart, unicode} {
- string wordstart "one tw\u00c7o three" 7
-} 4
-test cmdMZ-20.11 {Tcl_StringObjCmd: string wordstart, unicode} {
- string wordstart "ab\uc700\uc700 cdef ghi" 12
-} 10
-test cmdMZ-20.12 {Tcl_StringObjCmd: string wordstart, unicode} {
- string wordstart "\uc700\uc700 abc" 8
-} 3
-
+# The tests for Tcl_StringObjCmd are in string.test
# The tests for Tcl_SubstObjCmd are in subst.test
# The tests for Tcl_SwitchObjCmd are in switch.test
# There are no tests for Tcl_TimeObjCmd
@@ -581,17 +162,3 @@ test cmdMZ-20.12 {Tcl_StringObjCmd: string wordstart, unicode} {
# cleanup
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/error.test b/tests/error.test
index a4d311f..5427816 100644
--- a/tests/error.test
+++ b/tests/error.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: error.test,v 1.4 1999/05/04 01:33:12 stanton Exp $
+# RCS: @(#) $Id: error.test,v 1.5 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -32,20 +32,20 @@ proc foo2 {} {
# Catch errors occurring in commands and errors from "error" command
test error-1.1 {simple errors from commands} {
- catch {format [string compare]} b
+ catch {format [string index]} b
} 1
test error-1.2 {simple errors from commands} {
- catch {format [string compare]} b
+ catch {format [string index]} b
set b
-} {wrong # args: should be "string compare string1 string2 ?length?"}
+} {wrong # args: should be "string index string charIndex"}
test error-1.3 {simple errors from commands} {
- catch {format [string compare]} b
+ catch {format [string index]} b
set errorInfo
-} {wrong # args: should be "string compare string1 string2 ?length?"
+} {wrong # args: should be "string index string charIndex"
while executing
-"string compare"}
+"string index"}
test error-1.4 {simple errors from commands} {
catch {error glorp} b
@@ -178,15 +178,3 @@ test error-6.1 {catch must reset error state} {
catch {rename p ""}
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index 1937c5d..bb05635 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -12,7 +12,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: ioCmd.test,v 1.3 1999/04/16 00:47:29 stanton Exp $
+# RCS: @(#) $Id: ioCmd.test,v 1.4 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -100,16 +100,16 @@ test iocmd-3.5 {gets command} {
test iocmd-4.1 {read command} {
list [catch {read} msg] $msg
-} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"}}
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
test iocmd-4.2 {read command} {
list [catch {read a b c d e f g h} msg] $msg
-} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"}}
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
test iocmd-4.3 {read command} {
list [catch {read aaa} msg] $msg
} {1 {can not find channel named "aaa"}}
test iocmd-4.4 {read command} {
list [catch {read -nonewline} msg] $msg
-} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"}}
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
test iocmd-4.5 {read command} {
list [catch {read -nonew file4} msg] $msg $errorCode
} {1 {can not find channel named "-nonew"} NONE}
@@ -129,7 +129,7 @@ test iocmd-4.8 {read command with incorrect combination of arguments} {
set x [list [catch {read -nonewline $f 20 z} msg] $msg $errorCode]
close $f
set x
-} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"} NONE}
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"} NONE}
test iocmd-4.9 {read command} {
list [catch {read stdin foo} msg] $msg $errorCode
} {1 {bad argument "foo": should be "nonewline"} NONE}
diff --git a/tests/lindex.test b/tests/lindex.test
index ed79c31..a19fde4 100644
--- a/tests/lindex.test
+++ b/tests/lindex.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: lindex.test,v 1.4 1999/05/04 01:33:12 stanton Exp $
+# RCS: @(#) $Id: lindex.test,v 1.5 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -52,7 +52,7 @@ test lindex-2.2 {error conditions} {
} {1 {wrong # args: should be "lindex list index"}}
test lindex-2.3 {error conditions} {
list [catch {lindex 1 2a2} msg] $msg
-} {1 {syntax error in expression "2a2"}}
+} {1 {bad index "2a2": must be integer or end?-integer?}}
test lindex-2.4 {error conditions} {
list [catch {lindex "a \{" 2} msg] $msg
} {1 {unmatched open brace in list}}
@@ -79,15 +79,3 @@ test lindex-3.4 {quoted elements} {
# cleanup
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/linsert.test b/tests/linsert.test
index 456ea3e..e8ca689 100644
--- a/tests/linsert.test
+++ b/tests/linsert.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: linsert.test,v 1.4 1999/05/04 01:33:12 stanton Exp $
+# RCS: @(#) $Id: linsert.test,v 1.5 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -86,7 +86,7 @@ test linsert-2.2 {linsert errors} {
} {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 {syntax error in expression "12x"}}
+} {1 {bad index "12x": must be integer or end?-integer?}}
test linsert-2.4 {linsert errors} {
list [catch {linsert \{ 12 2} msg] $msg
} {1 {unmatched open brace in list}}
@@ -109,15 +109,3 @@ catch {unset lis}
catch {rename p ""}
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/lrange.test b/tests/lrange.test
index 4dc70f8..c928b19 100644
--- a/tests/lrange.test
+++ b/tests/lrange.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: lrange.test,v 1.4 1999/05/04 01:33:12 stanton Exp $
+# RCS: @(#) $Id: lrange.test,v 1.5 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -74,10 +74,10 @@ test lrange-2.2 {error conditions} {
} {1 {wrong # args: should be "lrange list first last"}}
test lrange-2.3 {error conditions} {
list [catch {lrange a b 6} msg] $msg
-} {1 {syntax error in expression "b"}}
+} {1 {bad index "b": must be integer or end?-integer?}}
test lrange-2.4 {error conditions} {
list [catch {lrange a 0 enigma} msg] $msg
-} {1 {syntax error in expression "enigma"}}
+} {1 {bad index "enigma": must be 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}}
@@ -88,15 +88,3 @@ test lrange-2.6 {error conditions} {
# cleanup
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/lreplace.test b/tests/lreplace.test
index b1f0657..868d98e 100644
--- a/tests/lreplace.test
+++ b/tests/lreplace.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: lreplace.test,v 1.4 1999/05/04 01:33:12 stanton Exp $
+# RCS: @(#) $Id: lreplace.test,v 1.5 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -109,13 +109,13 @@ test lreplace-2.2 {lreplace errors} {
} {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 {syntax error in expression "a"}}
+} {1 {bad index "a": must be integer or end?-integer?}}
test lreplace-2.4 {lreplace errors} {
list [catch {lreplace x 10 x} msg] $msg
-} {1 {syntax error in expression "x"}}
+} {1 {bad index "x": must be integer or end?-integer?}}
test lreplace-2.5 {lreplace errors} {
list [catch {lreplace x 10 1x} msg] $msg
-} {1 {syntax error in expression "1x"}}
+} {1 {bad index "1x": must be 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}}
@@ -135,15 +135,3 @@ test lreplace-3.1 {lreplace won't modify shared argument objects} {
catch {unset foo}
::tcltest::cleanupTests
return
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/string.test b/tests/string.test
index 3809ba9..cd396c2 100644
--- a/tests/string.test
+++ b/tests/string.test
@@ -11,604 +11,963 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: string.test,v 1.7 1999/05/04 02:57:55 stanton Exp $
+# RCS: @(#) $Id: string.test,v 1.8 1999/05/06 18:46:43 stanton Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
}
-test string-1.1 {string compare} {
+test string-1.1 {error conditions} {
+ list [catch {string gorp a b} msg] $msg
+} {1 {bad option "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
+test string-1.2 {error conditions} {
+ list [catch {string} msg] $msg
+} {1 {wrong # args: should be "string option arg ?arg ...?"}}
+
+test string-2.1 {string compare, too few args} {
+ list [catch {string compare a} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.2 {string compare, bad args} {
+ list [catch {string compare a b c} msg] $msg
+} {1 {bad option "a": must be -nocase or -length}}
+test string-2.3 {string compare, bad args} {
+ list [catch {string compare -length -nocase str1 str2} msg] $msg
+} {1 {expected integer but got "-nocase"}}
+test string-2.4 {string compare, too many args} {
+ list [catch {string compare -length 10 -nocase str1 str2 str3} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.5 {string compare with length unspecified} {
+ list [catch {string compare -length 10 10} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.6 {string compare} {
string compare abcde abdef
} -1
-test string-1.2 {string compare, shortest method name} {
+test string-2.7 {string compare, shortest method name} {
string c abcde ABCDE
} 1
-test string-1.3 {string compare} {
+test string-2.8 {string compare} {
string compare abcde abcde
} 0
-test string-1.4 {string compare too few args} {
- list [catch {string compare a} msg] $msg
-} {1 {wrong # args: should be "string compare string1 string2 ?length?"}}
-test string-1.5 {string compare bad args} {
- list [catch {string compare a b c} msg] $msg
-} {1 {expected integer but got "c"}}
-test string-1.6 {string compare too many args} {
- list [catch {string compare a b 1 c} msg] $msg
-} {1 {wrong # args: should be "string compare string1 string2 ?length?"}}
-test string-1.7 {string compare with length} {
- string compare abcde abxyz 2
+test string-2.9 {string compare with length} {
+ string compare -length 2 abcde abxyz
} 0
-test string-1.8 {string compare with special index} {
- list [catch {string compare abcde abxyz end-3} msg] $msg
+test string-2.10 {string compare with special index} {
+ list [catch {string compare -length end-3 abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.11 {string compare, unicode} {
+ string compare ab\u7266 ab\u7267
+} -1
+test string-2.12 {string compare, high bit} {
+ # This test will fail if the underlying comparaison
+ # is using signed chars instead of unsigned chars.
+ # (like SunOS's default memcmp thus the compat/memcmp.c)
+ string compare "\x80" "@"
+ # Nb this tests works also in utf8 space because \x80 is
+ # translated into a 2 or more bytelength but whose first byte has
+ # the high bit set.
+} 1
+test string-2.13 {string compare -nocase} {
+ string compare -nocase abcde abdef
+} -1
+test string-2.14 {string compare -nocase} {
+ string c -nocase abcde ABCDE
+} 0
+test string-2.15 {string compare -nocase} {
+ string compare -nocase abcde abcde
+} 0
+test string-2.16 {string compare -nocase with length} {
+ string compare -length 2 -nocase abcde Abxyz
+} 0
+test string-2.17 {string compare -nocase with length} {
+ string compare -nocase -length 3 abcde Abxyz
+} -1
+test string-2.18 {string compare -nocase with length <= 0} {
+ string compare -nocase -length -1 abcde AbCdEf
+} 0
+test string-2.19 {string compare -nocase with excessive length} {
+ string compare -nocase -length 50 AbCdEf abcde
+} 1
+test string-2.20 {string compare -len unicode} {
+ # These are strings that are 6 BYTELENGTH long, but the length
+ # shouldn't make a different because there are actually 3 CHARS long
+ string compare -len 5 \334\334\334 \334\334\374
+} -1
+test string-2.21 {string compare -nocase with special index} {
+ list [catch {string compare -nocase -length end-3 Abcde abxyz} msg] $msg
} {1 {expected integer but got "end-3"}}
-test string-2.1 {string first} {
+# only need a few tests on equal, since it uses the same code as
+# string compare, but just modifies the return output
+test string-3.1 {string equal} {
+ string equal abcde abdef
+} 0
+test string-3.2 {string equal} {
+ string eq abcde ABCDE
+} 0
+test string-3.3 {string equal} {
+ string equal abcde abcde
+} 1
+test string-3.4 {string equal -nocase} {
+ string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334
+} 1
+test string-3.5 {string equal -nocase} {
+ string equal -nocase abcde abdef
+} 0
+test string-3.6 {string equal -nocase} {
+ string eq -nocase abcde ABCDE
+} 1
+test string-3.7 {string equal -nocase} {
+ string equal -nocase abcde abcde
+} 1
+
+test string-4.1 {string first} {
+ list [catch {string first a} msg] $msg
+} {1 {wrong # args: should be "string first string1 string2"}}
+test string-4.2 {string first} {
+ list [catch {string first a b c} msg] $msg
+} {1 {wrong # args: should be "string first string1 string2"}}
+test string-4.3 {string first} {
string first bq abcdefgbcefgbqrs
} 12
-test string-2.2 {string first} {
+test string-4.4 {string first} {
string fir bcd abcdefgbcefgbqrs
} 1
-test string-2.3 {string first} {
+test string-4.5 {string first} {
string f b abcdefgbcefgbqrs
} 1
-test string-2.4 {string first} {
+test string-4.6 {string first} {
string first xxx x123xx345xxx789xxx012
} 9
-test string-2.5 {string first} {
+test string-4.7 {string first} {
string first "" x123xx345xxx789xxx012
} -1
-test string-2.6 {string first} {
- list [catch {string first a} msg] $msg
-} {1 {wrong # args: should be "string first string1 string2"}}
-test string-2.7 {string first} {
- list [catch {string first a b c} msg] $msg
-} {1 {wrong # args: should be "string first string1 string2"}}
+test string-4.8 {string first, unicode} {
+ string first x abc\u7266x
+} 4
+test string-4.9 {string first, unicode} {
+ string first \u7266 abc\u7266x
+} 3
-test string-3.1 {string index} {
+test string-5.1 {string index} {
+ list [catch {string index} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.2 {string index} {
+ list [catch {string index a b c} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.3 {string index} {
string index abcde 0
} a
-test string-3.2 {string index} {
+test string-5.4 {string index} {
string in abcde 4
} e
-test string-3.3 {string index} {
+test string-5.5 {string index} {
string index abcde 5
} {}
-test string-3.4 {string index} {
+test string-5.6 {string index} {
list [catch {string index abcde -10} msg] $msg
} {0 {}}
-test string-3.5 {string index} {
- list [catch {string index} msg] $msg
-} {1 {wrong # args: should be "string index string charIndex"}}
-test string-3.6 {string index} {
- list [catch {string index a b c} msg] $msg
-} {1 {wrong # args: should be "string index string charIndex"}}
-test string-3.7 {string index} {
+test string-5.7 {string index} {
list [catch {string index a xyz} msg] $msg
-} {1 {syntax error in expression "xyz"}}
-test string-3.8 {string index} {
+} {1 {bad index "xyz": must be integer or end?-integer?}}
+test string-5.8 {string index} {
string index abc end
} c
-test string-3.9 {string index} {
+test string-5.9 {string index} {
string index abc end-1
} b
-
-test string-4.1 {string last} {
+test string-5.10 {string index, unicode} {
+ string index abc\u7266d 4
+} d
+test string-5.11 {string index, unicode} {
+ string index abc\u7266d 3
+} \u7266
+
+test string-6.1 {string is, too few args} {
+ list [catch {string is} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.2 {string is, too few args} {
+ list [catch {string is alpha} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.3 {string is, bad args} {
+ list [catch {string is alpha -failin str} msg] $msg
+} {1 {wrong # args: should be "string is alpha ?-strict? ?-failindex var? str"}}
+test string-6.4 {string is, too many args} {
+ list [catch {string is alpha -failin var -strict str more} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.5 {string is, class check} {
+ list [catch {string is bogus str} msg] $msg
+} {1 {bad class "bogus": must be alnum, alpha, ascii, boolean, digit, double, false, integer, lower, space, true, upper, or wordchar}}
+test string-6.6 {string is, ambiguous class} {
+ list [catch {string is al str} msg] $msg
+} {1 {ambiguous class "al": must be alnum, alpha, ascii, boolean, digit, double, false, integer, lower, space, true, upper, or wordchar}}
+test string-6.7 {string is alpha, all ok} {
+ string is alpha -strict -failindex var abc
+} 1
+test string-6.8 {string is, error in var} {
+ list [string is alpha -failindex var abc5def] $var
+} {0 3}
+test string-6.9 {string is, var shouldn't get set} {
+ catch {unset var}
+ list [catch {string is alpha -failindex var abc; set var} msg] $msg
+} {1 {can't read "var": no such variable}}
+test string-6.10 {string is, ok on empty} {
+ string is alpha {}
+} 1
+test string-6.11 {string is, -strict check against empty} {
+ string is alpha -strict {}
+} 0
+test string-6.12 {string is alnum, true} {
+ string is alnum abc123
+} 1
+test string-6.13 {string is alnum, false} {
+ list [string is alnum -failindex var abc1.23] $var
+} {0 4}
+test string-6.14 {string is alnum, unicode} {
+ string is alnum abcü
+} 1
+test string-6.15 {string is alpha, true} {
+ string is alpha abc
+} 1
+test string-6.16 {string is alpha, false} {
+ list [string is alpha -fail var a1bcde] $var
+} {0 1}
+test string-6.17 {string is alpha, unicode} {
+ string is alpha abc\374
+} 1
+test string-6.18 {string is ascii, true} {
+ string is ascii abc\u007Fend
+} 1
+test string-6.19 {string is ascii, false} {
+ list [string is ascii -fail var abcdef\u0080more] $var
+} {0 6}
+test string-6.20 {string is boolean, true} {
+ string is boolean true
+} 1
+test string-6.21 {string is boolean, true} {
+ string is boolean f
+} 1
+test string-6.22 {string is boolean, true based on type} {
+ string is bool [string compare a a]
+} 1
+test string-6.23 {string is boolean, false} {
+ list [string is bool -fail var yada] $var
+} {0 0}
+test string-6.24 {string is digit, true} {
+ string is digit 0123456789
+} 1
+test string-6.25 {string is digit, false} {
+ list [string is digit -fail var 0123Ü567] $var
+} {0 4}
+test string-6.26 {string is digit, false} {
+ list [string is digit -fail var +123567] $var
+} {0 0}
+test string-6.27 {string is double, true} {
+ string is double 1
+} 1
+test string-6.28 {string is double, true} {
+ string is double [expr double(1)]
+} 1
+test string-6.29 {string is double, true} {
+ string is double 1.0
+} 1
+test string-6.30 {string is double, true} {
+ string is double [string compare a a]
+} 1
+test string-6.31 {string is double, true} {
+ string is double " +1.0e-1 "
+} 1
+test string-6.32 {string is double, true} {
+ string is double "\n1.0\v"
+} 1
+test string-6.33 {string is double, false} {
+ list [string is double -fail var 1abc] $var
+} {0 1}
+test string-6.34 {string is double, false} {
+ list [string is double -fail var abc] $var
+} {0 0}
+test string-6.35 {string is double, false} {
+ list [string is double -fail var " 1.0e4e4 "] $var
+} {0 8}
+test string-6.36 {string is double, false} {
+ list [string is double -fail var "\n"] $var
+} {0 0}
+test string-6.37 {string is double, false on int overflow} {
+ list [string is double -fail var 12345678901234567890] $var
+} {0 -1}
+test string-6.38 {string is double, false on underflow} {
+ catch {unset var}
+ list [string is double -fail var 123e-9999] $var
+} {0 -1}
+test string-6.39 {string is double, false} {
+ list [string is double -fail var .e1] $var
+} {0 0}
+test string-6.40 {string is false, true} {
+ string is false false
+} 1
+test string-6.41 {string is false, true} {
+ string is false FaLsE
+} 1
+test string-6.42 {string is false, true} {
+ string is false N
+} 1
+test string-6.43 {string is false, true} {
+ string is false 0
+} 1
+test string-6.44 {string is false, true} {
+ string is false off
+} 1
+test string-6.45 {string is false, false} {
+ list [string is false -fail var abc] $var
+} {0 0}
+test string-6.46 {string is false, false} {
+ catch {unset var}
+ list [string is false -fail var Y] $var
+} {0 0}
+test string-6.47 {string is false, false} {
+ catch {unset var}
+ list [string is false -fail var offensive] $var
+} {0 0}
+test string-6.48 {string is integer, true} {
+ string is integer +1234567890
+} 1
+test string-6.49 {string is integer, true on type} {
+ string is integer [expr int(50.0)]
+} 1
+test string-6.50 {string is integer, true} {
+ string is integer [list -10]
+} 1
+test string-6.51 {string is integer, true as hex} {
+ string is integer 0xabcdef
+} 1
+test string-6.52 {string is integer, true as octal} {
+ string is integer 012345
+} 1
+test string-6.53 {string is integer, true with whitespace} {
+ string is integer " \n1234\v"
+} 1
+test string-6.54 {string is integer, false} {
+ list [string is integer -fail var 123abc] $var
+} {0 3}
+test string-6.55 {string is integer, false on overflow} {
+ list [string is integer -fail var +12345678901234567890] $var
+} {0 -1}
+test string-6.56 {string is integer, false} {
+ list [string is integer -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.57 {string is integer, false} {
+ list [string is integer -fail var " "] $var
+} {0 0}
+test string-6.58 {string is integer, false on bad octal} {
+ list [string is integer -fail var 036963] $var
+} {0 3}
+test string-6.59 {string is integer, false on bad hex} {
+ list [string is integer -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.60 {string is lower, true} {
+ string is lower abc
+} 1
+test string-6.61 {string is lower, unicode true} {
+ string is lower abcüue
+} 1
+test string-6.62 {string is lower, false} {
+ list [string is lower -fail var aBc] $var
+} {0 1}
+test string-6.63 {string is lower, false} {
+ list [string is lower -fail var abc1] $var
+} {0 3}
+test string-6.64 {string is lower, unicode false} {
+ list [string is lower -fail var abÜUE] $var
+} {0 2}
+test string-6.65 {string is space, true} {
+ string is space " \t\n\v\f"
+} 1
+test string-6.66 {string is space, false} {
+ list [string is space -fail var " \t\n\v1\f"] $var
+} {0 4}
+test string-6.67 {string is true, true} {
+ string is true true
+} 1
+test string-6.68 {string is true, true} {
+ string is true TrU
+} 1
+test string-6.69 {string is true, true} {
+ string is true ye
+} 1
+test string-6.70 {string is true, true} {
+ string is true 1
+} 1
+test string-6.71 {string is true, true} {
+ string is true on
+} 1
+test string-6.72 {string is true, false} {
+ list [string is true -fail var onto] $var
+} {0 0}
+test string-6.73 {string is true, false} {
+ catch {unset var}
+ list [string is true -fail var 25] $var
+} {0 0}
+test string-6.74 {string is true, false} {
+ catch {unset var}
+ list [string is true -fail var no] $var
+} {0 0}
+test string-6.75 {string is upper, true} {
+ string is upper ABC
+} 1
+test string-6.76 {string is upper, unicode true} {
+ string is upper ABCÜUE
+} 1
+test string-6.77 {string is upper, false} {
+ list [string is upper -fail var AbC] $var
+} {0 1}
+test string-6.78 {string is upper, false} {
+ list [string is upper -fail var AB2C] $var
+} {0 2}
+test string-6.79 {string is upper, unicode false} {
+ list [string is upper -fail var ABCüue] $var
+} {0 3}
+test string-6.80 {string is wordchar, true} {
+ string is wordchar abc_123
+} 1
+test string-6.81 {string is wordchar, unicode true} {
+ string is wordchar abcüabÜAB\u5001
+} 1
+test string-6.82 {string is wordchar, false} {
+ list [string is wordchar -fail var abcd.ef] $var
+} {0 4}
+test string-6.83 {string is wordchar, unicode false} {
+ list [string is wordchar -fail var abc\u0080def] $var
+} {0 3}
+
+test string-7.1 {string last} {
+ list [catch {string last a} msg] $msg
+} {1 {wrong # args: should be "string last string1 string2"}}
+test string-7.2 {string last} {
+ list [catch {string last a b c} msg] $msg
+} {1 {wrong # args: should be "string last string1 string2"}}
+test string-7.3 {string last} {
string la xxx xxxx123xx345x678
} 1
-test string-4.2 {string last} {
+test string-7.4 {string last} {
string last xx xxxx123xx345x678
} 7
-test string-4.3 {string last} {
+test string-7.5 {string last} {
string las x xxxx123xx345x678
} 12
-test string-4.4 {string last} {
- list [catch {string last a} msg] $msg
-} {1 {wrong # args: should be "string last string1 string2"}}
-test string-4.5 {string last} {
- list [catch {string last a b c} msg] $msg
-} {1 {wrong # args: should be "string last string1 string2"}}
+test string-7.6 {string last, unicode} {
+ string las x xxxx12\u7266xx345x678
+} 12
+test string-7.7 {string last, unicode} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
-test string-5.1 {string length} {
- string length "a little string"
-} 15
-test string-5.2 {string length} {
- string le ""
+test cmdMZ-8.1 {Tcl_StringObjCmd: string bytelength} {
+ list [catch {string bytelength} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test cmdMZ-8.2 {Tcl_StringObjCmd: string bytelength} {
+ list [catch {string bytelength a b} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test cmdMZ-8.3 {Tcl_StringObjCmd: string bytelength} {
+ string bytelength "\u00c7"
+} 2
+test cmdMZ-8.4 {Tcl_StringObjCmd: string bytelength} {
+ string b ""
} 0
-test string-5.3 {string length} {
+
+test string-9.1 {string length} {
list [catch {string length} msg] $msg
} {1 {wrong # args: should be "string length string"}}
-test string-5.4 {string length} {
+test string-9.2 {string length} {
list [catch {string length a b} msg] $msg
} {1 {wrong # args: should be "string length string"}}
+test string-9.3 {string length} {
+ string length "a little string"
+} 15
+test string-9.4 {string length} {
+ string le ""
+} 0
+test string-9.5 {string length, unicode} {
+ string le "abcd\u7266"
+} 5
-test string-6.1 {string match} {
+test string-10.1 {string map, too few args} {
+ list [catch {string map} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.2 {string map, bad args} {
+ list [catch {string map {a b} abba oops} msg] $msg
+} {1 {bad option "a b": must be -nocase}}
+test string-10.3 {string map, too many args} {
+ list [catch {string map -nocase {a b} str1 str2} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.4 {string map} {
+ string map {a b} abba
+} {bbbb}
+test string-10.5 {string map} {
+ string map {a b} a
+} {b}
+test string-10.6 {string map -nocase} {
+ string map -nocase {a b} Abba
+} {bbbb}
+test string-10.7 {string map} {
+ string map {abc 321 ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.8 {string map -nocase} {
+ string map -nocase {aBc 321 Ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.9 {string map -nocase} {
+ string map -no {abc 321 Ab * a A} aAbCaBaAbAbcAb
+} {A321*A*321*}
+test string-10.10 {string map} {
+ list [catch {string map {a b c} abba} msg] $msg
+} {1 {char map list unbalanced}}
+test string-10.11 {string map, nulls} {
+ string map {\x00 NULL blah \x00nix} {qwerty}
+} {qwerty}
+test string-10.12 {string map, unicode} {
+ string map [list \374 ue UE \334] "a\374ueUE\000EU"
+} aueue\334\0EU
+test string-10.13 {string map, -nocase unicode} {
+ string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU"
+} aue\334\334\0EU
+
+test string-11.1 {string match} {
+ list [catch {string match a} msg] $msg
+} {1 {wrong # args: should be "string match pattern string"}}
+test string-11.2 {string match} {
+ list [catch {string match a b c} msg] $msg
+} {1 {wrong # args: should be "string match pattern string"}}
+test string-11.3 {string match} {
string match abc abc
} 1
-test string-6.2 {string match} {
+test string-11.4 {string match} {
string mat abc abd
} 0
-test string-6.3 {string match} {
+test string-11.5 {string match} {
string match ab*c abc
} 1
-test string-6.4 {string match} {
+test string-11.6 {string match} {
string match ab**c abc
} 1
-test string-6.5 {string match} {
+test string-11.7 {string match} {
string match ab* abcdef
} 1
-test string-6.6 {string match} {
+test string-11.8 {string match} {
string match *c abc
} 1
-test string-6.7 {string match} {
+test string-11.9 {string match} {
string match *3*6*9 0123456789
} 1
-test string-6.8 {string match} {
+test string-11.10 {string match} {
string match *3*6*9 01234567890
} 0
-test string-6.9 {string match} {
+test string-11.11 {string match} {
string match a?c abc
} 1
-test string-6.10 {string match} {
+test string-11.12 {string match} {
string match a??c abc
} 0
-test string-6.11 {string match} {
+test string-11.13 {string match} {
string match ?1??4???8? 0123456789
} 1
-test string-6.12 {string match} {
+test string-11.14 {string match} {
string match {[abc]bc} abc
} 1
-test string-6.13 {string match} {
+test string-11.15 {string match} {
string match {a[abc]c} abc
} 1
-test string-6.14 {string match} {
+test string-11.16 {string match} {
string match {a[xyz]c} abc
} 0
-test string-6.15 {string match} {
+test string-11.17 {string match} {
string match {12[2-7]45} 12345
} 1
-test string-6.16 {string match} {
+test string-11.18 {string match} {
string match {12[ab2-4cd]45} 12345
} 1
-test string-6.17 {string match} {
+test string-11.19 {string match} {
string match {12[ab2-4cd]45} 12b45
} 1
-test string-6.18 {string match} {
+test string-11.20 {string match} {
string match {12[ab2-4cd]45} 12d45
} 1
-test string-6.19 {string match} {
+test string-11.21 {string match} {
string match {12[ab2-4cd]45} 12145
} 0
-test string-6.20 {string match} {
+test string-11.22 {string match} {
string match {12[ab2-4cd]45} 12545
} 0
-test string-6.21 {string match} {
+test string-11.23 {string match} {
string match {a\*b} a*b
} 1
-test string-6.22 {string match} {
+test string-11.24 {string match} {
string match {a\*b} ab
} 0
-test string-6.23 {string match} {
+test string-11.25 {string match} {
string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
} 1
-test string-6.24 {string match} {
+test string-11.26 {string match} {
string match ** ""
} 1
-test string-6.25 {string match} {
+test string-11.27 {string match} {
string match *. ""
} 0
-test string-6.26 {string match} {
+test string-11.28 {string match} {
string match "" ""
} 1
-test string-6.27 {string match} {
+test string-11.29 {string match} {
string match \[a a
} 1
-test string-6.28 {string match} {
- list [catch {string match a} msg] $msg
-} {1 {wrong # args: should be "string match pattern string"}}
-test string-6.29 {string match} {
- list [catch {string match a b c} msg] $msg
-} {1 {wrong # args: should be "string match pattern string"}}
-test string-7.1 {string range} {
+test string-12.1 {string range} {
+ list [catch {string range} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.2 {string range} {
+ list [catch {string range a 1} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.3 {string range} {
+ list [catch {string range a 1 2 3} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.4 {string range} {
string range abcdefghijklmnop 2 14
} {cdefghijklmno}
-test string-7.2 {string range} {
+test string-12.5 {string range, last > length} {
string range abcdefghijklmnop 7 1000
} {hijklmnop}
-test string-7.3 {string range} {
+test string-12.6 {string range} {
string range abcdefghijklmnop 10 e
} {klmnop}
-test string-7.4 {string range} {
+test string-12.7 {string range, last < first} {
string range abcdefghijklmnop 10 9
} {}
-test string-7.5 {string range} {
+test string-12.8 {string range, first < 0} {
string range abcdefghijklmnop -3 2
} {abc}
-test string-7.6 {string range} {
+test string-12.9 {string range} {
string range abcdefghijklmnop -3 -2
} {}
-test string-7.7 {string range} {
+test string-12.10 {string range} {
string range abcdefghijklmnop 1000 1010
} {}
-test string-7.8 {string range} {
+test string-12.11 {string range} {
string range abcdefghijklmnop -100 end
} {abcdefghijklmnop}
-test string-7.9 {string range} {
- list [catch {string range} msg] $msg
-} {1 {wrong # args: should be "string range string first last"}}
-test string-7.10 {string range} {
- list [catch {string range a 1} msg] $msg
-} {1 {wrong # args: should be "string range string first last"}}
-test string-7.11 {string range} {
- list [catch {string range a 1 2 3} msg] $msg
-} {1 {wrong # args: should be "string range string first last"}}
-test string-7.12 {string range} {
+test string-12.12 {string range} {
list [catch {string range abc abc 1} msg] $msg
-} {1 {syntax error in expression "abc"}}
-test string-7.13 {string range} {
+} {1 {bad index "abc": must be integer or end?-integer?}}
+test string-12.13 {string range} {
list [catch {string range abc 1 eof} msg] $msg
-} {1 {syntax error in expression "eof"}}
-test string-7.14 {string range} {
+} {1 {bad index "eof": must be integer or end?-integer?}}
+test string-12.14 {string range} {
string range abcdefghijklmnop end-1 end
} {op}
-test string-7.15 {string range} {
+test string-12.15 {string range} {
string range abcdefghijklmnop e 1000
} {p}
-test string-7.16 {string range} {
+test string-12.16 {string range} {
string range abcdefghijklmnop end end-1
} {}
+test string-12.17 {string range, unicode} {
+ string range ab\u7266cdefghijklmnop 5 5
+} e
+test string-12.18 {string range, unicode} {
+ string range ab\u7266cdefghijklmnop 2 3
+} \u7266c
-test string-8.1 {string trim} {
- string trim " XYZ "
-} {XYZ}
-test string-8.2 {string trim} {
- string trim "\t\nXYZ\t\n\r\n"
-} {XYZ}
-test string-8.3 {string trim} {
- string trim " A XYZ A "
-} {A XYZ A}
-test string-8.4 {string trim} {
- string trim "XXYYZZABC XXYYZZ" ZYX
-} {ABC }
-test string-8.5 {string trim} {
- string trim " \t\r "
+test string-13.1 {string repeat} {
+ list [catch {string repeat} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.2 {string repeat} {
+ list [catch {string repeat abc 10 oops} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.3 {string repeat} {
+ string repeat {} 100
} {}
-test string-8.6 {string trim} {
- string trim {abcdefg} {}
-} {abcdefg}
-test string-8.7 {string trim} {
- string trim {}
+test string-13.4 {string repeat} {
+ string repeat { } 5
+} { }
+test string-13.5 {string repeat} {
+ string repeat abc 3
+} {abcabcabc}
+test string-13.6 {string repeat} {
+ string repeat abc -1
} {}
-test string-8.8 {string trim} {
- string trim ABC DEF
-} {ABC}
-test string-8.9 {string trim} {
- list [catch {string trim} msg] $msg
-} {1 {wrong # args: should be "string trim string ?chars?"}}
-test string-8.10 {string trim} {
- list [catch {string trim a b c} msg] $msg
-} {1 {wrong # args: should be "string trim string ?chars?"}}
-
-test string-9.1 {string trimleft} {
- string trimleft " XYZ "
-} {XYZ }
-test string-9.2 {string trimleft} {
- list [catch {string trimleft} msg] $msg
-} {1 {wrong # args: should be "string trimleft string ?chars?"}}
+test string-13.7 {string repeat} {
+ list [catch {string repeat abc end} msg] $msg
+} {1 {expected integer but got "end"}}
-test string-10.1 {string trimright} {
- string trimright " XYZ "
-} { XYZ}
-test string-10.2 {string trimright} {
- string trimright " "
+test string-14.1 {string replace} {
+ list [catch {string replace} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.2 {string replace} {
+ list [catch {string replace a 1} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.3 {string replace} {
+ list [catch {string replace a 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.4 {string replace} {
} {}
-test string-10.3 {string trimright} {
- string trimright ""
+test string-14.5 {string replace} {
+ string replace abcdefghijklmnop 2 14
+} {abp}
+test string-14.6 {string replace} {
+ string replace abcdefghijklmnop 7 1000
+} {abcdefg}
+test string-14.7 {string replace} {
+ string replace abcdefghijklmnop 10 e
+} {abcdefghij}
+test string-14.8 {string replace} {
+ string replace abcdefghijklmnop 10 9
+} {abcdefghijklmnop}
+test string-14.9 {string replace} {
+ string replace abcdefghijklmnop -3 2
+} {defghijklmnop}
+test string-14.10 {string replace} {
+ string replace abcdefghijklmnop -3 -2
+} {abcdefghijklmnop}
+test string-14.11 {string replace} {
+ string replace abcdefghijklmnop 1000 1010
+} {abcdefghijklmnop}
+test string-14.12 {string replace} {
+ string replace abcdefghijklmnop -100 end
} {}
-test string-10.4 {string trimright errors} {
- list [catch {string trimright} msg] $msg
-} {1 {wrong # args: should be "string trimright string ?chars?"}}
-test string-10.5 {string trimright errors} {
- list [catch {string trimg a} msg] $msg
-} {1 {bad option "trimg": must be bytelength, compare, equal, first, icompare, iequal, index, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
+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?}}
+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?}}
+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
+} {foo}
+test string-14.17 {string replace} {
+ string replace abcdefghijklmnop end end-1
+} {abcdefghijklmnop}
-test string-11.1 {string tolower} {
+test string-15.1 {string tolower too few args} {
+ list [catch {string tolower} msg] $msg
+} {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?}}
+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?"}}
+test string-15.4 {string tolower} {
string tolower ABCDeF
} {abcdef}
-test string-11.2 {string tolower} {
+test string-15.5 {string tolower} {
string tolower "ABC XyZ"
} {abc xyz}
-test string-11.3 {string tolower} {
+test string-15.6 {string tolower} {
string tolower {123#$&*()}
} {123#$&*()}
-test string-11.4 {string tolower too few args} {
- list [catch {string tolower} msg] $msg
-} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
-test string-11.5 {string tolower bad args} {
- list [catch {string tolower a b} msg] $msg
-} {1 {syntax error in expression "b"}}
-test string-11.6 {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?"}}
-test string-11.7 {string tolower} {
+test string-15.7 {string tolower} {
string tolower ABC 1
} AbC
-test string-11.8 {string tolower} {
+test string-15.8 {string tolower} {
string tolower ABC 1 end
} Abc
-test string-11.9 {string tolower} {
+test string-15.9 {string tolower} {
string tolower ABC 0 end-1
} abC
-test string-11.10 {string tolower called with badly formed Utf string} {
- string tolower [bytestring "\u00fcBER"]
-} [bytestring "\u00fcber"]
-
-test string-12.1 {string totitle} {
- string totitle ABCDeF
-} {Abcdef}
-test string-12.2 {string totitle} {
- string totitle "aBC d Hij xyZ"
-} {Abc d hij xyz}
-test string-12.3 {string totitle} {
- string totitle {123#$&*()}
-} {123#$&*()}
-test string-12.4 {string totitle} {
- list [catch {string totitle} msg] $msg
-} {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
-test string-12.5 {string totitle} {
- list [catch {string totitle a b} msg] $msg
-} {1 {syntax error in expression "b"}}
-test string-12.6 {string totitle too many args} {
- list [catch {string totitle ABC 1 end oops} msg] $msg
-} {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
-test string-12.7 {string totitle} {
- string totitle abC 1
-} aBC
-test string-12.8 {string totitle} {
- string totitle ABC 1 end
-} ABc
-test string-12.9 {string totitle} {
- string totitle ABC 0 end-1
-} AbC
-test string-12.10 {string totitle called with badly formed Utf string} {
- string totitle [bytestring "\u00fcBER"]
-} [bytestring "\u00fcber"]
+test string-15.10 {string tolower, unicode} {
+ string tolower ABCabc\xc7\xe7
+} "abcabc\xe7\xe7"
-test string-13.1 {string toupper} {
+test string-16.1 {string toupper} {
+ list [catch {string toupper} msg] $msg
+} {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?}}
+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?"}}
+test string-16.4 {string toupper} {
string toupper abCDEf
} {ABCDEF}
-test string-13.2 {string toupper} {
+test string-16.5 {string toupper} {
string toupper "abc xYz"
} {ABC XYZ}
-test string-13.3 {string toupper} {
+test string-16.6 {string toupper} {
string toupper {123#$&*()}
} {123#$&*()}
-test string-13.4 {string toupper} {
- list [catch {string toupper} msg] $msg
-} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
-test string-13.5 {string toupper} {
- list [catch {string toupper a b} msg] $msg
-} {1 {syntax error in expression "b"}}
-test string-13.6 {string toupper} {
- list [catch {string toupper a 1 end oops} msg] $msg
-} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
-test string-13.7 {string toupper} {
+test string-16.7 {string toupper} {
string toupper abc 1
} aBc
-test string-13.8 {string toupper} {
+test string-16.8 {string toupper} {
string toupper abc 1 end
} aBC
-test string-13.9 {string toupper} {
+test string-16.9 {string toupper} {
string toupper abc 0 end-1
} ABc
-test string-13.10 {string toupper called with badly formed Utf string} {
- string toupper [bytestring "\u00fcber"]
-} [bytestring "\u00fcBER"]
+test string-16.10 {string toupper, unicode} {
+ string toupper ABCabc\xc7\xe7
+} "ABCABC\xc7\xc7"
+
+test string-17.1 {string totitle} {
+ list [catch {string totitle} msg] $msg
+} {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?}}
+test string-17.3 {string totitle} {
+ string totitle abCDEf
+} {Abcdef}
+test string-17.4 {string totitle} {
+ string totitle "abc xYz"
+} {Abc xyz}
+test string-17.5 {string totitle} {
+ string totitle {123#$&*()}
+} {123#$&*()}
+test string-17.6 {string totitle, unicode} {
+ string totitle ABCabc\xc7\xe7
+} "Abcabc\xe7\xe7"
+test string-17.7 {string totitle, unicode} {
+ string totitle \u01f3BCabc\xc7\xe7
+} "\u01f2bcabc\xe7\xe7"
+
+test string-18.1 {string trim} {
+ list [catch {string trim} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.2 {string trim} {
+ list [catch {string trim a b c} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.3 {string trim} {
+ string trim " XYZ "
+} {XYZ}
+test string-18.4 {string trim} {
+ string trim "\t\nXYZ\t\n\r\n"
+} {XYZ}
+test string-18.5 {string trim} {
+ string trim " A XYZ A "
+} {A XYZ A}
+test string-18.6 {string trim} {
+ string trim "XXYYZZABC XXYYZZ" ZYX
+} {ABC }
+test string-18.7 {string trim} {
+ string trim " \t\r "
+} {}
+test string-18.8 {string trim} {
+ string trim {abcdefg} {}
+} {abcdefg}
+test string-18.9 {string trim} {
+ string trim {}
+} {}
+test string-18.10 {string trim} {
+ string trim ABC DEF
+} {ABC}
+test string-18.11 {string trim, unicode} {
+ string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
+} " AB\xe7C "
+
+test string-19.1 {string trimleft} {
+ list [catch {string trimleft} msg] $msg
+} {1 {wrong # args: should be "string trimleft string ?chars?"}}
+test string-19.2 {string trimleft} {
+ string trimleft " XYZ "
+} {XYZ }
+
+test string-20.1 {string trimright errors} {
+ list [catch {string trimright} msg] $msg
+} {1 {wrong # args: should be "string trimright string ?chars?"}}
+test string-20.2 {string trimright errors} {
+ list [catch {string trimg a} msg] $msg
+} {1 {bad option "trimg": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
+test string-20.3 {string trimright} {
+ string trimright " XYZ "
+} { XYZ}
+test string-20.4 {string trimright} {
+ string trimright " "
+} {}
+test string-20.5 {string trimright} {
+ string trimright ""
+} {}
-test string-14.1 {string wordend} {
+test string-21.1 {string wordend} {
list [catch {string wordend a} msg] $msg
} {1 {wrong # args: should be "string wordend string index"}}
-test string-14.2 {string wordend} {
+test string-21.2 {string wordend} {
list [catch {string wordend a b c} msg] $msg
} {1 {wrong # args: should be "string wordend string index"}}
-test string-14.3 {string wordend} {
+test string-21.3 {string wordend} {
list [catch {string wordend a gorp} msg] $msg
-} {1 {syntax error in expression "gorp"}}
-test string-14.4 {string wordend} {
+} {1 {bad index "gorp": must be integer or end?-integer?}}
+test string-21.4 {string wordend} {
string wordend abc. -1
} 3
-test string-14.5 {string wordend} {
+test string-21.5 {string wordend} {
string wordend abc. 100
} 4
-test string-14.6 {string wordend} {
+test string-21.6 {string wordend} {
string wordend "word_one two three" 2
} 8
-test string-14.7 {string wordend} {
+test string-21.7 {string wordend} {
string wordend "one .&# three" 5
} 6
-test string-14.8 {string wordend} {
+test string-21.8 {string wordend} {
string worde "x.y" 0
} 1
-test string-14.9 {string wordend} {
+test string-21.9 {string wordend} {
string worde "x.y" end-1
} 2
+test string-21.10 {string wordend, unicode} {
+ string wordend "xyz\u00c7de fg" 0
+} 6
+test string-21.11 {string wordend, unicode} {
+ string wordend "xyz\uc700de fg" 0
+} 6
+test string-21.12 {string wordend, unicode} {
+ string wordend "xyz\u203fde fg" 0
+} 6
+test string-21.13 {string wordend, unicode} {
+ string wordend "xyz\u2045de fg" 0
+} 3
+test string-21.14 {string wordend, unicode} {
+ string wordend "\uc700\uc700 abc" 8
+} 6
-test string-15.1 {string wordstart} {
+test string-22.1 {string wordstart} {
list [catch {string word a} msg] $msg
-} {1 {ambiguous option "word": must be bytelength, compare, equal, first, icompare, iequal, index, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
-test string-15.2 {string wordstart} {
+} {1 {ambiguous option "word": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
+test string-22.2 {string wordstart} {
list [catch {string wordstart a} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
-test string-15.3 {string wordstart} {
+test string-22.3 {string wordstart} {
list [catch {string wordstart a b c} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
-test string-15.4 {string wordstart} {
+test string-22.4 {string wordstart} {
list [catch {string wordstart a gorp} msg] $msg
-} {1 {syntax error in expression "gorp"}}
-test string-15.5 {string wordstart} {
+} {1 {bad index "gorp": must be integer or end?-integer?}}
+test string-22.5 {string wordstart} {
string wordstart "one two three_words" 400
} 8
-test string-15.6 {string wordstart} {
+test string-22.6 {string wordstart} {
string wordstart "one two three_words" 2
} 0
-test string-15.7 {string wordstart} {
+test string-22.7 {string wordstart} {
string wordstart "one two three_words" -2
} 0
-test string-15.8 {string wordstart} {
+test string-22.8 {string wordstart} {
string wordstart "one .*&^ three" 6
} 6
-test string-15.9 {string wordstart} {
+test string-22.9 {string wordstart} {
string wordstart "one two three" 4
} 4
-test string-15.10 {string wordstart} {
+test string-22.10 {string wordstart} {
string wordstart "one two three" end-5
} 7
-
-test string-16.1 {error conditions} {
- list [catch {string gorp a b} msg] $msg
-} {1 {bad option "gorp": must be bytelength, compare, equal, first, icompare, iequal, index, last, length, map, match, range, repeat, replace, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
-test string-16.2 {error conditions} {
- list [catch {string} msg] $msg
-} {1 {wrong # args: should be "string option arg ?arg ...?"}}
-
-# only need a few tests on equal, since it uses the same code as
-# string compare, but just modifies the return output
-test string-17.1 {string equal} {
- string equal abcde abdef
-} 0
-test string-17.2 {string equal} {
- string eq abcde ABCDE
-} 0
-test string-17.3 {string equal} {
- string equal abcde abcde
-} 1
-
-test string-18.1 {string icompare} {
- string icompare abcde abdef
-} -1
-test string-18.2 {string icompare} {
- string ic abcde ABCDE
-} 0
-test string-18.3 {string icompare} {
- string icompare abcde abcde
-} 0
-test string-18.4 {string icompare too few args} {
- list [catch {string icompare a} msg] $msg
-} {1 {wrong # args: should be "string icompare string1 string2 ?length?"}}
-test string-18.5 {string icompare bad args} {
- list [catch {string icompare a b c} msg] $msg
-} {1 {expected integer but got "c"}}
-test string-18.6 {string icompare too many args} {
- list [catch {string icompare a b 1 c} msg] $msg
-} {1 {wrong # args: should be "string icompare string1 string2 ?length?"}}
-test string-18.7 {string icompare with length} {
- string icompare abcde Abxyz 2
-} 0
-test string-18.8 {string icompare with special index} {
- list [catch {string icompare Abcde abxyz end-3} msg] $msg
-} {1 {expected integer but got "end-3"}}
-
-test string-19.1 {string iequal} {
- string iequal abcde abdef
-} 0
-test string-19.2 {string iequal} {
- string ieq abcde ABCDE
-} 1
-test string-19.3 {string iequal} {
- string iequal abcde abcde
-} 1
-
-test string-20.1 {string map} {
- list [catch {string map} msg] $msg
-} {1 {wrong # args: should be "string map charMap string"}}
-test string-20.2 {string map} {
- list [catch {string map {a b} abba oops} msg] $msg
-} {1 {wrong # args: should be "string map charMap string"}}
-test string-20.3 {string map} {
- string map {a b} abba
-} {bbbb}
-test string-20.4 {string map} {
- string map {abc 321 ab * a A} aabcabaababcab
-} {A321*A*321*}
-test string-20.5 {string map} {
- list [catch {string map {a b c} abba} msg] $msg
-} {1 {char map list unbalanced}}
-test string-20.6 {string map} {
- string map {\x00 NULL blah \x00nix} {qwerty}
-} {qwerty}
-
-test string-21.1 {string repeat} {
- list [catch {string repeat} msg] $msg
-} {1 {wrong # args: should be "string repeat string count"}}
-test string-21.2 {string repeat} {
- list [catch {string repeat abc 10 oops} msg] $msg
-} {1 {wrong # args: should be "string repeat string count"}}
-test string-21.3 {string repeat} {
- string repeat {} 100
-} {}
-test string-21.4 {string repeat} {
- string repeat { } 5
-} { }
-test string-21.5 {string repeat} {
- string repeat abc 3
-} {abcabcabc}
-test string-21.6 {string repeat} {
- string repeat abc -1
-} {}
-test string-21.7 {string repeat} {
- list [catch {string repeat abc end} msg] $msg
-} {1 {expected integer but got "end"}}
-
-test string-22.1 {string replace} {
-} {}
-test string-22.2 {string replace} {
- string replace abcdefghijklmnop 2 14
-} {abp}
-test string-22.3 {string replace} {
- string replace abcdefghijklmnop 7 1000
-} {abcdefg}
-test string-22.4 {string replace} {
- string replace abcdefghijklmnop 10 e
-} {abcdefghij}
-test string-22.5 {string replace} {
- string replace abcdefghijklmnop 10 9
-} {abcdefghijklmnop}
-test string-22.6 {string replace} {
- string replace abcdefghijklmnop -3 2
-} {defghijklmnop}
-test string-22.7 {string replace} {
- string replace abcdefghijklmnop -3 -2
-} {abcdefghijklmnop}
-test string-22.8 {string replace} {
- string replace abcdefghijklmnop 1000 1010
-} {abcdefghijklmnop}
-test string-22.9 {string replace} {
- string replace abcdefghijklmnop -100 end
-} {}
-test string-22.10 {string replace} {
- list [catch {string replace} msg] $msg
-} {1 {wrong # args: should be "string replace string first last ?string?"}}
-test string-22.11 {string replace} {
- list [catch {string replace a 1} msg] $msg
-} {1 {wrong # args: should be "string replace string first last ?string?"}}
-test string-22.12 {string replace} {
- list [catch {string replace a 1 2 3 4} msg] $msg
-} {1 {wrong # args: should be "string replace string first last ?string?"}}
-test string-22.13 {string replace} {
- list [catch {string replace abc abc 1} msg] $msg
-} {1 {syntax error in expression "abc"}}
-test string-22.14 {string replace} {
- list [catch {string replace abc 1 eof} msg] $msg
-} {1 {syntax error in expression "eof"}}
-test string-22.15 {string replace} {
- string replace abcdefghijklmnop end-10 end-2 NEW
-} {abcdeNEWop}
-test string-22.16 {string replace} {
- string replace abcdefghijklmnop 0 e foo
-} {foo}
-test string-22.17 {string replace} {
- string replace abcdefghijklmnop end end-1
-} {abcdefghijklmnop}
+test string-22.11 {string wordstart, unicode} {
+ string wordstart "one tw\u00c7o three" 7
+} 4
+test string-22.12 {string wordstart, unicode} {
+ string wordstart "ab\uc700\uc700 cdef ghi" 12
+} 10
+test string-22.13 {string wordstart, unicode} {
+ string wordstart "\uc700\uc700 abc" 8
+} 3
# cleanup
::tcltest::cleanupTests
@@ -619,12 +978,3 @@ return
-
-
-
-
-
-
-
-
-