差不多在幾個月前開始,用 TortoiseSVN 時,若程式裡有放 expansion keywords 的話,$Date$ 會被改成用 zh_TW.UTF-8 顯示。由於 C/C++ standard 規定,程式碼裡只應該使用 ASCII 碼,所以使用中文顯示 $Date$,會違反 C/C++ standard 規定。果不其然,上禮拜我就碰到了。為了要把程式移轉過去,測一測 Visual Studio .Net 2005,結果一編譯,洋洋灑灑跑出三百多個 warning,仔細一看,通通都是一樣的 warning:

warning C4819: The file contains a character that cannot be represented in the current code page (950). Save the file in Unicode format to prevent data loss    j:\wc\libmmi2\src\mmi2\mmi2.assert.cpp    1   

這可真是天大的麻煩啊,一個檔案就跑一個 warning 出來,project 一大,還真累人。所以我只好乖乖地去 Subversion/TortoiseSVN 的 issue tracking system 找,結果找到這個:

Subversion Issue 2332: Keyword expansion in non-UTF8 documents results in mixed charsets (另外注意一下這串 mailing list 的討論。)

簡單講就是,subversion 在代換 keyword 的時候,強制使用 <lang>.UTF-8 的格式輸出了。這確實是個 bug。按照目前的 locale 設定,輸出 keywords 是絕對要做的方法之一,但還是會有需要強制設定 locale 的情境。而問題就出在,該如何設定個別檔案的 locale 值。Max Bowsher 提出使用 svn:mime-type 設定 charset,就像正常的 mime-type 那樣的設法。不過 Peter N. Lundblad 認為 svn:mime-type 的值在很多地方都有被用到,就這麼更改其格式,也許會造成其他問題。所以結論是,目前這個問題算是被 pending 住了,神佛不理,那就只好自助了。

在 UNIX 下我是簡單地把 LC_TIME 設成 en_US.8859-1,反正如 ls 之類的 output,我也習慣看英文版。但在 Windows 下,設 LC_TIME 環境變數沒用 (我在 tcsh-win32 下測的)。另外,對於 C/C++ 而言,standard 規定只有 locale "C" 的 character 可以用在 source file 裡,所以依據目前 locale 設定,也不對。使用 property 規定 locale 這個方法是可以解,但缺了 repository-defined autoprops 就是不好用。也許我該來寫個 hook script 暫時擋一擋,以便強制使用正確的 svn:mime-typesvn:keywords 設定?

2008-05-13 更新:

可以以下面兩種方法,任取其一,來迴避這個問題:

  • 將程式碼存成 Unicode,並加上正確的 BOM[1]
  • 於專案屬性頁裡的 C/C++ » Advanced » Disable specific warnings,加上 C4819。

 


  1. 不過 b6s 卻說:「VS IDE 在存檔時卻又會把 BOM 拿掉。