使用 perl 从文件中删除 #ifdef/#endif 的出现

Kyl*_*ade 1 perl xcode xcode4 xcode4.5

我有一个代码文件,其中包含一些我想在构建库后在头文件中删除的#ifdef。我的第一个想法是将其作为 XCode 可以运行的 perl 脚本来实现。虽然我当然可以打开头文件并将其所有内容读入 perl 中的字符串中,但我很好奇执行以下操作的最佳方法

  1. 查找任何出现的 #ifdef 示例

  2. 删除它以及以下 #endif 之间的任何内容

所以例子是:

int i;
NSString *someString;
#ifdef EXAMPLE
NSString *exampleString;
#endif
bool done;
Run Code Online (Sandbox Code Playgroud)

输出将是:

int i;
NSString *someString;
bool done;
Run Code Online (Sandbox Code Playgroud)

我正在考虑的选项:

  • 查找每个 #ifdef 示例的索引,并通过子字符串将其与下一个找到的 #endif 一起删除
  • 编写一个正则表达式,可以以某种方式消除这些情况。

考虑到我以前没有写过 Perl(Objective-C 是我的主要语言),我很好奇是否有 XCode 或 Perl 开发人员对最佳方法有任何建议

Sch*_*ern 5

我不确定你为什么要去掉 ifdefs,你可能可以使用 C 预处理器来做到这一点,但这是你在 Perl 中的做法,因为这意味着我可以使用触发器运算符。

首先是制作一个足够的正则表达式来匹配 ifdef。IIRC 它们可以缩进,并且 the#和单词之间可以有缩进。

#ifdef
#    ifdef
    #ifdef
Run Code Online (Sandbox Code Playgroud)

不确定最后一个是否有效,但无论如何我都会接受。

my $ifdef_re = qr{^\s*#\s*ifdef\b};
my $endif_re = qr{^\s*#\s*endif\b};
Run Code Online (Sandbox Code Playgroud)

如果只是删除#ifdef和之间的文本#endif,Perl 有很少使用的触发器标量..运算符

#!/usr/bin/env perl

use strict;
use warnings;

my $ifdef_re = qr{^\s*#\s*ifdef\b};
my $endif_re = qr{^\s*#\s*endif\b};

while(<DATA>) {
    my $in_ifdef = /$ifdef_re/ .. /$endif_re/;

    print if !$in_ifdef;
}

__DATA__
int i;
NSString *someString;
#ifdef EXAMPLE
NSString *exampleString;
#endif
bool done;
Run Code Online (Sandbox Code Playgroud)

但由于我们需要担心嵌套的 ifdef,所以它还不够。深度计数器可以解决这个问题。

#!/usr/bin/env perl

use strict;
use warnings;

my $ifdef_re = qr{^\s*#\s*ifdef\b};
my $endif_re = qr{^\s*#\s*endif\b};

my $ifdef_count = 0;
while(<DATA>) {
    $ifdef_count++ if /$ifdef_re/;

    print if $ifdef_count <= 0;

    $ifdef_count-- if /$endif_re/;
}

__DATA__
int i;
NSString *someString;
#ifdef EXAMPLE
NSString *exampleString;
#    ifdef FOO
this should not appear
#    endif
nor should this
#endif
bool done;
Run Code Online (Sandbox Code Playgroud)

  • @Borodin 专家建议是一个协作过程。这不仅仅是回答问题,而是解决他们的问题。他们可能没有知识和经验来充分思考或表达问题,或者只是没有时间想出一个完整的例子。我的职责就是填补这些空白。嵌套的“#ifdefs”将会出现在任何有趣的代码库中。不解决这个问题就是因疏忽而撒谎。(`#else` 语句不会增加嵌套,因此可以安全地忽略它们) (4认同)