2011-07-28 14:32:44 +00:00
header = """
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
""" . strip ( )
###############################################################################
# #
# This file can be used to generate C++ code from Express schema files. The #
# generated code works alongside the IfcOpenShell IfcParse library. This #
# script has only been tested on IFC2X3_TC1.exp and will most probably not #
# work on any other schemas. #
# #
# Note this script uses funcparserlib, which is available at: #
# http://code.google.com/p/funcparserlib/ #
# The script only works with revision e1df5066addd because it uses the some() #
# parser and is incompatible with other changes as well. #
# #
###############################################################################
import os , sys
2012-03-17 11:47:31 +00:00
import IfcDocumentation
2011-07-28 14:32:44 +00:00
filename = sys . argv [ 1 ]
#
# A class to split the Express schema files into seperate tokens
#
class Tokenizer ( object ) :
2012-03-13 11:56:52 +00:00
comment = [ ' (* ' , ' *) ' ]
termchars = ' ,;()=[]: '
def __init__ ( self , fn ) :
if hasattr ( fn , ' read ' ) : object . __setattr__ ( self , ' f ' , fn )
else : object . __setattr__ ( self , ' f ' , open ( fn , ' rb ' ) )
def __getattr__ ( self , name ) :
return getattr ( self . f , name )
def __setattr__ ( self , name , value ) :
setattr ( self . f , name , value )
def __iter__ ( self ) : return self
def next ( self ) :
def get ( ) :
buffer = ' '
in_comment = False
in_string = False
offset = self . tell ( )
while True :
c = self . read ( 2 )
if len ( c ) < 2 : raise StopIteration
if c in Tokenizer . comment :
in_comment = c == Tokenizer . comment [ 0 ]
continue
if in_string and c == " ' ' " :
buffer + = " ' "
continue
self . seek ( - 1 , 1 )
if not in_string and c [ 0 ] . isspace ( ) :
if ( len ( buffer ) ) : return buffer
else :
offset = self . tell ( )
continue
if not in_comment :
if len ( buffer ) and ( c [ 0 ] in Tokenizer . termchars or buffer [ - 1 ] in Tokenizer . termchars ) :
self . seek ( - 1 , 1 )
return buffer
buffer + = c [ 0 ]
return get ( )
2011-07-28 14:32:44 +00:00
#
# Some global variables to keep track of variable names
#
express_to_cpp = {
2012-03-13 11:56:52 +00:00
' BOOLEAN ' : ' bool ' ,
' LOGICAL ' : ' bool ' ,
' INTEGER ' : ' int ' ,
' REAL ' : ' double ' ,
' NUMBER ' : ' double ' ,
' STRING ' : ' std::string '
2011-07-28 14:32:44 +00:00
}
schema_version = ' '
enumerations = set ( )
selections = set ( )
entity_names = set ( )
simple_types = set ( )
selectable_simple_types = set ( )
argument_count = { }
parent_relations = { }
#
# Since inherited arguments of Express entities are placed in sequence before the non-inherited once, we need to keep track of how many inherited arguments exist
#
def argument_start ( c ) :
2012-03-13 11:56:52 +00:00
if c not in parent_relations : return 0
i = 0
while True :
c = parent_relations [ c ]
i + = argument_count [ c ] if c in argument_count else 0
if not ( c in parent_relations ) : break
return i
2011-07-28 14:32:44 +00:00
#
# Several classes to generate code from Express types and entities
#
class ArrayType :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . type = express_to_cpp . get ( l [ 3 ] , l [ 3 ] )
self . upper = l [ 2 ]
self . lower = l [ 1 ]
def __str__ ( self ) :
if self . type in entity_names :
return " SHARED_PTR< IfcTemplatedEntityList< %s > > " % self . type
elif self . type in selections :
return " SHARED_PTR< IfcTemplatedEntityList<IfcAbstractSelect> > "
else :
return " std::vector< %(type)s > /*[ %(lower)s : %(upper)s ]*/ " % self . __dict__
2011-07-28 14:32:44 +00:00
class ScalarType :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) : self . type = express_to_cpp . get ( l , l )
def __str__ ( self ) : return self . type
2011-07-28 14:32:44 +00:00
class EnumType :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . v = [ ( x , ' %s _ %s ' % ( ' %(fancy_name)s ' , x ) ) for x in l ]
self . maxlen = max ( [ len ( v ) for v in self . v ] )
def __str__ ( self ) :
if generator_mode == ' HEADER ' :
return " enum { %s } " % " , " . join ( [ v2 for v1 , v2 in self . v ] )
elif generator_mode == ' SOURCE_TO ' :
return ' { " %s " } ' % ' " , " ' . join ( [ v1 for v1 , v2 in self . v ] )
elif generator_mode == ' SOURCE_FROM ' :
return " " . join ( [ ' if(s== " %s " %s ) return %s :: %s ; \n ' % ( v1 . upper ( ) , " " * ( self . maxlen - len ( v1 ) ) , " %(name)s " , v2 ) for v1 , v2 in self . v ] )
def __len__ ( self ) : return len ( self . v )
2011-07-28 14:32:44 +00:00
class SelectType :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
for x in l :
if x in simple_types : selectable_simple_types . add ( x )
def __str__ ( self ) : return " IfcSchemaEntity "
2011-07-28 14:32:44 +00:00
class BinaryType :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) : self . l = int ( l )
def __str__ ( self ) : return " char[ %s ] " % self . l
2011-07-28 14:32:44 +00:00
class InverseType :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . name , self . type , self . reference = l
2011-07-28 14:32:44 +00:00
class Typedef :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . name , self . type = l [ 1 : 3 ]
self . fancy_name = self . name [ : - 4 ] if self . name . endswith ( " Enum " ) else self . name
if isinstance ( self . type , EnumType ) :
enumerations . add ( self . name )
self . len = len ( self . type )
elif isinstance ( self . type , SelectType ) : selections . add ( self . name )
simple_types . add ( self . name )
2012-03-17 11:47:31 +00:00
comment = IfcDocumentation . description ( self . name )
self . comment = comment + " \n " if comment else ' '
2012-03-13 11:56:52 +00:00
def __str__ ( self ) :
global generator_mode
if generator_mode == ' HEADER ' and isinstance ( self . type , EnumType ) :
2012-03-17 11:47:31 +00:00
return ( " namespace %(name)s { \n %(comment)s typedef %(type)s %(name)s ; \n std::string ToString( %(name)s v); \n %(name)s FromString(const std::string& s); \n } " % self . __dict__ ) % self . __dict__
2012-03-13 11:56:52 +00:00
elif generator_mode == ' HEADER ' :
2012-03-17 11:47:31 +00:00
return " %s typedef %s %s ; " % ( self . comment , self . type , self . name )
2012-03-13 11:56:52 +00:00
elif generator_mode == ' SOURCE ' and isinstance ( self . type , EnumType ) :
generator_mode = ' SOURCE_TO '
s = " std::string %(name)s ::ToString( %(name)s v) { \n if ( v < 0 || v >= %(len)d ) throw IfcException( \" Unable to find find keyword in schema \" ); \n const char* names[] = %(type)s ; \n return names[v]; \n } \n " % self . __dict__
generator_mode = ' SOURCE_FROM '
s + = ( " %(name)s :: %(name)s %(name)s ::FromString(const std::string& s) { \n %(type)s throw IfcException( \" Unable to find find keyword in schema \" ); \n } " % self . __dict__ ) % self . __dict__
generator_mode = ' SOURCE '
return s
2011-07-28 14:32:44 +00:00
class Argument ( object ) :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . name , self . optional , self . type = l
2011-07-28 14:32:44 +00:00
class ArgumentList :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . l = [ Argument ( a ) for a in l ]
self . argstart = 0
def __len__ ( self ) : return len ( self . l )
def __str__ ( self ) :
s = " "
argv = self . argstart
for a in self . l :
2012-03-17 11:47:31 +00:00
class_name = indent = comment = optional_comment = " "
2012-03-13 11:56:52 +00:00
return_type = str ( a . type )
if generator_mode == ' SOURCE ' :
class_name = " %(class_name)s :: "
if isinstance ( a . type , BinaryType ) or ( isinstance ( a . type , ArrayType ) and isinstance ( a . type . type , BinaryType ) ) :
function_body = " { throw; /* Not implemented argument 7 */ } "
elif isinstance ( a . type , ArrayType ) and str ( a . type . type ) in entity_names :
function_body = " { RETURN_AS_LIST( %s , %d ) } " % ( a . type . type , argv )
elif isinstance ( a . type , ArrayType ) and str ( a . type . type ) in selections :
function_body = " { RETURN_AS_LIST(IfcAbstractSelect, %d ) } " % ( argv )
elif return_type in entity_names :
function_body = " { return reinterpret_pointer_cast<IfcBaseClass, %s >(*entity->getArgument( %d )); } " % ( return_type , argv )
elif return_type in enumerations :
function_body = " { return %s ::FromString(*entity->getArgument( %d )); } " % ( return_type , argv )
else :
function_body = " { return *entity->getArgument( %d ); } " % argv
function_body2 = " { return !entity->getArgument( %d )->isNull(); } " % argv
else :
indent = " "
2012-03-17 11:47:31 +00:00
function_body = function_body2 = " ; "
comment = IfcDocumentation . description ( ( self . class_name , a . name ) )
comment = comment + " \n " if comment else ' '
comment = comment . replace ( " /// " , " %s /// " % indent )
optional_comment = " %s /// Whether the optional attribute %s is defined for this %s \n " % ( indent , a . name , self . class_name )
if a . optional : s + = " \n %s %s bool %s has %s () %s " % ( optional_comment , indent , class_name , a . name , function_body2 )
2012-03-13 11:56:52 +00:00
if ( str ( a . type ) in enumerations ) :
return_type = " %(type)s :: %(type)s " % a . __dict__
elif ( str ( a . type ) in entity_names ) :
return_type = " %(type)s * " % a . __dict__
2012-03-17 11:47:31 +00:00
s + = " \n %s %s %s %s %s () %s " % ( comment , indent , return_type , class_name , a . name , function_body )
2012-03-13 11:56:52 +00:00
argv + = 1
return s
2011-07-28 14:32:44 +00:00
class InverseList :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . l = l
def __str__ ( self ) :
if self . l is None : return " "
s = " "
for i in self . l :
if generator_mode == ' HEADER ' :
s + = " \n SHARED_PTR< IfcTemplatedEntityList< %s > > %s (); // INVERSE %s :: %s " % ( i . type . type , i . name , i . type . type , i . reference )
elif generator_mode == ' SOURCE ' :
s + = " \n %s ::list %s :: %s () { RETURN_INVERSE( %s ) } " % ( i . type . type , " %(class_name)s " , i . name , i . type . type )
return s
2011-07-28 14:32:44 +00:00
class Classdef :
2012-03-13 11:56:52 +00:00
def __init__ ( self , l ) :
self . class_name , self . parent_class , self . arguments , self . inverse = l
2012-03-17 11:47:31 +00:00
self . arguments . class_name = self . class_name
2012-03-13 11:56:52 +00:00
entity_names . add ( self . class_name )
parent_relations [ self . class_name ] = self . parent_class
argument_count [ self . class_name ] = len ( self . arguments )
def __str__ ( self ) :
if generator_mode == ' HEADER ' :
2012-03-17 11:47:31 +00:00
comment = IfcDocumentation . description ( self . class_name )
comment = comment + " \n " if comment else ' '
return " %s class %s : public %s { \n public: %s %s %s \n }; " % ( comment , self . class_name ,
2012-03-13 11:56:52 +00:00
" IfcBaseClass " if self . parent_class is None else self . parent_class ,
self . arguments ,
self . inverse ,
( " \n bool is(Type::Enum v) const; " +
" \n Type::Enum type() const; " +
" \n static Type::Enum Class(); " +
" \n %(class_name)s (IfcAbstractEntityPtr e = IfcAbstractEntityPtr()); " +
" \n typedef %(class_name)s * ptr; " +
" \n typedef SHARED_PTR< IfcTemplatedEntityList< %(class_name)s > > list; " +
" \n typedef IfcTemplatedEntityList< %(class_name)s >::it it; " ) % self . __dict__
)
elif generator_mode == ' SOURCE ' :
self . arguments . argstart = argument_start ( self . class_name )
2012-03-17 11:47:31 +00:00
return ( ( " \n // Function implementations for %(class_name)s " + str ( self . arguments ) + str ( self . inverse ) +
2012-03-13 11:56:52 +00:00
( " \n bool %(class_name)s ::is(Type::Enum v) const { return v == Type:: %(class_name)s ; } " if self . parent_class is None else
" \n bool %(class_name)s ::is(Type::Enum v) const { return v == Type:: %(class_name)s || %(parent_class)s ::is(v); } " ) +
" \n Type::Enum %(class_name)s ::type() const { return Type:: %(class_name)s ; } " +
" \n Type::Enum %(class_name)s ::Class() { return Type:: %(class_name)s ; } " +
" \n %(class_name)s :: %(class_name)s (IfcAbstractEntityPtr e) { if (!is(Type:: %(class_name)s )) throw IfcException( \" Unable to find find keyword in schema \" ); entity = e; } " ) % self . __dict__ ) % self . __dict__
2011-07-28 14:32:44 +00:00
from funcparserlib . parser import a , skip , many , maybe , some
#
# Lambda functions to map combinator output to classes
#
array_type = lambda t : ArrayType ( t )
scalar_type = lambda t : ScalarType ( t )
enum_type = lambda t : EnumType ( t )
select_type = lambda t : SelectType ( t )
binary_type = lambda t : BinaryType ( t )
inverse_type = lambda t : InverseType ( t )
format_type = lambda t : Typedef ( t )
argument_list = lambda t : ArgumentList ( t )
inverse_list = lambda t : InverseList ( t )
format_options = lambda t : [ t [ 0 ] ] + t [ 1 ]
#
# The actual grammar definition
#
s = some ( lambda t : not t in [ ' UNIQUE ' , ' WHERE ' , ' END_ENTITY ' , ' END_TYPE ' , ' INVERSE ' , ' DERIVE ' ] )
x = lambda s : skip ( a ( s ) )
list_or_array = a ( ' ARRAY ' ) | a ( ' LIST ' ) | a ( ' SET ' )
binary = x ( ' BINARY ' ) + x ( ' ( ' ) + s + x ( ' ) ' ) >> binary_type
array = list_or_array + x ( ' [ ' ) + s + x ( ' : ' ) + s + x ( ' ] ' ) + x ( ' OF ' ) + skip ( maybe ( a ( ' UNIQUE ' ) ) ) + ( binary | s ) >> array_type
options = x ( ' ( ' ) + s + many ( x ( ' , ' ) + s ) + x ( ' ) ' ) >> format_options
enum = x ( ' ENUMERATION ' ) + x ( ' OF ' ) + options >> enum_type
select = x ( ' SELECT ' ) + options >> select_type
single = s + skip ( maybe ( x ( ' ( ' ) + s + x ( ' ) ' ) ) + maybe ( a ( ' FIXED ' ) ) ) >> scalar_type
type_type = array | enum | select | single
type_start = a ( ' TYPE ' ) + s + x ( ' = ' ) + type_type + x ( ' ; ' )
type_end = a ( ' END_TYPE ' ) + x ( ' ; ' )
to_end = many ( some ( lambda t : t != ' ; ' ) )
clause = s + x ( ' : ' ) + to_end + x ( ' ; ' )
where = a ( ' WHERE ' ) + many ( clause )
type = type_start + maybe ( where ) + type_end >> format_type
subtype = x ( ' SUBTYPE ' ) + x ( ' OF ' ) + x ( ' ( ' ) + s + x ( ' ) ' )
supertype = maybe ( x ( ' ABSTRACT ' ) ) + x ( ' SUPERTYPE ' ) + x ( ' OF ' ) + x ( ' ( ' ) + x ( ' ONEOF ' ) + options + x ( ' ) ' )
entity_start = x ( ' ENTITY ' ) + s + skip ( maybe ( supertype ) ) + maybe ( subtype ) + x ( ' ; ' )
entity_end = x ( ' END_ENTITY ' ) + x ( ' ; ' )
key_value = s + x ( ' : ' ) + maybe ( a ( ' OPTIONAL ' ) ) + ( array | binary | single ) + x ( ' ; ' )
arguments = many ( key_value ) >> argument_list
unique_value = s + x ( ' : ' ) + s + many ( a ( ' , ' ) + s ) + a ( ' ; ' )
unique = skip ( a ( ' UNIQUE ' ) + many ( unique_value ) )
inverse_def = s + x ( ' : ' ) + ( array | single ) + x ( ' FOR ' ) + s + x ( ' ; ' ) >> inverse_type
inverse = maybe ( x ( ' INVERSE ' ) + many ( inverse_def ) ) >> inverse_list
derive = skip ( a ( ' DERIVE ' ) + many ( clause ) )
entity = entity_start + arguments + skip ( maybe ( unique ) ) + skip ( maybe ( derive ) ) + inverse + skip ( maybe ( where ) ) + entity_end >> Classdef
schema = skip ( a ( ' SCHEMA ' ) ) + s + x ( ' ; ' )
express = schema + many ( type ) + many ( entity )
schema_version , types , entities = express . parse ( list ( Tokenizer ( filename ) ) )
schema_version = schema_version . capitalize ( )
#
# Writing of the three generated files starts here
#
h_file = open ( " %s .h " % schema_version , ' w ' )
enumh_file = open ( " %s enum.h " % schema_version , ' w ' )
cpp_file = open ( " %s .cpp " % schema_version , ' w ' )
header + = """
/********************************************************************************
* *
* This file has been generated from %s . Do not make modifications *
* but instead modify the python script that has been used to generate this. *
* *
********************************************************************************/
""" % filename
generator_mode = ' HEADER '
print >> h_file , header
print >> enumh_file , header
print >> cpp_file , header
print >> h_file , """ #ifndef %(schema_upper)s _H
#define %(schema_upper)s _H
#include <string>
#include <vector>
2011-09-03 13:58:59 +00:00
#include <map>
2011-07-28 14:32:44 +00:00
#include " ../ifcparse/IfcUtil.h "
#include " ../ifcparse/ %(schema)s enum.h "
using namespace IfcUtil;
#define RETURN_INVERSE(T) \\
2012-03-13 11:56:52 +00:00
IfcEntities e = entity->getInverse(T::Class()); \\
SHARED_PTR< IfcTemplatedEntityList<T> > l ( new IfcTemplatedEntityList<T>() ); \\
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) { \\
l->push(reinterpret_pointer_cast<IfcBaseClass,T>(*it)); \\
} \\
return l;
2011-07-28 14:32:44 +00:00
#define RETURN_AS_SINGLE(T,a) \\
2012-03-13 11:56:52 +00:00
return reinterpret_pointer_cast<IfcBaseClass,T>(*entity->getArgument(a));
2011-07-28 14:32:44 +00:00
#define RETURN_AS_LIST(T,a) \\
2012-03-13 11:56:52 +00:00
IfcEntities e = *entity->getArgument(a); \\
SHARED_PTR< IfcTemplatedEntityList<T> > l ( new IfcTemplatedEntityList<T>() ); \\
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) { \\
l->push(reinterpret_pointer_cast<IfcBaseClass,T>(*it)); \\
} \\
return l;
2011-07-28 14:32:44 +00:00
namespace %(schema)s {
""" % { ' schema_upper ' : schema_version . upper ( ) , ' schema ' : schema_version }
simple_enumerations = sorted ( selectable_simple_types )
entity_enumerations = sorted ( entity_names )
all_enumerations = simple_enumerations + entity_enumerations
print >> enumh_file , """ #ifndef IFC2X3ENUM_H
#define IFC2X3ENUM_H
namespace Ifc2x3 {
namespace Type {
typedef enum {
%(enum)s
2012-03-13 11:56:52 +00:00
} Enum;
Enum Parent(Enum v);
2011-07-28 14:32:44 +00:00
Enum FromString(const std::string& s);
std::string ToString(Enum v);
}
}
#endif
""" % { ' schema_upper ' : schema_version . upper ( ) , ' schema ' : schema_version , ' enum ' : " , " . join ( all_enumerations + [ " ALL " ] ) }
defined_types = set ( express_to_cpp . values ( ) )
deferred_types = [ ]
for t in [ T for T in types if not ( isinstance ( T . type , EnumType ) or isinstance ( T . type , SelectType ) ) ] :
2012-03-13 11:56:52 +00:00
if isinstance ( t . type , ScalarType ) and str ( t . type ) not in defined_types :
deferred_types . append ( t )
else :
print >> h_file , t
2011-07-28 14:32:44 +00:00
for t in [ T for T in types if isinstance ( T . type , SelectType ) ] :
2012-03-13 11:56:52 +00:00
print >> h_file , t
2011-07-28 14:32:44 +00:00
for t in deferred_types :
2012-03-13 11:56:52 +00:00
print >> h_file , t
2011-07-28 14:32:44 +00:00
for t in [ T for T in types if isinstance ( T . type , EnumType ) ] :
2012-03-13 11:56:52 +00:00
print >> h_file , t
2011-07-28 14:32:44 +00:00
print >> h_file , " // Forward definitions "
print >> h_file , " class %s ; \n " % " ; class " . join ( [ e . class_name for e in entities ] )
defined_classes = set ( )
while True :
2012-03-13 11:56:52 +00:00
classes = [ c for c in entities if c . class_name not in defined_classes ]
if not len ( classes ) : break
for c in classes :
if c . parent_class is None or c . parent_class in defined_classes :
defined_classes . add ( c . class_name )
print >> h_file , c
2011-09-03 13:58:59 +00:00
print >> h_file , " void InitStringMap(); "
print >> h_file , " IfcSchemaEntity SchemaEntity(IfcAbstractEntityPtr e = 0); "
2011-07-28 14:32:44 +00:00
print >> h_file , " } \n \n #endif "
generator_mode = ' SOURCE '
print >> cpp_file , """ #include " %(schema)s .h "
2011-10-13 11:25:59 +00:00
#include " IfcException.h "
2011-07-28 14:32:44 +00:00
using namespace %(schema)s ;
2011-10-13 11:25:59 +00:00
using namespace IfcParse;
2011-07-28 14:32:44 +00:00
2011-09-03 13:58:59 +00:00
IfcSchemaEntity %(schema)s ::SchemaEntity(IfcAbstractEntityPtr e) {
switch(e->type()) { """ % { ' schema ' : schema_version }
2011-07-28 14:32:44 +00:00
for e in simple_enumerations :
2012-03-13 11:56:52 +00:00
print >> cpp_file , " case Type:: %s : return new IfcEntitySelect(e); break; " % e
2011-07-28 14:32:44 +00:00
for e in entity_enumerations :
2012-03-13 11:56:52 +00:00
print >> cpp_file , " case Type:: %s : return new %s (e); break; " % ( e , e )
2011-10-13 11:25:59 +00:00
print >> cpp_file , " default: throw IfcException( \" Unable to find find keyword in schema \" ); break; "
2011-09-03 13:58:59 +00:00
print >> cpp_file , " } \n } "
2011-07-28 14:32:44 +00:00
print >> cpp_file
print >> cpp_file , " std::string Type::ToString(Enum v) { "
2011-10-13 11:25:59 +00:00
print >> cpp_file , " if (v < 0 || v >= %d ) throw IfcException( \" Unable to find find keyword in schema \" ); " % len ( all_enumerations )
2011-07-28 14:32:44 +00:00
print >> cpp_file , ' const char* names[] = { " %s " }; ' % ' " , " ' . join ( all_enumerations )
print >> cpp_file , ' return names[v]; '
print >> cpp_file , " } "
print >> cpp_file
2011-09-03 13:58:59 +00:00
#print >>cpp_file, "Type::Enum Type::FromStringOld(const std::string& s){"
#elseif = "if"
#maxlen = max([len(e) for e in all_enumerations])
#for e in all_enumerations:
2012-03-13 11:56:52 +00:00
# print >>cpp_file, ' %s(s=="%s"%s) { return %s; }'%(elseif,e.upper()," "*(maxlen-len(e)),e)
2011-09-03 13:58:59 +00:00
#print >>cpp_file, " throw;"
#print >>cpp_file, "}"
print >> cpp_file , " std::map<std::string,Type::Enum> string_map; "
print >> cpp_file , " void Ifc2x3::InitStringMap() { "
2011-07-28 14:32:44 +00:00
maxlen = max ( [ len ( e ) for e in all_enumerations ] )
for e in all_enumerations :
2012-03-13 11:56:52 +00:00
print >> cpp_file , ' string_map[ " %s " %s ] = Type:: %s ; ' % ( e . upper ( ) , " " * ( maxlen - len ( e ) ) , e )
2011-09-03 13:58:59 +00:00
print >> cpp_file , """ }
Type::Enum Type::FromString(const std::string& s) {
std::map<std::string,Type::Enum>::const_iterator it = string_map.find(s);
2012-03-13 11:56:52 +00:00
if ( it == string_map.end() ) throw IfcException( " Unable to find find keyword in schema " );
else return it->second;
2011-09-03 13:58:59 +00:00
} """
2011-07-28 14:32:44 +00:00
2011-08-24 12:21:07 +00:00
print >> cpp_file , " Type::Enum Type::Parent(Enum v) { "
2011-09-03 13:58:59 +00:00
print >> cpp_file , " if (v < 0 || v >= %d ) return (Enum)-1; " % len ( all_enumerations )
2011-08-24 12:21:07 +00:00
for e in entity_enumerations :
2012-03-13 11:56:52 +00:00
if e not in parent_relations or parent_relations [ e ] is None : continue
print >> cpp_file , ' if(v== %s %s ) { return %s ; } ' % ( e , " " * ( maxlen - len ( e ) ) , parent_relations [ e ] )
2011-09-03 13:58:59 +00:00
print >> cpp_file , " return (Enum)-1; "
2011-08-24 12:21:07 +00:00
print >> cpp_file , " } "
2011-07-28 14:32:44 +00:00
for t in [ T for T in types if isinstance ( T . type , EnumType ) ] :
2012-03-13 11:56:52 +00:00
print >> cpp_file , t
2011-07-28 14:32:44 +00:00
for e in entities : print >> cpp_file , e ,