diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2016-11-29 12:32:50 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2016-11-29 12:32:50 +0100 |
commit | bc476e8803b1be71014a4cd6a93abfcbb04465e5 (patch) | |
tree | 3fa5a2fa65bec6b68ca2fa4f576cafecbcef2491 | |
parent | 20f1f1b1a027dfe5dcdd91d25590095e99eb2bf3 (diff) | |
parent | 8a3dae92910e9df5817d9cde16aef81e76bfc60f (diff) |
Merge 5.8 into 5.8.0
Change-Id: I8fa59d8b2559aa620eb533ed4274ea1b7374d2c7
-rw-r--r-- | mkspecs/features/qscxmlc.prf | 2 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachineinfo.cpp | 80 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachineinfo_p.h | 13 | ||||
-rw-r--r-- | tests/auto/scion/scion.pro | 1 | ||||
-rw-r--r-- | tests/auto/statemachineinfo/tst_statemachineinfo.cpp | 38 | ||||
-rw-r--r-- | tools/qscxmlc/decl.t | 1 | ||||
-rw-r--r-- | tools/qscxmlc/doc/qscxmlc.qdoc | 14 | ||||
-rw-r--r-- | tools/qscxmlc/qscxmlc.cpp | 4 | ||||
-rw-r--r-- | tools/qscxmlc/scxmlcppdumper.cpp | 31 | ||||
-rw-r--r-- | tools/qscxmlc/scxmlcppdumper.h | 4 |
10 files changed, 125 insertions, 63 deletions
diff --git a/mkspecs/features/qscxmlc.prf b/mkspecs/features/qscxmlc.prf index 674abcb..25f1f10 100644 --- a/mkspecs/features/qscxmlc.prf +++ b/mkspecs/features/qscxmlc.prf @@ -9,8 +9,6 @@ debug_and_release { QSCXMLC_DIR = $$QSCXMLC_DIR$$SUFFIX -msvc:lessThan(MSC_VER,1800):QMAKE_QSCXMLC=$$QMAKE_QSCXMLC --no-c++11 # VS2012 cannot handle initializer lists. - { qscxmlc.name = QSCXMLC ${QMAKE_FILE_IN}.h qscxmlc.input = STATECHARTS diff --git a/src/scxml/qscxmlstatemachineinfo.cpp b/src/scxml/qscxmlstatemachineinfo.cpp index d3a23f9..d81956a 100644 --- a/src/scxml/qscxmlstatemachineinfo.cpp +++ b/src/scxml/qscxmlstatemachineinfo.cpp @@ -64,6 +64,13 @@ QScxmlStateMachineInfo::QScxmlStateMachineInfo(QScxmlStateMachine *stateMachine) QScxmlStateMachinePrivate::get(stateMachine)->attach(this); } +QScxmlStateMachine *QScxmlStateMachineInfo::stateMachine() const +{ + Q_D(const QScxmlStateMachineInfo); + + return d->stateMachine(); +} + QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::allStates() const { Q_D(const QScxmlStateMachineInfo); @@ -90,16 +97,9 @@ QString QScxmlStateMachineInfo::stateName(int stateId) const { Q_D(const QScxmlStateMachineInfo); - if (stateId < StateMachineRootState && stateId >= d->stateTable()->stateCount) + if (stateId < 0 || stateId >= d->stateTable()->stateCount) return QString(); - if (stateId == StateMachineRootState) { - if (d->stateTable()->name < 0) - return QString(); - else - return d->stateMachinePrivate()->m_tableData->string(d->stateTable()->name); - } - auto state = d->stateTable()->state(stateId); if (state.name >= 0) return d->stateMachinePrivate()->m_tableData->string(state.name); @@ -107,16 +107,24 @@ QString QScxmlStateMachineInfo::stateName(int stateId) const return QString(); } +QScxmlStateMachineInfo::StateId QScxmlStateMachineInfo::stateParent(StateId stateId) const +{ + Q_D(const QScxmlStateMachineInfo); + + if (stateId < 0 || stateId >= d->stateTable()->stateCount) + return InvalidStateId; + + auto state = d->stateTable()->state(stateId); + return state.parent; +} + QScxmlStateMachineInfo::StateType QScxmlStateMachineInfo::stateType(StateId stateId) const { Q_D(const QScxmlStateMachineInfo); - if (stateId < StateMachineRootState || stateId >= d->stateTable()->stateCount) + if (stateId < 0 || stateId >= d->stateTable()->stateCount) return InvalidState; - if (stateId == -1) - return StateMachineRootState; - auto state = d->stateTable()->state(stateId); switch (state.type) { default: return InvalidState; @@ -132,12 +140,18 @@ QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::stateChildren(S { Q_D(const QScxmlStateMachineInfo); + int childStates = QScxmlExecutableContent::StateTable::InvalidIndex; + if (stateId == InvalidStateId) + childStates = d->stateTable()->childStates; + if (stateId >= 0 && stateId < d->stateTable()->stateCount) + childStates = d->stateTable()->state(stateId).childStates; + QVector<QScxmlStateMachineInfo::StateId> all; - auto state = d->stateTable()->state(stateId); - if (state.childStates == QScxmlExecutableContent::StateTable::InvalidIndex) + if (childStates == QScxmlExecutableContent::StateTable::InvalidIndex) return all; - auto kids = d->stateTable()->array(state.childStates); + const auto kids = d->stateTable()->array(childStates); + all.reserve(kids.size()); for (auto childId : kids) { all.append(childId); } @@ -161,12 +175,25 @@ QScxmlStateMachineInfo::TransitionType QScxmlStateMachineInfo::transitionType(QS } } +QScxmlStateMachineInfo::TransitionId QScxmlStateMachineInfo::initialTransition(StateId stateId) const +{ + Q_D(const QScxmlStateMachineInfo); + + if (stateId == InvalidStateId) + return d->stateTable()->initialTransition; + + if (stateId < 0 || stateId >= d->stateTable()->stateCount) + return InvalidTransitionId; + + return d->stateTable()->state(stateId).initialTransition; +} + QScxmlStateMachineInfo::StateId QScxmlStateMachineInfo::transitionSource(TransitionId transitionId) const { Q_D(const QScxmlStateMachineInfo); if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount) - return InvalidState; + return InvalidStateId; auto transition = d->stateTable()->transition(transitionId); return transition.source; @@ -191,6 +218,27 @@ QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::transitionTarge return targets; } +QVector<QString> QScxmlStateMachineInfo::transitionEvents(TransitionId transitionId) const +{ + Q_D(const QScxmlStateMachineInfo); + + QVector<QString> events; + if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount) + return events; + + auto transition = d->stateTable()->transition(transitionId); + if (transition.events == QScxmlExecutableContent::StateTable::InvalidIndex) + return events; + + auto eventIds = d->stateTable()->array(transition.events); + events.reserve(eventIds.size()); + for (auto eventId : eventIds) { + events.append(d->stateMachinePrivate()->m_tableData->string(eventId)); + } + + return events; +} + QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::configuration() const { Q_D(const QScxmlStateMachineInfo); diff --git a/src/scxml/qscxmlstatemachineinfo_p.h b/src/scxml/qscxmlstatemachineinfo_p.h index a80ef35..7a8ca50 100644 --- a/src/scxml/qscxmlstatemachineinfo_p.h +++ b/src/scxml/qscxmlstatemachineinfo_p.h @@ -66,15 +66,19 @@ class Q_SCXML_EXPORT QScxmlStateMachineInfo: public QObject public: // types typedef int StateId; typedef int TransitionId; + + static const StateId InvalidStateId = -1; + static const TransitionId InvalidTransitionId = -1; + enum StateType : int { - InvalidState = -2, - StateMachineRootState = -1, + InvalidState = -1, NormalState = 0, ParallelState = 1, FinalState = 2, ShallowHistoryState = 3, DeepHistoryState = 4 }; + enum TransitionType : int { InvalidTransition = -1, InternalTransition = 0, @@ -85,14 +89,19 @@ public: // types public: // methods QScxmlStateMachineInfo(QScxmlStateMachine *stateMachine); + QScxmlStateMachine *stateMachine() const; + QVector<StateId> allStates() const; QVector<TransitionId> allTransitions() const; QString stateName(int stateId) const; + StateId stateParent(StateId stateId) const; StateType stateType(int stateId) const; QVector<StateId> stateChildren(StateId stateId) const; + TransitionId initialTransition(StateId stateId) const; TransitionType transitionType(TransitionId transitionId) const; StateId transitionSource(TransitionId transitionId) const; QVector<StateId> transitionTargets(TransitionId transitionId) const; + QVector<QString> transitionEvents(TransitionId transitionId) const; QVector<StateId> configuration() const; Q_SIGNALS: diff --git a/tests/auto/scion/scion.pro b/tests/auto/scion/scion.pro index 84d7b28..6e1f7f4 100644 --- a/tests/auto/scion/scion.pro +++ b/tests/auto/scion/scion.pro @@ -28,7 +28,6 @@ defineReplace(nameTheClass) { qtPrepareTool(QMAKE_QSCXMLC, qscxmlc) win32 { - QMAKE_QSCXMLC += --no-c++11 msvc: QMAKE_CXXFLAGS += /bigobj } diff --git a/tests/auto/statemachineinfo/tst_statemachineinfo.cpp b/tests/auto/statemachineinfo/tst_statemachineinfo.cpp index 1c33847..b1ecfe7 100644 --- a/tests/auto/statemachineinfo/tst_statemachineinfo.cpp +++ b/tests/auto/statemachineinfo/tst_statemachineinfo.cpp @@ -98,7 +98,7 @@ void tst_StateMachineInfo::checkInfo() auto info = new QScxmlStateMachineInfo(stateMachine.data()); const QString machineName = QLatin1String("InfoTest"); - QCOMPARE(info->stateName(QScxmlStateMachineInfo::StateMachineRootState), machineName); + QCOMPARE(stateMachine->name(), machineName); auto states = info->allStates(); QCOMPARE(states.size(), 5); @@ -108,45 +108,76 @@ void tst_StateMachineInfo::checkInfo() QCOMPARE(info->stateName(states.at(3)), QLatin1String("b")); QCOMPARE(info->stateName(states.at(4)), QLatin1String("theEnd")); + QCOMPARE(info->stateParent(QScxmlStateMachineInfo::InvalidState), + static_cast<int>(QScxmlStateMachineInfo::InvalidStateId)); + QCOMPARE(info->stateParent(states.at(0)), static_cast<int>(QScxmlStateMachineInfo::InvalidStateId)); + QCOMPARE(info->stateParent(states.at(1)), static_cast<int>(QScxmlStateMachineInfo::InvalidStateId)); + QCOMPARE(info->stateParent(states.at(2)), 1); + QCOMPARE(info->stateParent(states.at(3)), 1); + QCOMPARE(info->stateParent(states.at(4)), static_cast<int>(QScxmlStateMachineInfo::InvalidStateId)); + QCOMPARE(info->stateType(states.at(0)), QScxmlStateMachineInfo::NormalState); QCOMPARE(info->stateType(states.at(1)), QScxmlStateMachineInfo::ParallelState); QCOMPARE(info->stateType(states.at(2)), QScxmlStateMachineInfo::NormalState); QCOMPARE(info->stateType(states.at(3)), QScxmlStateMachineInfo::NormalState); QCOMPARE(info->stateType(states.at(4)), QScxmlStateMachineInfo::FinalState); + QCOMPARE(info->stateChildren(QScxmlStateMachineInfo::InvalidStateId), + QVector<int>() << 0 << 1 << 4); + QCOMPARE(info->stateChildren(states.at(0)), QVector<int>()); + QCOMPARE(info->stateChildren(states.at(1)), QVector<int>() << 2 << 3); + QCOMPARE(info->stateChildren(states.at(2)), QVector<int>()); + QCOMPARE(info->stateChildren(states.at(3)), QVector<int>()); + QCOMPARE(info->stateChildren(states.at(4)), QVector<int>()); + + QCOMPARE(info->initialTransition(QScxmlStateMachineInfo::InvalidStateId), 4); + QCOMPARE(info->initialTransition(states.at(0)), static_cast<int>(QScxmlStateMachineInfo::InvalidTransitionId)); + QCOMPARE(info->initialTransition(states.at(1)), 5); + QCOMPARE(info->initialTransition(states.at(2)), static_cast<int>(QScxmlStateMachineInfo::InvalidTransitionId)); + QCOMPARE(info->initialTransition(states.at(3)), static_cast<int>(QScxmlStateMachineInfo::InvalidTransitionId)); + QCOMPARE(info->initialTransition(states.at(4)), static_cast<int>(QScxmlStateMachineInfo::InvalidTransitionId)); + auto transitions = info->allTransitions(); QCOMPARE(transitions.size(), 6); // targetless transition on top level QCOMPARE(info->transitionType(transitions.at(0)), QScxmlStateMachineInfo::ExternalTransition); QCOMPARE(info->stateType(info->transitionSource(transitions.at(0))), - QScxmlStateMachineInfo::StateMachineRootState); + QScxmlStateMachineInfo::InvalidState); QCOMPARE(info->transitionTargets(transitions.at(0)).size(), 0); + QCOMPARE(info->transitionEvents(transitions.at(0)).size(), 0); // <anon>->next QCOMPARE(info->transitionType(transitions.at(1)), QScxmlStateMachineInfo::ExternalTransition); QCOMPARE(info->transitionSource(transitions.at(1)), states.at(0)); QCOMPARE(info->transitionTargets(transitions.at(1)).size(), 1); QCOMPARE(info->transitionTargets(transitions.at(1)).at(0), states.at(1)); + QCOMPARE(info->transitionEvents(transitions.at(1)).size(), 1); + QCOMPARE(info->transitionEvents(transitions.at(1)).at(0), QStringLiteral("step")); // a->theEnd QCOMPARE(info->transitionType(transitions.at(2)), QScxmlStateMachineInfo::ExternalTransition); QCOMPARE(info->transitionSource(transitions.at(2)), states.at(2)); QCOMPARE(info->transitionTargets(transitions.at(2)).size(), 1); QCOMPARE(info->transitionTargets(transitions.at(2)).at(0), states.at(4)); + QCOMPARE(info->transitionEvents(transitions.at(2)).size(), 1); + QCOMPARE(info->transitionEvents(transitions.at(2)).at(0), QStringLiteral("step")); // b->theEnd QCOMPARE(info->transitionType(transitions.at(3)), QScxmlStateMachineInfo::InternalTransition); QCOMPARE(info->transitionSource(transitions.at(3)), states.at(3)); QCOMPARE(info->transitionTargets(transitions.at(3)).size(), 1); QCOMPARE(info->transitionTargets(transitions.at(3)).at(0), states.at(4)); + QCOMPARE(info->transitionEvents(transitions.at(3)).size(), 1); + QCOMPARE(info->transitionEvents(transitions.at(3)).at(0), QStringLiteral("step")); // initial transition that activates the first (anonymous) state QCOMPARE(info->transitionType(transitions.at(4)), QScxmlStateMachineInfo::SyntheticTransition); QCOMPARE(info->stateType(info->transitionSource(transitions.at(4))), - QScxmlStateMachineInfo::StateMachineRootState); + QScxmlStateMachineInfo::InvalidState); QCOMPARE(info->transitionTargets(transitions.at(4)).size(), 1); QCOMPARE(info->transitionTargets(transitions.at(4)).at(0), states.at(0)); + QCOMPARE(info->transitionEvents(transitions.at(4)).size(), 0); // "initial" transition in the next state that activates all sub-states QCOMPARE(info->transitionType(transitions.at(5)), QScxmlStateMachineInfo::SyntheticTransition); @@ -154,6 +185,7 @@ void tst_StateMachineInfo::checkInfo() QCOMPARE(info->transitionTargets(transitions.at(5)).size(), 2); QCOMPARE(info->transitionTargets(transitions.at(5)).at(0), states.at(2)); QCOMPARE(info->transitionTargets(transitions.at(5)).at(1), states.at(3)); + QCOMPARE(info->transitionEvents(transitions.at(5)).size(), 0); Recorder recorder; QObject::connect(info, &QScxmlStateMachineInfo::statesEntered, diff --git a/tools/qscxmlc/decl.t b/tools/qscxmlc/decl.t index 09d6f72..648476d 100644 --- a/tools/qscxmlc/decl.t +++ b/tools/qscxmlc/decl.t @@ -1,6 +1,5 @@ class ${classname}: public QScxmlStateMachine { -public: /* qmake ignore Q_OBJECT */ Q_OBJECT ${properties} diff --git a/tools/qscxmlc/doc/qscxmlc.qdoc b/tools/qscxmlc/doc/qscxmlc.qdoc index f0d6726..07b5c8d 100644 --- a/tools/qscxmlc/doc/qscxmlc.qdoc +++ b/tools/qscxmlc/doc/qscxmlc.qdoc @@ -65,23 +65,21 @@ \li Option \li Description \row - \li \c -no-c++11 - \li Use no C++11 features in the generated code. - \row - \li \c {-namespace <namespace>} - \li Put the generated class(es) in the specified namespace. + \li \c {--namespace <namespace>} + \li Put the generated class(es) in the specified namespace. You can use the + \c QSCXMLC_NAMESPACE variable to specify this in your project file. \row \li \c {-o <base/out/name>} \li The base name of the output files. This can include a path. If none is specified, the basename of the input file is used. \row - \li \c {-oh <header/out>} + \li \c {--header <header/out>} \li The name of the output header file. If none is specified, .h is added to the base name. \row - \li \c {-ocpp <cpp/out>} + \li \c {--impl <cpp/out>} \li The name of the output header file. If none is specified, .cpp is added to the base name. \row - \li \c {-classname <StateMachineClassName>} + \li \c {--classname <StateMachineClassName>} \li The class name of the generated state machine. If none is specified, the value of the name attribute of the <scxml> tag is taken. If that attribute is not specified either, the basename (excluding path) is taken from the input file name. diff --git a/tools/qscxmlc/qscxmlc.cpp b/tools/qscxmlc/qscxmlc.cpp index de97a18..89abdaa 100644 --- a/tools/qscxmlc/qscxmlc.cpp +++ b/tools/qscxmlc/qscxmlc.cpp @@ -107,8 +107,6 @@ int run(const QStringList &arguments) cmdParser.setApplicationDescription(QCoreApplication::translate("main", "Compiles the given input.scxml file to a header and a cpp file.")); - QCommandLineOption optionNoCxx11(QLatin1String("no-c++11"), - QCoreApplication::translate("main", "Don't use C++11 in generated code.")); QCommandLineOption optionNamespace(QLatin1String("namespace"), QCoreApplication::translate("main", "Put generated code into <namespace>."), QCoreApplication::translate("main", "namespace")); @@ -127,7 +125,6 @@ int run(const QStringList &arguments) cmdParser.addPositionalArgument(QLatin1String("input"), QCoreApplication::translate("main", "Input SCXML file.")); - cmdParser.addOption(optionNoCxx11); cmdParser.addOption(optionNamespace); cmdParser.addOption(optionOutputBaseName); cmdParser.addOption(optionOutputHeaderName); @@ -152,7 +149,6 @@ int run(const QStringList &arguments) const QString scxmlFileName = inputFiles.at(0); TranslationUnit options; - options.useCxx11 = !cmdParser.isSet(optionNoCxx11); if (cmdParser.isSet(optionNamespace)) options.namespaceName = cmdParser.value(optionNamespace); QString outFileName = cmdParser.value(optionOutputBaseName); diff --git a/tools/qscxmlc/scxmlcppdumper.cpp b/tools/qscxmlc/scxmlcppdumper.cpp index aa207bb..f5e9b2e 100644 --- a/tools/qscxmlc/scxmlcppdumper.cpp +++ b/tools/qscxmlc/scxmlcppdumper.cpp @@ -143,28 +143,17 @@ static const char *headerStart = using namespace DocumentModel; -QString createContainer(const QString &baseType, const QString &elementType, - const QStringList &elements, bool useCxx11) +QString createContainer(const QStringList &elements) { QString result; - if (useCxx11) { - if (elements.isEmpty()) { - result += QStringLiteral("{}"); - } else { - result += QStringLiteral("{ ") + elements.join(QStringLiteral(", ")) + QStringLiteral(" }"); - } + if (elements.isEmpty()) { + result += QStringLiteral("{}"); } else { - result += QStringLiteral("%1< %2 >()").arg(baseType, elementType); - if (!elements.isEmpty()) { - result += QStringLiteral(" << ") + elements.join(QStringLiteral(" << ")); - } + result += QStringLiteral("{ ") + elements.join(QStringLiteral(", ")) + QStringLiteral(" }"); } return result; } -QString createVector(const QString &elementType, const QStringList &elements, bool useCxx11) -{ return createContainer(QStringLiteral("QVector"), elementType, elements, useCxx11); } - static void generateList(QString &out, std::function<QString(int)> next) { const int maxLineLength = 80; @@ -380,8 +369,7 @@ int createFactoryId(QStringList &factories, const QString &className, const QString &namespacePrefix, const QScxmlExecutableContent::InvokeInfo &invokeInfo, const QVector<QScxmlExecutableContent::StringId> &namelist, - const QVector<QScxmlExecutableContent::ParameterInfo> ¶meters, - bool useCxx11) + const QVector<QScxmlExecutableContent::ParameterInfo> ¶meters) { const int idx = factories.size(); @@ -405,8 +393,7 @@ int createFactoryId(QStringList &factories, const QString &className, for (auto name : namelist) { l.append(QString::number(name)); } - line += QStringLiteral("%1, ").arg( - createVector(QStringLiteral("QScxmlExecutableContent::StringId"), l, useCxx11)); + line += QStringLiteral("%1, ").arg(createContainer(l)); } { QStringList l; @@ -416,9 +403,7 @@ int createFactoryId(QStringList &factories, const QString &className, QString::number(parameter.expr), QString::number(parameter.location)); } - line += QStringLiteral("%1);").arg( - createVector(QStringLiteral("QScxmlExecutableContent::ParameterInfo"), l, - useCxx11)); + line += QStringLiteral("%1);").arg(createContainer(l)); } factories.append(line); @@ -464,7 +449,7 @@ void CppDumper::dump(TranslationUnit *unit) className = mangleIdentifier(classnameForDocument.value(content.data())); } return createFactoryId(factories[i], className, namespacePrefix, - invokeInfo, names, parameters, m_translationUnit->useCxx11); + invokeInfo, names, parameters); }); classNames.append(mangleIdentifier(classnameForDocument.value(doc))); } diff --git a/tools/qscxmlc/scxmlcppdumper.h b/tools/qscxmlc/scxmlcppdumper.h index 2d6b12c..95fa48a 100644 --- a/tools/qscxmlc/scxmlcppdumper.h +++ b/tools/qscxmlc/scxmlcppdumper.h @@ -41,14 +41,12 @@ QT_BEGIN_NAMESPACE struct TranslationUnit { TranslationUnit() - : useCxx11(true) - , mainDocument(Q_NULLPTR) + : mainDocument(Q_NULLPTR) {} QString scxmlFileName; QString outHFileName, outCppFileName; QString namespaceName; - bool useCxx11; DocumentModel::ScxmlDocument *mainDocument; QList<DocumentModel::ScxmlDocument *> allDocuments; QHash<DocumentModel::ScxmlDocument *, QString> classnameForDocument; |