Category: Programming

  • 以 boost::posix_time 處理時間字串

    其實標題並不是那麼準確,這點我們之後再談。 其實起源很簡單,我們常常需要從各式各樣的時間字串轉成 time_t 或者 struct tm,要不然還可能是 FILETIME 跟 SYSTEMTIME 之類的結構。個人覺得 parsing 時間是一件難搞的事情,尤其是當你還要考慮 timezone 的影響,一切都變得不是那麼簡單了。 首先我必須要說,在 Windows 中沒有 strptime(3) 這樣還算好用的東西可以用,所以我又把腦袋動到 boost 上面去了。 我的目標是正確的處理「Sat, 28 Mar 2009 20:18:32 +0800」這樣的字串,然後把他轉成 time_t。我們會分兩個部份處理,首先我們先處理「Sat, 28 Mar 2009 20:18:32」這個部份,因為目前的 %q 只能處理輸出部份,請參考 Date Time Formatter/Parser Objects。 這樣的確很簡單吧,只要按照文件寫的把 format 寫好,boost 就能幫你從 stringstream 的字串轉成 posix_time。 而 timezone 的部份就需要噁心一點的作法了。 我利用 setw 分別把 timezone 的小時與分抓出來,並轉成 time_duration,讓 posix_time…

  • 初探 TR1 function object

    最近的專案常常需要更新 INI 設定檔,而最麻煩的事情莫過於太多零散的設定,你必須要記住 INI 檔設定的 key,再把在某個 object 的 member function 把值抓出來,最後再丟給 WritePrivateProfileString 之類的 function 把值更新進檔案。 所以常常就會寫出一堆噁心的 code 像是。 obj.iniKey = “INI_SERVER”; obj.iniValue = info.GetServer(); UpdateByObj(obj); 這樣的話,有幾個設定就要寫幾次,所有的 Key 跟 Value 的相關性都顯得零散,未來要加上新的設定,也非得要再加上類似的 code 才行……。 忽然我就靈機一動,也許可以用 tr1::function 跟 tr1::bind 來做這樣的事情。 struct proxyConfig { std::string iniKey; std::tr1::function<std::string()> func; }; const proxyConfig configArray [] = { { “INI_SERVER”, std::tr1::bind(&proxyInfo::GetServer, &info)…

  • C++ Format String using boost::format

    如果你只想寫純粹的 C,那你可以忽略這篇的資訊了,因為 sprintf 之類的 function 大概就可以滿足你了。那為什麼還要提到 C++?我想 C++ 的 string 對於程式設計者是美好的,因為我們不用擔心 buffer 到底需要多長,我們可能是無腦的利用 operator += 去操作這個字串,並利用提供的 substring 等 function 快速的開發軟體。 但在我甚少的 C++ 開發經驗中,我總覺得透過 operator += 以及 stringstream 等東西,並沒有辦法像 sprintf 那樣直覺而優雅的將變數置換至字串當中。 就以 Windows 常見的 INI 格式來說,我們如果要輸出一個 AppName,像是 [MyApp],可能的作法是 這似乎比傳統的 sprintf 要顯得複雜的多,也顯得不好閱讀…… 現在你可以考慮 boost::format 讓你寫的 C++ 能有 sprintf 的優雅性,又不必太過於擔心 buffer 的操作。 至於一些 manipulators,與詳細的 formatting 的用法,就請你自己去看一下官方的說明吧。此外,我覺得 python 的…

  • 使用 sysexits.h 定義的 EX_ 變數

    以前我們常常在程式裡面直接呼叫 exit, 並搭配一個自己「想要」的變數作為程式的 return code,像是 exit(-1) 這樣的壞處是,我們不知道 0 代表什麼,-1 又代表什麼,這樣一來可讀性也會顯得比較差了一點。今天在無意之間看到 FreeBSD 的 lockf,他使用了 sysexits(3),在這邊節錄一下 man page 的敘述。 According to style(9), it is not a good practice to call exit(3) with arbitrary values to indicate a failure condition when ending a program. Instead, the pre-defined exit codes from sysexits should be used, so the caller of…

  • 用 mkdir 確保 shell script 執行的互斥性

    有些時候,你不希望一個 script 同時有兩個以上的 instance,這個時候你可能有很多想法,例如利用檢查 pid file 的方法,或者是找一個 lockf(1) 之類的程式幫你處理這些事情。(老實說 FreeBSD 的 lockf(1) 的確蠻方便的,尤其是對於懶惰寫 code 的我來說。) 但是這會有另外一個問題,不是每個 OS 都有提供 lockf(1),有些就只給你 lockf(2)。所以我就得換個方法作,首先,我想到這樣的寫法 if [ -f $lockfile] ; then touch $lockfile 利用一個 lockfile 來確保互斥性,只不過 -f 與 touch 之間還是有機會產生 race condition。結果在讀了一些文章之後,我發現有人說 mkdir(2) 是 atomic 的(我目前還沒有找到什麼佐證的資料,NFS 就先放一旁吧……),也有人就用 mkdir(1) 來確保同時只會有一個 shell script 的 instance,再搭配 trap 來處理一些 signal,這樣似乎就可以暫時取代 lockf 了……。 最後的版本就像這樣,應該還有很多問題,但先這樣吧。 ToLock()…

  • 你今天 static code analysis 了嗎?

    最近才稍微看了一下手邊專案的程式碼,不能說有什麼太多的問題,只是就制度面而言,其實還有更多可以改善的地方。 公司以往的作法是這樣,你先 check-in code,然後等到一個禮拜的 static code analysis 再進行全面性的更正。但我想 check-in 之後的 static code analysis 只能說是最後一道防線,在這之前,就只能端看開發者的自由心證。 所以,如果要等公司的工具告訴你問題之前,為什麼不先想辦法先作一次呢?自己先作一次有幾點好處。 確保 check-in 的 code 跑出來的 unit test 結果正確,降低事後修正造成的副作用 減少 submit log 上太多與 feature 無關的 log(例如 strcpy fixing) 而現有的 static code analysis 的工具你可以參考 List of tools for static code analysis 然後選擇用的順手的一個,以 C/C++ 而言,我剛剛稍微玩了一下 RATS 和 flawfinder,他們的確能夠提供一些有用的資訊,像是不該使用 gets,或是使用 strcpy 會造成的危險他都能一一列出。 然而 static…

  • HTML Form 中 disabled 的元件

    HTML Form 中 disabled 的元件的值不會被送出去阿 XDDDDD http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1是這樣說的: In this example, the INPUT element is disabled. Therefore, it cannot receive user input nor will its value be submitted with the form. 然後抱怨一下,不是這樣無聲無息地把 exception 吃掉吧,這樣 debug 很困難的……。

  • EQATEC Profiler – Compact Framework Code Profiler

    雖然大概三年左右沒寫 .NET Compact Framework 的東西,不過偶爾會看一下那方面的消息。 之前有大概搜尋一下 Windows Mobile 上的 native code profiler,那些 profiler 通常不是要錢,要不然就是很難用。不過剛剛看到這篇 Compact Framework Code Profiler,對於用 .NET Compact Framework 開發程式的人而言,好的 profile 往往是找出效能瓶頸的救星,而且他居然不用錢,這還能要求什麼呢? EQATEC Profiler

  • The global statement in python

    寫 code 時候踩到地雷,果然沒唸好 scope 果然是不行的 #!/usr/bin/env python flag = True def test(): flag = False print flag test() print flag 結果似乎和想的不太一樣。 # python 2.py True True 結果翻了一下 The global statement 才知道 It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

  • 工作之外更需要學習

    星富哥說工作的本身會榨乾一個人的活力,但我覺得工作之於我,工作並不是榨乾我的能力,而是太多瑣碎的事物使我無法更專注地學習。我好像能夠看見幾年後的自己,若是繼續維持這樣的生活下去,我就只是這樣而已,沒有進步,雖然經歷過幾個專案,或是幾個產品,我技術上是沒有進步的。 不過也因為現在的工作必須廣泛閱讀一些東西,像是我選修的一門課在探討跨平台的程式開發,讓與會的每個人分享閱讀 Cross-Platform Development in C++: Building Mac OS X, Linux, and Windows Applications 這本書,原本我想選關於 XUL 還有 XPCOM 的主題,結果這兩個主題很快就被我同事選走了。我最後因緣際會選了 Install 的章節,昨天在捷運上翻了一下,也包含許許多多有趣的主題,像是 XPInstall、NSIS。 結果這本書講了很多,Tinderbox、Autotools、wxWidgets 也許還有 CMake、GNUstep 等等的東西,但是這些東西在工作上都不見得會出現,工作常常是需要解決舊有產品的問題,這些有趣的東西就只能留待下班之後,或是假日時間。我會希望自己能好好的學習,像是工作需要學習的 python,我也能必須更廣泛的閱讀,思考是不是有更好的解決方案。否則我只是快速的解決一個問題,而並非創造。 我想這是我所需要的,所以我選擇在工作之餘再進行學習,一方面是興趣,一方面也是想不要太快被取代吧。 p.s. Learning Python Design Patterns Through Video Lectures