Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | enlarge a few small buffers, which could overflow using Unicode characters > /UFFFF. Eliminate some end-of-line spacing |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | core-8-branch |
Files: | files | file ages | folders |
SHA3-256: |
41c373ad8f619e272b2b801495228f94 |
User & Date: | jan.nijtmans 2019-03-18 22:14:24.739 |
Context
2019-03-18
| ||
22:32 | Comment Comment Tcl_UniCharToUtf() better, what happens handling surrogates. Add type cast in tclUtf... check-in: b02df08680 user: jan.nijtmans tags: core-8-branch | |
22:17 | Merge 8.7 check-in: b9ad5fe740 user: jan.nijtmans tags: trunk | |
22:14 | enlarge a few small buffers, which could overflow using Unicode characters > /UFFFF. Eliminate some... check-in: 41c373ad8f user: jan.nijtmans tags: core-8-branch | |
2019-03-17
| ||
22:16 | For Tcl >= 8.7, always compile-in the extended Unicode tables, no matter the value of TCL_UTF_MAX. D... check-in: 82477e9d3a user: jan.nijtmans tags: core-8-branch | |
Changes
Changes to doc/timerate.n.
︙ | ︙ | |||
52 53 54 55 56 57 58 | .TP \fI-calibrate\fR . To measure very fast scripts as exact as posible the calibration process may be required. The \fI-calibrate\fR option is used to calibrate timerate, calculating the | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | .TP \fI-calibrate\fR . To measure very fast scripts as exact as posible the calibration process may be required. The \fI-calibrate\fR option is used to calibrate timerate, calculating the estimated overhead of the given script as the default overhead for future invocations of the \fBtimerate\fR command. If the \fItime\fR parameter is not specified, the calibrate procedure runs for up to 10 seconds. .TP \fI-overhead double\fR . The \fI-overhead\fR parameter supplies an estimate (in microseconds) of the measurement overhead of each iteration of the tested script. This quantity will be subtracted from the measured time prior to reporting results. |
︙ | ︙ |
Changes to generic/regc_locale.c.
︙ | ︙ | |||
829 830 831 832 833 834 835 | NOTE(REG_ULOCALE); /* * Search table. */ Tcl_DStringInit(&ds); | | | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 | NOTE(REG_ULOCALE); /* * Search table. */ Tcl_DStringInit(&ds); np = Tcl_UniCharToUtfDString(startp, len, &ds); for (cn=cnames; cn->name!=NULL; cn++) { if (strlen(cn->name)==len && strncmp(cn->name, np, len)==0) { break; /* NOTE BREAK OUT */ } } Tcl_DStringFree(&ds); if (cn->name != NULL) { |
︙ | ︙ |
Changes to generic/tclCmdMZ.c.
︙ | ︙ | |||
1441 1442 1443 1444 1445 1446 1447 | */ if (TclIsPureByteArray(objv[1])) { unsigned char uch = (unsigned char) ch; Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1)); } else { | | | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | */ if (TclIsPureByteArray(objv[1])) { unsigned char uch = (unsigned char) ch; Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1)); } else { char buf[4] = ""; length = Tcl_UniCharToUtf(ch, buf); if ((ch >= 0xD800) && (length < 3)) { length += Tcl_UniCharToUtf(-1, buf + length); } Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length)); } |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
5211 5212 5213 5214 5215 5216 5217 | } else if (TclIsPureByteArray(valuePtr)) { objResultPtr = Tcl_NewByteArrayObj( Tcl_GetByteArrayFromObj(valuePtr, NULL)+index, 1); } else if (valuePtr->bytes && length == valuePtr->length) { objResultPtr = Tcl_NewStringObj((const char *) valuePtr->bytes+index, 1); } else { | | | 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 | } else if (TclIsPureByteArray(valuePtr)) { objResultPtr = Tcl_NewByteArrayObj( Tcl_GetByteArrayFromObj(valuePtr, NULL)+index, 1); } else if (valuePtr->bytes && length == valuePtr->length) { objResultPtr = Tcl_NewStringObj((const char *) valuePtr->bytes+index, 1); } else { char buf[4] = ""; int ch = Tcl_GetUniChar(valuePtr, index); /* * This could be: Tcl_NewUnicodeObj((const Tcl_UniChar *)&ch, 1) * but creating the object as a string seems to be faster in * practical use. */ |
︙ | ︙ |
Changes to generic/tclIO.c.
︙ | ︙ | |||
6212 6213 6214 6215 6216 6217 6218 | { /* * There are chars leading the buffer before the eof char. * Adjust the dstLimit so we go back and read only those * and do not encounter the eof char this time. */ | | | 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 | { /* * There are chars leading the buffer before the eof char. * Adjust the dstLimit so we go back and read only those * and do not encounter the eof char this time. */ dstLimit = dstRead + (TCL_UTF_MAX - 1); statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; continue; } } |
︙ | ︙ | |||
6237 6238 6239 6240 6241 6242 6243 | /* * There are chars we can read before we hit the bare CR. Go * back with a smaller dstLimit so we get them in the next * pass, compute a matching srcRead, and don't end up back * here in this call. */ | | | 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 | /* * There are chars we can read before we hit the bare CR. Go * back with a smaller dstLimit so we get them in the next * pass, compute a matching srcRead, and don't end up back * here in this call. */ dstLimit = dstRead + (TCL_UTF_MAX - 1); statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; continue; } assert(dstWrote == 0); |
︙ | ︙ | |||
6330 6331 6332 6333 6334 6335 6336 | * TODO: This cannot happen anymore. * * We read more chars than allowed. Reset limits to prevent that * and try again. Don't forget the extra padding of TCL_UTF_MAX * bytes demanded by the Tcl_ExternalToUtf() call! */ | | | 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 | * TODO: This cannot happen anymore. * * We read more chars than allowed. Reset limits to prevent that * and try again. Don't forget the extra padding of TCL_UTF_MAX * bytes demanded by the Tcl_ExternalToUtf() call! */ dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - dst + (TCL_UTF_MAX - 1); statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; continue; } if (dstWrote == 0) { |
︙ | ︙ |
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
2037 2038 2039 2040 2041 2042 2043 | numChars = precision; Tcl_IncrRefCount(segment); allocSegment = 1; } } break; case 'c': { | | | 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 | numChars = precision; Tcl_IncrRefCount(segment); allocSegment = 1; } } break; case 'c': { char buf[4] = ""; int code, length; if (TclGetIntFromObj(interp, segment, &code) != TCL_OK) { goto error; } length = Tcl_UniCharToUtf(code, buf); if ((code >= 0xD800) && (length < 3)) { |
︙ | ︙ |
Changes to tests-perf/clock.perf.tcl.
1 2 3 4 | #!/usr/bin/tclsh # ------------------------------------------------------------------------ # # test-performance.tcl -- | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/usr/bin/tclsh # ------------------------------------------------------------------------ # # test-performance.tcl -- # # This file provides common performance tests for comparison of tcl-speed # degradation by switching between branches. # (currently for clock ensemble only) # # ------------------------------------------------------------------------ # # Copyright (c) 2014 Serg G. Brester (aka sebres) # # See the file "license.terms" for information on usage and redistribution # of this file. # array set in {-time 500} if {[info exists ::argv0] && [file tail $::argv0] eq [file tail [info script]]} { array set in $argv } ## common test performance framework: |
︙ | ︙ | |||
211 212 213 214 215 216 217 | {clock scan "5 years 18 months 385 days next 1 January" -base 0 -gmt 1} # FreeScan : relative date with ordinal month and relative weekday {clock scan "5 years 18 months 385 days next January Fri" -base 0 -gmt 1} # FreeScan : ordinal month {clock scan "next January" -base 0 -gmt 1} # FreeScan : relative week {clock scan "next Fri" -base 0 -gmt 1} | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | {clock scan "5 years 18 months 385 days next 1 January" -base 0 -gmt 1} # FreeScan : relative date with ordinal month and relative weekday {clock scan "5 years 18 months 385 days next January Fri" -base 0 -gmt 1} # FreeScan : ordinal month {clock scan "next January" -base 0 -gmt 1} # FreeScan : relative week {clock scan "next Fri" -base 0 -gmt 1} # FreeScan : relative weekday and week offset {clock scan "next January + 2 week" -base 0 -gmt 1} # FreeScan : time only with base {clock scan "19:18:30" -base 148863600 -gmt 1} # FreeScan : time only without base, gmt {clock scan "19:18:30" -gmt 1} # FreeScan : time only without base, system {clock scan "19:18:30"} |
︙ | ︙ | |||
296 297 298 299 300 301 302 | {clock format [clock scan "19:18:30" -base 148863600 -timezone EST] -timezone MST} {clock format [clock scan "19:18:30" -base 148863600 -timezone MST] -timezone EST} # Convert TZ: included in scan string & format {clock format [clock scan "19:18:30 EST" -base 148863600] -format "%H:%M:%S %z" -timezone MST} {clock format [clock scan "19:18:30 EST" -base 148863600] -format "%H:%M:%S %z" -timezone EST} # Format locale 1x: comparison values | | | 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | {clock format [clock scan "19:18:30" -base 148863600 -timezone EST] -timezone MST} {clock format [clock scan "19:18:30" -base 148863600 -timezone MST] -timezone EST} # Convert TZ: included in scan string & format {clock format [clock scan "19:18:30 EST" -base 148863600] -format "%H:%M:%S %z" -timezone MST} {clock format [clock scan "19:18:30 EST" -base 148863600] -format "%H:%M:%S %z" -timezone EST} # Format locale 1x: comparison values {clock format 0 -gmt 1 -locale en} {clock format 0 -gmt 1 -locale de} {clock format 0 -gmt 1 -locale fr} # Format locale 2x: without switching locale (en, en) {clock format 0 -gmt 1 -locale en; clock format 0 -gmt 1 -locale en} # Format locale 2x: with switching locale (en, de) {clock format 0 -gmt 1 -locale en; clock format 0 -gmt 1 -locale de} # Format locale 3x: without switching locale (en, en, en) |
︙ | ︙ | |||
336 337 338 339 340 341 342 | # FreeScan TZ 2x (+1 system-default): without switching TZ {clock scan "19:18:30 MST" -base 148863600; clock scan "19:18:30 MST" -base 148863600} {clock scan "19:18:30 EST" -base 148863600; clock scan "19:18:30 EST" -base 148863600} # FreeScan TZ 2x (+1 system-default): with switching TZ {clock scan "19:18:30 MST" -base 148863600; clock scan "19:18:30 EST" -base 148863600} # FreeScan TZ 2x (+1 gmt, +1 system-default) {clock scan "19:18:30 MST" -base 148863600 -gmt 1; clock scan "19:18:30 EST" -base 148863600} | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | # FreeScan TZ 2x (+1 system-default): without switching TZ {clock scan "19:18:30 MST" -base 148863600; clock scan "19:18:30 MST" -base 148863600} {clock scan "19:18:30 EST" -base 148863600; clock scan "19:18:30 EST" -base 148863600} # FreeScan TZ 2x (+1 system-default): with switching TZ {clock scan "19:18:30 MST" -base 148863600; clock scan "19:18:30 EST" -base 148863600} # FreeScan TZ 2x (+1 gmt, +1 system-default) {clock scan "19:18:30 MST" -base 148863600 -gmt 1; clock scan "19:18:30 EST" -base 148863600} # Scan TZ: comparison included in scan string vs. given {clock scan "2009-06-30T18:30:00 CEST" -format "%Y-%m-%dT%H:%M:%S %z"} {clock scan "2009-06-30T18:30:00 CET" -format "%Y-%m-%dT%H:%M:%S %z"} {clock scan "2009-06-30T18:30:00" -timezone CET -format "%Y-%m-%dT%H:%M:%S"} } } |
︙ | ︙ |
Changes to tests-perf/test-performance.tcl.
1 2 3 | # ------------------------------------------------------------------------ # # test-performance.tcl -- | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # ------------------------------------------------------------------------ # # test-performance.tcl -- # # This file provides common performance tests for comparison of tcl-speed # degradation or regression by switching between branches. # # To execute test case evaluate direct corresponding file "tests-perf\*.perf.tcl". # # ------------------------------------------------------------------------ # # Copyright (c) 2014 Serg G. Brester (aka sebres) # # See the file "license.terms" for information on usage and redistribution # of this file. # namespace eval ::tclTestPerf { # warm-up interpeter compiler env, calibrate timerate measurement functionality: # if no timerate here - import from unsupported: if {[namespace which -command timerate] eq {}} { namespace inscope ::tcl::unsupported {namespace export timerate} namespace import ::tcl::unsupported::timerate } # if not yet calibrated: if {[lindex [timerate {} 10] 6] >= (10-1)} { puts -nonewline "Calibration ... "; flush stdout puts "done: [lrange \ [timerate -calibrate {}] \ 0 1]" } proc {**STOP**} {args} { return -code error -level 4 "**STOP** in [info level [expr {[info level]-2}]] [join $args { }]" } proc _test_get_commands {lst} { regsub -all {(?:^|\n)[ \t]*(\#[^\n]*|\msetup\M[^\n]*|\mcleanup\M[^\n]*)(?=\n\s*(?:[\{\#]|setup|cleanup|$))} $lst "\n{\\1}" } proc _test_out_total {} { |
︙ | ︙ |
Changes to tests-perf/timer-event.perf.tcl.
1 2 3 4 5 | #!/usr/bin/tclsh # ------------------------------------------------------------------------ # # timer-event.perf.tcl -- | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/usr/bin/tclsh # ------------------------------------------------------------------------ # # timer-event.perf.tcl -- # # This file provides performance tests for comparison of tcl-speed # of timer events (event-driven tcl-handling). # # ------------------------------------------------------------------------ # # Copyright (c) 2014 Serg G. Brester (aka sebres) # # See the file "license.terms" for information on usage and redistribution # of this file. # if {![namespace exists ::tclTestPerf]} { source [file join [file dirname [info script]] test-performance.tcl] } |
︙ | ︙ | |||
36 37 38 39 40 41 42 | puts "*** up to $howmuch events ***" # single iteration by update, so using -no-result (measure only): _test_run -no-result $reptime [string map [list \{*\}\$reptime $reptime \$howmuch $howmuch \\# \#] { # generate up to $howmuch idle-events: {after idle {set foo bar}} # update / after idle: {update; if {![llength [after info]]} break} | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | puts "*** up to $howmuch events ***" # single iteration by update, so using -no-result (measure only): _test_run -no-result $reptime [string map [list \{*\}\$reptime $reptime \$howmuch $howmuch \\# \#] { # generate up to $howmuch idle-events: {after idle {set foo bar}} # update / after idle: {update; if {![llength [after info]]} break} # generate up to $howmuch idle-events: {after idle {set foo bar}} # update idletasks / after idle: {update idletasks; if {![llength [after info]]} break} # generate up to $howmuch immediate events: {after 0 {set foo bar}} # update / after 0: {update; if {![llength [after info]]} break} # generate up to $howmuch 1-ms events: {after 1 {set foo bar}} setup {after 1} # update / after 1: {update; if {![llength [after info]]} break} # generate up to $howmuch immediate events (+ 1 event of the second generation): |
︙ | ︙ | |||
79 80 81 82 83 84 85 | {after cancel $ev([incr i]); if {$i >= $le} break} cleanup {update; unset -nocomplain ev} # cancel backwards "after 0" / $howmuch timer-events in queue: setup {set i 0; timerate {set ev([incr i]) [after 0 {set foo bar}]} {*}$reptime} setup {set le $i; incr i; list $le .. 1; # cancel up to $howmuch events} {after cancel $ev([incr i -1]); if {$i <= 1} break} cleanup {update; unset -nocomplain ev} | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | {after cancel $ev([incr i]); if {$i >= $le} break} cleanup {update; unset -nocomplain ev} # cancel backwards "after 0" / $howmuch timer-events in queue: setup {set i 0; timerate {set ev([incr i]) [after 0 {set foo bar}]} {*}$reptime} setup {set le $i; incr i; list $le .. 1; # cancel up to $howmuch events} {after cancel $ev([incr i -1]); if {$i <= 1} break} cleanup {update; unset -nocomplain ev} # end $howmuch events. cleanup {if [llength [after info]] {error "unexpected: [llength [after info]] events are still there."}} }] } proc test-access {{reptime {1000 5000}}} { set howmuch [lindex $reptime 1] |
︙ | ︙ | |||
145 146 147 148 149 150 151 | proc test-long {{reptime 1000}} { _test_run $reptime { # in-between important event by amount of idle events: {time {after idle {after 30}} 10; after 1 {set important 1}; vwait important;} cleanup {foreach i [after info] {after cancel $i}} # in-between important event (of new generation) by amount of idle events: | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | proc test-long {{reptime 1000}} { _test_run $reptime { # in-between important event by amount of idle events: {time {after idle {after 30}} 10; after 1 {set important 1}; vwait important;} cleanup {foreach i [after info] {after cancel $i}} # in-between important event (of new generation) by amount of idle events: {time {after idle {after 30}} 10; after 1 {after 0 {set important 1}}; vwait important;} cleanup {foreach i [after info] {after cancel $i}} } } proc test {{reptime 1000}} { test-exec $reptime foreach howmuch {5000 50000} { |
︙ | ︙ |
Changes to tests/util.test.
︙ | ︙ | |||
4126 4127 4128 4129 4130 4131 4132 | } {65536 65536} test util-18.12 {Tcl_ObjPrintf} {testprint} { testprint "%I64d %Id" 65537 } {65537 65537} if {[catch {set ::tcl_precision $saved_precision}]} { | | | 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 | } {65536 65536} test util-18.12 {Tcl_ObjPrintf} {testprint} { testprint "%I64d %Id" 65537 } {65537 65537} if {[catch {set ::tcl_precision $saved_precision}]} { unset ::tcl_precision } # cleanup ::tcltest::cleanupTests return # Local Variables: |
︙ | ︙ |