2011-12-13

lua and 64bit integer

lua 的整數運算很不幸的,只有到 32bit 的範圍(-2,147,483,648 ~ 2,147,483,647),但透過 lnum 之 patch 之後,可支援到 64bit(-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)底下是 patch 之過程的記錄:

1. 到 這裡 取得 Lua 5.1.4 原始碼。
2. 到 這裡 取得 lua514-lnum-20090417.patch.tgz。
3. 執行 patch 指令 
    a. linux or mac :  
        i. 解壓解 lua 5.1.4 及 lua514-lnum-20090417.patch.tgz
        ii. 把 lua514-lnum-20090417.patch  擺在 lua 5.1.4 之 src 目錄下
        ii. 進到 lua src 檔目錄下
        iii. 執行 patch < lua514-lnum-20090417.patch
    b. windows :
        i. 到 這裡 下載 patch 執行檔
        ii. 解壓解 lua 5.1.4 及 lua514-lnum-20090417.patch.tgz
        ii. 把 lua514-lnum-20090417.patch 和 patch.exe  擺在 lua 5.1.4 之 src 目錄下
        ii. 進到 lua src 檔目錄下
        iii. 假如使用的是 win7, vista 作業系統,須把 patch.exe 改成其它名稱(例如 cc.exe)
        iv. 執行 patch < lua514-lnum.patch(或者 cc < lua514-lnum.patch)
        v. 假如顯示 Assertion failed: hunk, file ../patch-2.5.9-src/patch.c, line 354…訊息: 
            1. 執行 write lua514-lnum-20090417.path
            2. 將會跳出 wordpad 視窗,此時直接按存檔並離開
            3. 重新執行 iv 指令
4. 開啟 luaconf.h,找到下列關鍵字:

/*
@@ LNUM_DOUBLE | LNUM_FLOAT | LNUM_LDOUBLE: Generic Lua number mode
@@ LNUM_INT32 | LNUM_INT64: Integer type (optional)
@@ LNUM_COMPLEX: Define for using 'a+bi' numbers
@*
@* You can combine LNUM_xxx but only one of each group. I.e. 'LNUM_FLOAT
@* LNUM_INT32 LNUM_COMPLEX' gives float range complex numbers, with
@* 32-bit scalar integer range optimized.
*/
/*#define LNUM_DOUBLE*/

5. 在關鍵字下一行加入 #define LNUM_INT64
6. 開始編譯(可參考 這篇

redirect git stdout message

假如現在執行一個 git 指令 “git clone git://github.com/joyent/node” 其顯示的訊息(包含檔案下載的進度)為:


最後完成時顯示為:


若要在 C# 執行上述 git 指令,通常使用 System.Diagnostics.Process 來呼叫執行,其程式碼如下:
static void Main(string[] args)
{

    Process myProcess = new Process();
    ProcessStartInfo info = new ProcessStartInfo("git.exe", "clone git://github.com/joyent/node");
    info.CreateNoWindow = true;
    info.UseShellExecute = false;
    info.RedirectStandardOutput = true;
    info.WorkingDirectory = "";
    myProcess.StartInfo = info;
    myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived);

    myProcess.Start();
    myProcess.BeginOutputReadLine();

    myProcess.WaitForExit();
    myProcess.Close();

}
static void myProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    if (!String.IsNullOrEmpty(e.Data))
    {
        Console.WriteLine("captured line> "+e.Data);
    }           
}
執行結果為:
由上圖發現執行過程中,只有顯示一行訊息,猜測是因為 git 在執行時期會呼叫其它的 process,而這些 process 所顯示的訊息未被 redirect 到 C#,下圖是 process explorer 在 git 執行時期所擷取的畫面,發現 git 的確產生 child process 來處理其它工作:

因此若要擷取 child process 顯示的訊息,改用下列指令:
cmd.exe /C “git.exe clone git://github.com/joyent/node –progress 2>&1”
程式碼修改為:
ProcessStartInfo info = new ProcessStartInfo("cmd.exe", "/C " + "" + "git.exe clone git://github.com/joyent/node --progress 2>&1" + "");
執行結果為:

終於把所有的訊息都 redirect 到 C# 了。