forked from qt-creator/qt-creator
Some refactoring of the preprocessor, it'll simplify my next commits.
This commit is contained in:
@@ -50,6 +50,8 @@
|
||||
|
||||
#include <Lexer.h>
|
||||
#include <Token.h>
|
||||
#include <Literals.h>
|
||||
|
||||
#include <QtDebug>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -450,7 +452,8 @@ private:
|
||||
Preprocessor::Preprocessor(Client *client, Environment &env)
|
||||
: client(client),
|
||||
env(env),
|
||||
expand(env)
|
||||
_expand(env),
|
||||
_result(0)
|
||||
{
|
||||
resetIfLevel ();
|
||||
}
|
||||
@@ -501,13 +504,23 @@ void Preprocessor::preprocess(const QByteArray &filename,
|
||||
QByteArray *result)
|
||||
{
|
||||
const QByteArray previousFile = env.currentFile;
|
||||
|
||||
env.currentFile = filename;
|
||||
|
||||
preprocess(source, result);
|
||||
|
||||
env.currentFile = previousFile;
|
||||
}
|
||||
|
||||
void Preprocessor::expand(const QByteArray &source, QByteArray *result)
|
||||
{
|
||||
_expand(source, result);
|
||||
}
|
||||
|
||||
void Preprocessor::expand(const char *first, const char *last, QByteArray *result)
|
||||
{
|
||||
const QByteArray source = QByteArray::fromRawData(first, last - first);
|
||||
return expand(source, result);
|
||||
}
|
||||
|
||||
Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source) const
|
||||
{
|
||||
State state;
|
||||
@@ -525,6 +538,9 @@ Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source
|
||||
|
||||
void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
{
|
||||
QByteArray *previousResult = _result;
|
||||
_result = result;
|
||||
|
||||
pushState(createStateFromSource(source));
|
||||
|
||||
const unsigned previousCurrentLine = env.currentLine;
|
||||
@@ -533,16 +549,16 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
while (true) {
|
||||
if (env.currentLine != _dot->lineno) {
|
||||
if (env.currentLine > _dot->lineno) {
|
||||
result->append("\n# ");
|
||||
result->append(QByteArray::number(_dot->lineno));
|
||||
result->append(' ');
|
||||
result->append('"');
|
||||
result->append(env.currentFile);
|
||||
result->append('"');
|
||||
result->append('\n');
|
||||
_result->append("\n# ");
|
||||
_result->append(QByteArray::number(_dot->lineno));
|
||||
_result->append(' ');
|
||||
_result->append('"');
|
||||
_result->append(env.currentFile);
|
||||
_result->append('"');
|
||||
_result->append('\n');
|
||||
} else {
|
||||
for (unsigned i = env.currentLine; i < _dot->lineno; ++i)
|
||||
result->append('\n');
|
||||
_result->append('\n');
|
||||
}
|
||||
env.currentLine = _dot->lineno;
|
||||
}
|
||||
@@ -580,12 +596,12 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
} while (_dot->isNot(T_EOF_SYMBOL) && (_dot->joined || ! _dot->newline));
|
||||
} else {
|
||||
if (_dot->joined)
|
||||
result->append("\\\n");
|
||||
_result->append("\\\n");
|
||||
else if (_dot->whitespace)
|
||||
result->append(' ');
|
||||
_result->append(' ');
|
||||
|
||||
if (_dot->isNot(T_IDENTIFIER)) {
|
||||
result->append(tokenSpell(*_dot));
|
||||
_result->append(tokenSpell(*_dot));
|
||||
++_dot;
|
||||
} else {
|
||||
const TokenIterator identifierToken = _dot;
|
||||
@@ -599,7 +615,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
client->startExpandingMacro(identifierToken->offset,
|
||||
trivial, spell);
|
||||
|
||||
expand(spell.constBegin(), spell.constEnd(), result);
|
||||
expand(spell, _result);
|
||||
|
||||
if (client)
|
||||
client->stopExpandingMacro(_dot->offset, trivial);
|
||||
@@ -609,7 +625,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
|
||||
Macro *m = env.resolve(spell);
|
||||
if (! m) {
|
||||
result->append(spell);
|
||||
_result->append(spell);
|
||||
} else {
|
||||
if (! m->isFunctionLike()) {
|
||||
if (_dot->isNot(T_LPAREN)) {
|
||||
@@ -618,7 +634,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
*m, spell);
|
||||
|
||||
m->setHidden(true);
|
||||
expand(m->definition(), result);
|
||||
expand(m->definition(), _result);
|
||||
m->setHidden(false);
|
||||
|
||||
if (client)
|
||||
@@ -650,7 +666,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
popState();
|
||||
|
||||
if (! m) {
|
||||
result->append(tmp);
|
||||
_result->append(tmp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -659,7 +675,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
// collect the actual arguments
|
||||
if (_dot->isNot(T_LPAREN)) {
|
||||
// ### warnng expected T_LPAREN
|
||||
result->append(m->name());
|
||||
_result->append(m->name());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -689,7 +705,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
*m, text);
|
||||
}
|
||||
|
||||
expand(beginOfText, endOfText, result);
|
||||
expand(beginOfText, endOfText, _result);
|
||||
|
||||
if (client)
|
||||
client->stopExpandingMacro(_dot->offset, *m);
|
||||
@@ -701,6 +717,7 @@ void Preprocessor::preprocess(const QByteArray &source, QByteArray *result)
|
||||
|
||||
popState();
|
||||
env.currentLine = previousCurrentLine;
|
||||
_result = previousResult;
|
||||
}
|
||||
|
||||
const char *Preprocessor::startOfToken(const Token &token) const
|
||||
@@ -788,9 +805,8 @@ QVector<Token> Preprocessor::tokenize(const QByteArray &text) const
|
||||
return tokens;
|
||||
}
|
||||
|
||||
void Preprocessor::processInclude(bool,
|
||||
TokenIterator firstToken, TokenIterator lastToken,
|
||||
bool acceptMacros)
|
||||
void Preprocessor::processInclude(bool, TokenIterator firstToken,
|
||||
TokenIterator lastToken, bool acceptMacros)
|
||||
{
|
||||
RangeLexer tk(firstToken, lastToken);
|
||||
++tk; // skip T_POUND
|
||||
@@ -1011,7 +1027,8 @@ void Preprocessor::processEndif(TokenIterator, TokenIterator)
|
||||
}
|
||||
|
||||
void Preprocessor::processIfdef(bool checkUndefined,
|
||||
TokenIterator firstToken, TokenIterator lastToken)
|
||||
TokenIterator firstToken,
|
||||
TokenIterator lastToken)
|
||||
{
|
||||
RangeLexer tk(firstToken, lastToken);
|
||||
|
||||
@@ -1054,47 +1071,47 @@ void Preprocessor::resetIfLevel ()
|
||||
_true_test[iflevel] = false;
|
||||
}
|
||||
|
||||
Preprocessor::PP_DIRECTIVE_TYPE Preprocessor::classifyDirective (const QByteArray &__directive) const
|
||||
Preprocessor::PP_DIRECTIVE_TYPE Preprocessor::classifyDirective(const QByteArray &directive) const
|
||||
{
|
||||
switch (__directive.size())
|
||||
switch (directive.size())
|
||||
{
|
||||
case 2:
|
||||
if (__directive[0] == 'i' && __directive[1] == 'f')
|
||||
if (directive[0] == 'i' && directive[1] == 'f')
|
||||
return PP_IF;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (__directive[0] == 'e' && __directive == "elif")
|
||||
if (directive[0] == 'e' && directive == "elif")
|
||||
return PP_ELIF;
|
||||
else if (__directive[0] == 'e' && __directive == "else")
|
||||
else if (directive[0] == 'e' && directive == "else")
|
||||
return PP_ELSE;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (__directive[0] == 'i' && __directive == "ifdef")
|
||||
if (directive[0] == 'i' && directive == "ifdef")
|
||||
return PP_IFDEF;
|
||||
else if (__directive[0] == 'u' && __directive == "undef")
|
||||
else if (directive[0] == 'u' && directive == "undef")
|
||||
return PP_UNDEF;
|
||||
else if (__directive[0] == 'e' && __directive == "endif")
|
||||
else if (directive[0] == 'e' && directive == "endif")
|
||||
return PP_ENDIF;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (__directive[0] == 'i' && __directive == "ifndef")
|
||||
if (directive[0] == 'i' && directive == "ifndef")
|
||||
return PP_IFNDEF;
|
||||
else if (__directive[0] == 'i' && __directive == "import")
|
||||
else if (directive[0] == 'i' && directive == "import")
|
||||
return PP_IMPORT;
|
||||
else if (__directive[0] == 'd' && __directive == "define")
|
||||
else if (directive[0] == 'd' && directive == "define")
|
||||
return PP_DEFINE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (__directive[0] == 'i' && __directive == "include")
|
||||
if (directive[0] == 'i' && directive == "include")
|
||||
return PP_INCLUDE;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (__directive[0] == 'i' && __directive == "include_next")
|
||||
if (directive[0] == 'i' && directive == "include_next")
|
||||
return PP_INCLUDE_NEXT;
|
||||
break;
|
||||
|
||||
@@ -1117,7 +1134,7 @@ int Preprocessor::skipping() const
|
||||
{ return _skipping[iflevel]; }
|
||||
|
||||
Value Preprocessor::evalExpression(TokenIterator firstToken, TokenIterator lastToken,
|
||||
const QByteArray &source) const
|
||||
const QByteArray &source) const
|
||||
{
|
||||
ExpressionEvaluator eval(&env);
|
||||
const Value result = eval(firstToken, lastToken, source);
|
||||
|
||||
@@ -60,174 +60,180 @@ namespace CPlusPlus {
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
struct Value
|
||||
struct Value
|
||||
{
|
||||
enum Kind {
|
||||
Kind_Long,
|
||||
Kind_ULong,
|
||||
};
|
||||
|
||||
Kind kind;
|
||||
|
||||
union {
|
||||
long l;
|
||||
unsigned long ul;
|
||||
};
|
||||
|
||||
|
||||
Value()
|
||||
: kind(Kind_Long), l(0)
|
||||
{ }
|
||||
|
||||
inline bool is_ulong () const
|
||||
{ return kind == Kind_ULong; }
|
||||
|
||||
inline void set_ulong (unsigned long v)
|
||||
{
|
||||
enum Kind {
|
||||
Kind_Long,
|
||||
Kind_ULong,
|
||||
};
|
||||
ul = v;
|
||||
kind = Kind_ULong;
|
||||
}
|
||||
|
||||
Kind kind;
|
||||
inline void set_long (long v)
|
||||
{
|
||||
l = v;
|
||||
kind = Kind_Long;
|
||||
}
|
||||
|
||||
union {
|
||||
long l;
|
||||
unsigned long ul;
|
||||
};
|
||||
|
||||
|
||||
Value()
|
||||
: kind(Kind_Long), l(0)
|
||||
{ }
|
||||
|
||||
inline bool is_ulong () const
|
||||
{ return kind == Kind_ULong; }
|
||||
|
||||
inline void set_ulong (unsigned long v)
|
||||
{
|
||||
ul = v;
|
||||
kind = Kind_ULong;
|
||||
}
|
||||
|
||||
inline void set_long (long v)
|
||||
{
|
||||
l = v;
|
||||
kind = Kind_Long;
|
||||
}
|
||||
|
||||
inline bool is_zero () const
|
||||
{ return l == 0; }
|
||||
inline bool is_zero () const
|
||||
{ return l == 0; }
|
||||
|
||||
#define PP_DEFINE_BIN_OP(name, op) \
|
||||
inline Value operator op(const Value &other) const \
|
||||
{ \
|
||||
Value v = *this; \
|
||||
if (v.is_ulong () || other.is_ulong ()) \
|
||||
v.set_ulong (v.ul op other.ul); \
|
||||
else \
|
||||
v.set_long (v.l op other.l); \
|
||||
return v; \
|
||||
}
|
||||
inline Value operator op(const Value &other) const \
|
||||
{ \
|
||||
Value v = *this; \
|
||||
if (v.is_ulong () || other.is_ulong ()) \
|
||||
v.set_ulong (v.ul op other.ul); \
|
||||
else \
|
||||
v.set_long (v.l op other.l); \
|
||||
return v; \
|
||||
}
|
||||
|
||||
PP_DEFINE_BIN_OP(op_add, +)
|
||||
PP_DEFINE_BIN_OP(op_sub, -)
|
||||
PP_DEFINE_BIN_OP(op_mult, *)
|
||||
PP_DEFINE_BIN_OP(op_div, /)
|
||||
PP_DEFINE_BIN_OP(op_mod, %)
|
||||
PP_DEFINE_BIN_OP(op_lhs, <<)
|
||||
PP_DEFINE_BIN_OP(op_rhs, >>)
|
||||
PP_DEFINE_BIN_OP(op_lt, <)
|
||||
PP_DEFINE_BIN_OP(op_gt, >)
|
||||
PP_DEFINE_BIN_OP(op_le, <=)
|
||||
PP_DEFINE_BIN_OP(op_ge, >=)
|
||||
PP_DEFINE_BIN_OP(op_eq, ==)
|
||||
PP_DEFINE_BIN_OP(op_ne, !=)
|
||||
PP_DEFINE_BIN_OP(op_bit_and, &)
|
||||
PP_DEFINE_BIN_OP(op_bit_or, |)
|
||||
PP_DEFINE_BIN_OP(op_bit_xor, ^)
|
||||
PP_DEFINE_BIN_OP(op_and, &&)
|
||||
PP_DEFINE_BIN_OP(op_or, ||)
|
||||
PP_DEFINE_BIN_OP(op_add, +)
|
||||
PP_DEFINE_BIN_OP(op_sub, -)
|
||||
PP_DEFINE_BIN_OP(op_mult, *)
|
||||
PP_DEFINE_BIN_OP(op_div, /)
|
||||
PP_DEFINE_BIN_OP(op_mod, %)
|
||||
PP_DEFINE_BIN_OP(op_lhs, <<)
|
||||
PP_DEFINE_BIN_OP(op_rhs, >>)
|
||||
PP_DEFINE_BIN_OP(op_lt, <)
|
||||
PP_DEFINE_BIN_OP(op_gt, >)
|
||||
PP_DEFINE_BIN_OP(op_le, <=)
|
||||
PP_DEFINE_BIN_OP(op_ge, >=)
|
||||
PP_DEFINE_BIN_OP(op_eq, ==)
|
||||
PP_DEFINE_BIN_OP(op_ne, !=)
|
||||
PP_DEFINE_BIN_OP(op_bit_and, &)
|
||||
PP_DEFINE_BIN_OP(op_bit_or, |)
|
||||
PP_DEFINE_BIN_OP(op_bit_xor, ^)
|
||||
PP_DEFINE_BIN_OP(op_and, &&)
|
||||
PP_DEFINE_BIN_OP(op_or, ||)
|
||||
|
||||
#undef PP_DEFINE_BIN_OP
|
||||
};
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT Preprocessor
|
||||
class CPLUSPLUS_EXPORT Preprocessor
|
||||
{
|
||||
public:
|
||||
Preprocessor(Client *client, Environment &env);
|
||||
|
||||
QByteArray operator()(const QByteArray &filename,
|
||||
const QByteArray &source);
|
||||
|
||||
QByteArray operator()(const QByteArray &source);
|
||||
|
||||
private:
|
||||
enum { MAX_LEVEL = 512 };
|
||||
|
||||
enum PP_DIRECTIVE_TYPE
|
||||
{
|
||||
Client *client;
|
||||
Environment &env;
|
||||
MacroExpander expand;
|
||||
|
||||
enum { MAX_LEVEL = 512 };
|
||||
|
||||
bool _skipping[MAX_LEVEL]; // ### move in state
|
||||
bool _true_test[MAX_LEVEL]; // ### move in state
|
||||
int iflevel; // ### move in state
|
||||
|
||||
enum PP_DIRECTIVE_TYPE
|
||||
{
|
||||
PP_UNKNOWN_DIRECTIVE,
|
||||
PP_DEFINE,
|
||||
PP_IMPORT,
|
||||
PP_INCLUDE,
|
||||
PP_INCLUDE_NEXT,
|
||||
PP_ELIF,
|
||||
PP_ELSE,
|
||||
PP_ENDIF,
|
||||
PP_IF,
|
||||
PP_IFDEF,
|
||||
PP_IFNDEF,
|
||||
PP_UNDEF
|
||||
};
|
||||
|
||||
typedef const CPlusPlus::Token *TokenIterator;
|
||||
|
||||
struct State {
|
||||
QByteArray source;
|
||||
QVector<CPlusPlus::Token> tokens;
|
||||
TokenIterator dot;
|
||||
};
|
||||
|
||||
QList<State> _savedStates;
|
||||
|
||||
State state() const;
|
||||
void pushState(const State &state);
|
||||
void popState();
|
||||
|
||||
QByteArray _source;
|
||||
QVector<CPlusPlus::Token> _tokens;
|
||||
TokenIterator _dot;
|
||||
|
||||
State createStateFromSource(const QByteArray &source) const;
|
||||
|
||||
public:
|
||||
Preprocessor(Client *client, Environment &env);
|
||||
|
||||
QByteArray operator()(const QByteArray &filename,
|
||||
const QByteArray &source);
|
||||
|
||||
QByteArray operator()(const QByteArray &source);
|
||||
|
||||
private:
|
||||
void preprocess(const QByteArray &filename,
|
||||
const QByteArray &source,
|
||||
QByteArray *result);
|
||||
|
||||
void preprocess(const QByteArray &source,
|
||||
QByteArray *result);
|
||||
|
||||
void resetIfLevel();
|
||||
bool testIfLevel();
|
||||
int skipping() const;
|
||||
|
||||
PP_DIRECTIVE_TYPE classifyDirective(const QByteArray &directive) const;
|
||||
|
||||
Value evalExpression(TokenIterator firstToken,
|
||||
TokenIterator lastToken,
|
||||
const QByteArray &source) const;
|
||||
|
||||
QVector<CPlusPlus::Token> tokenize(const QByteArray &text) const;
|
||||
|
||||
const char *startOfToken(const CPlusPlus::Token &token) const;
|
||||
const char *endOfToken(const CPlusPlus::Token &token) const;
|
||||
|
||||
QByteArray tokenSpell(const CPlusPlus::Token &token) const;
|
||||
QByteArray tokenText(const CPlusPlus::Token &token) const; // does a deep copy
|
||||
|
||||
void processDirective(TokenIterator dot, TokenIterator lastToken);
|
||||
void processInclude(bool skipCurrentPath,
|
||||
TokenIterator dot, TokenIterator lastToken,
|
||||
bool acceptMacros = true);
|
||||
void processDefine(TokenIterator dot, TokenIterator lastToken);
|
||||
void processIf(TokenIterator dot, TokenIterator lastToken);
|
||||
void processElse(TokenIterator dot, TokenIterator lastToken);
|
||||
void processElif(TokenIterator dot, TokenIterator lastToken);
|
||||
void processEndif(TokenIterator dot, TokenIterator lastToken);
|
||||
void processIfdef(bool checkUndefined,
|
||||
TokenIterator dot, TokenIterator lastToken);
|
||||
void processUndef(TokenIterator dot, TokenIterator lastToken);
|
||||
|
||||
bool isQtReservedWord(const QByteArray &name) const;
|
||||
PP_UNKNOWN_DIRECTIVE,
|
||||
PP_DEFINE,
|
||||
PP_IMPORT,
|
||||
PP_INCLUDE,
|
||||
PP_INCLUDE_NEXT,
|
||||
PP_ELIF,
|
||||
PP_ELSE,
|
||||
PP_ENDIF,
|
||||
PP_IF,
|
||||
PP_IFDEF,
|
||||
PP_IFNDEF,
|
||||
PP_UNDEF
|
||||
};
|
||||
|
||||
typedef const CPlusPlus::Token *TokenIterator;
|
||||
|
||||
struct State {
|
||||
QByteArray source;
|
||||
QVector<CPlusPlus::Token> tokens;
|
||||
TokenIterator dot;
|
||||
};
|
||||
|
||||
void preprocess(const QByteArray &filename,
|
||||
const QByteArray &source,
|
||||
QByteArray *result);
|
||||
|
||||
void preprocess(const QByteArray &source,
|
||||
QByteArray *result);
|
||||
|
||||
void expand(const QByteArray &source, QByteArray *result);
|
||||
void expand(const char *first, const char *last, QByteArray *result);
|
||||
|
||||
void resetIfLevel();
|
||||
bool testIfLevel();
|
||||
int skipping() const;
|
||||
|
||||
PP_DIRECTIVE_TYPE classifyDirective(const QByteArray &directive) const;
|
||||
|
||||
Value evalExpression(TokenIterator firstToken,
|
||||
TokenIterator lastToken,
|
||||
const QByteArray &source) const;
|
||||
|
||||
QVector<CPlusPlus::Token> tokenize(const QByteArray &text) const;
|
||||
|
||||
const char *startOfToken(const CPlusPlus::Token &token) const;
|
||||
const char *endOfToken(const CPlusPlus::Token &token) const;
|
||||
|
||||
QByteArray tokenSpell(const CPlusPlus::Token &token) const;
|
||||
QByteArray tokenText(const CPlusPlus::Token &token) const; // does a deep copy
|
||||
|
||||
void processDirective(TokenIterator dot, TokenIterator lastToken);
|
||||
void processInclude(bool skipCurrentPath,
|
||||
TokenIterator dot, TokenIterator lastToken,
|
||||
bool acceptMacros = true);
|
||||
void processDefine(TokenIterator dot, TokenIterator lastToken);
|
||||
void processIf(TokenIterator dot, TokenIterator lastToken);
|
||||
void processElse(TokenIterator dot, TokenIterator lastToken);
|
||||
void processElif(TokenIterator dot, TokenIterator lastToken);
|
||||
void processEndif(TokenIterator dot, TokenIterator lastToken);
|
||||
void processIfdef(bool checkUndefined,
|
||||
TokenIterator dot, TokenIterator lastToken);
|
||||
void processUndef(TokenIterator dot, TokenIterator lastToken);
|
||||
|
||||
bool isQtReservedWord(const QByteArray &name) const;
|
||||
|
||||
State state() const;
|
||||
void pushState(const State &state);
|
||||
void popState();
|
||||
|
||||
State createStateFromSource(const QByteArray &source) const;
|
||||
|
||||
private:
|
||||
Client *client;
|
||||
Environment &env;
|
||||
MacroExpander _expand;
|
||||
|
||||
bool _skipping[MAX_LEVEL]; // ### move in state
|
||||
bool _true_test[MAX_LEVEL]; // ### move in state
|
||||
int iflevel; // ### move in state
|
||||
|
||||
QList<State> _savedStates;
|
||||
|
||||
QByteArray _source;
|
||||
QVector<CPlusPlus::Token> _tokens;
|
||||
TokenIterator _dot;
|
||||
|
||||
QByteArray *_result;
|
||||
};
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
||||
#endif // CPLUSPLUS_PP_ENGINE_H
|
||||
|
||||
@@ -69,8 +69,14 @@ const QByteArray *MacroExpander::resolve_formal(const QByteArray &__name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *MacroExpander::operator () (const char *__first, const char *__last,
|
||||
QByteArray *__result)
|
||||
const char *MacroExpander::operator()(const char *first, const char *last,
|
||||
QByteArray *result)
|
||||
{
|
||||
return expand(first, last, result);
|
||||
}
|
||||
|
||||
const char *MacroExpander::expand(const char *__first, const char *__last,
|
||||
QByteArray *__result)
|
||||
{
|
||||
generated_lines = 0;
|
||||
__first = skip_blanks (__first, __last);
|
||||
|
||||
@@ -88,6 +88,9 @@ namespace CPlusPlus {
|
||||
QByteArray *result)
|
||||
{ return operator()(source.constBegin(), source.constEnd(), result); }
|
||||
|
||||
const char *expand(const char *first, const char *last,
|
||||
QByteArray *result);
|
||||
|
||||
const char *skip_argument_variadics (const QVector<QByteArray> &actuals,
|
||||
Macro *macro,
|
||||
const char *first, const char *last);
|
||||
|
||||
Reference in New Issue
Block a user