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[]) ...@@ -63,7 +63,8 @@ int main(int argc, char* argv[])
options.add_options("IO") options.add_options("IO")
("i,input", "XML file name", cxxopts::value<std::string>()->default_value(input_default)) ("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") options.add_options("Generation")
("f,force", "Enforce the generation", cxxopts::value<bool>()->default_value("false")); ("f,force", "Enforce the generation", cxxopts::value<bool>()->default_value("false"));
...@@ -108,6 +109,17 @@ int main(int argc, char* argv[]) ...@@ -108,6 +109,17 @@ int main(int argc, char* argv[])
std::filesystem::path input_file(filename); std::filesystem::path input_file(filename);
std::filesystem::path output_folder(output); 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)) 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; 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[]) ...@@ -132,7 +144,7 @@ int main(int argc, char* argv[])
} }
typereader::xml::Reader reader; typereader::xml::Reader reader;
reader.parseFile(input_file); reader.parseFile(input_file, includePaths);
if (verbose) if (verbose)
{ {
std::cout << "Parsing the XML file... done!" << std::endl; std::cout << "Parsing the XML file... done!" << std::endl;
......
...@@ -47,10 +47,10 @@ namespace armarx::aron::typereader ...@@ -47,10 +47,10 @@ namespace armarx::aron::typereader
Reader() = default; Reader() = default;
/// parse a filename /// 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 /// 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 std::vector<std::string> getCodeIncludes() const
{ {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
// Header // Header
#include "Reader.h" #include "Reader.h"
#include <sstream>
// ArmarX // ArmarX
#include <ArmarXCore/core/rapidxml/wrapper/RapidXmlReader.h> #include <ArmarXCore/core/rapidxml/wrapper/RapidXmlReader.h>
...@@ -42,8 +43,20 @@ namespace armarx::aron::typereader::xml ...@@ -42,8 +43,20 @@ namespace armarx::aron::typereader::xml
namespace namespace
{ {
/// Resolve a relative Package path. This may be removed in a newer version of aron /// 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(); const std::string package = *path.begin();
armarx::CMakePackageFinder finder(package); armarx::CMakePackageFinder finder(package);
if (finder.packageFound()) if (finder.packageFound())
...@@ -59,14 +72,12 @@ namespace armarx::aron::typereader::xml ...@@ -59,14 +72,12 @@ namespace armarx::aron::typereader::xml
} }
return std::nullopt; 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; std::string filename = _filename;
// Handle C++ style includes like "<path/to/file>". // Handle C++ style includes like "<path/to/file>".
...@@ -74,19 +85,19 @@ namespace armarx::aron::typereader::xml ...@@ -74,19 +85,19 @@ namespace armarx::aron::typereader::xml
{ {
filename = filename.substr(1, filename.size() - 2); 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; fs::path file = _file;
RapidXmlReaderPtr reader = RapidXmlReader::FromFile(file.string()); RapidXmlReaderPtr reader = RapidXmlReader::FromFile(file.string());
parse(reader, _file); parse(reader, _file, includePaths);
} }
// private method reading nodes // 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(); RapidXmlReaderNode root = reader->getRoot();
...@@ -104,7 +115,7 @@ namespace armarx::aron::typereader::xml ...@@ -104,7 +115,7 @@ namespace armarx::aron::typereader::xml
{ {
for (const auto& include : (*code_includes).nodes()) 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 ...@@ -113,7 +124,7 @@ namespace armarx::aron::typereader::xml
{ {
for (const auto& aronInclude : (*aron_includes).nodes()) 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 ...@@ -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::EnforceTagName(node, constantes::INCLUDE_TAG);
util::EnforceAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME); util::EnforceAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME);
...@@ -152,7 +163,7 @@ namespace armarx::aron::typereader::xml ...@@ -152,7 +163,7 @@ namespace armarx::aron::typereader::xml
return include; 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); util::EnforceTagName(node, constantes::INCLUDE_TAG);
std::string specifiedPath = util::GetAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME); std::string specifiedPath = util::GetAttribute(node, constantes::INCLUDE_ATTRIBUTE_NAME);
...@@ -166,7 +177,8 @@ namespace armarx::aron::typereader::xml ...@@ -166,7 +177,8 @@ namespace armarx::aron::typereader::xml
if (!xmlincludepath.empty() && xmlincludepath.is_relative()) 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 // check if relative path belongs to a package
resolved_absolute_path = resolvedPackagePath.value(); resolved_absolute_path = resolvedPackagePath.value();
...@@ -181,7 +193,13 @@ namespace armarx::aron::typereader::xml ...@@ -181,7 +193,13 @@ namespace armarx::aron::typereader::xml
if (!fs::is_regular_file(resolved_absolute_path)) 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 ...@@ -189,7 +207,7 @@ namespace armarx::aron::typereader::xml
// parse parent xml file and add objects to alreday known // parse parent xml file and add objects to alreday known
Reader anotherReader; Reader anotherReader;
anotherReader.parseFile(resolved_absolute_path); anotherReader.parseFile(resolved_absolute_path, includePaths);
for (const auto& previouslyKnown : anotherReader.factory.allPreviouslyKnownPublicTypes) for (const auto& previouslyKnown : anotherReader.factory.allPreviouslyKnownPublicTypes)
{ {
factory.allPreviouslyKnownPublicTypes.push_back(previouslyKnown); factory.allPreviouslyKnownPublicTypes.push_back(previouslyKnown);
...@@ -224,5 +242,3 @@ namespace armarx::aron::typereader::xml ...@@ -224,5 +242,3 @@ namespace armarx::aron::typereader::xml
return type::IntEnum::DynamicCastAndCheck(factory.create(node, Path())); return type::IntEnum::DynamicCastAndCheck(factory.create(node, Path()));
} }
} }
...@@ -50,14 +50,14 @@ namespace armarx::aron::typereader::xml ...@@ -50,14 +50,14 @@ namespace armarx::aron::typereader::xml
public: public:
Reader() = default; Reader() = default;
void parseFile(const std::string&) override; void parseFile(const std::string& filename, const std::vector<std::filesystem::path>& includePaths) override;
void parseFile(const std::filesystem::path&) override; void parseFile(const std::filesystem::path& file, const std::vector<std::filesystem::path>& includePaths) override;
private: 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 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); 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::ObjectPtr readGenerateObject(const RapidXmlReaderNode& node);
type::IntEnumPtr readGenerateIntEnum(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