aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/libparser/node
diff options
context:
space:
mode:
authorRenaud Guezennec <renaud@rolisteam.org>2024-12-28 15:00:29 +0100
committerRenaud Guezennec <renaud@rolisteam.org>2024-12-29 14:46:30 +0100
commit5c508b351a95f416e4a599f76902b888369de1b4 (patch)
treee3f6363fd7458fb0a46eabde6bd3a65b4746d798 /src/libparser/node
parent5515cd5a22ab97843f6ca1c234333ec110a9bab1 (diff)
downloadOneRoll-5c508b351a95f416e4a599f76902b888369de1b4.tar.gz
OneRoll-5c508b351a95f416e4a599f76902b888369de1b4.zip
Several fix from fuzzer test.
Diffstat (limited to 'src/libparser/node')
-rw-r--r--src/libparser/node/bind.cpp37
-rw-r--r--src/libparser/node/executionnode.cpp19
-rw-r--r--src/libparser/node/executionnode.h5
-rw-r--r--src/libparser/node/jumpbackwardnode.cpp9
-rw-r--r--src/libparser/node/jumpbackwardnode.h1
-rw-r--r--src/libparser/node/mergenode.cpp98
-rw-r--r--src/libparser/node/mergenode.h6
-rw-r--r--src/libparser/node/rerolldicenode.cpp61
8 files changed, 137 insertions, 99 deletions
diff --git a/src/libparser/node/bind.cpp b/src/libparser/node/bind.cpp
index 41449d8..9c502df 100644
--- a/src/libparser/node/bind.cpp
+++ b/src/libparser/node/bind.cpp
@@ -38,27 +38,36 @@ void BindNode::run(ExecutionNode* previous)
for(auto start : *m_startList)
{
ExecutionNode* last= getLatestNode(start);
- if(nullptr != last)
+ if(!last)
+ continue;
+
+ auto tmpResult= last->getResult();
+ QSet<Result*> alreadyVisited;
+ while(nullptr != tmpResult && !alreadyVisited.contains(tmpResult))
{
- auto tmpResult= last->getResult();
- while(nullptr != tmpResult)
+ alreadyVisited.insert(tmpResult);
+ DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
+
+ if(nullptr != dice)
{
- DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
- if(nullptr != dice)
+ m_diceResult->setHomogeneous(false);
+ auto list= dice->getResultList();
+ for(int i= 0; i < list.size(); ++i)
{
- m_diceResult->setHomogeneous(false);
- for(auto& die : dice->getResultList())
+ auto die= list[i];
+
+ if(!die)
+ continue;
+
+ if(!die->hasBeenDisplayed())
{
- if(!die->hasBeenDisplayed())
- {
- Die* tmpdie= new Die(*die);
- die->displayed();
- m_diceResult->getResultList().append(tmpdie);
- }
+ Die* tmpdie= new Die(*die);
+ die->displayed();
+ m_diceResult->getResultList().append(tmpdie);
}
}
- tmpResult= tmpResult->getPrevious();
}
+ tmpResult= tmpResult->getPrevious();
}
}
}
diff --git a/src/libparser/node/executionnode.cpp b/src/libparser/node/executionnode.cpp
index 096c8fe..b231416 100644
--- a/src/libparser/node/executionnode.cpp
+++ b/src/libparser/node/executionnode.cpp
@@ -2,6 +2,16 @@
#include <QUuid>
+namespace
+{
+#ifdef QT_DEBUG
+constexpr int WaitingTime{2 * 1000 * 60};
+#else
+constexpr int WaitingTime{30 * 60 * 1000};
+#endif
+
+} // namespace
+
ExecutionNode::ExecutionNode()
: m_previousNode(nullptr)
, m_result(nullptr)
@@ -43,12 +53,19 @@ ExecutionNode* ExecutionNode::getNextNode()
void ExecutionNode::execute(ExecutionNode* previous)
{
+ QElapsedTimer timer;
+ timer.start();
+
auto errorCount= m_errors.count();
run(previous);
- if(m_nextNode && errorCount == m_errors.count())
+ auto timeLimit= timer.hasExpired(WaitingTime);
+
+ if(m_nextNode && errorCount == m_errors.count() && !timeLimit)
m_nextNode->execute(this);
+ else if(timeLimit)
+ qDebug() << "Error too long" << WaitingTime << timeLimit << timer.elapsed();
}
QMap<Dice::ERROR_CODE, QString> ExecutionNode::getExecutionErrorMap()
diff --git a/src/libparser/node/executionnode.h b/src/libparser/node/executionnode.h
index 342ae36..a2912e3 100644
--- a/src/libparser/node/executionnode.h
+++ b/src/libparser/node/executionnode.h
@@ -6,6 +6,7 @@
#include <diceparser/diceparserhelper.h>
#include <QCoreApplication>
+#include <QElapsedTimer>
/**
* @brief The ExecutionNode class
*/
@@ -87,7 +88,7 @@ public:
protected:
/**
- * @brief m_nextNode
+ * @brief previous
*/
ExecutionNode* m_previousNode= nullptr;
/**
@@ -102,9 +103,7 @@ protected:
* @brief m_errors
*/
QMap<Dice::ERROR_CODE, QString> m_errors;
-
QMap<Dice::ERROR_CODE, QString> m_warnings;
-
QString m_id;
};
diff --git a/src/libparser/node/jumpbackwardnode.cpp b/src/libparser/node/jumpbackwardnode.cpp
index e4ae59a..3e2f4c1 100644
--- a/src/libparser/node/jumpbackwardnode.cpp
+++ b/src/libparser/node/jumpbackwardnode.cpp
@@ -29,6 +29,11 @@ JumpBackwardNode::JumpBackwardNode()
m_result= m_diceResult;
}
+JumpBackwardNode::~JumpBackwardNode()
+{
+ delete m_diceResult;
+}
+
qint64 JumpBackwardNode::getPriority() const
{
return 4;
@@ -126,13 +131,13 @@ void JumpBackwardNode::run(ExecutionNode* previous)
for(auto& die : diceResult->getResultList())
{
Die* tmpdie= new Die(*die);
- //*tmpdie= *die;
m_diceResult->insertResult(tmpdie);
die->displayed();
}
}
- m_result->setPrevious(previous->getResult());
+ if(m_result && previous)
+ m_result->setPrevious(previous->getResult());
if(m_nextNode)
m_nextNode->execute(this);
diff --git a/src/libparser/node/jumpbackwardnode.h b/src/libparser/node/jumpbackwardnode.h
index 5f20291..2e14a00 100644
--- a/src/libparser/node/jumpbackwardnode.h
+++ b/src/libparser/node/jumpbackwardnode.h
@@ -33,6 +33,7 @@ public:
* @brief JumpBackwardNode allows to get result from remote node in the execution tree.
*/
JumpBackwardNode();
+ virtual ~JumpBackwardNode();
/**
* @brief run - performs the actions
* @param previous
diff --git a/src/libparser/node/mergenode.cpp b/src/libparser/node/mergenode.cpp
index 4c19bd7..8f30289 100644
--- a/src/libparser/node/mergenode.cpp
+++ b/src/libparser/node/mergenode.cpp
@@ -23,75 +23,82 @@
#include <diceparser/parsingtoolbox.h>
-MergeNode::MergeNode() : m_diceResult(new DiceResult())
+MergeNode::MergeNode(std::vector<ExecutionNode*>& startList) : m_startList(startList), m_diceResult(new DiceResult())
{
m_result= m_diceResult;
}
+
+int findDistance(const std::vector<ExecutionNode*>& startList, MergeNode* node)
+{
+ int i= 0;
+ for(auto start : startList)
+ {
+ auto temp= start;
+ while(temp != nullptr)
+ {
+ if(temp == node)
+ return i;
+ temp= temp->getNextNode();
+ }
+ ++i;
+ }
+ return i;
+}
void MergeNode::run(ExecutionNode* previous)
{
if(isValid(!previous, Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No previous node before Merge operator")))
return;
- m_previousNode= previous;
- m_result->setPrevious(previous->getResult());
- ExecutionNode* previousLast= nullptr;
- std::vector<Result*> pastResult;
- if(!m_startList)
+ // m_previousNode= previous;
+ // m_result->setPrevious(previous->getResult());
+ // std::vector<Result*> pastResult;
+ if(isValid(m_startList.empty(), Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No several instruction")))
return;
- for(auto start : *m_startList)
- {
- ExecutionNode* last= getLatestNode(start);
- if(nullptr == last || nullptr == previousLast)
- {
- previousLast= last;
- continue;
- }
-
- auto startResult= start->getResult();
- if(nullptr == startResult)
- continue;
+ auto instId= findDistance(m_startList, this);
- startResult->setPrevious(previousLast->getResult());
- previousLast->setNextNode(start);
+ ExecutionNode* previousLast= nullptr;
+ std::for_each(std::begin(m_startList), std::end(m_startList),
+ [&previousLast, this](ExecutionNode* node)
+ {
+ ExecutionNode* last= getLatestNode(node);
+ if(previousLast)
+ {
+ previousLast->setNextNode(node);
+ auto resultNode= node->getResult();
+ if(resultNode)
+ resultNode->setPrevious(previousLast->getResult());
+ }
+ previousLast= last;
+ });
- previousLast= last;
- Result* tmpResult= last->getResult();
+ if(instId != 0)
+ {
+ Result* tmpResult= previous->getResult();
while(nullptr != tmpResult)
{
DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
- if(nullptr != dice)
+ if(nullptr != dice && dice != m_diceResult)
{
- ///@todo TODO improve here to set homogeneous while is really
m_diceResult->setHomogeneous(false);
+
for(auto& die : dice->getResultList())
{
if(!m_diceResult->getResultList().contains(die) && (!die->hasBeenDisplayed()))
{
Die* tmpdie= new Die(*die);
die->displayed();
- m_diceResult->getResultList().append(tmpdie);
+ m_diceResult->insertResult(tmpdie);
}
}
}
- auto it= std::find_if(pastResult.begin(), pastResult.end(),
- [tmpResult](const Result* a) { return (a == tmpResult->getPrevious()); });
- if(it == pastResult.end())
- {
- pastResult.push_back(previousLast->getResult());
- tmpResult= tmpResult->getPrevious();
- }
- else
- {
- tmpResult->setPrevious(nullptr);
- tmpResult= nullptr;
- }
+ tmpResult= tmpResult->getPrevious();
}
}
- auto first= m_startList->front();
- m_startList->clear();
- m_startList->push_back(first);
+ auto first= m_startList.front();
+ m_startList.clear();
+ m_startList.push_back(first);
}
#include <QDebug>
ExecutionNode* MergeNode::getLatestNode(ExecutionNode* node)
@@ -126,7 +133,7 @@ qint64 MergeNode::getPriority() const
}
ExecutionNode* MergeNode::getCopy() const
{
- MergeNode* node= new MergeNode();
+ MergeNode* node= new MergeNode(m_startList);
if(nullptr != m_nextNode)
{
node->setNextNode(m_nextNode->getCopy());
@@ -134,12 +141,7 @@ ExecutionNode* MergeNode::getCopy() const
return node;
}
-std::vector<ExecutionNode*>* MergeNode::getStartList() const
-{
- return m_startList;
-}
-
-void MergeNode::setStartList(std::vector<ExecutionNode*>* startList)
+/*void MergeNode::setStartList(const std::vector<ExecutionNode*>& startList)
{
m_startList= startList;
-}
+}*/
diff --git a/src/libparser/node/mergenode.h b/src/libparser/node/mergenode.h
index 515a2e9..1b32352 100644
--- a/src/libparser/node/mergenode.h
+++ b/src/libparser/node/mergenode.h
@@ -31,20 +31,18 @@
class MergeNode : public ExecutionNode
{
public:
- MergeNode();
+ MergeNode(std::vector<ExecutionNode*>& startList);
void run(ExecutionNode* previous);
virtual QString toString(bool withLabel) const;
virtual qint64 getPriority() const;
virtual ExecutionNode* getCopy() const;
- std::vector<ExecutionNode*>* getStartList() const;
- void setStartList(std::vector<ExecutionNode*>* startList);
private:
ExecutionNode* getLatestNode(ExecutionNode* node);
private:
+ std::vector<ExecutionNode*>& m_startList;
DiceResult* m_diceResult= nullptr;
- std::vector<ExecutionNode*>* m_startList= nullptr;
};
#endif // NUMBERNODE_H
diff --git a/src/libparser/node/rerolldicenode.cpp b/src/libparser/node/rerolldicenode.cpp
index af075ce..25143ac 100644
--- a/src/libparser/node/rerolldicenode.cpp
+++ b/src/libparser/node/rerolldicenode.cpp
@@ -19,74 +19,81 @@ RerollDiceNode::~RerollDiceNode()
}
void RerollDiceNode::run(ExecutionNode* previous)
{
- if(isValid(!previous, Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No Previous node")))
+ using DE= Dice::ERROR_CODE;
+ using DC= Dice::CONDITION_STATE;
+ if(isValid(!previous, DE::NO_PREVIOUS_ERROR, tr("No Previous node")))
return;
m_previousNode= previous;
auto previousDiceResult= previous->getResult();
- if(isValid(!previousDiceResult, Dice::ERROR_CODE::NO_VALID_RESULT, tr("No Valid result")))
+ if(isValid(!previousDiceResult, DE::NO_VALID_RESULT, tr("No Valid result")))
return;
DiceResult* previous_result= dynamic_cast<DiceResult*>(previousDiceResult);
- if(isValid(!previous_result, Dice::ERROR_CODE::DIE_RESULT_EXPECTED,
+ if(isValid(!previous_result, DE::DIE_RESULT_EXPECTED,
tr(" The a operator expects dice result. Please check the documentation and fix your command.")))
return;
m_result->setPrevious(previous_result);
- for(auto& die : previous_result->getResultList())
+ for(auto const& die : previous_result->getResultList())
{
+ if(!die)
+ return;
+
Die* tmpdie= new Die(*die);
m_diceResult->insertResult(tmpdie);
die->displayed();
}
- // m_diceResult->setResultList(list);
QList<Die*>& list= m_diceResult->getResultList();
QList<Die*> toRemove;
- for(auto& die : list)
+ for(int i= 0; i < list.size(); ++i)
{
+ auto die= list[i];
+ if(!die)
+ continue;
+
bool finished= false;
auto state
= m_validatorList->isValidRangeSize(std::make_pair<qint64, qint64>(die->getBase(), die->getMaxValue()));
- if((Dice::CONDITION_STATE::ALWAYSTRUE == state && m_adding)
- || (!m_reroll && !m_adding && state == Dice::CONDITION_STATE::UNREACHABLE))
+
+ if(isValid((DC::ALWAYSTRUE == state && m_adding) || (!m_reroll && !m_adding && state == DC::UNREACHABLE),
+ DE::ENDLESS_LOOP_ERROR,
+ QStringLiteral("Condition cause an endless loop with this dice: %1")
+ .arg(QStringLiteral("d[%1,%2]")
+ .arg(static_cast<int>(die->getBase()))
+ .arg(static_cast<int>(die->getMaxValue())))))
{
- m_errors.insert(Dice::ERROR_CODE::ENDLESS_LOOP_ERROR,
- QObject::tr("Condition (%1) cause an endless loop with this dice: %2")
- .arg(toString(true))
- .arg(QStringLiteral("d[%1,%2]")
- .arg(static_cast<int>(die->getBase()))
- .arg(static_cast<int>(die->getMaxValue()))));
continue;
}
+
while(m_validatorList->hasValid(die, false) && !finished)
{
- if(m_instruction != nullptr)
+ if(m_instruction)
{
m_instruction->execute(this);
auto lastNode= ParsingToolBox::getLeafNode(m_instruction);
- if(lastNode != nullptr)
+ if(lastNode == nullptr)
+ continue;
+ auto lastResult= dynamic_cast<DiceResult*>(lastNode->getResult());
+ if(lastResult != nullptr)
{
- auto lastResult= dynamic_cast<DiceResult*>(lastNode->getResult());
- if(lastResult != nullptr)
- {
- toRemove.append(die);
- list.append(lastResult->getResultList());
- lastResult->clear();
- }
+ toRemove.append(die);
+ if(list.size() < lastResult->getResultList().size())
+ break;
+ list.append(lastResult->getResultList());
+ die= list[i];
+ lastResult->clear();
}
}
else
{
die->roll(m_adding);
}
- if(m_reroll)
- {
- finished= true;
- }
+ finished= m_reroll;
}
}