diff --git a/cimgen/languages/cpp/lang_pack.py b/cimgen/languages/cpp/lang_pack.py index 0f22dea9..755757df 100644 --- a/cimgen/languages/cpp/lang_pack.py +++ b/cimgen/languages/cpp/lang_pack.py @@ -11,14 +11,14 @@ def location(version): # NOSONAR # Setup called only once: make output directory, create base class, create profile class, etc. # This just makes sure we have somewhere to write the classes. # cgmes_profile_details contains index, names and uris for each profile. -# We don't use that here because we aren't exporting into -# separate profiles. +# We use that to create the header data for the profiles. def setup(output_path: str, cgmes_profile_details: list, cim_namespace: str): # NOSONAR if not os.path.exists(output_path): os.makedirs(output_path) else: for filename in os.listdir(output_path): os.remove(os.path.join(output_path, filename)) + _create_cgmes_profile(output_path, cgmes_profile_details, cim_namespace) base = {"base_class": "BaseClass", "class_location": location} @@ -43,6 +43,10 @@ def setup(output_path: str, cgmes_profile_details: list, cim_namespace: str): # {"filename": "cpp_string_header_template.mustache", "ext": ".hpp"}, {"filename": "cpp_string_object_template.mustache", "ext": ".cpp"}, ] +profile_template_files = [ + {"filename": "cpp_cgmesProfile_header_template.mustache", "ext": ".hpp"}, + {"filename": "cpp_cgmesProfile_object_template.mustache", "ext": ".cpp"}, +] def get_class_location(class_name, class_map, version): # NOSONAR @@ -92,6 +96,16 @@ def _write_templated_file(class_file, class_details, template_filename): file.write(output) +def _create_cgmes_profile(output_path: str, profile_details: list, cim_namespace: str): + for template_info in profile_template_files: + class_file = os.path.join(output_path, "CGMESProfile" + template_info["ext"]) + class_details = { + "profiles": profile_details, + "cim_namespace": cim_namespace, + } + _write_templated_file(class_file, class_details, template_info["filename"]) + + # This function just allows us to avoid declaring a variable called 'switch', # which is in the definition of the ExcBBC class. def label(text, render): @@ -421,6 +435,7 @@ def _attribute_is_primitive_string(attribute: dict) -> bool: "assignments", "BaseClass", "BaseClassDefiner", + "CGMESProfile", "CIMClassList", "CIMFactory", "CIMNamespaces", diff --git a/cimgen/languages/cpp/static/BaseClass.cpp b/cimgen/languages/cpp/static/BaseClass.cpp index ff3a94a5..5baf1c2c 100644 --- a/cimgen/languages/cpp/static/BaseClass.cpp +++ b/cimgen/languages/cpp/static/BaseClass.cpp @@ -4,6 +4,9 @@ using namespace CIMPP; BaseClass::~BaseClass() {} +std::list BaseClass::getPossibleProfilesForClass() const { return {}; } +std::map> BaseClass::getPossibleProfilesForAttributes() const { return {}; } + const char BaseClass::debugName[] = "BaseClass"; const char* BaseClass::debugString() const { diff --git a/cimgen/languages/cpp/static/BaseClass.hpp b/cimgen/languages/cpp/static/BaseClass.hpp index 680172a8..a5b797f3 100644 --- a/cimgen/languages/cpp/static/BaseClass.hpp +++ b/cimgen/languages/cpp/static/BaseClass.hpp @@ -5,16 +5,18 @@ #define CGMES_BUILD #endif +#include +#include #include #include #include "BaseClassDefiner.hpp" +#include "CGMESProfile.hpp" class BaseClass { std::string rdfid; public: - enum cgmesProfile {EQ = 0, SSH = 1, TP = 2, SV = 3, DY = 4, GL = 5, DI = 6}; virtual ~BaseClass(); void setRdfid(const std::string& id) { rdfid = id; } @@ -23,6 +25,9 @@ class BaseClass static const char debugName[]; virtual const char* debugString() const; + virtual std::list getPossibleProfilesForClass() const; + virtual std::map> getPossibleProfilesForAttributes() const; + static void addConstructToMap(std::unordered_map& factory_map); static void addPrimitiveAssignFnsToMap(std::unordered_map& assign_map); static void addClassAssignFnsToMap(std::unordered_map& assign_map); diff --git a/cimgen/languages/cpp/templates/cpp_cgmesProfile_header_template.mustache b/cimgen/languages/cpp/templates/cpp_cgmesProfile_header_template.mustache new file mode 100644 index 00000000..41200a10 --- /dev/null +++ b/cimgen/languages/cpp/templates/cpp_cgmesProfile_header_template.mustache @@ -0,0 +1,30 @@ +#ifndef CGMESPROFILE_HPP +#define CGMESPROFILE_HPP +/* +Generated from the CGMES files via cimgen: https://github.com/sogno-platform/cimgen +*/ + +#include +#include + +enum class CGMESProfile : unsigned short +{ +{{#profiles}} + {{short_name}}, +{{/profiles}} +}; + +const CGMESProfile UnknownProfile = static_cast(-1); + +const std::list& getProfileList(); + +std::string getProfileShortName(CGMESProfile profile); +std::string getProfileLongName(CGMESProfile profile); +const std::list& getProfileURIs(CGMESProfile profile); + +CGMESProfile getProfileFromShortName(const std::string& name); +CGMESProfile getProfileFromLongName(const std::string& name); + +std::string getCimNamespace(); + +#endif // CGMESPROFILE_HPP diff --git a/cimgen/languages/cpp/templates/cpp_cgmesProfile_object_template.mustache b/cimgen/languages/cpp/templates/cpp_cgmesProfile_object_template.mustache new file mode 100644 index 00000000..a5e013a1 --- /dev/null +++ b/cimgen/languages/cpp/templates/cpp_cgmesProfile_object_template.mustache @@ -0,0 +1,110 @@ +/* +Generated from the CGMES files via cimgen: https://github.com/sogno-platform/cimgen +*/ +#include "CGMESProfile.hpp" + +#include +#include +#include + +static const std::list ProfileList = +{ +{{#profiles}} + CGMESProfile::{{short_name}}, +{{/profiles}} +}; + +static const std::map ProfileShortNames = +{ +{{#profiles}} + { CGMESProfile::{{short_name}}, "{{short_name}}" }, +{{/profiles}} +}; + +static const std::map ProfileLongNames = +{ +{{#profiles}} + { CGMESProfile::{{short_name}}, "{{long_name}}" }, +{{/profiles}} +}; + +static const std::map> ProfileURIs = +{ +{{#profiles}} + { CGMESProfile::{{short_name}}, { {{#uris}}"{{uri}}", {{/uris}}} }, +{{/profiles}} +}; + +static const std::string CimNamespace = "{{cim_namespace}}"; + +const std::list& +getProfileList() +{ + return ProfileList; +} + +std::string +getProfileShortName(CGMESProfile profile) +{ + auto it = ProfileShortNames.find(profile); + if (it != ProfileShortNames.end()) + { + return it->second; + } + return ""; // unknown profile +} + +std::string +getProfileLongName(CGMESProfile profile) +{ + auto it = ProfileLongNames.find(profile); + if (it != ProfileLongNames.end()) + { + return it->second; + } + return ""; // unknown profile +} + +const std::list& +getProfileURIs(CGMESProfile profile) +{ + static std::list empty_list; + auto it = ProfileURIs.find(profile); + if (it != ProfileURIs.end()) + { + return it->second; + } + return empty_list; // unknown profile +} + +CGMESProfile +getProfileFromShortName(const std::string& name) +{ + for (const auto& profile : ProfileShortNames) + { + if (name == profile.second) + { + return profile.first; + } + } + return UnknownProfile; +} + +CGMESProfile +getProfileFromLongName(const std::string& name) +{ + for (const auto& profile : ProfileLongNames) + { + if (name == profile.second) + { + return profile.first; + } + } + return UnknownProfile; +} + +std::string +getCimNamespace() +{ + return CimNamespace; +} diff --git a/cimgen/languages/cpp/templates/cpp_header_template.mustache b/cimgen/languages/cpp/templates/cpp_header_template.mustache index 2d8322de..58a15482 100644 --- a/cimgen/languages/cpp/templates/cpp_header_template.mustache +++ b/cimgen/languages/cpp/templates/cpp_header_template.mustache @@ -5,11 +5,13 @@ Generated from the CGMES files via cimgen: https://github.com/sogno-platform/cim */ #include +#include #include #include #include "{{sub_class_of}}.hpp" #include "BaseClassDefiner.hpp" +#include "CGMESProfile.hpp" {{#langPack._create_attribute_includes}}{{attributes}}{{/langPack._create_attribute_includes}} namespace CIMPP { @@ -33,6 +35,9 @@ namespace CIMPP static const char debugName[]; const char* debugString() const override; + std::list getPossibleProfilesForClass() const override; + std::map> getPossibleProfilesForAttributes() const override; + static void addConstructToMap(std::unordered_map& factory_map); static void addPrimitiveAssignFnsToMap(std::unordered_map& assign_map); static void addClassAssignFnsToMap(std::unordered_map& assign_map); diff --git a/cimgen/languages/cpp/templates/cpp_object_template.mustache b/cimgen/languages/cpp/templates/cpp_object_template.mustache index eec1a96b..845dd25e 100644 --- a/cimgen/languages/cpp/templates/cpp_object_template.mustache +++ b/cimgen/languages/cpp/templates/cpp_object_template.mustache @@ -15,6 +15,35 @@ using namespace CIMPP; {{class_name}}::{{class_name}}(){{#langPack.create_nullptr_assigns}} {{attributes}} {{/langPack.create_nullptr_assigns}} {}; {{class_name}}::~{{class_name}}() {}; +static const std::list PossibleProfilesForClass = +{ +{{#class_origin}} + CGMESProfile::{{origin}}, +{{/class_origin}} +}; + +static const std::map> PossibleProfilesForAttributes = +{ +{{#attributes}} + { "cim:{{about}}", { {{#attr_origin}}CGMESProfile::{{origin}}, {{/attr_origin}}} }, +{{/attributes}} +}; + +std::list +{{class_name}}::getPossibleProfilesForClass() const +{ + return PossibleProfilesForClass; +} + +std::map> +{{class_name}}::getPossibleProfilesForAttributes() const +{ + auto map = PossibleProfilesForAttributes; + auto&& parent_map = {{sub_class_of}}::getPossibleProfilesForAttributes(); + map.insert(parent_map.begin(), parent_map.end()); + return map; +} + {{#attributes}} {{#langPack.create_assign}}{{.}}{{/langPack.create_assign}} {{/attributes}}