Compare commits

...
Author SHA1 Message Date
dkf b55d5cc57e Fix for the weird [string first] behaviour. 2017-11-04 00:34:48 +00:00
dkf e4356f7d64 Detected bug in [string first] with unicode. Pat Thoyts found it. 2017-11-04 00:25:43 +00:00
dgp 0480b5d79b Revise a few stray packages not yet ready to tolerate a Tcl 9 bump. 2017-11-03 17:02:49 +00:00
dgp 10a9305777 TIP 345 Implementation. 2017-11-03 16:48:44 +00:00
jan.nijtmans d8596e5583 merge core-8-6-branch 2017-11-03 12:59:07 +00:00
jan.nijtmans 5528e1c1a2 Fix [6f2f83cc149e9918884faffefebc8dfa695f4ea0|6f2f83cc14]: tclWinload.c robustness. And fix a minor possible memory leak in TclSetupEnv() as well. Thanks to Christian Werner for both suggestions, backported from Androwish. 2017-11-03 12:57:15 +00:00
jan.nijtmans 785f1059e4 merge core-8-6-branch 2017-11-03 12:15:08 +00:00
jan.nijtmans 274ab123a8 Better versions of TclGetIntFromObj and TclGetIntForIndexM macro's, which give advantage for platforms where longs are not ints (e.g. linux64) 2017-11-03 12:14:01 +00:00
dgp 2ff3ecb534 merge trunk 2017-10-30 12:02:48 +00:00
dgp bed6e18d15 merge trunk 2017-10-27 13:12:09 +00:00
dgp 053a74e0fa Create new testing command [teststringbytes] to probe the things that
otherwise require [encoding convertto identity]. adapt encoding-15.3 to use.
2017-10-26 02:08:27 +00:00
dgp 30c6827ee1 Convert remaining tests to use [testbytestring].
encoding-15.3 still needs replacement for [encoding convertto identity].
That is, some testing command to expose objPtr->bytes.
2017-10-25 02:54:24 +00:00
dgp eb2cfa3e6f Repair Tcl_CreateEncoding(); Modernize [testencoding];
Update most tests toying with identity encoding.
2017-10-25 02:23:12 +00:00
dgp 40d9b81e23 Stop using "identity" as an encoding to test basic functionng of the
[encoding] command. "iso8859-1" is another one always available.
2017-10-24 23:30:35 +00:00
dgp 1552384787 Extend Tcl_CreateEncoding() to be able to create an encoding without
registering it when it has no name.  Then use this to create "identity"
encoding without naming it "identity". Then no one can look it up by that name.
2017-10-24 23:16:23 +00:00
dgp 319b71965b backout initial commit; need more care.
Binary writes internally make use of this encoding.  Need to hide it
instead of destroy it.
2017-10-23 17:58:07 +00:00
dgp 45d0977a5c Implementation branch for TIP 345: Kill the "identity" encoding.
This checkin, completely does that.  Bad news is it causes huge failures.
We're still making a lot of use of this encoding, and cannot complete
this TIP until the branch is repaired.
2017-10-23 17:06:57 +00:00
14 changed files with 153 additions and 84 deletions
+28 -24
View File
@@ -563,7 +563,7 @@ TclInitEncodingSubsystem(void)
* formed UTF-8 into a properly formed stream.
*/
type.encodingName = "identity";
type.encodingName = NULL;
type.toUtfProc = BinaryProc;
type.fromUtfProc = BinaryProc;
type.freeProc = NULL;
@@ -851,7 +851,9 @@ FreeEncoding(
if (encodingPtr->hPtr != NULL) {
Tcl_DeleteHashEntry(encodingPtr->hPtr);
}
ckfree(encodingPtr->name);
if (encodingPtr->name) {
ckfree(encodingPtr->name);
}
ckfree(encodingPtr);
}
}
@@ -1040,27 +1042,8 @@ Tcl_CreateEncoding(
const Tcl_EncodingType *typePtr)
/* The encoding type. */
{
Tcl_HashEntry *hPtr;
int isNew;
Encoding *encodingPtr;
char *name;
Tcl_MutexLock(&encodingMutex);
hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &isNew);
if (isNew == 0) {
/*
* Remove old encoding from hash table, but don't delete it until last
* reference goes away.
*/
encodingPtr = Tcl_GetHashValue(hPtr);
encodingPtr->hPtr = NULL;
}
name = ckalloc(strlen(typePtr->encodingName) + 1);
encodingPtr = ckalloc(sizeof(Encoding));
encodingPtr->name = strcpy(name, typePtr->encodingName);
Encoding *encodingPtr = ckalloc(sizeof(Encoding));
encodingPtr->name = NULL;
encodingPtr->toUtfProc = typePtr->toUtfProc;
encodingPtr->fromUtfProc = typePtr->fromUtfProc;
encodingPtr->freeProc = typePtr->freeProc;
@@ -1072,11 +1055,32 @@ Tcl_CreateEncoding(
encodingPtr->lengthProc = (LengthProc *) unilen;
}
encodingPtr->refCount = 1;
encodingPtr->hPtr = NULL;
if (typePtr->encodingName) {
Tcl_HashEntry *hPtr;
int isNew;
char *name;
Tcl_MutexLock(&encodingMutex);
hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &isNew);
if (isNew == 0) {
/*
* Remove old encoding from hash table, but don't delete it until last
* reference goes away.
*/
Encoding *replaceMe = Tcl_GetHashValue(hPtr);
replaceMe->hPtr = NULL;
}
name = ckalloc(strlen(typePtr->encodingName) + 1);
encodingPtr->name = strcpy(name, typePtr->encodingName);
encodingPtr->hPtr = hPtr;
Tcl_SetHashValue(hPtr, encodingPtr);
Tcl_MutexUnlock(&encodingMutex);
}
return (Tcl_Encoding) encodingPtr;
}
+1
View File
@@ -130,6 +130,7 @@ TclSetupEnv(
* '='; ignore the entry.
*/
Tcl_DStringFree(&envString);
continue;
}
p2++;
+13 -5
View File
@@ -2445,8 +2445,8 @@ typedef struct List {
#define TCL_EACH_COLLECT 1 /* Collect iteration result like [lmap] */
/*
* Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere,
* Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints.
* Macros providing a faster path to integers: Tcl_GetLongFromObj,
* Tcl_GetIntFromObj and TclGetIntForIndex.
*
* WARNING: these macros eval their args more than once.
*/
@@ -2467,9 +2467,17 @@ typedef struct List {
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
#else
#define TclGetIntFromObj(interp, objPtr, intPtr) \
Tcl_GetIntFromObj((interp), (objPtr), (intPtr))
#define TclGetIntForIndexM(interp, objPtr, ignore, idxPtr) \
TclGetIntForIndex(interp, objPtr, ignore, idxPtr)
(((objPtr)->typePtr == &tclIntType \
&& (objPtr)->internalRep.longValue >= -(Tcl_WideInt)(UINT_MAX) \
&& (objPtr)->internalRep.longValue <= (Tcl_WideInt)(UINT_MAX)) \
? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
(((objPtr)->typePtr == &tclIntType \
&& (objPtr)->internalRep.longValue >= INT_MIN \
&& (objPtr)->internalRep.longValue <= INT_MAX) \
? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
#endif
/*
+23 -19
View File
@@ -3242,40 +3242,44 @@ TclStringFind(
return -1;
}
/*
* Check if we have two strings of single-byte characters. If we have, we
* can use strstr() to do the search. Note that we can sometimes have
* multibyte characters when the string could be minimally represented
* using single byte characters; we can't assume that a mismatch here
* means no match.
*/
lh = Tcl_GetCharLength(haystack);
if (haystack->bytes && (lh == haystack->length)) {
/* haystack is all single-byte chars */
if (haystack->bytes && (lh == haystack->length) && needle->bytes
&& (ln == needle->length)) {
/*
* Both haystack and needle are all single-byte chars.
*/
if (needle->bytes && (ln == needle->length)) {
/* needle is also all single-byte chars */
char *found = strstr(haystack->bytes + start, needle->bytes);
char *found = strstr(haystack->bytes + start, needle->bytes);
if (found) {
return (found - haystack->bytes);
} else {
return -1;
}
if (found) {
return (found - haystack->bytes);
} else {
/*
* Cannot find substring with a multi-byte char inside
* a string with no multi-byte chars.
*/
return -1;
}
} else {
/*
* Do the search on the unicode representation for simplicity.
*/
Tcl_UniChar *try, *end, *uh;
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
uh = Tcl_GetUnicodeFromObj(haystack, &lh);
end = uh + lh;
try = uh + start;
while (try + ln <= end) {
if ((*try == *un)
&& (0 == memcmp(try+1, un+1, (ln-1)*sizeof(Tcl_UniChar)))) {
for (try = uh + start; try + ln <= end; try++) {
if ((*try == *un) && (0 ==
memcmp(try + 1, un + 1, (ln-1) * sizeof(Tcl_UniChar)))) {
return (try - uh);
}
try++;
}
return -1;
}
+44 -3
View File
@@ -227,6 +227,9 @@ static int TestasyncCmd(ClientData dummy,
static int TestbytestringObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
static int TeststringbytesObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
static int TestcmdinfoCmd(ClientData dummy,
Tcl_Interp *interp, int argc, const char **argv);
static int TestcmdtokenCmd(ClientData dummy,
@@ -581,6 +584,7 @@ Tcltest_Init(
Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "teststringbytes", TeststringbytesObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
NULL, NULL);
Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd,
@@ -1985,9 +1989,12 @@ TestencodingObjCmd(
if (objc != 3) {
return TCL_ERROR;
}
encoding = Tcl_GetEncoding(NULL, Tcl_GetString(objv[2]));
Tcl_FreeEncoding(encoding);
Tcl_FreeEncoding(encoding);
if (TCL_OK != Tcl_GetEncodingFromObj(interp, objv[2], &encoding)) {
return TCL_ERROR;
}
Tcl_FreeEncoding(encoding); /* Free returned reference */
Tcl_FreeEncoding(encoding); /* Free to match CREATE */
TclFreeIntRep(objv[2]); /* Free the cached ref */
break;
}
return TCL_OK;
@@ -5043,6 +5050,40 @@ NoopObjCmd(
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TeststringbytesObjCmd --
* Returns bytearray value of the bytes in argument string rep
*
* Results:
* Returns the TCL_OK result code.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TeststringbytesObjCmd(
ClientData unused, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
int n;
const unsigned char *p;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "value");
return TCL_ERROR;
}
p = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(p, n));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
+2 -2
View File
@@ -8,10 +8,10 @@
# on it. If your code does rely on this package you
# may directly incorporate this code into your application.
package require Tcl 8.2
package require Tcl 8.2-
# When this version number changes, update the pkgIndex.tcl file
# and the install directory in the Makefiles.
package provide opt 0.4.6
package provide opt 0.4.7
namespace eval ::tcl {
+2 -2
View File
@@ -8,5 +8,5 @@
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.
if {![package vsatisfies [package provide Tcl] 8.2]} {return}
package ifneeded opt 0.4.6 [list source [file join $dir optparse.tcl]]
if {![package vsatisfies [package provide Tcl] 8.2-]} {return}
package ifneeded opt 0.4.7 [list source [file join $dir optparse.tcl]]
+2 -2
View File
@@ -8,5 +8,5 @@
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
package ifneeded tcltest 2.4.0 [list source [file join $dir tcltest.tcl]]
if {![package vsatisfies [package provide Tcl] 8.5-]} {return}
package ifneeded tcltest 2.4.1 [list source [file join $dir tcltest.tcl]]
+1 -1
View File
@@ -22,7 +22,7 @@ namespace eval tcltest {
# When the version number changes, be sure to update the pkgIndex.tcl file,
# and the install directory in the Makefiles. When the minor version
# changes (new feature) be sure to update the man page as well.
variable Version 2.4.0
variable Version 2.4.1
# Compatibility support for dumb variables defined in tcltest 1
# Do not use these. Call [package provide Tcl] and [info patchlevel]
+11 -17
View File
@@ -34,6 +34,8 @@ proc runtests {} {
# Some tests require the testencoding command
testConstraint testencoding [llength [info commands testencoding]]
testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint teststringbytes [llength [info commands teststringbytes]]
testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}]
testConstraint exec [llength [info commands exec]]
testConstraint testgetencpath [llength [info commands testgetencpath]]
@@ -308,26 +310,18 @@ test encoding-13.1 {LoadEscapeTable} {
viewable [set x [encoding convertto iso2022 ab\u4e4e\u68d9g]]
} [viewable "ab\x1b\$B8C\x1b\$\(DD%\x1b(Bg"]
test encoding-14.1 {BinaryProc} {
encoding convertto identity \x12\x34\x56\xff\x69
} "\x12\x34\x56\xc3\xbf\x69"
test encoding-15.1 {UtfToUtfProc} {
encoding convertto utf-8 \xa3
} "\xc2\xa3"
test encoding-15.2 {UtfToUtfProc null character output} {
set x \u0000
set y [encoding convertto utf-8 \u0000]
set y [encoding convertfrom identity $y]
binary scan $y H* z
list [string bytelength $x] [string bytelength $y] $z
} {2 1 00}
test encoding-15.3 {UtfToUtfProc null character input} {
set x [encoding convertfrom identity \x00]
set y [encoding convertfrom utf-8 $x]
binary scan [encoding convertto identity $y] H* z
list [string bytelength $x] [string bytelength $y] $z
} {1 2 c080}
test encoding-15.2 {UtfToUtfProc null character output} testbytestring {
binary scan [testbytestring [encoding convertto utf-8 \u0000]] H* z
set z
} 00
test encoding-15.3 {UtfToUtfProc null character input} teststringbytes {
set y [encoding convertfrom utf-8 [encoding convertto utf-8 \u0000]]
binary scan [teststringbytes $y] H* z
set z
} c080
test encoding-16.1 {UnicodeToUtfProc} {
set val [encoding convertfrom unicode NN]
+13 -3
View File
@@ -28,6 +28,11 @@ testConstraint testindexobj [expr {[info commands testindexobj] != {}}]
# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
proc representationpoke s {
set r [::tcl::unsupported::representation $s]
list [lindex $r 3] [string match {*, string representation "*"} $r]
}
test string-1.1 {error conditions} {
list [catch {string gorp a b} msg] $msg
} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
@@ -224,6 +229,13 @@ test string-4.15 {string first, ability to two-byte encoded utf-8 chars} {
set uchar \u057e ;# character with two-byte encoding in utf-8
string first % %#$uchar$uchar#$uchar$uchar#% 3
} 8
test string-4.16 {string first, normal string vs pure unicode string} {
set s hello
regexp ll $s m
# Representation checks are canaries
list [representationpoke $s] [representationpoke $m] \
[string first $m $s]
} {{string 1} {string 0} 2}
test string-5.1 {string index} {
list [catch {string index} msg] $msg
@@ -2042,9 +2054,7 @@ test string-29.15 {string cat, efficiency} -setup {
} -body {
tcl::unsupported::representation [string cat $e $f $e $f [list x]]
} -match glob -result {*no string representation}
# cleanup
rename MemStress {}
catch {rename foo {}}
+4 -1
View File
@@ -480,7 +480,6 @@ test stringObj-15.8 {Tcl_Append*ToObj: self appends} testobj {
teststringobj set 1 foo
teststringobj appendself2 1 3
} foo
if {[testConstraint testobj]} {
testobj freeallvars
@@ -489,3 +488,7 @@ if {[testConstraint testobj]} {
# cleanup
::tcltest::cleanupTests
return
# Local Variables:
# mode: tcl
# End:
+2 -2
View File
@@ -857,8 +857,8 @@ install-libraries: libraries
done;
@echo "Installing package msgcat 1.6.1 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.1.tm;
@echo "Installing package tcltest 2.4.0 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.0.tm;
@echo "Installing package tcltest 2.4.1 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm;
@echo "Installing package platform 1.0.14 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.14.tm;
+7 -3
View File
@@ -63,7 +63,7 @@ TclpDlopen(
* file. */
int flags)
{
HINSTANCE hInstance;
HINSTANCE hInstance = NULL;
const TCHAR *nativeName;
Tcl_LoadHandle handlePtr;
DWORD firstError;
@@ -75,7 +75,10 @@ TclpDlopen(
*/
nativeName = Tcl_FSGetNativePath(pathPtr);
hInstance = LoadLibraryEx(nativeName,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
if (nativeName != NULL) {
hInstance = LoadLibraryEx(nativeName, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
}
if (hInstance == NULL) {
/*
* Let the OS loader examine the binary search path for whatever
@@ -89,7 +92,8 @@ TclpDlopen(
* Remember the first error on load attempt to be used if the
* second load attempt below also fails.
*/
firstError = GetLastError();
firstError = (nativeName == NULL) ?
ERROR_MOD_NOT_FOUND : GetLastError();
nativeName = Tcl_WinUtfToTChar(Tcl_GetString(pathPtr), -1, &ds);
hInstance = LoadLibraryEx(nativeName, NULL,