Preprocessor: Refactoring. Broke out code that parses out the parameters from code.
This commit is contained in:
parent
dcdbe117e6
commit
38c3de7343
|
@ -1449,6 +1449,121 @@ void Preprocessor::handleIncludes(std::string &code, const std::string &filePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip string in line. A string begins and ends with either a " or a '
|
||||||
|
* @param line the string
|
||||||
|
* @param pos in=start position of string, out=end position of string
|
||||||
|
*/
|
||||||
|
static void skipstring(const std::string &line, std::string::size_type &pos)
|
||||||
|
{
|
||||||
|
const unsigned char ch = line[pos];
|
||||||
|
|
||||||
|
++pos;
|
||||||
|
while (pos < line.size() && line[pos] != ch)
|
||||||
|
{
|
||||||
|
if (line[pos] == '\\')
|
||||||
|
++pos;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get parameters from code. For example 'foo(1,2)' => '1','2'
|
||||||
|
* @param line in: The code
|
||||||
|
* @param pos in: Position to the '('. out: Position to the ')'
|
||||||
|
* @param params out: The extracted parameters
|
||||||
|
* @param numberOfNewlines out: number of newlines in the macro call
|
||||||
|
* @param endFound out: was the end paranthesis found?
|
||||||
|
*/
|
||||||
|
static void getparams(const std::string &line,
|
||||||
|
unsigned int &pos2,
|
||||||
|
std::vector<std::string> ¶ms,
|
||||||
|
unsigned int &numberOfNewlines,
|
||||||
|
bool &endFound)
|
||||||
|
{
|
||||||
|
params.clear();
|
||||||
|
numberOfNewlines = 0;
|
||||||
|
endFound = false;
|
||||||
|
|
||||||
|
if (line[pos2] == ' ')
|
||||||
|
pos2++;
|
||||||
|
|
||||||
|
if (line[pos2] != '(')
|
||||||
|
return;
|
||||||
|
|
||||||
|
// parantheses level
|
||||||
|
int parlevel = 0;
|
||||||
|
|
||||||
|
// current parameter
|
||||||
|
std::string par;
|
||||||
|
|
||||||
|
|
||||||
|
// scan for parameters..
|
||||||
|
for (; pos2 < line.length(); ++pos2)
|
||||||
|
{
|
||||||
|
// increase paranthesis level
|
||||||
|
if (line[pos2] == '(')
|
||||||
|
{
|
||||||
|
++parlevel;
|
||||||
|
if (parlevel == 1)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrease paranthesis level
|
||||||
|
else if (line[pos2] == ')')
|
||||||
|
{
|
||||||
|
--parlevel;
|
||||||
|
if (parlevel <= 0)
|
||||||
|
{
|
||||||
|
endFound = true;
|
||||||
|
params.push_back(par);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// string
|
||||||
|
else if (line[pos2] == '\"' || line[pos2] == '\'')
|
||||||
|
{
|
||||||
|
const std::string::size_type p = pos2;
|
||||||
|
skipstring(line, pos2);
|
||||||
|
if (pos2 == line.length())
|
||||||
|
break;
|
||||||
|
par += line.substr(p, pos2 + 1 - p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// count newlines. the expanded macro must have the same number of newlines
|
||||||
|
else if (line[pos2] == '\n')
|
||||||
|
{
|
||||||
|
++numberOfNewlines;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new parameter
|
||||||
|
if (parlevel == 1 && line[pos2] == ',')
|
||||||
|
{
|
||||||
|
params.push_back(par);
|
||||||
|
par = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// spaces are only added if needed
|
||||||
|
else if (line[pos2] == ' ')
|
||||||
|
{
|
||||||
|
// Add space only if it is needed
|
||||||
|
if (par.size() && std::isalnum(par[par.length()-1]))
|
||||||
|
{
|
||||||
|
par += ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add character to current parameter
|
||||||
|
else if (parlevel >= 1)
|
||||||
|
{
|
||||||
|
par.append(1, line[pos2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief Class that the preprocessor uses when it expands macros. This class represents a preprocessor macro */
|
/** @brief Class that the preprocessor uses when it expands macros. This class represents a preprocessor macro */
|
||||||
class PreprocessorMacro
|
class PreprocessorMacro
|
||||||
{
|
{
|
||||||
|
@ -1705,26 +1820,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skip string in line. A string begins and ends with either a " or a '
|
|
||||||
* @param line the string
|
|
||||||
* @param pos in=start position of string, out=end position of string
|
|
||||||
*/
|
|
||||||
static void skipstring(const std::string &line, std::string::size_type &pos)
|
|
||||||
{
|
|
||||||
const unsigned char ch = line[pos];
|
|
||||||
|
|
||||||
++pos;
|
|
||||||
while (pos < line.size() && line[pos] != ch)
|
|
||||||
{
|
|
||||||
if (line[pos] == '\\')
|
|
||||||
++pos;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get data from a input string. This is an extended version of std::getline.
|
* Get data from a input string. This is an extended version of std::getline.
|
||||||
* The std::getline only get a single line at a time. It can therefore happen that it
|
* The std::getline only get a single line at a time. It can therefore happen that it
|
||||||
|
@ -1972,85 +2067,11 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
|
||||||
// if the macro has parantheses, get parameters
|
// if the macro has parantheses, get parameters
|
||||||
if (macro->variadic() || macro->nopar() || macro->params().size())
|
if (macro->variadic() || macro->nopar() || macro->params().size())
|
||||||
{
|
{
|
||||||
if (line[pos2] == ' ')
|
|
||||||
pos2++;
|
|
||||||
|
|
||||||
if (line[pos2] != '(')
|
|
||||||
break;
|
|
||||||
|
|
||||||
// parantheses level
|
|
||||||
int parlevel = 0;
|
|
||||||
|
|
||||||
// current parameter
|
|
||||||
std::string par;
|
|
||||||
|
|
||||||
// is the end paranthesis found?
|
// is the end paranthesis found?
|
||||||
bool endFound = false;
|
bool endFound = false;
|
||||||
|
|
||||||
// scan for parameters..
|
getparams(line,pos2,params,numberOfNewlines,endFound);
|
||||||
for (; pos2 < line.length(); ++pos2)
|
|
||||||
{
|
|
||||||
// increase paranthesis level
|
|
||||||
if (line[pos2] == '(')
|
|
||||||
{
|
|
||||||
++parlevel;
|
|
||||||
if (parlevel == 1)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// decrease paranthesis level
|
|
||||||
else if (line[pos2] == ')')
|
|
||||||
{
|
|
||||||
--parlevel;
|
|
||||||
if (parlevel <= 0)
|
|
||||||
{
|
|
||||||
endFound = true;
|
|
||||||
params.push_back(par);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// string
|
|
||||||
else if (line[pos2] == '\"' || line[pos2] == '\'')
|
|
||||||
{
|
|
||||||
const std::string::size_type p = pos2;
|
|
||||||
skipstring(line, pos2);
|
|
||||||
if (pos2 == line.length())
|
|
||||||
break;
|
|
||||||
par += line.substr(p, pos2 + 1 - p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// count newlines. the expanded macro must have the same number of newlines
|
|
||||||
else if (line[pos2] == '\n')
|
|
||||||
{
|
|
||||||
++numberOfNewlines;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// new parameter
|
|
||||||
if (parlevel == 1 && line[pos2] == ',')
|
|
||||||
{
|
|
||||||
params.push_back(par);
|
|
||||||
par = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// spaces are only added if needed
|
|
||||||
else if (line[pos2] == ' ')
|
|
||||||
{
|
|
||||||
// Add space only if it is needed
|
|
||||||
if (par.size() && std::isalnum(par[par.length()-1]))
|
|
||||||
{
|
|
||||||
par += ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add character to current parameter
|
|
||||||
else if (parlevel >= 1)
|
|
||||||
{
|
|
||||||
par.append(1, line[pos2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// something went wrong so bail out
|
// something went wrong so bail out
|
||||||
if (!endFound)
|
if (!endFound)
|
||||||
|
|
Loading…
Reference in New Issue