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

Xcode 使用perl从文件中删除出现的#ifdef/#endif,xcode,perl,xcode4,xcode4.5,Xcode,Perl,Xcode4,Xcode4.5,我有一个代码文件,其中包含一些在构建库后希望在头文件中删除的#ifdef。我的第一个想法是将其作为一个perl脚本来执行,XCode可以运行。虽然我当然可以用perl打开头文件并将其所有内容读入字符串,但我很想知道执行以下操作的最佳方法 查找任何出现的#ifdef示例 移除它和以下之间的任何东西#endif 例如: int i; NSString *someString; #ifdef EXAMPLE NSString *exampleString; #endif bool done; 其结果

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

  • 查找任何出现的#ifdef示例

  • 移除它和以下之间的任何东西#endif

  • 例如:

    int i;
    NSString *someString;
    #ifdef EXAMPLE
    NSString *exampleString;
    #endif
    bool done;
    
    其结果是:

    int i;
    NSString *someString;
    bool done;
    
    我正在考虑的选择:

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

    考虑到我以前没有编写过Perl(Objective-C是我的主要语言),我很好奇是否有任何XCode或Perl开发人员对最好的方法有任何建议,我不确定为什么要去掉ifdef,您可能可以使用C预处理器来完成这项工作,但这里是如何在Perl中实现的,因为这意味着我可以使用触发器操作符

    第一件事是创建一个足够的正则表达式来匹配ifdef。IIRC它们可以缩进,并且
    #
    和单词之间可以缩进

    #ifdef
    #    ifdef
        #ifdef
    
    我不确定最后一个是否有效,但我还是会同意的

    my $ifdef_re = qr{^\s*#\s*ifdef\b};
    my $endif_re = qr{^\s*#\s*endif\b};
    
    如果只是删除
    #ifdef
    #endif
    之间的文本,那么Perl几乎没有什么用处

    #/usr/bin/env perl
    严格使用;
    使用警告;
    我的$ifdef_re=qr{^\s*\s*ifdef\b};
    我的$endif_re=qr{^\s*\s*endif\b};
    while(){
    我的$in_ifdef=/$ifdef_re/。/$endif_re/;
    打印if!$in_ifdef;
    }
    __资料__
    int i;
    NSString*someString;
    #ifdef示例
    NSString*示例字符串;
    #恩迪夫
    布尔多;
    
    但是,由于我们需要担心嵌套的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;
    
    #/usr/bin/env perl
    严格使用;
    使用警告;
    我的$ifdef_re=qr{^\s*\s*ifdef\b};
    我的$endif_re=qr{^\s*\s*endif\b};
    我的$ifdef_计数=0;
    while(){
    $ifdef_count++if/$ifdef_re/;
    
    打印if$ifdef_count我不确定为什么要去掉ifdef,您可能可以使用C预处理器来完成这项工作,但下面是在Perl中如何完成的,因为这意味着我可以使用触发器操作符

    第一件事是创建一个足够的正则表达式来匹配ifdef。IIRC它们可以缩进,并且
    和单词之间可以缩进

    #ifdef
    #    ifdef
        #ifdef
    
    我不确定最后一个是否有效,但我还是会同意的

    my $ifdef_re = qr{^\s*#\s*ifdef\b};
    my $endif_re = qr{^\s*#\s*endif\b};
    
    如果只是删除
    #ifdef
    #endif
    之间的文本,那么Perl几乎没有什么用处

    !/usr/bin/env perl
    严格使用;
    使用警告;
    我的$ifdef_re=qr{^\s*\s*ifdef\b};
    我的$endif_re=qr{^\s*\s*endif\b};
    while(){
    我的$in_ifdef=/$ifdef_re/。/$endif_re/;
    打印if!$in_ifdef;
    }
    __资料__
    int i;
    NSString*someString;
    #ifdef示例
    NSString*示例字符串;
    #恩迪夫
    布尔多;
    
    但是,由于我们需要担心嵌套的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;
    
    !/usr/bin/env perl
    严格使用;
    使用警告;
    我的$ifdef_re=qr{^\s*\s*ifdef\b};
    我的$endif_re=qr{^\s*\s*endif\b};
    我的$ifdef_计数=0;
    while(){
    $ifdef_count++if/$ifdef_re/;
    
    打印if$ifdef_count我喜欢正则表达式,但对于这个问题,我不会使用正则表达式,我只是逐行阅读,跟踪我是否在ifdef中:

    my $nesting = 0;
    while (<STDIN>)
       {
       $nesting += 1 if /^#ifdef/;
       print $_ unless $nesting;
       $nesting -= 1 if /^#endif/;
       }
    
    ^
    字符将表达式的这些部分锚定到行首。
    $
    使匹配的最后一部分仅发生在行尾

    *?
    的行为几乎与
    *
    类似,它匹配零个或多个字符,只是它进行了最小匹配。因此,它不会一直匹配到最后一个
    #endif
    ,而是匹配到第一个字符

    最后的
    /gms
    使其:

  • 替换每个事件,而不仅仅是一个(即g)
  • 使“^”和“$在行边界处匹配,而不仅仅是字符串边界(m)
  • 生成.匹配换行符(s)

  • 您可能希望在每个
    #ifdef
    #endif
    后面加上
    \s
    ,只有在字符串后面有空格时才匹配。

    我喜欢正则表达式,但对于这个问题,我不会使用正则表达式,我只是逐行读取,跟踪我是否在ifdef中:

    my $nesting = 0;
    while (<STDIN>)
       {
       $nesting += 1 if /^#ifdef/;
       print $_ unless $nesting;
       $nesting -= 1 if /^#endif/;
       }
    
    ^
    字符将表达式的这些部分锚定到行首。
    $
    使匹配的最后一部分仅发生在行尾

    *?
    的行为几乎与
    *
    类似,它匹配零个或多个字符,只是它进行了最小匹配。因此,它不会一直匹配到最后一个
    #endif
    ,而是匹配到第一个字符

    最后的
    /gms
    使其:

  • 替换每个事件,而不仅仅是一个(即g)
  • 使“^”和“$在行边界处匹配,而不仅仅是字符串边界(m)
  • 生成.匹配换行符(s)
  • 您可能希望在每个
    #ifdef
    #endif
    后面加上
    \s
    ,以便仅在该字符串后面有空格时匹配。

    我只需要用.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.
    
    我只需要使用.XCode就可以了。默认情况下,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.
    

    为什么要删除ifdef?为什么不直接使用C预处理器?@MichaelCarman为什么不向他演示如何删除ifdef?为什么不直接使用C预处理器?@MichaelCarman为什么不向他演示如何删除ifdef?我不清楚为什么要为嵌套的
    #ifdef
    语句编码,尤其是在不考虑
    #else
    陈述。这不是问题的一部分。@Borodin专家建议是一个协作过程。它不仅仅是回答问题,而是解决他们的问题。他们可能没有知识和经验