From 0a0ca2f24e6d4ed38a83437b2098195f904f5120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Thu, 25 Jul 2024 21:51:14 +0200 Subject: [PATCH 1/5] fix the recognition of float classes (e.g. Float, ActivePowerPerFrequency), fix generation of Float class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Günther --- cimgen/cimgen.py | 6 +++++- cimgen/languages/cpp/lang_pack.py | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cimgen/cimgen.py b/cimgen/cimgen.py index a39abe4d..ef40303a 100644 --- a/cimgen/cimgen.py +++ b/cimgen/cimgen.py @@ -221,6 +221,7 @@ def _get_rid_of_hash(name): class CIMComponentDefinition: def __init__(self, rdfsEntry): + self.about = rdfsEntry.about() self.attribute_list = [] self.comment = rdfsEntry.comment() self.instance_list = [] @@ -272,6 +273,8 @@ def _simple_float_attribute(attr): return False def is_a_float(self): + if self.about == "Float": + return True simple_float = False for attr in self.attribute_list: if CIMComponentDefinition._simple_float_attribute(attr): @@ -283,11 +286,12 @@ def is_a_float(self): return True candidate_array = {"value": False, "unit": False, "multiplier": False} + optional_attributes = ["denominatorUnit", "denominatorMultiplier"] for attr in self.attribute_list: key = attr["label"] if key in candidate_array: candidate_array[key] = True - else: + elif key not in optional_attributes: return False for key in candidate_array: if not candidate_array[key]: diff --git a/cimgen/languages/cpp/lang_pack.py b/cimgen/languages/cpp/lang_pack.py index 9dca2ccb..570de640 100644 --- a/cimgen/languages/cpp/lang_pack.py +++ b/cimgen/languages/cpp/lang_pack.py @@ -432,6 +432,8 @@ def set_default(dataType): return "''" elif dataType == "Boolean": return "false" + elif dataType == "Float": + return "0.0" else: return "nullptr" From c406409e93152502329d585b17560854b7101085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Thu, 25 Jul 2024 22:12:31 +0200 Subject: [PATCH 2/5] sort schema files and attributes to guarantee a stable order in the generated sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Günther --- cimgen/cimgen.py | 3 ++- cimgen/languages/cpp/lang_pack.py | 3 +-- cimgen/languages/cpp/templates/cpp_object_template.mustache | 4 ++-- cimgen/languages/java/lang_pack.py | 3 +-- cimgen/languages/python/lang_pack.py | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cimgen/cimgen.py b/cimgen/cimgen.py index ef40303a..0e0d7313 100644 --- a/cimgen/cimgen.py +++ b/cimgen/cimgen.py @@ -526,6 +526,7 @@ def _write_python_files(elem_dict, lang_pack, output_path, version): initial_indent="", subsequent_indent=" " * 6, ) + class_details["attributes"].sort(key=lambda d: d["label"]) _write_files(class_details, output_path, version) @@ -721,7 +722,7 @@ def cim_generate(directory, output_path, version, lang_pack): t0 = time() # iterate over files in the directory and check if they are RDF files - for file in os.listdir(directory): + for file in sorted(os.listdir(directory)): if file.endswith(".rdf"): logger.info('Start of parsing file "%s"', file) diff --git a/cimgen/languages/cpp/lang_pack.py b/cimgen/languages/cpp/lang_pack.py index 570de640..2698d92a 100644 --- a/cimgen/languages/cpp/lang_pack.py +++ b/cimgen/languages/cpp/lang_pack.py @@ -476,13 +476,12 @@ def _create_header_include_file(directory, header_include_filename, header, foot lines = [] - for filename in os.listdir(directory): + for filename in sorted(os.listdir(directory)): filepath = os.path.join(directory, filename) basepath, ext = os.path.splitext(filepath) basename = os.path.basename(basepath) if ext == ".hpp" and not _is_enum_class(filepath) and basename not in blacklist: lines.append(before + basename + after) - lines.sort() for line in lines: header.append(line) for line in footer: diff --git a/cimgen/languages/cpp/templates/cpp_object_template.mustache b/cimgen/languages/cpp/templates/cpp_object_template.mustache index 1fa1b14b..529623c4 100644 --- a/cimgen/languages/cpp/templates/cpp_object_template.mustache +++ b/cimgen/languages/cpp/templates/cpp_object_template.mustache @@ -13,11 +13,11 @@ using namespace CIMPP; {{class_name}}::~{{class_name}}() {}; {{#attributes}} -{{#langPack.create_class_assign}}{{.}}{{/langPack.create_class_assign}} +{{#langPack.create_assign}}{{.}}{{/langPack.create_assign}} {{/attributes}} {{#attributes}} -{{#langPack.create_assign}}{{.}}{{/langPack.create_assign}} +{{#langPack.create_class_assign}}{{.}}{{/langPack.create_class_assign}} {{/attributes}} namespace CIMPP { diff --git a/cimgen/languages/java/lang_pack.py b/cimgen/languages/java/lang_pack.py index 339249c6..f9a0e4fd 100644 --- a/cimgen/languages/java/lang_pack.py +++ b/cimgen/languages/java/lang_pack.py @@ -400,13 +400,12 @@ def _create_header_include_file(directory, header_include_filename, header, foot lines = [] - for filename in os.listdir(directory): + for filename in sorted(os.listdir(directory)): filepath = os.path.join(directory, filename) basepath, ext = os.path.splitext(filepath) basename = os.path.basename(basepath) if ext == ".java" and not _is_enum_class(filepath) and basename not in blacklist: lines.append(before + 'Map.entry("' + basename + '", new cim4j.' + basename + after + "),\n") - lines.sort() lines[-1] = lines[-1].replace("),", ")") for line in lines: header.append(line) diff --git a/cimgen/languages/python/lang_pack.py b/cimgen/languages/python/lang_pack.py index 50257c88..40fc1242 100644 --- a/cimgen/languages/python/lang_pack.py +++ b/cimgen/languages/python/lang_pack.py @@ -126,7 +126,7 @@ def _create_base(path): def resolve_headers(path): filenames = glob.glob(path + "/*.py") include_names = [] - for filename in filenames: + for filename in sorted(filenames): include_names.append(os.path.splitext(os.path.basename(filename))[0]) with open(path + "/__init__.py", "w") as header_file: for include_name in include_names: From 93e93b7f8326c54b98840d535bfc22dcf6dab820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Thu, 25 Jul 2024 22:33:45 +0200 Subject: [PATCH 3/5] set encoding to utf-8 to fix generation on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Günther --- cimgen/languages/cpp/lang_pack.py | 4 ++-- cimgen/languages/java/lang_pack.py | 4 ++-- cimgen/languages/javascript/lang_pack.py | 4 ++-- cimgen/languages/python/lang_pack.py | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cimgen/languages/cpp/lang_pack.py b/cimgen/languages/cpp/lang_pack.py index 2698d92a..d81ccaae 100644 --- a/cimgen/languages/cpp/lang_pack.py +++ b/cimgen/languages/cpp/lang_pack.py @@ -74,9 +74,9 @@ def run_template(outputPath, class_details): for template_info in templates: class_file = os.path.join(outputPath, class_details["class_name"] + template_info["ext"]) if not os.path.exists(class_file): - with open(class_file, "w") as file: + with open(class_file, "w", encoding="utf-8") as file: templates = files("cimgen.languages.cpp.templates") - with templates.joinpath(template_info["filename"]).open() as f: + with templates.joinpath(template_info["filename"]).open(encoding="utf-8") as f: args = { "data": class_details, "template": f, diff --git a/cimgen/languages/java/lang_pack.py b/cimgen/languages/java/lang_pack.py index f9a0e4fd..06eedb93 100644 --- a/cimgen/languages/java/lang_pack.py +++ b/cimgen/languages/java/lang_pack.py @@ -66,10 +66,10 @@ def run_template(outputPath, class_details): for template_info in templates: class_file = os.path.join(outputPath, class_details["class_name"] + template_info["ext"]) if not os.path.exists(class_file): - with open(class_file, "w") as file: + with open(class_file, "w", encoding="utf-8") as file: class_details["setDefault"] = _set_default templates = files("cimgen.languages.java.templates") - with templates.joinpath(template_info["filename"]).open() as f: + with templates.joinpath(template_info["filename"]).open(encoding="utf-8") as f: args = { "data": class_details, "template": f, diff --git a/cimgen/languages/javascript/lang_pack.py b/cimgen/languages/javascript/lang_pack.py index 018b177b..d605e99b 100644 --- a/cimgen/languages/javascript/lang_pack.py +++ b/cimgen/languages/javascript/lang_pack.py @@ -190,9 +190,9 @@ def run_template(outputPath, class_details): def write_templated_file(class_file, class_details, template_filename): if not os.path.exists(class_file): - with open(class_file, "w") as file: + with open(class_file, "w", encoding="utf-8") as file: templates = files("cimgen.languages.javascript.templates") - with templates.joinpath(template_filename).open() as f: + with templates.joinpath(template_filename).open(encoding="utf-8") as f: args = {"data": class_details, "template": f, "partials_dict": partials} output = chevron.render(**args) file.write(output) diff --git a/cimgen/languages/python/lang_pack.py b/cimgen/languages/python/lang_pack.py index 40fc1242..a6ae58ac 100644 --- a/cimgen/languages/python/lang_pack.py +++ b/cimgen/languages/python/lang_pack.py @@ -80,10 +80,10 @@ def run_template(version_path, class_details): for template_info in template_files: class_file = os.path.join(version_path, class_details["class_name"] + template_info["ext"]) if not os.path.exists(class_file): - with open(class_file, "w") as file: + with open(class_file, "w", encoding="utf-8") as file: class_details["setDefault"] = _set_default templates = files("cimgen.languages.python.templates") - with templates.joinpath(template_info["filename"]).open() as f: + with templates.joinpath(template_info["filename"]).open(encoding="utf-8") as f: args = { "data": class_details, "template": f, @@ -95,7 +95,7 @@ def run_template(version_path, class_details): def _create_init(path): init_file = path + "/__init__.py" - with open(init_file, "w"): + with open(init_file, "w", encoding="utf-8"): pass @@ -118,7 +118,7 @@ def _create_base(path): " return dict\n", ] - with open(base_path, "w") as f: + with open(base_path, "w", encoding="utf-8") as f: for line in base: f.write(line) @@ -128,7 +128,7 @@ def resolve_headers(path): include_names = [] for filename in sorted(filenames): include_names.append(os.path.splitext(os.path.basename(filename))[0]) - with open(path + "/__init__.py", "w") as header_file: + with open(path + "/__init__.py", "w", encoding="utf-8") as header_file: for include_name in include_names: header_file.write("from " + "." + include_name + " import " + include_name + " as " + include_name + "\n") header_file.close() From f8de63464de62b2b36f65063775ffaf4c9889906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Sat, 27 Jul 2024 13:09:57 +0200 Subject: [PATCH 4/5] improve README: add option cgmes_version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Günther --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 18c0ae4e..eb52133b 100644 --- a/README.md +++ b/README.md @@ -14,18 +14,19 @@ Python tool for code generation from CIM data model for several programming lang ```bash pip install -e . -cimgen --outdir=output/cpp/CGMES_2.4.15_27JAN2020 --schemadir=cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=cpp +cimgen --outdir=output/cpp/CGMES_2.4.15_27JAN2020 --schemadir=cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=cpp --cgmes_version=cgmes_v2_4_15 ``` -This will build version `CGMES_2.4.15_27JAN2020` in the subfolder `CGMES_2.4.15_27JAN2020_cpp`. +This will build version `CGMES_2.4.15_27JAN2020` in the subfolder `output/cpp/CGMES_2.4.15_27JAN2020`. If you wish to build an alternative version, you can see available options in the subfolder called `cgmes_schema`. +For the schema `CGMES_3.0.0` you have to use the option `--cgmes_version=cgmes_v3_0_0`. #### Generating C++ files in a Docker container ```bash docker build --tag cimgen --file Dockerfile . -docker run --volume "$(pwd)/output:/output" cimgen --outdir=/output/cpp/CGMES_2.4.15_27JAN2020 --schemadir=/cimgen/cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=cpp +docker run --volume "$(pwd)/output:/output" cimgen --outdir=/output/cpp/CGMES_2.4.15_27JAN2020 --schemadir=/cimgen/cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=cpp --cgmes_version=cgmes_v2_4_15 ``` ### Generating Python files @@ -34,7 +35,7 @@ docker run --volume "$(pwd)/output:/output" cimgen --outdir=/output/cpp/CGMES_2. ```bash pip install -e . -cimgen --outdir=output/python/CGMES_2.4.15_27JAN2020 --schemadir=cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=python +cimgen --outdir=output/python/CGMES_2.4.15_27JAN2020 --schemadir=cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=python --cgmes_version=cgmes_v2_4_15 ``` `outdir` can be set to whichever absolute path you wish to create the files in. @@ -43,7 +44,7 @@ cimgen --outdir=output/python/CGMES_2.4.15_27JAN2020 --schemadir=cgmes_schema/CG ```bash docker build --tag cimgen --file Dockerfile . -docker run --volume "$(pwd)/output:/output" cimgen --outdir=/output/python/CGMES_2.4.15_27JAN2020 --schemadir=/cimgen/cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=python +docker run --volume "$(pwd)/output:/output" cimgen --outdir=/output/python/CGMES_2.4.15_27JAN2020 --schemadir=/cimgen/cgmes_schema/CGMES_2.4.15_27JAN2020 --langdir=python --cgmes_version=cgmes_v2_4_15 ``` ## License From 944a6f71f79e6b1faa45585288d007d13e33ea1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Sat, 27 Jul 2024 15:41:25 +0200 Subject: [PATCH 5/5] remove cmake dependency, as it is no longer necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Günther --- CMakeLists.txt | 26 -------------------------- pyproject.toml | 1 - 2 files changed, 27 deletions(-) delete mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 4c3f99d7..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - - -if(NOT USE_CIM_VERSION) - set(USE_CIM_VERSION "CGMES_2.4.15_27JAN2020") -endif() -if(NOT CGMES_OUTPUT_FOLDER) - set(CGMES_OUTPUT_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/${USE_CIM_VERSION}" CACHE STRING "Define CGMES c++ file output folder") -endif() -if(NOT CIM_OUTPUT_LANG) - set(CIM_OUTPUT_LANG "cpp") -endif() -if(USE_CIM_VERSION STREQUAL "CGMES_2.4.13_18DEC2013") - message(STATUS "Using CIM Version: ${USE_CIM_VERSION}") -elseif(USE_CIM_VERSION STREQUAL "CGMES_2.4.15_16FEB2016") - message(STATUS "Using CIM Version: ${USE_CIM_VERSION}") -elseif(USE_CIM_VERSION STREQUAL "CGMES_2.4.15_27JAN2020") - message(STATUS "Using CIM Version: ${USE_CIM_VERSION}") -else() - message(FATAL_ERROR "${USE_CIM_VERSION} is an invalid value for USE_CIM_VERSION") -endif() -message(STATUS "Using output folder: ${CGMES_OUTPUT_FOLDER}") -set(SCHEMA_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/cgmes_schema/${USE_CIM_VERSION}") -find_package (Python COMPONENTS Interpreter) -execute_process(WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/build.py --outdir=${CGMES_OUTPUT_FOLDER} --schemadir=${SCHEMA_FOLDER} --langdir=${CIM_OUTPUT_LANG}) -unset(SCHEMA_FOLDER) diff --git a/pyproject.toml b/pyproject.toml index 0c45cd45..3c4e0177 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,6 @@ keywords = ["cim", "cgmes", "code-generation"] dependencies = [ "xmltodict >= 0.13.0, < 1", "chevron >= 0.14.0, < 1", - "cmake >= 3.27.0, < 4", "pydantic < 2", "beautifulsoup4 >= 4.12.2, < 5" ]