Skip to content
Snippets Groups Projects
Commit 64c7784f authored by Fabian Reister's avatar Fabian Reister
Browse files

aron code generation: explicitly specifying include paths

parent 871f4906
No related branches found
No related tags found
1 merge request!258RobotUnit with global robot pose information
......@@ -63,7 +63,8 @@ int main(int argc, char* argv[])
options.add_options("IO")
("i,input", "XML file name", cxxopts::value<std::string>()->default_value(input_default))
("o,output", "The output path", cxxopts::value<std::string>()->default_value(output_default));
("o,output", "The output path", cxxopts::value<std::string>()->default_value(output_default))
("I,include", "include path", cxxopts::value<std::vector<std::string>>());
options.add_options("Generation")
("f,force", "Enforce the generation", cxxopts::value<bool>()->default_value("false"));
......@@ -108,6 +109,17 @@ int main(int argc, char* argv[])
std::filesystem::path input_file(filename);
std::filesystem::path output_folder(output);
std::vector<std::filesystem::path> includePaths;
if(result.count("I") > 0)
{
for(const auto& path: result["I"].as<std::vector<std::string>>())
{
includePaths.emplace_back(path);
}
}
if (!std::filesystem::exists(input_file) || !std::filesystem::is_regular_file(input_file))
{
std::cerr << "The input file does not exist or is not a regular file." << std::endl;
......@@ -132,7 +144,7 @@ int main(int argc, char* argv[])
}
typereader::xml::Reader reader;
reader.parseFile(input_file);
reader.parseFile(input_file, includePaths);
if (verbose)
{
std::cout << "Parsing the XML file... done!" << std::endl;
......
......@@ -47,10 +47,10 @@ namespace armarx::aron::typereader
Reader() = default;
/// parse a filename
virtual void parseFile(const std::string& filename) = 0;
virtual void parseFile(const std::string& filename, const std::vector<std::filesystem::path>& includePaths) = 0;
/// path a file given by std::filesystem
virtual void parseFile(const std::filesystem::path& file) = 0;
virtual void parseFile(const std::filesystem::path& file, const std::vector<std::filesystem::path>& includePaths) = 0;
std::vector<std::string> getCodeIncludes() const
{
......
......@@ -26,6 +26,7 @@
// Header
#include "Reader.h"
#include <sstream>
// ArmarX
#include <ArmarXCore/core/rapidxml/wrapper/RapidXmlReader.h>
......@@ -42,8 +43,20 @@ namespace armarx::aron::typereader::xml
namespace
{
/// Resolve a relative Package path. This may be removed in a newer version of aron
std::optional<fs::path> resolveRelativePackagePath(const fs::path& path)
std::optional<fs::path> resolveRelativePackagePath(const fs::path& path, const std::vector<fs::path>& includePaths)
{
// new behavior: using provided include paths
for (const auto& includePath : includePaths)
{
fs::path absPath = includePath / path;
if (fs::is_regular_file(absPath))
{
// path is valid
return absPath;
}
}
// legacy behavior: using cmake package finder paths
const std::string package = *path.begin();
armarx::CMakePackageFinder finder(package);
if (finder.packageFound())
......@@ -59,14 +72,12 @@ namespace armarx::aron::typereader::xml
}
return std::nullopt;
}
else
{
return std::nullopt;
}
return std::nullopt;
}
}
void Reader::parseFile(const std::string& _filename)
void Reader::parseFile(const std::string& _filename, const std::vector<std::filesystem::path>& includePaths)
{
std::string filename = _filename;
// Handle C++ style includes like "<path/to/file>".
......@@ -74,19 +85,19 @@ namespace armarx::aron::typereader::xml
{
filename = filename.substr(1, filename.size() - 2);
}
parseFile(std::filesystem::path(filename));
parseFile(std::filesystem::path(filename), includePaths);
}
void Reader::parseFile(const std::filesystem::path& _file)
void Reader::parseFile(const std::filesystem::path& _file, const std::vector<std::filesystem::path>& includePaths)
{
fs::path file = _file;
RapidXmlReaderPtr reader = RapidXmlReader::FromFile(file.string());
parse(reader, _file);
parse(reader, _file, includePaths);
}
// private method reading nodes
void Reader::parse(const RapidXmlReaderPtr& reader, const std::filesystem::path& filePath)
void Reader::parse(const RapidXmlReaderPtr& reader, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths)
{
RapidXmlReaderNode root = reader->getRoot();
......@@ -104,7 +115,7 @@ namespace armarx::aron::typereader::xml
{
for (const auto& include : (*code_includes).nodes())
{
this->codeIncludes.push_back(readCodeInclude(include, filePath));
this->codeIncludes.push_back(readCodeInclude(include, filePath, includePaths));
}
}
......@@ -113,7 +124,7 @@ namespace armarx::aron::typereader::xml
{
for (const auto& aronInclude : (*aron_includes).nodes())
{
this->aronIncludes.push_back(readAronInclude(aronInclude, filePath));
this->aronIncludes.push_back(readAronInclude(aronInclude, filePath, includePaths));
}
}
......@@ -144,7 +155,7 @@ namespace armarx::aron::typereader::xml
}
}
std::string Reader::readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath)
std::string Reader::readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths)
{
util::EnforceTagName(node, constantes::INCLUDE_TAG);
util::EnforceAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME);
......@@ -152,7 +163,7 @@ namespace armarx::aron::typereader::xml
return include;
}
std::string Reader::readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath)
std::string Reader::readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths)
{
util::EnforceTagName(node, constantes::INCLUDE_TAG);
std::string specifiedPath = util::GetAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME);
......@@ -166,7 +177,8 @@ namespace armarx::aron::typereader::xml
if (!xmlincludepath.empty() && xmlincludepath.is_relative())
{
if (std::optional<fs::path> resolvedPackagePath = resolveRelativePackagePath(xmlincludepath); resolvedPackagePath.has_value())
// ARMARX_INFO << "Checking file " << xmlincludepath;
if (std::optional<fs::path> resolvedPackagePath = resolveRelativePackagePath(xmlincludepath, includePaths); resolvedPackagePath.has_value())
{
// check if relative path belongs to a package
resolved_absolute_path = resolvedPackagePath.value();
......@@ -181,7 +193,13 @@ namespace armarx::aron::typereader::xml
if (!fs::is_regular_file(resolved_absolute_path))
{
throw error::AronException(__PRETTY_FUNCTION__, "Could not find an aron XML file. Last path tried was: " + resolved_absolute_path.string());
std::stringstream ss;
for(const auto& includePath: includePaths)
{
ss << includePath << ", ";
}
throw error::AronException(__PRETTY_FUNCTION__, "Could not find an aron XML file `" + xmlincludepath.string() + "`. Search paths are: " + ss.str());
}
}
}
......@@ -189,7 +207,7 @@ namespace armarx::aron::typereader::xml
// parse parent xml file and add objects to alreday known
Reader anotherReader;
anotherReader.parseFile(resolved_absolute_path);
anotherReader.parseFile(resolved_absolute_path, includePaths);
for (const auto& previouslyKnown : anotherReader.factory.allPreviouslyKnownPublicTypes)
{
factory.allPreviouslyKnownPublicTypes.push_back(previouslyKnown);
......@@ -224,5 +242,3 @@ namespace armarx::aron::typereader::xml
return type::IntEnum::DynamicCastAndCheck(factory.create(node, Path()));
}
}
......@@ -50,14 +50,14 @@ namespace armarx::aron::typereader::xml
public:
Reader() = default;
void parseFile(const std::string&) override;
void parseFile(const std::filesystem::path&) override;
void parseFile(const std::string& filename, const std::vector<std::filesystem::path>& includePaths) override;
void parseFile(const std::filesystem::path& file, const std::vector<std::filesystem::path>& includePaths) override;
private:
void parse(const RapidXmlReaderPtr& node, const std::filesystem::path& filePath);
void parse(const RapidXmlReaderPtr& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths);
std::string readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath);
std::string readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath);
std::string readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths);
std::string readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath, const std::vector<std::filesystem::path>& includePaths);
type::ObjectPtr readGenerateObject(const RapidXmlReaderNode& node);
type::IntEnumPtr readGenerateIntEnum(const RapidXmlReaderNode& node);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment