preprocessor: refactoring
This commit is contained in:
parent
3f80b27c43
commit
6390873a09
|
@ -19,11 +19,26 @@
|
||||||
|
|
||||||
#include "preprocessor.h"
|
#include "preprocessor.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all possible configurations. By looking at the ifdefs and ifndefs in filedata
|
||||||
|
*/
|
||||||
|
static std::list<std::string> getcfgs( const std::string &filedata );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get preprocessed code for a given configuration
|
||||||
|
*/
|
||||||
static std::string getcode(const std::string &filedata, std::string cfg);
|
static std::string getcode(const std::string &filedata, std::string cfg);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the code for each configuration
|
||||||
|
* \param istr The (file/string) stream to read from.
|
||||||
|
* \param result The map that will get the results
|
||||||
|
*/
|
||||||
void preprocess(std::istream &istr, std::map<std::string, std::string> &result)
|
void preprocess(std::istream &istr, std::map<std::string, std::string> &result)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
@ -31,12 +46,42 @@ void preprocess(std::istream &istr, std::map<std::string, std::string> &result)
|
||||||
while ( getline(istr, line) )
|
while ( getline(istr, line) )
|
||||||
ostr << line << "\n";
|
ostr << line << "\n";
|
||||||
|
|
||||||
|
// Get all possible configurations..
|
||||||
|
std::list<std::string> cfgs = getcfgs( ostr.str() );
|
||||||
|
|
||||||
|
// Extract the code for each possible configuration..
|
||||||
result.clear();
|
result.clear();
|
||||||
result[""] = getcode( ostr.str(), "" );
|
for ( std::list<std::string>::const_iterator it = cfgs.begin(); it != cfgs.end(); ++it )
|
||||||
result["WIN32"] = getcode( ostr.str(), "WIN32" );
|
{
|
||||||
|
result[ *it ] = getcode( ostr.str(), *it );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static std::list<std::string> getcfgs( const std::string &filedata )
|
||||||
|
{
|
||||||
|
std::list<std::string> ret;
|
||||||
|
ret.push_back("");
|
||||||
|
|
||||||
|
std::istringstream istr(filedata);
|
||||||
|
std::string line;
|
||||||
|
while ( getline(istr, line) )
|
||||||
|
{
|
||||||
|
if ( line.find("#ifdef ")==0 || line.find("#ifndef ")==0 )
|
||||||
|
{
|
||||||
|
std::string def( line.substr(line.find(" ") + 1) );
|
||||||
|
if (std::find(ret.begin(), ret.end(), def) == ret.end())
|
||||||
|
ret.push_back( def );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static std::string getcode(const std::string &filedata, std::string cfg)
|
static std::string getcode(const std::string &filedata, std::string cfg)
|
||||||
{
|
{
|
||||||
std::ostringstream ret;
|
std::ostringstream ret;
|
||||||
|
@ -50,6 +95,9 @@ static std::string getcode(const std::string &filedata, std::string cfg)
|
||||||
if ( line.find("#ifdef ") == 0 )
|
if ( line.find("#ifdef ") == 0 )
|
||||||
matching_ifdef.push_back( !cfg.empty() && line.find(cfg) != std::string::npos );
|
matching_ifdef.push_back( !cfg.empty() && line.find(cfg) != std::string::npos );
|
||||||
|
|
||||||
|
else if ( line.find("#ifndef ") == 0 )
|
||||||
|
matching_ifdef.push_back( cfg.empty() || line.find(cfg) == std::string::npos );
|
||||||
|
|
||||||
else if ( line.find("#else") == 0)
|
else if ( line.find("#else") == 0)
|
||||||
matching_ifdef.back() = ! matching_ifdef.back();
|
matching_ifdef.back() = ! matching_ifdef.back();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ private:
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
TEST_CASE( test1 );
|
TEST_CASE( test1 );
|
||||||
|
TEST_CASE( test2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(const char filedata[], const std::map<std::string,std::string> &expected)
|
void check(const char filedata[], const std::map<std::string,std::string> &expected)
|
||||||
|
@ -71,6 +72,21 @@ private:
|
||||||
|
|
||||||
check( filedata, expected );
|
check( filedata, expected );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
const char filedata[] = "#ifndef WIN32\n"
|
||||||
|
" abcdef\n"
|
||||||
|
"#else\n"
|
||||||
|
" qwerty\n"
|
||||||
|
"#endif\n";
|
||||||
|
|
||||||
|
std::map<std::string, std::string> expected;
|
||||||
|
expected[""] = "\n abcdef\n\n\n\n";
|
||||||
|
expected["WIN32"] = "\n\n\n qwerty\n\n";
|
||||||
|
|
||||||
|
check( filedata, expected );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST( TestPreprocessor )
|
REGISTER_TEST( TestPreprocessor )
|
||||||
|
|
Loading…
Reference in New Issue