我有一个代码文件,在构建库后,我想在头文件中删除一些#ifdefs。我的第一个想法是将此作为XCode可以运行的perl脚本。虽然我当然可以打开头文件并将其中的所有内容读入perl中的字符串,但我很好奇以最佳方式执行以下操作
查找#ifdef EXAMPLE
删除它以及以下#endif
所以示例是:
int i;
NSString *someString;
#ifdef EXAMPLE
NSString *exampleString;
#endif
bool done;
,输出为:
int i;
NSString *someString;
bool done;
我考虑的选项:
考虑到我之前没有写过Perl(Objective-C是我的主要语言),我很好奇是否有任何XCode或Perl开发人员对最佳方法有什么建议
答案 0 :(得分:4)
我不确定你为什么要剥离ifdef,你可以使用C预处理器来做这个,但是这里你是如何在Perl中做的,因为这意味着我可以玩翻盖-flop operator。
首先要制作足够的正则表达式来匹配ifdef。 IIRC它们可以缩进,#
和单词之间可以有缩进。
#ifdef
# ifdef
#ifdef
不确定最后一个是否有效,但无论如何我都会使用它。
my $ifdef_re = qr{^\s*#\s*ifdef\b};
my $endif_re = qr{^\s*#\s*endif\b};
如果仅删除#ifdef
和#endif
之间的文字,则Perl使用的内容很少flip flop scalar ..
operator。
#!/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;
但是既然我们需要担心嵌套的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;
答案 1 :(得分:1)
我喜欢正则表达式,但是对于这个问题,我不会使用正则表达式,我只是逐行阅读,跟踪我是否在ifdef中:
my $nesting = 0;
while (<STDIN>)
{
$nesting += 1 if /^#ifdef/;
print $_ unless $nesting;
$nesting -= 1 if /^#endif/;
}
如果您真的想使用正则表达式,并且已将整个文件读入变量$source
,我认为如果您不需要担心嵌套,这将有效:
$source =~ s/^#ifdef.*?^#endif.*?$//gms;
^
个字符将表达式的那些部分锚定到一行的开头。 $
使得匹配的最后部分仅发生在一行的末尾。
.*?
的行为几乎与.*
相似,它匹配零个或多个字符,但它只进行最小匹配。因此,它不是一直匹配到最后一个#endif
,而是与第一个匹配。
最后的/gms
使其成为:
您可能希望将#ifdef
和#endif
与\s
一起关注,只有在该字符串后面有空格时才会匹配。
答案 2 :(得分:0)
我只是使用unifdef
执行此操作。 XCode默认安装:
-U will remove #ifdef and matching #else/#endif as if <constant> is undefined.
-D will remove #ifdef and matching #else/#endif as if <constant> is defined.
以下是一个例子:
$ cat test.h
#ifdef TEST
#ifdef DEBUG
# define AWESOME_DEBUG_LEVEL 1
#else
# define AWESOME_DEBUG_LEVEL 0
#endif
#endif
$ unifdef -U DEBUG test.h
#ifdef TEST
# define AWESOME_DEBUG_LEVEL 0
#endif
$ unifdef -U DEBUG -D TEST test.h
# define AWESOME_DEBUG_LEVEL 0