preprocessor: refactoring

This commit is contained in:
Daniel Marjamäki 2008-10-26 15:36:52 +00:00
parent 3f80b27c43
commit 6390873a09
2 changed files with 66 additions and 2 deletions

View File

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

View File

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