跳到主要內容

發表文章

目前顯示的是 2018的文章

VIM on Windows

I have done with the slowness of cygwin git and switch to git-for-windows. Unfortunately, vim on cygwin doesn’t work well with git-for-windows per various path problems (e.g. plugin, path delimiters, etc). Here are some notes for tweaking vim on Windows. .vim or vimfiles Directories? Later one is used on Windows, however, many plugin or your scripts may refer the previous one. Thus, mklink it! i.e. .vim <==> vimfiles . VIM with Python Support Official vim81 compiles vim.exe without python support and gvim.exe with python/dyn (verify that with gvim --version ). Thus, Python support is only avail as of gvim.exe per official packages. Assume python.exe and python27.dll was installed in C:\Python\bin Add following environment variables PYTHONHOME=C:\Python\bin PATH=%PATH%;%PYTHONHOME% For :h pythonhome and :h pythondll . Verify above settings with :python print '' . Color Scheme gvim requires true color to apply color scheme correctly. Convert you

C++: 延遲函式實例化與 CRTP

C++: 延遲函式實例化與 CRTP Curiously recurring template pattern (CRTP) 是很有趣的模式,在標準函式庫中也有像 enable_shared_from_this 等應用,各種應用情境請參照前面的 Wiki 頁面。下面寫一個簡化的例子: template < typename T > struct base { auto interface ( ) { return static_cast < T * > ( this ) - > foo ( ) ; } } ; struct derived : base < derived > { int foo ( ) { return 123 ; } } ; int main ( ) { // your code goes here derived ( ) . interface ( ) ; return 0 ; } 這個範例中的 auto interface() 寫法,在 C++14 後才支援,在 C++11 以前,編譯器無法自動推導出 int 這個回傳型別而會吐出以下錯誤: error : 'interface' function uses 'auto' type specifier without trailing return type auto interface ( ) { ^ 也就是我們得自己寫出 auto interface() -> XXX {} ;那要 XXX 要怎麼推導呢? 直覺的寫法: template < typename T > struct base { auto interface ( ) - > decltype ( static_cast < T * > ( nullptr ) - > foo ( ) ) { return static_cast < T * >

UTF8 與 Unicode 的轉換 (C++)

UTF8 與 Unicode 的轉換 (C++) 先釐清一下這兩者的性質 Unicode: 為世界上所有的文字系統制訂的標準,基本上就是給每個字(letter)一個編號 UTF-8: 為 unicode 的編號制定一個數位編碼方法 UTF-8 是一個長度介於 1~6 byte 的編碼,將 unicode 編號 (code point) 分為六個區間如下表 1 Bits First code point Last code point Bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 7 U+0000 U+007F 1 0xxxxxxx 11 U+0080 U+07FF 2 110xxxxx 10xxxxxx 16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx 21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 觀察上面的表應該可以發現 除了 7 bits 的區間外,第一個 byte 開頭連續 1 的個數就是長度,例如 110XXXXX 就是 2 byte 長,而 1110xxxx 就是 3 byte 除了第一個 byte 外,之後的 byte 前兩個 bit 一定是 10 開頭,這樣的好處在於確立了編碼的 self-synchronizeing,意即當編碼為多個 byte 時,任取一個 byte 無法正常解碼。 Note 第一點中的例外 (7 bits) 是為了與 ASCII 的相容性,而第二點會影響到 code point 至 UTF-8 的轉換。 為了與 UTF-16 的相容性,在 R

Testlink on Ubuntu with postgresql, nginx, and LDAP

Testlink on Ubuntu with postgresql, nginx, and LDAP 目標 在 Ubuntu 14.04 上架設 testlink 使用 LDAP 管理 testlink 使用者 使用 nginx 作為 web server Step 1. 安裝 sudo apt-get install postgresql sudo apt-get install php5-fpm php5-pgsql php5-gd php5-ldap php5-json sudo apt-get install nginx-extras 從 testlink 官方 sourceforge 取得 tar 檔 tar xvf testlink-1.9.10.tar.gz mv testlink-1.9.10 /usr/share/nginx/html/testlink Step 2. 設定 DB user 詳細設定請參考 1 。 以 postgres ( system user) 身份執行 psql 命令並切換成 postgres ( db user) 身份 sudo -u postgres psql postgres 變更 postgres ( db user) 的密碼 \password postgres Enter Password: .. . 這裡的 postgres 與密碼稍後在設定 testlink 會用到 Step 3. 設定 nginx 編輯 /etc/nginx/site-available/default Note 這裡直接使用 default site 來設定,可自行修改 將 index.php 加進 index directive index index.html index.htm index.php; 將 php 相關設定的註解拿掉 location ~ \.php$ { fastcgi_split_path_info ^ ( .+\.php ) ( /.+ ) $ ; # NOTE: You should have "cgi.fix_pathinfo = 0

boost::python - 從 C C++ 中呼叫 Python 函式

boost::python - 從 C C++ 中呼叫 Python 函式 背景 如果對 callback 已經很熟悉的可以跳過這段;不少函式庫的 API 會接收 callback 或者是 action 函式,如下 // File: callback.hpp # ifndef CALLBACK_HPP_ # define CALLBACK_HPP_ // void* 為使用者傳入的 context, val 是函式庫指定的值 typedef void ( raw_cb_t ) ( void * ctx , int val ) ; void libfunc ( raw_cb_t * cb , void * ctx ) ; # endif 這裡的 raw_cb_t cb 就是 callback/action 函式,作為一個參數傳遞給 libfunc ,由它決定何時呼叫,如下 // File: callback.cpp # include "callback.hpp" void libfunc ( raw_cb_t * cb , void * ctx ) { for ( int i = 0 ; i < 10 ; i ++ ) { cb ( ctx , i ) ; } } 使用 libfunc 這個 API 的方式在 C/C++ 裡面可以是 // File: main.cpp # include <iostream> # include "callback.hpp" void handler ( void * ctx , int val ) { int * sum = static_cast < int * > ( ctx ) ; std : : cout << ( * sum ) + = val << std : : endl ; } int main ( void ) { int sum = 0 ; libfunc ( & handler ,

使用免費工具救援硬碟資料

前陣子處理一顆突然變成「未格式化」(RAW format) 的 行動硬碟,筆記一下用到的工具、指令;因為這顆硬碟只有資料沒有開機磁區,以下步驟未包含 MBR 相關的修復。 這裡紀錄的只是個人筆記,不保證適用特定系統、硬體,作者對任何衍生行為的結果不提供任何保證。 首要重點 製作一個備份硬碟,只對備份硬碟進行修復 。 製作一個備份硬碟,只對備份硬碟進行修復 。 製作一個備份硬碟,只對備份硬碟進行修復 。 製作備份: 我使用 dd 來達成; 找一台正常的系統, 安裝 Cygwin 1 接上損壞的硬碟 (Disk 1),跟額外的備份硬碟 (Disk 2),容量必須 Disk 2 > Disk 1。 打開 terminal/cygwin,找出對應的裝置 $ ls /dev/sd* /dev/sda /dev/sda2 /dev/sda4 /dev/sda6 /dev/sdx /dev/sda1 /dev/sda3 /dev/sda5 /dev/sda7 /dev/sdx1 /dev/sdy /dev/sdy1 如果不知道 /dev/sdx 的意思,或是不確定要修的硬碟對應到那個路徑,不建議繼續往下進行。 假設損壞硬碟 (Disk 1) 在 sdx ,備份硬碟 (Disk 2) 在 sdy ,而且 你知道自己在做甚麼 ,以管理員權限執行以下指令。 time dd if=/dev/sdx of=/dev/sdy iflag=direct conv=noerror,sync bs=64K 視硬碟大小、讀寫速度,這個步驟會耗費不少時間,假設每秒 10MB ,1TB 大概需要 27.7 小時。期間請確保系統不會更新或斷電。 進行修復: 移除 (Eject) 損壞的硬碟 (Disk 1) 以管理員權限執行 cmd 確認 Disk 2 掛載點,假設是 E: ,若 Disk 2 沒有正常掛載,可用 diskpart 或 diskmgr (GUI)手動掛載 修復指令 chkdsk e: /offlinescanandfix 修復完成後再用 diskpart 或 diskmgr online Disk 2 復原的檔案會放在 e:\found.000 隱藏目錄下,用 File Explorer 會看不

Tips: Lexicographical Comparable Type in C++

PST: Lexicographical Comparable Type in C++ It has been years since last update to this blog. It should be good to write some small (for happily copy’n paste :-) tips for re-familiar writing. Lexicographical comparing a aggregated type in C++ struct Version { int major ; int minor ; int patch ; friend bool operator < ( const Version & lhs , const Version & rhs ) { if ( lhs . major < rhs . major ) return true ; if ( lhs . minor < rhs . minor ) return true ; return lhs . patch < rhs . patch ; } } ; Nothing wrong with above code. However # include <tuple> using Version = std :: tuple < int , int , int > ; is sometimes sufficient. Pro: No need to write all comparison operators Con: Not that obvious accessing method, e.g. get<0>(var) – Written with StackEdit .

Notes for C/C++ Programming

Notes for C/C++ Programming Notes for C/C++ Programming Off by One Error Prone # define LEN 128 char buf [ LEN ] = { 0 } ; // -1 for prevent missing NULL terminator // since strncpy doesn't preserve it for us. strncpy ( buf , something , sizeof ( buf ) - 1 ) ; // snprintf does preserve NULL terminator for us // i.e. actual size for placing characters is sizeof(buf) - 1 // but it takes extra time to parsing format snprintf ( buf , sizeof ( buf ) , something ) ; Bad things often happen when we mess with -1 or +1 to pointers point to continuous elements. Absorber # define LEN 128 char buf [ LEN + 1 ] = { 0 } ; // ^^^^ Always preserve 1 byte strncpy ( buf , somethin , sizeof ( buf ) ) ; Constant Correctness (C/C++) Bad void do_something ( char * dest , char * src ) ; struct MyList { void do_something ( std :: string & name ) ; } ; Reason : Will the name be modified by the lookup method? Will stat