JeffHung.Blog

(My smile insists of having nose. :-)

再探 wcfind -- 用 find2perl 實作

本系列目前有四篇文章,建議依照以下順序閱讀:

wcfind - avoid find(1) into subversion meta directories
use grep(1) accompany with my wcfind via xargs(1)
Setting svn:keywords in many files simultaneously
再探 wcfind — 用 find2perl 實作

由於 CVS、Subversion 這類的 version control systems,通常會在 working copy 目錄下,建立如 CVS/、.svn/ 的 meta directories,使得一些 command-line 工具會水土不服。例如,grep 會連 .svn/ 目錄下的檔案都去尋找,不僅拖慢速度,更讓結果雜亂,難以使用。因此,很久以前,我參照了 Ben Reser 的作法,弄了一個 wcfind 給自己用。
可是,之前的 wcfind 是使用 Bourne Shell 實作,並依賴於 FreeBSD 下的 find [...]

Implementing dprintf() without __VA_ARGS__

本系列共有三篇文章,以及一篇補充資料,建議依照以下順序閱讀:

Race condition in C wrapper of mutex class (補充資料)
Implementing dprintf() with __VA_ARGS__
Implementing dprintf() without __VA_ARGS__
Implementing DFORMAT and DOUT (尚未完成)

在這篇《Implementing dprintf() with __VA_ARGS__》裡,簡介了如何利用 __VA_ARGS__ 做出好用的 dprintf(),以協助我們僅在測試版裡傾印偵錯訊息。然而,某些老舊但仍然十分活躍的 compilers,如 VC6,並沒有支援 __VA_ARGS__。因為通常來說,為了照顧既有的大量程式,以及一些政治問題,更換 compiler 有時是不可能的。所以我們最好還是來想想,怎樣在不支援 __VA_ARGS__ 的情況下,仍然將 dprintf() 實作出來。
仔細檢視 dprintf_v2() 與 dprintf_v3() 在 #define 時的差別,我們會發現,dprintf_v2() 其實並不是一個真正的 function-like macro,而僅僅只是把 dprintf_v2 這個「名字」給代換成 dprintf_v2_impl。於是,原本跟在後面,屬於 dprintf_v2 的參數,經過 preprocessor 處理之後,變成了跟在 dprintf_v2_impl 的後面。這樣的作法,除了之前提過的,在釋出版裡,剩下來的參數列,不一定有辦法被最佳化去掉之外,還有一個更大的問題就是,沒有辦法於呼叫 dprintf_v2() 時省略 __FILE__ [...]

Wrong %z in strftime() on Visual C++?

(這是一篇積存的舊文,原始發想時間大約在 2007 年,但精確的日子已不可考。)
這是怎樣,平均每個月可以遇到一個 VC6 的問題,真苦。XD
這次的問題出在 strftime() 這個標準 C 的函式。依據 C99,若傳進 strftime() 的 format specifier 有 %Z 或 %z 的話,分別應該被代換為:

%Z is replaced by the locale’s time zone name or abbreviation, or by no characters if no time zone is determinable. [tm_isdst]
%z is replaced by the offset from UTC in the ISO8601 format ‘‘-0430’’ (meaning 4 hours [...]

Detecting VC6 service pack version

Microsoft Visual C++ 6 (VC6) 是個歷史悠久的 compiler,自 1998 年推出之後,一直到了 2002 年,才有 Visual Studio .NET 2002 這個後繼版本推出。在這期間,Microsoft 一共推出了 6 個 service packs,以解決各種 VC6 的 bug。但在實務上,我們並沒有一個很方便的方法,可以得知目前灌在系統裡的 VC6,其 service pack 的版本為何:

從 VC6 選單的 Help > About Visual C++,我們只會看到簡單的「Visual C++R 6.0」的版本號。
從控制台的「變更或移除程式」,我們也只能看到「Microsoft Visual Studio 6.0 xxx Edition」的字樣。

能否弄清楚 patch 到那一版的 service pack,有時候非常重要。不同的 service pack 版本,小則編譯出來的程式執行效率不同,大則執行結果不同,這些差異,無法忽視。
根據 MSDN 的這篇《How To Tell That a [...]

Best font for programming is...?

(這是一篇自 2005 年開始撰寫[1],最近才補完的舊文,文中的連結可能已經失效,請見諒。)
在 moztw 看到這篇《你喜歡甚麼等距字型?》,在討論寫程式時,用什麼等距字型比較好。因為我很討厭 moztw 必須要註冊才能發表文章的政策,但這又是蠻有趣的議題,因此拉回來自己討論自己的。
在這篇《Finding the Best Programmer's Font》裡,n8f8 列出了他認為,寫程式用的字型,應該具備以下條件:

Crisp clear characters. (清晰)
Extended character-set. (延伸字元集)
Good use of whitespace. (妥善使用空白字元)
'l', '1' and 'i' are easily distinguished. (能夠清楚分辨大寫 l、數字 1 以及小寫 i).
'0', 'o' and 'O' are easily distinguished. (能夠清楚分辨數字 0、小寫 o 以及大寫 O).
Forward quotes from back quotes are easily distinguished -prefer mirrored appearance. (能夠清楚分辨 forward [...]

Google Map 的門牌查詢,也太爛了吧?

看到 Neo 在介紹 Wamap (挖地圖),想到還沒試過 Google Map 的中文門牌查詢,就試了一下,發現了驚人的笑果:

查「民族路30-9號」跑出「民族路16-9號」[1];
查「民族路30-9號14樓之3」跑出「民族路29巷3弄9號」。

感覺像是前端文字處理就爛掉了的樣子。
只看第一筆查詢,還可以解釋說是因為圖資不夠,所以演算法自動找「從地址來看最接近的地點」來顯示。但搭配第二筆查詢來看,很明顯就是前端文字處理爛掉了,樓層高度對這種地圖門牌查詢來說,並無意義,本來就應該先濾掉。但很明顯地,整個被攪和進去,結果跟第一筆的結果不同。
台廠有 UrMap 可以用,門牌查詢還蠻準的,雖然說路徑規劃太多結果,大部分都很莫名其妙,但也都至少有一、兩個是有用的。剛剛 h 君也推薦[2]了 Yahoo! 奇摩生活+地圖,試用了一下也很不錯。
我隱藏了完整測試地址,文中的地址片段也不是與我有關的地址。有興趣的人,可以拿自己家地址試試。 ↩利益揭露:h 君與 Yahoo! TW 有工作往來關係。 ↩

"mail".toUpperCase() 不等於 "MAIL"?

(這是一篇積存的舊文,文中的連結可能已經失效,請見諒。)
從這篇《Comment On Extra Sensitive Case Insensitivity》的 comments 裡,看到一段有趣的程式:

下面這段 Java 並非永遠回傳 true。

"mail".toUpperCase().equals("MAIL")
因為,在土耳其,"i" 的大寫不是 "I"。

不過因為我不懂土耳其文,所以無法驗證這個說法的正確性。

Sudo_root - prompt when needed in script

(這是一篇積存的舊文。)
Sudo 是個很好用的工具,讓我們可以盡可能地減少擁有 root 權限的時間,並隱藏 root 密碼,以提升系統安全性[1]。不過,當我們在使用 shell script,而 script 裡只有一小部分需要用到 root 權限時,卻通常是直接用 sudo 或 su 成 root 執行整個 script,讓 script 裡面大部分沒有需要 root 權限的地方,也獲得了 root 權限。如果,我們能夠善用 sudo,只在 script 裡真正需要 root 權限的地方,才切換成 root 身份執行,這樣應該可以降低 script 其他部分,對系統可能的危害。
最簡單的想法,就是在 script 裡,有需要 root 權限的指令前面,加上 sudo 就好了。由於 sudo 會記錄上一次執行的 time-stamp,因此就算我們加上 sudo 的指令,在一個跑上千次的迴圈裡面,我們也只需要輸入密碼一次。好比說:

#!/bin/sh
# backup all configuration files in /etc.
for i in /etc/*; do
[...]

我可不可以不要寫這種 code?

我可不可以不要寫這種 code?

#define NUM 5

int main()
{
FooParam param;
memset(&param, 0, sizeof(param));
param.size = sizeof(param);
param.num = NUM;
param.results = (FooResult**)malloc(NUM * sizeof(FooResult*));;
FooResult* results_body = (FooResult*)malloc(NUM * sizeof(FooResult));
for (int i = 0; i < [...]

Race condition in C wrapper of mutex class

本系列共有三篇文章,以及一篇補充資料,建議依照以下順序閱讀:

Race condition in C wrapper of mutex class (補充資料)
Implementing dprintf() with __VA_ARGS__
Implementing dprintf() without __VA_ARGS__
Implementing DFORMAT and DOUT (尚未完成)

最近[1]在寫 code 時發現了一個隱藏的 race condition,是因為 API 的 prototype 設計錯誤,造成 client code[2] 幾乎無可避免地會寫出 race condition 的程式。
原本的 API 設計
我們有套用 C++ 寫的 thread library,用起來很像 Boost.Thread[3],不過因為我們有許多 C code 也需要用到 thread 的功能,因此這個用 C++ 寫的 thread library,也有提供 C 的 API。
C++ 版 mutex 當然依照 RAII [...]

 Prev 1 2 3 4 5 6 7 8 ...17 18 19 Next