Changeset 81:880187d1eb2c in finroc_plugins_parameters


Ignore:
Timestamp:
25.11.2019 16:42:08 (3 months ago)
Author:
Max Reichardt <max.reichardt@…>
Branch:
17.03
Phase:
public
Message:

Adds feature to include config files from other config files ('<include file="included_file.xml"/>' - notably also possible within sub-nodes)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tConfigFile.cpp

    r80 r81  
    8585//---------------------------------------------------------------------- 
    8686 
     87namespace 
     88{ 
     89 
     90#ifdef _LIB_RRLIB_XML_PRESENT_ 
     91 
     92rrlib::xml::tDocument LoadConfigFile(const std::string& file); 
     93 
     94bool ProcessIncludes(rrlib::xml::tNode& node, const std::string& source_file) 
     95{ 
     96  if (node.Name() == "include") 
     97  { 
     98    if (!node.HasAttribute("file")) 
     99    { 
     100      FINROC_LOG_PRINT_STATIC(DEBUG_WARNING, "Found 'include' node without 'file' attribute in '", source_file, "'"); 
     101    } 
     102    else 
     103    { 
     104      std::string file_name = node.GetStringAttribute("file"); 
     105      try 
     106      { 
     107        rrlib::xml::tDocument insert = LoadConfigFile(file_name); 
     108        auto& parent = node.Parent(); 
     109        for (auto it = insert.RootNode().ChildrenBegin(); it != insert.RootNode().ChildrenEnd(); ++it) 
     110        { 
     111          node.AddNextSibling(*it, true); // not using copy resulted in erroneous behavior 
     112        } 
     113        parent.RemoveChildNode(node); 
     114        return true; 
     115      } 
     116      catch (const std::exception& e) 
     117      { 
     118        FINROC_LOG_PRINT(ERROR, "Error including '", file_name, "' in config file: ", e); 
     119      } 
     120    } 
     121  } 
     122 
     123  long int index = 0; 
     124  for (auto it = node.ChildrenBegin(); it != node.ChildrenEnd();) 
     125  { 
     126    long int number_of_children = node.GetNumberOfChildren(); 
     127    if (ProcessIncludes(*it, source_file)) 
     128    { 
     129      // Iterator could be invalid -> reinitialize 
     130      long int size_difference = node.GetNumberOfChildren() - number_of_children; 
     131      assert(size_difference >= -1); 
     132      index += (size_difference + 1); 
     133      it = node.ChildrenBegin(); 
     134      for (auto i = 0; i < index; i++) 
     135      { 
     136        ++it; 
     137      } 
     138    } 
     139    else 
     140    { 
     141      ++index; 
     142      ++it; 
     143    } 
     144  } 
     145  return false; 
     146} 
     147 
     148void ProcessIncludes(rrlib::xml::tDocument& document, const std::string& source_file) 
     149{ 
     150  ProcessIncludes(document.RootNode(), source_file); 
     151} 
     152 
     153rrlib::xml::tDocument LoadConfigFile(const std::string& filename) 
     154{ 
     155  rrlib::xml::tDocument result = core::GetFinrocXMLDocument(filename, false); // false = do not validate with dtd 
     156  ProcessIncludes(result, filename); 
     157  //FINROC_LOG_PRINT(DEBUG, result.RootNode().GetXMLDump(true)); 
     158  return result; 
     159} 
     160 
     161 
     162#endif 
     163 
     164} 
     165 
    87166tConfigFile::tConfigFile() : 
    88167#ifdef _LIB_RRLIB_XML_PRESENT_ 
     
    109188    try 
    110189    { 
    111       wrapped = core::GetFinrocXMLDocument(filename, false); // false = do not validate with dtd 
     190      wrapped = LoadConfigFile(filename); 
    112191      return; 
    113192    } 
     
    132211  { 
    133212    // merge entries into first document 
    134     auto document = core::GetFinrocXMLDocument(filename, false); // false = do not validate with dtd 
     213    auto document = LoadConfigFile(filename); 
    135214    auto& root_node = document.RootNode(); 
    136215    for (auto it = root_node.ChildrenBegin(); it != root_node.ChildrenEnd(); ++it) 
     
    371450    try 
    372451    { 
    373       wrapped = core::GetFinrocXMLDocument(filename, false); // false = do not validate with dtd 
     452      wrapped = LoadConfigFile(filename); 
    374453      return; 
    375454    } 
     
    467546      try 
    468547      { 
    469         config_file.wrapped = core::GetFinrocXMLDocument(file, false); 
     548        config_file.wrapped = LoadConfigFile(file); 
    470549      } 
    471550      catch (const std::exception& e) 
Note: See TracChangeset for help on using the changeset viewer.