From 20188493aff274e9b29b7349c875d52a86954ab1 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 14 Jul 2023 14:18:18 +0000 Subject: dup test name --- tests/lseq.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lseq.test b/tests/lseq.test index a149908..6082856 100644 --- a/tests/lseq.test +++ b/tests/lseq.test @@ -470,7 +470,7 @@ test lseq-3.32 {lsearch nested lists of lseq} arithSeriesShimmer { # lsearch - # -- should not shimmer lseq list # -- should not leak lseq elements -test lseq-3.32 {lsearch nested lists of lseq} -constraints arithSeriesShimmer -body { +test lseq-3.33 {lsearch nested lists of lseq} -constraints arithSeriesShimmer -body { set srchlist {} for {set i 5} {$i < 25} {incr i} { lappend srchlist [lseq $i count 7 by 3] -- cgit v0.12 From 88dd8c191144dcad7cbdf74bf67739e19adb4e52 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 14 Jul 2023 15:36:05 +0000 Subject: Move channel close commands to -cleanup so that when the (expected) error occurs in [fcopy] we do not leave open channels lurking to interfere with later tests. --- tests/io.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/io.test b/tests/io.test index 0fed043..d79cfb8 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7525,10 +7525,11 @@ test io-52.10 {TclCopyChannel & encodings} -constraints fcopy -body { fconfigure $out -translation binary fcopy $in $out - close $in - close $out file size $path(utf8-fcopy.txt) +} -cleanup { + close $in + close $out } -returnCodes 1 -match glob -result {error writing "*":\ invalid or incomplete multibyte or wide character} test io-52.11 {TclCopyChannel & encodings} -setup { -- cgit v0.12 From e10b5cb8b9d540f5ea378d7c705cd290d6c8156e Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 14 Jul 2023 15:59:12 +0000 Subject: Same fix in chanio.test --- tests/chanio.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/chanio.test b/tests/chanio.test index 5a793d6..e7a125b 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -6877,9 +6877,10 @@ test chan-io-52.10 {TclCopyChannel & encodings} -constraints {fcopy} -body { # -translation binary is also -encoding binary chan configure $out -translation binary chan copy $in $out + file size $path(utf8-fcopy.txt) +} -cleanup { chan close $in chan close $out - file size $path(utf8-fcopy.txt) } -returnCodes 1 -match glob -result {error writing "*":\ invalid or incomplete multibyte or wide character} test chan-io-52.11 {TclCopyChannel & encodings} -setup { -- cgit v0.12 From 56ca2a64d7665bc088790e6cfa134b39a7d0034f Mon Sep 17 00:00:00 2001 From: griffin Date: Sun, 16 Jul 2023 00:24:54 +0000 Subject: Fix bug [c25d2cd3e6], as well as memory leaks in lsearch and concat. Add cleanup to some tests. Fix bug and leak in tclTestABSList.c Correct comment in tclArithSeries.c --- generic/tclArithSeries.c | 3 ++- generic/tclCmdIL.c | 24 ++++++++++++++++++++---- generic/tclTestABSList.c | 15 ++++++++++++--- generic/tclUtil.c | 2 ++ tests/abstractlist.test | 11 +++++++---- tests/lseq.test | 8 +++++--- 6 files changed, 48 insertions(+), 15 deletions(-) diff --git a/generic/tclArithSeries.c b/generic/tclArithSeries.c index caf701b..166c1c9 100755 --- a/generic/tclArithSeries.c +++ b/generic/tclArithSeries.c @@ -588,11 +588,12 @@ TclNewArithSeriesObj( * * Results: * - * TCL_OK on success, TCL_ERROR on index out of range. + * TCL_OK on success. * * Side Effects: * * On success, the integer pointed by *element is modified. + * An empty string ("") is assigned if index is out-of-bounds. * *---------------------------------------------------------------------- */ diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index d52d6d5..663d962 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2635,7 +2635,7 @@ Tcl_LpopObjCmd( Tcl_Size listLen; int copied = 0, result; Tcl_Obj *elemPtr, *stored; - Tcl_Obj *listPtr, **elemPtrs; + Tcl_Obj *listPtr; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "listvar ?index?"); @@ -2647,7 +2647,7 @@ Tcl_LpopObjCmd( return TCL_ERROR; } - result = TclListObjGetElementsM(interp, listPtr, &listLen, &elemPtrs); + result = TclListObjLengthM(interp, listPtr, &listLen); if (result != TCL_OK) { return result; } @@ -2666,7 +2666,12 @@ Tcl_LpopObjCmd( "OUTOFRANGE", NULL); return TCL_ERROR; } - elemPtr = elemPtrs[listLen - 1]; + + result = Tcl_ListObjIndex(interp, listPtr, (listLen-1), &elemPtr); + if (result != TCL_OK) { + return result; + } + Tcl_IncrRefCount(elemPtr); } else { elemPtr = TclLindexFlat(interp, listPtr, objc-2, objv+2); @@ -2699,7 +2704,13 @@ Tcl_LpopObjCmd( return result; } } else { - Tcl_Obj *newListPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL); + Tcl_Obj *newListPtr; + Tcl_ObjTypeSetElement *proc = TclObjTypeHasProc(listPtr, setElementProc); + if (proc) { + newListPtr = proc(interp, listPtr, objc-2, objv+2, NULL); + } else { + newListPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL); + } if (newListPtr == NULL) { if (copied) { Tcl_DecrRefCount(listPtr); @@ -3946,6 +3957,7 @@ Tcl_LsearchObjCmd( */ if (returnSubindices && (sortInfo.indexc != 0)) { + Tcl_BumpObj(itemPtr); itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo); Tcl_ListObjAppendElement(interp, listPtr, itemPtr); @@ -3953,6 +3965,7 @@ Tcl_LsearchObjCmd( Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0, groupSize, &listv[i]); } else { + Tcl_BumpObj(itemPtr); itemPtr = listv[i]; Tcl_ListObjAppendElement(interp, listPtr, itemPtr); } @@ -4023,6 +4036,9 @@ Tcl_LsearchObjCmd( */ done: + /* potential lingering abstract list element */ + Tcl_BumpObj(itemPtr); + if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); } diff --git a/generic/tclTestABSList.c b/generic/tclTestABSList.c index f9f2fda..7ac6308 100644 --- a/generic/tclTestABSList.c +++ b/generic/tclTestABSList.c @@ -361,7 +361,6 @@ my_LStringObjSetElem( { LString *lstringRepPtr = (LString*)lstringObj->internalRep.twoPtrValue.ptr1; Tcl_Size index; - const char *newvalue; int status; Tcl_Obj *returnObj; @@ -385,8 +384,17 @@ my_LStringObjSetElem( lstringRepPtr->string = (char*)Tcl_Realloc(lstringRepPtr->string, lstringRepPtr->strlen+1); } - newvalue = Tcl_GetString(valueObj); - lstringRepPtr->string[index] = newvalue[0]; + if (valueObj) { + const char newvalue = Tcl_GetString(valueObj)[0]; + lstringRepPtr->string[index] = newvalue; + } else if (index < lstringRepPtr->strlen) { + /* Remove the char by sliding the tail of the string down */ + char *sptr = &lstringRepPtr->string[index]; + /* This is an overlapping copy, by definition */ + lstringRepPtr->strlen--; + memmove(sptr, (sptr+1), (lstringRepPtr->strlen - index)); + } + // else do nothing Tcl_InvalidateStringRep(returnObj); @@ -684,6 +692,7 @@ my_NewLStringObj( i++; } if (i != objc-1) { + Tcl_Free((char*)lstringRepPtr); Tcl_WrongNumArgs(interp, 0, objv, "lstring string"); return NULL; } diff --git a/generic/tclUtil.c b/generic/tclUtil.c index ac292db..1fdcda3 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -2005,8 +2005,10 @@ Tcl_ConcatObj( != Tcl_ListObjAppendList(NULL, resPtr, objPtr)) { /* Abandon ship! */ Tcl_DecrRefCount(resPtr); + Tcl_BumpObj(elemPtr); // could be an abstract list element goto slow; } + Tcl_BumpObj(elemPtr); // could be an an abstract list element } else { resPtr = TclDuplicatePureObj( NULL, objPtr, &tclListType); diff --git a/tests/abstractlist.test b/tests/abstractlist.test index 4335daa..5c92048 100644 --- a/tests/abstractlist.test +++ b/tests/abstractlist.test @@ -41,13 +41,15 @@ test abstractlist-1.1 {error cases} -body { } -returnCodes 1 \ -result {wrong # args: should be "lstring string"} -test abstractlist-2.0 {no shimmer llength} { +test abstractlist-2.0 {no shimmer llength} -body { set l [lstring $str] set l-isa [testobj objtype $l] set len [llength $l] set l-isa2 [testobj objtype $l] list $l ${l-isa} ${len} ${l-isa2} -} {{M y { } n a m e { } i s { } I n i g o { } M o n t o y a . { } Y o u { } k i l l e d { } m y { } f a t h e r . { } P r e p a r e { } t o { } d i e !} lstring 63 lstring} +} -cleanup { +unset l +} -result {{M y { } n a m e { } i s { } I n i g o { } M o n t o y a . { } Y o u { } k i l l e d { } m y { } f a t h e r . { } P r e p a r e { } t o { } d i e !} lstring 63 lstring} test abstractlist-2.1 {no shimmer lindex} { set l [lstring $str] @@ -501,14 +503,15 @@ test abstractlist-$not-4.11e {error case lset multiple indicies} \ -result {Multiple indicies not supported by lstring.} # lrepeat -test abstractlist-$not-4.12 {shimmer lrepeat} { +test abstractlist-$not-4.12 {shimmer lrepeat} -body { set l [lstring {*}$options Inconceivable] set l-isa [testobj objtype $l] set m [lrepeat 3 $l] set m-isa [testobj objtype $m] set n [lindex $m 1] list $l ${l-isa} $m ${m-isa} [testobj objtype $n] [value-cmp l n] -} {{I n c o n c e i v a b l e} lstring {{I n c o n c e i v a b l e} {I n c o n c e i v a b l e} {I n c o n c e i v a b l e}} list lstring 0} +} -cleanup { +} -result {{I n c o n c e i v a b l e} lstring {{I n c o n c e i v a b l e} {I n c o n c e i v a b l e} {I n c o n c e i v a b l e}} list lstring 0} # Disable constraint testConstraint [format "%sShimmer" [string totitle $not]] 1 diff --git a/tests/lseq.test b/tests/lseq.test index 6082856..4544675 100644 --- a/tests/lseq.test +++ b/tests/lseq.test @@ -455,7 +455,7 @@ test lseq-3.31 {lreverse inplace with doubles} {arithSeriesDouble} { # lsearch - # -- should not shimmer lseq list # -- should not leak lseq elements -test lseq-3.32 {lsearch nested lists of lseq} arithSeriesShimmer { +test lseq-3.32 {lsearch nested lists of lseq} -constraints arithSeriesShimmer -body { set srchlist {} for {set i 5} {$i < 25} {incr i} { lappend srchlist [lseq $i count 7 by 3] @@ -464,7 +464,9 @@ test lseq-3.32 {lsearch nested lists of lseq} arithSeriesShimmer { set b [lmap i $a {lindex [tcl::unsupported::representation $i] 3}] list [lindex [tcl::unsupported::representation $a] 3] $a $b \ [lindex [tcl::unsupported::representation [lindex $srchlist 15]] 3] -} {list {{20 23 26 29 32 35 38}} arithseries arithseries} +} -cleanup { + unset a b srchlist i +} -result {list {{20 23 26 29 32 35 38}} arithseries arithseries} # lsearch - @@ -725,7 +727,7 @@ test lseq-bug-54329e39c7 {does not cause memory bloat} -constraints { set premem [memusage] p $l set postmem [memusage] - expr {($postmem - $premem) < 10} + expr {[string match *purify* [tcl::build-info]] || ($postmem - $premem < 10) ? 1 : ($postmem - $premem)} } -result 1 # cleanup -- cgit v0.12 From ccf857a3db566e41ba8167be6442441cdf92a9e3 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Sun, 16 Jul 2023 06:15:36 +0000 Subject: Bug [a366c6efee] --- generic/tclInt.h | 4 ++-- generic/tclListObj.c | 15 ++++++++++----- tests/lreplace.test | 9 +++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index ffceb5c..61ad487 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2606,8 +2606,8 @@ typedef struct ListRep { * (1) No string representation exists which means it will obviously have * to be generated from the list representation when needed * (2) The ListStore flags is marked canonical. This is done at the time - * the string representation is generated from the list IF the list - * representation does not have a span (see comments in UpdateStringOfList). + * the string representation is generated from the list under certain + * conditions (see comments in UpdateStringOfList). * (3) The list representation does not have a span component. This is * because list Tcl_Obj's with spans are always created from existing lists * and never from strings (see SetListFromAny) and thus their string diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 7a8f9ab..2f433c5 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -3448,16 +3448,21 @@ UpdateStringOfList( * Mark the list as being canonical; although it will now have a string * rep, it is one we derived through proper "canonical" quoting and so * it's known to be free from nasties relating to [concat] and [eval]. - * However, we only do this if this is not a spanned list. Marking the - * storage canonical for a spanned list make ALL lists using the storage - * canonical which is not right. (Consider a list generated from a + * However, we only do this if + * + * (a) the store is not shared as a shared store may be referenced by + * multiple lists with different string reps. (see [a366c6efee]), AND + * + * (b) list does not have a span. Consider a list generated from a * string and then this function called for a spanned list generated - * from it). On the other hand, a spanned list is always canonical + * from the original list. We cannot mark the list store as canonical as + * that would also make the originating list canonical, which it may not + * be. On the other hand, the spanned list itself is always canonical * (never generated from a string) so it does not have to be explicitly * marked as such. The ListObjIsCanonical macro takes this into account. * See the comments there. */ - if (listRep.spanPtr == NULL) { + if (listRep.storePtr->refCount < 2 && listRep.spanPtr == NULL) { LIST_ASSERT(listRep.storePtr->firstUsed == 0);/* Invariant */ listRep.storePtr->flags |= LISTSTORE_CANONICAL; } diff --git a/tests/lreplace.test b/tests/lreplace.test index 009170e..55b3ee3 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -505,6 +505,15 @@ test ledit-5.2 {compiled lreplace: Bug 47ac84309b} { }} {a b c} } {a b A c} +test ledit-bug-a366c6efee {Bug [a366c6efee]} -body { + apply {{} { + set l { } + string length [ledit l 1 1]; # Force string generation + set result foo + append result " " bar + }} +} -result "foo bar" + # Testing for compiled behaviour. Far too many variations to check with # spelt-out tests. Note that this *just* checks whether the compiled version # and the interpreted version are the same, not whether the interpreted -- cgit v0.12 From fc0c89372c3880ec1cd9e520d031e6b72436585e Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Mon, 17 Jul 2023 06:19:41 +0000 Subject: Fix missing TIP 548 function docs. Some copy editing of doc prototypes for clarity (sez he). --- doc/DString.3 | 2 +- doc/Utf.3 | 106 +++++++++++++++++++++++++++++++--------------------------- 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/doc/DString.3 b/doc/DString.3 index 66323a7..33dd297 100644 --- a/doc/DString.3 +++ b/doc/DString.3 @@ -9,7 +9,7 @@ .so man.macros .BS .SH NAME -Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringTrunc, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings +Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringTrunc, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult, Tcl_DStringToObj \- manipulate dynamic strings .SH SYNOPSIS .nf \fB#include \fR diff --git a/doc/Utf.3 b/doc/Utf.3 index b0c7f64..069a612 100644 --- a/doc/Utf.3 +++ b/doc/Utf.3 @@ -8,7 +8,7 @@ .so man.macros .BS .SH NAME -Tcl_UniChar, Tcl_UniCharToUtf, Tcl_UtfToUniChar, Tcl_UtfToChar16, Tcl_UtfToWChar, Tcl_UniCharToUtfDString, Tcl_UtfToUniCharDString, Tcl_Char16ToUtfDString, Tcl_UtfToWCharDString, Tcl_UtfToChar16DString, Tcl_WCharLen, Tcl_Char16Len, Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UniCharNcasecmp, Tcl_UniCharCaseMatch, Tcl_UtfNcmp, Tcl_UtfNcasecmp, Tcl_UtfCharComplete, Tcl_NumUtfChars, Tcl_UtfFindFirst, Tcl_UtfFindLast, Tcl_UtfNext, Tcl_UtfPrev, Tcl_UniCharAtIndex, Tcl_UtfAtIndex, Tcl_UtfBackslash \- routines for manipulating UTF-8 strings +Tcl_UniChar, Tcl_UniCharToUtf, Tcl_UtfToUniChar, Tcl_UtfToChar16, Tcl_UtfToWChar, Tcl_UniCharToUtfDString, Tcl_UtfToUniCharDString, Tcl_Char16ToUtfDString, Tcl_UtfToWCharDString, Tcl_UtfToChar16DString, Tcl_WCharToUtfDString, Tcl_WCharLen, Tcl_Char16Len, Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UniCharNcasecmp, Tcl_UniCharCaseMatch, Tcl_UtfNcmp, Tcl_UtfNcasecmp, Tcl_UtfCharComplete, Tcl_NumUtfChars, Tcl_UtfFindFirst, Tcl_UtfFindLast, Tcl_UtfNext, Tcl_UtfPrev, Tcl_UniCharAtIndex, Tcl_UtfAtIndex, Tcl_UtfBackslash \- routines for manipulating UTF-8 strings .SH SYNOPSIS .nf \fB#include \fR @@ -28,28 +28,28 @@ int \fBTcl_UtfToWChar\fR(\fIsrc, wPtr\fR) .sp char * -\fBTcl_UniCharToUtfDString\fR(\fIuniStr, uniLength, dsPtr\fR) +\fBTcl_UniCharToUtfDString\fR(\fIuniStr, numUniChars, dsPtr\fR) .sp char * -\fBTcl_Char16ToUtfDString\fR(\fIuStr, uniLength, dsPtr\fR) +\fBTcl_Char16ToUtfDString\fR(\fIutf16, numUtf16, dsPtr\fR) .sp char * -\fBTcl_WCharToUtfDString\fR(\fIwStr, uniLength, dsPtr\fR) +\fBTcl_WCharToUtfDString\fR(\fIwcharStr, numWChars, dsPtr\fR) .sp Tcl_UniChar * -\fBTcl_UtfToUniCharDString\fR(\fIsrc, length, dsPtr\fR) +\fBTcl_UtfToUniCharDString\fR(\fIsrc, numBytes, dsPtr\fR) .sp unsigned short * -\fBTcl_UtfToChar16DString\fR(\fIsrc, length, dsPtr\fR) +\fBTcl_UtfToChar16DString\fR(\fIsrc, numBytes, dsPtr\fR) .sp wchar_t * -\fBTcl_UtfToWCharDString\fR(\fIsrc, length, dsPtr\fR) +\fBTcl_UtfToWCharDString\fR(\fIsrc, numBytes, dsPtr\fR) .sp int -\fBTcl_Char16Len\fR(\fIuniStr\fR) +\fBTcl_Char16Len\fR(\fIutf16\fR) .sp int -\fBTcl_WCharLen\fR(\fIuniStr\fR) +\fBTcl_WCharLen\fR(\fIwcharStr\fR) .sp int \fBTcl_UniCharLen\fR(\fIuniStr\fR) @@ -70,10 +70,10 @@ int \fBTcl_UtfNcasecmp\fR(\fIcs, ct, numChars\fR) .sp int -\fBTcl_UtfCharComplete\fR(\fIsrc, length\fR) +\fBTcl_UtfCharComplete\fR(\fIsrc, numBytes\fR) .sp int -\fBTcl_NumUtfChars\fR(\fIsrc, length\fR) +\fBTcl_NumUtfChars\fR(\fIsrc, numBytes\fR) .sp const char * \fBTcl_UtfFindFirst\fR(\fIsrc, ch\fR) @@ -115,28 +115,32 @@ Pointer to a UTF-8 string. .AP "const char" *ct in Pointer to a UTF-8 string. .AP "const Tcl_UniChar" *uniStr in -A null-terminated Unicode string. +A sequence of \fBTcl_UniChar\fR units with null-termination optional +depending on function. .AP "const Tcl_UniChar" *ucs in -A null-terminated Unicode string. +A null-terminated sequence of \fBTcl_UniChar\fR. .AP "const Tcl_UniChar" *uct in -A null-terminated Unicode string. +A null-terminated sequence of \fBTcl_UniChar\fR. .AP "const Tcl_UniChar" *uniPattern in -A null-terminated Unicode string. -.AP "const unsigned short" *uStr in -A null-terminated UTF-16 string. -.AP "const wchar_t" *wStr in -A null-terminated wchar_t string. -.AP "const unsigned short" *utf16s in -A null-terminated utf-16 string. -.AP "const unsigned short" *utf16t in -A null-terminated utf-16 string. -.AP "const unsigned short" *utf16Pattern in -A null-terminated utf-16 string. -.AP int length in -The length of the UTF-8 string in bytes (not UTF-8 characters). If -negative, all bytes up to the first null byte are used. -.AP int uniLength in -The length of the Unicode string in characters. +A null-terminated sequence of \fBTcl_UniChar\fR. +.AP "const unsigned short" *utf16 in +A sequence of UTF-16 units with null-termination optional +depending on function. +.AP "const wchar_t" *wcharStr in +A sequence of \fBwchar_t\fR units with null-termination optional +depending on function. +.AP int numBytes in +The length of the UTF-8 input in bytes. If +negative, the length includes all bytes until the first null byte. +.AP int numUtf16 in +The length of the input in UTF-16 units. +If negative, the length includes all bytes until the first null. +.AP int numUniChars in +The length of the input in Tcl_UniChar units. +If negative, the length includes all bytes until the first null. +.AP int numWChars in +The length of the input in wchar_t units. +If negative, the length includes all bytes until the first null. .AP "Tcl_DString" *dsPtr in/out A pointer to a previously initialized \fBTcl_DString\fR. .AP "unsigned long" numChars in @@ -187,30 +191,32 @@ not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x00A0 and 0x00FF and return 1. .PP -\fBTcl_UniCharToUtfDString\fR converts the given Unicode string -to UTF-8, storing the result in a previously initialized \fBTcl_DString\fR. -The return value is a pointer to the UTF-8 representation of the -Unicode string. Storage for the return value is appended to the -end of the \fBTcl_DString\fR. +\fBTcl_UniCharToUtfDString\fR converts the input in the form of a +sequence of \fBTcl_UniChar\fR code points to UTF-8, appending the result to the +previously initialized output \fBTcl_DString\fR. The return value is a pointer +to the UTF-8 representation of the \fBappended\fR string. .PP -\fBTcl_UtfToUniCharDString\fR converts the given UTF-8 string to Unicode, -storing the result in the previously initialized \fBTcl_DString\fR. -In the argument \fIlength\fR, you may either specify the length of -the given UTF-8 string in bytes or -.QW \-1 , -in which case \fBTcl_UtfToUniCharDString\fR uses \fBstrlen\fR to -calculate the length. The return value is a pointer to the Unicode -representation of the UTF-8 string. Storage for the return value -is appended to the end of the \fBTcl_DString\fR. The Unicode string -is terminated with a Unicode null character. +\fBTcl_UtfToUniCharDString\fR converts the input in the form of +a UTF-8 encoded string to a \fBTcl_UniChar\fR sequence +appending the result in the previously initialized \fBTcl_DString\fR. +The return value is a pointer to the appended result which is also +terminated with a \fBTcl_UniChar\fR null character. +.PP +\fBTcl_WCharToUtfDString\fR and \fBTcl_UtfToWCharDString\fR are similar to +\fBTcl_UniCharToUtfDString\fR and \fBTcl_UtfToUniCharDString\fR except they +operate on sequences of \fBwchar_t\fR instead of \fBTcl_UniChar\fR. +.PP +\fBTcl_Char16ToUtfDString\fR and \fBTcl_UtfToChar16DString\fR are similar to +\fBTcl_UniCharToUtfDString\fR and \fBTcl_UtfToUniCharDString\fR except they +operate on sequences of \fBUTF-16\fR units instead of \fBTcl_UniChar\fR. .PP \fBTcl_Char16Len\fR corresponds to \fBstrlen\fR for UTF-16 -characters. It accepts a null-terminated Unicode string and returns -the number of Unicode characters (not bytes) in that string. +characters. It accepts a null-terminated UTF-16 sequence and returns +the number of UTF-16 units until the null. .PP \fBTcl_WCharLen\fR corresponds to \fBstrlen\fR for wchar_t -characters. It accepts a null-terminated Unicode string and returns -the number of Unicode characters (not bytes) in that string. +characters. It accepts a null-terminated \fBwchar_t\fR sequence and returns +the number of \fBwchar_t\fR units until the null. .PP \fBTcl_UniCharLen\fR corresponds to \fBstrlen\fR for Unicode characters. It accepts a null-terminated Unicode string and returns @@ -246,7 +252,7 @@ differences in case when comparing upper, lower or title case characters. .PP \fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR -of \fIlength\fR bytes is long enough to be decoded by +of \fInumBytes\fR bytes is long enough to be decoded by \fBTcl_UtfToUniChar\fR/\fBTcl_UtfNext\fR, or 0 otherwise. This function does not guarantee that the UTF-8 string is properly formed. This routine is used by procedures that are operating on a byte at a time and need to -- cgit v0.12 From 0a3cfc79026050f3740f75dc472a4cd5ff284b57 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Mon, 17 Jul 2023 16:36:51 +0000 Subject: Fix: tommath.lib needs to be installed to permit extensions to link when using the tommath C API --- win/makefile.vc | 1 + 1 file changed, 1 insertion(+) diff --git a/win/makefile.vc b/win/makefile.vc index b1a8b6a..625337d 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -971,6 +971,7 @@ install-binaries: @$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\" @$(CPY) "$(OUT_DIR)\zlib1.dll" "$(BIN_INSTALL_DIR)\" @$(CPY) "$(OUT_DIR)\libtommath.dll" "$(BIN_INSTALL_DIR)\" + @$(CPY) "$(OUT_DIR)\tommath.lib" "$(LIB_INSTALL_DIR)\" !if exist($(TCLSH)) @echo Installing $(TCLSHNAME) @$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\" -- cgit v0.12