Skip to content
Snippets Groups Projects
Commit b010670c authored by Fabian Tërnava's avatar Fabian Tërnava
Browse files

Merge remote-tracking branch 'origin/master' into fabianpk

parents 678b63df 9e1e89e0
No related branches found
No related tags found
1 merge request!337Merge fabianpk dev branch
...@@ -177,33 +177,60 @@ int main(int argc, char* argv[]) ...@@ -177,33 +177,60 @@ int main(int argc, char* argv[])
} }
} }
auto w = CppWriterPtr(new CppWriter());
// Generate enums at top of generated header file
std::vector<MetaEnumPtr> enums = writer.getTypeEnums();
if (verbose)
{
std::cout << "Now exporting enums..." << std::endl;
}
MetaEnum::Write(enums, w);
std::string enum_file_generation_content = w->getString();
if (verbose)
{
std::cout << "Now exporting enums... done!" << std::endl;
}
if (enums.size() > 0 && enum_file_generation_content == "")
{
std::cerr << "\033[31m" << "Error code 11 - Found error in code generation. Aborting!" << "\033[0m" << std::endl;
exit(1);
}
// Generate all classes
std::vector<MetaClassPtr> classes = writer.getTypeClasses(); std::vector<MetaClassPtr> classes = writer.getTypeClasses();
if (verbose) if (verbose)
{ {
std::cout << "Now exporting classes..." << std::endl; std::cout << "Now exporting classes..." << std::endl;
} }
auto w = CppWriterPtr(new CppWriter());
CppClass::Write(classes, w); CppClass::Write(classes, w);
std::string new_file_content = w->getString(); std::string class_file_generation_content = simox::alg::remove_prefix(w->getString(), enum_file_generation_content);
if (verbose) if (verbose)
{ {
std::cout << "Now exporting classes... done!" << std::endl; std::cout << "Now exporting classes... done!" << std::endl;
} }
if (new_file_content == "") if (classes.size() > 0 && class_file_generation_content == "")
{ {
std::cerr << "Found error in code generation. Aborting!" << std::endl; std::cerr << "\033[31m" << "Error code 21 - Found error in code generation. Aborting!" << "\033[0m" << std::endl;
exit(1); exit(1);
} }
std::time_t current_time = std::time(0);
std::tm* now = std::localtime(&current_time);
std::string current_year = std::to_string(now->tm_year + 1900);
std::string new_file_header = "\ std::string new_file_header = "\
/* \n\ /* \n\
* This file is part of ArmarX. \n\ * This file is part of ArmarX. \n\
* \n\ * \n\
* Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), \n\ * Copyright (C) 2012-" + current_year + ", High Performance Humanoid Technologies (H2T), \n\
* Karlsruhe Institute of Technology (KIT), all rights reserved. \n\ * Karlsruhe Institute of Technology (KIT), all rights reserved. \n\
* \n\ * \n\
* ArmarX is free software; you can redistribute it and/or modify \n\ * ArmarX is free software; you can redistribute it and/or modify \n\
...@@ -228,7 +255,7 @@ int main(int argc, char* argv[]) ...@@ -228,7 +255,7 @@ int main(int argc, char* argv[])
************************************************************************* \n\ ************************************************************************* \n\
*/\n\n\n"; */\n\n\n";
std::string new_file_full_content = new_file_header + new_file_content; std::string new_file_full_content = new_file_header + w->getString();
std::string new_name_with_extension = input_file.filename().replace_extension("").string(); std::string new_name_with_extension = input_file.filename().replace_extension("").string();
new_name_with_extension += ".aron.generated.h"; new_name_with_extension += ".aron.generated.h";
...@@ -247,7 +274,7 @@ int main(int argc, char* argv[]) ...@@ -247,7 +274,7 @@ int main(int argc, char* argv[])
{ {
if (verbose) if (verbose)
{ {
std::cout << "File content not changed for <" + output_file.string() + ">" << std::endl; std::cout << "\033[31m" << "Error code 31 - File content not changed for <" + output_file.string() + ">" << "\033[0m" << std::endl;
} }
exit(0); exit(0);
} }
...@@ -261,12 +288,12 @@ int main(int argc, char* argv[]) ...@@ -261,12 +288,12 @@ int main(int argc, char* argv[])
if (verbose) if (verbose)
{ {
std::cout << "Finished generating <" + output_file.string() + ">. The new file ist called <" << output_file.string() << ">" << std::endl; std::cout << "\033[32m" << "Finished generating <" + output_file.string() + ">. The new file ist called <" << output_file.string() << ">" << "\033[0m" << std::endl;
} }
} }
catch (const cxxopts::OptionException& e) catch (const cxxopts::OptionException& e)
{ {
std::cerr << "Error in parsing cxxopts options: " << e.what() << std::endl; std::cerr << "\033[31m" << "Error code 01 - Error in parsing cxxopts options: " << e.what() << "\033[0m" << std::endl;
exit(1); exit(1);
} }
exit(0); exit(0);
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <typeindex> #include <typeindex>
// ArmarX // ArmarX
#include <ArmarXCore/libraries/cppgen/MetaClass.h> #include <ArmarXCore/libraries/cppgen/CppEnum.h>
#include <ArmarXCore/libraries/cppgen/CppClass.h>
#include <RobotAPI/libraries/aron/core/type/variant/All.h> #include <RobotAPI/libraries/aron/core/type/variant/All.h>
...@@ -61,12 +62,18 @@ namespace armarx::aron::codegenerator ...@@ -61,12 +62,18 @@ namespace armarx::aron::codegenerator
return typeClasses; return typeClasses;
} }
std::vector<MetaEnumPtr> getTypeEnums() const // TODO: Create Meta Enum class to abstract away cpp details
{
return typeEnums;
}
protected: protected:
virtual void addSpecificReaderMethods() = 0; virtual void addSpecificReaderMethods() = 0;
virtual void addSpecificWriterMethods() = 0; virtual void addSpecificWriterMethods() = 0;
protected: protected:
std::vector<MetaClassPtr> typeClasses; std::vector<MetaClassPtr> typeClasses;
std::vector<MetaEnumPtr> typeEnums;
std::string producerName; std::string producerName;
std::vector<codegenerator::WriterInfo> dataWriters; std::vector<codegenerator::WriterInfo> dataWriters;
......
...@@ -247,17 +247,19 @@ namespace armarx::aron::codegenerator::cpp ...@@ -247,17 +247,19 @@ namespace armarx::aron::codegenerator::cpp
ARMARX_CHECK_NOT_NULL(nav); ARMARX_CHECK_NOT_NULL(nav);
generator::IntEnumClass generator(*nav); generator::IntEnumClass generator(*nav);
// Create enum class and add to enums
CppEnumPtr enumrepresentation = setupEnumPtr(publicGenerateIntEnumType, generator);
typeEnums.push_back(enumrepresentation);
// Generate aron wrapper class and add to classes
CppClassPtr c = setupBasicCppClass(publicGenerateIntEnumType, generator); CppClassPtr c = setupBasicCppClass(publicGenerateIntEnumType, generator);
setupMemberFields(c, publicGenerateIntEnumType.doc_values, generator); setupMemberFields(c, publicGenerateIntEnumType.doc_values, generator);
c->addInherit("public armarx::aron::cpp::AronGeneratedClass"); c->addInherit("public armarx::aron::cpp::AronGeneratedClass");
// ctor // ctor
c->addCtor(generator.toInnerEnumCtor(c->getName())); c->addCtor(generator.toEnumCtor(c->getName()));
// Specific methods
CppEnumPtr enumrepresentation = generator.toInnerEnumDefinition();
c->addInnerEnum(enumrepresentation);
CppMethodPtr toString = generator.toToStringMethod(); CppMethodPtr toString = generator.toToStringMethod();
c->addMethod(toString); c->addMethod(toString);
...@@ -346,6 +348,33 @@ namespace armarx::aron::codegenerator::cpp ...@@ -346,6 +348,33 @@ namespace armarx::aron::codegenerator::cpp
} }
} }
CppEnumPtr Writer::setupEnumPtr(const typereader::GenerateInfo& info, const generator::IntEnumClass& gen) const
{
const auto& type = gen.getType();
if (type.getMaybe() != type::Maybe::NONE)
{
// Should not happen since we check the maybe flag on creation of the generator. However, better to double check
throw error::ValueNotValidException(__PRETTY_FUNCTION__, "Somehow the maybe flag of a top level object declaration is set. This is not valid!", std::to_string((int) type.getMaybe()) + " aka " + type::defaultconversion::string::Maybe2String.at(type.getMaybe()), type.getPath());
}
const std::string classCppTypename = gen.getClassCppTypename();
std::vector<std::string> namespaces = info.getNamespaces();
std::string rawObjectName = info.getNameWithoutNamespace();
namespaces.push_back(simox::alg::to_lower(rawObjectName) + "_details");
std::string enumdoc = "The enum definition of the enum of the auogenerated class '" + gen.getFullClassCppTypename() + "'.";
CppEnumPtr e = std::make_shared<CppEnum>(namespaces, "Enum");
auto enumFields = gen.toEnumFields();
for (const auto& field : enumFields)
{
e->addField(field);
}
return e;
}
CppClassPtr Writer::setupBasicCppClass(const typereader::GenerateInfo& info, const Generator& gen) const CppClassPtr Writer::setupBasicCppClass(const typereader::GenerateInfo& info, const Generator& gen) const
{ {
const auto& type = gen.getType(); const auto& type = gen.getType();
...@@ -393,7 +422,7 @@ namespace armarx::aron::codegenerator::cpp ...@@ -393,7 +422,7 @@ namespace armarx::aron::codegenerator::cpp
} }
} }
// add aron includes // always add aron includes
c->addInclude("<RobotAPI/libraries/aron/core/aron_conversions.h>"); c->addInclude("<RobotAPI/libraries/aron/core/aron_conversions.h>");
c->addInclude("<RobotAPI/libraries/aron/core/rw.h>"); c->addInclude("<RobotAPI/libraries/aron/core/rw.h>");
c->addInclude("<RobotAPI/libraries/aron/core/codegeneration/cpp/AronGeneratedClass.h>"); c->addInclude("<RobotAPI/libraries/aron/core/codegeneration/cpp/AronGeneratedClass.h>");
...@@ -434,7 +463,7 @@ namespace armarx::aron::codegenerator::cpp ...@@ -434,7 +463,7 @@ namespace armarx::aron::codegenerator::cpp
void Writer::setupMemberFields(CppClassPtr& c, const std::map<std::string, std::string>& doc_members, const generator::ObjectClass& o) const void Writer::setupMemberFields(CppClassPtr& c, const std::map<std::string, std::string>& doc_members, const generator::ObjectClass& o) const
{ {
auto publicFields = o.getPublicVariableDeclarations(""); auto publicFields = o.getPublicVariableDeclarations(c->getName());
for (const auto& f : publicFields) for (const auto& f : publicFields)
{ {
if (auto it = doc_members.find(f->getName()); it != doc_members.end()) if (auto it = doc_members.find(f->getName()); it != doc_members.end())
...@@ -447,7 +476,7 @@ namespace armarx::aron::codegenerator::cpp ...@@ -447,7 +476,7 @@ namespace armarx::aron::codegenerator::cpp
void Writer::setupMemberFields(CppClassPtr& c, const std::map<std::string, std::string>& doc_members, const generator::IntEnumClass& o) const void Writer::setupMemberFields(CppClassPtr& c, const std::map<std::string, std::string>& doc_members, const generator::IntEnumClass& o) const
{ {
auto publicFields = o.getPublicVariableDeclarations(""); auto publicFields = o.getPublicVariableDeclarations(c->getName());
for (const auto& f : publicFields) for (const auto& f : publicFields)
{ {
if (auto it = doc_members.find(f->getName()); it != doc_members.end()) if (auto it = doc_members.find(f->getName()); it != doc_members.end())
......
...@@ -59,6 +59,8 @@ namespace armarx::aron::codegenerator::cpp ...@@ -59,6 +59,8 @@ namespace armarx::aron::codegenerator::cpp
virtual void addSpecificReaderMethods() override; virtual void addSpecificReaderMethods() override;
CppClassPtr setupBasicCppClass(const typereader::GenerateInfo& info, const Generator& gen) const; CppClassPtr setupBasicCppClass(const typereader::GenerateInfo& info, const Generator& gen) const;
CppEnumPtr setupEnumPtr(const typereader::GenerateInfo& info, const generator::IntEnumClass& gen) const;
void setupMemberFields(CppClassPtr&, const std::map<std::string, std::string>& doc_members, const generator::ObjectClass&) const; void setupMemberFields(CppClassPtr&, const std::map<std::string, std::string>& doc_members, const generator::ObjectClass&) const;
void setupMemberFields(CppClassPtr&, const std::map<std::string, std::string>& doc_members, const generator::IntEnumClass&) const; void setupMemberFields(CppClassPtr&, const std::map<std::string, std::string>& doc_members, const generator::IntEnumClass&) const;
......
...@@ -44,7 +44,7 @@ namespace armarx::aron::codegenerator::cpp::generator ...@@ -44,7 +44,7 @@ namespace armarx::aron::codegenerator::cpp::generator
} }
} }
std::vector<CppFieldPtr> IntEnumClass::getPublicVariableDeclarations(const std::string&) const std::vector<CppFieldPtr> IntEnumClass::getPublicVariableDeclarations(const std::string& className) const
{ {
std::vector<CppFieldPtr> fields; std::vector<CppFieldPtr> fields;
std::stringstream enum_to_name; std::stringstream enum_to_name;
...@@ -52,6 +52,9 @@ namespace armarx::aron::codegenerator::cpp::generator ...@@ -52,6 +52,9 @@ namespace armarx::aron::codegenerator::cpp::generator
std::stringstream enum_to_value; std::stringstream enum_to_value;
std::stringstream value_to_enum; std::stringstream value_to_enum;
// add legacy typedef
fields.push_back(std::make_shared<CppField>("using", std::string(IMPL_ENUM), simox::alg::to_lower(className) + "_details::Enum", "Legacy typedef of enum"));
enum_to_name << "{" << std::endl; enum_to_name << "{" << std::endl;
name_to_enum << "{" << std::endl; name_to_enum << "{" << std::endl;
enum_to_value << "{" << std::endl; enum_to_value << "{" << std::endl;
...@@ -164,7 +167,7 @@ namespace armarx::aron::codegenerator::cpp::generator ...@@ -164,7 +167,7 @@ namespace armarx::aron::codegenerator::cpp::generator
return {{{"value", ARON_OTHER_ACCESSOR + ".value"}}, false}; return {{{"value", ARON_OTHER_ACCESSOR + ".value"}}, false};
} }
CppCtorPtr IntEnumClass::toInnerEnumCtor(const std::string& name) const CppCtorPtr IntEnumClass::toEnumCtor(const std::string& name) const
{ {
CppCtorPtr c = std::make_shared<CppCtor>(name + "(const " + std::string(IMPL_ENUM) + " e)"); CppCtorPtr c = std::make_shared<CppCtor>(name + "(const " + std::string(IMPL_ENUM) + " e)");
std::vector<std::pair<std::string, std::string>> initList = {{"value", "e"}}; std::vector<std::pair<std::string, std::string>> initList = {{"value", "e"}};
...@@ -173,12 +176,12 @@ namespace armarx::aron::codegenerator::cpp::generator ...@@ -173,12 +176,12 @@ namespace armarx::aron::codegenerator::cpp::generator
return c; return c;
} }
CppEnumPtr IntEnumClass::toInnerEnumDefinition() const std::vector<CppEnumFieldPtr> IntEnumClass::toEnumFields() const
{ {
CppEnumPtr e = std::make_shared<CppEnum>(std::string(IMPL_ENUM), "The internal enum definition of the enum of this autogenerated class."); std::vector<CppEnumFieldPtr> e;
for (const auto& [key, value] : type.getAcceptedValueMap()) for (const auto& [key, value] : type.getAcceptedValueMap())
{ {
e->addField(std::make_shared<CppEnumField>(key)); e.push_back(std::make_shared<CppEnumField>(key));
} }
return e; return e;
} }
......
...@@ -54,8 +54,8 @@ namespace armarx::aron::codegenerator::cpp::generator ...@@ -54,8 +54,8 @@ namespace armarx::aron::codegenerator::cpp::generator
// TODO: Move some of those methods to upper class for enums (if we want to support multiple enums) // TODO: Move some of those methods to upper class for enums (if we want to support multiple enums)
//CppCtorPtr toCopyCtor(const std::string&) const; //CppCtorPtr toCopyCtor(const std::string&) const;
CppCtorPtr toInnerEnumCtor(const std::string&) const; std::vector<CppEnumFieldPtr> toEnumFields() const;
CppEnumPtr toInnerEnumDefinition() const; CppCtorPtr toEnumCtor(const std::string&) const;
CppMethodPtr toIntMethod() const; CppMethodPtr toIntMethod() const;
CppMethodPtr toCopyAssignmentMethod() const; CppMethodPtr toCopyAssignmentMethod() const;
CppMethodPtr toEnumAssignmentMethod() const; CppMethodPtr toEnumAssignmentMethod() const;
......
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