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/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 diff --git a/cimgen/cimgen.py b/cimgen/cimgen.py index a39abe4d..0e0d7313 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]: @@ -522,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) @@ -717,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 9dca2ccb..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, @@ -432,6 +432,8 @@ def set_default(dataType): return "''" elif dataType == "Boolean": return "false" + elif dataType == "Float": + return "0.0" else: return "nullptr" @@ -474,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..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, @@ -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/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 50257c88..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) @@ -126,9 +126,9 @@ 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: + 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() 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" ]