2009/12/24

Colorsvn 讓 SVN 一目了然

就像 colordiff 一樣,小小顏色卻能大大提高 diff 檔的可讀性。習慣用命令列 svn 指令的人應該會喜歡 colorsvn (http://colorsvn.tigris.org):


Ubuntu 的正式套件目前還沒有收錄 colorsvn,可用以下方法安裝:
  1. 到以下位置下載 .rpm 檔:
    http://www.console-colors.de/index.php?n=ConsColors.Downloads
  2. 利用 alien 來安裝 .rpm 檔:
    sudo alien -i colorsvn-0.3.2-1.noarch.rpm
  3. 在 .bashrc 增加 alias svn='colorsvn'
PS 1: 若你安裝完之後看不到顏色,請檢查是否有 `/etc/colorsvnrc` 或 `~/.colorsvnrc`。若沒有,可以下載 colorsvn 的 tarball,裡面有個 colorsvnrc-original,可以拿這個檔案出來用。

PS 2: 裝了 colorsvn 之後,svn diff 一樣沒有顏色,需要搭配 colordiff

2009/11/18

Subversion 的 Log

使用 Subversion 之類的 version control system 時,commit log 是非常重要的一項資訊。在你追查歷史時,可以幫助你回復記憶或幫助別人迅速理解 changeset 的目的。

但人吃五穀雜糧長大,打字難免會錯。因此,就有修改 commit log 的需求產生。Subversion 安裝預設是無法修改 commit log 的。以下是開放此項功能的方法 ($REPOS 代表 repository 的目錄):
cd $REPOS/hooks
mv pre-revprop-change.tmpl pre-revprop-change
chmod +x pre-revprop-change
若設定正確,就可以用以下指令來修改任一版本的 log:
svn pe -r 1234 --revprop svn:log $REPOS

svn ps -r 1234 --revprop svn:log "New commit log" $REPOS
若你恰好跟我一樣,也用 Trac 搭配 Subversion 時,正確的 log 更重要。因為 log 可用來搜尋 changeset。不過 Trac 上的 log 是你 commit 時,Trac 偷偷複製的。你改了 Subversion 的 log,Trac 並不知道,所以 Trac 上的 log 還是舊的。

解決方法是要求 Trac 重新校正 log:
# Trac 0.12 以前
trac-admin $PROJENV resync 1234
# Trac 0.12 及以後
trac-admin $PROJENV repository resync "" 1234
其中 $PROJENV 是 Trac 的 environment 位置;1234 是 revision number,若你改了很多 log,省略這個參數就可以全部一起校正。

每次手動校正 log 很麻煩,管理也不方便。所以可以將上述指令寫在另外一個 Subversion 的 hook script -- post-revprop-change:
REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
ACTION="$5"
TRAC_ENV="..."

if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then
PYTHON_EGG_CACHE=/tmp trac-admin $TRAC_ENV repository resync "" $2
# 若你的 Trac 比 0.12 版舊,請改用以下這一行
# PYTHON_EGG_CACHE=/tmp trac-admin $TRAC_ENV resync $2
exit 0;
fi
注意!上面的 TRAC_ENV 要設定到對應此 repository 的 Trac environment。

2009/11/01

由 Ubuntu 9.04 升級到 9.10 很不平順

由 Ubuntu 9.04 升級到 9.10 很簡單:執行 系統->管理->更新管理員,應該會看到 有新的發行版,只要按 升級 就可以將 9.04 升級到 9.10。

但升級後發現中文介面不見了,變成全英文介面。這倒還好,反正英文介面也是可以看中文文件。比較麻煩的是無法輸入中文。後來摸索了很久,終於研究出把中文介面找回來的方法:開啟 System -> Administration -> Synaptic Package Manager,點選 Installed 然後在 Quick search 輸入「hant」。這樣會列出所有已安裝的 Traditional Chinese 相關套件,全選這些套件然後 Mark for ReinstallationApply 即可重新安裝這些套件,重新開機之後便找回中文介面。

不過,問題還沒有完全解決。9.10 的輸入法引擎由 SCIM 改成 IBUS,我習慣用酷音輸入法搭配許氏鍵盤。但這種組合似乎還有 bug:會自動切回標準鍵盤。每次發生這種現象之後,就要重設一次鍵盤。又摸索了一陣子,終於找到解決方法:換回 SCIM。方法如下:
  • 系統->管理->語言支援
  • 鍵盤輸入系統 = scim
另外,升級到 9.10 也幫我解決不少 9.04 的問題:
  • 不支援 Asus 某款 NB 上的 Fn 功能鍵
  • 不支援上述 NB 的 Realtek High-Definition 音效控制晶片
  • Minicom 搭配某款 USB-to-serial adapter (/dev/ttyUSB0) 啟動時會有亂碼
總結:升級過程雖然有點不平順,但我還是 Ubuntu 的衷心擁護者,強烈推薦大家轉換到這個開放的平台。

2009/10/16

CuteCom 的 Input History

CuteCom 是 Linux 上相當好用的 terminal emulator 之一 (請參考 這裡)。他最大的特色是有一個 input history,會保存最近輸入過的指令,隨時可以點選取用。

比較討厭的是,輸入錯誤的指令也會佔據有限的 history 空間,令人想除之而後快。不過 CuteCom 似乎沒有提供刪除 history 的介面。後來找到一個解法,直接編輯設定檔:
vi .config/Unknown\ Organization.conf
修改最底下那行 History= 就可以了。

超好用的 colordiff

如果你跟我一樣習慣用 diff 來比較前後版程式修改了哪些地方,你一定也會喜歡 colordiff。顧名思義,它是有顏色的 diff -- 以不同顏色來顯示刪除或新增的地方,這讓 diff 的結果一目了然。

安裝方法:
sudo apt-get install colordiff
使用方式:
  • colordiff file1 file2
  • colordiff -u file1 file2 | more
  • colordiff -u file1 file2 | less -R
  • svn diff file1 | colordiff
若不想改變平常下指令的習慣,可以這樣做:
  • 在 .bashrc 加上一條 alias diff='colordiff'
  • 將 .subversion/config 的 diff-cmd 設成 colordiff
這樣以後 diff 和 svn diff 就直接變成彩色版了。

2009/09/13

在 Ubuntu VM 上安裝 VirtualBox Guest Additions

VirtualBox Guest Additions 能讓 guest OS 和 host OS 之間更緊密合作,也提供 guest OS 許多額外的功能 (例如和 host OS 分享資料夾)。想享受這些好處,請參考如下步驟安裝 VirtualBox Guest Additions。

首先,啟動 guest OS,並在所屬視窗的功能表上點選 Devices,然後再點 Install Guest Additions。注意!這並不會啟動安裝的動作,而是將安裝光碟插入 guest OS 的光碟機中。你必須手動執行安裝的指令。請用以下指令看看安裝光碟的內容:
sudo -s
ls -la /media/cdrom
註:若看不到任何東西,表示你的 Ubuntu 沒有自動幫你 mount 剛插入的光碟。請用以下指令自己來:
mount -t iso9660 /dev/cdrom /media/cdrom
若一切順利,你應該會看到幾個 VBox 開頭的檔案。然後,請執行以下指令:
/media/cdrom/VBoxLinuxAdditions-x86.run
如果你的 guest Ubuntu 才剛安裝完畢,上述指令應該會提醒你缺了哪些東西以至於無法安裝。以下是我剛安裝好 jeos-8.04.3-jeos-i386 之後所得到的「提醒」:
VirtualBox 3.0.6 Guest Additions installation
Please install GNU make.
Please install the build and header files for your current Linux kernel.
Ther current kernel version is 2.6.24-24-virtual
Please install the GNU compiler.
Problems were found which would prevent the Guest Additions from installing.
Please correct these problems and try again.
此時你必須發揮見招拆招的精神把這些問題解決:
apt-get install make
apt-get install linux-headers-2.6.24-24-virtual
apt-get install gcc
將缺少的東西補足之後,再執行一次 VBoxLinuxAdditions-x86.run 即可完成安裝的動作。

Reboot 之後,執行以下指令應該可以看到 guest OS 已經載入幾個 VirtualBox 的 kernel modules (如 vboxvfs、vboxadd 等):
lsmod | grep vbox
恭喜!這代表你已經大功告成了!

2009/08/28

在 Ubuntu 上設定 PPPoE 連線

在 Ubuntu 上設定 PPPoE 連線非常簡單,只要執行 pppoeconf 即可。它會一步一步詢問你所需要的設定,程序大致如下 (若要中斷程序,可以按 Esc):
  1. 首先找出機器上所有的網卡,如果沒有遺漏就可以進到下一步
  2. 接下來會自動偵測這些網卡的連線上是否有 PPPoE 伺服器 (PPPoE Access Concentrator)。若 MODEM 有開,網路也接對,應該會自動找到連接 PPPoE 的網卡
  3. 接下來會詢問你是否要用 noauth 與 defaultroute 兩個選項。一般來說,應該回答「是」
  4. 再來是輸入帳號和密碼,請查閱 ISP 給你的帳號資料卡
  5. 接下來會問你是否要使用 ISP 配發的 DNS 伺服器。一般來說,應該回答「是」
  6. 再來會詢問是否要限制 MSS。一般來說,應該回答「是」
  7. 接下來會問是否想在開機的時候就啟動連線。可看自己的需求來回答
順利的話,完成上述步驟時,PPPoE 應該就已經連接成功了。有以下指令可以操控連線:
  • plog => 查看 PPPoE 連線最近的 log,故障排除時很有用
  • poff => 斷線
  • pon dsl-provider => 啟動上述設定的連線
  • ifconfig ppp0 => 查看 PPPoE 連線的結果
內行一點的人,可以編輯 /etc/ppp/peers/dsl-provider 來微調上述設定。

2009/08/21

在 Ubuntu 上安裝 VMware Player

首先到以下位置下載 VMware Player。填完註冊表格之後,便可選擇要哪一種平台的哪一個版本,請選擇 for Linux (.rpm):
http://www.vmware.com/download/player/
截至發文的時間,最新的版本是 2.5.3。若你有安裝舊版本,請用以下指令移除:
$ LANG=C rpm -e VMware-Player
若用以下指令安裝,會有「相依性偵測失敗:/bin/sh 被 VMware-Player-2.5.3-185404.i386 所需要」的錯誤發生:
$ rpm -Uhv VMware-Player-2.5.3-185404.i386.rpm
請改用以下指令跳過相依性檢查,就可以安裝成功:
$ LANG=C rpm --nodeps -Uhv VMware-Player-2.5.3-185404.i386.rpm
安裝成功之後,可以在系統工具選單找到 VMware Player 的啟動圖示。

2009/07/27

C/C++ Predefined Macros

寫程式經常會用到編譯器預先定義的巨集 (Predefined Macros),例如:__FILE__、__LINE__、__DATE__、__TIME__、__func__ 等。這些巨集有些是標準 C/C++ 語言所定義的,有些則是編譯器自行定義的。使用 GNU C/C++ 的人,可參考以下資料:
Predefined Macros (GNU C/C++)
這份資料所提到的 System-specific Predefined Macros 是指針對不同的系統平台 (arm、mips 等),編譯器所預先定義的特殊巨集。若想直接看看這些預先定義的巨集,可執行以下指令:
echo | gcc -dM -E - | sort
使用 Microsoft 系列編譯器的人,可參考以下資料:
Predefined Macros (MSDN)

2009/07/22

兩個管理 init script 的指令: service、rcconf

在 Ubuntu 上安裝一些 daemon (如 apache、ushare 等) 後,都要靠 init script 來控制。有兩個管理 init script 的指令一定要會用:service 和 rcconf。

service

用來啟動、停止和檢查這些 daemon 的狀態。例如:
  • service --status-all => 列出目前所有 daemon 的狀態
  • sudo service XXX start => 馬上啟動 XXX daemon
  • sudo service XXX stop => 馬上關閉 XXX daemon
  • service XXX status => 檢查 XXX 的狀態
rcconf

用來控制系統開機時是否要執行這些 daemon。例如:
  • sudo rcconf --list => 列出目前所有 daemon 的啟動設定
  • sudo rcconf --on XXX => 設定 XXX daemon 開機時自動啟動
  • sudo rcconf --off XXX => 設定 XXX daemon 開機時自動啟動
若你的系統沒有 rcconf 指令,請按以下方式安裝:
sudo apt-get install rcconf

2009/06/14

在 Ubuntu Desktop 上安裝 TFTP Server

其實,以前就記下安裝 TFTP server 的方式 (參看 這裡)。但標題不對,所以自己也忘了。以下重新整理一遍。

首先安裝 tftpd package:
sudo apt-get install tftpd
然後建立 tftpd 的分享目錄,此目錄用來存放要傳送和接收的資料:
mkdir -p /srv/tftp
chmod 777 /srv/tftp
 較新的 Ubuntu 已經改用 xinetd,你必須新增一個內容如下的 /etc/xinetd.d/tftp:
service tftp
{
    socket_type     = dgram
    protocol        = udp
    wait            = yes
    user            = root
    server          = /usr/sbin/in.tftpd
    server_args     = -s /srv/tftp
#   disable         = yes
}
若你還是用 inetd,就必須修改 /etc/inetd.conf:
tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp
最後,重新啟動 xinetd:
sudo service xinetd restart
或者 inetd:
/etc/init.d/openbsd-inetd restart
PS: 一般從 TFTP server 抓資料比較沒問題,權限對就可抓。但放資料到 TFTP server 上就需要特別注意,一般的設定顧及安全性,你要先有同名檔案,然後才能傳送過去 (覆蓋)。

2009/05/15

String::CRC::Cksum module for 64-bit Perl

When I used the following command to install String::CRC::Cksum on my 64-bit Ubuntu,
perl -MCPAN -e "install String::CRC::Cksum"
the following error message is shown and perl rejected to install it:
Use of uninitialized value in bitwise xor (^) at at /usr/local/share/perl/5.10.0/String/CRC/Cksum.pm line 73.
I managed to google the solution but in vain. Finally, I realized the problem is caused by 64-bit integer on my 64-bit Ubuntu.

To fix this problem, force to install String::CRC::Cksum module first:
$ sudo cpan
Terminal does not support AddHistory.

cpan shell -- CPAN exploration and modules installation (v1.9205)
ReadLine support available (maybe install Bundle::CPAN or Bundle::CPANxxl?)

cpan[1]> force install String::CRC::Cksum
and then patch it (/usr/local/share/perl/5.10.0/String/CRC/Cksum.pm, "chmod" first! it's read-only):
--- Cksum.pm    2009-05-15 00:33:20.000000000 +0800
+++ Cksum.pm 2009-05-15 00:25:36.000000000 +0800
@@ -70,7 +70,7 @@

for(my $i = 0; $i < $n; ++$i) {
my $c = unpack 'C', substr $_[0], $i, 1;
- $cksum = ($cksum << 8) ^ $crctab[($cksum >> 24) ^ $c];
+ $cksum = ($cksum << 8) ^ $crctab[(($cksum >> 24)&255) ^ $c];
++$size;
}

@@ -111,7 +111,7 @@
while($size != 0) {
my $c = $size & 0377;
$size >>= 8;
- $cksum = ($cksum << 8) ^ $crctab[($cksum >> 24) ^ $c];
+ $cksum = ($cksum << 8) ^ $crctab[(($cksum >> 24)&255) ^ $c];
}
$cksum = ~ $cksum;

2009/05/10

將 Ubuntu 從 8.04 升級到 9.04

Ubuntu 9.04 已經出來一陣子了,口碑還不錯。而 Ubuntu 8.04 是 LTS 版 (Long Term Support),所以不能直接升級到 9.04,必須用以下方法來升級。

首先要修改一項和更新有關的設定 (系統->管理->軟體來源->更新):將 顯示新的發行版本發布長期支援的發布 改為 正常發布




接下來,執行更新管理員 (系統->管理->更新管理員),應該會看到 有新的發行版,只要按 升級 就可以將 8.04 升級到 8.10:



升級過程約需要三十至六十分鐘。等升級完畢,再執行一次更新管理員,從 8.10 再升級到 9.04 即可。

PS: 升級完畢,可用以下指令刪除一些不必要的 package,節省空間:
sudo apt-get clean

2009/04/27

辨認 GNU/Linux 的發行版本 (distro)

網路上有多少 GNU/Linux 的發行版本 (distro)?看看這張令人眼花撩亂的 族譜 吧,我相信沒有幾個人有興致去數清楚的。但弄清楚你正在使用的 GNU/Linux 是哪一個版本可能是相當重要的課題 (透過 ssh 去登入主機的使用者,不見得知道該主機作業系統的詳細資料)。

由於 GNU/Linux 的發行版本很多,多數又有繼承演化的關係,要辨認出每個版本不是一件容易的事。以下是一些簡單的辨別方法,越前面的越精確,但不見得都適用,若該方法行不通,請退而求其次,試試下一個方法。

執行 lsb_release -a


這是最精確的方法,以下是一些輸出範例:

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 8.10
Release: 8.10
Codename: intrepid
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 4.0 (etch)
Release: 4.0
Codename: etch
LSB Version: :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description: CentOS release 5.2 (Final)
Release: 5.2
Codename: Final
執行 ls /etc/*release 再執行 cat /etc/*release

有許多發行版本的資訊都寫在 /etc/*release 的檔案之中,例如:
  • /etc/lsb-release (Ubuntu)
  • /etc/SuSE-release (SuSE)
  • /etc/redhat-release (RedHat, CentOS)
  • /etc/mandrake-release (Mandrake)
  • /etc/distro-release (AsteriskNOW)
執行 ls /etc/*version 再執行 cat /etc/*version

有另一些發行版本的資訊是寫在 /etc/*version 的檔案之中,例如:
  • /etc/debian_version (Debian, Ubuntu)
  • /etc/slackware-version (Slackware)
執行 cat /etc/issue

嚴格說來,這不是正確的方法,因為此檔案是用來儲存一些要秀給使用者登入時看的訊息。但很多 distro 都會在這個檔案寫上自己的發行名稱,所以也是不錯的參考資料。例如:
  • Ubuntu 8.10 \n \l
  • Ubuntu 8.04.2 \n \l
  • Debian GNU/Linux 4.0 \n \l
  • CentOS release 5.2 (Final) Kernel \r on an \m
執行 cat /proc/version

此方法的訊息更不明確,但也不失為一個判斷的依據。例如:
  • Ubuntu 8.10 => Linux version 2.6.27-11-generic (buildd@yellow) (gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu11) ) #1 SMP Wed Apr 1 20:53:41 UTC 2009
  • Ubuntu 8.04.2 => Linux version 2.6.24-23-server (buildd@vernadsky) (gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)) #1 SMP Mon Jan 26 00:55:21 UTC 2009
  • Debian 4.0 => Linux version 2.6.22-3-vserver-amd64 (Debian 2.6.22-6) (maks@debian.org) (gcc version 4.1.3 20071019 (prerelease) (Debian 4.1.2-17)) #1 SMP Sun Nov 4 18:41:00 UTC 2007
  • CentOS 5.2 => Linux version 2.6.18-92.el5 (mockbuild@builder16.centos.org) (gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)) #1 SMP Tue Jun 10 18:49:47 EDT 2008

2009/04/17

我的 Firefox 擴充套件點點名

將個人喜好的 Firefox 擴充套件記錄如下,也推薦給大家:
  • Favicon Picker 3 讓你自訂 bookmark 的圖示。
  • Firebug 超強網頁除錯工具,內行人應該都知道。
  • User Agent Switcher 改變 Firefox 送出的 User-Agent 字串,內行人應該都知道。
  • Flashblock 擋下不必要的 flash 花招,並在該處留白,想看時再自己點選。
  • Google Bookarks Button Reloaded 將自己的 bookmark 放在 Google 上。
  • Hide Menubar 將很少用到的 Firefox 選單列隱藏起來,需要時按 ALT 即可顯現出來。
  • Mozilla Archive FormatUnMHT 收到惱人的 .mht 檔案嗎?用這個可以開啟喔! (進一步介紹)。
  • PDFescape 讓你線上「編輯」 PDF 文件 (進一步介紹)。
  • Tab Mix Plus 強化 Firefox 的分頁瀏覽功能。
  • Wired-Marker 閱讀網頁的最佳夥伴 (進一步介紹)。

2009/04/10

我的 Ubuntu 軟體點點名

用 Ubuntu 越久,就越覺得方便。需要甚麼功能的軟體,絕大部分用 Synaptic 就可以下載安裝。將好用的軟體記錄如下,也推薦給大家 (不含 Ubuntu 固定會安裝的)。
  • KchmViewer 電子書 .chm 檔案的檢視器。套件:kchmviewer (曾試過 GnoCHM 和 ChmSee,這兩者的搜尋功能都不好用)
  • hexedit 非文字檔的編輯工具。套件:hexedit
  • unrar 解壓縮程式,可與 file-roller 整合。網路上有那麼多免費、公開的壓縮軟體,搞不懂為什麼那麼多人喜歡將檔案壓成 .rar。套件:unrar
  • minicom 終端機模擬軟體 (terminal emulator),透過 RS232 連到某些設備的 console。套件:minicom (進一步介紹)
  • Wire Shark 封包抓取和分析軟體。套件:wireshark (進一步介紹)
  • Virtual Box 虛擬機器。套件:virtualbox-ose,但我推薦 官方網站 的版本,不管用哪一套都需安裝 scim-bridge-client-qt (進一步介紹)
  • Sox 聲音檔轉換工具 (命令列模式)。套件:sox、libsox-fmt-all
  • VLC media player 影音播放軟體。套件:vlc
  • Wave Surfer 聲音檔處理、分析工具,可檢視聲音波形、區間播放等。套件:wavesurfer

2009/03/10

Subversion, Grep, Diff

我很習慣用 grep 來找 source code 當中的字串;也很習慣用 diff 來比較兩個 source tree 的差異。如:
grep -r STRING *
diff -ur DIR1 DIR2
這兩個指令很好用。但是遇到 Subversion 的 working copy 時,就會受到 .svn 目錄的干擾。所幸這兩個指令都提供排除非必要目錄的方法:
grep --exclude-dir=.svn -r STRING *
diff -x .svn -ur DIR1 DIR2

老實說,常會忘記這些參數,也常弄混。因此建議在 .bashrc 當中加上以下設定,這樣以後不管是不是 working copy 都可以安心使用 grep -r 和 diff -r 了:
alias grep='grep --exclude-dir=.svn'
alias diff='diff -x .svn'

2009/02/02

在 64-bit Ubuntu 上安裝 32-bit 的 package

使用 64-bit Ubuntu 時,經常會遇到一個問題:某些外部 package 只提供 32-bit 的版本 (i386),而沒有 64-bit 的版本 (amd64),例如:Adobe Reader 和 Skype 等。

解決方法很簡單,加上 --force-architecture 參數即可:
  • sudo dpkg -i --force-architecture AdobeReader_cht-8.1.3-1.i386.deb
  • sudo dpkg -i --force-architecture skype-debian_2.0.0.72-1_i386.deb

2009/01/15

好康推薦:PrintWhatYouLike.com

網路世界的資源非常豐富,但不一定長久。不管是書籤還是最愛,留下 URL 並不能保證將來你還可以再找到相同的資料。所以,當發現有些值得保存的資料時,我會想辦法留下副本。

另存新檔?詳實用 HTML 紀錄原始的資料,但垃圾多又不方便管理。所以我習慣輸出成 PDF 文件。不過網頁上通常充斥廣告等不相干的內容,令人想去之而後快。還好,Firefox 有許多外掛程式提供這類編輯網頁的功能,如:Nuke Anything EnhancedPage Hacker 等。

這次要推薦的不是以上那些 extension,而是一個有同樣功能的服務網站:
透過這個網站,編修網頁更加容易上手。當然,缺點就是不是所有的網頁都可以利用這項服務,例如公司內部網站。如果,printwhatyoulike 能夠改寫成 extension,那就是太完美了。

Firefox 的 PDFescape Extension

唉... 可能寫筆記不夠用心,竟然跟上時代潮流放起無薪假來了。趁著悠閒,上網看看 Firefox 有什麼新鮮的外掛程式可用,發現 PDFescape 是蠻有意思的服務。

裝上這個 extension 之後,你可以將網路上的 PDF 文件送到 http://www.pdfescape.com 作線上編輯,如:用空白蓋掉原有的內容、加上新的文字和簡易的方圓等圖形,甚至可以加上文字輸入方塊和 checkbox 等。等改好之後,就可以下載這份修改過的文件。

我想到一個使用場合。有時我們必須下載 PDF 格式的表格,印出、填寫然後拿去申請任何東東。有了這服務,寫字難看的我就可以先加工過再印出來,頂多留下簽名欄位就可以了。

我承認用到的場合不多,所以我不會安裝這個 extension。因此隨手記下,以備將來之需...

2009/01/13

使用 vim 和 cscope 來 trace 程式碼

Vim 是個很實用的程式編寫工具,不過一開始需要花點心力走過學習曲線。有興趣的人可以在網路上找找學習教材;如果你已經有點基礎但記不清按鍵,以下這個網址提供相當有系統的整理,依照功能分成七個自學課程,很值得一看:
除了編寫程式,Vim 用來追溯程式 (trace code) 也相當好用。例如,先將游標移到程式的某個文字串,再按以下按鍵:
  • '*' 往前找出此文字串 (按 n、N 繼續找)
  • '#' 往後找出此文字串 (按 n、N 繼續找)
  • 'gd' 將此文字串視為 local 變數,找到定義此 local 變數的地方 (如果有的話)
其他追溯程式常見的動作:
  • '%' 找到被配的括號
  • '[[' 找到函數的開頭
  • ']]' 找到下一個函數的開頭
當你維護的軟體專案不小時,上述功能絕對不夠用。這時你需要 cscope 的協助。當你安裝好 cscope,而且建立好專案的 cscope 資料庫之後,將游標移到程式當中某個文字串,按 Ctrl+\ 再按以下按鍵:
  • 's': 即 Symbol,以此文字串當識別字,列出專案當中所有參考到此識別字的地方,包含定義和引用
  • 'g': 即 Global,以此文字串當作 global 變數或函數的名稱,跳到專案中定義此 global 變數或函數的地方 (這個功能有另一個與 ctags 相同的快速鍵 Ctrl-])
  • 'c': 即 Calls,以此文字串當函數名稱,找出所有呼叫到的此函數的函數
  • 't': 即 Text,列出專案中所有出現此文字串的地方 (包含註解)
  • 'e': 即 Egrep,以此文字串當 regular expression,用 egrep 方式來搜尋
  • 'f': 即 File,以此文字串當檔案名稱,開啟此檔案
  • 'i': 即 Includes,以此文字串當 header 檔名稱,列出所有 include 此檔案的檔案
  • 'd': 即 calleD,以此文字串當函數名稱,列出此函數所呼叫到的函數
上述指令若是列出相關程式碼,你可以輸入數字加 Enter 來跳到該檔案的相對位置。按 Ctrl-T 就會回到游標原來的檔案和位置。你也可以用以下的方式來輸入指令 (foo 就是搜尋的文字串):
  • :cscope find symbol foo
  • :cs f s foo
安裝 cscope 的方法:
sudo apt-get install cscope
mkdir -p ~/.vim/plugin
cd ~/.vim/plugin
wget http://cscope.sourceforge.net/cscope_maps.vim
建立及更新軟體專案 cscope 資料庫的簡單方法如下 (其他更複雜的用法請參考 http://cscope.sourceforge.net):
cd PROJECT
cscope -bR

2009/01/07

Ubuntu 存放 icon 的位置

這絕對是一件小事,但每次都記不得,所以決定寫下來:Ubuntu 存放 icon 的主要目錄是 /usr/share/pixmaps。當你在面板上加入自訂的程式啟動圖示時,常常會需要到這個目錄找應用程式的圖示。