Reputation:
I desire to have my program (main.cpp) read a cpp file (code.cpp), and determine whether certain variables are used. This could easily be done by reading the file and searching for substrings, but this has undesired drawbacks as explained below.
Content of code.cpp
double a4 = 4.0;
int main() {
double a1 = 1.0;
double a2 = 2.0;
//a3 is inside comment. Therefore a3 does not exist
double a33 = 3.0; //a33 exists. a3 does not exist
string s = "a1a2a3"; //a3 still does not exist
return 0;
}
Content of main.cpp (my current attempt for solving this task)
#include <iostream>
#include <fstream>
using namespace std;
int main() {
std::ifstream file;
file.open("code.cpp");
std::string s;
while(std::getline(file,s)){
if (s.find("a1") != std::string::npos)
cout << "found a1" << endl;
if (s.find("a2") != std::string::npos)
cout << "found a2" << endl;
if (s.find("a3") != std::string::npos)
cout << "found a3 :(" << endl;
if (s.find("a4") != std::string::npos)
cout << "found a4" << endl;
}
return 0;
}
Output from main execution:
found a4
found a1
found a2
found a3 :(
found a3 :(
found a1
found a2
found a3 :(
main.cpp is unsuccessful because it detects a3 being a variable used in code.cpp.
Is there any practical method to determine whether variables by certain names exist or are used in a c++ file?
Further information:
Upvotes: 1
Views: 927
Reputation: 503
As Jesper mentioned, you need a C++ parser. To determine whether variables by certain names exist or are used in a c++ file, the easiest is to employ the Clang AST Matcher, instead of implementing a tool yourself.
So install LLVM, Clang, Clang toolings and fire clang-query:
$ clang-query yourcode.cpp
clang-query> match varDecl(hasName("a1"))
Match #1:
/home/yourcode.cpp:3:5: note: "root" binds here
double a1 = 1.0;
^~~~~~~~~~~~~~~
1 match.
clang-query> match varDecl(hasName("a2"))
Match #1:
/home/yourcode.cpp:4:5: note: "root" binds here
double a2 = 2.0;
^~~~~~~~~~~~~~~
1 match.
clang-query> match varDecl(hasName("a3"))
0 matches.
clang-query> match varDecl(hasName("a4"))
Match #1:
/home/yourcode.cpp:1:1: note: "root" binds here
double a4 = 4.0;
^~~~~~~~~~~~~~~
1 match.
You can do a lot more than this, check the AST Matcher Reference http://clang.llvm.org/docs/LibASTMatchersReference.html
Upvotes: 1
Reputation: 31464
I would build such a tool on top of Clang's libtooling library, since that gives you easy access to a C++ parser and the ability to easily search the AST for whatever your heart desires. Perhaps even easier would be to write it as a ClangTidy check.
Upvotes: 1