2009-12-02 41 views
1

我正在尋找一個C/C++宏,它可以將一個隨機的SVN版本(如「$ Revision:9 $」或「$ Revision:9999999 $」)轉換爲整數或串。C宏將SVN修訂版本轉換爲整數

我知道存在簡單的函數來實現這一點,但我希望這是在編譯時進行的。

我的願望是寫的東西,如:unsigned int rev = SVN_TO_INT("$Revision$");

+0

與編譯器的好處是,他們實際上可以用所得到的值替換函數調用,如果你只使用編譯時間常數。當我想比較幾種交換價值的方式時,VC曾經這樣做過;生成的彙編代碼(帶/ O2)根本不包含任何函數調用;只有常數。 – Joey 2009-12-02 14:59:44

+2

如果您想自動將修訂號嵌入到可執行文件中,我認爲您的路徑錯誤,因爲通過svn關鍵字嵌入的修訂版號僅在提交*修改的文件*時纔會更改。因此,您無法確定帶有SVN_TO_INT宏的文件將始終反映您項目的修訂版。 – 2009-12-02 15:11:10

+0

我同意你的評論,但是,每個文件修訂版本系統適合我的使用(每個文件一個類和每個類一個修訂版) – 2009-12-02 15:37:03

回答

1

我同意它不可用宏,但是,我發現使用編譯器優化技巧。 其結果是,表達JL_SvnRevToInt(「$修訂:12345 $」)被降低到一個單一的無符號整數:12345

inline unsigned int JL_SvnRevToInt(const char *r) { 


    if (r == NULL || r[0] == '\0' || r[10] == '\0' || r[11] == '\0' || r[12] == '\0' || r[13] == '\0') 
    return 0; 

    const unsigned int count = 
      r[11] == ' ' ? 1 
     : r[12] == ' ' ? 10 
     : r[13] == ' ' ? 100 
     : r[14] == ' ' ? 1000 
     : r[15] == ' ' ? 10000 
     : r[16] == ' ' ? 100000 
     : r[17] == ' ' ? 1000000 
     : r[18] == ' ' ? 10000000 
     : r[19] == ' ' ? 100000000 
     : 0; 

    return 
     (r[11] == ' ' ? 0 : (r[11]-'0') * (count/10) + 
     (r[12] == ' ' ? 0 : (r[12]-'0') * (count/100) + 
     (r[13] == ' ' ? 0 : (r[13]-'0') * (count/1000) + 
     (r[14] == ' ' ? 0 : (r[14]-'0') * (count/10000) + 
     (r[15] == ' ' ? 0 : (r[15]-'0') * (count/100000) + 
     (r[16] == ' ' ? 0 : (r[16]-'0') * (count/1000000) + 
     (r[17] == ' ' ? 0 : (r[17]-'0') * (count/10000000) + 
     (r[18] == ' ' ? 0 : (r[18]-'0') * (count/100000000) + 
     (r[19] == ' ' ? 0 : (r[19]-'0') * (count/1000000000) + 
     0))))))))); 
} 

它supports9位修訂號,NULL和空和「$修訂$」的字符串。

2

我是比較肯定,這是不可能的宏。

模板metaprogramming可能是可能的,但我從來沒有走近它。

也可以使用預編譯腳本將預期文本替換爲SVN_TO_INT。

雖然我不明白你爲什麼要這樣做,因爲在編譯時知道它的版本號會很容易。

+0

是的,但每次都改變它是一種痛苦:) – Jacob 2009-12-02 15:02:44

+2

你實際上可以破解一起在makefile中運行的腳本,並將-DSVN_REVISION = 89278放入命令行。 – Joey 2009-12-02 15:09:03

+1

+1基本上是「爲什麼如果你可以在編譯之前做到這一點」,我只是想着想。 – 2009-12-02 15:23:17

1

你不能完全在預處理處理字符串或編譯的時間 - 但爲什麼不使用的東西是這樣的:

int svn_version() 
{ 
    static const int v = extract_svn_version(REVISION); 
    return v; 
} 
+0

我想避免將修訂字符串存儲在我的二進制文件(「$ Revision:XXXX $」)中 – 2009-12-02 15:28:21

+0

然後,您必須在源代碼之外完成並在構建環境中對其進行定義 - 即使在C++ 0x似乎有編譯時字符串處理(在此之前沒有),我想仍然不能保證字符串文字將從二進制中消除 - 編譯器可能會或可能不會這樣做。 – 2009-12-02 15:32:40

+2

爲什麼你不需要它在你的二進制文件?我們曾經使用過(在CVS中),我們可以在二進制文件中找到構建信息。一旦二進制文件發送給客戶,我們無法控制他們去哪裏,並且知道某個客戶系統運行的版本有時是非常有用的。 – 2009-12-02 16:03:28

6

我同意,你不能在編譯字符串工作時間通過宏或模板。所以....不要使用字符串。

這是一個醜陋的黑客,但我認爲它滿足您的所有要求。我不推薦它。

#define $Revision struct REV_STR { unsigned foo 
#define $ * 64; }; 

$Revision: 4521 $ 

enum { REV = sizeof(REV_STR)/8 }; 

#undef $Revision 
#undef $ 

#include <iostream> 
int main() 
{ 
    std::cout << REV << std::endl; 
    return 0; 
} 

// $ g++ -Wall -Wextra revision.cpp && ./a.exe 
// revision.cpp:4: warning: width of `REV_STR::foo' exceeds its type 
// 4521 
+6

這真是令人厭惡,我向你致敬! – caf 2009-12-02 21:30:08

+0

尊重! 我喜歡它! 雖然我會建議任何人反對寫任何類似的東西。 – dudico 2010-02-15 07:18:48

1

如果您有基於makefile的構建系統,您可以制定一個特殊規則,每make時間創建一個文件。

.PHONY: svn_revision.c 

svn_revision.c: 
     echo -n "int svn_revision = " > svn_revision.c 
     svn info | grep Revision | cut -f2 -d" " >> svn_revision.c 
     echo ";" >> svn_revision.c 

svn_revision.o: svn_revision.c 
2

我的解決辦法是

#define $Revision (false?1 
#define $ +0) 

int codeRevision() { return $Revision: $; } 

#undef $Revision 
#undef $