From f832cd22b120385368e264c684cf8d874014bf3b Mon Sep 17 00:00:00 2001 From: stanton Date: Thu, 6 May 1999 18:46:42 +0000 Subject: * 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. --- doc/string.n | 84 ++-- generic/tclCmdMZ.c | 466 +++++++++++++++----- generic/tclUtil.c | 29 +- tests/cmdIL.test | 16 +- tests/cmdMZ.test | 437 +------------------ tests/error.test | 26 +- tests/ioCmd.test | 10 +- tests/lindex.test | 16 +- tests/linsert.test | 16 +- tests/lrange.test | 18 +- tests/lreplace.test | 20 +- tests/string.test | 1166 +++++++++++++++++++++++++++++++++------------------ 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 - - - - - - - - - -- cgit v0.12