diff options
Diffstat (limited to 'apps/uscxml-dot.cpp')
-rw-r--r-- | apps/uscxml-dot.cpp | 92 |
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; |