2013-09-13

Get current OS string

使用下面的變數就可以拿到目前的 OS 字串:

$::tcl_platform(os)


以 Windows XP 來說,結果是下面的字串:

Windows NT

2013-06-16

Check Tcl support Thread or not

proc is_threaded {} {
 return [expr {[info exists ::tcl_platform(threaded)] && $::tcl_platform(threaded)}]
}


然後就可以使用 is_threaded 來判斷是否有支援 Thread.


如果要共用資料,可以使用 tsv command。下面是改寫以後的備份程式:
#!/usr/local/bin/tclsh
#
# This file is used to backup my homepage
#


proc is_threaded {} {
 return [expr {[info exists ::tcl_platform(threaded)] && $::tcl_platform(threaded)}]
}

set support [is_threaded]

proc backup_to_7z {} {
  set backupfile $::env(HOME)
  append backupfile "/Homepage-"
  append backupfile [clock format [clock seconds] -format %Y%m%d]
  append backupfile ".7z"

  set backupdir $::env(HOME)
  append backupdir "/public_html"

  set fileExist [file exists $backupfile]
  if {$fileExist > 0} {
      puts "Now try to remove old backup file."
      file delete $backupfile
  }

  set var [list 7z -p12345 a $backupfile $backupdir]
  exec {*}$var
}


if {$support == 1} {
  package require Tk
  package require Thread

  set ::gThread [thread::create {thread::wait} ]
  tsv::set body_backup_to_7z shared [info body backup_to_7z]


  label .greetings -text "Now backup my homepage..." -bd 4 -relief ridge
  pack .greetings -fill both

  wm title . "Backup"

  thread::send -async $::gThread { 
    set command [tsv::get body_backup_to_7z shared]
    eval $command
  } result  

  vwait result
} else {
  puts "No thread support..., so this script can't use Thread."

  backup_to_7z
}

exit

利用 Tcl 的特性,所以可以取得 proc body 以後當成是共用資料傳遞,如果資料量很小的時候,這是個很好玩的做法。

2013-06-15

Build snack 2.2.10 on openSUSE 12.3

如果是從 Snack 下載 source code 自己 build,會遇到二個問題。

1. math.h compilation error: expected declaration specifiers or '…' before '('

解決方法參考: http://stackoverflow.com/questions/9503473/math-h-compilation-error-expected-declaration-specifiers-or-before

找到 math.h,然後放到 roundf 函式的宣告的前面(這是只有 GCC 才有的問題) ,所以要做的就是修正 ./jkFormatMP3.c,

#include
#include
#include "snack.h"
#include "jkFormatMP3.h"


2. 因為要在 Linux 上使用 ALSA,所以要這樣下(在 x86_64 版本上):
./configure --enable-alsa --enable-shared --with-tcl=/usr/lib64 --with-tk=/usr/lib64

如果是 x86 的版本:
./configure --enable-alsa --enable-shared --with-tcl=/usr/lib --with-tk=/usr/lib


但是因為 _snd_pcm_mmap_hw_ptr 已經是過時的 function,所以要使用 snack-alsa.patch 裡面的內容來修正,下面是修正的地方:

Index: unix/jkAudIO_alsa.c
===================================================================
--- unix/jkAudIO_alsa.c.orig
+++ unix/jkAudIO_alsa.c
@@ -49,6 +49,8 @@ static int littleEndian = 0;

 static int minNumChan = 1;

+static snd_pcm_uframes_t hw_bufsize = 0;
+
 int
 SnackAudioOpen(ADesc *A, Tcl_Interp *interp, char *device, int mode, int freq,
            int nchannels, int encoding)
@@ -135,6 +137,9 @@ SnackAudioOpen(ADesc *A, Tcl_Interp *int
     Tcl_AppendResult(interp, "Failed setting HW params.", NULL);
     return TCL_ERROR;
   }
+
+  snd_pcm_hw_params_get_buffer_size (hw_params, &hw_bufsize);
+
   snd_pcm_hw_params_free(hw_params);
   snd_pcm_prepare(A->handle);
   if (A->mode == RECORD) {
@@ -202,6 +207,8 @@ SnackAudioPost(ADesc *A)
   int i;
   static char buf[64];

+  return;
+     
   if (A->debug > 1) Snack_WriteLog("  Enter SnackAudioPost\n");

   for (i = 0; i < 1000; i++) {
@@ -267,12 +274,14 @@ SnackAudioWriteable(ADesc *A)
 long
 SnackAudioPlayed(ADesc *A)
 {
-  long avail = _snd_pcm_mmap_hw_ptr(A->handle);
+  // FIX Here, _snd_pcm_mmap_hw_ptr is deprecated in new alsalib
+  long played = A->nWritten - (hw_bufsize - SnackAudioWriteable(A));
+  // long avail = _snd_pcm_mmap_hw_ptr(A->handle);
  
-  if (avail < 0)
-    avail = 0;
+  if (played < 0)
+   return 0;

-  return (avail+A->nPlayed);
+  return (played);
 }



在修正過後,就可以編譯出來正確的 Tcl-Snack (Linux-ALSA) 版本。但是我不知道實際上執行的時候是否正常。


剛剛快速測試以後,確定可以撥放 wav 檔,所以是可以正確使用的。



更新:
在將 tclsh 放置在 /usr/bin 以後,即使 snack 在 configure 時設定 prefix ,make install 以後仍然會放置在 /lib64/,需要自己手動放置到 /usr/lib64 (不知道怎麼解決)

Build tDOM-0.8.3 on openSUSE 12.3

錯誤訊息:

./generic/tcldom.c: In function ‘tcldom_EvalLocked’:
./generic/tcldom.c:5937:47: error: ‘Tcl_Interp’ has no member named ‘errorLine’
./generic/tcldom.c: In function ‘tcldom_RegisterDocShared’:
./generic/tcldom.c:5957:9: warning: variable ‘refCount’ set but not used [-Wunused-but-set-variable]
make: *** [tcldom.o] Error 1



解決方法:
http://sourceforge.net/p/modules/bugs/62/

Apparently errorLine is a deprecated feature.

A temporary fix is to enable this deprecated feature - although eventually this will cease to work. To do this configure with a line like this:

bash> CPPFLAGS="-DUSE_INTERP_ERRORLINE" ./configure
Then make && make install as usual.

2013-06-04

Tcl/Tk 8.4.20 RELEASED

Tcl/Tk 8.4.20 RELEASED



文章中寫到:

This is the twentieth and *FINAL*  patch release of Tcl/Tk 8.4.  With this release, support for Tcl/Tk 8.4 comes to an end.

所以如果沒有意外,這將是最後一個 Tcl/Tk 8.4.x 的版本。

2013-06-02

FreeWrap 6.6: both 32 and 64 bit Windows version support

FreeWrap


在隔了一陣子回來看 FreeWrap 的情況以後,發現 FreeWrap 現在 32/64 bit Windows 環境都支援了,我想這是一個好消息,提供了更多的彈性。

How to find out the Tcl version

How to find out the Tcl version


如果我們要知道目前的 Tcl 版本,可以使用 puts $tcl_version 就可以知道目前使用的版本。

2013-06-01

Building Tcl/Tk with Mingw

Building Tcl/Tk with Mingw


Tcler's Wiki 上有說明怎麼使用 Mingw + MSYS build Tcl/Tk,經過測試,Tcl 8.6.0 也 buld 成功。

我主要使用下列的 script:

#!/bin/sh
mkdir -p /src
mkdir -p /opt/tcl
mkdir -p /build/tcl
mkdir -p /build/tk
[ -e /src/tcl ] && {
    cd /build/tcl
    /src/tcl/win/configure --prefix=/opt/tcl --enable-threads && make && make install && {
        [ -e /src/tk ] && {
        cd /build/tk
        /src/tk/win/configure --prefix=/opt/tcl --enable-threads --with-tcl=/build/tcl \
            && make && make install
        }
    }
}

2013-04-12

freeWrap version 6.6

freeWrap 6.6 released (supports TCL/TK 8.6.0)

Changes implemented in version 6.6
------------------------------
------
  1. This version is based on TCL/TK 8.6.0.
  2. FreeWrap is now distributed as a 64-bit application. 
  3. The freeWrapPLUS variation has been discontinued. The regular freeWrap variation contains any added extensions. 
  4. Tkpng is no longer included in freeWrap since the TCL/TK core itself now supports PNG image formats. 
  5. SQLite is now included as part of the regular TCL 8.6 distribution and is packaged as such. 
  6. BLT is no longer included in freeWrap since BLT does not support TCL/TK 8.6. 
  7. TCLLIB (version 1.15) is now included in freeWrap at the virtual directory of /tcllib1.15
  8. TKLIB (version 0.5) is now included in freeWrap at the virtual directory of /tklib0.5 
  9. The virtual directory structure has been modified to better reflect the normal TCL/TK directory layout.

freeWrap 6.6 對應的版本是 Tcl/Tk 8.6.0,change log 我已經轉貼過來了。

我想把 Tcllib 和 Tklib 包在一起也好,Tcllib 一開始就有 Tcl standard library 的企圖,而 Tklib 則是掛在 Tcllib 下面。


相關連結:
官方網站

2013-04-09

7zip and password

要建立一個有設密碼的 7zip 檔,只要使用 7zip 的 -p 這個選項就可以搞定了。

下面是在 Windows 的範例:

    set backupfile $env(HOME)
    append backupfile "\\My Documents"
    append backupfile "\\Homepage-"
    append backupfile [clock format [clock seconds] -format %Y%m%d]
    append backupfile ".7z"

    set backupdir $env(HOME)
    append backupdir "\\My Documents"
    append backupdir "\\public_html"

    set fileExist [file exists $backupfile]
    if {$fileExist > 0} {
        puts "Now try to remove old backup file."
        file delete $backupfile
    }

    set var [list 7z -ppassword a $backupfile $backupdir]
    exec {*}$var

這樣子做就可以建立一個有設密碼的 7zip 檔。