5

我想要一个 C 预处理器,它从源代码中过滤一些#define 语句而不改变任何其他内容。

为什么?如果源被分发给另一个客户端,这应该用于从源中删除一些客户端特定的代码。

有谁知道现有的解决方案?

谢谢!西蒙

4

9 回答 9

9

您可以使用 awk 代替 CPP 之类的东西吗?在代码中围绕要删除的代码添加一些标志。例如:

(...)
//BEGIN_REMOVE_THIS_CODE

printf("secret code");

//END_REMOVE_THIS_CODE
(...)

然后编写一个 awk 脚本来删除此代码,例如...

BEGIN { write=1;}
/^\/\/BEGIN_REMOVE_THIS_CODE/ { write=0; next;}
/^\/\/END_REMOVE_THIS_CODE/ { write=1; next;}
    {
    if(write==1) print $0;
    }
于 2009-09-15T11:12:29.367 回答
2

我建议使用额外的宏语言层进行代码过滤,例如filepp。您可以使用 C 预处理器友好的语法来表达哪些部分属于哪些客户端。

//%ifdef CLIENT_A
  code for client A
//%endif

//%ifdef CLIENT_B
  code for client B
//%endif

//%if "CLIENT_A" || "CLIENT_B"
  code for client A and B
//%endif

'//%' 前缀使您能够编译未修改的代码。您可以在将代码分发给客户端之前运行filepp 。

于 2009-09-15T13:19:03.540 回答
2

这听起来像是我在Is there a C pre-processor which 根据 values defined 消除 ifdef 块。我得到的最佳答案是sunifdef,或“unifdef 之子”,它在一些过度扭曲的条件代码上可靠地为我工作(在各种平台上进行了 20 多年的开发积累的杂物,但关于如何做的理论不足平台特定的编译)。

于 2009-09-15T14:04:16.853 回答
1

我认为您不需要为此使用预处理器。如果您的代码中没有嵌套#ifdef's,则任何正则表达式引擎都可以删除位于#ifdef CLIENTand之间的任何内容#endif(使用非贪婪匹配来匹配 first #endif,而不是 last )。

于 2009-09-15T11:11:14.483 回答
1

我会将客户端特定的代码放在单独的目录中,或者可能是需要从源代码管理中签出的不同项目的一部分。

放置一个函数调用,该函数调用将被存根或(我忘记了正确的术语)松散链接,以便可以将另一个函数放置在它的位置。

于 2009-09-15T12:43:47.420 回答
0

如果您使用的是 gcc,那么您可以使用:

gcc <insert files here> -E

-E 选项告诉 gcc 只预处理源,而不是编译它们。

或者,您可以使用 grep 过滤掉特定文件,让预处理器只对它们进行处理。

grep -r '#define CLIENT_CODE' ./*.h 
于 2009-09-15T11:11:53.640 回答
0

您也可以尝试unifdef,它比 sunifdef 更简单。

于 2010-01-18T21:09:48.757 回答
0

你为什么不做类似的事情:

client_a_specific_functions_definition.c

double discount_for_paying_upfront() { return 0.1; };
// ...

client_b_specific_functions_definition.c

double discount_for_paying_upfront() { return 0.05; };
// ...

当您分发代码时,只需选择具有特定定义的正确文件即可。

然后,您将创建一个头文件以将其包含在您需要访问客户端特定代码的位置,例如:

client_functions.h

#pragma once 

double discount_for_paying_upfront();

#define stringify(x) #x
#define FILE2(a) stringify(client_##a##_specific_functions_definition.c)
#define FILE(a) FILE2(a)

#include FILE(CLIENT_NAME)

#undef stringify
#undef FILE2
#undef FILE

然后#include "client_functions.h"在你的main.c. 你可以编译它:

 gcc -DCLIENT_NAME=a main.c -o a.exe
 gcc -DCLIENT_NAME=b main.c -o b.exe
于 2019-10-28T14:41:19.087 回答
-2

据我所知......预处理器可以作为一个单独的步骤运行(使用正确的编译器选项)。这样你就可以对处理后的代码做任何你想做的事情。

于 2009-09-15T11:12:43.423 回答