3

I'm attempting to get the header names of all the #include declarations in my robot.cpp, i.e., if I have an example.cpp with two declarations:

example.cpp

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

//some code

I want to see in my output something like this:

INCLUDE_NAME MyLib.h
INCLUDE_NAME iosream

I have these robot.cpp and CMakeLists.txt files (they are simplified):

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;
        }
    }
}

Then, if I execute in a console my CMakeList.txt, I get this output:

...
    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    
...

However, if I change all the symbols > to <, the result is ok, and I get the following output:

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

I guess it is because the regex, but I don't know how fix it.

Does anyone?

0

2 Answers 2

2

I believe there are two problems. The first one, I strongly suspect, is line endings in your source code. Your code would have worked as you'd had it originally except that the code you're parsing is probably downloaded from somewhere and that file likely has different line endings. This can happen, for example, if the original was developed under Linux and you're operating under Windows. That needs to be fixed first.

Secondly, what you really want is a regex that doesn't accept just any character in the middle, but only characters that don't match " or >. Here's what I tested with just now:

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()

The contents of 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"

Note that there is a tab character in the middle of bar.h line and at the begining of the surprise.h line. Weird, but still accepted by preprocessors is also the variation shown on the foo.h line in which there are spaces or tabs between the # and the directive. The regex shown handles all of these.

This the the output of that:

INCLUDE_NAME foo
INCLUDE_NAME bar
INCLUDE_NAME foo.h
INCLUDE_NAME bar.h
INCLUDE_NAME ArduinoRobot.h
INCLUDE_NAME surprise.h
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot @Edward, it works!! :) I just tested my code and it goes smoothly
0

CMake regexes are greedy, thus the output.

Maybe try to match less things in between the apostrophes :

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

I am wondering if CMake accepts explicit non-greedy syntax such as

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

(not tested!)

1 Comment

Thanks so much @Barth but it doesn't work :( I know CMake regexes are greedy but I didn't find anything to fix it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.