summaryrefslogtreecommitdiffstats
path: root/apps/uscxml-dot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/uscxml-dot.cpp')
-rw-r--r--apps/uscxml-dot.cpp92
1 files changed, 62 insertions, 30 deletions
diff --git a/apps/uscxml-dot.cpp b/apps/uscxml-dot.cpp
index 3324e54..56f5c57 100644
--- a/apps/uscxml-dot.cpp
+++ b/apps/uscxml-dot.cpp
@@ -7,6 +7,7 @@
#include "uscxml/Factory.h"
#include <boost/algorithm/string.hpp>
+
using namespace uscxml;
void printUsageAndExit(const char* progName) {
@@ -19,12 +20,17 @@ void printUsageAndExit(const char* progName) {
printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str());
printf("Usage\n");
printf("\t%s", progStr.c_str());
- printf(" [-dN_0] URL");
- printf(" [[-dN_1] state_id1] .. [[-dN_M] state_idM]");
+ printf(" [-eTYPE] [-dN] [-tN] URL");
+ printf(" [[-dN] [-tN] [-eTYPE] state_id1] .. [[-dN] [-tN] [-eTYPE] state_idM]");
printf("\n");
printf("Options\n");
printf("\tURL : URL of SCXML document\n");
+ printf("\t-e TYPE : type of edges to use:\n");
+ printf("\t 'target' - aggregate per target node (default)\n");
+ printf("\t 'event' - aggregate per event name\n");
+ printf("\t 'transition' no aggregation, display each transition\n");
printf("\t-d : depth below anchor node (INF per default)\n");
+ printf("\t-t : transition depth below anchor (INF per default)\n");
printf("\tstate_id : anchor node state id (topmost scxml element per default)\n");
printf("\n");
exit(1);
@@ -32,9 +38,9 @@ void printUsageAndExit(const char* progName) {
int currOpt = 1;
-int consumeDepthOption(int argc, char** argv) {
+int32_t consumeNumericOption(int argc, char** argv, const std::string& name, int32_t defaultVal) {
std::string test = argv[currOpt];
- if (boost::starts_with(test, "-")) {
+ if (boost::starts_with(test, std::string("-") + name)) {
int value = 0;
if (test.size() > 2) {
// no space before value
@@ -52,7 +58,7 @@ int consumeDepthOption(int argc, char** argv) {
return value;
}
- return -1;
+ return defaultVal;
}
int main(int argc, char** argv) {
@@ -61,43 +67,69 @@ int main(int argc, char** argv) {
google::LogToStderr();
google::InitGoogleLogging(argv[0]);
- std::list<SCXMLDotWriter::StateAnchor> stateAnchors;
-
+
if (argc < 2)
printUsageAndExit(argv[0]);
- try {
- // see if there is an initial depth given for root
- int depth = consumeDepthOption(argc, argv);
- if (depth >= 0) {
- SCXMLDotWriter::StateAnchor anchor;
- anchor.depth = depth;
- stateAnchors.push_back(anchor);
+ std::list<SCXMLDotWriter::StateAnchor> stateAnchors;
+ SCXMLDotWriter::StateAnchor currAnchor;
+
+ int option;
+ while ((option = getopt(argc, argv, "d:t:")) != -1) {
+ switch(option) {
+ case 'd': currAnchor.childDepth = strTo<int32_t>(optarg); break;
+ case 't': currAnchor.transDepth = strTo<int32_t>(optarg); break;
+ case 'e': {
+ std::string edgeType(optarg);
+ if (edgeType == "target") {
+ currAnchor.type = SCXMLDotWriter::PORT_TARGET;
+ } else if (edgeType == "event") {
+ currAnchor.type = SCXMLDotWriter::PORT_EVENT;
+ } else if (edgeType == "transition") {
+ currAnchor.type = SCXMLDotWriter::PORT_TRANSITION;
+ } else {
+ printUsageAndExit(argv[0]);
+ }
+ break;
+ }
+ default: break;
}
+ }
+
+ if (currAnchor)
+ stateAnchors.push_back(currAnchor);
+ try {
// current option has to be the interpreter's name
- URL inputFile(argv[currOpt++]);
+ URL inputFile(argv[optind]);
Interpreter interpreter = Interpreter::fromURI(inputFile);
-
- for (; currOpt < argc; currOpt++) {
- SCXMLDotWriter::StateAnchor anchor;
- depth = consumeDepthOption(argc, argv);
-
- if (depth >= 0) {
- anchor.depth = depth;
+ optind++;
+
+ while(optind < argc) {
+ // are
+ while ((option = getopt(argc, argv, "d:t:")) != -1) {
+ switch(option) {
+ case 'd': currAnchor.childDepth = strTo<int32_t>(optarg); break;
+ case 't': currAnchor.transDepth = strTo<int32_t>(optarg); break;
+ default: break;
+ }
}
-
- if (argc > currOpt) {
- std::string expr(argv[currOpt++]);
- anchor.element = interpreter.getImpl()->getState(expr);
+ if (argc > optind) {
+ std::string expr(argv[optind++]);
+ currAnchor.element = interpreter.getImpl()->getState(expr);
} else {
printUsageAndExit(argv[0]);
}
-
- stateAnchors.push_back(anchor);
+
+ if (currAnchor) {
+ stateAnchors.push_back(currAnchor);
+ }
+
+ currAnchor = SCXMLDotWriter::StateAnchor();
}
-
- SCXMLDotWriter::toDot("machine.dot", interpreter, stateAnchors);
+
+ std::string outName = inputFile.file() + ".dot";
+ SCXMLDotWriter::toDot(outName, interpreter, stateAnchors);
} catch(Event e) {
std::cerr << e << std::cout;