CMake正则表达式匹配包含声明中的标题名称

时间:2014-04-07 14:52:13

标签: c++ regex cmake

我试图在我的robot.cpp中获取所有#include声明的标题名称,即,如果我有一个带有两个声明的 example.cpp

example.cpp

#include "MyLib.h"
#include <iosream>

//some code

我想在输出中看到类似这样的内容:

INCLUDE_NAME MyLib.h
INCLUDE_NAME iosream

我有这些robot.cppCMakeLists.txt个文件(它们已经简化):

的CMakeLists.txt

...
   file(STRINGS ${SRC_FILE} SRC_CONTENT) #copy the file content

   foreach(SRC_LINE ${SRC_CONTENT})
     if("${SRC_LINE }" MATCHES "^ *#include *[<\"](.*)[>\"]")
        message("INCLUDE_NAME ${CMAKE_MATCH_1}")
...

robot.cpp

#include "ArduinoRobot.h"
#include "EasyTransfer2.h"

void RobotControl::pointTo(int angle){
    int target=angle;
    uint8_t speed=80;
    target=target%360;
    if(target<0){
        target+=360;
    }
    int direction=angle;
    while(1){
        if(direction>0){
            motorsWrite(speed,-speed);//right
            delay(10);
        }else{
            motorsWrite(-speed,speed);//left
            delay(10);
        }
        int currentAngle=compassRead();
        int diff=target-currentAngle;
        if(diff<-180) 
            diff += 360;
        else if(diff> 180) 
            diff -= 360;
        direction=-diff;

        if(abs(diff)<5){
            motorsWrite(0,0);
            return;
        }
    }
}

然后,如果我在控制台中执行我的CMakeList.txt,我得到这个输出:

...
    INCLUDE_NAME ArduinoRobot.h"#include "EasyTransfer2.h"void RobotControl::pointTo(int angle){     int target=angle;       uint8_t speed=80;       target=target%360;      if(target<0){           target+=360; }       int direction=angle;    while(1){               if(direction>0){                        motorsWrite(speed,-speed);//right                       delay(10);              }else{                  motorsWrite(-speed,speed);//left                     delay(10);              }               int currentAngle=compassRead();         int diff=target-currentAngle;           if(diff<-180)                   diff += 360;            else if(diff    
...

但是,如果我将所有符号>更改为<,结果就可以了,我得到以下输出:

...
INCLUDE_NAME ArduinoRobot.h
INCLUDE_NAME EasyTransfer2.h
...

我想这是因为正则表达式,但我不知道如何修复它。

有人吗?

2 个答案:

答案 0 :(得分:2)

我相信有两个问题。我强烈怀疑,第一个是源代码中的行结尾。你的代码本来就像你原来的那样工作,除了你正在解析的代码可能是从某个地方下载的,而且该文件可能有不同的行结尾。例如,如果原始版本是在Linux下开发并且您在Windows下运行,则可能会发生这种情况。这需要先修复。

其次,你真正想要的是一个正则表达式,它不接受中间的任何字符,但只接受与">不匹配的字符。这是我刚才测试的内容:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(NONSENSE NONE)
file(STRINGS "silly.txt" SRC_CONTENT)
foreach(SRC_LINE ${SRC_CONTENT})
    if("${SRC_LINE}" MATCHES "^[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]")
        message("INCLUDE_NAME ${CMAKE_MATCH_1}")
    endif()
ENDFOREACH()

silly.txt的内容:

#  include "foo.h"
#include    "bar.h"

#include "ArduinoRobot.h"#include "EasyTransfer2.h"int main()
{
    printf("This is not a header.\n");
    return 0;
}

    #include "surprise.h"

请注意,在bar.h行的中间和surprise.h行的开头有一个制表符。很奇怪,但仍被预处理器接受也是foo.h行上显示的变体,其中#和指令之间有空格或制表符。显示的正则表达式处理所有这些。

这是输出:

INCLUDE_NAME foo
INCLUDE_NAME bar
INCLUDE_NAME foo.h
INCLUDE_NAME bar.h
INCLUDE_NAME ArduinoRobot.h
INCLUDE_NAME surprise.h

答案 1 :(得分:0)

CMake正则表达式是贪婪的,因此输出。

也许尝试在撇号之间匹配较少的东西:

"^ *#include *[<\"](\w+)[>\"]"

我想知道CMake是否接受明确的非贪婪语法,例如

"^ *#include *[<\"]\\(.*)\\[>\"]"

(未经测试!)