星期五, 10月 15, 2010

vim的path option

在vim中在一個檔案名稱下使用gf就可以跳進至該檔案編輯。特別是在寫C的時候,要找一些header file的定義時特別方便。vim中使用了path option來決定按下gf時要搜尋哪些路徑。因此,所謂path option基本上就是一個目錄清單。

:set path=.,/usr/include,,
此例中可看到目錄可以是相對路徑,也可以是絕對路徑。各個目錄之間以逗號相間隔。

由於目錄的階層就是一個目錄樹的結構滿,搜尋檔案可以
往下搜尋(更深層)
在path中使用*或**。

*映射到檔名,而**映射到目錄。
**後面可以加數字代表最多要往下幾層
例如: /usr/**2對映到
/usr
/usr/include
/usr/include/sys
/usr/include/g++
/usr/lib
/usr/lib/x11
但不會對映到/usr/include/g++/std因為std是往下三層了。

**可以用在路徑的中間或是路徑的最後
*和**合併使用的範例
/usr/**/sys/*
/usr/*tory/sys/**
/usr/**2/sys/*

也可以往上搜尋(往上,最上層是根目錄)
 (待續...)

星期四, 10月 14, 2010

pyhton的argc與argv

如果用C寫一般的命令列工具,常透過main函式的argc,argv來取得使用者所輸入的命令參數。
int main(int argc, char *argv)
{
...
}

那麼在python中要作同樣的事該怎麼作呢?

第一,python是一個script language,所以沒有像C語言一樣規定程式執行的起點一定是main(),要作到同樣的事python裡面可以這樣寫
if __name__=='__main__':
   ...傳統上main()要作的事寫在這裡
   ...
第二,還需要知道從何處取得像C一樣定義的argc/argv。
在python中我們需要引入sys模組,並由sys.argv來取得命令列參數項

以下列程式為例,若我們在命令列上執行
$ python test.py 1 2 3 4 5
執行結果為
['test.py', '1', '2', '3', '4', '5']

test.py的內容如下
import sys

if __name__:'__main__':
  print sys.argv

至於C中的argc,在python中可由len(sys.argv)取得。

星期二, 10月 05, 2010

python struct

Python standard library中提供了一個struct模組,主要用來讀取二進制檔案的資料,按照C語言的data type讀出。
主要使用的方式是建立一個格式化字串,這個格式化字串用來描述所要讀取之資料。
下表描述格式化字串所使用的符號。
http://docs.python.org/library/struct.html

Format C Type Python type Standard size Notes
x pad byte no value
c char string of length 1 1
b signed char integer 1 (3)
B unsigned char integer 1 (3)
? _Bool bool 1 (1)
h short integer 2 (3)
H unsigned short integer 2 (3)
i int integer 4 (3)
I unsigned int integer 4 (3)
l long integer 4 (3)
L unsigned long integer 4 (3)
q long long integer 8 (2), (3)
Q unsigned long long integer 8 (2), (3)
f float float 4 (4)
d double float 8 (4)
s char[] string
p char[] string
P void * integer (5), (3)

例如我們有一個二進制檔案裡面是四個1byte的資料和一個4 byte的unsigned integer。則格式化字串可寫成"BBBBI" ,連續四個B也可以寫成4B,因此格式化字串也可寫成"4BI"

ps 格式化字串中符號間的空白會省略

另外,存放在檔案中的資料會有byte ordering的問題,因此格式化字串的第一個符號必需指出所要讀取之資料的byte order為何。參見下表。
Character Byte order Size Alignment
@ native native native
= native standard none
< little-endian standard none
> big-endian standard none
! network (= big-endian) standard none
若沒有寫第一個符號(如上例)則預設為native。"4BI"就是"@4BI"。

有了格式化字串之後,可使用struct.calcsize(fmt)將格式化字串帶入取得格式化字串所代表的資料量大小。此例:struct.calcsize("@4BI")回傳值為。

一旦格式化字串準備好,便可以使用struct.pack跟struct.unpack函式來操作。
struct.pack(fmt,v1,v2,...)
此函式第一個參數fmt為格式化字串,其後對應於格式化字串接著各個參數,回傳值即為根據格化字串及所帶的參數所產生的二進制字串。
struct.unpack(fmt,string)
此函式第一個參數fmt為格式化字串,其後是一個二進制字串(或者說是一個byte stream),回傳值即為根據格化字串將二進制字串解開,解成一個個不同的資料單位。

例:
>>> a = struct.pack("4BI",1,2,3,4,5)
>>> a
'\x01\x02\x03\x04\x05\x00\x00\x00'
>>> struct.unpack("4BI",a)
(1, 2, 3, 4, 5)

另外,格式化字串中使用s時,放在s前頭的數字代表這個char []的大小。
例如16s代表一個char [16]的空間。

星期一, 10月 04, 2010

該是動筆寫點東西了

兩年過去,這個blog最後一篇文章的時間還停在2008年七月。
這兩年真的是非常的忙碌啊!
該是在提筆寫點東西了...