summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/features/qscxmlc.prf2
-rw-r--r--src/scxml/qscxmlstatemachineinfo.cpp80
-rw-r--r--src/scxml/qscxmlstatemachineinfo_p.h13
-rw-r--r--tests/auto/scion/scion.pro1
-rw-r--r--tests/auto/statemachineinfo/tst_statemachineinfo.cpp38
-rw-r--r--tools/qscxmlc/decl.t1
-rw-r--r--tools/qscxmlc/doc/qscxmlc.qdoc14
-rw-r--r--tools/qscxmlc/qscxmlc.cpp4
-rw-r--r--tools/qscxmlc/scxmlcppdumper.cpp31
-rw-r--r--tools/qscxmlc/scxmlcppdumper.h4
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> &parameters,
- bool useCxx11)
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters)
{
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;