29 #include <boost/format.hpp> 
   31 #include <SimoxUtility/algorithm/string/string_tools.h> 
   46         std::set<std::string> usedProfiles;
 
   49              stateNode.
nodes(
"InputParameters", 
"Parameter", 
"DefaultValue"))
 
   51             usedProfiles.insert(defaultNode.attribute_value_or_default(
"profile", 
"Root"));
 
   55              stateNode.
nodes(
"OutputParameters", 
"Parameter", 
"DefaultValue"))
 
   57             usedProfiles.insert(defaultNode.attribute_value_or_default(
"profile", 
"Root"));
 
   61              stateNode.
nodes(
"LocalParameters", 
"Parameter", 
"DefaultValue"))
 
   63             usedProfiles.insert(defaultNode.attribute_value_or_default(
"profile", 
"Root"));
 
   70     StatechartGroupDocGenerator::unescapeString(std::string 
str)
 const 
   73         std::string::const_iterator it = 
str.begin();
 
   75         while (it != 
str.end())
 
   79             if (
c == 
'\\' && it != 
str.end())
 
  113     StatechartGroupDocGenerator::nToBr(std::string 
str)
 const 
  115         return simox::alg::replace_all(
str, 
"\n", 
"<br />\n");
 
  119     StatechartGroupDocGenerator::buildParameterTable(RapidXmlReaderNode parametersNode)
 const 
  121         std::set<std::string> usedProfiles;
 
  123         for (RapidXmlReaderNode defaultNode : parametersNode.nodes(
"Parameter", 
"DefaultValue"))
 
  125             usedProfiles.insert(defaultNode.attribute_value_or_default(
"profile", 
"Root"));
 
  128         std::vector<std::string> header;
 
  130         header.push_back(
"Name");
 
  131         header.push_back(
"Type");
 
  132         header.push_back(
"Description");
 
  133         std::copy(usedProfiles.begin(), usedProfiles.end(), std::back_inserter(header));
 
  136         for (RapidXmlReaderNode parameterNode : parametersNode.nodes(
"Parameter"))
 
  138             std::vector<std::string> row(header.size());
 
  139             row.at(0) = parameterNode.attribute_value(
"name");
 
  140             row.at(1) = parameterNode.has_attribute(
"docType")
 
  141                             ? parameterNode.attribute_value(
"docType")
 
  142                             : parameterNode.attribute_value(
"type");
 
  143             row.at(2) = nToBr(parameterNode.first_node_value_or_default(
"Description", 
""));
 
  145             for (RapidXmlReaderNode defaultNode : parameterNode.nodes(
"DefaultValue"))
 
  149                                       defaultNode.attribute_value_or_default(
"profile", 
"Root")) -
 
  151                 std::string defaultValue = defaultNode.has_attribute(
"docValue")
 
  152                                                ? defaultNode.attribute_value(
"docValue")
 
  153                                                : defaultNode.attribute_value(
"value");
 
  154                 row.at(
index) = nToBr(unescapeString(defaultValue));
 
  164     StatechartGroupDocGenerator::addParameterTable(
const DoxDocPtr& doc,
 
  165                                                    const RapidXmlReaderNode& stateNode,
 
  167                                                    const char* nodeName)
 const 
  169         DoxTablePtr table = buildParameterTable(stateNode.first_node(nodeName));
 
  171         if (table->rows() == 0)
 
  173             doc->addLine(
"No " + name + 
".<br />");
 
  177             doc->addLine(name + 
":");
 
  178             doc->addEntry(table);
 
  183     StatechartGroupDocGenerator::getNodeAttrsFromStateType(
const std::string& nodeType)
 const 
  185         if (nodeType == 
"EndState")
 
  187             return "shape=box,style=filled,fillcolor=\"#FFFF96\"";
 
  190         if (nodeType == 
"RemoteState")
 
  192             return "shape=box,style=filled,fillcolor=\"#96FFFA\"";
 
  195         if (nodeType == 
"DynamicRemoteState")
 
  197             return "shape=box,style=filled,fillcolor=\"#B147EA\"";
 
  200         return "shape=box,style=filled,fillcolor=\"#B3D7FF\"";
 
  207         std::string packageName = reader->getPackageName();
 
  208         std::string groupName = reader->getGroupName();
 
  209         doc->addLine(fmt(
"@defgroup %s-%s %s", packageName, groupName, groupName));
 
  210         doc->addLine(fmt(
"@ingroup Statecharts  %s-Statecharts", packageName));
 
  211         doc->addLine(nToBr(reader->getDescription()));
 
  214         bool anyPrivateStateFound = 
false;
 
  216         for (std::string statefile : reader->getStateFilepaths())
 
  220                 anyPrivateStateFound = 
true;
 
  224         if (anyPrivateStateFound)
 
  227             doc->addLine(fmt(
"@defgroup %s-%s-PrivateStates %s Private States",
 
  231             doc->addLine(fmt(
"@ingroup %s-%s", packageName, groupName));
 
  234         for (std::string statefile : reader->getStateFilepaths())
 
  243             doc->addLine(fmt(
"@defgroup State-%s %s", stateUuid, stateName));
 
  245                 fmt(
"@ingroup %s-%s%s",
 
  250                         : 
"-PrivateStates"));
 
  252                                          "Description", 
"This state has no description."));
 
  255             addParameterTable(doc, stateNode, 
"\\b Input \\b Parameters", 
"InputParameters");
 
  256             addParameterTable(doc, stateNode, 
"\\b Local \\b Parameters", 
"LocalParameters");
 
  257             addParameterTable(doc, stateNode, 
"\\b Output \\b Parameters", 
"OutputParameters");
 
  259             doc->addLine(
"<br/>\\b State \\b used by:<br />");
 
  263                 std::set<std::string> users = 
usageMap.find(stateUuid)->second;
 
  265                 for (std::string uuid : users)
 
  267                     doc->addLine(fmt(
"@ref State-%s <br />", uuid));
 
  271             doc->addLine(
"<br/>\\b Substates:<br />");
 
  275                 if (substateNode.name() == 
"LocalState" || substateNode.name() == 
"RemoteState" ||
 
  276                     substateNode.name() == 
"DynamicRemoteState")
 
  278                     std::string name = substateNode.attribute_value(
"name");
 
  279                     std::string refuuid = substateNode.attribute_value(
"refuuid");
 
  280                     std::map<std::string, StateInfo>::const_iterator it =
 
  286                             fmt(
"@ref State-%s \"%s (External Package)\"<br />", refuuid, name));
 
  290                         StateInfo stateInfo = it->second;
 
  292                         if (stateInfo.group == groupName && stateInfo.state == name)
 
  294                             doc->addLine(fmt(
"@ref State-%s<br />", refuuid));
 
  296                         else if (stateInfo.group == groupName)
 
  298                             doc->addLine(fmt(
"%s -> @ref State-%s \"%s\"<br />",
 
  305                             doc->addLine(fmt(
"%s -> @ref State-%s \"%s-%s\"<br />",
 
  315             doc->addLine(
"<br/>\\b Statechart \\b layout:");
 
  317             graph->addNode(
"", 
"shape=point");
 
  322                 graph->addTransition(
"", startStateNode.
attribute_value(
"substateName"), 
"");
 
  327                 std::string shape = getNodeAttrsFromStateType(substateNode.name());
 
  328                 graph->addNode(substateNode.attribute_value(
"name"), shape);
 
  333                 if (transition.has_attribute(
"from") && transition.has_attribute(
"to") &&
 
  334                     transition.has_attribute(
"eventName"))
 
  336                     std::string 
from = transition.attribute_value_or_default(
"from", 
"");
 
  337                     std::string to = transition.attribute_value_or_default(
"to", 
"");
 
  338                     std::string eventName = transition.attribute_value_or_default(
"eventName", 
"");
 
  340                     graph->addTransition(
from, to, eventName);
 
  344             if (graph->transitionCount() > 0)
 
  346                 doc->addEntry(graph);
 
  377         doc->writeDoc(writer);
 
  378         return writer->getString();
 
  382     StatechartGroupDocGenerator::fmt(
const std::string& fmt, 
const std::string& arg1)
 const 
  388     StatechartGroupDocGenerator::fmt(
const std::string& fmt,
 
  389                                      const std::string& arg1,
 
  390                                      const std::string& arg2)
 const 
  392         return boost::str(boost::format(fmt) % arg1 % arg2);
 
  396     StatechartGroupDocGenerator::fmt(
const std::string& fmt,
 
  397                                      const std::string& arg1,
 
  398                                      const std::string& arg2,
 
  399                                      const std::string& arg3)
 const 
  401         return boost::str(boost::format(fmt) % arg1 % arg2 % arg3);
 
  405     StatechartGroupDocGenerator::fmt(
const std::string& fmt,
 
  406                                      const std::string& arg1,
 
  407                                      const std::string& arg2,
 
  408                                      const std::string& arg3,
 
  409                                      const std::string& arg4)
 const 
  411         return boost::str(boost::format(fmt) % arg1 % arg2 % arg3 % arg4);
 
  418         reader->readXml(std::filesystem::path(groupDefinitionFilePath));
 
  421         std::filesystem::path doxyFile = finder.
getBuildDir();
 
  428         if (!doxyFile.string().empty())
 
  430             doxyFile /= 
"doxygen";
 
  437         doxyFile /= reader->getGroupName() + 
".dox";
 
  440         file.open(doxyFile.string().c_str());
 
  450         ARMARX_INFO_S << 
"wrote " << docstr.size() << 
" bytes to " << doxyFile.string();
 
  456         for (std::string groupDefinitionFilePath : groups)
 
  460             reader->readXml(std::filesystem::path(groupDefinitionFilePath));
 
  462             for (std::string statefile : reader->getStateFilepaths())
 
  470                     StateInfo(reader->getPackageName(), reader->getGroupName(), stateName)));
 
  474                     if (substateNode.name() == 
"LocalState" ||
 
  475                         substateNode.name() == 
"RemoteState" ||
 
  476                         substateNode.name() == 
"DynamicRemoteState")
 
  479                         std::string refuuid = substateNode.attribute_value(
"refuuid");
 
  483                             usageMap.insert(std::make_pair(refuuid, std::set<std::string>()));
 
  486                         usageMap[refuuid].insert(stateUuid);
 
  496         for (std::string groupDefinitionFilePath : groups)
 
  508     std::vector<std::string>
 
  510         const std::filesystem::path& path)
 
  512         std::vector<std::string> result;
 
  518             for (std::filesystem::recursive_directory_iterator end, dir(path); dir != end;
 
  521                 if (dir->path().extension() == 
".scgxml" &&
 
  522                     dir->path().string().find(
"deprecated") == std::string::npos)
 
  524                     result.push_back(dir->path().c_str());
 
  529                     ARMARX_INFO_S << 
"Scanning file " << i << 
": " << dir->path().c_str();
 
  533         catch (std::exception& e)
 
  544         auto itFinders = 
finders.find(reader->getPackageName());
 
  546         if (itFinders == 
finders.end())
 
  549                             .insert(std::make_pair(reader->getPackageName(),
 
  554         return itFinders->second;