Refactorization in Preprocessor: Support beginning/end of file in removeSpaceNearNL(), avoid string copying when calling replaceIfDefined()
This commit is contained in:
parent
2e2735518e
commit
dd9cb929bf
|
@ -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 tmp;
|
||||
char prev = 0;
|
||||
char prev = '\n'; // treat start of file as newline
|
||||
for (std::size_t i = 0; i < str.size(); i++) {
|
||||
if (str[i] == ' ' &&
|
||||
((i > 0 && prev == '\n') ||
|
||||
(i + 1 < str.size() && str[i+1] == '\n')
|
||||
(prev == '\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
|
||||
|
@ -894,59 +895,54 @@ std::string Preprocessor::removeSpaceNearNL(const std::string &str)
|
|||
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;
|
||||
|
||||
pos = 0;
|
||||
while ((pos = ret.find("#if defined(", pos)) != std::string::npos) {
|
||||
std::string::size_type pos2 = ret.find(")", pos + 9);
|
||||
if (pos2 > ret.length() - 1)
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = str.find("#if defined(", pos)) != std::string::npos) {
|
||||
std::string::size_type pos2 = str.find(")", pos + 9);
|
||||
if (pos2 > str.length() - 1)
|
||||
break;
|
||||
if (ret[pos2+1] == '\n') {
|
||||
ret.erase(pos2, 1);
|
||||
ret.erase(pos + 3, 9);
|
||||
ret.insert(pos + 3, "def ");
|
||||
if (str[pos2+1] == '\n') {
|
||||
str.erase(pos2, 1);
|
||||
str.erase(pos + 3, 9);
|
||||
str.insert(pos + 3, "def ");
|
||||
}
|
||||
++pos;
|
||||
|
||||
if (_settings && _settings->terminated())
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
while ((pos = ret.find("#if !defined(", pos)) != std::string::npos) {
|
||||
std::string::size_type pos2 = ret.find(")", pos + 9);
|
||||
if (pos2 > ret.length() - 1)
|
||||
while ((pos = str.find("#if !defined(", pos)) != std::string::npos) {
|
||||
std::string::size_type pos2 = str.find(")", pos + 9);
|
||||
if (pos2 > str.length() - 1)
|
||||
break;
|
||||
if (ret[pos2+1] == '\n') {
|
||||
ret.erase(pos2, 1);
|
||||
ret.erase(pos + 3, 10);
|
||||
ret.insert(pos + 3, "ndef ");
|
||||
if (str[pos2+1] == '\n') {
|
||||
str.erase(pos2, 1);
|
||||
str.erase(pos + 3, 10);
|
||||
str.insert(pos + 3, "ndef ");
|
||||
}
|
||||
++pos;
|
||||
|
||||
if (_settings && _settings->terminated())
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
while ((pos = ret.find("#elif defined(", pos)) != std::string::npos) {
|
||||
std::string::size_type pos2 = ret.find(")", pos + 9);
|
||||
if (pos2 > ret.length() - 1)
|
||||
while ((pos = str.find("#elif defined(", pos)) != std::string::npos) {
|
||||
std::string::size_type pos2 = str.find(")", pos + 9);
|
||||
if (pos2 > str.length() - 1)
|
||||
break;
|
||||
if (ret[pos2+1] == '\n') {
|
||||
ret.erase(pos2, 1);
|
||||
ret.erase(pos + 6, 8);
|
||||
if (str[pos2+1] == '\n') {
|
||||
str.erase(pos2, 1);
|
||||
str.erase(pos + 6, 8);
|
||||
}
|
||||
++pos;
|
||||
|
||||
if (_settings && _settings->terminated())
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Preprocessor::preprocessWhitespaces(std::string &processedFile)
|
||||
|
@ -954,10 +950,6 @@ void Preprocessor::preprocessWhitespaces(std::string &processedFile)
|
|||
// Replace all tabs with spaces..
|
||||
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
|
||||
processedFile = removeSpaceNearNL(processedFile);
|
||||
}
|
||||
|
@ -1057,7 +1049,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
|
|||
} else {
|
||||
handleIncludes(processedFile, filename, includePaths);
|
||||
|
||||
processedFile = replaceIfDefined(processedFile);
|
||||
replaceIfDefined(processedFile);
|
||||
|
||||
// Get all possible configurations..
|
||||
resultConfigurations = getcfgs(processedFile, filename, defs);
|
||||
|
|
|
@ -147,9 +147,8 @@ public:
|
|||
* Replace "#if defined" with "#ifdef" where possible
|
||||
*
|
||||
* @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
|
||||
|
|
|
@ -46,12 +46,14 @@ public:
|
|||
|
||||
class OurPreprocessor : public Preprocessor {
|
||||
public:
|
||||
static std::string replaceIfDefined(const std::string &str) {
|
||||
static std::string replaceIfDefined(const char str[]) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue