Alien-SmokeQt
view release on metacpan or search on metacpan
generator/parser/rpp/pp-engine.cpp view on Meta::CPAN
++input;
} while (input == '.');
}
while (!input.atEnd() && input == ',')
{
skip_blanks(++input, devnull());
uint formal = skip_identifier(input);
if (formal)
macro->formals.append( IndexedString::fromIndex(formal) );
skip_blanks (input, devnull());
if (input == '.') {
macro->variadics = true;
do {
++input;
} while (input == '.');
}
}
RETURN_ON_FAIL(input == ')');
++input;
}
skip_blanks (input, devnull());
while (!input.atEnd() && input != '\n')
{
if(input == '/' && (input.peekNextCharacter() == '/' || input.peekNextCharacter() == '*')) {
skip_comment_or_divop(input, devnull());
if(!input.atEnd() && input != '\n')
skip_blanks (input, devnull());
continue;
}
if (input == '\\')
{
int pos = input.offset();
skip_blanks (++input, devnull());
if (!input.atEnd() && input == '\n')
{
skip_blanks(++input, devnull());
macro->definition.append(IndexedString::fromIndex(indexFromCharacter(' ')));
continue;
} else {
// Whoops, rewind :)
input.seek(pos);
}
}
macro->definition.append(IndexedString::fromIndex(input.current()));
++input;
}
m_environment->setMacro(macro);
}
void pp::skip (Stream& input, Stream& output, bool outputText)
{
pp_skip_string_literal skip_string_literal;
pp_skip_char_literal skip_char_literal;
while (!input.atEnd() && input != '\n')
{
if (input == '/')
{
skip_comment_or_divop (input, output, outputText);
}
else if (input == '"')
{
skip_string_literal (input, output);
}
else if (input == '\'')
{
skip_char_literal (input, output);
}
else if (input == '\\')
{
output << input;
skip_blanks (++input, output);
if (!input.atEnd() && input == '\n')
{
output << input;
++input;
}
}
else
{
output << input;
++input;
}
}
}
inline bool pp::test_if_level()
{
bool result = !_M_skipping[iflevel++];
_M_skipping[iflevel] = _M_skipping[iflevel - 1];
_M_true_test[iflevel] = false;
return result;
}
inline int pp::skipping() const
{ return _M_skipping[iflevel]; }
Value pp::eval_primary(Stream& input)
{
int start = input.offset();
bool expect_paren = false;
int token = next_token_accept(input);
Value result;
switch (token) {
case TOKEN_NUMBER:
result.set_long(token_value);
break;
case TOKEN_UNUMBER:
result.set_ulong(token_uvalue);
break;
case TOKEN_DEFINED:
token = next_token_accept(input);
if (token == '(')
{
expect_paren = true;
token = next_token_accept(input);
}
if (token != TOKEN_IDENTIFIER)
{
Problem* problem = new Problem;
problem->file = currentFileNameString();
problem->position = input.originalInputPosition();
QChar tk(token);
problem->description = QString("Expected \"identifier\", found: %1").arg((tk < TOKENS_END && tk > TOKENS_START) ? QString(tk) : QString("character %1").arg(token));
problem->explanation = QString("<h5>Token text</h5><pre>%1</pre><h5>Input</h5><pre>%2</pre>").arg(token_text.str())
.arg(QString::fromUtf8(input.stringFrom(start)));
problemEncountered(problem);
break;
}
{
pp_macro* m = m_environment->retrieveMacro(token_text, true);
result.set_long( (m && !m->isUndef()) ? 1 : 0);
}
token = next_token(input); // skip '('
if (expect_paren) {
if (token != ')') {
Problem* problem = new Problem;
problem->file = currentFileNameString();
problem->position = input.originalInputPosition();
QChar tk(token);
problem->description = QString("Expected \")\", found %1").arg(tk.isLetterOrNumber() ? QString(tk) : QString("character %1").arg(token));
problem->explanation = QString("<h5>Token text</h5><pre>%1</pre><h5>Input</h5><pre>%2</pre>").arg(token_text.str())
.arg(QString::fromUtf8(input.stringFrom(start)));
problemEncountered(problem);
} else {
accept_token();
}
}
break;
case TOKEN_IDENTIFIER:
break;
case '-':
result.set_long(- eval_primary(input).l);
break;
case '+':
result.set_long(+ eval_primary(input).l);
break;
case '!':
result.set_long(eval_primary(input).is_zero());
break;
case '(':
result = eval_constant_expression(input);
token = next_token(input);
if (token != ')') {
Problem* problem = new Problem;
problem->file = currentFileNameString();
problem->position = input.originalInputPosition();
QChar tk(token);
problem->description = QString("Expected \")\", found %1").arg(tk.isLetterOrNumber() ? QString(tk) : QString("character %1").arg(token));
problem->explanation = QString("<h5>Token text</h5><pre>%1</pre><h5>Input</h5><pre>%2</pre>").arg(token_text.str())
.arg(QString::fromUtf8(input.stringFrom(start)));
problemEncountered(problem);
} else {
accept_token();
}
break;
default:
break;
}
return result;
generator/parser/rpp/pp-engine.cpp view on Meta::CPAN
}
}
}
void pp::handle_endif(Stream& input, Stream& output)
{
if (iflevel == 0 && !skipping())
{
Problem* problem = new Problem;
problem->file = currentFileNameString();
problem->position = input.originalInputPosition();
problem->description = QString("#endif without #if at output line %1")
.arg(m_environment->locationTable()->anchorForOffset(output.offset()).anchor.line);
problemEncountered(problem);
}
else
{
environment()->leaveBlock();
_M_skipping[iflevel] = 0;
_M_true_test[iflevel] = 0;
--iflevel;
if(iflevel == 0) {
if(!guardCandidate.isEmpty()) {
checkGuardEnd = true;
}
}
}
}
uint pp::branchingHash() const
{
uint hash = 0;
for( int a = 0; a <= iflevel; a++ ) {
hash *= 19;
if( _M_skipping[a] )
hash += 3;
if( _M_true_test[a] )
hash += 7;
}
return hash;
}
void pp::handle_ifdef (bool check_undefined, Stream& input)
{
IndexedString macro_name = IndexedString::fromIndex(skip_identifier(input));
///@todo eventually fix the block description
if(check_undefined && expand.in_header_section() && guardCandidate.isEmpty() && !hadGuardCandidate && iflevel == 0) {
//It's the first #ifndef and the header-section hasn't ended yet, assume it to be the header-guard
guardCandidate = macro_name;
}
hadGuardCandidate = true;
environment()->enterBlock(input.inputPosition().line);//, QString("%1defined(%2)").arg(check_undefined ? "!" : "").arg(macro_name).toUtf8());
if (test_if_level())
{
pp_macro* macro = m_environment->retrieveMacro(macro_name, true);
bool value = false;
if( macro && macro->defined )
value = true;
if (check_undefined)
value = !value;
_M_true_test[iflevel] = value;
_M_skipping[iflevel] = !value;
}
}
void pp::handle_undef(Stream& input)
{
skip_blanks (input, devnull());
IndexedString macro_name = IndexedString::fromIndex(skip_identifier(input));
RETURN_ON_FAIL(!macro_name.isEmpty());
pp_macro* macro = new pp_macro;
macro->file = currentFileName();
macro->name = macro_name;
macro->sourceLine = input.originalInputPosition().line;
macro->defined = false;
m_environment->setMacro(macro);
}
IndexedString definedText("defined");
int pp::next_token (Stream& input)
{
if (haveNextToken)
return nextToken;
skip_blanks(input, devnull());
if (input.atEnd())
{
return 0;
}
char ch = 0;
if(isCharacter(input.current()))
ch = characterFromIndex(input.current());
char ch2 = input.peekNextCharacter();
nextToken = 0;
switch (ch) {
case '/':
if (ch2 == '/' || ch2 == '*')
{
skip_comment_or_divop(input, devnull());
return next_token(input);
}
++input;
nextToken = '/';
break;
case '<':
++input;
if (ch2 == '<')
{
++input;
nextToken = TOKEN_LT_LT;
}
else if (ch2 == '=')
{
++input;
nextToken = TOKEN_LT_EQ;
}
else
nextToken = '<';
break;
case '>':
++input;
if (ch2 == '>')
{
++input;
nextToken = TOKEN_GT_GT;
}
else if (ch2 == '=')
{
generator/parser/rpp/pp-engine.cpp view on Meta::CPAN
token_text = IndexedString::fromIndex( skip_identifier (input) );
if (token_text == definedText)
nextToken = TOKEN_DEFINED;
else
nextToken = TOKEN_IDENTIFIER;
}
else if (isNumber(ch))
{
PreprocessedContents byteNumber;
{
Stream ns(&byteNumber);
skip_number(input, ns);
}
QString number(QString::fromUtf8(stringFromContents(byteNumber)));
int base = 10;
if (number.startsWith("0x")) {
base = 16;
} else if (number.startsWith('0')) {
base = 8;
}
if (number.endsWith('u', Qt::CaseInsensitive)) {
token_uvalue = number.toULong(0, base);
nextToken = TOKEN_UNUMBER;
} else {
token_value = number.toLong(0, base);
nextToken = TOKEN_NUMBER;
}
}
else
{
if(isCharacter(input.current()))
nextToken = characterFromIndex(input.current());
else
nextToken = TOKEN_IDENTIFIER;
++input;
}
}
//kDebug(9007) << "Next token '" << ch << ch2 << "'" << nextToken << "txt" << token_text << "val" << token_value;
haveNextToken = true;
return nextToken;
}
int pp::next_token_accept (Stream& input)
{
int result = next_token(input);
accept_token();
return result;
}
void pp::accept_token()
{
haveNextToken = false;
nextToken = 0;
}
bool pp::hideNextMacro( ) const
{
return hideNext;
}
void pp::setHideNextMacro( bool h )
{
hideNext = h;
}
Environment* pp::environment( ) const
{
return m_environment;
}
void pp::setEnvironment(Environment* env)
{
delete m_environment;
m_environment = env;
}
const QList< Problem* > & rpp::pp::problems() const
{
return m_problems;
}
void rpp::pp::problemEncountered(Problem *problem)
{
m_problems.append(problem);
}
( run in 0.462 second using v1.01-cache-2.11-cpan-71847e10f99 )