首页 文章

使用Regex(POSIX)查找#ifdef语句外的printf()调用

提问于
浏览
2

我被同事要求提出一个正则表达式(POSIX语法)来查找 printf(...); 的调用 - 在一个c代码文件中 - 它不在 #ifdef ... #endif 范围内 .

然而,由于我只是在Uni学习Regex,我对此并不完全有信心 .

场景看起来像这样:

possibly some code
printf(some_parameters);  // This should match
possibly more code

#ifdef DEBUG
possibly some code
printf(some_parameters);  // This shouldn't match
possibly more code
#endif

possibly some code
printf(some_parameters);  // This should also match
possibly more code

请注意,c文件可能根本不包含#ifdef / #endif语句,在这种情况下,对 printf(); 的所有调用都应匹配 .

到目前为止我尝试过的是:

(?<!(#ifdef [A-Å0-9]+)).*printf\(.*\);.*(?!(#endif))

......以及围绕着* *的位置(甚至包含/排除) .

任何帮助或提示赞赏 .

2 回答

  • 1

    不需要正则表达式 .

    cpp -D<your #define options here> | grep printf
    
  • 0

    正则表达式不是解决此问题的好方法 . 它们不能很好地处理多行搜索,并且它们可以表达的模式受到限制,例如:使用regexen无法指定任意嵌套 .

    解决此问题的正确方法是使用旨在处理C代码中的条件编译指令的工具 . 这将是编译器的C预处理器,或者像 unifdef 这样的专用工具:

    $ unifdef -UDEBUG file.c | grep printf
    printf(some_parameters);  // This should match
    printf(some_parameters);  // This should also match
    

    从手册:

    UNIFDEF(1)                BSD General Commands Manual               UNIFDEF(1)
    
    NAME
         unifdef, unifdefall — remove preprocessor conditionals from code
    
    SYNOPSIS
         unifdef [-ceklst] [-Ipath -Dsym[=val] -Usym -iDsym[=val] -iUsym] ... [file]
         unifdefall [-Ipath] ... file
    
    DESCRIPTION
         The unifdef utility selectively processes conditional cpp(1) directives.
         It removes from a file both the directives and any additional text that
         they specify should be removed, while otherwise leaving the file alone.
    
         The unifdef utility acts on #if, #ifdef, #ifndef, #elif, #else, and #endif
         lines, and it understands only the commonly-used subset of the expression
         syntax for #if and #elif lines.  It handles integer values of symbols
         defined on the command line, the defined() operator applied to symbols
         defined or undefined on the command line, the operators !, <, >, <=, >=,
         ==, !=, &&, ||, and parenthesized expressions.  Anything that it does not
         understand is passed through unharmed.  It only processes #ifdef and
         #ifndef directives if the symbol is specified on the command line, other‐
         wise they are also passed through unchanged.  By default, it ignores #if
         and #elif lines with constant expressions, or they may be processed by
         specifying the -k flag on the command line.
    

相关问题