diff --git a/preprocessor.cpp b/preprocessor.cpp index e74b1366b..93becaf13 100644 --- a/preprocessor.cpp +++ b/preprocessor.cpp @@ -19,11 +19,26 @@ #include "preprocessor.h" +#include #include #include +/** + * Get all possible configurations. By looking at the ifdefs and ifndefs in filedata + */ +static std::list getcfgs( const std::string &filedata ); + +/** + * Get preprocessed code for a given configuration + */ 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 &result) { std::ostringstream ostr; @@ -31,12 +46,42 @@ void preprocess(std::istream &istr, std::map &result) while ( getline(istr, line) ) ostr << line << "\n"; + // Get all possible configurations.. + std::list cfgs = getcfgs( ostr.str() ); + + // Extract the code for each possible configuration.. result.clear(); - result[""] = getcode( ostr.str(), "" ); - result["WIN32"] = getcode( ostr.str(), "WIN32" ); + for ( std::list::const_iterator it = cfgs.begin(); it != cfgs.end(); ++it ) + { + result[ *it ] = getcode( ostr.str(), *it ); + } } + +static std::list getcfgs( const std::string &filedata ) +{ + std::list 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) { std::ostringstream ret; @@ -50,6 +95,9 @@ static std::string getcode(const std::string &filedata, std::string cfg) if ( line.find("#ifdef ") == 0 ) 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) matching_ifdef.back() = ! matching_ifdef.back(); diff --git a/testpreprocessor.cpp b/testpreprocessor.cpp index 7b828519a..61f33f012 100644 --- a/testpreprocessor.cpp +++ b/testpreprocessor.cpp @@ -38,6 +38,7 @@ private: void run() { TEST_CASE( test1 ); + TEST_CASE( test2 ); } void check(const char filedata[], const std::map &expected) @@ -71,6 +72,21 @@ private: check( filedata, expected ); } + + void test2() + { + const char filedata[] = "#ifndef WIN32\n" + " abcdef\n" + "#else\n" + " qwerty\n" + "#endif\n"; + + std::map expected; + expected[""] = "\n abcdef\n\n\n\n"; + expected["WIN32"] = "\n\n\n qwerty\n\n"; + + check( filedata, expected ); + } }; REGISTER_TEST( TestPreprocessor )