From 4698ae19c6b3fd9eb91ed87ad9313627038aed42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 27 Oct 2008 19:02:49 +0000 Subject: [PATCH] preprocessor: refactoring the preprocessor and added TestPreprocessor::if0 --- preprocessor.cpp | 92 ++++++++++++++++++++++++++++++----------- testpreprocessor.cpp | 98 +++++++++++++++++++++++++++++++++----------- 2 files changed, 142 insertions(+), 48 deletions(-) diff --git a/preprocessor.cpp b/preprocessor.cpp index 8f791f87a..8e43bbb4c 100644 --- a/preprocessor.cpp +++ b/preprocessor.cpp @@ -76,32 +76,25 @@ void preprocess(std::istream &istr, std::map &result) else if ( ch == '\"' ) { + code << "\""; do { - code << std::string(1,ch); ch = (char)istr.get(); + if ( ch != '\"' ) + code << "."; if ( ch == '\\' ) - { - code << "\\"; ch = (char)istr.get(); - } } while ( !istr.eof() && ch != '\"' ); - code << std::string(1, ch); + code << "\""; } else if ( ch == '\'' ) { - do - { - code << std::string(1, ch); + ch = (char)istr.get(); + if ( ch == '\\' ) ch = (char)istr.get(); - if ( ch == '\\' ) - { - code << "\\"; - ch = (char)istr.get(); - } - } while ( !istr.eof() && ch != '\'' ); - code << std::string(1, ch); + ch = (char)istr.get(); + code << "\'.\'"; } else @@ -112,6 +105,63 @@ void preprocess(std::istream &istr, std::map &result) std::string codestr( code.str() ); + // Replace all tabs with spaces.. + while ( codestr.find("\t") != std::string::npos ) + codestr[ codestr.find("\t") ] = ' '; + + // Remove all indentation.. + while ( ! codestr.empty() && codestr[0] == ' ' ) + codestr.erase(0, 1); + while ( codestr.find("\n ") != std::string::npos ) + codestr.erase( 1 + codestr.find("\n "), 1 ); + + // Remove double spaces.. + while ( codestr.find(" ") != std::string::npos ) + codestr.erase( codestr.find(" "), 1 ); + + // Remove all trailing spaces.. + while ( codestr.find(" \n") != std::string::npos ) + codestr.erase( codestr.find(" \n"), 1 ); + + // Remove space in "# if.." + while ( codestr.find("# ") != std::string::npos ) + codestr.erase( 1 + codestr.find("# "), 1 ); + + // Remove "#if 0" blocks.. + if ( codestr.find("#if 0") != std::string::npos ) + { + code.str(""); + std::string line; + std::istringstream istr(codestr.c_str()); + while (getline(istr,line)) + { + if ( line == "#if 0" ) + { + code << "\n"; + unsigned int iflevel = 1; + while ( getline(istr, line) ) + { + code << "\n"; + + if ( line.find("#if") != std::string::npos ) + ++iflevel; + + else if ( line.find("#endif") != std::string::npos ) + { + --iflevel; + if ( iflevel == 0 ) + break; + } + } + } + else + { + code << line << "\n"; + } + } + codestr = code.str(); + } + // Get all possible configurations.. std::list cfgs = getcfgs( codestr ); @@ -128,14 +178,6 @@ void preprocess(std::istream &istr, std::map &result) // Get the DEF in this line: "#ifdef DEF" static std::string getdef(std::string line, bool def) { - // Replace tabs with spaces.. - while ( line.find("\t") != std::string::npos ) - line[ line.find("\t") ] = 0; - - // Trim off any leading spaces.. - while (line[0] == ' ') - line.erase(0, 1); - // If def is true, the line must start with "#ifdef" if ( def && line.find("#ifdef ") != 0 ) { @@ -203,10 +245,10 @@ static std::string getcode(const std::string &filedata, std::string cfg) else if ( ! ndef.empty() ) matching_ifdef.push_back( cfg != ndef ); - else if ( line.find("#else") == 0) + else if ( line == "#else" ) matching_ifdef.back() = ! matching_ifdef.back(); - else if ( line.find("#endif") == 0 ) + else if ( line == "#endif" ) matching_ifdef.pop_back(); if ( !matching_ifdef.empty() && !matching_ifdef.back() ) diff --git a/testpreprocessor.cpp b/testpreprocessor.cpp index 92ac58f15..519e5110d 100644 --- a/testpreprocessor.cpp +++ b/testpreprocessor.cpp @@ -41,29 +41,36 @@ private: TEST_CASE( test2 ); TEST_CASE( comments1 ); + + TEST_CASE( if0 ); } - void check(const char filedata[], const std::map &expected) + bool cmpmaps(const std::map &m1, const std::map &m2) { - std::istringstream istr(filedata); - std::map actual; - preprocess( istr, actual ); - - ASSERT_EQUALS( expected.size(), actual.size() ); - for ( std::map::const_iterator it = actual.begin(); it != actual.end(); ++it ) + // Begin by checking the sizes + if ( m1.size() != m2.size() ) + return false; + + // Check each item in the maps.. + for ( std::map::const_iterator it1 = m1.begin(); it1 != m1.end(); ++it1 ) { - std::map::const_iterator it2 = expected.find(it->first); - if ( it2 == expected.end() ) - assertFail(__FILE__, __LINE__); + std::map::const_iterator it2 = m2.find(it1->first); + if ( it2 == m2.end() ) + return false; else { - std::string s1 = it->second; + std::string s1 = it1->second; std::string s2 = it2->second; - ASSERT_EQUALS( it->second, it2->second ); + if ( s1 != s2 ) + return false; } } + + // No diffs were found + return true; } + void test1() { const char filedata[] = "#ifdef WIN32 \n" @@ -72,26 +79,40 @@ private: " qwerty\n" "#endif\n"; + // Expected result.. std::map expected; - expected[""] = "\n\n\n qwerty\n\n"; - expected["WIN32"] = "\n abcdef\n\n\n\n"; + expected[""] = "\n\n\nqwerty\n\n"; + expected["WIN32"] = "\nabcdef\n\n\n\n"; - check( filedata, expected ); + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + preprocess( istr, actual ); + + // Compare results.. + ASSERT_EQUALS( true, cmpmaps(actual, expected)); } void test2() { - const char filedata[] = "#ifndef WIN32\n" - " abcdef\n" - "#else\n" + const char filedata[] = "# ifndef WIN32\n" + " \"#ifdef WIN32\" // a comment\n" + " # else \n" " qwerty\n" - "#endif\n"; + " # endif \n"; + // Expected result.. std::map expected; - expected[""] = "\n abcdef\n\n\n\n"; - expected["WIN32"] = "\n\n\n qwerty\n\n"; + expected[""] = "\n\"............\"\n\n\n\n"; + expected["WIN32"] = "\n\n\nqwerty\n\n"; - check( filedata, expected ); + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + preprocess( istr, actual ); + + // Compare results.. + ASSERT_EQUALS( true, cmpmaps(actual, expected)); } @@ -103,11 +124,42 @@ private: "#endif\n" "*/\n"; + // Expected result.. std::map expected; expected[""] = "\n\n\n\n"; - check( filedata, expected ); + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + preprocess( istr, actual ); + + // Compare results.. + ASSERT_EQUALS( true, cmpmaps(actual, expected)); } + + + void if0() + { + const char filedata[] = " # if /* comment */ 0 // comment\n" + "#ifdef WIN32\n" + "#endif\n" + "#endif\n"; + + // Expected result.. + std::map expected; + expected[""] = "\n\n\n\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + preprocess( istr, actual ); + + // Compare results.. + ASSERT_EQUALS( true, cmpmaps(actual, expected)); + } + + }; REGISTER_TEST( TestPreprocessor )