代码之家  ›  专栏  ›  技术社区  ›  Franck Freiburger

将SVN修订版转换为整数的C宏

  •  1
  • Franck Freiburger  · 技术社区  · 15 年前

    我正在寻找一个C/C++宏,它可以将一个随机的VSN修订像“$修订:9美元”或“$修订:9999999美元”转换成一个整数或一个字符串。

    我知道有简单的函数可以实现这一点,但我希望在编译时实现这一点。

    我的愿望是写一些东西,比如: unsigned int rev = SVN_TO_INT("$Revision$");

    7 回复  |  直到 15 年前
        1
  •  6
  •   Dan    15 年前

    我同意在编译时不能通过宏或模板使用字符串。所以…不要使用字符串。

    这是一个丑陋的黑客,但我认为它符合你的所有要求。我不推荐。

    #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
    
        2
  •  2
  •   Collin Dauphinee    15 年前

    我相对确定用宏是不可能的。

    使用模板元编程可能是可能的,但我从未接近过它。

    也可以使用预构建脚本,用所需的文本替换svn-to-int。

    不过,我不明白您为什么要这样做,因为硬编码版本号和编译时知道的版本号一样容易。

        3
  •  2
  •   Michael Burr    15 年前

    在编译时,您不能用C预处理器(宏)或模板(C++)来进行字符串操作。您需要使用一个外部实用程序或脚本,您可以从构建过程中调用它。

    一些实用程序/脚本/代码可能会帮助您:

        4
  •  2
  •   TheLion    13 年前

    我的解决方案是

    #define $Revision (false?1
    #define $ +0)
    
    int codeRevision() { return $Revision: $; }
    
    #undef $Revision
    #undef $
    
        5
  •  1
  •   Georg Fritzsche    15 年前

    您不能在预处理或编译时完全处理字符串,但为什么不使用类似以下的内容:

    int svn_version() 
    {
         static const int v = extract_svn_version(REVISION);
         return v;
    }
    
        6
  •  1
  •   Franck Freiburger    15 年前

    我同意宏是不可行的,但是,我发现了一个使用编译器优化的技巧。 结果是,表达式jl_svnrevpoint(“$revision: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)))))))));
    }
    

    它支持9位修订号、空值和“$revision$”字符串。

        7
  •  1
  •   epatel    15 年前

    如果你有 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