forked from qt-creator/qt-creator
directly link ProItems instead of using QList<ProItem*>
somewhat faster again
This commit is contained in:
@@ -192,11 +192,23 @@ public:
|
|||||||
|
|
||||||
/////////////// Reading pro file
|
/////////////// Reading pro file
|
||||||
|
|
||||||
|
struct BlockCursor {
|
||||||
|
BlockCursor() : cursor(0) {}
|
||||||
|
BlockCursor(ProBlock *blk) : block(blk), cursor(blk->itemsRef()) {}
|
||||||
|
~BlockCursor() { if (cursor) *cursor = 0; }
|
||||||
|
void set(ProBlock *blk) { if (cursor) *cursor = 0; block = blk; cursor = blk->itemsRef(); }
|
||||||
|
void reset() { if (cursor) { *cursor = 0; cursor = 0; } }
|
||||||
|
void append(ProItem *item) { *cursor = item; cursor = item->nextRef(); }
|
||||||
|
bool isValid() const { return cursor != 0; }
|
||||||
|
ProBlock *block;
|
||||||
|
ProItem **cursor;
|
||||||
|
};
|
||||||
|
|
||||||
bool read(ProFile *pro);
|
bool read(ProFile *pro);
|
||||||
bool read(ProBlock *pro, const QString &content);
|
bool read(ProBlock *pro, const QString &content);
|
||||||
bool readInternal(ProBlock *pro, const QString &content, ushort *buf);
|
bool readInternal(ProBlock *pro, const QString &content, ushort *buf);
|
||||||
|
|
||||||
ProBlock *currentBlock();
|
BlockCursor ¤tBlock();
|
||||||
void updateItem(ushort *uc, ushort *ptr);
|
void updateItem(ushort *uc, ushort *ptr);
|
||||||
ProVariable *startVariable(ushort *uc, ushort *ptr);
|
ProVariable *startVariable(ushort *uc, ushort *ptr);
|
||||||
void finalizeVariable(ProVariable *var, ushort *uc, ushort *ptr);
|
void finalizeVariable(ProVariable *var, ushort *uc, ushort *ptr);
|
||||||
@@ -205,8 +217,8 @@ public:
|
|||||||
void leaveScope();
|
void leaveScope();
|
||||||
void finalizeBlock();
|
void finalizeBlock();
|
||||||
|
|
||||||
QStack<ProBlock *> m_blockstack;
|
QStack<BlockCursor> m_blockstack;
|
||||||
ProBlock *m_block;
|
BlockCursor m_block;
|
||||||
|
|
||||||
/////////////// Evaluating pro file contents
|
/////////////// Evaluating pro file contents
|
||||||
|
|
||||||
@@ -355,9 +367,7 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, const QString &content)
|
|||||||
bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, ushort *buf)
|
bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, ushort *buf)
|
||||||
{
|
{
|
||||||
// Parser state
|
// Parser state
|
||||||
m_block = 0;
|
m_blockstack.push(BlockCursor(pro));
|
||||||
m_blockstack.clear();
|
|
||||||
m_blockstack.push(pro);
|
|
||||||
|
|
||||||
// We rely on QStrings being null-terminated, so don't maintain a global end pointer.
|
// We rely on QStrings being null-terminated, so don't maintain a global end pointer.
|
||||||
const ushort *cur = (const ushort *)in.unicode();
|
const ushort *cur = (const ushort *)in.unicode();
|
||||||
@@ -387,6 +397,8 @@ bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, u
|
|||||||
++m_lineNo;
|
++m_lineNo;
|
||||||
goto freshLine;
|
goto freshLine;
|
||||||
}
|
}
|
||||||
|
m_block.reset();
|
||||||
|
m_blockstack.clear(); // FIXME: should actually check the state here
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (c != ' ' && c != '\t' && c != '\r')
|
if (c != ' ' && c != '\t' && c != '\r')
|
||||||
@@ -560,9 +572,9 @@ bool ProFileEvaluator::Private::readInternal(ProBlock *pro, const QString &in, u
|
|||||||
|
|
||||||
void ProFileEvaluator::Private::finalizeBlock()
|
void ProFileEvaluator::Private::finalizeBlock()
|
||||||
{
|
{
|
||||||
if (m_blockstack.top()->blockKind() & ProBlock::SingleLine)
|
if (m_blockstack.top().block->blockKind() & ProBlock::SingleLine)
|
||||||
leaveScope();
|
leaveScope();
|
||||||
m_block = 0;
|
m_block.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProVariable *ProFileEvaluator::Private::startVariable(ushort *uc, ushort *ptr)
|
ProVariable *ProFileEvaluator::Private::startVariable(ushort *uc, ushort *ptr)
|
||||||
@@ -610,8 +622,7 @@ void ProFileEvaluator::Private::finalizeVariable(ProVariable *variable, ushort *
|
|||||||
{
|
{
|
||||||
variable->setValue(QString((QChar*)uc, ptr - uc));
|
variable->setValue(QString((QChar*)uc, ptr - uc));
|
||||||
|
|
||||||
ProBlock *block = m_blockstack.top();
|
m_blockstack.top().append(variable);
|
||||||
block->appendItem(variable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::insertOperator(const char op)
|
void ProFileEvaluator::Private::insertOperator(const char op)
|
||||||
@@ -628,28 +639,27 @@ void ProFileEvaluator::Private::insertOperator(const char op)
|
|||||||
opkind = ProOperator::OrOperator;
|
opkind = ProOperator::OrOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProBlock * const block = currentBlock();
|
|
||||||
ProOperator * const proOp = new ProOperator(opkind);
|
ProOperator * const proOp = new ProOperator(opkind);
|
||||||
proOp->setLineNumber(m_lineNo);
|
proOp->setLineNumber(m_lineNo);
|
||||||
block->appendItem(proOp);
|
currentBlock().append(proOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::enterScope(bool multiLine)
|
void ProFileEvaluator::Private::enterScope(bool multiLine)
|
||||||
{
|
{
|
||||||
ProBlock *parent = currentBlock();
|
BlockCursor &parent = currentBlock();
|
||||||
|
|
||||||
ProBlock *block = new ProBlock();
|
ProBlock *block = new ProBlock();
|
||||||
block->setLineNumber(m_lineNo);
|
block->setLineNumber(m_lineNo);
|
||||||
parent->setBlockKind(ProBlock::ScopeKind);
|
|
||||||
|
|
||||||
parent->appendItem(block);
|
|
||||||
|
|
||||||
if (multiLine)
|
if (multiLine)
|
||||||
block->setBlockKind(ProBlock::ScopeContentsKind);
|
block->setBlockKind(ProBlock::ScopeContentsKind);
|
||||||
else
|
else
|
||||||
block->setBlockKind(ProBlock::ScopeContentsKind|ProBlock::SingleLine);
|
block->setBlockKind(ProBlock::ScopeContentsKind|ProBlock::SingleLine);
|
||||||
|
m_blockstack.push(BlockCursor(block));
|
||||||
|
|
||||||
m_blockstack.push(block);
|
parent.block->setBlockKind(ProBlock::ScopeKind);
|
||||||
m_block = 0;
|
parent.append(block);
|
||||||
|
|
||||||
|
m_block.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::leaveScope()
|
void ProFileEvaluator::Private::leaveScope()
|
||||||
@@ -661,16 +671,14 @@ void ProFileEvaluator::Private::leaveScope()
|
|||||||
finalizeBlock();
|
finalizeBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProBlock *ProFileEvaluator::Private::currentBlock()
|
ProFileEvaluator::Private::BlockCursor &ProFileEvaluator::Private::currentBlock()
|
||||||
{
|
{
|
||||||
if (m_block)
|
if (!m_block.isValid()) {
|
||||||
return m_block;
|
ProBlock *blk = new ProBlock();
|
||||||
|
blk->setLineNumber(m_lineNo);
|
||||||
ProBlock *parent = m_blockstack.top();
|
m_blockstack.top().append(blk);
|
||||||
m_block = new ProBlock();
|
m_block.set(blk);
|
||||||
m_block->setLineNumber(m_lineNo);
|
}
|
||||||
parent->appendItem(m_block);
|
|
||||||
|
|
||||||
return m_block;
|
return m_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,7 +689,6 @@ void ProFileEvaluator::Private::updateItem(ushort *uc, ushort *ptr)
|
|||||||
|
|
||||||
QString proItem = QString((QChar*)uc, ptr - uc);
|
QString proItem = QString((QChar*)uc, ptr - uc);
|
||||||
|
|
||||||
ProBlock *block = currentBlock();
|
|
||||||
ProItem *item;
|
ProItem *item;
|
||||||
if (proItem.endsWith(QLatin1Char(')'))) {
|
if (proItem.endsWith(QLatin1Char(')'))) {
|
||||||
item = new ProFunction(proItem);
|
item = new ProFunction(proItem);
|
||||||
@@ -689,7 +696,7 @@ void ProFileEvaluator::Private::updateItem(ushort *uc, ushort *ptr)
|
|||||||
item = new ProCondition(proItem);
|
item = new ProCondition(proItem);
|
||||||
}
|
}
|
||||||
item->setLineNumber(m_lineNo);
|
item->setLineNumber(m_lineNo);
|
||||||
block->appendItem(item);
|
currentBlock().append(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////// Evaluator tools /////////
|
//////// Evaluator tools /////////
|
||||||
@@ -866,15 +873,14 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProBlock(ProBlock *block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProItem::ProItemReturn rt = ProItem::ReturnTrue;
|
ProItem::ProItemReturn rt = ProItem::ReturnTrue;
|
||||||
QList<ProItem *> items = block->items();
|
for (ProItem *item = block->items(); item; item = item->next()) {
|
||||||
for (int i = 0; i < items.count(); ++i) {
|
rt = visitProItem(item);
|
||||||
rt = visitProItem(items.at(i));
|
|
||||||
if (rt != ProItem::ReturnTrue && rt != ProItem::ReturnFalse) {
|
if (rt != ProItem::ReturnTrue && rt != ProItem::ReturnFalse) {
|
||||||
if (rt == ProItem::ReturnLoop) {
|
if (rt == ProItem::ReturnLoop) {
|
||||||
rt = ProItem::ReturnTrue;
|
rt = ProItem::ReturnTrue;
|
||||||
while (visitProLoopIteration())
|
while (visitProLoopIteration())
|
||||||
for (int j = i; ++j < items.count(); ) {
|
for (ProItem *lItem = item; (lItem = lItem->next()); ) {
|
||||||
rt = visitProItem(items.at(j));
|
rt = visitProItem(lItem);
|
||||||
if (rt != ProItem::ReturnTrue && rt != ProItem::ReturnFalse) {
|
if (rt != ProItem::ReturnTrue && rt != ProItem::ReturnFalse) {
|
||||||
if (rt == ProItem::ReturnNext) {
|
if (rt == ProItem::ReturnNext) {
|
||||||
rt = ProItem::ReturnTrue;
|
rt = ProItem::ReturnTrue;
|
||||||
|
|||||||
@@ -36,17 +36,20 @@ QT_BEGIN_NAMESPACE
|
|||||||
ProBlock::ProBlock()
|
ProBlock::ProBlock()
|
||||||
: ProItem(BlockKind)
|
: ProItem(BlockKind)
|
||||||
{
|
{
|
||||||
|
m_proitems = 0;
|
||||||
m_blockKind = 0;
|
m_blockKind = 0;
|
||||||
m_refCount = 1;
|
m_refCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProBlock::~ProBlock()
|
ProBlock::~ProBlock()
|
||||||
{
|
{
|
||||||
foreach (ProItem *itm, m_proitems)
|
for (ProItem *itm, *nitm = m_proitems; (itm = nitm); ) {
|
||||||
|
nitm = itm->m_next;
|
||||||
if (itm->kind() == BlockKind)
|
if (itm->kind() == BlockKind)
|
||||||
static_cast<ProBlock *>(itm)->deref();
|
static_cast<ProBlock *>(itm)->deref();
|
||||||
else
|
else
|
||||||
delete itm;
|
delete itm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFile::ProFile(const QString &fileName)
|
ProFile::ProFile(const QString &fileName)
|
||||||
|
|||||||
@@ -63,9 +63,15 @@ public:
|
|||||||
int lineNumber() const { return m_lineNumber; }
|
int lineNumber() const { return m_lineNumber; }
|
||||||
void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
|
void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
|
||||||
|
|
||||||
|
ProItem *next() const { return m_next; }
|
||||||
|
ProItem **nextRef() { return &m_next; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ProItem *m_next;
|
||||||
ProItemKind m_kind;
|
ProItemKind m_kind;
|
||||||
int m_lineNumber;
|
int m_lineNumber;
|
||||||
|
|
||||||
|
friend class ProBlock; // C++ is braindead ...
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProBlock : public ProItem
|
class ProBlock : public ProItem
|
||||||
@@ -83,16 +89,17 @@ public:
|
|||||||
ProBlock();
|
ProBlock();
|
||||||
~ProBlock();
|
~ProBlock();
|
||||||
|
|
||||||
void appendItem(ProItem *proitem) { m_proitems << proitem; }
|
|
||||||
QList<ProItem *> items() const { return m_proitems; }
|
|
||||||
void setBlockKind(int blockKind) { m_blockKind = blockKind; }
|
void setBlockKind(int blockKind) { m_blockKind = blockKind; }
|
||||||
int blockKind() const { return m_blockKind; }
|
int blockKind() const { return m_blockKind; }
|
||||||
|
|
||||||
|
ProItem *items() const { return m_proitems; }
|
||||||
|
ProItem **itemsRef() { return &m_proitems; }
|
||||||
|
|
||||||
void ref() { ++m_refCount; }
|
void ref() { ++m_refCount; }
|
||||||
void deref() { if (!--m_refCount) delete this; }
|
void deref() { if (!--m_refCount) delete this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<ProItem *> m_proitems;
|
ProItem *m_proitems;
|
||||||
int m_blockKind;
|
int m_blockKind;
|
||||||
int m_refCount;
|
int m_refCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines,
|
|||||||
const QStringList &vars)
|
const QStringList &vars)
|
||||||
{
|
{
|
||||||
// Check if variable item exists as child of root item
|
// Check if variable item exists as child of root item
|
||||||
foreach (ProItem *item, profile->items()) {
|
for (ProItem *item = profile->items(); item; item = item->next()) {
|
||||||
if (item->kind() == ProItem::VariableKind) {
|
if (item->kind() == ProItem::VariableKind) {
|
||||||
ProVariable *proVar = static_cast<ProVariable*>(item);
|
ProVariable *proVar = static_cast<ProVariable*>(item);
|
||||||
if (vars.contains(proVar->variable())
|
if (vars.contains(proVar->variable())
|
||||||
@@ -87,7 +87,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines,
|
|||||||
static void findProVariables(ProBlock *block, const QStringList &vars,
|
static void findProVariables(ProBlock *block, const QStringList &vars,
|
||||||
QList<ProVariable *> *proVars)
|
QList<ProVariable *> *proVars)
|
||||||
{
|
{
|
||||||
foreach (ProItem *item, block->items()) {
|
for (ProItem *item = block->items(); item; item = item->next()) {
|
||||||
if (item->kind() == ProItem::BlockKind) {
|
if (item->kind() == ProItem::BlockKind) {
|
||||||
findProVariables(static_cast<ProBlock*>(item), vars, proVars);
|
findProVariables(static_cast<ProBlock*>(item), vars, proVars);
|
||||||
} else if (item->kind() == ProItem::VariableKind) {
|
} else if (item->kind() == ProItem::VariableKind) {
|
||||||
|
|||||||
Reference in New Issue
Block a user