预处理器

问题描述 投票:5回答:9

我想拥有一个C预处理程序,它可以从源代码中过滤一些#define语句,而无需进行其他任何更改。

为什么?如果将源移交给另一个客户端,则应该使用此方法从源中删除一些客户端特定的代码。

有人知道现有解决方案吗?

谢谢!西蒙

c preprocessor filtering
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;
    }

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


2
投票

这听起来像我在Is there a C pre-processor which eliminates ifdef blocks based on values defined中的要求。我得到的最佳答案是sunifdef,或“ unifdef的儿子”,它对我来说确实适用于某些过度扭曲的条件代码(过去20年来在各种平台上开发的积累成果,但对理论的理解不足。如何进行特定于平台的编译)。


1
投票

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


1
投票

我会将客户特定的代码放在一个单独的目录中,或者放置在另一个需要从源代码管理中检出的不同项目的一部分中。

放置将被存根或松散链接的函数调用,以便可以将另一个函数放在它的位置。


0
投票

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

gcc <insert files here> -E

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

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

grep -r '#define CLIENT_CODE' ./*.h 

0
投票

您还可以尝试比sunifdef更简单的unifdef


0
投票

为什么不做类似的事情:

client_specific_functions_declaration.h

double discount_for_paying_upfront();
// ...

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 };
// ...

然后,当您为客户端A编译代码时,您将编译client_a_specific_functions_definition.c,对于客户端B则编译了client_b_specific_functions_definition.c。分发代码时,只需选择具有特定定义的正确文件即可。


-2
投票

据我所知...预处理程序可以作为单独的步骤运行(使用正确的编译器optios)。这样,您可以对处理后的代码进行任何操作。

© www.soinside.com 2019 - 2024. All rights reserved.