2017-10-05

Sugar: Lisp-like macro system for Tcl

Sugar


會注意到是因為 Debian/Ubuntu 有這個套件 (套件名叫 tcl-sugar),然後就去 Tcler's wiki 看是不是有資料。沒想到可以用 pure Tcl 實作了一個類似 Lisp 的 macro system。

2017-10-02

Magicsplat Tcl/Tk for Windows, Visual Studio 2017 and Jsonnet

Google Jsonnet 在 v0.9.5 加入一個 Visual Studio 2017 的專案檔,這表示已經成功的移植到 Windows(使用 Visual Studio 2017 編譯)。

我按照以前寫的 extension,改寫之前 win 目錄下的 makefile.vc 等檔案,試看看能不能使用 Visual Studio 2017 來編譯 tcljsonnet。結果出現一個很奇怪的狀況,在最後連結的時候,Visual Studio 2017 會一直抱怨 BAWT-Tcl (使用 MinGW-W64 編譯) 所使用的是舊的格式,我需要重新編譯才能夠正確連結。

經過思考,換成 Magicsplat Tcl/Tk for Windows 來測試(注:我安裝 在 c:\Tcl,而 Magicsplat  使用 Visual Studio 編譯),然後就很順利的編譯了,而且 tcljsonnet 也可以很正確的使用,不會有 C++ exception 模式不相容的問題。

但是這樣也代表,微軟 Windows 平台出現了格式的相容性問題,但是除非是一個環境中會使用 MinGW-W64 與 Visual Studio 2017 的人才會很快就遇到這個問題。

但是如果將 MinGW-W64 與 Visual Studio 2017 因為 binary 格式不相容而視為二個平台,就會出現很大的維護問題,至少對我而言會很吃力。而目前看起來,並沒有一個好的解法,還蠻麻煩的。 更新:我把使用 MinGW-64 編譯的 extension(例如我自己寫的 tcl-lmdb)放到 Magicsplat Tcl/Tk for Windows 的 lib 目錄下,發現可以使用,所以看起來問題沒那麼大。目前我還是以使用 Mingw-W64 為主,只有需要 Visual Studio 的時候才使用 Visual Studio。

2017-09-19

BAWT-Tcl Windows installer

BAWT 提供了 8.6.x 系列的 Windows 安裝程式,並且安裝了一些常用的擴充套件以及 BAWT 作者自己的作品。


如果你使用 MSYS2/MinGW-w64 的組合,然後 Tcl 使用 BAWT-Tcl 安裝 (假設是安裝在 c:/Tcl),在編譯自己的套件時有可能會出現一些小亂流。

這是因為 tclConfig.shtkConfig.sh 在編譯的機器所指向的目錄和目標機器並不相同。也就是 TCL_PREFIX, TCL_EXEC_PREFIX, TCL_BUILD_LIB_SPEC, TCL_LIB_SPEC 等目錄所記錄的資料不是正確的。但是要修改很簡單,只要指向正確的目銾就可以解決問題,下面是一個例子:

# Top-level directory in which Tcl's platform-independent files are
# installed.
TCL_PREFIX='/c/Tcl'


假設要改善的話,應該只能夠從安裝程式著手,也就是使用者設定好安裝目錄以後,按照安裝目錄的位置進行改寫。取巧的做法是編譯機器和目標機器的環境很像,然後目標機器的預設目錄符合預設的設定(還是有可能出問題,因為使用者有可能不是安裝在預設位置,但是機率大幅度降低)。

2017-09-17

regex_rez: Tcl bindings for RE2

regex_rez


可是,我目前只需要基本功能,所以只實作最簡單的 fullmatch, partialmatch, replace 和 globalrelpace。


維基百科:
RE2 (software)


第一個測試程式使用內建的正規表示式:
puts -nonewline "Please input a number: "
flush stdout
gets stdin number
if {$number <= 0 || $number >= 10} {
   puts "The range is 1 - 9."
   exit
}

set max [expr pow(10, $number)]
set result [list]

puts "\nNow get the result:"
puts "==========="
puts "Start"
puts "==========="
puts [time {
set re {1.*1|2.*2|3.*3|4.*4|5.*5|6.*6|7.*7|8.*8|9.*9|0.*0}
for {set i 1} {$i < $max} {incr i} {
    if {[regexp $re $i] != 1} {
        lappend result $i
    }
}
} 1]
puts "\n"
puts [join $result ", "]
puts "\n==========="
puts "End"
puts "==========="

第二個測試程式使用 RE2:

package require regex_rez

puts -nonewline "Please input a number: "
flush stdout
gets stdin number
if {$number <= 0 || $number >= 10} {
   puts "The range is 1 - 9."
   exit
}

set max [expr pow(10, $number)]
set result [list]

puts "\nNow get the result:"
puts "==========="
puts "Start"
puts "==========="
puts [time {
set re [regex::re2 create {1.*1|2.*2|3.*3|4.*4|5.*5|6.*6|7.*7|8.*8|9.*9|0.*0}]
for {set i 1} {$i < $max} {incr i} {
    if {[$re partialmatch $i] != 1} {
        lappend result $i
    }
}
} 1]
puts "\n"
puts [join $result ", "]
$re close
puts "\n==========="
puts "End"
puts "==========="

(* 更新測試程式二,加上 $re close,這樣才會正確 close)

內建從輸入數字一到數字九:
475 microseconds per iteration
1029 microseconds per iteration
6884 microseconds per iteration
36152 microseconds per iteration
315566 microseconds per iteration
3134428 microseconds per iteration
32075931 microseconds per iteration
325211857 microseconds per iteration
2147483648 microseconds per iteration

RE2 從輸入數字一到數字九:
325 microseconds per iteration
649 microseconds per iteration
7262 microseconds per iteration
48204 microseconds per iteration
347111 microseconds per iteration
2727082 microseconds per iteration
21171756 microseconds per iteration
173788033 microseconds per iteration
1628503061 microseconds per iteration


雖然沒有很仔細的比較,在這個測試中如果是百萬級數目或者是以前比對,內建的正規表示式表現都很不錯,但是如果數目到達百萬級或者是以後比對,Tcl 內建的正規表示式速度看起來明顯的比較慢。

很有趣的問題。

2017-09-12

tclmixer - use SDL2/SDL2_mixer

tclmixer


TclMixer 使用 SDL 1.2 和 SDL_Mixer 1.2,我這幾天突然有個神奇的想法,那就是如果切換到 SDL2/SDL2_mixer 不知道會不會很難。

所以我下載了 TEA sample extension 然後將 TclMixer 的 source code 移過來,做了一點點小修改(主要是改版本,改成 2.0.0),然後發現…… SDL 和 SDL2 的 API 差距沒想像中大,因為沒改什麼東西,可是看起來 TclMixer 可以用。

實測 openSUSE 42.3 的結果,雖然可以使用,但是 SDL_mixer 還沒有 mp3 的部份,不過 OGG/Vorbis 是可用的。

MP3 的最後一個軟體專利在今年到期,所以一些原本無法直接使用的 MP3 自由軟體應該會開始逐漸重新進入 Linux 世界。至少在我測試 mpg123 的時候,我發現 openSUSE 在 42.3 將這個軟體放進來了(只是 devel package name 有改變,與 packman 的不同,但是主套件和 shared library package name 看起來是一致的)。

2017-09-09

Tcl/Tk 8.7a1 RELEASED

Tcl/Tk 8.7a1 RELEASED


Tcl/Tk 8.7 alpha 1 釋出,這是第一個測試的 alpha 版本,但是離可以穩定使用應該還有一段距離才對。


This release is a development release, and should only be considered for deployment use after considerable testing.

    * [TIP 458] New notifiers based on epoll() or kqueue()
    * [TIP 166] Extended color notation for alpha channel with [$image get|put]
    * [TIP 442] New options to display text in a progressbar
    * [TIP 463] New option: [regsub -command]
    * [TIP 449] [text] undo/redo return character range
    * [TIP 472] Support "0d" as optional prefix for decimal integers
    * [TIP 459] New introspection: [package files]
    * [TIP 470] Access to the context objects in oo definition commands
         => TclOO 1.2.0
    * [TIP 456] Extended C interface for opening server socket
    * Socket accept callbacks now always eval in the global namespace
         *** POTENTIAL INCOMPATIBILITY ***
    * Undocumented command [tk_getFileType] removed
         *** POTENTIAL INCOMPATIBILITY ***
    * [array names -regexp] now supports backrefs
    * Support for and
    * New Win shell builtins: assoc ftype move
    * Fix crash when command overwrite triggers delete trace that
      deletes enclosing namespace.
    * Fix memory leak in [text] widget operations.
    * [spinbox] now handles reversed -to / -from ordering.
    * Revised port selection for server sockets.
    * Repaired shadowing problem with compatibility fonts.
    * Repaired threaded allocator initialization.
    * http 2.8.12 fixes state 100 continue handling
    * library/msgs/*.msg files converted to true utf-8.
    * Itcl 3 "wrong num args" error messages no longer repaired.

2017-08-26

tDOM 0.9.0

ANNOUNCE: tDOM 0.9.0


tDOM 在很長一段時間的 0.8.3 以後,釋出了一個新版 v0.9.0。這版加入了 JSON 的支援,並且在編譯時開啟 html5 選項(需要連結 Google Gumbo html parser library)的情況下就有 html5 parser 可以用。

tDOM contains:

    *  for convenience expat 2.2.0, the XML parser originated from
       James Clark, although you're able to link tDOM with other
       expat versions or the library provided by the system.
    *  building a DOM tree from XML in one go implemented in C for
       maximum performance and minimum memory usage, and DOM I and II
       methods to work on such a tree using either a OO-like or a
       handle syntax.
    *  a Tcl interface to expat for event-like (SAX-like) XML parsing.
    *  a complete, compliant and fast XPath implementation in C
       following the November 99 W3C recommendation for navigating and
       data extraction.
    *  a fast XSLT implementation in C following the W3C Recommendation
       16 November 1999.
    *  optional DTD validation.
    *  a JSON parser which parses any possible JSON input into a DOM
       tree without losing information.
    *  an efficient and Tcl'ish way to create XML and HTML documents
       and JSON string.
    *  as build option an interface to the gumbo HTML5 parser, which
       also digests almost any other HTML.
    *  an even faster simple XML parser for trusted XML input.
    *  additional convenience methods.

2017-08-21

tcl-rocksdb v0.1.1

tcl-rocksdb


RocksDB 更改了授權,從原本的 BSD+PATENTS 變成 BSD+PATENTS/GPL v2 (dual license) 然後又變成 Apache 2.0/GPL v2 (dual license)。

而會修改授權,是因為 Apache 基金會接到 Apache Cassandra Team 的請求,希望能夠釐清使用 RocksDB 是否會有版權上的疑慮以後,公佈了結果,Facebook BSD+PATENTS license 被列為 category-x,同時提出了下列的建議:
  • No new project, sub-project or codebase, which has not used Facebook BSD+patents licensed jars (or similar), are allowed to use them. In other words, if you haven't been using them, you aren't allowed to start. It is Cat-X.
  • If you have been using it, and have done so in a *release*, you have a temporary exclusion from the Cat-X classification thru August 31, 2017. At that point in time, ANY and ALL usage of these Facebook BSD+patents licensed artifacts are DISALLOWED. You must either find a suitably licensed replacement, or do without. There will be NO exceptions.
  • Any situation not covered by the above is an implicit DISALLOWAL of usage.

所以如果 RocksDB 沒有修改授權,那麼 Apache Cassandra 就無法使用 RocksDB,已經使用的 Apache Flink, Apache Samza 等各個專案也需要開始尋找替代品。而 RocksDB team 在 Apache 基金會公佈結果以後,很快就修改了授權,變成 Apache 2.0/GPL v2 (dual license)。

既然授權的疑慮清除(PATENTS 是很複雜的議題,如果可以,我會儘量避開),所以我實作了 tcl-rocksdb (prototype),實作一些最基本的操作,同時也寫了簡易的 test case 測試。因為其它的部份我不知道怎麼實作成 Tcl extension 比較好,所以目前的 v0.1.1 就是我實作上比較知道怎麼做的部份了。


2017/08/22
加入幾個新的 command,更新版本為 v0.2。

另外,我發現 LevelDB 和 RocksDB 的基本操作長的很像,所以按照目前的資料,也寫了一個 tcl-leveldb

2017-08-10

Tcl/Tk 8.6.7 RELEASED

Tcl / Tk 8.6.7 RELEASED


Tcl/Tk 釋出了新的版本 8.6.7,下面是修正的項目:

Summary of Changes since Tcl/Tk 8.6.6:
------------------------------

This is a patch release, so it primarily includes bug fixes and corrections to erratic behavior.  Highlighted changes are noted below. The changes file at the root of the source tree contains a more complete list.  The Timelines of all changes are online.

         http://core.tcl.tk/tcl/
         http://core.tcl.tk/tk/

    * [TIP 473] (TclOO 1.1.0) Let [oo::copy] specify target namespace
    * [TIP 464] Support multimedia keys on Windows
    * Revise Tcl_LinkVar to tolerate some prefixes
         *** POTENTIAL INCOMPATIBILITY ***

    * Allow empty command as [interp alias] target
         *** POTENTIAL INCOMPATIBILITY ***

    * Revise Tcl_UtfToUniChar() handling of invalid UTF-8
         *** POTENTIAL INCOMPATIBILITY ***

    * [clock] and [encoding] are now ensembles
    * Several [clock] subcommands are now compiled to bytecode

    * Fix crashes or hangs in...
      - [socket -async ::1 0] with no host
      - Threaded memory allocator in thread finalization
      - Tcl_ListObjReplace() error when passed NULL interp
      - [binary scan a$n] when $n overflows int
      - [lsort -unique [lrepeat [expr {1<<27 1="" br="">      - Drawing many dashed canvas objects
      - Using Tk after IME restart
      - Warp pointer operations
      - [[text .t] insert 0.0 \na; .t replace 2.0 3.0 b]
      - Resource exhaustion processing corrupt GIF

    * Fix memory leaks in...
      - namespace delete when unset trace revives namespace variable.
      - Deletion of the [history] command
      - http::geturl when keep-alive is denied
      - TclJoinPath on a custom Tcl_Filesystem
      - text BTree operations

    * Update Unicode data to 10.0
         *** POTENTIAL INCOMPATIBILITY ***

    * Merge updates from new libtommath release; purge unused files
         *** POTENTIAL INCOMPATIBILITY ***

    * Update bundled zlib to release 1.2.11

    * Remove legacy support macro panic() - conflicts with system libs
         *** POTENTIAL INCOMPATIBILITY ***

    * Revise Tk font support to avoid type mismatch with recent Xft
    * Repair cmd resolver caching, demonstrated by tests resolver-3.1*
    * Repair zlib stream buffer flushing; zlib-7.8 and PNG writing
    * Prevent Win thread termination during init and teardown
    * Make KeyRelease event handling get _L and _R right
    * Repaint ttk::button when its image changes
    * Wrapped text don't start lines with whitespace
    * Non-native themes properly display tri-state buttons
    * File dialog repairs for -typevariable, -initialdir, -initialfile
    * Avoid unreleasable global grab due to menu keyboard traversal
    * Fix Win regression [event generate .e ]
    * Fix [grid configure -in] to fully clear outdated info
    * Fix ttk::combobox proper style with -postoffset (test combobox-3)
    * OSX: Stop [$text bbox] returning negative width
    * Repair autoloader fragility loading procs that call tailcall
    * Correct parsing in [scan 0x1 %b], [scan 0x1 %o]
    * Fix [string replace] so test stringComp-14.5 passes
    * Invalidate VFS mounts on sytem encoding change
    * Fix [expr {NaN > "Gran"}] to return 1; string comparison
    * Stop frequent Tcl_GetTime() calls creating clock drift
    * Correct functioning of dynamic unexport of methods
    * Fix [file join a //b] and [file join //a b]
    * Compute correct warp cursor position on 2nd display
    * Enable dismissal of ttk::menubutton without hover
    * Tk_BindEvent filter events Tk ignores avoid X11 ring buffer flood
    * Allow [$photo read] to read files beginning with "-"
    * [text] redisplay calculations corrected on OSX
    * Fix drawing of long text lines on Windows
    * Disabled combobox arrow appearance (danckaert)
    * Fix {PNG -alpha} format for 16-bit color
    * Workaround X11 drawing defects in Ubuntu 16.10+
    * Fix calculation of ttk::notebook tab widths and tab user management
    * Scidb race in notebook tab selection
    * Color name parsing set to reject invalid hex color codes (#ABCZ)
    * OSX scrollbar draw position, highlights, & smooth scroll
    * Race condition on Win clipboard cleanup
    * Center image on button
    * Paneconfigure get pane heights right
    * Windows: User switch forced theme reset
    * Updated bundled packages
       - Itcl 4.1.0      (incompatible with Itk 4.0, get Itk 4.1)
       - sqlite3 3.20.0
       - Thread 2.8.1
       - tdbc* 1.0.5
       - http 2.8.11
       - tcltest 2.4.1
       - msgcat 1.6.1

2017-08-05

Apache Tomcat HTTP/2 與 TclCurl

一閈始是設定 Apache Tomcat HTTP/2 的部份(Apache Tomcat 在 8.5 及以後的版本開始支援)。

HTTP/2 需要 Apache Tomcat Native Library 的支援才行, 所以首先是先安裝 Apache Tomcat Native Library。

Tomcat Native Library 需要 libapr1,所以如果是使用 openSUSE,
sudo zypper install libapr1-devel

再來是自己編譯 Tomcat 或者是使用 RPM 安裝

然後,需要創造 OpenSSL Certificate。 可以參考 Howto: Make Your Own Cert With OpenSSL。

如果只是要自己測試使用所以使用 self-signed,在 conf 目錄下使用下列的指令:
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt

最後修改 conf 目錄下的 server.xml,開啟 HTTP/2 的支援並且修改如下:

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/ca.key"
                         certificateFile="conf/ca.crt" />
        </SSLHostConfig>
    </Connector>

再來重新開啟 Apache Tomcat server,如果 https://localhost:8443 可以瀏覽,就正確的設定好了(* 因為是 self-signed,所以會看到安全性警告)。


TclCurl 在最近的版本有支援 HTTP/2,下面是驗證 Apache Tomcat HTTP/2 (self-signed) 的範例:
package require TclCurl

set curlHandle [curl::init]
$curlHandle configure -url https://localhost:8443 -sslverifyhost 0 \
    -sslverifypeer 0 -bodyvar result
$curlHandle setopt CURLOPT_HTTP_VERSION 2TLS

catch { $curlHandle perform } curlErrorNumber
if { $curlErrorNumber != 0 } {
    puts "error [curl::easystrerror $curlErrorNumber]"
}

# Print result and clean up
puts $result
$curlHandle cleanup

那麼我們怎麼知道真的是使用 HTTP/2 協定呢?這只要檢查 Tomcat logs 目錄下的 log 就可以確定。