Refactorization in Preprocessor: Support beginning/end of file in removeSpaceNearNL(), avoid string copying when calling replaceIfDefined()

This commit is contained in:
PKEuS 2015-03-12 21:16:54 +01:00
parent 2e2735518e
commit dd9cb929bf
3 changed files with 36 additions and 43 deletions

View File

@ -877,11 +877,12 @@ void Preprocessor::preprocess(std::istream &istr, std::map<std::string, std::str
std::string Preprocessor::removeSpaceNearNL(const std::string &str) std::string Preprocessor::removeSpaceNearNL(const std::string &str)
{ {
std::string tmp; std::string tmp;
char prev = 0; char prev = '\n'; // treat start of file as newline
for (std::size_t i = 0; i < str.size(); i++) { for (std::size_t i = 0; i < str.size(); i++) {
if (str[i] == ' ' && if (str[i] == ' ' &&
((i > 0 && prev == '\n') || (prev == '\n' ||
(i + 1 < str.size() && str[i+1] == '\n') i + 1 >= str.size() || // treat end of file as newline
str[i+1] == '\n'
) )
) { ) {
// Ignore space that has new line in either side of it // Ignore space that has new line in either side of it
@ -894,59 +895,54 @@ std::string Preprocessor::removeSpaceNearNL(const std::string &str)
return tmp; return tmp;
} }
std::string Preprocessor::replaceIfDefined(const std::string &str) const void Preprocessor::replaceIfDefined(std::string &str) const
{ {
std::string ret(str); std::string::size_type pos = 0;
std::string::size_type pos; while ((pos = str.find("#if defined(", pos)) != std::string::npos) {
std::string::size_type pos2 = str.find(")", pos + 9);
pos = 0; if (pos2 > str.length() - 1)
while ((pos = ret.find("#if defined(", pos)) != std::string::npos) {
std::string::size_type pos2 = ret.find(")", pos + 9);
if (pos2 > ret.length() - 1)
break; break;
if (ret[pos2+1] == '\n') { if (str[pos2+1] == '\n') {
ret.erase(pos2, 1); str.erase(pos2, 1);
ret.erase(pos + 3, 9); str.erase(pos + 3, 9);
ret.insert(pos + 3, "def "); str.insert(pos + 3, "def ");
} }
++pos; ++pos;
if (_settings && _settings->terminated()) if (_settings && _settings->terminated())
return ""; return;
} }
pos = 0; pos = 0;
while ((pos = ret.find("#if !defined(", pos)) != std::string::npos) { while ((pos = str.find("#if !defined(", pos)) != std::string::npos) {
std::string::size_type pos2 = ret.find(")", pos + 9); std::string::size_type pos2 = str.find(")", pos + 9);
if (pos2 > ret.length() - 1) if (pos2 > str.length() - 1)
break; break;
if (ret[pos2+1] == '\n') { if (str[pos2+1] == '\n') {
ret.erase(pos2, 1); str.erase(pos2, 1);
ret.erase(pos + 3, 10); str.erase(pos + 3, 10);
ret.insert(pos + 3, "ndef "); str.insert(pos + 3, "ndef ");
} }
++pos; ++pos;
if (_settings && _settings->terminated()) if (_settings && _settings->terminated())
return ""; return;
} }
pos = 0; pos = 0;
while ((pos = ret.find("#elif defined(", pos)) != std::string::npos) { while ((pos = str.find("#elif defined(", pos)) != std::string::npos) {
std::string::size_type pos2 = ret.find(")", pos + 9); std::string::size_type pos2 = str.find(")", pos + 9);
if (pos2 > ret.length() - 1) if (pos2 > str.length() - 1)
break; break;
if (ret[pos2+1] == '\n') { if (str[pos2+1] == '\n') {
ret.erase(pos2, 1); str.erase(pos2, 1);
ret.erase(pos + 6, 8); str.erase(pos + 6, 8);
} }
++pos; ++pos;
if (_settings && _settings->terminated()) if (_settings && _settings->terminated())
return ""; return;
} }
return ret;
} }
void Preprocessor::preprocessWhitespaces(std::string &processedFile) void Preprocessor::preprocessWhitespaces(std::string &processedFile)
@ -954,10 +950,6 @@ void Preprocessor::preprocessWhitespaces(std::string &processedFile)
// Replace all tabs with spaces.. // Replace all tabs with spaces..
std::replace(processedFile.begin(), processedFile.end(), '\t', ' '); std::replace(processedFile.begin(), processedFile.end(), '\t', ' ');
// Remove all indentation..
if (!processedFile.empty() && processedFile[0] == ' ')
processedFile.erase(0, processedFile.find_first_not_of(" "));
// Remove space characters that are after or before new line character // Remove space characters that are after or before new line character
processedFile = removeSpaceNearNL(processedFile); processedFile = removeSpaceNearNL(processedFile);
} }
@ -1057,7 +1049,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
} else { } else {
handleIncludes(processedFile, filename, includePaths); handleIncludes(processedFile, filename, includePaths);
processedFile = replaceIfDefined(processedFile); replaceIfDefined(processedFile);
// Get all possible configurations.. // Get all possible configurations..
resultConfigurations = getcfgs(processedFile, filename, defs); resultConfigurations = getcfgs(processedFile, filename, defs);

View File

@ -147,9 +147,8 @@ public:
* Replace "#if defined" with "#ifdef" where possible * Replace "#if defined" with "#ifdef" where possible
* *
* @param str The string to be converted * @param str The string to be converted
* @return The replaced string
*/ */
std::string replaceIfDefined(const std::string &str) const; void replaceIfDefined(std::string &str) const;
/** /**
* expand macros in code. ifdefs etc are ignored so the code must be a single configuration * expand macros in code. ifdefs etc are ignored so the code must be a single configuration

View File

@ -46,12 +46,14 @@ public:
class OurPreprocessor : public Preprocessor { class OurPreprocessor : public Preprocessor {
public: public:
static std::string replaceIfDefined(const std::string &str) { static std::string replaceIfDefined(const char str[]) {
Preprocessor p; Preprocessor p;
return p.replaceIfDefined(str); std::string ret(str);
p.replaceIfDefined(ret);
return ret;
} }
static std::string expandMacros(const std::string& code, ErrorLogger *errorLogger = 0) { static std::string expandMacros(const char code[], ErrorLogger *errorLogger = 0) {
return Preprocessor::expandMacros(code, "file.cpp", "", errorLogger); return Preprocessor::expandMacros(code, "file.cpp", "", errorLogger);
} }