First draft for a SCL python generator

This commit is contained in:
tpaviot
2012-02-22 17:57:21 +01:00
parent becb8405ba
commit 10999e7a48
32 changed files with 11231 additions and 0 deletions
+4
View File
@@ -58,6 +58,9 @@ OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON)
# build static libs by default
OPTION(BUILD_STATIC_LIBS "Build static libraries" OFF)
OPTION(PYTHON_GENERATOR "Compile fedex_plus_python" ON)
OPTION(CPP_GENERATOR "Compile fedex_plus" ON)
# Set version
SET(SCL_VERSION_MAJOR "3")
SET(SCL_VERSION_MINOR "2")
@@ -258,6 +261,7 @@ include_directories(
ADD_SUBDIRECTORY(src/express)
ADD_SUBDIRECTORY(src/exppp)
ADD_SUBDIRECTORY(src/fedex_plus)
ADD_SUBDIRECTORY(src/fedex_python)
ADD_SUBDIRECTORY(src/clstepcore)
ADD_SUBDIRECTORY(src/cleditor)
ADD_SUBDIRECTORY(src/cldai)
+2
View File
@@ -235,6 +235,8 @@ GLOBAL SCL_EXPRESS_EXPORT Error ERROR_corrupted_type INITIALLY( ERROR_none );
#define TYPEis_identifier(t) ((t)->u.type->body->type == identifier_)
#define TYPEis_logical(t) ((t)->u.type->body->type == logical_)
#define TYPEis_boolean(t) ((t)->u.type->body->type == boolean_)
#define TYPEis_real(t) ((t)->u.type->body->type == real_)
#define TYPEis_integer(t) ((t)->u.type->body->type == integer_)
#define TYPEis_string(t) ((t)->u.type->body->type == string_)
#define TYPEis_expression(t) ((t)->u.type->body->type == op_)
#define TYPEis_oneof(t) ((t)->u.type->body->type == oneof_)
+44
View File
@@ -0,0 +1,44 @@
if(PYTHON_GENERATOR)
include_directories(
${SCL_SOURCE_DIR}/include
${SCL_SOURCE_DIR}/include/exppp
${SCL_SOURCE_DIR}/include/express
${SCL_SOURCE_DIR}/src/fedex_plus
)
add_definitions( -DHAVE_CONFIG_H )
IF(MSVC)
set(fedex_plus_MSVC_SOURCES
${SCL_SOURCE_DIR}/src/fedex_plus/xgetopt.cc
)
add_definitions( -DSCL_EXPRESS_DLL_IMPORTS )
add_definitions( -DSCL_EXPPP_DLL_IMPORTS )
ENDIF(MSVC)
set(fedex_python_SOURCES
src/classes_misc_python.c
${SCL_SOURCE_DIR}/src/express/fedex.c
src/fedex_main_python.c
src/classes_wrapper_python.cc
src/classes_python.c
src/selects_python.c
src/multpass_python.c
${SCL_SOURCE_DIR}/src/fedex_plus/collect.cc
${SCL_SOURCE_DIR}/src/fedex_plus/complexlist.cc
${SCL_SOURCE_DIR}/src/fedex_plus/entlist.cc
${SCL_SOURCE_DIR}/src/fedex_plus/multlist.cc
${SCL_SOURCE_DIR}/src/fedex_plus/orlist.cc
${SCL_SOURCE_DIR}/src/fedex_plus/entnode.cc
${SCL_SOURCE_DIR}/src/fedex_plus/expressbuild.cc
${SCL_SOURCE_DIR}/src/fedex_plus/non-ors.cc
${SCL_SOURCE_DIR}/src/fedex_plus/match-ors.cc
${SCL_SOURCE_DIR}/src/fedex_plus/trynext.cc
${SCL_SOURCE_DIR}/src/fedex_plus/write.cc
${SCL_SOURCE_DIR}/src/fedex_plus/print.cc
)
SCL_ADDEXEC(fedex_python "${fedex_python_SOURCES} ${fedex_plus_MSVC_SOURCES}" "libexppp express")
add_dependencies( fedex_python version_string )
endif(PYTHON_GENERATOR)
+1
View File
@@ -0,0 +1 @@
Howto
@@ -0,0 +1,13 @@
__doc__= ''' This script runs fedex_python over each EXPRESS schema in the test/unitary_schemas folder'''
unitary_schemas_path = '../../../../test/unitary_schemas'
fedex_python_path = '../../../../cmake-build/bin/fedex_python'
import subprocess
import glob
import os
unitary_schemas = glob.glob(os.path.join(unitary_schemas_path,'*.exp'))
for unitary_schema in unitary_schemas:
subprocess.call([fedex_python_path,unitary_schema])
@@ -0,0 +1,105 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
common_datum_list = 'LIST TYPE Not implemented'
label = STRING
####################
# ENTITY shape_aspect #
####################
class shape_aspect(BaseEntityClass):
'''Entity shape_aspect definition.
:param name
:type name:STRING
:param of_shape
:type of_shape:product_definition_shape
'''
def __init__( self , name,of_shape, ):
self.name = name
self.of_shape = of_shape
@apply
def name():
def fget( self ):
return self._name
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument name is mantatory and can not be set to None')
check_type(value,STRING)
self._name = value
return property(**locals())
@apply
def of_shape():
def fget( self ):
return self._of_shape
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument of_shape is mantatory and can not be set to None')
check_type(value,product_definition_shape)
self._of_shape = value
return property(**locals())
####################
# ENTITY general_datum_reference #
####################
class general_datum_reference(shape_aspect):
'''Entity general_datum_reference definition.
:param base
:type base:datum_or_common_datum
'''
def __init__( self , shape_aspect__name , shape_aspect__of_shape , base, ):
shape_aspect.__init__(self , shape_aspect__name , shape_aspect__of_shape , )
self.base = base
@apply
def base():
def fget( self ):
return self._base
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument base is mantatory and can not be set to None')
check_type(value,datum_or_common_datum)
self._base = value
return property(**locals())
####################
# ENTITY product_definition_shape #
####################
class product_definition_shape(BaseEntityClass):
'''Entity product_definition_shape definition.
'''
# This class does not define any attribute.
pass
####################
# ENTITY datum_reference_element #
####################
class datum_reference_element(general_datum_reference):
'''Entity datum_reference_element definition.
'''
def __init__( self , general_datum_reference__base , ):
general_datum_reference.__init__(self , general_datum_reference__base , )
####################
# ENTITY datum #
####################
class datum(shape_aspect):
'''Entity datum definition.
'''
def __init__( self , shape_aspect__name , shape_aspect__of_shape , ):
shape_aspect.__init__(self , shape_aspect__name , shape_aspect__of_shape , )
# SELECT TYPE datum_or_common_datum
datum_or_common_datum=SELECT([common_datum_list,datum])
@@ -0,0 +1,33 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
####################
# ENTITY point #
####################
class point(BaseEntityClass):
'''Entity point definition.
:param coords
:type coords:(null)
'''
def __init__( self , coords, ):
self.coords = coords
@apply
def coords():
def fget( self ):
return self._coords
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument coords is mantatory and can not be set to None')
check_type(value,ARRAY(1,3,REAL))
self._coords = value
return property(**locals())
@@ -0,0 +1,65 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
####################
# ENTITY point #
####################
class point(BaseEntityClass):
'''Entity point definition.
:param arr_real
:type arr_real:(null)
:param arr_string
:type arr_string:(null)
:param arr_integer
:type arr_integer:(null)
'''
def __init__( self , arr_real,arr_string,arr_integer, ):
self.arr_real = arr_real
self.arr_string = arr_string
self.arr_integer = arr_integer
@apply
def arr_real():
def fget( self ):
return self._arr_real
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument arr_real is mantatory and can not be set to None')
check_type(value,ARRAY(1,3,REAL))
self._arr_real = value
return property(**locals())
@apply
def arr_string():
def fget( self ):
return self._arr_string
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument arr_string is mantatory and can not be set to None')
check_type(value,ARRAY(1,3,STRING))
self._arr_string = value
return property(**locals())
@apply
def arr_integer():
def fget( self ):
return self._arr_integer
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument arr_integer is mantatory and can not be set to None')
check_type(value,ARRAY(1,None,INTEGER))
self._arr_integer = value
return property(**locals())
@@ -0,0 +1,185 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
####################
# ENTITY vector #
####################
class vector(BaseEntityClass):
'''Entity vector definition.
:param x
:type x:REAL
:param y
:type y:REAL
'''
def __init__( self , x,y, ):
self.x = x
self.y = y
@apply
def x():
def fget( self ):
return self._x
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument x is mantatory and can not be set to None')
check_type(value,REAL)
self._x = value
return property(**locals())
@apply
def y():
def fget( self ):
return self._y
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument y is mantatory and can not be set to None')
check_type(value,REAL)
self._y = value
return property(**locals())
####################
# ENTITY circle #
####################
class circle(BaseEntityClass):
'''Entity circle definition.
:param centre
:type centre:point
:param radius
:type radius:REAL
:param axis
:type axis:vector
:param area
:type area:REAL
:param perimeter
:type perimeter:REAL
'''
def __init__( self , centre,radius,axis, ):
self.centre = centre
self.radius = radius
self.axis = axis
@apply
def centre():
def fget( self ):
return self._centre
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument centre is mantatory and can not be set to None')
check_type(value,point)
self._centre = value
return property(**locals())
@apply
def radius():
def fget( self ):
return self._radius
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument radius is mantatory and can not be set to None')
check_type(value,REAL)
self._radius = value
return property(**locals())
@apply
def axis():
def fget( self ):
return self._axis
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument axis is mantatory and can not be set to None')
check_type(value,vector)
self._axis = value
return property(**locals())
@apply
def area():
def fget( self ):
return EvalDerivedAttribute(self,'''PI * (radius ** 2)''')
def fset( self, value ):
# DERIVED argument
raise AssertionError('Argument area is DERIVED. It is computed and can not be set to any value')
return property(**locals())
@apply
def perimeter():
def fget( self ):
return EvalDerivedAttribute(self,'''2 * PI * radius''')
def fset( self, value ):
# DERIVED argument
raise AssertionError('Argument perimeter is DERIVED. It is computed and can not be set to any value')
return property(**locals())
####################
# ENTITY point #
####################
class point(BaseEntityClass):
'''Entity point definition.
:param x
:type x:REAL
:param y
:type y:REAL
:param z
:type z:REAL
'''
def __init__( self , x,y,z, ):
self.x = x
self.y = y
self.z = z
@apply
def x():
def fget( self ):
return self._x
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument x is mantatory and can not be set to None')
check_type(value,REAL)
self._x = value
return property(**locals())
@apply
def y():
def fget( self ):
return self._y
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument y is mantatory and can not be set to None')
check_type(value,REAL)
self._y = value
return property(**locals())
@apply
def z():
def fget( self ):
return self._z
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument z is mantatory and can not be set to None')
check_type(value,REAL)
self._z = value
return property(**locals())
@@ -0,0 +1,14 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
# ENUMERATION TYPE simple_datum_reference_modifier
simple_datum_reference_modifier = ENUMERATION([
'line',
'translation',
])
@@ -0,0 +1,19 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
# ENUMERATION TYPE hair_color
hair_color = ENUMERATION([
'bald',
'red',
])
# ENUMERATION TYPE favorite_color
favorite_color = ENUMERATION([
'clear',
'red',
])
@@ -0,0 +1,456 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
text = STRING
identifier = STRING
label = STRING
####################
# ENTITY address #
####################
class address(BaseEntityClass):
'''Entity address definition.
:param internal_location
:type internal_location:STRING
:param street_number
:type street_number:STRING
:param street
:type street:STRING
:param postal_box
:type postal_box:STRING
:param town
:type town:STRING
:param region
:type region:STRING
:param postal_code
:type postal_code:STRING
:param country
:type country:STRING
:param facsimile_number
:type facsimile_number:STRING
:param telephone_number
:type telephone_number:STRING
:param electronic_mail_address
:type electronic_mail_address:STRING
:param telex_number
:type telex_number:STRING
'''
def __init__( self , internal_location,street_number,street,postal_box,town,region,postal_code,country,facsimile_number,telephone_number,electronic_mail_address,telex_number, ):
self.internal_location = internal_location
self.street_number = street_number
self.street = street
self.postal_box = postal_box
self.town = town
self.region = region
self.postal_code = postal_code
self.country = country
self.facsimile_number = facsimile_number
self.telephone_number = telephone_number
self.electronic_mail_address = electronic_mail_address
self.telex_number = telex_number
@apply
def internal_location():
def fget( self ):
return self._internal_location
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._internal_location = value
return property(**locals())
@apply
def street_number():
def fget( self ):
return self._street_number
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._street_number = value
return property(**locals())
@apply
def street():
def fget( self ):
return self._street
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._street = value
return property(**locals())
@apply
def postal_box():
def fget( self ):
return self._postal_box
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._postal_box = value
return property(**locals())
@apply
def town():
def fget( self ):
return self._town
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._town = value
return property(**locals())
@apply
def region():
def fget( self ):
return self._region
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._region = value
return property(**locals())
@apply
def postal_code():
def fget( self ):
return self._postal_code
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._postal_code = value
return property(**locals())
@apply
def country():
def fget( self ):
return self._country
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._country = value
return property(**locals())
@apply
def facsimile_number():
def fget( self ):
return self._facsimile_number
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._facsimile_number = value
return property(**locals())
@apply
def telephone_number():
def fget( self ):
return self._telephone_number
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._telephone_number = value
return property(**locals())
@apply
def electronic_mail_address():
def fget( self ):
return self._electronic_mail_address
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._electronic_mail_address = value
return property(**locals())
@apply
def telex_number():
def fget( self ):
return self._telex_number
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._telex_number = value
return property(**locals())
####################
# ENTITY personal_address #
####################
class personal_address(address):
'''Entity personal_address definition.
:param people
:type people:(null)
:param description
:type description:STRING
'''
def __init__( self , address__internal_location , address__street_number , address__street , address__postal_box , address__town , address__region , address__postal_code , address__country , address__facsimile_number , address__telephone_number , address__electronic_mail_address , address__telex_number , people,description, ):
address.__init__(self , address__internal_location , address__street_number , address__street , address__postal_box , address__town , address__region , address__postal_code , address__country , address__facsimile_number , address__telephone_number , address__electronic_mail_address , address__telex_number , )
self.people = people
self.description = description
@apply
def people():
def fget( self ):
return self._people
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument people is mantatory and can not be set to None')
check_type(value,SET(1,None,person))
self._people = value
return property(**locals())
@apply
def description():
def fget( self ):
return self._description
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._description = value
return property(**locals())
####################
# ENTITY organizational_address #
####################
class organizational_address(address):
'''Entity organizational_address definition.
:param organizations
:type organizations:(null)
:param description
:type description:STRING
'''
def __init__( self , address__internal_location , address__street_number , address__street , address__postal_box , address__town , address__region , address__postal_code , address__country , address__facsimile_number , address__telephone_number , address__electronic_mail_address , address__telex_number , organizations,description, ):
address.__init__(self , address__internal_location , address__street_number , address__street , address__postal_box , address__town , address__region , address__postal_code , address__country , address__facsimile_number , address__telephone_number , address__electronic_mail_address , address__telex_number , )
self.organizations = organizations
self.description = description
@apply
def organizations():
def fget( self ):
return self._organizations
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument organizations is mantatory and can not be set to None')
check_type(value,SET(1,None,organization))
self._organizations = value
return property(**locals())
@apply
def description():
def fget( self ):
return self._description
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._description = value
return property(**locals())
####################
# ENTITY person #
####################
class person(BaseEntityClass):
'''Entity person definition.
:param id
:type id:STRING
:param last_name
:type last_name:STRING
:param first_name
:type first_name:STRING
:param middle_names
:type middle_names:(null)
:param prefix_titles
:type prefix_titles:(null)
:param suffix_titles
:type suffix_titles:(null)
'''
def __init__( self , id,last_name,first_name,middle_names,prefix_titles,suffix_titles, ):
self.id = id
self.last_name = last_name
self.first_name = first_name
self.middle_names = middle_names
self.prefix_titles = prefix_titles
self.suffix_titles = suffix_titles
@apply
def id():
def fget( self ):
return self._id
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument id is mantatory and can not be set to None')
check_type(value,STRING)
self._id = value
return property(**locals())
@apply
def last_name():
def fget( self ):
return self._last_name
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._last_name = value
return property(**locals())
@apply
def first_name():
def fget( self ):
return self._first_name
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._first_name = value
return property(**locals())
@apply
def middle_names():
def fget( self ):
return self._middle_names
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,LIST(1,None,STRING))
self._middle_names = value
return property(**locals())
@apply
def prefix_titles():
def fget( self ):
return self._prefix_titles
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,LIST(1,None,STRING))
self._prefix_titles = value
return property(**locals())
@apply
def suffix_titles():
def fget( self ):
return self._suffix_titles
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,LIST(1,None,STRING))
self._suffix_titles = value
return property(**locals())
####################
# ENTITY organization #
####################
class organization(BaseEntityClass):
'''Entity organization definition.
:param id
:type id:STRING
:param name
:type name:STRING
:param description
:type description:STRING
'''
def __init__( self , id,name,description, ):
self.id = id
self.name = name
self.description = description
@apply
def id():
def fget( self ):
return self._id
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._id = value
return property(**locals())
@apply
def name():
def fget( self ):
return self._name
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument name is mantatory and can not be set to None')
check_type(value,STRING)
self._name = value
return property(**locals())
@apply
def description():
def fget( self ):
return self._description
def fset( self, value ):
if value != None: # OPTIONAL attribute
check_type(value,STRING)
self._description = value
return property(**locals())
####################
# ENTITY person_and_organization_address #
####################
class person_and_organization_address(organizational_address,personal_address):
'''Entity person_and_organization_address definition.
:param organizational_address_organizations
:type organizational_address_organizations:(null)
:param personal_address_people
:type personal_address_people:(null)
'''
def __init__( self , organizational_address__organizations , organizational_address__description , personal_address__people , personal_address__description , organizational_address_organizations,personal_address_people, ):
organizational_address.__init__(self , organizational_address__organizations , organizational_address__description , )
personal_address.__init__(self , personal_address__people , personal_address__description , )
self.organizational_address_organizations = organizational_address_organizations
self.personal_address_people = personal_address_people
@apply
def organizational_address_organizations():
def fget( self ):
return self._organizational_address_organizations
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument organizational_address_organizations is mantatory and can not be set to None')
check_type(value,SET(1,1,organization))
self._organizational_address_organizations = value
return property(**locals())
@apply
def personal_address_people():
def fget( self ):
return self._personal_address_people
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument personal_address_people is mantatory and can not be set to None')
check_type(value,SET(1,1,person))
self._personal_address_people = value
return property(**locals())
# SELECT TYPE classification_item
classification_item=SELECT([person_and_organization_address,address])
@@ -0,0 +1,35 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
measure = REAL
type2 = INTEGER
####################
# ENTITY line #
####################
class line(BaseEntityClass):
'''Entity line definition.
:param line_length
:type line_length:REAL
'''
def __init__( self , line_length, ):
self.line_length = line_length
@apply
def line_length():
def fget( self ):
return self._line_length
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument line_length is mantatory and can not be set to None')
check_type(value,REAL)
self._line_length = value
return property(**locals())
@@ -0,0 +1,215 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
####################
# ENTITY weld #
####################
class weld(BaseEntityClass):
'''Entity weld definition.
:param composition
:type composition:STRING
'''
def __init__( self , composition, ):
self.composition = composition
@apply
def composition():
def fget( self ):
return self._composition
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument composition is mantatory and can not be set to None')
check_type(value,STRING)
self._composition = value
return property(**locals())
####################
# ENTITY glue #
####################
class glue(BaseEntityClass):
'''Entity glue definition.
:param composition
:type composition:STRING
:param solvent
:type solvent:STRING
'''
def __init__( self , composition,solvent, ):
self.composition = composition
self.solvent = solvent
@apply
def composition():
def fget( self ):
return self._composition
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument composition is mantatory and can not be set to None')
check_type(value,STRING)
self._composition = value
return property(**locals())
@apply
def solvent():
def fget( self ):
return self._solvent
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument solvent is mantatory and can not be set to None')
check_type(value,STRING)
self._solvent = value
return property(**locals())
####################
# ENTITY wall_mounting #
####################
class wall_mounting(BaseEntityClass):
'''Entity wall_mounting definition.
:param mounting
:type mounting:STRING
:param on
:type on:STRING
:param using
:type using:attachment_method
'''
def __init__( self , mounting,on,using, ):
self.mounting = mounting
self.on = on
self.using = using
@apply
def mounting():
def fget( self ):
return self._mounting
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument mounting is mantatory and can not be set to None')
check_type(value,STRING)
self._mounting = value
return property(**locals())
@apply
def on():
def fget( self ):
return self._on
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument on is mantatory and can not be set to None')
check_type(value,STRING)
self._on = value
return property(**locals())
@apply
def using():
def fget( self ):
return self._using
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument using is mantatory and can not be set to None')
check_type(value,attachment_method)
self._using = value
return property(**locals())
####################
# ENTITY screw #
####################
class screw(BaseEntityClass):
'''Entity screw definition.
:param body_length
:type body_length:REAL
:param pitch
:type pitch:REAL
'''
def __init__( self , body_length,pitch, ):
self.body_length = body_length
self.pitch = pitch
@apply
def body_length():
def fget( self ):
return self._body_length
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument body_length is mantatory and can not be set to None')
check_type(value,REAL)
self._body_length = value
return property(**locals())
@apply
def pitch():
def fget( self ):
return self._pitch
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument pitch is mantatory and can not be set to None')
check_type(value,REAL)
self._pitch = value
return property(**locals())
####################
# ENTITY nail #
####################
class nail(BaseEntityClass):
'''Entity nail definition.
:param body_length
:type body_length:REAL
:param head_area
:type head_area:REAL
'''
def __init__( self , body_length,head_area, ):
self.body_length = body_length
self.head_area = head_area
@apply
def body_length():
def fget( self ):
return self._body_length
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument body_length is mantatory and can not be set to None')
check_type(value,REAL)
self._body_length = value
return property(**locals())
@apply
def head_area():
def fget( self ):
return self._head_area
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument head_area is mantatory and can not be set to None')
check_type(value,REAL)
self._head_area = value
return property(**locals())
# SELECT TYPE permanent_attachment
permanent_attachment=SELECT([glue,weld])
# SELECT TYPE temporary_attachment
temporary_attachment=SELECT([nail,screw])
# SELECT TYPE attachment_method
attachment_method=SELECT([permanent_attachment,temporary_attachment])
@@ -0,0 +1,93 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
length_measure = REAL
label = STRING
point = REAL
####################
# ENTITY shape #
####################
class shape(BaseEntityClass):
'''Entity shape definition.
:param item_name
:type item_name:STRING
:param number_of_sides
:type number_of_sides:INTEGER
'''
def __init__( self , item_name,number_of_sides, ):
self.item_name = item_name
self.number_of_sides = number_of_sides
@apply
def item_name():
def fget( self ):
return self._item_name
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument item_name is mantatory and can not be set to None')
check_type(value,STRING)
self._item_name = value
return property(**locals())
@apply
def number_of_sides():
def fget( self ):
return self._number_of_sides
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument number_of_sides is mantatory and can not be set to None')
check_type(value,INTEGER)
self._number_of_sides = value
return property(**locals())
####################
# ENTITY rectangle #
####################
class rectangle(shape):
'''Entity rectangle definition.
:param height
:type height:REAL
:param width
:type width:REAL
'''
def __init__( self , shape__item_name , shape__number_of_sides , height,width, ):
shape.__init__(self , shape__item_name , shape__number_of_sides , )
self.height = height
self.width = width
@apply
def height():
def fget( self ):
return self._height
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument height is mantatory and can not be set to None')
check_type(value,REAL)
self._height = value
return property(**locals())
@apply
def width():
def fget( self ):
return self._width
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument width is mantatory and can not be set to None')
check_type(value,REAL)
self._width = value
return property(**locals())
@@ -0,0 +1,102 @@
# This file was generated by fedex_python. You probably don't want to edit
# it since your modifications will be lost if fedex_plus is used to
# regenerate it.
from SCL.SCLBase import *
from SCL.SimpleDataTypes import *
from SCL.ConstructedDataTypes import *
from SCL.AggregationDataType import *
from SCL.TypeChecker import check_type
from SCL.Expr import *
length_measure = REAL
label = STRING
point = REAL
####################
# ENTITY shape #
####################
class shape(BaseEntityClass):
'''Entity shape definition.
:param item_name
:type item_name:STRING
:param number_of_sides
:type number_of_sides:INTEGER
'''
def __init__( self , item_name,number_of_sides, ):
self.item_name = item_name
self.number_of_sides = number_of_sides
@apply
def item_name():
def fget( self ):
return self._item_name
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument item_name is mantatory and can not be set to None')
check_type(value,STRING)
self._item_name = value
return property(**locals())
@apply
def number_of_sides():
def fget( self ):
return self._number_of_sides
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument number_of_sides is mantatory and can not be set to None')
check_type(value,INTEGER)
self._number_of_sides = value
return property(**locals())
####################
# ENTITY subshape #
####################
class subshape(shape):
'''Entity subshape definition.
'''
def __init__( self , shape__item_name , shape__number_of_sides , ):
shape.__init__(self , shape__item_name , shape__number_of_sides , )
####################
# ENTITY rectangle #
####################
class rectangle(subshape):
'''Entity rectangle definition.
:param height
:type height:REAL
:param width
:type width:REAL
'''
def __init__( self , height,width, ):
subshape.__init__(self , )
self.height = height
self.width = width
@apply
def height():
def fget( self ):
return self._height
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument height is mantatory and can not be set to None')
check_type(value,REAL)
self._height = value
return property(**locals())
@apply
def width():
def fget( self ):
return self._width
def fset( self, value ):
# Mandatory argument
if value==None:
raise AssertionError('Argument width is mantatory and can not be set to None')
check_type(value,REAL)
self._width = value
return property(**locals())
@@ -0,0 +1,117 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from SimpleDataTypes import *
class BaseAggregate(object):
""" A class that define common properties to ARRAY, LIST, SET and BAG.
"""
def __init__( self , bound1 , bound2 , base_type ):
# init base list with an empty list
list.__init__(self,[])
# check that bound1<bound2
if (bound1!=None and bound2!=None):
if bound1>bound2:
raise AssertionError("bound1 shall be less than or equal to bound2")
self._bound1 = bound1
self._bound2 = bound2
self._base_type = base_type
print base_type
def __getitem__(self, index):
if index<self._bound1:
raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound1,index))
elif(self._bound2!=None and index>self._bound2):
raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound2,index))
else:
return list.__getitem__(self,index)
def __setitem__(self,index,value):
if index<self._bound1:
raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound1,index))
elif (self._bound2!=None and index>self._bound2):
raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound2,index))
elif not isinstance(value,self._base_type):
raise TypeError("%s type expected, passed %s."%(self._base_type, type(value)))
else:
# first find the length of the list, and extend it if ever
# the index is
list.__setitem__(self,index,value)
class ARRAY(list, BaseAggregate):
"""An array data type has as its domain indexed, fixed-size collections of like elements. The lower
and upper bounds, which are integer-valued expressions, define the range of index values, and
thus the size of each array collection.
An array data type definition may optionally specify
that an array value cannot contain duplicate elements.
It may also specify that an array value
need not contain an element at every index position.
"""
def __init__( self , bound1 , bound2 , base_type ):
BaseAggregate.__init__( self , bound1 , bound2 , base_type )
class LIST(list, BaseAggregate):
"""A list data type has as its domain sequences of like elements. The optional lower and upper
bounds, which are integer-valued expressions, dfine the minimum and maximum number of
elements that can be held in the collection defined by a list data type.
A list data type
definition may optionally specify that a list value cannot contain duplicate elements.
"""
def __init__( self , bound1 , bound2 , base_type ):
BaseAggregate.__init__( self , bound1 , bound2 , base_type )
class BAG(tuple, BaseAggregate):
"""A bag data type has as its domain unordered collections of like elements. The optional lower
and upper bounds, which are integer-valued expressions, de ne the minimum and maximum
number of elements that can be held in the collection de ned by a bag data type.
"""
def __init__( self , bound1 , bound2 , base_type ):
BaseAggregate.__init__( self , bound1 , bound2 , base_type )
class SET(set, BaseAggregate):
"""A set data type has as its domain unordered collections of like elements. The set data type is
a specialization of the bag data type. The optional lower and upper bounds, which are integer-
valued expressions, de ne the minimum and maximum number of elements that can be held in
the collection de ned by a set data type. The collection de ned by set data type shall not
contain two or more elements which are instance equal.
"""
def __init__( self , bound1 , bound2 , base_type ):
BaseAggregate.__init__( self , bound1 , bound2 , base_type )
if __name__=='__main__':
# test ARRAY
a = ARRAY(1,3,REAL)
a[1] = REAL(3.)
a[2] = REAL(-1.5)
a[3] = REAL(4.)
print a
@@ -0,0 +1,67 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class ENUMERATION(list):
""" An ENUMERATION data type has as its domain an ordered set of names. The names represent
values of the enumeration data type.
"""
def __getattr__(self,attr_name):
if attr_name in self:
return attr_name
else:
raise AttributeError("This ENUMERATION has no element '%s'"%attr_name)
class SELECT(list):
""" A select data type has as its domain the union of the domains of the named data types in
its select list. The select data type is a generalization of each of the named data types in its
select list.
"""
def get_aggregated_allowed_types(self):
""" This method returns a list of all types that are handle by this SELECT.
A SELECT can actually be an aggregate of many SELECTs"""
agg = []
for allowed_type in self:
if isinstance(allowed_type,SELECT):
# in this case, we should recurse the select to get all subtypes
b = allowed_type.get_aggregated_allowed_types()
for elem in b:
agg.append(elem)
else:
agg.append(allowed_type)
return agg
if __name__=='__main__':
a = SELECT([1,2])
b = SELECT([3,4])
c = SELECT([a,b])
print a.get_aggregated_allowed_types()
print c.get_aggregated_allowed_types()
+71
View File
@@ -0,0 +1,71 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from math import *
PI = pi #in EXPRESS, PI is uppercase
def EvalDerivedAttribute(class_instance, str_expr):
'''
This functions tries to evaluate EXPRESS math expr.
For instance in the following example:
==
ENTITY circle;
centre : point;
radius : REAL;
axis : vector;
DERIVE
area : REAL := PI*radius**2;
perimeter : REAL := 2.0*PI*radius;
END_ENTITY;
==
The following string should be passed to EvalExpr:
'PI*radius**2'
'''
# first, try to find class paramters
# in the previous example, we should replace radius with self.radius before eval'ing expr
props = []
for prop in dir(class_instance):
if not prop.startswith("_"): #means prop is an item that might be considered
props.append(prop)
for item in props:
str_expr = str_expr.replace(item,"class_instance.%s"%item)
# after that step, the expression should be:
# PI*class_instance.radiüs*class_instance.radius
# this can be evaluated with the eval function
# CAREFUL: eval is known to be unsafe. This should be changed in the future
# (using a parser, or simpy for instance)
try:
return eval(str_expr.lower())
except:
print 'Error evaluating expression'
return None
+203
View File
@@ -0,0 +1,203 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import re
INSTANCE_DEFINITION_RE = re.compile("#(\d+)[^\S\n]?=[^\S\n]?(.*?)\((.*)\)[^\S\n]?;[\\r]?$")
def map_string_to_num(stri):
""" Take a string, check wether it is an integer, a float or not
"""
if ('.' in stri) or ('E' in stri): #it's definitely a float
return REAL(stri)
else:
return INTEGER(stri)
class Model:
"""
A model contains a list of instances
"""
def __init__(self,name):
self._name = name
# a dict of instances
# each time an instance is added to the model, count is incremented
self._instances = {}
self._number_of_instances = 0
def add_instance(self, instance):
'''
Adds an instance to the model
'''
self._number_of_instances += 1
self._instances[self._number_of_instances-1] = instance
def print_instances(self):
'''
Dump instances to stdout
'''
for idx in range(self._number_of_instances):
"=========="
print "Instance #%i"%(idx+1)
print self._instances[idx]
class Part21Loader:
"""
Loads all instances definition of a Part21 file into memory.
Two dicts are created:
self._instance_definition : stores attibutes, key is the instance integer id
self._number_of_ancestors : stores the number of ancestors of entity id. This enables
to define the order of instances creation.
"""
def __init__(self, filename):
self._filename = filename
# the schema
self._schema = ""
# the dict self._instances contain instance definition
self._instances_definition = {}
# this dict contains lists of 0 ancestors, 1 ancestor, etc.
# initializes this dict
self._number_of_ancestors = {}
for i in range(2000):
self._number_of_ancestors[i]=[]
print "Parsing file %s..."%filename,
self.parse_file()
print "done."
# reduce number_of_ancestors dict
for item in self._number_of_ancestors.keys():
if len(self._number_of_ancestors[item])==0:
del self._number_of_ancestors[item]
def get_schema(self):
return self._schema
def get_number_of_instances(self):
return len(self._instances_definition.keys())
def parse_file(self):
fp = open(self._filename)
for line in fp:
# parse line
match_instance_definition = INSTANCE_DEFINITION_RE.search(line) # id,name,attrs
if match_instance_definition:
instance_id, entity_name, entity_attrs = match_instance_definition.groups()
instance_int_id = int(instance_id)
# find number of ancestors
number_of_ancestors = entity_attrs.count('#')
# fill number of ancestors dict
self._number_of_ancestors[number_of_ancestors].append(instance_int_id)
self._instances_definition[instance_int_id] = [entity_name,entity_attrs]
else: #does not match with entity instance definition, parse the header
if line.startswith('FILE_SCHEMA'):
#identify the schema name
self._schema = line.split("'")[1].split("'")[0].split(" ")[0].lower()
fp.close()
class Part21Population(object):
def __init__(self, part21_loader):
""" Take a part21_loader a tries to create entities
"""
self._part21_loader = part21_loader
self._aggregate_scope = []
self._aggr_scope = False
def create_entity_instances(self):
""" Starts entity instances creation
"""
for number_of_ancestor in self._part21_loader._number_of_ancestors.keys():
for entity_definition_id in self._part21_loader._number_of_ancestors[number_of_ancestor]:
self.create_entity_instance(entity_definition_id)
def create_entity_instance(self, instance_id):
instance_definition = self._part21_loader._instances_definition[instance_id]
# first find class name
class_name = instance_definition[0].lower()
object_ = globals()[class_name]
# then attributes
#print object_.__doc__
instance_attributes = instance_definition[1]
#print instance_attributes
# find attributes
attributes = instance_attributes.split(",")
instance_attributes = []
#print attributes
for attr in attributes:
if attr[0]=="(":#new aggregate_scope
#print "new aggregate scope"
self._aggr_scope = True
at = self.map_express_to_python(attr[1:])
#self._aggregate_scope.append(at)
elif attr[-1]==")":
#print "end aggregate scope"
at = self.map_express_to_python(attr[:-1])
self._aggregate_scope.append(at)
self._aggr_scope = False
else:
at = self.map_express_to_python(attr)
if self._aggr_scope:
self._aggregate_scope.append(at)
if len(self._aggregate_scope)>0 and not self._aggr_scope:
instance_attributes.append(self._aggregate_scope)
self._aggregate_scope = []
elif len(self._aggregate_scope)>0 and self._aggr_scope:
pass
else:
instance_attributes.append(at)
a = object_(*instance_attributes)
def map_express_to_python(self,attr):
""" Map EXPRESS to python"""
if attr in ["$","''"]: #optional argument
return None
elif attr.startswith('#'): #entity_id
return attr[1:]
else:
return map_string_to_num(attr)
if __name__ == "__main__":
import time
import sys
sys.path.append("..")
from config_control_design import *
t1 = time.time()
print "Loading file into memory"
#file = Part21Loader("as1-oc-214.stp")
#file = Part21Loader("as1-tu-203.stp")
#file = Part21Loader("HAYON.stp")
p21loader = Part21Loader("as1.stp")
t2 = time.time()
print "Loading schema took: %s s \n" % ((t2-t1))
t1 = time.time()
print "Creating instances"
p21population = Part21Population(p21loader)
p21population.create_entity_instances()
t2 = time.time()
print "Creating instances took: %s s \n" % ((t2-t1))
+44
View File
@@ -0,0 +1,44 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class BaseEntityClass(object):
""" A class that allows advanced __repr__ features for entity instances
"""
def __repr__(self):
""" Displays attribute with their values
"""
doc_string = "# %s class description:\n%s\n# Instance attributes:\n"%(self.__class__,self.__doc__)
# write each argument with its value
properties = dir(self)
for elem in properties:
if not elem.startswith("_"):
doc_string += "\t%s:%s\n"%(elem,self.__getattribute__(elem))
return doc_string
@@ -0,0 +1,186 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Docstrings are courtesy of ISO 10303-11:1994(E)
"""
class NUMBER:
"""
The number data type has as its domain all numeric values in the language. The number data
type shall be used when a more specific numeric representation is not important.
Python mapping: cannot be mapped to a builtin python type. The constructor only checks that
the parameter passed at initialization is a number.
"""
def __init__(self,value):
# should test the type of value (float, or integer)
pass
class REAL(float):
"""
The real data type has as its domain all rational, irrational and scientfic real numbers. It is
a specialization of the number data type.
Syntax:
265 real_type = REAL [ '(' precision_spec ')' ] .
255 precision_spec = numeric_expression .
Rational and irrational numbers have infnite resolution and are exact. Scientific numbers rep-
resent quantities which are known only to a specified precision. The precision_spec is stated
in terms of significant digits.
A real number literal is represented by a mantissa and optional exponent. The number of digits
making up the mantissa when all leading zeros have been removed is the number of significant
digits. The known precision of a value is the number of leading digits that are necessary to the
application.
Rules and restrictions:
a) The precision_spec gives the minimum number of digits of resolution that are re-
quired. This expression shall evaluate to a positive integer value.
b) When no resolution specification is given the precision of the real number is uncon-
strained.
Python mapping: REAL is mapped to 'float' type
"""
pass
class INTEGER(int):
"""
The integer data type has as its domain all integer numbers. It is a specialization of the real
data type.
Python mapping: INTEGER is mapped to 'int' type"""
pass
class STRING(str):
"""
The string data type has as its domain sequences of characters. The characters which are
permitted to form part of a string value are de ned in ISO 10646.
Syntax:
293 string_type = STRING [ width_spec ] .
318 width_spec = '(' width ')' [ FIXED ] .
317 width = numeric_expression .
A string data type may be de ned as either xed or varying width (number of characters). If
it is not specfically defined as fixed width (by using the fixed reserved word in the dfinition)
the string has varying width.
The domain of a xed width string data type is the set of all character sequences of exactly
the width speci ed in the type de nition.
The domain of a varying width string data type is the set of all character sequences of width
less than or equal to the maximum width speci ed in the type de nition.
If no width is speci ed, the domain is the set of all character sequences, with no constraint on
the width of these sequences.
Substrings and individual characters may be addressed using subscripts as described in 12.5.
The case (upper or lower) of letters within a string is signi cant.
Python mapping: INTEGER is mapped the 'str' type. An additional width_spec parameter can be passed
to handle the FIXED length constraint
"""
pass
class LOGICAL:
"""
The logical data type has as its domain the three literals true, false and unknown.
Syntax:
243 logical_type = LOGICAL .
The following ordering holds for the values of the logical data type: false < unknown <
true. The logical data type is compatible with the boolean data type, except that the value
unknown cannot be assigned to a boolean variable.
"""
pass
Unknown = LOGICAL()
#
#The boolean data type has as its domain the two literals true and false. The boolean data
#type is a specialization of the logical data type.
#
#Python mapping: BOOLEAN is mapped to 'bool' type
#
# The bool data type can't however be subclassed in Python (see
# See http://mail.python.org/pipermail/python-dev/2002-March/020822.html)
# so it is just set to bool
BOOLEAN = bool
class BINARY(str):
"""
The binary data type has as its domain sequences of bits, each bit being represented by 0 or 1.
Syntax:
172 binary_type = BINARY [ width_spec ] .
318 width_spec = '(' width ')' [ FIXED ] .
317 width = numeric_expression .
A binary data type may be defined as either fixed or varying width (number of bits). If it is
not specifically defined as fixed width (by using the fixed reserved word in the definition) the
binary data type has varying width.
The domain of a fixed width binary data type is the set of all bit sequences of exactly the width
speci ed in the type definition.
The domain of a varying width binary data type is the set of all bit sequences of width less
than or equal to the maximum width speci ed in the type de nition. If no width is specified,
the domain is the set of all bit sequences, with no constraint on the width of these sequences.
Subbinaries and individual bits may be addressed using subscripts as described in 12.3.
Python mapping: BINARY is mapped to the 'str' type. A check is performed to validate it is a binary
string representing a number.
"""
def __new__(self, value, width=-1, fixed=False):
return str.__new__(self, value)
def __init__(self, value, width=-1, fixed=False):
""" By default, lenght is set to None"""
self._specified_width = width
self._fixed = fixed
# Check implicit width
if (width!=-1) and not fixed:
raise ValueError("The 'width' parameter is passed but 'fixed' is still false. Please explicitely set 'fixed' to True to avoid implicit declaration")
# First check the string length if 'fixed' is set to True
if fixed:
if len(value) != width:
raise ValueError("The BINARY width %i is not consistent with the 'width' declaration(%i)"%(len(value),width))
# Check that the value passed is actually a binary
try:
int(value,2)
except ValueError:
raise ValueError("%s is not a binary"%value)
if __name__=="__main__":
print "Creating REAL from float value"
a = REAL(1.5)
print a*2
print "Creating REAL from string value"
a = REAL("1.2")
print a*3
print "Creating INTEGER from int value"
b = INTEGER(2)
c = INTEGER(3)
print b+c
print "Creating INTEGER from string value"
e = INTEGER("5")
f = INTEGER("8")
print e*f
@@ -0,0 +1,53 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from ConstructedDataTypes import ENUMERATION, SELECT
def check_type(instance, expected_type):
""" This function checks wether an object is an instance of a given class
returns False or True
"""
type_match = False #by default, will be set to True if any match
# in the case of an enumeration, we have to check if the instance is in the list
if isinstance(expected_type,ENUMERATION):
type_match = instance in expected_type
elif isinstance(expected_type,SELECT):
# we check if the instance is of the type of any of the types that are in the SELECT
if type(instance) in expected_type.get_aggregated_allowed_types():
type_match = True
else:
type_match = isinstance(instance,expected_type)
if not type_match:
raise TypeError('Type of argument number_of_sides must be %s (you passed %s)'%(expected_type,type(instance)))
else:
return True
+166
View File
@@ -0,0 +1,166 @@
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from SCL.SimpleDataTypes import *
from SCL.TypeChecker import *
from SCL.ConstructedDataTypes import *
import unittest
#
# Simple data types
#
class TestINTEGER(unittest.TestCase):
'''
INTEGER test
'''
def test_create_from_int(self):
a = INTEGER(1)
self.assertEqual(a,1)
b = REAL(0)
self.assertEqual(b,0)
def test_create_from_string(self):
a = REAL("10")
self.assertEqual(a,10)
b = REAL("0")
self.assertEqual(b,0)
def test_type(self):
a = INTEGER(5)
self.assertTrue(type(a) == INTEGER)
def test_INTEGER_ops(self):
a = INTEGER(2)
b = INTEGER(3)
c = a*b
self.assertEqual(c,6)
self.assertTrue(type(c) == int)
def test_create_from_string_exception(self):
'''
INT cannot be constructed from an ascii string
'''
try:
INTEGER("c")
except ValueError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
class TestREAL(unittest.TestCase):
'''
REAL test
'''
def test_create_from_float(self):
a = REAL(1.5)
self.assertEqual(a,1.5)
b = REAL(0)
self.assertEqual(b,0)
def test_create_from_string(self):
a = REAL("1.5")
self.assertEqual(a,1.5)
b = REAL("0")
self.assertEqual(b,0)
def test_type(self):
a = REAL(5)
self.assertTrue(type(a) == REAL)
def test_REAL_ops(self):
a = REAL(1.5)
b = REAL(2)
c = a*b
self.assertEqual(c,3)
self.assertTrue(type(c) == float)
def test_REAL_INTEGER_ops(self):
a = REAL(5.5)
b = INTEGER(3)
self.assertEqual(a+b,8.5)
self.assertTrue(type(a+b) == float)
def test_create_from_string_exception(self):
'''
REAL cannot be constructed from an ascii string
'''
try:
REAL("c")
except ValueError:
pass
except e:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
class TestBOOLEAN(unittest.TestCase):
'''
BOOLEAN test
'''
def test_create_from_bool(self):
a = BOOLEAN(True)
self.assertTrue(a)
b = BOOLEAN(False)
self.assertFalse(b)
#
# TypeChecker
#
class TestTypeChecker(unittest.TestCase):
def test_match_type(self):
class P:
pass
p = P()
match_type = check_type(p,P) #should return True
self.assertTrue(match_type)
def test_type_dontmatch(self):
class P:
pass
p = P()
try:
check_type(3,P)
except TypeError:
pass
except a:
self.fail('Unexpected exception thrown:', e)
else:
self.fail('ExpectedException not thrown')
def test_check_enum_type(self):
enum = ENUMERATION(["my","string"])
print check_type("my",enum)
unittest.main()
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# All rights reserved.
# This file is part StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of the <ORGANIZATION> nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from distutils.core import setup
setup(name='SCL',
version='0.4',
description='Python STEP Class Library',
author='Thomas Paviot',
author_email='tpaviot@gmail.com',
url='http://www.python.org/sigs/distutils-sig/',
packages=['SCL'],
)
+859
View File
@@ -0,0 +1,859 @@
#define CLASSES_MISC_C
#include <stdlib.h>
#include "classes.h"
/*******************************************************************
** FedEx parser output module for generating C++ class definitions
** December 5, 1989
** release 2 17-Feb-1992
** release 3 March 1993
** release 4 December 1993
** K. C. Morris
**
** Development of FedEx was funded by the United States Government,
** and is not subject to copyright.
*******************************************************************
The conventions used in this binding follow the proposed specification
for the STEP Standard Data Access Interface as defined in document
N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7.
*******************************************************************/
extern int multiple_inheritance;
/*extern int corba_binding; */
/******************************************************************
** The following functions will be used ***
*** through out the the program fedex_plus ***/
/******************************************************************
** Procedure: CheckWord
** Description: if word is a reserved word, it is capitalized
** Parameters: word -- string to be checked
** Returns: altered word if word is reserved; otherwise the original word
** Side Effects: the word is altered in memory
** Status: started 12/1
******************************************************************/
const char *
CheckWord( const char * word ) {
#ifdef NOT_USING_SDAI_BINDING
/* obsolete with proposed c++ binding */
static char * reserved_words [] = {
"application_marker", "asm", "attributes", "auto",
"break", "case", "char", "class", "const", "continue",
"default", "delete", "do", "double",
"else", "enum", "extern",
"float", "for", "friend", "goto", "handle",
"if", "inline", "instance_id", "int", "long",
"new", "nullable", "opcode", "operator", "overload",
"private", "protected", "public", "register", "return",
"shared", "short", "sizeof", "static", "struct", "switch",
"this", "template", "type", "typedef", "type_name",
"union", "unsigned",
"val", "virtual", "void", "volatile"
};
int nwords = ( sizeof reserved_words / sizeof reserved_words[0] );
int cond,
i,
low = 0,
high = nwords - 1;
/* word is obviously not in list, if it is longer than any of the words in the list */
if( strlen( word ) > 12 ) {
return ( word );
}
while( low <= high ) {
i = ( low + high ) / 2;
if( ( cond = strcmp( word, reserved_words [i] ) ) < 0 ) {
high = i - 1;
} else if( cond > 0 ) {
low = i + 1;
} else { /* word is a reserved word, capitalize it */
printf( "** warning: reserved word %s ", word );
*( word + 0 ) = toupper( *( word + 0 ) );
printf( "is changed to %s **\n", word );
}
}
#endif
return ( word );
}
/******************************************************************
** Procedure: string functions
** Description: These functions take a character or a string and return
** a temporary copy of the string with the function applied to it.
** Parameters:
** Returns: temporary copy of characters
** Side Effects: character or string returned persists until the
** next invocation of the function
** Status: complete
******************************************************************/
char
ToLower( char c ) {
if( isupper( c ) ) {
return ( tolower( c ) );
} else {
return ( c );
}
}
char
ToUpper( char c ) {
if( islower( c ) ) {
return ( toupper( c ) );
} else {
return ( c );
}
}
const char *
StrToLower( const char * word ) {
static char newword [MAX_LEN];
int i = 0;
if( !word ) {
return 0;
}
while( word [i] != '\0' ) {
newword [i] = ToLower( word [i] );
++i;
}
newword [i] = '\0';
return ( newword ) ;
}
const char *
StrToUpper( const char * word ) {
static char newword [MAX_LEN];
int i = 0;
char ToUpper( char c );
while( word [i] != '\0' ) {
newword [i] = ToUpper( word [i] );
++i;
}
newword [i] = '\0';
return ( newword );
}
const char *
StrToConstant( const char * word ) {
static char newword [MAX_LEN];
int i = 0;
while( word [i] != '\0' ) {
if( word [i] == '/' || word [i] == '.' ) {
newword [i] = '_';
} else {
newword [i] = ToUpper( word [i] );
}
++i;
}
newword [i] = '\0';
return ( newword );
}
/******************************************************************
** Procedure: FILEcreate
** Description: creates a file for c++ with header definitions
** Parameters: filename
** Returns: FILE* pointer to file created or NULL
** Side Effects: creates a file with name filename
** Status: complete
******************************************************************/
FILE *
FILEcreate( const char * filename ) {
FILE * file;
//const char * fn;
if( ( file = fopen( filename, "w" ) ) == NULL ) {
printf( "**Error in SCHEMAprint: unable to create file %s ** \n", filename );
return ( NULL );
}
//fprintf( file, "#ifndef %s\n", fn = StrToConstant( filename ) );
//fprintf( file, "#define %s\n", fn );
fprintf( file, "# This file was generated by fedex_python. You probably don't want to edit\n" );
fprintf( file, "# it since your modifications will be lost if fedex_plus is used to\n" );
fprintf( file, "# regenerate it.\n" );
return ( file );
}
/******************************************************************
** Procedure: FILEclose
** Description: closes a file opened with FILEcreate
** Parameters: FILE* file -- pointer to file to close
** Returns:
** Side Effects:
** Status: complete
******************************************************************/
void
FILEclose( FILE * file ) {
//fprintf( file, "#endif\n" );
fclose( file );
}
/******************************************************************
** Procedure: isAggregate
** Parameters: Attribute a
** Returns: int indicates whether the attribute is an aggregate
** Description: indicates whether the attribute is an aggregate
** Side Effects: none
** Status: complete 1/15/91
******************************************************************/
int
isAggregate( Variable a ) {
return( TYPEinherits_from( VARget_type( a ), aggregate_ ) );
}
int
isAggregateType( const Type t ) {
return( TYPEinherits_from( t, aggregate_ ) );
}
/******************************************************************
** Procedure: TYPEget_ctype
** Parameters: const Type t -- type for attribute
** Returns: a string which is the type of the data member in the c++ class
** Description: supplies the type of a data member for the c++ class
** Side Effects:
** Status: complete 1/15/90
** Changes: Modified by CD to return the appropriate types as outlined in
** "SDAI C++ Binding for PDES, Inc. Prototyping" by Stephen Clark
** Change Date: 5/22/91 CD
** Change Date: 28-Sep-1993 made entities use their real type instead of base
** class STEPentityH
******************************************************************/
const char *
TYPEget_ctype( const Type t ) {
Class_Of_Type class;
Type bt;
static char retval [BUFSIZ];
/* aggregates are based on their base type
case TYPE_ARRAY:
case TYPE_BAG:
case TYPE_LIST:
case TYPE_SET:
*/
if( isAggregateType( t ) ) {
bt = TYPEget_body( t )->base;
if( isAggregateType( bt ) ) {
return( "GenericAggregate" );
}
class = TYPEget_type( bt );
/* case TYPE_INTEGER: */
if( class == Class_Integer_Type ) {
return ( "IntAggregate" );
}
/* case TYPE_REAL:
case TYPE_NUMBER: */
if( ( class == Class_Number_Type ) || ( class == Class_Real_Type ) ) {
return ( "RealAggregate" );
}
/* case TYPE_ENTITY: */
if( class == Class_Entity_Type ) {
return( "EntityAggregate" );
}
/* case TYPE_ENUM: */
/* case TYPE_SELECT: */
if( ( class == Class_Enumeration_Type )
|| ( class == Class_Select_Type ) ) {
/*
strcpy (retval, ClassName (TYPEget_name (bt)));
*/
strcpy( retval, TYPEget_ctype( bt ) );
strcat( retval, "s" );
return ( retval );
}
/* case TYPE_LOGICAL: */
if( class == Class_Logical_Type ) {
return ( "LOGICALS" );
}
/* case TYPE_BOOLEAN: */
if( class == Class_Boolean_Type ) {
return ( "BOOLEANS" );
}
/* case TYPE_STRING: */
if( class == Class_String_Type ) {
return( "StringAggregate" );
}
/* case TYPE_BINARY: */
if( class == Class_Binary_Type ) {
return( "BinaryAggregate" );
}
}
/* the rest is for things that are not aggregates */
class = TYPEget_type( t );
/* case TYPE_LOGICAL: */
if( class == Class_Logical_Type ) {
return ( "SCLP23(LOGICAL)" );
}
/* case TYPE_BOOLEAN: */
if( class == Class_Boolean_Type ) {
return ( "SCLP23(BOOLEAN)" );
}
/* case TYPE_INTEGER: */
if( class == Class_Integer_Type ) {
return ( "SCLP23(Integer)" );
}
/* case TYPE_REAL:
case TYPE_NUMBER: */
if( ( class == Class_Number_Type ) || ( class == Class_Real_Type ) ) {
return ( "SCLP23(Real)" ) ;
}
/* case TYPE_STRING: */
if( class == Class_String_Type ) {
return ( "SCLP23(String)" );
}
/* case TYPE_BINARY: */
if( class == Class_Binary_Type ) {
return ( "SCLP23(Binary)" );
}
/* case TYPE_ENTITY: */
if( class == Class_Entity_Type ) {
strncpy( retval, TypeName( t ), BUFSIZ - 2 );
strcat( retval, "_ptr" );
return retval;
/* return ("STEPentityH"); */
}
/* case TYPE_ENUM: */
/* case TYPE_SELECT: */
if( class == Class_Enumeration_Type ) {
strncpy( retval, TypeName( t ), BUFSIZ - 2 );
strcat( retval, "_var" );
return retval;
}
if( class == Class_Select_Type ) {
return ( TypeName( t ) );
}
/* default returns undefined */
return ( "SCLundefined" );
}
/******************************************************************
** Procedure: TypeName
** Parameters: Type t
** Returns: name of type as defined in SDAI C++ binding 4-Nov-1993
** Status: 4-Nov-1993
******************************************************************/
const char *
TypeName( Type t ) {
static char name [BUFSIZ];
strcpy( name, TYPE_PREFIX );
if( TYPEget_name( t ) ) {
strncat( name, FirstToUpper( TYPEget_name( t ) ), BUFSIZ - strlen( TYPE_PREFIX ) - 1 );
} else {
return TYPEget_ctype( t );
}
return name;
}
/******************************************************************
** Procedure: AccessType
** Parameters: const Type t -- type for attribute
** Returns: a string which is the type used by the access functions to
the data member in the c++ class
** Description: supplies the type for access functions in a c++ class
** Side Effects:
** Status: 3-Nov-1993 -kcm
******************************************************************/
const char *
AccessType( Type t ) {
Class_Of_Type class;
static char nm [BUFSIZ];
strncpy( nm, TypeName( t ), BUFSIZ - 4 );
if( TYPEis_entity( t ) ) {
/* if(corba_binding)
{
if (TYPEget_name (t))
strncpy (nm, FirstToUpper (TYPEget_name (t)), BUFSIZ-1);
}
*/
strcat( nm, "_ptr" );
return nm;
} else if( TYPEis_select( t ) || TYPEis_aggregate( t ) ) {
strcat( nm, "_ptr" );
return nm;
}
class = TYPEget_type( t );
if( class == Class_Enumeration_Type ) {
strncpy( nm, TypeName( t ), BUFSIZ - 2 );
strcat( nm, "_var" );
return nm;
}
if( class == Class_Logical_Type ) {
strncpy( nm, "Logical", BUFSIZ - 2 );
}
/* case TYPE_BOOLEAN: */
if( class == Class_Boolean_Type ) {
strncpy( nm, "Boolean", BUFSIZ - 2 );
}
return nm;
}
/******************************************************************
** Procedure: ClassName
** Parameters: const char * oldname
** Returns: temporary copy of name suitable for use as a class name
** Side Effects: erases the name created by a previous call to this function
** Status: complete
******************************************************************/
const char *
ClassName( const char * oldname ) {
int i = 0, j = 0;
static char newname [BUFSIZ];
if( !oldname ) {
return ( "" );
}
strcpy( newname, ENTITYCLASS_PREFIX ) ;
j = strlen( ENTITYCLASS_PREFIX ) ;
newname [j] = ToUpper( oldname [i] );
++i;
++j;
while( oldname [i] != '\0' ) {
newname [j] = ToLower( oldname [i] );
/* if (oldname [i] == '_') */
/* character is '_' */
/* newname [++j] = ToUpper (oldname [++i]);*/
++i;
++j;
}
newname [j] = '\0';
return ( newname );
/****** This procedure gets rid of '_' and is no longer being used
if (oldname [i] != '_') newname [j] = ToLower (oldname [i]);
else { *//* character is '_' *//*
newname [j] = ToUpper (oldname [++i]);
if (oldname [i] == '\0') --i;
}
++i;
++j;
*******/
}
const char *
ENTITYget_CORBAname( Entity ent ) {
static char newname [BUFSIZ];
strcpy( newname, ENTITYget_name( ent ) );
newname[0] = ToUpper( newname [0] );
return newname;
}
/******************************************************************
** Procedure: ENTITYget_classname
** Parameters: Entity ent
** Returns: the name of the c++ class representing the entity
** Status: complete
******************************************************************/
const char *
ENTITYget_classname( Entity ent ) {
const char * oldname = ENTITYget_name( ent );
return ( ClassName( oldname ) );
}
/******************************************************************
** Procedure: PrettyTmpName (char * oldname)
** Procedure: PrettyNewName (char * oldname)
** Parameters: oldname
** Returns: a new capitalized name
** Description: creates a new name with first character's in caps
** Side Effects: PrettyNewName allocates memory for the new name
** Status: OK 7-Oct-1992 kcm
******************************************************************/
const char *
PrettyTmpName( const char * oldname ) {
int i = 0;
static char newname [BUFSIZ];
newname [0] = '\0';
while( ( oldname [i] != '\0' ) && ( i < BUFSIZ ) ) {
newname [i] = ToLower( oldname [i] );
if( oldname [i] == '_' ) { /* character is '_' */
++i;
newname [i] = ToUpper( oldname [i] );
}
if( oldname [i] != '\0' ) {
++i;
}
}
newname [0] = ToUpper( oldname [0] );
newname [i] = '\0';
return newname;
}
/* This function is out of date DAS */
const char *
EnumName( const char * oldname ) {
int j = 0;
static char newname [MAX_LEN];
if( !oldname ) {
return ( "" );
}
strcpy( newname, ENUM_PREFIX ) ;
j = strlen( ENUM_PREFIX ) ;
newname [j] = ToUpper( oldname [0] );
strncpy( newname + j + 1, StrToLower( oldname + 1 ), MAX_LEN - j );
j = strlen( newname );
newname [j] = '\0';
return ( newname );
}
const char *
SelectName( const char * oldname ) {
int j = 0;
static char newname [MAX_LEN];
if( !oldname ) {
return ( "" );
}
strcpy( newname, TYPE_PREFIX );
newname [0] = ToUpper( newname [0] );
j = strlen( TYPE_PREFIX );
newname [j] = ToUpper( oldname [0] );
strncpy( newname + j + 1, StrToLower( oldname + 1 ), MAX_LEN - j );
j = strlen( newname );
newname [j] = '\0';
return ( newname );
}
const char *
FirstToUpper( const char * word ) {
static char newword [MAX_LEN];
strncpy( newword, word, MAX_LEN );
newword[0] = ToUpper( newword[0] );
return ( newword );
}
/* return fundamental type but as the string which corresponds to */
/* the appropriate type descriptor */
/* if report_reftypes is true, report REFERENCE_TYPE when appropriate */
char *
FundamentalType( const Type t, int report_reftypes ) {
if( report_reftypes && TYPEget_head( t ) ) {
return( "REFERENCE_TYPE" );
}
switch( TYPEget_body( t )->type ) {
case integer_:
return( "INTEGER" );
case real_:
return( "REAL" );
case string_:
return( "STRING" );
case binary_:
return( "BINARY" );
case boolean_:
return( "BOOLEAN" );
case logical_:
return( "LOGICAL" );
case number_:
return( "NUMBER" );
case generic_:
return( "GENERIC_TYPE" );
case aggregate_:
return( "AGGREGATE_" );
case array_:
return( "ARRAY_TYPE" );
case bag_:
return( "BAG_TYPE" );
case set_:
return( "'SET_TYPE not implemented'" );
case list_:
return( "'LIST TYPE Not implemented'" );
case entity_:
return( "INSTANCE" );
case enumeration_:
return( "ENUMERATION" );
case select_:
return ( "SELECT" );
default:
return( "UNKNOWN_TYPE" );
}
}
/* this actually gets you the name of the variable that will be generated to
be a TypeDescriptor or subtype of TypeDescriptor to represent Type t in
the dictionary. */
const char *
TypeDescriptorName( Type t ) {
static char b [BUFSIZ];
Schema parent = t->superscope;
/* NOTE - I corrected a prev bug here in which the *current* schema was
** passed to this function. Now we take "parent" - the schema in which
** Type t was defined - which was actually used to create t's name. DAR */
if( !parent ) {
parent = TYPEget_body( t )->entity->superscope;
/* This works in certain cases that don't work otherwise (basically a
** kludge). For some reason types which are really entity choices of
** a select have no superscope value, but their super may be tracked
** by following through the entity they reference, as above. */
}
sprintf( b, "%s%s%s", SCHEMAget_name( parent ), TYPEprefix( t ),
TYPEget_name( t ) );
return b;
}
/* this gets you the name of the type of TypeDescriptor (or subtype) that a
variable generated to represent Type t would be an instance of. */
const char *
GetTypeDescriptorName( Type t ) {
switch( TYPEget_body( t )->type ) {
case aggregate_:
return "AggrTypeDescriptor";
case list_:
return "ListTypeDescriptor";
case set_:
return "SetTypeDescriptor";
case bag_:
return "BagTypeDescriptor";
case array_:
return "ArrayTypeDescriptor";
case select_:
return "SelectTypeDescriptor";
case boolean_:
case logical_:
case enumeration_:
return "EnumTypeDescriptor";
case entity_:
return "EntityDescriptor";
case integer_:
case real_:
case string_:
case binary_:
case number_:
case generic_:
return "TypeDescriptor";
default:
printf( "Error in %s, line %d: type %d not handled by switch statement.", __FILE__, __LINE__, TYPEget_body( t )->type );
abort();
}
}
int
ENTITYhas_explicit_attributes( Entity e ) {
Linked_List l = ENTITYget_attributes( e );
int cnt = 0;
LISTdo( l, a, Variable )
if( VARget_initializer( a ) == EXPRESSION_NULL ) {
++cnt;
}
LISTod;
return cnt;
}
Entity
ENTITYput_superclass( Entity entity ) {
#define ENTITYget_type(e) ((e)->u.entity->type)
Linked_List l = ENTITYget_supertypes( entity );
Entity super = 0;
Entity ignore = 0;
int super_cnt = 0;
EntityTag tag;
Linked_List list = 0;
if( ! LISTempty( l ) ) {
if( multiple_inheritance ) {
list = ENTITYget_supertypes( entity );
if( ! LISTempty( list ) ) {
/* assign superclass to be the first one on the list of parents */
super = ( Entity )LISTpeek_first( list );
}
} else {
/* find the first parent that has attributes (in the parent or any of its
ancestors). Make super point at that parent and print warnings for
all the rest of the parents. DAS */
LISTdo( l, e, Entity )
/* if there's no super class yet,
or if the entity super class [the variable] super is pointing at
doesn't have any attributes: make super point at the current parent.
As soon as the parent pointed to by super has attributes, stop
assigning super and print ignore messages for the remaining parents.
*/
if( ( ! super ) || ( ! ENTITYhas_explicit_attributes( super ) ) ) {
ignore = super;
super = e;
++ super_cnt;
} else {
ignore = e;
}
if( ignore ) {
printf( "WARNING: multiple inheritance not implemented.\n" );
printf( "\tin ENTITY %s\n\tSUPERTYPE %s IGNORED.\n\n",
ENTITYget_name( entity ), ENTITYget_name( e ) );
}
LISTod;
}
tag = ( EntityTag ) malloc( sizeof( struct EntityTag_ ) );
tag -> superclass = super;
TYPEput_clientData( ENTITYget_type( entity ), tag );
return super;
}
return 0;
}
Entity
ENTITYget_superclass( Entity entity ) {
EntityTag tag;
tag = TYPEget_clientData( ENTITYget_type( entity ) );
return ( tag ? tag -> superclass : 0 );
}
void ENTITYget_first_attribs( Entity entity, Linked_List result ) {
Linked_List supers;
LISTdo( ENTITYget_attributes( entity ), attr, Generic )
LISTadd_last( result, attr );
LISTod;
supers = ENTITYget_supertypes( entity );
if( supers ) {
ENTITYget_first_attribs( ( Entity )LISTget_first( supers ), result );
}
}
/* Attributes are divided into four categories:
** these are not exclusive as far as I can tell! I added defs below DAS
**
** . simple explicit
** . type shifters // not DERIVEd - redefines type in ancestor
** // VARget_initializer(v) returns null
**
** . simple derived // DERIVEd - is calculated - VARget_initializer(v)
** // returns non-zero, VARis_derived(v) is non-zero
**
** . overriding // includes type shifters and derived
**
** All of them are added to the dictionary.
** Only type shifters generate a new STEPattribute.
** Type shifters generate access functions and data members, for now.
** Overriding generate access functions and data members, for now. ???? DAS
** // type shifting attributes
** // ------------------------
** // before printing new STEPattribute
** // check to see if it\'s already printed in supertype
** // still add new access function
**
** // overriding attributes
** // ---------------------
** // go through derived attributes
** // if STEPattribute found with same name
** // tell it to be * for reading and writing
**/
Variable
VARis_type_shifter( Variable a ) {
char * temp;
if( VARis_derived( a ) || VARget_inverse( a ) ) {
return 0;
}
temp = EXPRto_string( VARget_name( a ) );
if( ! strncmp( StrToLower( temp ), "self\\", 5 ) ) {
/* a is a type shifter */
free( temp );
return a;
}
free( temp );
return 0;
}
Variable
VARis_overrider( Entity e, Variable a ) {
Variable other;
char * tmp;
tmp = VARget_simple_name( a );
LISTdo( ENTITYget_supertypes( e ), s, Entity )
if( ( other = ENTITYget_named_attribute( s, tmp ) )
&& other != a ) {
return other;
}
LISTod;
return 0;
}
Type
TYPEget_ancestor( Type t )
/*
* For a renamed type, returns the original (ancestor) type from which t
* descends. Return NULL if t is top level.
*/
{
Type i = t;
if( !TYPEget_head( i ) ) {
return NULL;
}
while( TYPEget_head( i ) ) {
i = TYPEget_head( i );
}
return i;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,553 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "complexSupport.h"
extern int corba_binding;
void use_ref( Schema, Express, FILES * );
void
create_builtin_type_decl( FILES * files, char * name ) {
//fprintf( files->incall, "extern TypeDescriptor *%s%s_TYPE;\n",
// TD_PREFIX, name );
}
void
create_builtin_type_defn( FILES * files, char * name ) {
//fprintf( files->initall, "\t%s%s_TYPE = TypeDescriptor (",
// TD_PREFIX, name );
//fprintf( files->initall, "\"%s\", %s_TYPE, \"%s\");\n",
// PrettyTmpName( name ), StrToUpper( name ), StrToLower( name ) );
}
/******************************************************************
** Procedure: print_file_header
** Parameters: const Schema schema - top-level schema being printed
** FILE* file - file on which to print header
** Returns:
** Description: handles file related tasks that need to be done once
** at the beginning of processing.
** In this case the file schema.h is initiated
** Status: ok 1/15/91
******************************************************************/
void
print_file_header( Express express, FILES * files ) {
//files -> incall = FILEcreate( "schema.h" );
/* prevent RCS from expanding this! */
//fprintf( files->incall, "import sdai\n" );
//fprintf( files->incall, "import Registry\n" );
//fprintf( files->incall, "\n#include <STEPaggregate.h>\n" );
//fprintf( files->incall, "\n#include <STEPundefined.h>\n" );
//fprintf( files->incall, "\n#include <ExpDict.h>\n" );
//fprintf( files->incall, "\n#include <STEPattribute.h>\n" );
//fprintf( files->incall, "\n#include <Sdaiclasses.h>\n" );
//fprintf( files->incall, "import Sdaiclasses\n" );
//fprintf( files->incall, "extern void SchemaInit (Registry &);\n" );
//fprintf( files->incall, "extern void InitSchemasAndEnts (Registry &);\n" );
//files -> initall = FILEcreate( "schema.py" );
//fprintf( files->initall, "/* %cId$ */ \n", '\044' );
//fprintf( files->initall, "#include <schema.h>\n" );
//fprintf( files->initall, "import schema\n" );
//fprintf( files-> initall, "class Registry:\n" );
//fprintf( files->initall, "\tdef SchemaInit (Registry reg)\n{\n" );
//fprintf( files->initall, "\t extern void InitSchemasAndEnts " );
//fprintf( files->initall, "(Registry & r);\n" );
//fprintf( files->initall, "\t InitSchemasAndEnts (reg);\n" );
// This file will contain instantiation statements for all the schemas and
// entities in the express file. (They must all be in separate function
// called first by SchemaInit() so that all entities will exist
//files -> create = FILEcreate( "SdaiAll.py" );
//fprintf( files->create, "/* %cId$ */ \n", '\044' );
//fprintf( files->create, "#include <schema.h>\n" );
//fprintf( files->create, "import schema" );
//fprintf( files->create, "\nvoid\nInitSchemasAndEnts (Registry & reg)\n{\n" );
// This file declares all entity classes as incomplete types. This will
// allow all the .h files to reference all .h's. We can then have e.g.,
// entX from schemaA have attribute attr1 = entY from schemaB.
//files -> classes = FILEcreate( "Sdaiclasses.h" );
//fprintf( files->classes, "/* %cId$ */ \n", '$' );
//fprintf( files->classes, "#include <schema.h>\n" );
/* create built-in types */
/* no need to generate
create_builtin_type_decl(files,"INTEGER");
create_builtin_type_decl(files,"REAL");
create_builtin_type_decl(files,"STRING");
create_builtin_type_decl(files,"BINARY");
create_builtin_type_decl(files,"BOOLEAN");
create_builtin_type_decl(files,"LOGICAL");
create_builtin_type_decl(files,"NUMBER");
create_builtin_type_decl(files,"GENERIC");
*/
/* create built-in types */
/* no need to generate
create_builtin_type_defn(files,"INTEGER");
create_builtin_type_defn(files,"REAL");
create_builtin_type_defn(files,"STRING");
create_builtin_type_defn(files,"BINARY");
create_builtin_type_defn(files,"BOOLEAN");
create_builtin_type_defn(files,"LOGICAL");
create_builtin_type_defn(files,"NUMBER");
create_builtin_type_defn(files,"GENERIC");
*/
}
/******************************************************************
** Procedure: print_file_trailer
** Parameters: const Schema schema - top-level schema printed
** FILE* file - file on which to print trailer
** Returns:
** Description: handles cleaning up things at end of processing
** Status: ok 1/15/91
******************************************************************/
/*ARGSUSED*/
void
print_file_trailer( Express express, FILES * files ) {
//FILEclose( files->incall );
//FILEclose( files->initall );
//fprintf( files->create, "}\n\n" );
//FILEclose( files->create );
//fprintf( files->classes, "\n" );
//FILEclose( files->classes );
}
/******************************************************************
** SCHEMA SECTION **/
/******************************************************************
** Procedure: SCOPEPrint
** Parameters: const Scope scope - scope to print
** FILE* file - file on which to print
** Returns:
** Description: cycles through the scopes of the input Express schema
** Side Effects: calls functions for processing entities and types
** Status: working 1/15/91
** -- it's still not clear how include files should be organized
** and what the relationship is between this organization and the
** organization of the schemas in the input Express
******************************************************************/
void
SCOPEPrint( Scope scope, FILES * files, Schema schema, Express model,
ComplexCollect * col, int cnt ) {
Linked_List list = SCOPEget_entities_superclass_order( scope );
DictionaryEntry de;
Type i;
int redefs = 0;// index = 0;
/* fill in the values for the type descriptors */
/* and print the enumerations */
//fprintf( files -> inc, "\n/*\t************** TYPES \t*/\n" );
//fprintf( files -> lib, "\n/*\t************** TYPES \t*/\n" );
SCOPEdo_types( scope, t, de )
// First check for one exception: Say enumeration type B is defined
// to be a rename of enum A. If A is in this schema but has not been
// processed yet, we must wait till it's processed first. The reason
// is because B will basically be defined with a couple of typedefs to
// the classes which represent A. (To simplify, we wait even if A is
// in another schema, so long as it's been processed.)
if( ( t->search_id == CANPROCESS )
&& ( TYPEis_enumeration( t ) )
&& ( ( i = TYPEget_ancestor( t ) ) != NULL )
&& ( i->search_id >= CANPROCESS ) ) {
redefs = 1;
}
SCOPEod
SCOPEdo_types( scope, t, de )
// Do the non-redefined enumerations:
if( ( t->search_id == CANPROCESS )
&& !( TYPEis_enumeration( t ) && TYPEget_head( t ) ) ) {
TYPEprint_descriptions( t, files, schema );
if( !TYPEis_select( t ) ) {
// Selects have a lot more processing and are done below.
t->search_id = PROCESSED;
}
}
SCOPEod;
if( redefs ) {
// Here we process redefined enumerations. See note, 2 loops ago.
SCOPEdo_types( scope, t, de )
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
t->search_id = PROCESSED;
}
SCOPEod;
}
// Write Schema Classes for each entity
// This must be done *before* typedefs are defined
LISTdo( list, e, Entity );
if( e->search_id == CANPROCESS ) {
ENTITYPrint( e, files, schema );
e->search_id = PROCESSED;
}
LISTod;
/* do the select definitions next, since they depend on the others */
//fprintf( files->inc, "\n//\t***** Build the SELECT Types \t\n" );
// Note - say we have sel B, rename of sel A (as above by enum's). Here
// we don't have to worry about printing B before A. This is checked in
// TYPEselect_print().
SCOPEdo_types( scope, t, de )
if( t->search_id == CANPROCESS ) {
// Only selects haven't been processed yet and may still be set to
// CANPROCESS.
TYPEselect_print( t, files, schema );
t->search_id = PROCESSED;
}
SCOPEod;
LISTfree( list );
}
void
PrintModelContentsSchema( Scope scope, FILES * files, Schema schema,
Express model ) {
Linked_List list;
char nm[BUFSIZ];
DictionaryEntry de;
//fprintf( files -> inc, "\n/*\t************** TYPES \t*/\n" );
// Types should be exported to schema_name.DefinedDataTypes
//fprintf( files -> lib, "\n/*\t************** TYPES \t*/\n" );
//fprintf( files -> init, "\n/*\t************** TYPES \t*/\n" );
/* do \'new\'s for types descriptors */
SCOPEdo_types( scope, t, de )
//TYPEprint_new( t, files->create, schema );
SCOPEod;
/* do \'new\'s for entity descriptors */
list = SCOPEget_entities_superclass_order( scope );
//fprintf( files->init, "\n\t//\t***** Describe the Entities \t*/\n" );
fprintf( files->inc, "\n//\t***** Describe the Entities \t\n" );
LISTdo( list, e, Entity );
ENTITYput_superclass( e ); /* find supertype to use for single */
ENTITYprint_new( e, files, schema, 0 ); /* inheritance */
LISTod;
// Print Entity Classes
LISTdo( list, e, Entity );
ENTITYPrint( e, files, schema );
LISTod;
/* fill in the values for the type descriptors */
/* and print the enumerations */
//fprintf(files->lib,"register_defined_types():\n");
fprintf( files->inc, "\n//\t***** Describe the Other Types \t\n" );
SCOPEdo_types( scope, t, de )
TYPEprint_descriptions( t, files, schema );
if( TYPEis_select( t ) ) {
/* do the select aggregates here */
strncpy( nm, SelectName( TYPEget_name( t ) ), BUFSIZ );
fprintf( files->inc, "class %s;\ntypedef %s * %sH;\n", nm, nm, nm );
fprintf( files->inc,
"typedef %s * %s_ptr;\ntypedef %s_ptr %s_var;\n\n",
nm, nm, nm, nm );
fprintf( files->inc, "class %ss;\ntypedef %ss * %ssH;\n", nm, nm, nm );
fprintf( files->inc,
"typedef %ss * %ss_ptr;\ntypedef %ss_ptr %ss_var;\n\n",
nm, nm, nm, nm );
}
SCOPEod;
/* build the typedefs */
SCOPEdo_types( scope, t, de )
if( !( TYPEis_select( t ) ) ) {
TYPEprint_typedefs( t, files ->inc );
}
SCOPEod;
/* do the select definitions next, since they depend on the others */
fprintf( files->inc, "\n//\t***** Build the SELECT Types \t\n" );
//fprintf( files->init, "\n//\t***** Add the TypeDescriptor's to the"
// " SELECT Types \t\n" );
SCOPEdo_types( scope, t, de )
if( TYPEis_select( t ) ) {
TYPEselect_print( t, files, schema );
}
SCOPEod;
LISTfree( list );
}
/******************************************************************
** Procedure: SCHEMAprint
** Parameters: const Schema schema - schema to print
** FILES *file - file on which to print
** Express model - fedex rep of entire EXPRESS file
** ComplexCollect col - all the complex entity info pertaining
** to this EXPRESS file
** int suffix - suffix to use for generated cc files
** Returns:
** Description: handles initialization of files specific to schemas
** Side Effects:
** Status:
******************************************************************/
void
SCHEMAprint( Schema schema, FILES * files, Express model, void * complexCol,
int suffix ) {
char schnm[MAX_LEN], sufnm[MAX_LEN], fnm[MAX_LEN], *np;
/* sufnm = schema name + suffix */
FILE * libfile,
//*incfile,
//*schemafile = files->incall,
// *schemainit = files->initall,
*initfile
// *createall = files->create
;
Rule r;
Function f;
Procedure p;
DictionaryEntry de;
char * tmpstr = 0;
unsigned int tmpstr_size = 0;
/********** create files based on name of schema ***********/
/* return if failure */
/* 1. header file */
//sprintf( schnm, "%s%s", SCHEMA_FILE_PREFIX,
// StrToUpper( SCHEMAget_name( schema ) ) );
sprintf( schnm, "%s", SCHEMAget_name( schema ) );
if( suffix == 0 ) {
sprintf( sufnm, "%s", schnm );
} else {
sprintf( sufnm, "%s_%d", schnm, suffix );
}
sprintf( fnm, "%s.h", sufnm );
//if( !( incfile = ( files -> inc ) = FILEcreate( fnm ) ) ) {
// return;
//}
/* Generate local to SCHEMA.init.cc file */
/* fprintf(incfile,"Schema *%s%s;\n",*/
/* SCHEMA_PREFIX,SCHEMAget_name(schema));*/
/* fprintf (incfile, "extern void %sInit (Registry & r);\n", schnm);*/
/* fprintf (incfile, "extern void SchemaInit (Registry & r);\n");*/
np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */
/* 2. class source file */
sprintf( np, "py" );
//if( !( libfile = ( files -> lib ) = FILEcreate( fnm ) ) ) {
if( !( libfile = ( files -> lib ) = FILEcreate( fnm ) ) ) {
return;
}
//fprintf( libfile, "/* %cId$ */ \n", '$' );
fprintf(libfile,"from SCL.SCLBase import *\n");
fprintf(libfile,"from SCL.SimpleDataTypes import *\n");
fprintf(libfile,"from SCL.ConstructedDataTypes import *\n");
fprintf(libfile,"from SCL.AggregationDataType import *\n");
fprintf(libfile,"from SCL.TypeChecker import check_type\n");
fprintf(libfile,"from SCL.Expr import *\n");
/********** do the schemas ***********/
/* really, create calls for entity constructors */
SCOPEPrint( schema, files, schema, model, ( ComplexCollect * )complexCol,
suffix );
/********** close the files ***********/
FILEclose( libfile );
//FILEclose( incfile );
//if( schema->search_id == PROCESSED ) {
// fprintf( initfile, "\n}\n" );
// FILEclose( initfile );
//} else {
// fclose( initfile );
//}
}
/******************************************************************
** Procedure: getMCPrint
** Parameters:
Express express - in memory representation of an express model
FILE* schema_h - generated schema.h file
FILE* schema_cc - schema.cc file
** Returns:
** Description: drives functions to generate code for all the schemas
** in an Express model into one set of files -- works with
** print_schemas_combined
** Side Effects: generates code
** Status: 24-Feb-1992 new -kcm
******************************************************************/
void
getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) {
DictionaryEntry de;
Schema schema;
fprintf( schema_h,
"\nSCLP23(Model_contents_ptr) GetModelContents(char *schemaName);\n" );
fprintf( schema_cc, "%s%s%s%s",
"// Generate a function to be called by Model to help it\n",
"// create the necessary Model_contents without the\n",
"// dictionary (Registry) handle since it doesn't have a\n",
"// predetermined way to access to the handle.\n" );
fprintf( schema_cc,
"\nSCLP23(Model_contents_ptr) GetModelContents(char *schemaName)\n{\n" );
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
schema = ( Scope )DICTdo( &de );
fprintf( schema_cc,
" if(!strcmp(schemaName, \"%s\"))\n",
SCHEMAget_name( schema ) );
fprintf( schema_cc,
" return (SCLP23(Model_contents_ptr)) new SdaiModel_contents_%s; \n",
SCHEMAget_name( schema ) );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
fprintf( schema_cc,
" else if(!strcmp(schemaName, \"%s\"))\n",
SCHEMAget_name( schema ) );
fprintf( schema_cc,
" return (SCLP23(Model_contents_ptr)) new SdaiModel_contents_%s; \n",
SCHEMAget_name( schema ) );
}
fprintf( schema_cc, "}\n" );
}
/******************************************************************
** Procedure: EXPRESSPrint
** Parameters:
Express express -- in memory representation of an express model
FILES* files -- set of output files to print to
** Returns:
** Description: drives functions to generate code for all the schemas
** in an Express model into one set of files -- works with
** print_schemas_combined
** Side Effects: generates code
** Status: 24-Feb-1992 new -kcm
******************************************************************/
void
EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
char fnm [MAX_LEN], *np;
const char * schnm; /* schnm is really "express name" */
FILE * libfile;
//FILE * incfile;
//FILE * schemafile = files -> incall;
//FILE * schemainit = files -> initall;
FILE * initfile;
/* new */
Schema schema;
DictionaryEntry de;
/********** create files based on name of schema ***********/
/* return if failure */
/* 1. header file */
sprintf( fnm, "%s.h", schnm = ClassName( EXPRESSget_basename( express ) ) );
//if( !( incfile = ( files -> inc ) = FILEcreate( fnm ) ) ) {
// return;
//}
//fprintf( incfile, "/* %cId$ */\n", '$' );
//fprintf( incfile, "#ifdef __O3DB__\n" );
//fprintf( incfile, "#include <OpenOODB.h>\n" );
//fprintf( incfile, "#endif\n\n" );
//fprintf( incfile, "#include <sdai.h> \n" );
/* fprintf (incfile, "#include <schema.h> \n");*/
/* fprintf (incfile, "extern void %sInit (Registry & r);\n", schnm);*/
//np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */
/* 2. class source file */
//sprintf( np, "cc" );
if( !( libfile = ( files -> lib ) = FILEcreate( fnm ) ) ) {
return;
}
//fprintf( libfile, "/* %cId$ */\n", '$' );
//fprintf( libfile, "#include <%s.h> n", schnm );
/* 3. source code to initialize entity registry */
/* prints header of file for input function */
//sprintf( np, "init.cc" );
//if( !( initfile = ( files -> init ) = FILEcreate( fnm ) ) ) {
// return;
//}
//fprintf( initfile, "/* $Id%d */\n", '$' );
//fprintf( initfile, "#include <%s.h>\n\n", schnm );
//fprintf( initfile, "void \n%sInit (Registry& reg)\n{\n", schnm );
/********** record in files relating to entire input ***********/
/* add to schema's include and initialization file */
//fprintf( schemafile, "#include <%s.h>\n\n", schnm );
//fprintf( schemafile, "extern void %sInit (Registry & r);\n", schnm );
//fprintf( schemainit, "\t extern void %sInit (Registry & r);\n", schnm );
//fprintf( schemainit, "\t %sInit (reg);\n", schnm );
/********** do all schemas ***********/
DICTdo_init( express->symbol_table, &de );
while( 0 != ( schema = ( Scope )DICTdo( &de ) ) ) {
SCOPEPrint( schema, files, schema, express, &col, 0 );
}
/********** close the files ***********/
FILEclose( libfile );
//FILEclose( incfile );
//fprintf( initfile, "\n}\n" );
//FILEclose( initfile );
}
/******************************************************************
** Procedure: print_schemas_combined
** Parameters:
Express express -- in memory representation of an express model
FILES* files -- set of output files to print to
** Returns:
** Description: drives functions to generate code for all the schemas
** in an Express model into one set of files -- works with EXPRESSPrint
** Side Effects: generates code
** Status: 24-Feb-1992 new -kcm
******************************************************************/
void
print_schemas_combined( Express express, ComplexCollect & col, FILES * files ) {
EXPRESSPrint( express, col, files );
}
/*
** Procedure: print_file
** Parameters: const Schema schema - top-level schema to print
** FILE* file - file on which to print
** Returns: void
** Description: this function calls one of two different functions
** depending on whether the output should be combined into a single
** set of files or a separate set for each schema
**
*/
void
print_file( Express express ) {
extern void RESOLUTIONsucceed( void );
int separate_schemas = 1;
ComplexCollect col( express );
File_holder files;
resolution_success();
print_file_header( express, &files );
if( separate_schemas ) {
print_schemas_separate( express, ( void * )&col, &files );
} else {
print_schemas_combined( express, col, &files );
}
print_file_trailer( express, &files );
//print_complex( col, ( const char * )"compstructs.cc" );
}
+134
View File
@@ -0,0 +1,134 @@
/************************************************************************
** Driver for Fed-X Express parser.
************************************************************************/
/*
* This software was developed by U.S. Government employees as part of
* their official duties and is not subject to copyright.
*
* $Log: fedex_main.c,v $
* Revision 3.0.1.3 1997/11/05 23:12:18 sauderd
* Adding a new state DP3.1 and associated revision
*
* Revision 3.0.1.2 1997/09/26 15:59:10 sauderd
* Finished implementing the -a option (changed from -e) to generate the early
* bound access functions the old way. Implemented the change to generate them
* the new correct way by default.
*
* Revision 3.0.1.1 1997/09/18 21:18:41 sauderd
* Added a -e or -E option to generate attribute get and put functions the old
* way (without an underscore). It sets the variable old_accessors. This doesn't
* currently do anything. It needs to be implemented to generate attr funcs
* correctly.
*
* Revision 3.0.1.0 1997/04/16 19:29:03 dar
* Setting the first branch
*
* Revision 3.0 1997/04/16 19:29:02 dar
* STEP Class Library Pre Release 3.0
*
* Revision 2.1.0.5 1997/03/11 15:33:59 sauderd
* Changed code so that if fedex_plus is passed the -c or -C option it would
* generate implementation objects for Orbix (CORBA). Look for code that is
* inside stmts such as if(corba_binding)
*
* Revision 2.1.0.4 1996/09/25 22:56:55 sauderd
* Added a command line argument for logging SCL use. The option added is -l or
* -L. It also says the option in the usage stmt when you run fedex_plus without
* an argument. Added the options to the EXPRESSgetopt_options string.
*
* Revision 2.1.0.3 1996/06/18 18:14:17 sauderd
* Changed the line that gets printed when you run fedex_plus with no
* arguments to include the option for single inheritance.
*
* Revision 2.1.0.2 1995/05/19 22:40:03 sauderd
* Added a command line argument -s or -S for generating code based on the old
* method as opposed to the new method of multiple inheritance.
*
* Revision 2.1.0.1 1995/05/16 19:52:18 lubell
* setting state to dp21
*
* Revision 2.1.0.0 1995/05/12 18:53:48 lubell
* setting branch
*
* Revision 2.1 1995/05/12 18:53:47 lubell
* changing version to 2.1
*
* Revision 1.7 1995/03/16 20:58:50 sauderd
* ? changes.
*
* Revision 1.6 1992/09/29 15:46:55 libes
* added messages for KC
*
* Revision 1.5 1992/08/27 23:28:52 libes
* moved Descriptor "new"s to precede assignments
* punted SELECT type
*
* Revision 1.4 1992/08/19 18:49:59 libes
* registry support
*
* Revision 1.3 1992/06/05 19:55:28 libes
* Added * to typedefs. Replaced warning kludges with ERRORoption.
*/
#include <stdlib.h>
#include <stdio.h>
#include "../express/express.h"
#include "../express/resolve.h"
extern void print_fedex_version( void );
static void fedex_plus_usage( void ) {
fprintf( stderr, "usage: %s [-v] [-d # | -d 9 -l nnn -u nnn] [-n] [-p <object_type>] {-w|-i <warning>} express_file\n", EXPRESSprogram_name );
//fprintf( stderr, "where\t-s or -S uses only single inheritance in the generated C++ classes\n" );
//fprintf( stderr, "\t-a or -A generates the early bound access functions for entity classes the old way (without an underscore)\n" );
//fprintf( stderr, "\t-c or -C generates C++ classes for use with CORBA (Orbix)\n" );
//fprintf( stderr, "\t-L prints logging code in the generated C++ classes\n" );
fprintf( stderr, "\t-v produces the version description below\n" );
fprintf( stderr, "\t-d turns on debugging (\"-d 0\" describes this further\n" );
//fprintf( stderr, "\t-p turns on printing when processing certain objects (see below)\n" );
//fprintf( stderr, "\t-n do not pause for internal errors (useful with delta script)\n" );
fprintf( stderr, "\t-w warning enable\n" );
fprintf( stderr, "\t-i warning ignore\n" );
fprintf( stderr, "and <warning> is one of:\n" );
fprintf( stderr, "\tnone\n\tall\n" );
LISTdo( ERRORwarnings, opt, Error_Warning )
fprintf( stderr, "\t%s\n", opt->name );
LISTod
fprintf( stderr, "and <object_type> is one or more of:\n" );
fprintf( stderr, " e entity\n" );
fprintf( stderr, " p procedure\n" );
fprintf( stderr, " r rule\n" );
fprintf( stderr, " f function\n" );
fprintf( stderr, " t type\n" );
fprintf( stderr, " s schema or file\n" );
fprintf( stderr, " # pass #\n" );
fprintf( stderr, " E everything (all of the above)\n" );
print_fedex_version();
exit( 2 );
}
int Handle_FedPlus_Args( int, char * );
void print_file( Express );
void resolution_success( void ) {
printf( "Resolution successful.\nWriting python module..." );
}
int success( Express model ) {
printf( "Done.\n" );
return( 0 );
}
/* This function is called from main() which is part of the NIST Express
Toolkit. It assigns 2 pointers to functions which are called in main() */
void EXPRESSinit_init() {
EXPRESSbackend = print_file;
EXPRESSsucceed = success;
EXPRESSgetopt = Handle_FedPlus_Args;
/* so the function getopt (see man 3 getopt) will not report an error */
strcat( EXPRESSgetopt_options, "sSLcCaA" );
ERRORusage_function = fedex_plus_usage;
}
+729
View File
@@ -0,0 +1,729 @@
/*****************************************************************************
* multpass.c *
* *
* Description: *
* Adds multi-schema support enhancement to fedex_plus parser. Allows the *
* generation of C++ representations for multiple EXPRESS schemas without *
* creating conflicting header files. Previously, fedex_plus would gene- *
* rate a single set of files (.h, .cc, .init.cc) for each schema found in *
* the processed EXPRESS file. A number of problem situations occurred: *
* *
* (1) Two schemas which USE or REFERENCE entities from one another. If *
* e.g. schema A USEs entity 1 from schema B and defines ent 2 subtype *
* of 1, and schema B USEs ent 2 from A and defines ents 1 and 3 sub- *
* type of 2, neither include file could be compiled first. *
* (2) An entity which has a select or enumeration attribute which is de- *
* fined in another schema. *
* (3) A select type which has a select or enum member item which is de- *
* fined in another schema.
* (4) An enumeration type which is a redefinition of an enum defined in *
* another schema. *
* *
* The functions in multpass.c provide for the processing of each schema *
* in multiple passes. At each pass, only entities and types which are *
* not dependent on undefined objects are processed. With each pass, more *
* entities and types become defined and more dependent entities and types *
* will become processable. At each state of processing, a separate set *
* of C++ files is generated. Lastly, multpass processes certain aggre- *
* gate and redefined objects after all the fundamental types are defined. *
* *
* Created by: David Rosenfeld *
* Date: 04/09/97 *
*****************************************************************************/
#include <stdlib.h>
#include "classes.h"
#define FALSE 0
#define TRUE 1
int isAggregateType( const Type t );
/* Local function prototypes: */
static void initializeMarks( Express );
static void unsetObjs( Schema );
static int checkTypes( Schema );
static int checkEnts( Schema );
static void markDescs( Entity );
static int checkItem( Type, Scope, Schema, int *, int );
static int ENUMcanBeProcessed( Type, Schema );
static int inSchema( Scope, Scope );
static void addRenameTypedefs( Schema, FILE * );
static void addAggrTypedefs( Schema , FILE * );
static void addUseRefNames( Schema, FILE * );
void print_schemas_separate( Express express, void * complexCol, FILES * files )
/*
* Generates the C++ files corresponding to a list of schemas. Does so in
* multiple passes through the schemas. In each pass it checks for enti-
* ties which are subtypes of entites in other schemas which have not yet
* been processed. Such entities cannot be processed in that pass until
* their supertypes have been defined. It also checks for entities which
* have enum or select attributes which have not been processed, and for
* select types which have enum or select items (or entities containing
* enums) which have not been processed.
*/
{
int complete = FALSE, val1, val2, suffix;
DictionaryEntry de;
Schema schema;
/* First set all marks we'll be using to UNPROCESSED/NOTKNOWN: */
initializeMarks( express );
//FIXME SdaiAll.cc:12:24: warning: unused variable ‘is’ [-Wunused-variable] (also for ui & ri)
//fprintf( files->create, " Interface_spec_ptr is;\n Used_item_ptr ui;\n Referenced_item_ptr ri;\n Uniqueness_rule_ptr ur;\n Where_rule_ptr wr;\n Global_rule_ptr gr;\n" );
while( !complete ) {
complete = TRUE;
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
if( schema->search_id == UNPROCESSED ) {
/* i.e., if the schema has more ents/types to process in it */
unsetObjs( schema );
/* Unset the ones which had search_id = CANTPROCESS. We're
// going to check that again since things may have changed by
// this pass. The ones with search_id = PROCESSED do not
// change since we're done with them. */
schema->search_id = PROCESSED;
/* We assume this is the case unless something goes wrong. */
val1 = checkTypes( schema );
val2 = checkEnts( schema );
/* The check functions recheck all the ents, types, USEd, and
// REFs which are still NOTKNOWN to see if we can process any
// more this pass. If any returns TRUE, we'll process again
// this round. */
if( val1 || val2 ) {
if( schema->search_id == UNPROCESSED ||
*( int * )schema->clientData > 0 ) {
/* What we're trying to determine here is if we will
// need to print multiple files for this schema. If
// we're already beyond a first file (2nd condition)
// or we're at the first but there are more entities
// which couldn't be processed yet (and thus search_id
// was still set to UNPROCESSED), this schema will be
// printed in multiple files. If so, SCHEMAprint()
// will create files with the suffixes "_1", "_2", etc.
// If not, no file suffix will be added. */
suffix = ++*( int * )schema->clientData;
SCHEMAprint( schema, files, express, complexCol,
suffix );
} else {
SCHEMAprint( schema, files, express, complexCol, 0 );
}
}
complete = complete && ( schema->search_id == PROCESSED );
/* Job's not complete so long as schema still has entities it
// had to skip. */
}
}
}
/*******************
*******************/
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
//fprintf( files->create,
// "\t//////////////// USE statements\n" );
//USEREFout( schema, schema->u.schema->usedict, schema->u.schema->use_schemas, "USE", files->create );
//fprintf( files->create,
// "\t//////////////// REFERENCE statements\n" );
//USEREFout( schema, schema->u.schema->refdict, schema->u.schema->ref_schemas, "REFERENCE", files->create );
}
/*****************
*****************/
/* Before closing, we have three more situations to deal with (i.e., three
// types of declarations etc. which could only be printed at the end).
// Each is explained in the header section of its respective function. */
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
/* (These two tasks are totally unrelated but are done in the same loop
// for efficiency.) */
addRenameTypedefs( schema, files->classes );
addUseRefNames( schema, files->create );
}
/* Third situation: (Must be dealt with after first, see header comments
// of addAggrTypedefs.) */
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
addAggrTypedefs( schema, files->classes );
}
/* On our way out, print the necessary statements to add support for
// complex entities. (The 1st line below is a part of SchemaInit(),
// which hasn't been closed yet. (That's done on 2nd line below.)) */
//fprintf( files->initall, "\t reg.SetCompCollect( gencomplex() );\n" );
//fprintf( files->initall, "}\n\n" );
//fprintf( files->incall, "\n#include <complexSupport.h>\n" );
//fprintf( files->incall, "ComplexCollect *gencomplex();\n" );
/* Function GetModelContents() is printed at the end of the schema.xx
// files. This is done in a separate loop through the schemas, in function
// below. */
//getMCPrint( express, files->incall, files->initall );
}
static void initializeMarks( Express express )
/*
* Set all schema->search_id's to UNPROCESSED, meaning we haven't processed
* all the ents and types in it yet. Also, put an int=0 in each schema's
* clientData field. We'll use it to record what # file we're generating
* for each schema. Set all entity and type search_id's to NOTKNOWN mean-
* we don't know if we can process it yet. (An ent & select type may have
* an attribute/item which comes from another schema. All other types can
* be processed the first time, but that will be caught in checkTypes().)
*/
{
DictionaryEntry de_sch, de_ent, de_type;
Schema schema;
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
schema->search_id = UNPROCESSED;
schema->clientData = ( int * )malloc( sizeof( int ) );
*( int * )schema->clientData = 0;
SCOPEdo_entities( schema, ent, de_ent )
ent->search_id = NOTKNOWN;
SCOPEod
SCOPEdo_types( schema, t, de_type )
t->search_id = NOTKNOWN;
SCOPEod
}
}
static void unsetObjs( Schema schema )
/*
* Resets all the ents & types of schema which had been set to CANTPROCRSS
* to NOTKNOWN. This function is called every time print_schemas_separate
* iterates through the schemas, printing to file what can be printed. At
* each pass we re-examine what ents/types can be processed. Ones which
* couldn't be processed at the last pass may be processable now. Ents/
* types which have already been marked PROCESSED will not have to be
* revisited, and are not changed.
*/
{
DictionaryEntry de;
SCOPEdo_types( schema, t, de )
if( t->search_id == CANTPROCESS ) {
t->search_id = NOTKNOWN;
}
SCOPEod
SCOPEdo_entities( schema, ent, de )
if( ent->search_id == CANTPROCESS ) {
ent->search_id = NOTKNOWN;
}
SCOPEod
}
static int checkTypes( Schema schema )
/*
* Goes through the types contained in this schema checking for ones which
* can't be processed. This may be the case if: (1) We have a select type
* which has enumeration or select items which have not yet been defined
* (are defined in a different schema we haven't processed yet). (2) We
* have a select which has an entity item which contains unprocessed enums.
* (Unproc'ed selects, however, do not pose a problem here for reasons
* beyond the scope.) (3) We have an enum type which is a redefinition of
* an enum not yet defined. If we find any such type, we set its mark to
* CANTPROCESS. If some types in schema *can* be processed now, we return
* TRUE. (See relevant header comments of checkEnts() below.)
*/
{
DictionaryEntry de;
int retval = FALSE, unknowncnt;
Type i;
Entity ent;
Linked_List attribs;
do {
unknowncnt = 0;
SCOPEdo_types( schema, type, de )
if( type->search_id != NOTKNOWN ) {
continue;
}
/* We're only interested in the ones which haven't been processed
// already or accepted (set to CANPROCESS in a previous pass thru
// the do loop) already. */
type->search_id = CANPROCESS;
/* Assume this until disproven. */
if( TYPEis_enumeration( type ) && TYPEget_head( type ) ) {
i = TYPEget_ancestor( type );
if( !sameSchema( i, type ) && i->search_id != PROCESSED ) {
/* Note - if, however, i is in same schema, we're safe: We
// know it'll be processed this pass because enum's are
// always processed on the first pass. (We do have to take
// care to process the original enum before the redefined.
// This is done in SCOPEPrint, in classes_wrapper.cc.) */
type->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
}
} else if( TYPEis_select( type ) ) {
LISTdo( SEL_TYPEget_items( type ), i, Type )
if( !TYPEis_entity( i ) ) {
if( checkItem( i, type, schema, &unknowncnt, 0 ) ) {
break;
}
/* checkItem does most of the work of determining if
// an item of a select will make the select type un-
// processable. It checks for conditions which would
// make this true and sets values in type, schema, and
// unknowncnt accordingly. (See checkItem's commenting
// below.) It also return TRUE if i has made type un-
// processable. If so, we break - there's no point
// checking the other items of type any more. */
} else {
/* Check if our select has an entity item which itself
// has unprocessed selects or enums. */
ent = ENT_TYPEget_entity( i );
if( ent->search_id == PROCESSED ) {
continue;
}
/* If entity has been processed already, things must be
// okay. (Note - but if it hasn't been processed yet we
// may still be able to process type. This is because
// a sel type will only contain a pointer to an entity-
// item (and we can create a pointer to a not-yet-pro-
// cessed object), while it will contain actual objects
// for the enum and select attributes of ent.) */
attribs = ENTITYget_all_attributes( ent );
LISTdo( attribs, attr, Variable )
if( checkItem( attr->type, type, schema,
&unknowncnt, 1 ) ) {
break;
}
LISTod
LISTfree( attribs );
}
LISTod
/* One more condition - if we're a select which is a rename of
// another select - we must also make sure the original select
// is in this schema or has been processed. Since a rename-
// select is defined with typedef's to the original, we can't
// do that if the original hasn't been defined. */
if( ( type->search_id == CANPROCESS )
&& ( ( i = TYPEget_ancestor( type ) ) != NULL )
&& ( !sameSchema( i, type ) )
&& ( i->search_id != PROCESSED ) ) {
type->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
}
}
if( type->search_id == CANPROCESS ) {
/* NOTE - This condition will be met if type isn't a select or
// enum at all and above if was never entered (and it's our
// first pass so type hasn't been processed). So for non-enums
// and selects, checkTypes() will simply check the type off and
// go on. */
retval = TRUE;
}
SCOPEod
} while( unknowncnt > 0 );
/* We loop to deal with the following situation: Say sel A contains enum B
// as an item, but A appears earlier in the EXPRESS file than B. In such a
// case, we really can process A now since it doesn't depend on anything
// which won't be processed till later. But when we first reach A, item B
// will have value NOTKNOWN, and at the time we won't know if B will be set
// to CANPROCESS when we get to it. To deal with this, checkItem() below
// increments unknowncnt for every item which is in this schema and still
// has search_id = NOTKNOWN. (Not if id = CANTPROCESS, which means we've
// tried already this pass and B still can't be processed.) Here, we keep
// looping until all the unknowns are resolved. (It may take may passes if
// selX has item selY which has item selZ.) (I take all the trouble with
// this so as not to generate mult files in unnecessary cases where e.g.
// the EXPRESS is in a single schema.) */
return retval;
}
static int checkEnts( Schema schema )
/*
* Goes through the entities contained in this schema checking for ones
* which can't be processed. It checks for two situations: (1) If we find
* an entity which is a subtype of a not-yet-processed entity in another
* schema. (2) If an entity has an attribute which is an enumeration or
* select type (which is implemented by fedex_plus as a C++ class), and the
* enum or select class has not yet been defined. For each entity which
* satisfies one of the above conditions, we set its mark and the marks of
* all its subtype descendents to CANTPROCESS. Later, when C++ files are
* generated for this schema, the ents marked CANTPROCESS will be skipped.
* checkEnts() will return TRUE if there are some ents/types which *can* be
* processed now. This will tell later functions that there are some pro-
* cessable entities at this pass and C++ files should be generated. (Some
* of the inline commenting of checkTypes() is applicable here and is not
* repeated.)
*/
{
DictionaryEntry de;
int retval = FALSE, ignore = 0;
/* Loop through schema's entities: */
SCOPEdo_entities( schema, ent, de )
if( ent->search_id != NOTKNOWN ) {
continue;
}
/* ent->search_id may = CANTPROCESS signifying we've already determined
// that this ent is dependent on an undefined external one. (It got
// its mark already because it was the descendent of a parent entity we
// already checked and rejected.) ent->search_id may = PROCESSED. In
// such a case there of course is also nothing to check now. */
ent->search_id = CANPROCESS;
/* First traverse ent's supertypes. If any is from a different schema
// and is not yet defined, ent will have to wait. */
LISTdo( ENTITYget_supertypes( ent ), super, Entity )
if( ( !sameSchema( ent, super ) )
&& ( super->search_id != PROCESSED ) ) {
markDescs( ent );
schema->search_id = UNPROCESSED;
break;
/* Exit the LISTdo loop. Since we found an unprocessed
// parent, we're done with this entity. */
}
LISTod
/* Next traverse ent's attributes, looking for attributes which are
// not yet defined (more explanation in checkItem()). */
if( ent->search_id == CANPROCESS ) {
/* Only do next test if ent hasn't already failed the 1st. */
LISTdo( ENTITYget_attributes( ent ), attr, Variable )
if( checkItem( attr->type, ent, schema, &ignore, 0 ) ) {
markDescs( ent );
break;
}
LISTod
}
if( ent->search_id == CANPROCESS ) {
/* If ent's mark still = CANPROCESS and not CANTPROCESS, it
// must still be processable. Set retval to TRUE signifying
// that there are ent's we'll be able to process. */
retval = TRUE;
}
SCOPEod
/* NOTE - We don't have to loop here as in checkTypes() (see long comment
// there). It was necessary there because we may have processed type
// sel1 before its member enum1. Whereas here, since all types are done
// before selects (checkTypes() is called before checkEnts()), there is
// no such concern. */
return retval;
}
static void markDescs( Entity ent )
/*
* Sets the mark value of ent and all its subtypes to CANTPROCESS. This
* function is called if we've determined that ent is a subtype of an
* entity defined in a different schema which has not yet been processed.
*/
{
ent->search_id = CANTPROCESS;
LISTdo( ENTITYget_subtypes( ent ), sub, Entity )
markDescs( sub );
LISTod
}
static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt,
int noSel )
/*
* Function with a lot of side effects: Checks if type t, a member of
* `parent' makes parent unprocessable. parent may be an entity and t is
* its attribute. parent may be a select type and t is one of its items.
* parent may be a select type and t an attribute of one of its entity
* items. Lastly, parent may be an aggregate and t its base type. t will
* make parent unprocessable if it is an enum or sel which hasn't been
* processed yet, see inline commenting. If so, parent->search_id is set
* to CANTPROCESS, and schema->search_id is set to UNPROCESSED (i.e., we're
* not done yet). Also, if one of parent's items is still NOTKNOWN (caused
* if it's in our schema and we haven't gotten to it yet - see comment, end
* of checkTypes()), parent is set to NOTKNOWN and unknowncnt is incremen-
* ted to tell us that we'll have to try parent again after its item has
* been processed (i.e., we have to repeat the do-loop in checkTypes()).
* checkItem returns TRUE if parent became unprocessable; FALSE otherwise.
*
* NOTE: noSel deals with the following: Say selA has member entX. If
* entX has attribute enumP, it creates a problem, while if entX has attr
* selB, it is not. When using checkItem for an ent member of a select,
* noSel is set to 1 to tell it to worry about t if it's an enum but not
* if it's a select.
*/
{
Type i = t;
if( isAggregateType( t ) ) {
i = TYPEget_base_type( t );
/* NOTE - If t is a 2D aggregate or higher, we do not go down to its
// lowest base type. An item which is a higher dimension aggregates
// does not make its parent unprocessable. All an e.g. entity needs
// defined to have a 2D aggr attribute is GenericAggregate (built in)
// and a typedef for a pointer to the type name, which is declared in
// Sdaiclasses.h. */
}
if( TYPEis_enumeration( i ) && !ENUMcanBeProcessed( i, schema ) ) {
/* Enum's are usually processed on the first try. ENUMcanBeProcessed()
// checks for cases of renamed enum's, which must wait for the enum i
// is a rename of. */
if( parent->search_id == NOTKNOWN ) {
/* We had thought parent's val was going to be NOTKNOWN - i.e.,
// dependent on other selects in this schema which haven't been
// processed. When we set it to NOTKNOWN we also incremented
// unknowncnt. Now we see it's not going to be unknown so we
// decrement the count: */
( *unknowncnt )--;
}
parent->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
return TRUE;
} else if( TYPEis_select( i ) && !noSel ) {
if( !sameSchema( i, parent ) ) {
if( i->search_id != PROCESSED ) {
if( parent->search_id == NOTKNOWN ) {
( *unknowncnt )--;
}
parent->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
return TRUE;
}
} else {
/* We have another sel in the same schema. This gets complicated -
// it may be processable but we just haven't gotten to it yet. So
// we may have to wait on parent. */
if( i->search_id == CANTPROCESS ) {
/* We *have* checked i already and it can't be processed. */
if( parent->search_id == NOTKNOWN ) {
( *unknowncnt )--;
}
parent->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
return TRUE;
} else if( i->search_id == NOTKNOWN ) {
/* We haven't processed i this pass. */
if( parent->search_id != NOTKNOWN ) {
parent->search_id = NOTKNOWN;
/* We lower parent's value. But don't return TRUE. That
// would tell checkTypes() that there's nothing more to
// check. But checkTypes should keep looping thru the re-
// maining items of parent - maybe one of them will tell us
// that parent definitely can't be processed this pass. */
( *unknowncnt )++;
}
}
}
}
return FALSE;
}
static int ENUMcanBeProcessed( Type e, Schema s )
/*
* Tells us if an enumeration type has been processed already, or if not
* will be processed this pass through schema s. As always, I take great
* pains to avoid breaking up a schema into >1 file unnecessarily. In
* cases where a user is building a library based on a single schema, we
* shouldn't cause him to suffer side-effects of the mult schema support,
* because of a case that "looks like" it may require multiple files.
*/
{
Type a;
if( !inSchema( e, s ) ) {
/* If e is not in s - the schema we're processing now - things are
// fairly simple. Nothing is going to change by the time we finish
// with this schema. Base the return val on whether or not e *was*
// processed already. */
return ( e->search_id == PROCESSED );
}
if( e->search_id != NOTKNOWN ) {
/* Next case: e is in our schema, but either it's been processed
// already, or we've determined that it can or can't be processed.
// This case is also relatively simple - we have nothing more to
// figure out here. */
return ( e->search_id >= CANPROCESS );
/* PROC/CANPROC - TRUE; UNPROC'ED/CANTPROC - FALSE */
}
/* Remaining case: e is in our schema and still = NOTKNOWN. I.e., we
// haven't gotten to e this pass and don't yet know whether it'll be
// processable. Figure that out now: */
if( ( a = TYPEget_ancestor( e ) ) == NULL ) {
/* If e is not a rename of anything, it should be processed now. */
return TRUE;
}
if( inSchema( a, s ) || a->search_id == PROCESSED ) {
/* If e's ancestor (the one it's a rename of) is in our schema it will
// be processed now. If not, it must have been processed already. */
return TRUE;
}
return FALSE;
}
int sameSchema( Scope sc1, Scope sc2 )
/*
* Checks if sc1 and sc2 are in the same superscope. Normally called for
* two types to see if they're in the same schema.
*/
{
return ( !strcmp( SCOPEget_name( sc1->superscope ),
SCOPEget_name( sc2->superscope ) ) );
}
static int inSchema( Scope scope, Scope super )
/*
* Checks if scope is contained in super's scope.
*/
{
return ( !strcmp( SCOPEget_name( scope->superscope ),
SCOPEget_name( super ) ) );
}
static void addRenameTypedefs( Schema schema, FILE * classes )
/*
* Prints typedefs at the end of Sdaiclasses.h for enumeration or select
* types which are renamed from other enum/sel's. Since the original e/s
* may be in any schema, this must be done at the end of all the schemas.
* (Actually, for the enum only the aggregate class name is written in
* Sdaiclasses.h (needs to have forward declarations here).)
*/
{
DictionaryEntry de;
Type i;
char nm[BUFSIZ], basenm[BUFSIZ];
static int firsttime = TRUE;
SCOPEdo_types( schema, t, de )
if( ( TYPEis_enumeration( t ) || TYPEis_select( t ) )
&& ( ( i = TYPEget_ancestor( t ) ) != NULL ) ) {
/* I.e., t is a renamed enum/sel type. i is set to the orig enum/
// sel t is based on (in case it's a rename of a rename etc). */
if( firsttime ) {
printf( "\n// Renamed enum and select\n" );
//printf( " types (from all schemas):\n" );
firsttime = FALSE;
}
if( TYPEis_enumeration( t ) ) {
strncpy( nm, TYPEget_ctype( t ), BUFSIZ - 1 );
strncpy( basenm, TYPEget_ctype( i ), BUFSIZ - 1 );
//fprintf( classes, "typedef %ss\t%ss;\n", basenm, nm );
} else {
strncpy( nm, SelectName( TYPEget_name( t ) ), BUFSIZ - 1 );
strncpy( basenm, SelectName( TYPEget_name( i ) ), BUFSIZ - 1 );
printf( "typedef %s %s;\n", basenm, nm );
//fprintf( "typedef %s * %s_ptr;\n", nm, nm );
//fprintf( classes, "typedef %ss %ss;\n", basenm, nm );
//fprintf( classes, "typedef %ss * %ss_ptr;\n", nm, nm );
}
}
SCOPEod
}
static void addAggrTypedefs( Schema schema, FILE * classes )
/*
* Print typedefs at the end of Sdiaclasses.h for aggregates of enum's and
* selects. Since the underlying enum/sel may appear in any schema, this
* must be done at the end of all the schemas. Note that this function is
* called after addRenameTypedefs() since an aggregate may also be based on
* one of the renamed enum/sel's defined there.
*/
{
DictionaryEntry de;
Type i;
static int firsttime = TRUE;
char nm[BUFSIZ];
SCOPEdo_types( schema, t, de )
if( TYPEis_aggregate( t ) ) {
i = TYPEget_base_type( t );
if( TYPEis_enumeration( i ) || TYPEis_select( i ) ) {
/* This if will pass if t was a 1D aggregate only. They are
// the only types which had to wait for their underlying type.
// 2D aggr's and higher only need type GenericAggr defined
// which is built-in. */
if( firsttime ) {
fprintf( classes, "\n// Aggregate types (from all sche" );
fprintf( classes, "mas) which depend on other types:\n" );
firsttime = FALSE;
}
strncpy( nm, ClassName( TYPEget_name( t ) ), BUFSIZ );
fprintf( classes, "typedef %s\t%s;\n",
TYPEget_ctype( t ), nm );
fprintf( classes, "typedef %s *\t%sH;\n", nm, nm );
fprintf( classes, "typedef %s *\t%s_ptr;\n", nm, nm );
}
}
SCOPEod
}
static void addUseRefNames( Schema schema, FILE * create )
/*
* Checks the USE and REFERENCE dicts contained in schema. If either dict
* contains items (types or entities) which are renamed in this schema,
* code is written to add another member to the "altNames" list of the
* corresponding TypeDescriptor or EntityDescriptor object in the SCL. The
* list will be used in the SCL to use the correct name of this type or
* entity when reading and writing files.
*/
{
Dictionary useRefDict;
DictionaryEntry de;
Rename * rnm;
char * oldnm, schNm[BUFSIZ];
static int firsttime = TRUE;
if( ( useRefDict = schema->u.schema->usedict ) != NULL ) {
DICTdo_init( useRefDict, &de );
while( ( rnm = ( Rename * )DICTdo( &de ) ) != 0 ) {
oldnm = ( ( Scope )rnm->object )->symbol.name;
if( ( strcmp( oldnm, rnm->nnew->name ) ) ) {
/* strcmp != 0, so old and new names different.
// Note: can't just check if nnew != old. That wouldn't
// catch following: schema C USEs obj Y from schema B
// (not renamed). B USEd it from schema A and renamed it
// from X. nnew would = old, but name would not be same
// as rnm->object's name. */
if( firsttime ) {
fprintf( create, "\t// Alternate names for types and " );
fprintf( create, "entities when used in other schemas:\n" );
firsttime = FALSE;
}
if( rnm->type == OBJ_TYPE ) {
fprintf( create, "\t%s", TYPEtd_name( ( Type )rnm->object ) );
} else {
/* must be an entity */
fprintf( create, "\t%s%s%s",
SCOPEget_name( ( ( Entity )rnm->object )->superscope ),
ENT_PREFIX, ENTITYget_name( ( Entity )rnm->object ) );
}
strcpy( schNm, PrettyTmpName( SCHEMAget_name( schema ) ) );
fprintf( create, "->addAltName( \"%s\", \"%s\" );\n",
schNm, PrettyTmpName( rnm->nnew->name ) );
}
}
}
if( ( useRefDict = schema->u.schema->refdict ) != NULL ) {
DICTdo_init( useRefDict, &de );
while( ( rnm = ( Rename * )DICTdo( &de ) ) != 0 ) {
oldnm = ( ( Scope )rnm->object )->symbol.name;
if( ( strcmp( oldnm, rnm->nnew->name ) ) ) {
if( firsttime ) {
fprintf( create, "\t// Alternate names for types and " );
fprintf( create, "entities when used in other schemas:\n" );
firsttime = FALSE;
}
if( rnm->type == OBJ_TYPE ) {
fprintf( create, "\t%s", TYPEtd_name( ( Type )rnm->object ) );
} else {
fprintf( create, "\t%s%s%s",
SCOPEget_name( ( ( Entity )rnm->object )->superscope ),
ENT_PREFIX, ENTITYget_name( ( Entity )rnm->object ) );
}
strcpy( schNm, PrettyTmpName( SCHEMAget_name( schema ) ) );
fprintf( create, "->addAltName( \"%s\", \"%s\" );\n",
schNm, PrettyTmpName( rnm->nnew->name ) );
}
}
}
}
File diff suppressed because it is too large Load Diff