2014-02-17 22:13:55 +00:00
|
|
|
###############################################################################
|
|
|
|
|
# #
|
|
|
|
|
# This file is part of IfcOpenShell. #
|
|
|
|
|
# #
|
|
|
|
|
# IfcOpenShell is free software: you can redistribute it and/or modify #
|
|
|
|
|
# it under the terms of the Lesser GNU General Public License as published by #
|
|
|
|
|
# the Free Software Foundation, either version 3.0 of the License, or #
|
|
|
|
|
# (at your option) any later version. #
|
|
|
|
|
# #
|
|
|
|
|
# IfcOpenShell is distributed in the hope that it will be useful, #
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
|
|
|
# Lesser GNU General Public License for more details. #
|
|
|
|
|
# #
|
|
|
|
|
# You should have received a copy of the Lesser GNU General Public License #
|
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
|
|
|
# #
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
2017-08-04 16:29:26 +02:00
|
|
|
import operator
|
|
|
|
|
|
2016-02-18 13:17:15 +01:00
|
|
|
import codegen
|
2014-02-17 22:13:55 +00:00
|
|
|
import templates
|
|
|
|
|
import documentation
|
|
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
|
2016-02-18 13:17:15 +01:00
|
|
|
class Header(codegen.Base):
|
2014-02-17 22:13:55 +00:00
|
|
|
def __init__(self, mapping):
|
|
|
|
|
declarations = []
|
|
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
write = lambda str, **kwargs: declarations.append(
|
|
|
|
|
str
|
|
|
|
|
% dict({"documentation": templates.multi_line_comment(documentation.description(kwargs["name"]))}, **kwargs)
|
|
|
|
|
)
|
|
|
|
|
|
2015-01-05 14:11:42 +00:00
|
|
|
forward_names = list(mapping.schema.entities.keys()) + list(mapping.schema.simpletypes.keys())
|
2020-11-01 20:08:27 +07:00
|
|
|
forward_definitions = "".join(["class %s; " % n for n in forward_names])
|
|
|
|
|
|
2014-02-17 22:13:55 +00:00
|
|
|
for name, type in mapping.schema.selects.items():
|
|
|
|
|
write(templates.select, name=name)
|
|
|
|
|
|
|
|
|
|
for name, type in mapping.schema.enumerations.items():
|
|
|
|
|
short_name = name[:-4] if name.endswith("Enum") else name
|
2020-11-01 20:08:27 +07:00
|
|
|
write(templates.enumeration, name=name, values=", ".join(["%s_%s" % (short_name, v) for v in type.values]))
|
|
|
|
|
|
2015-01-05 14:11:42 +00:00
|
|
|
emitted_simpletypes = set()
|
|
|
|
|
while len(emitted_simpletypes) < len(mapping.schema.simpletypes):
|
|
|
|
|
for name, type in mapping.schema.simpletypes.items():
|
2020-11-01 20:08:27 +07:00
|
|
|
if name.lower() in emitted_simpletypes:
|
|
|
|
|
continue
|
2015-01-05 14:11:42 +00:00
|
|
|
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
|
|
|
|
|
attr_type = mapping.make_argument_type(type)
|
|
|
|
|
superclass = mapping.simple_type_parent(name)
|
2020-11-01 20:08:27 +07:00
|
|
|
if superclass is None:
|
2015-01-05 14:11:42 +00:00
|
|
|
superclass = "IfcUtil::IfcBaseType"
|
2016-04-08 23:23:29 +02:00
|
|
|
elif superclass.lower() not in emitted_simpletypes:
|
2015-01-05 14:11:42 +00:00
|
|
|
continue
|
2016-04-08 23:23:29 +02:00
|
|
|
else:
|
|
|
|
|
# Case normalize
|
|
|
|
|
superclass = [k for k in mapping.schema.simpletypes.keys() if k.lower() == superclass.lower()][0]
|
|
|
|
|
emitted_simpletypes.add(name.lower())
|
2015-01-05 14:11:42 +00:00
|
|
|
write(templates.simpletype, name=name, type=type_str, attr_type=attr_type, superclass=superclass)
|
2014-02-17 22:13:55 +00:00
|
|
|
|
|
|
|
|
class_definitions = []
|
|
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
write = lambda str, **kwargs: class_definitions.append(
|
|
|
|
|
str
|
|
|
|
|
% dict({"documentation": templates.multi_line_comment(documentation.description(kwargs["name"]))}, **kwargs)
|
|
|
|
|
)
|
2014-02-17 22:13:55 +00:00
|
|
|
|
|
|
|
|
emitted_entities = set()
|
|
|
|
|
while len(emitted_entities) < len(mapping.schema.entities):
|
|
|
|
|
for name, type in mapping.schema.entities.items():
|
2020-11-01 20:08:27 +07:00
|
|
|
if name.lower() in emitted_entities:
|
|
|
|
|
continue
|
2016-04-08 23:23:29 +02:00
|
|
|
if len(type.supertypes) == 0 or set(map(str.lower, type.supertypes)) <= emitted_entities:
|
2014-02-17 22:13:55 +00:00
|
|
|
attr_lines = []
|
2020-11-01 20:08:27 +07:00
|
|
|
|
2014-02-17 22:13:55 +00:00
|
|
|
def write_method(attr):
|
|
|
|
|
if attr.optional:
|
|
|
|
|
attr_lines.append(templates.optional_attribute_description % (attr.name, name))
|
2020-11-01 20:08:27 +07:00
|
|
|
attr_lines.append("bool has%s() const;" % (attr.name))
|
|
|
|
|
attr_lines.extend(
|
|
|
|
|
["/// %s" % d for d in documentation.description(".".join((name, attr.name)))]
|
|
|
|
|
)
|
2014-02-17 22:13:55 +00:00
|
|
|
type_str = mapping.get_parameter_type(attr, allow_optional=False, allow_entities=False)
|
|
|
|
|
if mapping.make_argument_type(attr) != "IfcUtil::Argument_UNKNOWN":
|
2020-11-01 20:08:27 +07:00
|
|
|
attr_lines.append("%s %s() const;" % (type_str, attr.name))
|
|
|
|
|
attr_lines.append("void set%s(%s v);" % (attr.name, type_str))
|
2014-02-17 22:13:55 +00:00
|
|
|
|
|
|
|
|
[write_method(attr) for attr in type.attributes]
|
|
|
|
|
|
|
|
|
|
inv_lines = []
|
2020-11-01 20:08:27 +07:00
|
|
|
|
2014-02-17 22:13:55 +00:00
|
|
|
def write_inverse(attr):
|
2020-11-01 20:08:27 +07:00
|
|
|
inv_lines.append(
|
|
|
|
|
templates.inverse_attr
|
|
|
|
|
% {"name": attr.name, "entity": attr.entity, "attribute": attr.attribute}
|
|
|
|
|
)
|
2014-02-17 22:13:55 +00:00
|
|
|
|
|
|
|
|
if type.inverse:
|
2020-08-29 10:23:59 +02:00
|
|
|
[write_inverse(attr) for attr in type.inverse]
|
2014-02-17 22:13:55 +00:00
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
attributes = "\n".join(["%s%s" % (" " * 4, a) for a in attr_lines])
|
|
|
|
|
if len(attributes):
|
|
|
|
|
attributes += "\n"
|
2014-02-17 22:13:55 +00:00
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
inverse = "\n".join(["%s%s" % (" " * 4, a) for a in inv_lines])
|
|
|
|
|
if len(inverse):
|
|
|
|
|
inverse += "\n"
|
2014-02-17 22:13:55 +00:00
|
|
|
|
2016-04-08 23:23:29 +02:00
|
|
|
def case_norm(n):
|
|
|
|
|
n = n.lower()
|
|
|
|
|
return [k for k in mapping.schema.entities.keys() if k.lower() == n][0]
|
2020-11-01 20:08:27 +07:00
|
|
|
|
|
|
|
|
supertypes = map(case_norm, type.supertypes) if len(type.supertypes) else ["IfcUtil::IfcBaseEntity"]
|
|
|
|
|
superclass = ": %s " % (", ".join(["public %s" % c for c in supertypes]))
|
2014-02-17 22:13:55 +00:00
|
|
|
|
|
|
|
|
argument_count = mapping.argument_count(type)
|
|
|
|
|
|
|
|
|
|
argument_start = argument_count - len(type.attributes)
|
|
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
argument_name_function_body_switch_stmt = (
|
|
|
|
|
" switch (i) {%s}"
|
|
|
|
|
% (
|
|
|
|
|
"".join(
|
|
|
|
|
[
|
|
|
|
|
'case %d: return "%s"; ' % (i + argument_start, attr.name)
|
|
|
|
|
for i, attr in enumerate(type.attributes)
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
if len(type.attributes)
|
|
|
|
|
else ""
|
|
|
|
|
)
|
|
|
|
|
argument_name_function_body_tail = (
|
|
|
|
|
(" return %s::getArgumentName(i); " % type.supertypes[0])
|
|
|
|
|
if len(type.supertypes) == 1
|
|
|
|
|
else ' (void)i; throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); '
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
argument_name_function_body = (
|
|
|
|
|
argument_name_function_body_switch_stmt + argument_name_function_body_tail
|
|
|
|
|
)
|
2014-02-17 22:13:55 +00:00
|
|
|
|
2017-08-04 16:29:26 +02:00
|
|
|
derived = mapping.derived_in_supertype(type)
|
2020-11-01 20:08:27 +07:00
|
|
|
attribute_names = list(map(operator.attrgetter("name"), mapping.arguments(type)))
|
2017-08-04 16:29:26 +02:00
|
|
|
derived_in_supertype = set(derived) & set(attribute_names)
|
|
|
|
|
derived_in_supertype_indices = sorted(attribute_names.index(nm) for nm in derived_in_supertype)
|
2020-11-01 20:08:27 +07:00
|
|
|
attribute_type_cases = [
|
|
|
|
|
"case %d: return IfcUtil::Argument_DERIVED; " % idx for idx in derived_in_supertype_indices
|
|
|
|
|
]
|
|
|
|
|
attribute_type_cases += [
|
|
|
|
|
"case %d: return %s; " % (i + argument_start, mapping.make_argument_type(attr))
|
|
|
|
|
for i, attr in enumerate(type.attributes)
|
|
|
|
|
]
|
|
|
|
|
argument_type_function_body_switch_stmt = (
|
|
|
|
|
" switch (i) {%s}" % ("".join(attribute_type_cases)) if len(type.attributes) else ""
|
|
|
|
|
)
|
|
|
|
|
argument_type_function_body_tail = (
|
|
|
|
|
(" return %s::getArgumentType(i); " % type.supertypes[0])
|
|
|
|
|
if len(type.supertypes) == 1
|
|
|
|
|
else ' (void)i; throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); '
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
argument_type_function_body = (
|
|
|
|
|
argument_type_function_body_switch_stmt + argument_type_function_body_tail
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
argument_entity_function_body_switch_stmt = (
|
|
|
|
|
" switch (i) {%s}"
|
|
|
|
|
% (
|
|
|
|
|
"".join(
|
|
|
|
|
[
|
|
|
|
|
"case %d: return %s; " % (i + argument_start, mapping.make_argument_entity(attr))
|
|
|
|
|
for i, attr in enumerate(type.attributes)
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
if len(type.attributes)
|
|
|
|
|
else ""
|
|
|
|
|
)
|
|
|
|
|
argument_entity_function_body_tail = (
|
|
|
|
|
(" return %s::getArgumentEntity(i); " % type.supertypes[0])
|
|
|
|
|
if len(type.supertypes) == 1
|
|
|
|
|
else ' (void)i; throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); '
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
argument_entity_function_body = (
|
|
|
|
|
argument_entity_function_body_switch_stmt + argument_entity_function_body_tail
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
constructor_arguments = ", ".join(
|
|
|
|
|
"%(full_type)s v%(index)d_%(name)s" % a for a in mapping.get_assignable_arguments(type)
|
|
|
|
|
)
|
2014-02-17 22:13:55 +00:00
|
|
|
|
|
|
|
|
write(templates.entity, **locals())
|
|
|
|
|
emitted_entities.add(name)
|
|
|
|
|
|
|
|
|
|
self.str = templates.header % {
|
2020-11-01 20:08:27 +07:00
|
|
|
"schema_name_upper": mapping.schema.name.upper(),
|
|
|
|
|
"schema_name": mapping.schema.name.capitalize(),
|
|
|
|
|
"declarations": "".join(declarations),
|
|
|
|
|
"forward_definitions": forward_definitions,
|
|
|
|
|
"class_definitions": "".join(class_definitions),
|
2014-02-17 22:13:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.schema_name = mapping.schema.name.capitalize()
|
2020-11-01 20:08:27 +07:00
|
|
|
|
|
|
|
|
self.file_name = "%s.h" % self.schema_name
|
|
|
|
|
|
2014-02-17 22:13:55 +00:00
|
|
|
def __repr__(self):
|
|
|
|
|
return self.str
|
2020-03-17 11:55:28 +01:00
|
|
|
|
2020-11-01 20:08:27 +07:00
|
|
|
|
2020-03-17 11:55:28 +01:00
|
|
|
Generator = Header
|