Compare commits

...
120 Commits
Author SHA1 Message Date
Mark 953021ec9d Merge pull request #303 from stepcode/review/inverse-attributes
inverse attributes...finally!
2014-12-26 15:12:05 -05:00
Mark Pictor c8f14a0821 bump version (0.8), update AUTHORS, NEWS for v0.8, add travis-ci build status to README 2014-12-26 15:10:00 -05:00
Mark 63049515d1 Merge pull request #300 from cshorler/python_properties_and_assert
Python properties and assert
2014-12-26 14:29:32 -05:00
Mark ca7487fa95 Merge pull request #299 from cshorler/investigate_ply_usage
Investigate Ply usage
2014-12-26 14:28:49 -05:00
Mark Pictor 0f5179e74b oops, forgot an include 2014-12-26 13:51:09 -05:00
Mark Pictor bfbd8df61e minor cleanup 2014-12-26 13:34:38 -05:00
Mark Pictor dfe69a923d bug in superInvAttrIter allowed null pointer return for ia 2014-12-26 13:34:38 -05:00
Mark Pictor 50452e8282 fix inv attr code in SDAI_Application_instance 2014-12-26 13:34:38 -05:00
Mark Pictor e74d4dc813 fix inverse attr initialization; attr was being found but it wasn't exiting the loop 2014-12-26 13:34:38 -05:00
Mark Pictor 653625f56a fix crash with lazy loading and unexpected newlines, found in cd209 files 2014-12-26 13:34:38 -05:00
Mark Pictor 5f702fb702 fix dumpComplexInst func, stupid mistake - was using wrong data member 2014-12-26 13:34:38 -05:00
Mark Pictor 8273ce1866 lazyRefs works now 2014-12-26 13:34:38 -05:00
Mark Pictor efb82853b7 don't print code for inverse data members, they're in iAMap now 2014-12-26 13:34:37 -05:00
Mark Pictor 37901afbbb redo attribute numbering, print inverse attr access members separately 2014-12-26 13:34:37 -05:00
Mark Pictor 6bac26d3c7 add index to struct Variable_, fix some whitespace 2014-12-26 13:34:37 -05:00
Mark Pictor ff3fd1f5e7 _complex is now bool, not int - update STEPcomplex ctors 2014-12-26 13:34:37 -05:00
Mark Pictor 9313b8e6ee move some attr-specific stuff from classes_entity to classes_attribute, also minor cleanup 2014-12-26 13:34:37 -05:00
Mark Pictor 921de860b0 closer... 2014-12-26 13:34:28 -05:00
Mark Pictor 5df2f69930 inching forward on inverse attrs 2014-12-26 13:32:24 -05:00
Mark Pictor 31bf315543 const correctness in superInvAttrIter 2014-12-26 13:32:24 -05:00
Mark Pictor 87c66bb4dc flesh out InitIAttrs() in eDesc, instance 2014-12-26 13:32:23 -05:00
Mark Pictor c91109b7b4 add functions to access schema class members 2014-12-26 13:32:23 -05:00
Mark Pictor febbb636fc allow const or non-const for ed iter 2014-12-26 13:32:23 -05:00
Mark Pictor 7976c8bee5 loop through ed's with inverse attrs, connecting them to what they point at 2014-12-26 13:32:23 -05:00
Mark Pictor 0b42b2fe89 oops, move eDesc initialization back into SdaiAll
otherwise, they may be initialized after being ref'd in attrDescs
2014-12-26 13:32:23 -05:00
Mark Pictor d36d12c6d3 fix failing schema 2014-12-26 13:32:23 -05:00
Mark Pictor 86bbc327fa cleanup 2014-12-26 13:32:23 -05:00
Mark Pictor c8cfac3acc some types still print in SdaiAll 2014-12-26 13:32:23 -05:00
Mark Pictor 9efd75ebc1 add some small schemas and a .p21; should be examined, maybe moved/simplified 2014-12-26 13:32:23 -05:00
Mark Pictor 98283dca34 more work on inverse attrs, code generation 2014-12-26 13:31:21 -05:00
Mark Pictor 65c703b811 work on inverse attrs 2014-12-26 13:29:08 -05:00
Mark Pictor 2374029ae8 cleanup 2014-12-26 13:29:08 -05:00
Mark Pictor c6d841789e initialize entity iAttrs using eDesc 2014-12-26 13:29:08 -05:00
Mark Pictor 14689c6db6 split ENTITYprint_new() into two, print into different files
* split into ENTITYprint_descriptors(), ENTITYprint_classes()
  * the former is now called from ENTITYprint_cc()
* make some changes to the args (don't pass ComplexCollect, just a bool)
2014-12-26 13:29:08 -05:00
Mark Pictor 01db3788a2 silence a signed-unsigned warning by using size_t 2014-12-26 13:29:07 -05:00
Mark Pictor 712d9657e8 improve comments, whitespace 2014-12-26 13:29:07 -05:00
Mark Pictor 168e7a93ed split up a 32-line fprintf 2014-12-26 13:29:07 -05:00
Mark Pictor 7ae34348be indents in generated code 2014-12-26 13:29:07 -05:00
Mark Pictor 1e95f8f61e remove LIBcopy_constructor() - unused since 1992(!) 2014-12-26 13:29:07 -05:00
Mark Pictor 4df86e5fea schema name changed for some p21 tests - update it 2014-12-26 13:29:07 -05:00
Mark Pictor 78427423ab redo some comments 2014-12-26 13:29:07 -05:00
Mark Pictor c2c0a6443b reformat some error message code, add one message for complex insts 2014-12-26 13:29:07 -05:00
Mark Pictor 674fa941f6 delete the array of names after creating a STEPcomplex 2014-12-26 13:29:07 -05:00
Mark Pictor 9db1170803 improve some comments in lazy loading code 2014-12-26 13:29:07 -05:00
Mark Pictor 7089bdbf5c when loading instance dependencies, seek to original position afterwards
otherwise, SDAI_Application_instance::STEPRead() will crash and burn when the file position changes on it
2014-12-26 13:29:07 -05:00
Mark Pictor 409315841b fix test dependency so 'make test ARGS=-jN' works 2014-12-26 13:29:07 -05:00
Mark Pictor 4bde538c65 add comment with express that fails 2014-12-26 13:28:54 -05:00
Mark Pictor 6955a03fca check for both aggr and non-aggr inverse attributes 2014-12-26 13:28:54 -05:00
Mark Pictor b31ffa3968 more changes to attrIsObj() 2014-12-26 13:28:22 -05:00
Mark Pictor 06bfc7d4d1 handle both aggr and non-aggr inverses 2014-12-26 13:28:21 -05:00
Mark Pictor 73b3c1b901 fix assertion - can either be aggregate or instance 2014-12-26 13:28:21 -05:00
Mark Pictor 66deaafb30 change behavior of attrIsObj() fn in classes_attribute 2014-12-26 13:27:02 -05:00
Mark Pictor 9e1d078b46 add 2 protos to classes_attribute header 2014-12-26 13:27:02 -05:00
Mark Pictor 31331651df modify const-ness in AGGRprint_access_methods 2014-12-26 13:27:02 -05:00
Mark Pictor 6117e532f8 move much of ATTRprint_access_methods into a series of smaller funcs 2014-12-26 13:27:02 -05:00
Mark Pictor b9db4568fe CONST -> const in a few more places 2014-12-26 13:27:02 -05:00
Mark Pictor ea24200c67 make STEPinvAttrList work with the new setter/getter variants 2014-12-26 13:27:02 -05:00
Mark Pictor acdc338c9d static setter/getter won't always have the same signature
detect whether to use sdaiApplicationInstance or EntityAggregate
2014-12-26 13:27:02 -05:00
Mark Pictor 9cf54cf374 add attrIsObj(), which returns true if const and non-const methods are sensible for a given var 2014-12-26 13:27:02 -05:00
Mark Pictor ea339e2ffa exp2cxx: move select getters into own function, print const and non-const 2014-12-26 13:27:01 -05:00
Mark Pictor 14d7b32320 remove duplicate function prototypes that masked a signature change 2014-12-26 13:27:01 -05:00
Mark Pictor 62ef3c6edd add const getter for string/bin attr's 2014-12-26 13:27:01 -05:00
Mark Pictor 521a999af9 change const getter for entity attr's 2014-12-26 13:27:01 -05:00
Mark Pictor 47d42ad558 invert sense of test in logging code - wouldn't print unless null 2014-12-26 13:27:01 -05:00
Mark Pictor f63835532b move string/binary access methods into 2 small funcs 2014-12-26 13:27:01 -05:00
Mark Pictor cd08570a3f print const and non-const getters for select attrs 2014-12-26 13:27:01 -05:00
Mark Pictor 4a01038cd0 fix a couple comments 2014-12-26 13:27:01 -05:00
Mark Pictor 3132089419 note that unity headers are probably useless since the main schema header includes all of the headers 2014-12-26 13:27:01 -05:00
Mark Pictor 5c0bea384c add braces and indenting to two LISTdo..LISTod's 2014-12-26 13:27:01 -05:00
Mark Pictor d64bbc3611 move count var so that derived attrs are counted
otherwise, the attr numbers in the ctor will be off by the number of preceding derived attrs
2014-12-26 13:27:01 -05:00
Mark Pictor 236778a5fc generated code: also print a const getter in class header when attr is a pointer type 2014-12-26 13:27:01 -05:00
Mark Pictor d6bb20d81b use instMgrBase in SDAI_Select operator test 2014-12-26 13:27:00 -05:00
Mark Pictor 6cb750a3eb don't print const for getter 2014-12-26 13:27:00 -05:00
Mark Pictor 118d8b295b merge with instMgrBase commit 2014-12-26 13:27:00 -05:00
Mark Pictor 64dd1d2a9a two libstructor_print calls missing neededAttr param 2014-12-26 13:27:00 -05:00
Mark Pictor 2ae605d5ae rename var - 'class' may not be a C keyword, but it's confusing 2014-12-26 13:27:00 -05:00
Mark Pictor 23a5a62397 formatting 2014-12-26 13:27:00 -05:00
Mark Pictor aaa1ca04a6 fix a few comments 2014-12-26 13:27:00 -05:00
Mark Pictor d4f13e0179 replace entity access member code with call to new func 2014-12-26 13:27:00 -05:00
Mark Pictor 800453e68a split entity methods out of ATTRprint_access_methods into 2 new funcs
second new func prints log stuff, called by other func 3x
2014-12-26 13:27:00 -05:00
Mark Pictor a74dc1d32c forgot to add 'const' keyword in several places after changing the ..._get_head() fn 2014-12-26 13:27:00 -05:00
Mark Pictor d9c89b9e94 when printing initializers, skip derived attrs 2014-12-26 13:27:00 -05:00
Mark Pictor fdcdd5a966 forgot to replace InstMgr with InstMgrBase in selects.c 2014-12-26 13:26:59 -05:00
Mark Pictor 7222c91c01 update inverse attr test 3 2014-12-26 13:26:59 -05:00
Mark Pictor 51acb993da whoops, don't pretend an instance can't be found if it is already loaded 2014-12-26 13:26:59 -05:00
Mark Pictor ebb7a920f2 use InstMgrBase instead of InstMgr in most stepcore classes
this is so that lazyInstMgr functions will be called when necessary
2014-12-26 13:26:59 -05:00
Mark Pictor f6078d8b5b eliminate unused buffer 2014-12-26 13:26:59 -05:00
Mark Pictor 4b3e433667 in generated c++: create data members for null pointers 2014-12-26 13:26:59 -05:00
Mark Pictor 1fddd17a64 in generated c++: ensure pointer is non-null before calling shallowCopy 2014-12-26 13:26:59 -05:00
Mark Pictor 647ecbcf99 in generated c++: ensure that pointers are zeroed (DataMemberInitializers()) 2014-12-26 13:26:59 -05:00
Mark Pictor ef2c01d76c in generated c++: in constructors, populate iAttrs
is populated with inverse attrs, setters, getters
2014-12-26 13:26:59 -05:00
Mark Pictor e17938afe8 generated c++: static setter/getter for inverse attrs 2014-12-26 13:26:59 -05:00
Mark Pictor d5f693a862 use STEPinvAttrList in sdaiApplication_Instance 2014-12-26 13:26:59 -05:00
Mark Pictor bd402b2567 add STEPinvAttrList for inv attr descs and setter/getter pointers
this will allow access to inverse attr values even with late binding, and is necessary to
set these attr values when the instances are being loaded
2014-12-26 13:26:59 -05:00
Mark Pictor ca560239ce use lazyRefs in lazyInstMgr 2014-12-26 13:26:55 -05:00
Mark Pictor b3b464632b trivial changes 2014-12-26 13:24:59 -05:00
Mark Pictor 0188910a3a add lazyRefs.h 2014-12-26 13:24:59 -05:00
Mark Pictor 35ead380af include subsuperiterators header 2014-12-26 13:24:59 -05:00
Mark Pictor b1387b731e improve comments, a few other small changes that don't affect behavior 2014-12-26 13:24:56 -05:00
Mark Pictor d1062cddfa use lazyInstMgr for inverse_attr3.cc 2014-12-26 13:21:52 -05:00
Mark Pictor 6e636d1c20 add variable names to some prototypes in ErrorDescriptor header 2014-12-26 13:21:52 -05:00
Mark Pictor f3cd328b24 add a FIXME 2014-12-26 13:21:52 -05:00
Mark Pictor 7867505fdc macro CONST -> const 2014-12-26 13:21:52 -05:00
Mark Pictor 57d3d2fe07 improve some comments for doxygen 2014-12-26 13:21:52 -05:00
Mark Pictor 259750e31e split a big fprintf up for readability 2014-12-26 13:21:52 -05:00
Mark Pictor 9144443d69 doxify comments in classes_misc.c 2014-12-26 13:21:52 -05:00
Mark Pictor 6004ba458b remove outdated comment from inverse_attr2.cc 2014-12-26 13:21:52 -05:00
Mark Pictor 2d060e7cc3 minor changes to judyLArray.h, judy.c 2014-12-26 13:21:52 -05:00
Mark Pictor 6419146cf1 functions to look up instance type in file 2014-12-26 13:21:47 -05:00
Mark Pictor ffd0da9ceb default to case insensitive when searching by instance type 2014-12-26 13:08:08 -05:00
Mark Pictor bf39d90382 _mainRegistry wasn't initialized 2014-12-26 13:08:07 -05:00
Mark Pictor 5b14529f63 warning about comparison that was always true 2014-12-26 13:08:07 -05:00
Mark Pictor 60141ce6f7 abstract class with non-virtual destructor 2014-12-26 13:08:07 -05:00
Christopher Horler 4515ffca43 improvements to error handling
* Lexer now has a compatibility mode for entity names not all in uppercase
* Lexer now takes an extra argument header_limit, input is searched for
  valid start point, extra text up to header_limit is ignored.
2014-06-22 20:38:52 +01:00
Christopher Horler 4e90ff65e8 add logging to module, and mapping of lexer attributes lineno and lexpos to improve error messages 2014-06-22 12:11:56 +01:00
Christopher Horler e18b6d5c2a check for duplicate entity definitions in input 2014-06-20 22:34:38 +01:00
Christopher Horler ecaa9ba13f Update Python syntax and class definitions / style
- properties now use the @property decorator
- the assert statement is used in some places to enable disabling checks
2014-06-18 00:35:47 +01:00
Christopher Horler 53fac955ba add debug option to parse, add support to lexer for entity keywords 2014-06-17 22:17:37 +01:00
Christopher Horler aee532dd14 Use Ply for parser implementation 2014-06-17 20:07:06 +01:00
Christopher Horler 5840883239 add 'build' subdir ignores for CMake and Python 2014-06-17 19:59:01 +01:00
76 changed files with 3177 additions and 2204 deletions
+2
View File
@@ -0,0 +1,2 @@
/build
+6 -1
View File
@@ -5,21 +5,26 @@ http://brlcad.svn.sourceforge.net/viewvc/brlcad/brlcad/trunk/src/other/step/?vie
In alphabetical order:
Bertucat, Roch (rbertucat)
Bowman, W. Keith (indianlarry)
da Costa, Raphael Kubo (rakuco)
DeGraw, Jason (jasondegraw)
Easterbrook, Zach (lainiwakurax)
Greenwald, Erik (erikg, erikgreenwald)
Horler, Chris (cshorler)
Lanning, Craig (craigl64)
Loman, David (davidloman)
McDonald, Rob (ramcdona)
Mittal, Pulkit (hoiji09)
Morrison, Christopher Sean (sean, morrison, brlcad)
Paviot, Thomas (tpaviot)
Pictor, Mark (mpictor)
Reed, Nick (nickreed)
Shah, Kesha (kesha)
Shah, Kesha (kesha, keshashah)
Thomas, Dawn (homovulgaris, madant)
Wouters, Dave (davyw)
Yapp, Clifford (starseeker)
Special thanks:
Hunten, Keith (Lockheed Martin)
Lubbell, Joshua (NIST)
Stirk, Charlie (CostVision)
Thurman, Tom (TRThurman)
+21
View File
@@ -1,4 +1,25 @@
STEPcode -- http://github.com/stepcode/stepcode -- http://stepcode.org
************************************************************************
Release 0.8 (December, 2014)
New since v0.7:
* handle diamond inheritance, derived Attributes
* rename fedex_python, fedex_plus to exp2py, exp2cxx
* many changes to the pretty printer, due to use in reformatting draft
and IS schemas (Thanks Tom!)
* parser was also changed due to errors caught while pretty printing
- we can be much more confident that the parser is correct now
* fix incorrect quoting of timestamp in p21 header
* fix various copy constructors and ShallowCopy() members
* split generated code into many small files
- far easier to open generated code in editors
- support more compilers
- small files are combined (via #include statements) into a few
large files for faster "unitary" builds, if the compiler can handle it
- unitary builds are faster than the previous builds
* most compiler warnings fixed
* finally, all tests pass!
************************************************************************
Release 0.7 (April, 2013)
+5 -2
View File
@@ -1,5 +1,8 @@
Travis-CI build status:
[![Build Status](https://travis-ci.org/stepcode/stepcode.svg?branch=master)](https://travis-ci.org/stepcode/stepcode)
***********************************************************************
STEPcode v0.7 -- stepcode.org, github.com/stepcode/stepcode
STEPcode v0.8 -- stepcode.org, github.com/stepcode/stepcode
* What is STEPcode? SC reads ISO10303-11 EXPRESS schemas and generates
C++ source code that can read and write Part 21 files conforming
@@ -54,4 +57,4 @@ Download astyle from http://sourceforge.net/projects/astyle/files/astyle/
***********************************************************************
For more info, see the wiki.
For more info, see the wiki.
+1 -1
View File
@@ -1 +1 @@
0.7
0.8
+1 -1
View File
@@ -65,7 +65,7 @@ macro(SCHEMA_TESTS)
COMMAND ${CMAKE_COMMAND} --build .
--target lazy_${PROJECT_NAME}
--config $<CONFIGURATION>)
set_tests_properties(build_lazy_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${PROJECT_NAME} LABELS cpp_schema_build)
set_tests_properties(build_lazy_cpp_${PROJECT_NAME} PROPERTIES DEPENDS build_cpp_${PROJECT_NAME} LABELS cpp_schema_build)
endif(NOT WIN32)
endmacro(SCHEMA_TESTS)
+3 -2
View File
@@ -76,10 +76,11 @@ typedef struct Variable_ * Variable;
/***************************/
struct Variable_ {
Expression name; /**< Symbol is inside of 'name' */
Expression name; /**< Symbol is inside of 'name' */
Type type;
Expression initializer; /**< or 'derived' */
int offset; /**< used for attr order in Entitys, and for decl order in LOCAL vars. these two uses should never conflict! */
int offset; /**< used for attr order in Entitys, and for decl order in LOCAL vars. these two uses should never conflict! */
int idx; /**< used in exp2cxx to simplify calculation of attrDescriptor names in generated code */
struct {
unsigned int optional : 1; /**< OPTIONAL keyword */
+2 -1
View File
@@ -903,8 +903,9 @@ JudySlot * judy_last( Judy * judy, JudySlot next, unsigned int off, unsigned int
JudySlot * judy_end( Judy * judy ) {
judy->level = 0;
return judy_last( judy, *judy->root, 0, 0 );
} // judy_nxt: return next entry
}
// judy_nxt: return next entry
JudySlot * judy_nxt( Judy * judy ) {
JudySlot * table, *inner;
int slot, size, cnt;
+12 -8
View File
@@ -29,14 +29,16 @@ struct judylKVpair {
*/
template< typename JudyKey, typename JudyValue >
class judyLArray {
public:
typedef judylKVpair< JudyKey, JudyValue > pair;
protected:
Judy * _judyarray;
unsigned int _maxLevels, _depth;
JudyValue * _lastSlot;
JudyKey _buff[1];
bool _success;
pair _kv;
public:
typedef judylKVpair< JudyKey, JudyValue > pair;
judyLArray(): _maxLevels( sizeof( JudyKey ) ), _depth( 1 ), _lastSlot( 0 ), _success( true ) {
assert( sizeof( JudyKey ) == JUDY_key_size && "JudyKey *must* be the same size as a pointer!" );
assert( sizeof( JudyValue ) == JUDY_key_size && "JudyValue *must* be the same size as a pointer!" );
@@ -55,9 +57,12 @@ class judyLArray {
judy_close( _judyarray );
}
void clear() {
void clear( bool deleteContents = false ) {
JudyKey key = 0;
while( 0 != ( _lastSlot = ( JudyValue * ) judy_strt( _judyarray, ( const unsigned char * ) &key, 0 ) ) ) {
if( deleteContents ) {
delete *_lastSlot;
}
judy_del( _judyarray );
}
}
@@ -112,18 +117,17 @@ class judyLArray {
}
/// retrieve the key-value pair for the most recent judy query.
inline const pair mostRecentPair() {
pair kv;
inline const pair & mostRecentPair() {
judy_key( _judyarray, ( unsigned char * ) _buff, _depth * JUDY_key_size );
if( _lastSlot ) {
kv.value = *_lastSlot;
_kv.value = *_lastSlot;
_success = true;
} else {
kv.value = ( JudyValue ) 0;
_kv.value = ( JudyValue ) 0;
_success = false;
}
kv.key = _buff[0];
return kv;
_kv.key = _buff[0];
return _kv;
}
/// retrieve the first key-value pair in the array
+1 -1
View File
@@ -27,7 +27,7 @@ class SC_LAZYFILE_EXPORT headerSectionReader: public sectionReader {
return _headerInstances;
}
~headerSectionReader() {
virtual ~headerSectionReader() {
//FIXME delete each instance?! maybe add to clear, since it iterates over everything already
//enum clearHow { rawData, deletePointers }
_headerInstances->clear();
+6 -5
View File
@@ -14,7 +14,7 @@
* This class is used when creating SDAI_Application_instance's and using a lazyInstMgr. It is returned
* by instMgrAdapter. SDAI_Application_instance only uses the GetSTEPentity function.
*/
class mgrNodeHelper: protected MgrNode {
class mgrNodeHelper: public MgrNodeBase {
protected:
lazyInstMgr * _lim;
instanceID _id;
@@ -22,13 +22,13 @@ class mgrNodeHelper: protected MgrNode {
mgrNodeHelper( lazyInstMgr * lim ) {
_lim = lim;
_id = 0;
prev = next = 0;
}
inline void setInstance( instanceID id ) {
_id = id;
}
inline SDAI_Application_instance * GetSTEPentity() {
// unsigned int c = _lim->countDataSections();
return _lim->loadInstance( _id );
return _lim->loadInstance( _id, true );
}
};
@@ -40,13 +40,14 @@ class mgrNodeHelper: protected MgrNode {
* when an instance is looked up, this uses lazyInstMgr to load it, and then returns a pointer to it.
*/
class instMgrAdapter: public InstMgr {
class instMgrAdapter: public InstMgrBase {
protected:
mgrNodeHelper _mn;
public:
instMgrAdapter( lazyInstMgr * lim ): InstMgr( 0 ), _mn( lim ) {}
instMgrAdapter( lazyInstMgr * lim ): InstMgrBase(), _mn( lim ) {}
inline mgrNodeHelper * FindFileId( int fileId ) {
//TODO check if fileId exists. if not, return null
_mn.setInstance( fileId );
return &_mn;
}
+35 -9
View File
@@ -1,8 +1,10 @@
#include "lazyTypes.h"
#include "lazyInstMgr.h"
#include "Registry.h"
#include <SubSuperIterators.h>
#include "SdaiSchemaInit.h"
#include "instMgrHelper.h"
#include "lazyRefs.h"
lazyInstMgr::lazyInstMgr() {
_headerRegistry = new Registry( HeaderSchemaInit );
@@ -10,6 +12,7 @@ lazyInstMgr::lazyInstMgr() {
_lazyInstanceCount = 0;
_loadedInstanceCount = 0;
_longestTypeNameLen = 0;
_mainRegistry = 0;
_errors = new ErrorDescriptor();
_ima = new instMgrAdapter( this );
}
@@ -38,7 +41,7 @@ sectionID lazyInstMgr::registerDataSection( lazyDataSectionReader * sreader ) {
void lazyInstMgr::addLazyInstance( namedLazyInstance inst ) {
_lazyInstanceCount++;
assert( inst.loc.begin > 0 && inst.loc.instance > 0 && inst.loc.section >= 0 );
assert( inst.loc.begin > 0 && inst.loc.instance > 0 );
int len = strlen( inst.name );
if( len > _longestTypeNameLen ) {
_longestTypeNameLen = len;
@@ -46,8 +49,12 @@ void lazyInstMgr::addLazyInstance( namedLazyInstance inst ) {
}
_instanceTypes->insert( inst.name, inst.loc.instance );
/* store 16 bits of section id and 48 of instance offset into one 64-bit int
* TODO: check and warn if anything is lost (in calling code?)
* does 32bit need anything special?
** TODO: check and warn if anything is lost (in calling code?)
** does 32bit need anything special?
**
** create conversion class?
** could then initialize conversion object with number of bits
** also a good place to check for data loss
*/
positionAndSection ps = inst.loc.section;
ps <<= 48;
@@ -85,18 +92,29 @@ unsigned long lazyInstMgr::getNumTypes() const {
}
void lazyInstMgr::openFile( std::string fname ) {
_files.push_back( new lazyFileReader( fname, this, _files.size() ) );
//don't want to hold a lock for the entire time we're reading the file.
//create a place in the vector and remember its location, then free lock
///FIXME begin atomic op
size_t i = _files.size();
_files.push_back( (lazyFileReader * ) 0 );
///FIXME end atomic op
lazyFileReader * lfr = new lazyFileReader( fname, this, i );
_files[i] = lfr;
/// TODO resolve inverse attr references
//between instances, or eDesc --> inst????
}
SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id, bool reSeek ) {
assert( _mainRegistry && "Main registry has not been initialized. Do so with initRegistry() or setRegistry()." );
SDAI_Application_instance * inst = 0;
std::streampos oldPos;
positionAndSection ps;
sectionID sid;
inst = _instancesLoaded.find( id );
SDAI_Application_instance * inst = _instancesLoaded.find( id );
if( inst ) {
return inst;
}
instanceStreamPos_t::cvector * cv;
if( !inst && 0 != ( cv = _instanceStreamPos.find( id ) ) ) {
//FIXME _instanceStreamPos.find( id ) can return nonzero for nonexistent key?!
if( 0 != ( cv = _instanceStreamPos.find( id ) ) ) {
switch( cv->size() ) {
case 0:
std::cerr << "Instance #" << id << " not found in any section." << std::endl;
@@ -107,7 +125,13 @@ SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
off = ps & 0xFFFFFFFFFFFFULL;
sid = ps >> 48;
assert( _dataSections.size() > sid );
if( reSeek ) {
oldPos = _dataSections[sid]->tellg();
}
inst = _dataSections[sid]->getRealInstance( _mainRegistry, off, id );
if( reSeek ) {
_dataSections[sid]->seekg( oldPos );
}
break;
default:
std::cerr << "Instance #" << id << " exists in multiple sections. This is not yet supported." << std::endl;
@@ -116,6 +140,8 @@ SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
if( ( inst ) && ( inst != & NilSTEPentity ) ) {
_instancesLoaded.insert( id, inst );
_loadedInstanceCount++;
lazyRefs lr( this, inst );
lazyRefs::referentInstances_t insts = lr.result();
} else {
std::cerr << "Error loading instance #" << id << "." << std::endl;
}
+59 -16
View File
@@ -22,11 +22,11 @@ class instMgrAdapter;
class lazyInstMgr {
protected:
/** map from instance number to instances that it refers to
/** multimap from instance number to instances that it refers to
* \sa instanceRefs_pair
*/
instanceRefs_t _fwdInstanceRefs;
/** map from instance number to instances that refer to it
/** multimap from instance number to instances that refer to it - the majority of these will not be inverse references!
* \sa instanceRefs_pair
*/
instanceRefs_t _revInstanceRefs;
@@ -39,11 +39,15 @@ class lazyInstMgr {
/** map from instance number to instance pointer (loaded instances only)
* \sa instancesLoaded_pair
*
* TODO should be multimap to allow use of instances in multiple data sections?
* a unique instance ID (containing sectionID and instanceID) would also work
*/
instancesLoaded_t _instancesLoaded;
/** map from instance number to beginning and end positions and the data section
* \sa instanceStreamPos_pair
*
* FIXME to save memory, modify judyL2Array to not use a vector until there are several
* instances with the same instanceID. This will help elsewhere as well.
*/
@@ -65,7 +69,6 @@ class lazyInstMgr {
public:
lazyInstMgr();
~lazyInstMgr();
void addSchema( void ( *initFn )() ); //?
void openFile( std::string fname );
void addLazyInstance( namedLazyInstance inst );
@@ -80,8 +83,14 @@ class lazyInstMgr {
instanceRefs_t * getRevRefs() {
return & _revInstanceRefs;
}
/// returns two iterators delimiting the instances that match `type`
instanceTypes_t::cvector * getInstances( std::string type ) { /*const*/
/// returns a vector containing the instances that match `type`
instanceTypes_t::cvector * getInstances( std::string type, bool caseSensitive = false ) { /*const*/
if( !caseSensitive ) {
std::string::iterator it = type.begin();
for( ; it != type.end(); ++it ) {
*it = toupper( *it );
}
}
return _instanceTypes->find( type.c_str() );
}
/// get the number of instances of a certain type
@@ -140,28 +149,62 @@ class lazyInstMgr {
unsigned long getNumTypes() const;
sectionID registerDataSection( lazyDataSectionReader * sreader );
fileID registerLazyFile( lazyFileReader * freader );
ErrorDescriptor * getErrorDesc() {
return _errors;
}
SDAI_Application_instance * loadInstance( instanceID id );
/** returns a pointer to an instance, loading it if necessary.
* \param id the instance number to look for
* \param reSeek if true, reset file position to current position when done. only necessary when loading an instance with dependencies; excessive use will cause a performance hit
*/
SDAI_Application_instance * loadInstance( instanceID id, bool reSeek = false );
//list all instances that one instance depends on (recursive)
instanceSet * instanceDependencies( instanceID id );
bool isLoaded( instanceID id ) {
_instancesLoaded.find( id );
return _instancesLoaded.success();
}
const char * typeFromFile( instanceID id ) {
instanceStreamPos_t::cvector * cv;
cv = _instanceStreamPos.find( id );
if( cv ) {
if( cv->size() != 1 ) {
std::cerr << "Error at " << __FILE__ << ":" << __LINE__ << " - multiple instances (" << cv->size() << ") with one instanceID (" << id << ") not supported yet." << std::endl;
return 0;
}
positionAndSection ps = cv->at( 0 );
//extract p, s, call
long int off = ps & 0xFFFFFFFFFFFFULL;
sectionID sid = ps >> 48;
return _dataSections[sid]->getType( off );
}
std::cerr << "Error at " << __FILE__ << ":" << __LINE__ << " - instanceID " << id << " not found." << std::endl;
return 0;
}
// TODO implement these
/* * the opposite of instanceDependencies() - all instances that are *not* dependencies of one particular instance
same as above, but with list of instances */
//std::vector<instanceID> notDependencies(...)
//renumber instances so that they are numbered 1..N where N is the total number of instances
//void normalizeInstanceIds();
//find data that is repeated and eliminate, if possible
//void eliminateDuplicates();
//tell instMgr to use instances from this section
//void useDataSection( sectionID id );
// add another schema to registry
//void addSchema( void ( *initFn )() );
//list all instances that one instance depends on (recursive)
//std::vector<instanceID> instanceDependencies( instanceID id ); //set is faster?
/* * the opposite of instanceDependencies() - all instances that are *not* dependencies of one particular instance
same as above, but with list of instances */
//std::vector<instanceID> notDependencies(...)
//renumber instances so that they are numbered 1..N where N is the total number of instances
//void normalizeInstanceIds();
//find data that is repeated and eliminate, if possible
//void eliminateDuplicates();
//tell instMgr to use instances from this section
//void useDataSection( sectionID id );
// TODO support references from one file to another
};
+1 -1
View File
@@ -43,6 +43,7 @@ lazyP21DataSectionReader::lazyP21DataSectionReader( lazyFileReader * parent, std
}
// part of readdata1
//if this changes, probably need to change sectionReader::getType()
const namedLazyInstance lazyP21DataSectionReader::nextInstance() {
std::streampos end = -1;
namedLazyInstance i;
@@ -53,7 +54,6 @@ const namedLazyInstance lazyP21DataSectionReader::nextInstance() {
if( ( _file.good() ) && ( i.loc.instance > 0 ) ) {
skipWS();
i.loc.section = _sectionID;
skipWS();
i.name = getDelimitedKeyword( ";( /\\" );
if( _file.good() ) {
end = seekInstanceEnd( & i.refs );
+290
View File
@@ -0,0 +1,290 @@
#ifndef LAZYREFS_H
#define LAZYREFS_H
#include <string>
#include <set>
#include <utility>
#include <vector>
#include "lazyTypes.h"
#include "lazyInstMgr.h"
#include "ExpDict.h"
#include "sdaiApplication_instance.h"
#include "SubSuperIterators.h"
#include <STEPattribute.h>
#include <STEPaggregate.h>
/*
* given inverted attr ia:
* attr method value
* ----------- -----
* ia->Name() isdefinedby
* ia->inverted_attr_id_() relatedobjects
* ia->inverted_entity_id_() reldefinesbytype
*
* 1. for the instance in question, find inverse attrs with recursion
* 2. look up references to the current instance (_r)
* a. for each item in _r, look up its type and add mapping (instanceID -> char* typestring) to _refMap
* 3. for each ia,
* a. entity name is returned by ia->inverted_entity_id_()
* b. add this entity and its children to a list ( edL )
* c. compare the type of each item in _refMap with types in edL; for types in both, remember the instance number ( _referentInstances )
* d. load each instance in _referentInstances
* e. check if the relevant inverted attr of instances loaded from _referentInstances reference the instance in step 1; if not, unload **IF** the instance hadn't been loaded
* --> if it was loaded, this implies that it is used elsewhere
* f. (optional / TODO ) for performance, cache list edL - it may be useful in the future
* -- best to store such that the most recently (frequently?) used lists are retained and others are discarded
*/
/* ****
* ALTERNATE for 2a, 3c:
* for each type t in edL, use lim->getInstances( t ) to get a list of instances of that type, Lt
* for each instance i in Lt, check if it is in _r
* if so, load it
* BENEFIT: no need to write lazyInstMgr::getTypeStr() (however, it might be necessary in the future regardless)
*/
//TODO screen out intances that appear to be possible inverse refs but aren't actually
// note - doing this well will require major changes, since each inst automatically loads every instance that it references
//TODO what about complex instances? scanning each on disk could be a bitch; should the compositional types be scanned during lazy loading?
//TODO/FIXME in generated code, store ia data in map and eliminate data members that are currently used. modify accessors to use map.
class lazyRefs {
public:
typedef std::set< instanceID > referentInstances_t;
protected:
typedef std::set< const Inverse_attribute * > iaList_t;
typedef judyLArray< instanceID, std::string * > refMap_t;
typedef std::set< const EntityDescriptor * > edList_t;
iaList_t _iaList;
lazyInstMgr * _lim;
instanceID _id;
refMap_t _refMap;
referentInstances_t _referentInstances;
SDAI_Application_instance * _inst;
void checkAnInvAttr( const Inverse_attribute * ia ) {
const EntityDescriptor * ed;
const Registry * reg = _lim->getMainRegistry();
ed = reg->FindEntity( ia->_inverted_entity_id );
subtypesIterator subtypeIter( ed );
edList_t edL;
edL.insert( ed );
// 3b - use subtypeIter to add to edL
for( ; !subtypeIter.empty(); ++subtypeIter ) {
edL.insert( *subtypeIter );
}
//3c - for each item in both _refMap and edL, add it to _referentInstances
potentialReferentInsts( edL );
//3d - load each inst
iAstruct ias = invAttr( _inst, ia );
referentInstances_t::iterator insts = _referentInstances.begin();
for( ; insts != _referentInstances.end(); ++insts ) {
loadInstIFFreferent( *insts, ias, ia );
}
//3f - cache edL - TODO
}
void loadInstIFFreferent( instanceID inst, iAstruct ias, const Inverse_attribute * ia ) {
bool prevLoaded = _lim->isLoaded( inst );
SDAI_Application_instance * rinst = _lim->loadInstance( inst );
bool ref = refersToCurrentInst( ia, rinst );
if( ref ) {
if( ia->inverted_attr_()->IsAggrType() ) {
if( !ias.a ) {
ias.a = new EntityAggregate;
_inst->setInvAttr( ia, ias );
assert( invAttr( _inst, ia ).a == ias.a );
}
EntityAggregate * ea = ias.a;
//TODO check if duplicate
ea->AddNode( new EntityNode( rinst ) );
} else {
SDAI_Application_instance * ai = ias.i;
if( !ai ) {
ias.i = rinst;
_inst->setInvAttr( ia, ias );
} else if( ai->GetFileId() != inst ) {
std::cerr << "ERROR: two instances (" << rinst << ", #" << rinst->GetFileId() << "=" << rinst->getEDesc()->Name();
std::cerr << " and " << ai << ", #" << ai->GetFileId() <<"=" << ai->getEDesc()->Name() << ") refer to inst ";
std::cerr << _inst->GetFileId() << ", but its inverse attribute is not an aggregation type!" << std::endl;
// TODO _error->GreaterSeverity( SEVERITY_INPUT_ERROR );
}
}
} else {
if( !prevLoaded ) {
//TODO _lim->unload( inst ); //this should keep the inst loaded for now, but put it in a list of ones that can be unloaded if not accessed
}
}
}
///3e - check if actually inverse ref
bool refersToCurrentInst( const Inverse_attribute * ia, SDAI_Application_instance * referrer ) {
//find the attr
int rindex = attrIndex( referrer, ia->_inverted_attr_id, ia->_inverted_entity_id );
STEPattribute sa = referrer->attributes[ rindex ];
assert( sa.getADesc()->BaseType() == ENTITY_TYPE );
bool found = false;
if( sa.getADesc()->IsAggrType() ) {
//aggregate - search for current inst id
EntityAggregate * aggr = dynamic_cast< EntityAggregate * >( sa.Aggregate());
assert( aggr );
EntityNode * en = ( EntityNode * ) aggr->GetHead();
while( en ) {
if( en->node == _inst ) {
found = true;
break;
}
en = ( EntityNode * ) en->NextNode();
}
} else {
//single instance
assert( sa.getADesc()->NonRefType() == ENTITY_TYPE );
if( sa.Entity() == _inst ) {
found = true;
}
}
if( !found ) {
std::cerr << "inst #" << _inst->FileId() << " not found in #" << referrer->FileId();
std::cerr << ", attr #" << rindex << " [contents: ";
referrer->STEPwrite( std::cerr );
std::cerr << "]" << std::endl;
}
return found;
}
int attrIndex( SDAI_Application_instance * inst, const char * name, const char * entity ) {
for( int i = 0; i < inst->attributes.list_length(); i++ ) {
// std::cout << "attr " << i << " name " << inst->attributes[i].Name() << ", entity " << inst->EntityName() << std::endl;
if( ( strcasecmp( name, inst->attributes[i].Name() ) == 0 ) &&
( strcasecmp( entity, inst->attributes[i].getADesc()->Owner().Name() ) == 0 ) ) {
return i;
}
}
return -1;
}
iAstruct invAttr( SDAI_Application_instance * inst, const Inverse_attribute * ia /*, iaList_t & iaList */ ) {
SDAI_Application_instance::iAMap_t map = inst->getInvAttrs();
SDAI_Application_instance::iAMap_t::iterator iai = map.begin();
while( iai != map.end() ) {
if( iai->first == ia ) {
return iai->second;
}
++iai;
}
std::cerr << "Error! inverse attr " << ia->Name() << " (" << ia << ") not found in iAMap for entity " << inst->getEDesc()->Name() << std::endl;
abort();
iAstruct nil;
return nil;
}
/** 3c. compare the type of each item in R with types in A
* for items that match, remember the instance number (list C)
*/
void potentialReferentInsts( edList_t & edL ) {
refMap_t::pair kv = _refMap.begin();
while( kv.value != 0 ) {
std::set< const EntityDescriptor * >::iterator edi = edL.begin();
for( ; edi != edL.end(); ++edi ) {
if( 0 == strcasecmp( kv.value->c_str(), ( *edi )->Name() ) ) {
_referentInstances.insert( kv.key );
break;
}
}
kv = _refMap.next();
}
}
///find any inverse attributes, put in `iaList`
/// attrs not necessarily in order!
void getInverseAttrs( const EntityDescriptor * ed, iaList_t & iaList ) {
iaList.clear();
supertypesIterator supersIter( ed );
const Inverse_attribute * iAttr;
for( ; !supersIter.empty(); ++supersIter ) {
//look at attrs of *si
InverseAItr iai( &( ( *supersIter )->InverseAttr() ) );
while( 0 != ( iAttr = iai.NextInverse_attribute() ) ) {
iaList.insert( iAttr );
}
}
// look at our own attrs
InverseAItr invAttrIter( &( ed->InverseAttr() ) );
while( 0 != ( iAttr = invAttrIter.NextInverse_attribute() ) ) {
iaList.insert( iAttr );
}
}
// 2. find reverse refs
//2a. convert to map where K=instanceID and V=char*
// rather than keeping each V in memory or trying to free non-unique ones, look up each type in the Registry and use that pointer
bool mapRefsToTypes() {
_refMap.clear( true ); // true -> use delete on pointers
instanceRefs_t::cvector * refs = _lim->getRevRefs()->find( _id );
if( !refs || refs->empty() ) {
return false;
}
instanceRefs_t::cvector::const_iterator it;
for( it = refs->begin(); it != refs->end(); ++it ) {
const char * type = _lim->typeFromFile( *it );
_refMap.insert( *it, new std::string( type ) );
}
return true;
}
public:
lazyRefs( lazyInstMgr * lmgr ): _lim( lmgr ), _id( 0 ) {
_iaList.clear();
}
lazyRefs( lazyInstMgr * lmgr, SDAI_Application_instance * ai ): _lim( lmgr ), _id( 0 ) {
_iaList.clear();
init( 0, ai );
}
lazyRefs( lazyInstMgr * lmgr, instanceID iid ): _lim( lmgr ) {
_iaList.clear();
init( iid, 0 );
}
~lazyRefs() {
// delete strings in refMap
_refMap.clear( true );
}
/// initialize with the given instance; will use ai if given, else loads instance iid
void init( instanceID iid, SDAI_Application_instance * ai = 0 ) {
if( iid == 0 && ai == 0 ) {
std::cerr << "Error at " << __FILE__ << ":" << __LINE__ << " - both args are null" << std::endl;
return;
}
if( !ai ) {
_inst = _lim->loadInstance( iid );
_id = iid;
} else {
_inst = ai;
_id = _inst->GetFileId();
}
_refMap.clear( true );
// 1. find inverse attrs with recursion
getInverseAttrs( ai->getEDesc(), _iaList );
//2. find reverse refs, map id to type (stop if there are no inverse attrs or no refs)
if( _iaList.size() == 0 || !mapRefsToTypes() ) {
return;
}
iaList_t::iterator iai = _iaList.begin();
for( ; iai != _iaList.end(); ++iai ) {
// 3. for each IA, ...
checkAnInvAttr( *iai );
}
}
referentInstances_t result() {
return _referentInstances;
}
};
#endif //LAZYREFS_H
+74
View File
@@ -0,0 +1,74 @@
for inverse attrs, we have the attr name and the type of the instance
--load instance, find inverse attr(s)
--for each inverse attr:
--find all instance types that inherit from the inverted attr's owner (list A)
--look up instances that reference the one in question (list B) - use memoization
--find instances that match both lists, put in list C
--load instances in list C
--for list C, check that the relevant attr references the original instance - if not, unload (?)
--
--when done with this inverse attr, cache list A
EXAMPLE
*******
information model
-----------------
ENTITY Object;
ObjectType : OPTIONAL STRING;
INVERSE
IsDefinedBy : SET [0:?] OF RelDefinesByType FOR RelatedObjects;
END_ENTITY;
ENTITY RelDefinesByType;
RelatedObjects : SET [1:?] OF Object;
END_ENTITY;
ENTITY Window
SUBTYPE OF (Object);
Description : OPTIONAL string;
END_ENTITY;
data file
---------
#1=OBJECT('one');
#2=RELDEFINESBYTYPE((#1));
#3=RELDEFINESBYTYPE((#4));
#4=WINDOW('two','blah');
#1 and #4 have an inverse attr, but this is not visible in the data file
#2 and #3 have #1 and #4, respectively, in an aggregate (thus the parenthesis around the instance); in this case, a SET called RelatedObjects
RelatedObjects is the inverted attr that the inverse attr IsDefinedBy links to
looking at the entity descriptor for WINDOW, it is not apparent that there is an inverse attr; its parents must be examined
given inverted attr ia:
attr method value
----------- -----
ia->Name() isdefinedby
ia->inverted_attr_id_() relatedobjects
ia->inverted_entity_id_() reldefinesbytype
1. for the instance in question, find inverse attrs with recursion
2. for each ia,
a. entity name is returned by ia->inverted_entity_id_()
b. add this entity and its children to a list (list A)
c. look up references to the current instance (list B)
d. for each item in B, look up its type; if its type is present in A, remember the instance number (list C)
e. load each instance in C
f. (optional) check if the relevant inverted attr of instances loaded from list C reference the instance in step 1; if not, unload **IF** the instance hadn't been loaded
--> if it was loaded, this implies that it is used elsewhere
g. cache list A, since it may be useful in the future
-- best to store such that the most recently (frequently?) used lists are retained and others are discarded
NEED TO DO
----------
make it possible to access inverse attrs without knowing their names
probably best to do this much like explicit attrs - creating an array. each element should have a pointer to the inverted attr desc, a pointer to the setter, and a pointer to the getter
+1 -1
View File
@@ -45,7 +45,7 @@ typedef std::set< instanceID > instanceSet;
* situations, so the information should be kept up-to-date.
*/
typedef struct {
long begin;
long begin; ///< this is the result of tellg() before reading the instanceID; there may be whitespace or comments, but nothing else.
instanceID instance;
sectionID section;
/* bool modified; */ /* this will be useful when writing instances - if an instance is
+26 -14
View File
@@ -100,20 +100,31 @@ void printDeps( lazyInstMgr & mgr ) {
}
///prints info about a complex instance
void dumpComplexInst( STEPcomplex * c, unsigned int depth ) {
void dumpComplexInst( STEPcomplex * c ) {
int depth = 0;
if( c ) {
std::cout << "attr list size: " << c->_attr_data_list.size() << ", depth " << depth << std::endl;
STEPcomplex_attr_data_list::iterator it;
for( it = c->_attr_data_list.begin(); it != c->_attr_data_list.end(); it++ ) {
std::cout << "*** Not printing complex instance attribute info - many eDesc pointers are invalid. ***" << std::endl; //FIXME!
// std::cout << "attr list size: " << c->_attr_data_list.size() << ", depth " << depth << std::endl;
// STEPcomplex_attr_data_list::iterator it;
// for( it = c->_attr_data_list.begin(); it != c->_attr_data_list.end(); it++ ) {
// std::cout << "*** Not printing complex instance attribute info - many eDesc pointers are invalid. ***" << std::endl; //FIXME!
// SDAI_Application_instance * attr = ( SDAI_Application_instance * ) *it;
// if( attr->IsComplex() ) {
// dumpComplexInst( dynamic_cast<STEPcomplex *>( attr ), depth + 1 );
// } else if( attr->eDesc > ( void * ) 0xFF ) { //arbitrary number - invalid ones are usually 0x51
// std::cout << "attr " << attr->eDesc->Name() << std::endl;
// } else {
// std::cout << "attr has eDesc with pointer " << attr->eDesc << std::endl;
// }
STEPcomplex * complex = c->head;
while( complex ) {
if( complex->IsComplex() ) {
std::cout << "Complex component " << complex->getEDesc()->Name() << " at depth " << depth << " with attr list size ";
std::cout << complex->_attr_data_list.size() << std::endl;
// dumpComplexInst( complex, depth + 1 );
} else {
//probably won't ever get here...
SDAI_Application_instance * ai = dynamic_cast< SDAI_Application_instance * >( complex );
if( ai ) {
std::cout << "non-complex component at depth " << depth << ", " << ai->getEDesc()->Name() << std::endl;
} else {
std::cout << "unknown component at depth " << depth << ": " << complex << std::endl;
}
}
complex = complex->sc;
depth++;
}
}
}
@@ -143,6 +154,7 @@ int main( int argc, char ** argv ) {
std::cout << ( float )( scanStats.physMemKB * 1000 ) / instances << " bytes per instance)" << std::endl << std::endl;
fileInfo( *mgr, 0 );
//these are just common types
countTypeInstances( *mgr, "CARTESIAN_POINT" );
countTypeInstances( *mgr, "POSITIVE_LENGTH_MEASURE" );
countTypeInstances( *mgr, "VERTEX_POINT" );
@@ -168,9 +180,9 @@ int main( int argc, char ** argv ) {
instanceTypes_t::cvector * complexInsts = mgr->getInstances( "" );
if( complexInsts && complexInsts->size() > 0 ) {
std::cout << "loading lazy instance #" << complexInsts->at( 0 ) << "." << std::endl;
std::cout << "loading complex instance #" << complexInsts->at( 0 ) << "." << std::endl;
STEPcomplex * c = dynamic_cast<STEPcomplex *>( mgr->loadInstance( complexInsts->at( 0 ) ) );
dumpComplexInst( c, 0 );
dumpComplexInst( c );
std::cout << "Number of instances loaded now: " << mgr->loadedInstanceCount() << std::endl;
}
#else
+14 -6
View File
@@ -82,6 +82,7 @@ std::streampos sectionReader::findNormalString( const std::string & str, bool se
//NOTE different behavior than const char * GetKeyword( istream & in, const char * delims, ErrorDescriptor & err ) in read_func.cc
// returns pointer to the contents of a static std::string
const char * sectionReader::getDelimitedKeyword( const char * delimiters ) {
static std::string str;
char c;
@@ -246,13 +247,15 @@ instanceID sectionReader::readInstanceNumber() {
return id;
}
//TODO: most of the rest of readdata1, all of readdata2
/** load an instance and return a pointer to it.
* side effect: recursively loads any instances the specified instance depends upon
*/
SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg, long int begin, instanceID instance,
const std::string & typeName, const std::string & schName, bool header ) {
char c;
const char * tName = 0, * sName = 0; //these are necessary since typeName and schName are const
std::string comment;
Severity sev;
Severity sev = SEVERITY_NULL;
SDAI_Application_instance * inst = 0;
tName = typeName.c_str();
@@ -305,12 +308,13 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg
if( !comment.empty() ) {
inst->AddP21Comment( comment );
}
assert( inst->eDesc );
assert( inst->getEDesc() );
_file.seekg( begin );
findNormalString( "(" );
_file.unget();
//TODO do something with 'sev'
sev = inst->STEPread( instance, 0, _lazyFile->getInstMgr()->getAdapter(), _file, sName, true, false );
//TODO do something with 'sev'
inst->InitIAttrs();
}
return inst;
}
@@ -320,8 +324,9 @@ STEPcomplex * sectionReader::CreateSubSuperInstance( const Registry * reg, insta
ErrorDescriptor err;
std::vector<std::string *> typeNames;
_file.get(); //move past the first '('
skipWS();
while( _file.good() && ( _file.peek() != ')' ) ) {
typeNames.push_back( new std::string( getDelimitedKeyword( ";( /\\" ) ) );
typeNames.push_back( new std::string( getDelimitedKeyword( ";( /\\\n" ) ) );
if( typeNames.back()->empty() ) {
delete typeNames.back();
typeNames.pop_back();
@@ -343,6 +348,9 @@ STEPcomplex * sectionReader::CreateSubSuperInstance( const Registry * reg, insta
names[ i ] = typeNames[i]->c_str();
}
//TODO still need the schema name
return new STEPcomplex( ( const_cast<Registry *>( reg ) ), ( const char ** ) names, ( int ) fileid /*, schnm*/ );
STEPcomplex * sc = new STEPcomplex( ( const_cast<Registry *>( reg ) ), names, ( int ) fileid /*, schnm*/ );
delete[] names;
//TODO also delete contents of typeNames!
return sc;
}
+20
View File
@@ -81,7 +81,27 @@ class SC_LAZYFILE_EXPORT sectionReader {
virtual const namedLazyInstance nextInstance() = 0;
/** returns the type string for an instance, read straight from the file
* if this function changes, probably need to change nextInstance() as well
* don't check errors - they would have been encountered during the initial file scan, and the file is still open so it can't have been modified */
const char * getType( long int offset ) {
if( offset <= 0 ) {
return 0;
}
_file.seekg( offset );
readInstanceNumber();
skipWS();
return getDelimitedKeyword( ";( /\\" );
}
instanceID readInstanceNumber();
void seekg( std::streampos pos ) {
_file.seekg( pos );
}
std::streampos tellg() {
return _file.tellg();
}
};
#endif //SECTIONREADER_H
+5 -3
View File
@@ -2,13 +2,14 @@
set(LIBSTEPCORE_SRCS
sdaiApplication_instance.cc
STEPcomplex.cc
STEPaggregate.cc
STEPattribute.cc
STEPattribute.inline.cc
STEPattributeList.cc
STEPinvAttrList.cc
STEPundefined.cc
sdai.cc
sdaiSelect.cc
STEPaggregate.cc
STEPundefined.cc
STEPattributeList.cc
SingleLinkList.cc
SingleLinkList.inline.cc
Registry.inline.cc
@@ -48,6 +49,7 @@ set(SC_CLSTEPCORE_HDRS
STEPaggregate.h
STEPattribute.h
STEPattributeList.h
STEPinvAttrList.h
STEPcomplex.h
STEPundefined.h
instmgr.h
+48 -6
View File
@@ -18,8 +18,9 @@
#include <ExpDict.h>
#include <STEPaggregate.h>
#include <Registry.h>
#include "sc_memmgr.h"
#include <SubSuperIterators.h>
Explicit_item_id__set::Explicit_item_id__set( int defaultSize ) {
_bufsize = defaultSize;
@@ -536,9 +537,9 @@ IntAggregate * create_IntAggregate() {
return new IntAggregate;
}
const EntityDescriptor * EntityDescItr::NextEntityDesc() {
EntityDescriptor * EntityDescItr::NextEntityDesc_nc() {
if( cur ) {
const EntityDescriptor * ed = cur->EntityDesc();
EntityDescriptor * ed = cur->EntityDesc();
cur = ( EntityDescLinkNode * )( cur->NextNode() );
return ed;
}
@@ -554,9 +555,9 @@ const AttrDescriptor * AttrDescItr::NextAttrDesc() {
return 0;
}
const Inverse_attribute * InverseAItr::NextInverse_attribute() {
Inverse_attribute * InverseAItr::NextInverse_attribute() {
if( cur ) {
const Inverse_attribute * ia = cur->Inverse_attr();
Inverse_attribute * ia = cur->Inverse_attr();
cur = ( Inverse_attributeLinkNode * )( cur->NextNode() );
return ia;
}
@@ -811,6 +812,47 @@ EntityDescriptor::~EntityDescriptor() {
delete _uniqueness_rules;
}
// initialize one inverse attr; used in InitIAttrs, below
void initIAttr( Inverse_attribute * ia, Registry & reg, const char * schNm, const char * name ) {
const AttrDescriptor * ad;
const char * aid = ia->inverted_attr_id_();
const char * eid = ia->inverted_entity_id_();
const EntityDescriptor * e = reg.FindEntity( eid, schNm );
AttrDescItr adl( e->ExplicitAttr() );
while( 0 != ( ad = adl.NextAttrDesc() ) ) {
if( !strcmp( aid, ad->Name() ) ) {
ia->inverted_attr_( ad );
return;
}
}
supertypesIterator sit(e);
for( ; !sit.empty(); ++sit ) {
AttrDescItr adi( sit.current()->ExplicitAttr() );
while( 0 != ( ad = adi.NextAttrDesc() ) ) {
if( !strcmp( aid, ad->Name() ) ) {
ia->inverted_attr_( ad );
return;
}
}
}
std::cerr << "Inverse attr " << ia->Name() << " for " << name << ": cannot find AttrDescriptor " << aid << " for entity " << eid << "." << std::endl;
//FIXME should we abort? or is there a sensible recovery path?
abort();
}
/** initialize inverse attrs
* call once per eDesc (once per EXPRESS entity type)
* must be called _after_ init_Sdai* functions for any ia->inverted_entity_id_'s
*
*/
void EntityDescriptor::InitIAttrs( Registry & reg, const char * schNm ) {
InverseAItr iai( &( InverseAttr() ) );
Inverse_attribute * ia;
while( 0 != ( ia = iai.NextInverse_attribute() ) ) {
initIAttr( ia, reg, schNm, _name );
}
}
const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
std::string sstr;
int count;
@@ -878,7 +920,7 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
}
/////////
InverseAItr iai( _inverseAttr );
InverseAItr iai( &_inverseAttr );
iai.ResetItr();
const Inverse_attribute * ia = iai.NextInverse_attribute();
+98 -45
View File
@@ -172,7 +172,11 @@ class SC_CORE_EXPORT EntityDescItr {
cur = ( EntityDescLinkNode * )( edl.GetHead() );
}
const EntityDescriptor * NextEntityDesc();
inline const EntityDescriptor * NextEntityDesc() {
return NextEntityDesc_nc();
}
EntityDescriptor * NextEntityDesc_nc();
};
@@ -664,6 +668,7 @@ class SC_CORE_EXPORT Schema : public Dictionary_instance {
protected:
const char * _name;
EntityDescriptorList _entList; // list of entities in the schema
EntityDescriptorList _entsWithInverseAttrs;
TypeDescriptorList _typeList; // list of types in the schema
TypeDescriptorList _unnamed_typeList; // list of unnamed types in the schema (for cleanup)
Interface_spec _interface; // list of USE and REF interfaces (SDAI)
@@ -729,15 +734,43 @@ class SC_CORE_EXPORT Schema : public Dictionary_instance {
EntityDescLinkNode * AddEntity( EntityDescriptor * ed ) {
return _entList.AddNode( ed );
}
/// must be called in addition to AddEntity()
EntityDescLinkNode * AddEntityWInverse( EntityDescriptor * ed ) {
return _entsWithInverseAttrs.AddNode( ed );
}
TypeDescLinkNode * AddType( TypeDescriptor * td ) {
return _typeList.AddNode( td );
}
TypeDescLinkNode * AddUnnamedType( TypeDescriptor * td ) {
return _unnamed_typeList.AddNode( td );
}
const EntityDescriptorList * Entities() const {
return & _entList;
}
const EntityDescriptorList * EntsWInverse() const {
return & _entsWithInverseAttrs;
}
const TypeDescriptorList * Types() const {
return & _typeList;
}
const TypeDescriptorList * UnnamedTypes() const {
return & _unnamed_typeList;
}
EntityDescriptorList * Entities() {
return & _entList;
}
EntityDescriptorList * EntsWInverse() {
return & _entsWithInverseAttrs;
}
TypeDescriptorList * Types() {
return & _typeList;
}
TypeDescriptorList * UnnamedTypes() {
return & _unnamed_typeList;
}
// the whole schema
void GenerateExpress( ostream & out ) const;
@@ -811,7 +844,7 @@ class SC_CORE_EXPORT Inverse_attributeLinkNode : public SingleLinkNode {
Inverse_attributeLinkNode();
virtual ~Inverse_attributeLinkNode();
const Inverse_attribute * Inverse_attr() const {
Inverse_attribute * Inverse_attr() const {
return _invAttr;
}
void Inverse_attr( Inverse_attribute * ia ) {
@@ -822,30 +855,32 @@ class SC_CORE_EXPORT Inverse_attributeLinkNode : public SingleLinkNode {
class SC_CORE_EXPORT Inverse_attributeList : public SingleLinkList {
private:
protected:
public:
Inverse_attributeList();
virtual ~Inverse_attributeList();
virtual SingleLinkNode * NewNode() {
return new Inverse_attributeLinkNode;
}
public:
Inverse_attributeList();
virtual ~Inverse_attributeList();
Inverse_attributeLinkNode * AddNode( Inverse_attribute * ia );
};
class SC_CORE_EXPORT InverseAItr {
protected:
const Inverse_attributeList & ial;
const Inverse_attributeList * ial;
const Inverse_attributeLinkNode * cur;
public:
InverseAItr( const Inverse_attributeList & iaList );
InverseAItr( const Inverse_attributeList * iaList );
virtual ~InverseAItr();
void ResetItr() {
cur = ( Inverse_attributeLinkNode * )( ial.GetHead() );
void ResetItr( const Inverse_attributeList * iaList = 0 ) {
if( iaList ) {
ial = iaList;
}
cur = ( Inverse_attributeLinkNode * )( ial->GetHead() );
}
const Inverse_attribute * NextInverse_attribute();
Inverse_attribute * NextInverse_attribute();
};
/**
@@ -889,34 +924,44 @@ class SC_CORE_EXPORT AttrDescriptor {
_name = n;
}
// BaseType() is the underlying type of this attribute.
// NonRefType() is the first non REFERENCE_TYPE type
// e.g. Given attributes of each of the following types
// TYPE count = INTEGER;
// TYPE ref_count = count;
// TYPE count_set = SET OF ref_count;
// BaseType() will return INTEGER_TYPE for an attr of each type.
// BaseTypeDescriptor() returns the TypeDescriptor for Integer
// NonRefType() will return INTEGER_TYPE for the first two. For an
// attribute of type count_set NonRefType() would return
// AGGREGATE_TYPE
// NonRefTypeDescriptor() returns the TypeDescriptor for Integer
// for the first two and a TypeDescriptor for an
// aggregate for the last.
/** BaseType() is the underlying type of this attribute.
* NonRefType() is the first non REFERENCE_TYPE type
* e.g. Given attributes of each of the following types
* TYPE count = INTEGER;
* TYPE ref_count = count;
* TYPE count_set = SET OF ref_count;
* BaseType() will return INTEGER_TYPE for an attr of each type.
* BaseTypeDescriptor() returns the TypeDescriptor for Integer
* NonRefType() will return INTEGER_TYPE for the first two. For an
* attribute of type count_set NonRefType() would return
* AGGREGATE_TYPE
* NonRefTypeDescriptor() returns the TypeDescriptor for Integer
* for the first two and a TypeDescriptor for an
* aggregate for the last.
*
* \sa NonRefType()
* \sa NonRefTypeDescriptor()
*/
///@{
PrimitiveType BaseType() const;
const TypeDescriptor * BaseTypeDescriptor() const;
///@}
// the first PrimitiveType that is not REFERENCE_TYPE (the first
// TypeDescriptor *_referentType that does not have REFERENCE_TYPE
// for it's fundamentalType variable). This would return the same
// as BaseType() for fundamental types. An aggregate type
// would return AGGREGATE_TYPE then you could find out the type of
// an element by calling AggrElemType(). Select types
// would work the same?
/**
* the first PrimitiveType that is not REFERENCE_TYPE (the first
* TypeDescriptor *_referentType that does not have REFERENCE_TYPE
* for it's fundamentalType variable). This would return the same
* as BaseType() for fundamental types. An aggregate type
* would return AGGREGATE_TYPE then you could find out the type of
* an element by calling AggrElemType(). Select types
* would work the same?
*
* \sa BaseType()
*/
///@{
PrimitiveType NonRefType() const;
const TypeDescriptor * NonRefTypeDescriptor() const;
///@}
int IsAggrType() const;
PrimitiveType AggrElemType() const;
@@ -1063,7 +1108,7 @@ class SC_CORE_EXPORT Inverse_attribute : public AttrDescriptor {
const char * _inverted_attr_id;
const char * _inverted_entity_id;
protected:
AttrDescriptor * _inverted_attr; // not implemented
const AttrDescriptor * _inverted_attr; // not implemented (?!) (perhaps this means "not used"?)
public:
Inverse_attribute(
@@ -1098,22 +1143,23 @@ class SC_CORE_EXPORT Inverse_attribute : public AttrDescriptor {
_inverted_entity_id = iei;
}
/// FIXME not implemented
class AttrDescriptor * inverted_attr_() {
/// FIXME not implemented (?!) (perhaps this means "not set"?)
//set _inverted_attr in an extra init step in generated code? any other way to ensure pointers are valid?
const class AttrDescriptor * inverted_attr_() const {
return _inverted_attr;
}
void inverted_attr_( AttrDescriptor * ia ) {
void inverted_attr_( const AttrDescriptor * ia ) {
_inverted_attr = ia;
}
// below are obsolete (and not implemented anyway)
class AttrDescriptor * InverseAttribute() {
return _inverted_attr;
}
void InverseOf( AttrDescriptor * invAttr ) {
_inverted_attr = invAttr;
}
// class AttrDescriptor * InverseAttribute() {
// return _inverted_attr;
// }
// void InverseOf( AttrDescriptor * invAttr ) {
// _inverted_attr = invAttr;
// }
};
/** \class SchRename
@@ -1464,9 +1510,14 @@ class SC_CORE_EXPORT EnumTypeDescriptor : public TypeDescriptor {
* will be building the same thing but using the new schema info.
* nodes (i.e. EntityDesc nodes) for each entity.
*/
class Registry;
class SC_CORE_EXPORT EntityDescriptor : public TypeDescriptor {
protected:
//used in InitIAttrs so we don't have to #include registry.h
SDAI_LOGICAL _abstractEntity;
SDAI_LOGICAL _extMapping;
// does external mapping have to be used to create an instance of
@@ -1493,6 +1544,8 @@ class SC_CORE_EXPORT EntityDescriptor : public TypeDescriptor {
virtual ~EntityDescriptor();
void InitIAttrs( Registry & reg, const char * schNm );
const char * GenerateExpress( std::string & buf ) const;
const char * QualifiedName( std::string & s ) const;
+2 -2
View File
@@ -162,9 +162,9 @@ Inverse_attributeLinkNode * Inverse_attributeList::AddNode( Inverse_attribute *
return node;
}
InverseAItr::InverseAItr( const Inverse_attributeList & iaList )
InverseAItr::InverseAItr( const Inverse_attributeList * iaList )
: ial( iaList ) {
cur = ( Inverse_attributeLinkNode * )( ial.GetHead() );
cur = ( Inverse_attributeLinkNode * )( ial->GetHead() );
}
InverseAItr::~InverseAItr() {
+1 -1
View File
@@ -324,7 +324,7 @@ SDAI_Application_instance * Registry::ObjCreate( const char * nm, const char * s
se->Error().severity( SEVERITY_WARNING );
se->Error().UserMsg( "ENTITY requires external mapping" );
}
se->eDesc = entd;
se->setEDesc( entd );
return se;
} else {
return ENTITY_NULL;
+15 -15
View File
@@ -58,7 +58,7 @@ STEPaggregate & STEPaggregate::ShallowCopy( const STEPaggregate & a ) {
/// do not require exchange file format
Severity STEPaggregate::AggrValidLevel( const char * value, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int optional, char * tokenList, int addFileId,
int clearError ) {
std::string buf;
@@ -78,7 +78,7 @@ Severity STEPaggregate::AggrValidLevel( const char * value, ErrorDescriptor * er
/// require exchange file format
Severity STEPaggregate::AggrValidLevel( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int optional, char * tokenList, int addFileId,
int clearError ) {
std::string buf;
@@ -97,7 +97,7 @@ Severity STEPaggregate::AggrValidLevel( istream & in, ErrorDescriptor * err,
/// if exchangeFileFormat == 1 then paren delims are required.
Severity STEPaggregate::ReadValue( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int addFileId, int assignVal, int exchangeFileFormat,
const char * ) {
(void) insts; //not used in ReadValue() for this class
@@ -203,7 +203,7 @@ Severity STEPaggregate::ReadValue( istream & in, ErrorDescriptor * err,
}
Severity STEPaggregate::StrToVal( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int addFileId ) {
istringstream in( ( char * )s );
return ReadValue( in, err, elem_type, insts, addFileId, 1, 0 );
@@ -212,7 +212,7 @@ Severity STEPaggregate::StrToVal( const char * s, ErrorDescriptor * err,
///////////////////////////////////////////////////////////////////////////////
Severity STEPaggregate::STEPread( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int addFileId, const char * currSch ) {
return ReadValue( in, err, elem_type, insts, addFileId, 1, 1, currSch );
}
@@ -476,7 +476,7 @@ EntityAggregate::~EntityAggregate() {
/// if exchangeFileFormat == 1 then delims are required.
Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int addFileId, int assignVal,
int exchangeFileFormat, const char * ) {
ErrorDescriptor errdesc;
@@ -618,7 +618,7 @@ SingleLinkNode * EntityNode::NewNode() {
Severity EntityNode::StrToVal( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId ) {
InstMgrBase * insts, int addFileId ) {
SDAI_Application_instance * se = ReadEntityRef( s, err, ",)", insts,
addFileId );
if( se != S_ENTITY_NULL ) {
@@ -639,20 +639,20 @@ Severity EntityNode::StrToVal( const char * s, ErrorDescriptor * err,
Severity EntityNode::StrToVal( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId ) {
InstMgrBase * insts, int addFileId ) {
return STEPread( in, err, elem_type, insts, addFileId );
}
Severity EntityNode::STEPread( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId ) {
InstMgrBase * insts, int addFileId ) {
istringstream in( ( char * )s );
return STEPread( in, err, elem_type, insts, addFileId );
}
Severity EntityNode::STEPread( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId ) {
InstMgrBase * insts, int addFileId ) {
SDAI_Application_instance * se = ReadEntityRef( in, err, ",)", insts,
addFileId );
if( se != S_ENTITY_NULL ) {
@@ -714,7 +714,7 @@ SelectAggregate::~SelectAggregate() {
/// if exchangeFileFormat == 1 then delims are required.
Severity SelectAggregate::ReadValue( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int addFileId, int assignVal,
int exchangeFileFormat, const char * currSch ) {
ErrorDescriptor errdesc;
@@ -858,7 +858,7 @@ SingleLinkNode * SelectNode::NewNode() {
Severity SelectNode::StrToVal( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId ) {
InstMgrBase * insts, int addFileId ) {
(void) elem_type; //unused
(void) addFileId; //unused
istringstream in( ( char * )s );
@@ -870,20 +870,20 @@ Severity SelectNode::StrToVal( const char * s, ErrorDescriptor * err,
Severity SelectNode::StrToVal( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId, const char * currSch ) {
InstMgrBase * insts, int addFileId, const char * currSch ) {
return STEPread( in, err, elem_type, insts, addFileId, currSch );
}
Severity SelectNode::STEPread( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId ) {
InstMgrBase * insts, int addFileId ) {
istringstream in( ( char * )s );
return STEPread( in, err, elem_type, insts, addFileId );
}
Severity SelectNode::STEPread( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId, const char * currSch ) {
InstMgrBase * insts, int addFileId, const char * currSch ) {
(void) elem_type; //unused
if( !node ) {
cerr << "Internal error: " << __FILE__ << ": " << __LINE__ << "\n"
+56 -45
View File
@@ -12,7 +12,7 @@
* and is not subject to copyright.
*/
class InstMgr;
class InstMgrBase;
class STEPaggregate;
class TypeDescriptor;
@@ -42,7 +42,7 @@ class SC_CORE_EXPORT STEPaggregate : public SingleLinkList {
virtual Severity ReadValue( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0,
InstMgrBase * insts, int addFileId = 0,
int assignVal = 1, int ExchangeFileFormat = 1,
const char * currSch = 0 );
public:
@@ -52,22 +52,22 @@ class SC_CORE_EXPORT STEPaggregate : public SingleLinkList {
}
virtual Severity AggrValidLevel( const char * value, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int optional, char * tokenList, int addFileId = 0,
int clearError = 0 );
virtual Severity AggrValidLevel( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type, InstMgr * insts,
const TypeDescriptor * elem_type, InstMgrBase * insts,
int optional, char * tokenList, int addFileId = 0,
int clearError = 0 );
// INPUT
virtual Severity StrToVal( const char * s, ErrorDescriptor * err = 0,
const TypeDescriptor * elem_type = 0,
InstMgr * insts = 0, int addFileId = 0 );
InstMgrBase * insts = 0, int addFileId = 0 );
virtual Severity STEPread( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type = 0,
InstMgr * insts = 0, int addFileId = 0,
InstMgrBase * insts = 0, int addFileId = 0,
const char * currSch = 0 );
// OUTPUT
virtual const char * asStr( std::string & s ) const;
@@ -88,6 +88,7 @@ class SC_CORE_EXPORT STEPaggregate : public SingleLinkList {
** \class GenericAggregate
** This class supports LIST OF:
** SELECT_TYPE, BINARY_TYPE, GENERIC_TYPE, ENUM_TYPE, UNKNOWN_TYPE type
** FIXME this class, as well as SelectAggregate, for SELECTs?!
******************************************************************/
class SC_CORE_EXPORT GenericAggregate : public STEPaggregate {
public:
@@ -97,9 +98,10 @@ class SC_CORE_EXPORT GenericAggregate : public STEPaggregate {
GenericAggregate();
virtual ~GenericAggregate();
};
typedef GenericAggregate * GenericAggregateH;
typedef GenericAggregate * GenericAggregate_ptr;
typedef GenericAggregate_ptr GenericAggregate_var;
typedef GenericAggregate * GenericAggregateH;
typedef GenericAggregate * GenericAggregate_ptr;
typedef const GenericAggregate * GenericAggregate_ptr_c;
typedef GenericAggregate_ptr GenericAggregate_var;
/******************************************************************************
**
@@ -109,7 +111,7 @@ class SC_CORE_EXPORT EntityAggregate : public STEPaggregate {
public:
virtual Severity ReadValue( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0,
InstMgrBase * insts, int addFileId = 0,
int assignVal = 1, int ExchangeFileFormat = 1,
const char * currSch = 0 );
@@ -119,9 +121,10 @@ class SC_CORE_EXPORT EntityAggregate : public STEPaggregate {
EntityAggregate();
virtual ~EntityAggregate();
};
typedef EntityAggregate * EntityAggregateH;
typedef EntityAggregate * EntityAggregate_ptr;
typedef EntityAggregate_ptr EntityAggregate_var;
typedef EntityAggregate * EntityAggregateH;
typedef EntityAggregate * EntityAggregate_ptr;
typedef const EntityAggregate * EntityAggregate_ptr_c;
typedef EntityAggregate_ptr EntityAggregate_var;
/****************************************************************//**
** \class SelectAggregate
@@ -131,7 +134,7 @@ class SC_CORE_EXPORT SelectAggregate : public STEPaggregate {
public:
virtual Severity ReadValue( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0,
InstMgrBase * insts, int addFileId = 0,
int assignVal = 1, int ExchangeFileFormat = 1,
const char * currSch = 0 );
@@ -141,9 +144,10 @@ class SC_CORE_EXPORT SelectAggregate : public STEPaggregate {
SelectAggregate();
virtual ~SelectAggregate();
};
typedef SelectAggregate * SelectAggregateH;
typedef SelectAggregate * SelectAggregate_ptr;
typedef SelectAggregate_ptr SelectAggregate_var;
typedef SelectAggregate * SelectAggregateH;
typedef SelectAggregate * SelectAggregate_ptr;
typedef const SelectAggregate * SelectAggregate_ptr_c;
typedef SelectAggregate_ptr SelectAggregate_var;
/****************************************************************//**
** \class StringAggregate
@@ -157,9 +161,10 @@ class SC_CORE_EXPORT StringAggregate : public STEPaggregate {
StringAggregate();
virtual ~StringAggregate();
};
typedef StringAggregate * StringAggregateH;
typedef StringAggregate * StringAggregate_ptr;
typedef StringAggregate_ptr StringAggregate_var;
typedef StringAggregate * StringAggregateH;
typedef StringAggregate * StringAggregate_ptr;
typedef const StringAggregate * StringAggregate_ptr_c;
typedef StringAggregate_ptr StringAggregate_var;
/****************************************************************//**
@@ -174,9 +179,10 @@ class SC_CORE_EXPORT BinaryAggregate : public STEPaggregate {
BinaryAggregate();
virtual ~BinaryAggregate();
};
typedef BinaryAggregate * BinaryAggregateH;
typedef BinaryAggregate * BinaryAggregate_ptr;
typedef BinaryAggregate_ptr BinaryAggregate_var;
typedef BinaryAggregate * BinaryAggregateH;
typedef BinaryAggregate * BinaryAggregate_ptr;
typedef const BinaryAggregate * BinaryAggregate_ptr_c;
typedef BinaryAggregate_ptr BinaryAggregate_var;
/**************************************************************//**
** \class EnumAggregate
@@ -190,9 +196,10 @@ class SC_CORE_EXPORT EnumAggregate : public STEPaggregate {
EnumAggregate();
virtual ~EnumAggregate();
};
typedef EnumAggregate * EnumAggregateH;
typedef EnumAggregate * EnumAggregate_ptr;
typedef EnumAggregate_ptr EnumAggregate_var;
typedef EnumAggregate * EnumAggregateH;
typedef EnumAggregate * EnumAggregate_ptr;
typedef const EnumAggregate * EnumAggregate_ptr_c;
typedef EnumAggregate_ptr EnumAggregate_var;
class SC_CORE_EXPORT LOGICALS : public EnumAggregate {
public:
@@ -201,9 +208,10 @@ class SC_CORE_EXPORT LOGICALS : public EnumAggregate {
LOGICALS();
virtual ~LOGICALS();
};
typedef LOGICALS * LogicalsH;
typedef LOGICALS * LOGICALS_ptr;
typedef LOGICALS_ptr LOGICALS_var;
typedef LOGICALS * LogicalsH;
typedef LOGICALS * LOGICALS_ptr;
typedef const LOGICALS * LOGICALS_ptr_c;
typedef LOGICALS_ptr LOGICALS_var;
SC_CORE_EXPORT LOGICALS * create_LOGICALS();
@@ -215,8 +223,9 @@ class SC_CORE_EXPORT BOOLEANS : public EnumAggregate {
virtual ~BOOLEANS();
};
typedef BOOLEANS * BOOLEANS_ptr;
typedef BOOLEANS_ptr BOOLEANS_var;
typedef BOOLEANS * BOOLEANS_ptr;
typedef const BOOLEANS * BOOLEANS_ptr_c;
typedef BOOLEANS_ptr BOOLEANS_var;
SC_CORE_EXPORT BOOLEANS * create_BOOLEANS();
@@ -229,9 +238,10 @@ class SC_CORE_EXPORT RealAggregate : public STEPaggregate {
RealAggregate();
virtual ~RealAggregate();
};
typedef RealAggregate * RealAggregateH;
typedef RealAggregate * RealAggregate_ptr;
typedef RealAggregate_ptr RealAggregate_var;
typedef RealAggregate * RealAggregateH;
typedef RealAggregate * RealAggregate_ptr;
typedef const RealAggregate * RealAggregate_ptr_c;
typedef RealAggregate_ptr RealAggregate_var;
class SC_CORE_EXPORT IntAggregate : public STEPaggregate {
@@ -242,9 +252,10 @@ class SC_CORE_EXPORT IntAggregate : public STEPaggregate {
IntAggregate();
virtual ~IntAggregate();
};
typedef IntAggregate * IntAggregateH;
typedef IntAggregate * IntAggregate_ptr;
typedef IntAggregate_ptr IntAggregate_var;
typedef IntAggregate * IntAggregateH;
typedef IntAggregate * IntAggregate_ptr;
typedef const IntAggregate * IntAggregate_ptr_c;
typedef IntAggregate_ptr IntAggregate_var;
///////////////////////////////////////////////////////////////////////////////
@@ -311,17 +322,17 @@ class SC_CORE_EXPORT EntityNode : public STEPnode {
// INPUT
virtual Severity StrToVal( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0 );
InstMgrBase * insts, int addFileId = 0 );
virtual Severity StrToVal( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0 );
InstMgrBase * insts, int addFileId = 0 );
virtual Severity STEPread( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0 );
InstMgrBase * insts, int addFileId = 0 );
virtual Severity STEPread( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0 );
InstMgrBase * insts, int addFileId = 0 );
// OUTPUT
virtual const char * asStr( std::string & s );
virtual const char * STEPwrite( std::string & s, const char * = 0 );
@@ -370,18 +381,18 @@ class SC_CORE_EXPORT SelectNode : public STEPnode {
// INPUT
virtual Severity StrToVal( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0 );
InstMgrBase * insts, int addFileId = 0 );
virtual Severity StrToVal( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0,
InstMgrBase * insts, int addFileId = 0,
const char * currSch = 0 );
virtual Severity STEPread( const char * s, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0 );
InstMgrBase * insts, int addFileId = 0 );
virtual Severity STEPread( istream & in, ErrorDescriptor * err,
const TypeDescriptor * elem_type,
InstMgr * insts, int addFileId = 0,
InstMgrBase * insts, int addFileId = 0,
const char * currSch = 0 );
// OUTPUT
virtual const char * asStr( std::string & s );
+3 -3
View File
@@ -46,7 +46,7 @@ const int Real_Num_Precision = REAL_NUM_PRECISION;
///////////////////////////////////////////////////////////////////////////////
/// the value of the attribute is assigned from the supplied string
Severity STEPattribute::StrToVal( const char * s, InstMgr * instances, int addFileId ) {
Severity STEPattribute::StrToVal( const char * s, InstMgrBase * instances, int addFileId ) {
if( _redefAttr ) {
return _redefAttr->StrToVal( s, instances, addFileId );
}
@@ -194,7 +194,7 @@ Severity STEPattribute::StrToVal( const char * s, InstMgr * instances, int addFi
** value >= SEVERITY_WARNING means program can continue parsing input,
** value <= SEVERITY_INPUT_ERROR is fatal read error
******************************************************************/
Severity STEPattribute::STEPread( istream & in, InstMgr * instances, int addFileId,
Severity STEPattribute::STEPread( istream & in, InstMgrBase * instances, int addFileId,
const char * currSch, bool strict ) {
// The attribute has been redefined by the attribute pointed
@@ -1069,7 +1069,7 @@ bool sameADesc( const STEPattribute & a1, const STEPattribute & a2 ) {
* *note* for string values - (attrValue = 0) => string value does not exist,
* attrValue exists it is valid.
******************************************************************/
Severity STEPattribute::ValidLevel( const char * attrValue, ErrorDescriptor * error, InstMgr * im, bool clearError ) {
Severity STEPattribute::ValidLevel( const char * attrValue, ErrorDescriptor * error, InstMgrBase * im, bool clearError ) {
if( clearError ) {
ClearErrorMsg();
}
+11 -21
View File
@@ -28,7 +28,7 @@
typedef double real;
class InstMgr;
class InstMgrBase;
class SDAI_Application_instance;
class STEPaggregate;
class SCLundefined;
@@ -42,10 +42,10 @@ class EntityDescriptor;
extern SC_CORE_EXPORT int SetErrOnNull( const char * attrValue, ErrorDescriptor * error );
extern SC_CORE_EXPORT SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err, const char * tokenList,
InstMgr * instances, int addFileId );
InstMgrBase * instances, int addFileId );
extern SC_CORE_EXPORT SDAI_Application_instance * ReadEntityRef( const char * s, ErrorDescriptor * err, const char * tokenList,
InstMgr * instances, int addFileId );
InstMgrBase * instances, int addFileId );
extern SC_CORE_EXPORT Severity EntityValidLevel( SDAI_Application_instance * se,
const TypeDescriptor * ed, ///< entity type that entity se needs to match. (this must be an EntityDescriptor)
@@ -55,13 +55,13 @@ extern SC_CORE_EXPORT Severity EntityValidLevel( const char * attrValue, ///< st
const TypeDescriptor * ed, /**< entity type that entity in attrValue (if it exists) needs
* to match. (this must be an EntityDescriptor)
*/
ErrorDescriptor * err, InstMgr * im, int clearError );
ErrorDescriptor * err, InstMgrBase * im, int clearError );
////////////////////
////////////////////
extern SC_CORE_EXPORT SDAI_Application_instance * STEPread_reference( const char * s, ErrorDescriptor * err,
InstMgr * instances, int addFileId );
InstMgrBase * instances, int addFileId );
////////////////////
extern SC_CORE_EXPORT int QuoteInString( istream & in );
@@ -132,9 +132,9 @@ class SC_CORE_EXPORT STEPattribute {
///////////// Read, Write, Assign attr value
Severity StrToVal( const char * s, InstMgr * instances = 0,
Severity StrToVal( const char * s, InstMgrBase * instances = 0,
int addFileId = 0 );
Severity STEPread( istream & in = cin, InstMgr * instances = 0,
Severity STEPread( istream & in = cin, InstMgrBase * instances = 0,
int addFileId = 0, const char * currSch = NULL, bool strict = true );
/// return the attr value as a string
@@ -146,19 +146,7 @@ class SC_CORE_EXPORT STEPattribute {
Severity set_null();
/** \fn Integer()
* \fn Real()
* \fn Number()
* \fn String()
* \fn Binary()
* \fn Entity()
* \fn Aggregate()
* \fn Enum()
* \fn Logical()
* \fn Boolean()
* \fn Select()
* \fn Undefined()
*
/**
* These functions verify that the attribute contains the requested type and
* returns a pointer. The pointer is null if the requested type does not match.
*
@@ -166,6 +154,7 @@ class SC_CORE_EXPORT STEPattribute {
* \sa NonRefType()
* \sa is_null()
*/
///@{
SDAI_Integer * Integer();
SDAI_Real * Real();
SDAI_Real * Number();
@@ -178,6 +167,7 @@ class SC_CORE_EXPORT STEPattribute {
SDAI_BOOLEAN * Boolean();
SDAI_Select * Select();
SCLundefined * Undefined();
///@}
/// allows direct access to the union containing attr data (dangerous!)
attrUnion * Raw() {
@@ -232,7 +222,7 @@ class SC_CORE_EXPORT STEPattribute {
_error.ClearErrorMsg();
}
Severity ValidLevel( const char* attrValue, ErrorDescriptor* error, InstMgr* im, bool clearError = true );
Severity ValidLevel( const char* attrValue, ErrorDescriptor* error, InstMgrBase * im, bool clearError = true );
////////////////// Constructors
+25 -27
View File
@@ -12,13 +12,13 @@ ReadStdKeyword( istream & in, std::string & buf, int skipInitWS );
STEPcomplex::STEPcomplex( Registry * registry, int fileid )
: SDAI_Application_instance( fileid, 1 ), sc( 0 ), _registry( registry ), visited( 0 ) {
: SDAI_Application_instance( fileid, true ), sc( 0 ), _registry( registry ), visited( 0 ) {
head = this;
}
STEPcomplex::STEPcomplex( Registry * registry, const std::string ** names,
int fileid, const char * schnm )
: SDAI_Application_instance( fileid, 1 ), sc( 0 ), _registry( registry ), visited( 0 ) {
: SDAI_Application_instance( fileid, true ), sc( 0 ), _registry( registry ), visited( 0 ) {
char * nms[BUFSIZ];
int j, k;
@@ -38,7 +38,7 @@ STEPcomplex::STEPcomplex( Registry * registry, const std::string ** names,
STEPcomplex::STEPcomplex( Registry * registry, const char ** names, int fileid,
const char * schnm )
: SDAI_Application_instance( fileid, 1 ), sc( 0 ), _registry( registry ), visited( 0 ) {
: SDAI_Application_instance( fileid, true ), sc( 0 ), _registry( registry ), visited( 0 ) {
head = this;
Initialize( names, schnm );
@@ -204,17 +204,14 @@ void STEPcomplex::AssignDerives() {
}
}
/** \fn STEPcomplex::AddEntityPart
** this function should only be called for the head entity
** in the list of entity parts.
*/
/** this function should only be called for the head entity in the list of entity parts. */
void STEPcomplex::AddEntityPart( const char * name ) {
STEPcomplex * scomplex;
if( name ) {
scomplex = new STEPcomplex( _registry, STEPfile_id );
scomplex->BuildAttrs( name );
if( scomplex->eDesc ) {
scomplex->InitIAttrs();
scomplex->head = this;
AppendEntity( scomplex );
} else {
@@ -231,9 +228,10 @@ STEPcomplex * STEPcomplex::EntityPart( const char * name, const char * currSch )
if( scomp->eDesc->CurrName( name, currSch ) ) {
return scomp;
}
} else
} else {
cout << "Bug in STEPcomplex::EntityPart(): entity part has "
<< "no EntityDescriptor\n";
}
scomp = scomp->sc;
}
return 0;
@@ -258,7 +256,7 @@ const EntityDescriptor * STEPcomplex::IsA( const EntityDescriptor * ed ) const {
}
}
Severity STEPcomplex::ValidLevel( ErrorDescriptor * error, InstMgr * im,
Severity STEPcomplex::ValidLevel( ErrorDescriptor * error, InstMgrBase * im,
int clearError ) {
(void) error; //unused
(void) im;
@@ -276,7 +274,7 @@ void STEPcomplex::AppendEntity( STEPcomplex * stepc ) {
}
// READ
Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgr * instance_set,
Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgrBase * instance_set,
istream & in, const char * currSch, bool /*useTechCor*/, bool /*strict*/ ) {
char c;
std::string typeNm;
@@ -303,8 +301,7 @@ Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgr * instance_
in >> ws;
c = in.peek();
if( c != '(' ) {
_error.AppendToDetailMsg(
"Missing open paren before entity attr values.\n" );
_error.AppendToDetailMsg( "Missing open paren before entity attr values.\n" );
cout << "ERROR: missing open paren\n";
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
STEPread_error( c, 0, in, currSch );
@@ -312,15 +309,12 @@ Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgr * instance_
}
stepc = EntityPart( typeNm.c_str(), currSch );
if( stepc )
stepc->SDAI_Application_instance::STEPread( id, addFileId,
instance_set, in,
currSch );
else {
cout << "ERROR: complex entity part \"" << typeNm
<< "\" does not exist.\n";
_error.AppendToDetailMsg(
"Complex entity part of instance does not exist.\n" );
if( stepc ) {
//WARNING need to seek to the correct position when this is done... how?
stepc->SDAI_Application_instance::STEPread( id, addFileId, instance_set, in, currSch );
} else {
cout << "ERROR: complex entity part \"" << typeNm << "\" does not exist." << endl;;
_error.AppendToDetailMsg( "Complex entity part of instance does not exist.\n" );
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
STEPread_error( c, 0, in, currSch );
return _error.severity();
@@ -328,12 +322,16 @@ Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgr * instance_
in >> ws;
c = in.peek();
}
if( c != ')' )
cout <<
"ERROR: missing ending paren for complex entity instance.\n";
else {
if( c != ')' ) {
cout << "ERROR: missing ending paren for complex entity instance." << endl;
} else {
in.get( c ); // read the closing paren
}
} else {
_error.AppendToDetailMsg( "Complex instances must begin with '('. Found '" );
_error.AppendToDetailMsg( c );
_error.AppendToDetailMsg( "' instead.\n" );
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
}
return _error.severity();
}
@@ -341,7 +339,7 @@ Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgr * instance_
//FIXME delete this?
#ifdef buildwhileread
// READ
Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgr * instance_set,
Severity STEPcomplex::STEPread( int id, int addFileId, class InstMgrBase * instance_set,
istream & in, const char * currSch ) {
ClearError( 1 );
STEPfile_id = id;
+18 -3
View File
@@ -13,13 +13,28 @@
typedef std::list<void *> STEPcomplex_attr_data_list;
typedef std::list<void *>::iterator STEPcomplex_attr_data;
/** TODO add a method to ed to create iAttr structure
* either call same method in all parents, or add their iAttrs in some other way
* does not need to be ordered
*
* simply move iAttrs into eDesc? don't recall whether that data can be safely shared amongst multiple instances or not
* if it can't be shared, we'd need to enforce copy-on-write somehow - perhaps making iAttrs protected with a getter
* that requires an instance as an arg - i.e. inst->eDesc->iAttrSetup(inst)
*
* what about inheritance? should each eDesc include all iattrs, or assemble the list as necessary at runtime?
* eDesc should assemble a complete list on demand at runtime...
*
* How to initialize iAttrs for SC's? BuildIAttrs( eDesc )
*/
class SC_CORE_EXPORT STEPcomplex : public SDAI_Application_instance {
public: //TODO should this _really_ be public?!
STEPcomplex * sc;
STEPcomplex * head;
Registry * _registry;
int visited; ///< used when reading (or as you wish?)
STEPcomplex_attr_data_list _attr_data_list;
STEPcomplex_attr_data_list _attr_data_list; //< what is this for?
public:
STEPcomplex( Registry * registry, int fileid );
STEPcomplex( Registry * registry, const std::string ** names, int fileid,
@@ -34,11 +49,11 @@ class SC_CORE_EXPORT STEPcomplex : public SDAI_Application_instance {
virtual const EntityDescriptor * IsA( const EntityDescriptor * ) const;
virtual Severity ValidLevel( ErrorDescriptor * error, InstMgr * im,
virtual Severity ValidLevel( ErrorDescriptor * error, InstMgrBase * im,
int clearError = 1 );
// READ
virtual Severity STEPread( int id, int addFileId,
class InstMgr * instance_set,
class InstMgrBase * instance_set,
istream & in = cin, const char * currSch = NULL,
bool useTechCor = true, bool strict = true );
+66
View File
@@ -0,0 +1,66 @@
/** \file STEPinvAttrList.cc
* derived from STEPattributeList.cc
*/
#include <STEPinvAttrList.h>
#include <ExpDict.h>
#include "sc_memmgr.h"
invAttrListNodeI::invAttrListNodeI(Inverse_attribute* a, setterI_t s, getterI_t g): invAttrListNode(a), set( s ), get( g ) {}
invAttrListNodeA::invAttrListNodeA(Inverse_attribute* a, setterA_t s, getterA_t g): invAttrListNode(a), set( s ), get( g ) {}
invAttrListNodeI::~invAttrListNodeI() {}
invAttrListNodeA::~invAttrListNodeA() {}
STEPinvAttrList::STEPinvAttrList() {}
STEPinvAttrList::~STEPinvAttrList() {}
invAttrListNode * STEPinvAttrList::operator []( int n ) {
int x = 0;
invAttrListNode * a = ( invAttrListNode * )head;
int cnt = EntryCount();
if( n < cnt ) {
while( a && ( x < n ) ) {
a = ( invAttrListNode * )( a->next );
x++;
}
}
if( !a ) {
cerr << "\nERROR in STEP Core library: " << __FILE__ << ":"
<< __LINE__ << "\n" << _POC_ << "\n\n";
}
return a;
}
int STEPinvAttrList::list_length() {
return EntryCount();
}
void STEPinvAttrList::push( Inverse_attribute * a, setterA_t s, getterA_t g ) {
invAttrListNode * an = ( invAttrListNode * )head;
// if the attribute already exists in the list, don't push it
while( an ) {
if( a == ( an -> attr ) ) {
return;
}
an = ( invAttrListNode * )( an->next );
}
invAttrListNode * ialn = (invAttrListNode *) new invAttrListNodeA( a, s, g );
AppendNode( ialn );
}
void STEPinvAttrList::push( Inverse_attribute * a, setterI_t s, getterI_t g ) {
invAttrListNode * an = ( invAttrListNode * )head;
// if the attribute already exists in the list, don't push it
while( an ) {
if( a == ( an -> attr ) ) {
return;
}
an = ( invAttrListNode * )( an->next );
}
invAttrListNode * ialn = (invAttrListNode *) new invAttrListNodeI( a, s, g );
AppendNode( ialn );
}
+100
View File
@@ -0,0 +1,100 @@
#ifndef _STEPinvAttrList_h
#define _STEPinvAttrList_h 1
/// FIXME remove these classes? not sure there's a use for them now...
/** \file STEPinvAttrList.h
* derived from STEPattributeList.h
*
* Similar to Inverse_attributeList, but this list also contains pointers to the setter and getter.
*
* \sa Inverse_attributeList
*/
class Inverse_attribute;
#include <sc_export.h>
#include <SingleLinkList.h>
class STEPinvAttrList;
class EntityAggregate;
class SDAI_Application_instance;
/** setterI_t, getterI_t: for inverse attrs that only allow a single (Instance) reference
* setterA_t, getterA_t: for inverse attrs that allow multiple (Aggregate) refs
* @{
*/
typedef void ( *setterI_t )( SDAI_Application_instance *, const SDAI_Application_instance * );
typedef SDAI_Application_instance * ( *getterI_t )( const SDAI_Application_instance * );
typedef void ( *setterA_t )( SDAI_Application_instance *, const EntityAggregate * );
typedef EntityAggregate * ( *getterA_t )( const SDAI_Application_instance * );
/** @} */
/** invAttrListNode: base class + 2 derived classes, one for single instances and one for aggregates
* @{
*/
class SC_CORE_EXPORT invAttrListNode : public SingleLinkNode {
friend class STEPinvAttrList;
protected:
invAttrListNode( Inverse_attribute * a ) : attr( a ) {};
Inverse_attribute * attr;
public:
Inverse_attribute * inverseADesc() {
return attr;
}
virtual bool isAggregate() = 0;
};
class SC_CORE_EXPORT invAttrListNodeI : public invAttrListNode {
friend class STEPinvAttrList;
protected:
setterI_t set;
getterI_t get;
public:
invAttrListNodeI( Inverse_attribute * a, setterI_t s, getterI_t g );
virtual ~invAttrListNodeI();
setterI_t setter() {
return set;
}
getterI_t getter() {
return get;
}
virtual bool isAggregate() {
return false;
}
};
class SC_CORE_EXPORT invAttrListNodeA : public invAttrListNode {
friend class STEPinvAttrList;
protected:
setterA_t set;
getterA_t get;
public:
invAttrListNodeA( Inverse_attribute * a, setterA_t s, getterA_t g );
virtual ~invAttrListNodeA();
setterA_t setter() {
return set;
}
getterA_t getter() {
return get;
}
virtual bool isAggregate() {
return true;
}
};
/** @} */
/// Similar to Inverse_attributeList, but this list also contains pointers to the setter and getter.
class SC_CORE_EXPORT STEPinvAttrList : public SingleLinkList {
public:
STEPinvAttrList();
virtual ~STEPinvAttrList();
invAttrListNode * operator []( int n );
int list_length();
void push( Inverse_attribute * a, setterA_t s, getterA_t g );
void push( Inverse_attribute * a, setterI_t s, getterI_t g );
};
#endif
+7 -1
View File
@@ -39,7 +39,13 @@
#include <mgrnodearray.h>
class SC_CORE_EXPORT InstMgr {
class SC_CORE_EXPORT InstMgrBase {
public:
virtual MgrNodeBase * FindFileId( int fileId ) = 0;
virtual ~InstMgrBase() {};
};
class SC_CORE_EXPORT InstMgr : public InstMgrBase {
protected:
int maxFileId;
int _ownsInstances; // if true will delete instances inside destructor
+9 -1
View File
@@ -29,13 +29,21 @@ class DisplayNode;
class InstMgr;
class SC_CORE_EXPORT MgrNodeBase : public GenericNode {
public:
virtual inline SDAI_Application_instance * GetSTEPentity() {
abort();
};
virtual ~MgrNodeBase() {};
};
//////////////////////////////////////////////////////////////////////////////
// class MgrNode
// If you delete this object, it deletes the SDAI_Application_instance it represents,
// the DisplayNode, and removes itself from any list it is in.
//////////////////////////////////////////////////////////////////////////////
class SC_CORE_EXPORT MgrNode : public GenericNode {
class SC_CORE_EXPORT MgrNode : public MgrNodeBase {
friend class GenNodeList;
friend class MgrNodeList;
friend class InstMgr;
+3 -2
View File
@@ -38,9 +38,10 @@ typedef std::string Express_id;
class TypeDescriptor;
class EntityDescriptor;
class SelectTypeDescriptor;
class InstMgr;
class InstMgrBase;
#include "STEPattributeList.h"
#include "STEPinvAttrList.h"
class STEPattributeList;
class STEPattribute;
@@ -226,7 +227,7 @@ typedef SDAI_Application_instance * STEPentityH;
extern SC_CORE_EXPORT SDAI_Application_instance *
ReadEntityRef( istream & in, ErrorDescriptor * err, const char * tokenList,
InstMgr * instances, int addFileId );
InstMgrBase * instances, int addFileId );
#define SdaiInteger SDAI_Integer
#define SdaiReal SDAI_Real
+73 -19
View File
@@ -10,13 +10,16 @@
* and is not subject to copyright.
*/
#include <map>
#include <sdai.h>
#include <instmgr.h>
#include <STEPcomplex.h>
#include <STEPattribute.h>
#include <read_func.h> //for ReadTokenSeparator, used when comments are inside entities
#include "sdaiApplication_instance.h"
#include "superInvAttrIter.h"
SDAI_Application_instance NilSTEPentity;
/**************************************************************//**
@@ -32,22 +35,22 @@ SDAI_Application_instance NilSTEPentity;
SDAI_Application_instance::SDAI_Application_instance()
: _cur( 0 ),
eDesc( NULL ),
_complex( false ),
STEPfile_id( 0 ),
p21Comment( std::string( "" ) ),
eDesc( NULL ),
headMiEntity( 0 ),
nextMiEntity( 0 ),
_complex( 0 ) {
nextMiEntity( 0 ) {
}
SDAI_Application_instance::SDAI_Application_instance( int fileid, int complex )
: _cur( 0 ),
eDesc( NULL ),
_complex( complex ),
STEPfile_id( fileid ),
p21Comment( std::string( "" ) ),
eDesc( NULL ),
headMiEntity( 0 ),
nextMiEntity( 0 ),
_complex( complex ) {
nextMiEntity( 0 ) {
}
SDAI_Application_instance::~SDAI_Application_instance() {
@@ -70,6 +73,27 @@ SDAI_Application_instance::~SDAI_Application_instance() {
}
}
/// initialize inverse attrs
/// eDesc->InitIAttrs() must have been called previously
/// call once per instance (*not* once per class)
void SDAI_Application_instance::InitIAttrs() {
assert( eDesc && "eDesc must be set; please report this bug." );
InverseAItr iai( &( eDesc->InverseAttr() ) );
const Inverse_attribute * ia;
iAstruct s;
memset( &s, 0, sizeof s );
while( 0 != ( ia = iai.NextInverse_attribute() ) ) {
iAMap.insert( iAMap_t::value_type( ia, s ) );
}
superInvAttrIter siai( eDesc );
while( !siai.empty() ) {
ia = siai.next();
assert( ia && "Null inverse attr!" );
iAMap.insert( iAMap_t::value_type( ia, s ) );
}
}
SDAI_Application_instance * SDAI_Application_instance::Replicate() {
char errStr[BUFSIZ];
if( IsComplex() ) {
@@ -251,7 +275,7 @@ const EntityDescriptor * SDAI_Application_instance::IsA( const EntityDescriptor
/**
* Checks the validity of the current attribute values for the entity
*/
Severity SDAI_Application_instance::ValidLevel( ErrorDescriptor * error, InstMgr * im,
Severity SDAI_Application_instance::ValidLevel( ErrorDescriptor * error, InstMgrBase * im,
int clearError ) {
ErrorDescriptor err;
if( clearError ) {
@@ -477,7 +501,7 @@ void SDAI_Application_instance::STEPread_error( char c, int i, istream & in, con
** Status:
******************************************************************/
Severity SDAI_Application_instance::STEPread( int id, int idIncr,
InstMgr * instance_set, istream & in,
InstMgrBase * instance_set, istream & in,
const char * currSch, bool useTechCor, bool strict ) {
STEPfile_id = id;
char c = '\0';
@@ -631,7 +655,7 @@ Severity SDAI_Application_instance::STEPread( int id, int idIncr,
/// read an entity reference and return a pointer to the SDAI_Application_instance
SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err, const char * tokenList,
InstMgr * instances, int addFileId ) {
InstMgrBase * instances, int addFileId ) {
char c;
char errStr[BUFSIZ];
errStr[0] = '\0';
@@ -640,8 +664,7 @@ SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err,
in >> c;
switch( c ) {
case '@':
err->AppendToDetailMsg(
"Use of @ instead of # to identify entity.\n" );
err->AppendToDetailMsg( "Use of @ instead of # to identify entity.\n" );
err->GreaterSeverity( SEVERITY_WARNING );
// no break statement here on purpose
case '#': {
@@ -675,7 +698,7 @@ SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err,
// lookup which object has id as its instance id
SDAI_Application_instance * inst;
/* If there is a ManagerNode it should have a SDAI_Application_instance */
MgrNode * mn = 0;
MgrNodeBase * mn = 0;
mn = instances->FindFileId( id );
if( mn ) {
inst = mn->GetSTEPentity() ;
@@ -715,7 +738,7 @@ SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err,
/// read an entity reference and return a pointer to the SDAI_Application_instance
SDAI_Application_instance * ReadEntityRef( const char * s, ErrorDescriptor * err, const char * tokenList,
InstMgr * instances, int addFileId ) {
InstMgrBase * instances, int addFileId ) {
istringstream in( ( char * )s );
return ReadEntityRef( in, err, tokenList, instances, addFileId );
}
@@ -755,9 +778,9 @@ Severity EntityValidLevel( SDAI_Application_instance * se,
// DAVE: Can an entity be used in an Express TYPE so that this
// EntityDescriptor would have type REFERENCE_TYPE -- it looks like NO
else if( se->eDesc ) {
else if( se->getEDesc() ) {
// is se a descendant of ed?
if( se->eDesc->IsA( ed ) ) {
if( se->getEDesc()->IsA( ed ) ) {
return SEVERITY_NULL;
} else {
if( se->IsComplex() ) {
@@ -822,7 +845,7 @@ Severity EntityValidLevel( const char * attrValue, // string contain entity ref
// attrValue (if it exists) needs
// to match. (this must be an
// EntityDescriptor)
ErrorDescriptor * err, InstMgr * im, int clearError ) {
ErrorDescriptor * err, InstMgrBase * im, int clearError ) {
char tmp [BUFSIZ];
tmp[0] = '\0';
char messageBuf [BUFSIZ];
@@ -834,7 +857,7 @@ Severity EntityValidLevel( const char * attrValue, // string contain entity ref
}
int fileId;
MgrNode * mn = 0;
MgrNodeBase * mn = 0;
// fmtstr1 contains "#%d %ns" where n is BUFSIZ-1
fmtstr1 << " #%d %" << BUFSIZ - 1 << "s ";
@@ -896,9 +919,40 @@ STEPattribute * SDAI_Application_instance::NextAttribute() {
return 0;
}
return &attributes [_cur - 1];
}
int SDAI_Application_instance::AttributeCount() {
return attributes.list_length();
}
const iAstruct SDAI_Application_instance::getInvAttr( const Inverse_attribute * const ia ) const {
iAstruct ias;
memset( &ias, 0, sizeof ias );
iAMap_t::const_iterator it = iAMap.find( ia );
if( it != iAMap.end() ) {
ias = (*it).second;
}
return ias;
}
const SDAI_Application_instance::iAMap_t::value_type SDAI_Application_instance::getInvAttr( const char * name ) const {
iAMap_t::const_iterator it = iAMap.begin();
for( ; it != iAMap.end(); ++it ) {
if( 0 == strcmp( it->first->Name(), name) ) {
return *it;
}
}
iAstruct z;
memset( &z, 0, sizeof z );
iAMap_t::value_type nil( NULL, z );
return nil;
}
void SDAI_Application_instance::setInvAttr( const Inverse_attribute * const ia, const iAstruct ias ) {
iAMap_t::iterator it = iAMap.find(ia);
if( it != iAMap.end() ) {
it->second = ias;
} else {
iAMap.insert( iAMap_t::value_type( ia, ias ) );
}
}
+47 -17
View File
@@ -13,21 +13,39 @@
*/
#include <sc_export.h>
#include <map>
#include <iostream>
///////////////////////////////////////////////////////////////////////////////
// SDAI_Application_instance used to be STEPentity
//class STEPinvAttrList;
class EntityAggregate;
class Inverse_attribute;
typedef struct {
// bool aggregate;
union {
EntityAggregate * a;
SDAI_Application_instance * i;
};
} iAstruct;
/** @class
* this used to be STEPentity
*/
class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI {
private:
int _cur; // provides a built-in way of accessing attributes in order.
public:
typedef std::map< const Inverse_attribute * const, iAstruct> iAMap_t;
protected:
const EntityDescriptor * eDesc;
iAMap_t iAMap;
bool _complex;
public: //TODO make these private?
STEPattributeList attributes;
int STEPfile_id;
int STEPfile_id; //TODO are neg values ever used (signalling)? if not, make unsigned?
ErrorDescriptor _error;
std::string p21Comment;
// registry additions
const EntityDescriptor * eDesc;
/**
** head entity for multiple inheritance. If it is null then this
@@ -40,18 +58,23 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI {
/// these form a chain of other entity parents for multiple inheritance
SDAI_Application_instance * nextMiEntity;
protected:
int _complex;
public:
SDAI_Application_instance();
SDAI_Application_instance( int fileid, int complex = 0 );
virtual ~SDAI_Application_instance();
int IsComplex() const {
bool IsComplex() const {
return _complex;
}
/// initialize inverse attribute list
void InitIAttrs();
void setEDesc( const EntityDescriptor * const ed ) {
eDesc = ed;
}
const EntityDescriptor * getEDesc() const {
return eDesc;
}
void StepFileId( int fid ) {
STEPfile_id = fid;
}
@@ -74,7 +97,7 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI {
virtual const EntityDescriptor * IsA( const EntityDescriptor * ) const;
virtual Severity ValidLevel( ErrorDescriptor * error, InstMgr * im,
virtual Severity ValidLevel( ErrorDescriptor * error, InstMgrBase * im,
int clearError = 1 );
ErrorDescriptor & Error() {
return _error;
@@ -92,27 +115,34 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI {
void ResetAttributes() {
_cur = 0;
}
// ACCESS inverse attributes
const iAstruct getInvAttr( const Inverse_attribute * const ia ) const;
const iAMap_t::value_type getInvAttr( const char * name ) const;
void setInvAttr( const Inverse_attribute * const ia, const iAstruct ias );
const iAMap_t & getInvAttrs() const {
return iAMap;
}
// READ
virtual Severity STEPread( int id, int addFileId,
class InstMgr * instance_set,
istream & in = cin, const char * currSch = NULL,
class InstMgrBase * instance_set,
std::istream & in = std::cin, const char * currSch = NULL,
bool useTechCor = true, bool strict = true );
virtual void STEPread_error( char c, int i, std::istream& in, const char * schnm );
// WRITE
virtual void STEPwrite( ostream & out = cout, const char * currSch = NULL,
virtual void STEPwrite( std::ostream & out = std::cout, const char * currSch = NULL,
int writeComments = 1 );
virtual const char * STEPwrite( std::string & buf, const char * currSch = NULL );
void WriteValuePairs( ostream & out, const char * currSch = NULL,
void WriteValuePairs( std::ostream & out, const char * currSch = NULL,
int writeComments = 1, int mixedCase = 1 );
void STEPwrite_reference( ostream & out = cout );
void STEPwrite_reference( std::ostream & out = std::cout );
const char * STEPwrite_reference( std::string & buf );
void beginSTEPwrite( ostream & out = cout ); ///< writes out the SCOPE section
void endSTEPwrite( ostream & out = cout );
void beginSTEPwrite( std::ostream & out = std::cout ); ///< writes out the SCOPE section
void endSTEPwrite( std::ostream & out = std::cout );
// MULTIPLE INHERITANCE
int MultipleInheritance() {
+3 -3
View File
@@ -155,7 +155,7 @@ void SDAI_Select::nullify() {
}
Severity SDAI_Select::SelectValidLevel( const char * attrValue, ErrorDescriptor * err,
InstMgr * im ) {
InstMgrBase * im ) {
SDAI_Select * tmp = NewSelect();
Severity s = SEVERITY_NULL;
@@ -166,7 +166,7 @@ Severity SDAI_Select::SelectValidLevel( const char * attrValue, ErrorDescriptor
}
Severity SDAI_Select::StrToVal( const char * Val, const char * selectType,
ErrorDescriptor * err, InstMgr * instances ) {
ErrorDescriptor * err, InstMgrBase * instances ) {
severity( SEVERITY_NULL );
if( SetUnderlyingType( CanBe( selectType ) ) )
@@ -228,7 +228,7 @@ Severity SDAI_Select::StrToVal( const char * Val, const char * selectType,
* This function does the following:
*/
Severity SDAI_Select::STEPread( istream & in, ErrorDescriptor * err,
InstMgr * instances, const char * utype,
InstMgrBase * instances, const char * utype,
int addFileId, const char * currSch ) {
char c = '\0';
std::string tmp;
+5 -5
View File
@@ -62,7 +62,7 @@ class SC_CORE_EXPORT SDAI_Select {
void nullify();
Severity SelectValidLevel( const char * attrValue, ErrorDescriptor * err,
InstMgr * im );
InstMgrBase * im );
// reading and writing
const char * STEPwrite( std::string & s, const char * currSch = 0 ) const;
@@ -76,17 +76,17 @@ class SC_CORE_EXPORT SDAI_Select {
Severity StrToVal( const char * val, const char * selectType,
ErrorDescriptor * err, InstMgr * instances = 0 );
ErrorDescriptor * err, InstMgrBase * instances = 0 );
virtual Severity StrToVal_content( const char *,
InstMgr * instances = 0 ) = 0;
InstMgrBase * instances = 0 ) = 0;
Severity STEPread( istream & in, ErrorDescriptor * err,
InstMgr * instances = 0, const char * utype = 0,
InstMgrBase * instances = 0, const char * utype = 0,
int addFileId = 0, const char * = NULL );
// abstract function
virtual Severity STEPread_content( istream & in = cin,
InstMgr * instances = 0,
InstMgrBase * instances = 0,
const char * utype = 0,
int addFileId = 0,
const char * currSch = 0 ) = 0;
+72
View File
@@ -0,0 +1,72 @@
#ifndef SUPERINVATTRITER_H
#define SUPERINVATTRITER_H
#include "SubSuperIterators.h"
#include "ExpDict.h"
/**
* this class implements an iterator for inverse attributes in an EntityDescriptor's supertypes
* makes use of supertypesIterator and InverseAItr
*
* TODO verify that this iterates correctly!
*/
class superInvAttrIter {
protected:
supertypesIterator sit;
InverseAItr * invIter;
const Inverse_attribute * nextInv;
bool isempty; ///< if true, don't try to access invIter - it is not initialized
public:
/// WARNING this will not iterate over the ia's in the first ed, only in its supertypes! change that?
superInvAttrIter( const EntityDescriptor * ed ): sit( ed ), invIter(0), nextInv( 0 ), isempty( false ) {
reset();
}
void reset( const EntityDescriptor * ed = 0 ) {
sit.reset( ed );
if( invIter ) {
delete invIter;
invIter = 0;
}
if( sit.empty() ) {
isempty = true;
} else {
invIter = new InverseAItr( &( sit.current()->InverseAttr() ) );
nextInv = invIter->NextInverse_attribute();
if( !nextInv ) {
next();
}
}
}
~superInvAttrIter() {
if( invIter ) {
delete invIter;
invIter = 0;
}
}
const EntityDescriptor * currentEDesc() {
if( isempty ) {
return NULL;
}
return sit.current();
}
bool empty() {
if( isempty ) {
return true;
}
return ( !sit.hasNext() && !nextInv );
}
const Inverse_attribute * next() {
if( isempty ) {
return NULL;
}
const Inverse_attribute * ia = nextInv;
/* if we're on the last inverse attr for the current super, go to the next super
* keep going until we find an ia or run out of supers */
while( ( 0 == ( nextInv = invIter->NextInverse_attribute() ) ) && sit.hasNext() ) {
invIter->ResetItr( &( sit.next()->InverseAttr() ) );
}
return ia;
}
};
#endif //SUPERINVATTRITER_H
@@ -45,11 +45,12 @@ class TestSdaiSelect: public SDAI_Select {
SDAI_Select* NewSelect(){ return (SDAI_Select *)0; }
BASE_TYPE ValueType() const { return sdaiBOOLEAN; }
void STEPwrite_content( std::ostream& /*o*/, const char* /*a*/ ) const {}
Severity StrToVal_content( const char* /*a*/, InstMgr* /*m*/ ) { return SEVERITY_NULL; }
Severity STEPread_content(std::istream& i, InstMgr* m, const char* c, int n, const char* d) {
Severity StrToVal_content( const char* /*a*/, InstMgrBase* /*m*/ ) { return SEVERITY_NULL; }
Severity STEPread_content(std::istream& i, InstMgrBase* m, const char* c, int n, const char* d) {
(void)i; (void)m; (void)c; (void)n; (void)d; return SEVERITY_NULL;
}
};
/// \return true for success
bool testOperatorEq() {
Schema * sch = 0;
+6 -6
View File
@@ -90,17 +90,17 @@ class SC_UTILS_EXPORT ErrorDescriptor {
std::string UserMsg() const {
return _userMsg;
}
void UserMsg( const char * );
void UserMsg( const char * msg );
void UserMsg( const std::string msg ) {
_userMsg.assign( msg );
}
void AppendToUserMsg( const char * );
void AppendToUserMsg( const char * msg );
void AppendToUserMsg( const char c );
void AppendToUserMsg( const std::string & msg ) {
_userMsg.append( msg );
}
void PrependToUserMsg( const char * );
void PrependToUserMsg( const char * msg );
std::string DetailMsg() const {
return _detailMsg;
@@ -108,12 +108,12 @@ class SC_UTILS_EXPORT ErrorDescriptor {
void DetailMsg( const std::string msg ) {
_detailMsg.assign( msg );
}
void DetailMsg( const char * );
void AppendToDetailMsg( const char * );
void DetailMsg( const char * msg );
void AppendToDetailMsg( const char * msg );
void AppendToDetailMsg( const std::string & msg ) {
_detailMsg.append( msg );
}
void PrependToDetailMsg( const char * );
void PrependToDetailMsg( const char * msg );
void AppendToDetailMsg( const char c );
Severity AppendFromErrorArg( ErrorDescriptor * err ) {
+1
View File
@@ -14,6 +14,7 @@ set(exp2cxx_SOURCES
class_strings.c
selects.c
multpass.c
rules.c
collect.cc
complexlist.cc
entlist.cc
+1 -1
View File
@@ -36,7 +36,7 @@ const char * ENTITYget_classname( Entity ent ) {
* in many circumstances, this func will return a short string rather than using that buffer
* buf_siz is ignored in those cases since it is meaningless
*/
const char * TYPE_get_ctype( const Type t, char * retval, int buf_siz ) {
const char * TYPE_get_ctype( const Type t, char * retval, size_t buf_siz ) {
const char * ptr = "_ptr", * var = "_var", * agg = "_agg";
const char * overflowMsg = "buffer overflow detected at %s:%d!";
Class_Of_Type ctype;
+4 -9
View File
@@ -118,8 +118,7 @@ void USEREFout( Schema schema, Dictionary refdict, Linked_List reflist, char * t
} else {
fprintf( file, " %s::schema->ref_interface_list_()->Append(is);\n", SCHEMAget_name( schema ) );
}
}
LISTod
} LISTod
if( !refdict ) {
return;
@@ -228,8 +227,7 @@ void MODELPrintConstructorBody( Entity entity, FILES * files, Schema schema ) {
fprintf( files->lib, " eep = new SDAI_Entity_extent;\n" );
fprintf( files->lib, " eep->definition_(%s::%s%s);\n",
SCHEMAget_name( schema ), ENT_PREFIX, ENTITYget_name( entity ) );
fprintf( files->lib, " eep->definition_(%s::%s%s);\n", SCHEMAget_name( schema ), ENT_PREFIX, ENTITYget_name( entity ) );
fprintf( files->lib, " _folders.Append(eep);\n\n" );
}
@@ -239,11 +237,8 @@ void MODELPrint( Entity entity, FILES * files, Schema schema, int index ) {
DEBUG( "Entering MODELPrint for %s\n", n );
n = ENTITYget_classname( entity );
fprintf( files->lib, "\n%s__set_var SdaiModel_contents_%s::%s_get_extents()\n",
n, SCHEMAget_name( schema ), n );
fprintf( files->lib,
"{\n return (%s__set_var)((_folders.retrieve(%d))->instances_());\n}\n",
n, index );
fprintf( files->lib, "\n%s__set_var SdaiModel_contents_%s::%s_get_extents() {\n", n, SCHEMAget_name( schema ), n );
fprintf( files->lib, "\n return (%s__set_var)((_folders.retrieve(%d))->instances_());\n}\n", n, index );
DEBUG( "DONE MODELPrint\n" ) ;
}
+1
View File
@@ -115,6 +115,7 @@ void print_file( Express );
void resolution_success( void );
void SCHEMAprint( Schema schema, FILES* files, void* complexCol, int suffix );
const char * FundamentalType( const Type t, int report_reftypes );
void numberAttributes( Scope scope );
/*Variable*/
#define VARis_simple_explicit(a) (!VARis_type_shifter(a))
+365 -231
View File
@@ -14,8 +14,10 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7.
#include <stdlib.h>
#include <assert.h>
#include <sc_mkdir.h>
#include "classes.h"
#include <ordered_attrs.h>
#include <type.h>
#include "classes.h"
#include "classes_attribute.h"
#include <sc_trace_fprintf.h>
@@ -71,8 +73,79 @@ char * generate_attribute_func_name( Variable a, char * out ) {
return out;
}
/* return true if attr needs const and non-const getters */
bool attrIsObj( Type t ) {
/* if( TYPEis_select( t ) || TYPEis_aggregate( t ) ) {
/ * const doesn't make sense for pointer types * /
return false;
} else */
Class_Of_Type class = TYPEget_type( t );
switch( class ) {
case number_:
case real_:
case integer_:
case boolean_:
case logical_:
return false;
default:
return true;
}
}
/** print attr descriptors to the namespace
* \p attr_count_tmp is a _copy_ of attr_count
*/
void ATTRnames_print( Entity entity, FILE* file ) {
char attrnm [BUFSIZ];
LISTdo( ENTITYget_attributes( entity ), v, Variable ) {
generate_attribute_name( v, attrnm );
fprintf( file, " extern %s *%s%d%s%s;\n",
( VARget_inverse( v ) ? "Inverse_attribute" : ( VARis_derived( v ) ? "Derived_attribute" : "AttrDescriptor" ) ),
ATTR_PREFIX, v->idx,
( VARis_derived( v ) ? "D" : ( VARis_type_shifter( v ) ? "R" : ( VARget_inverse( v ) ? "I" : "" ) ) ),
attrnm );
} LISTod
}
/** prints out the current attribute for an entity's c++ class definition
* skips inverse attrs, since they are now stored in a map
* \param entity entity being processed
* \param a attribute being processed
* \param file file being written to
*/
void DataMemberPrintAttr( Entity entity, Variable a, FILE * file ) {
char attrnm [BUFSIZ];
const char * ctype, * etype;
if( !VARget_inverse( a ) && ( VARget_initializer( a ) == EXPRESSION_NULL ) ) {
ctype = TYPEget_ctype( VARget_type( a ) );
generate_attribute_name( a, attrnm );
if( !strcmp( ctype, "SCLundefined" ) ) {
printf( "WARNING: in entity %s, ", ENTITYget_name( entity ) );
printf( " the type for attribute %s is not fully implemented\n", attrnm );
}
if( TYPEis_entity( VARget_type( a ) ) ) {
fprintf( file, " SDAI_Application_instance_ptr _%s;", attrnm );
} else if( TYPEis_aggregate( VARget_type( a ) ) ) {
fprintf( file, " %s_ptr _%s;", ctype, attrnm );
} else {
fprintf( file, " %s _%s;", ctype, attrnm );
}
if( VARget_optional( a ) ) {
fprintf( file, " // OPTIONAL" );
}
if( isAggregate( a ) ) {
/* if it's a named type, comment the type */
if( ( etype = TYPEget_name ( TYPEget_nonaggregate_base_type( VARget_type( a ) ) ) ) ) {
fprintf( file, " // of %s\n", etype );
}
}
fprintf( file, "\n" );
}
}
/**************************************************************//**
** Procedure: ATTRsign_access_method
** Procedure: ATTRsign_access_methods
** Parameters: const Variable a -- attribute to print
access method signature for
** FILE* file -- file being written to
@@ -94,8 +167,21 @@ void ATTRsign_access_methods( Variable a, FILE * file ) {
strncpy( ctype, AccessType( t ), BUFSIZ );
ctype[BUFSIZ-1] = '\0';
fprintf( file, " %s %s() const;\n", ctype, attrnm );
fprintf( file, " void %s (const %s x);\n\n", attrnm, ctype );
if( attrIsObj( t ) ) {
/* object or pointer, so provide const and non-const methods */
if( TYPEis_entity( t ) || TYPEis_select( t ) || TYPEis_aggregate( t ) ) {
/* it's a typedef, so prefacing with 'const' won't do what we desire */
fprintf( file, " %s_c %s() const;\n", ctype, attrnm );
} else {
fprintf( file, " const %s %s() const;\n", ctype, attrnm );
}
fprintf( file, " %s %s();\n", ctype, attrnm );
} else {
fprintf( file, " %s %s() const;\n", ctype, attrnm );
}
fprintf( file, " void %s( const %s x );\n", attrnm, ctype );
fprintf( file, "\n" );
return;
}
@@ -115,19 +201,18 @@ void ATTRsign_access_methods( Variable a, FILE * file ) {
** Side Effects:
** Status: complete 7/15/93 by DDH
******************************************************************/
void ATTRprint_access_methods_get_head( const char * classnm, Variable a,
FILE * file ) {
void ATTRprint_access_methods_get_head( const char * classnm, Variable a, FILE * file, bool returnsConst ) {
Type t = VARget_type( a );
char ctype [BUFSIZ]; /* return type of the get function */
char funcnm [BUFSIZ]; /* name of member function */
generate_attribute_func_name( a, funcnm );
/* ///////////////////////////////////////////////// */
strncpy( ctype, AccessType( t ), BUFSIZ );
ctype[BUFSIZ-1] = '\0';
fprintf( file, "\n%s %s::%s() const ", ctype, classnm, funcnm );
if( TYPEis_entity( t ) || TYPEis_select( t ) || TYPEis_aggregate( t ) ) {
fprintf( file, "\n%s%s %s::%s() ", ctype, ( returnsConst ? "_c" : "" ), classnm, funcnm );
} else {
fprintf( file, "\n%s%s %s::%s() ", ( returnsConst ? "const " : "" ), ctype, classnm, funcnm );
}
return;
}
@@ -147,7 +232,7 @@ void ATTRprint_access_methods_get_head( const char * classnm, Variable a,
** Side Effects:
** Status: complete 7/15/93 by DDH
******************************************************************/
void ATTRprint_access_methods_put_head( CONST char * entnm, Variable a, FILE * file ) {
void ATTRprint_access_methods_put_head( const char * entnm, Variable a, FILE * file ) {
Type t = VARget_type( a );
char ctype [BUFSIZ];
@@ -162,40 +247,251 @@ void ATTRprint_access_methods_put_head( CONST char * entnm, Variable a, FILE * f
return;
}
void AGGRprint_access_methods( CONST char * entnm, Variable a, FILE * file,
/** print access methods for aggregate attribute */
void AGGRprint_access_methods( const char * entnm, Variable a, FILE * file,
char * ctype, char * attrnm ) {
ATTRprint_access_methods_get_head( entnm, a, file );
fprintf( file, "{\n" );
ATTRprint_access_methods_get_head( entnm, a, file, false );
fprintf( file, "{\n if( !_%s ) {\n _%s = new %s;\n }\n", attrnm, attrnm, TypeName( a->type ) );
fprintf( file, " return ( %s ) %s_%s;\n}\n", ctype, ( ( a->type->u.type->body->base ) ? "" : "& " ), attrnm );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n" );
fprintf( file, " return ( %s ) %s_%s;\n}\n", ctype, ( ( a->type->u.type->body->base ) ? "" : "& " ), attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n _%s%sShallowCopy( * x );\n}\n", attrnm, ( ( a->type->u.type->body->base ) ? "->" : "." ) );
fprintf( file, "{\n if( !_%s ) {\n _%s = new %s;\n }\n", attrnm, attrnm, TypeName( a->type ) );
fprintf( file, " _%s%sShallowCopy( * x );\n}\n", attrnm, ( ( a->type->u.type->body->base ) ? "->" : "." ) );
return;
}
/**************************************************************//**
** Procedure: ATTRprint_access_method
** Parameters: const Variable a -- attribute to find the type for
** FILE* file -- file being written to
** Returns: name to be used for the type of the c++ access functions
** Description: prints the access method based on the attribute type
** i.e. get and put value access functions defined in a class
** generated for an entity.
** Side Effects:
** Status: complete 1/15/91
** updated 17-Feb-1992 to print to library file instead of header
** updated 15-July-1993 to call the get/put head functions by DDH
******************************************************************/
void ATTRprint_access_methods( CONST char * entnm, Variable a, FILE * file ) {
/** print logging code for access methods for attrs that are entities
* \p var is the variable name, minus preceding underscore, or null if 'x' is to be used
* \p dir is either "returned" or "assigned"
*/
void ATTRprint_access_methods_entity_logging( const char * entnm, const char * funcnm, const char * nm,
const char * var, const char * dir, FILE * file ) {
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if( *logStream ) {\n" );
fprintf( file, " logStream -> open( SCLLOGFILE, ios::app );\n" );
fprintf( file, " if( !( %s%s == S_ENTITY_NULL ) )\n {\n", ( var ? "_" : "" ), ( var ? var : "x" ) );
fprintf( file, " *logStream << time( NULL ) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, dir );
fprintf( file, " *logStream << \"reference to Sdai%s entity #\"", nm );
fprintf( file, " << %s%s->STEPfile_id << std::endl;\n", ( var ? "_" : "" ), ( var ? var : "x" ) );
fprintf( file, " } else {\n" );
fprintf( file, " *logStream << time( NULL ) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, dir );
fprintf( file, " *logStream << \"null entity\" << std::endl;\n }\n" );
fprintf( file, " logStream->close();\n" );
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
}
/** print access methods for attrs that are entities
* prints const and non-const getters and a setter
*/
void ATTRprint_access_methods_entity( const char * entnm, const char * attrnm, const char * funcnm, const char * nm,
const char * ctype, Variable a, FILE * file ) {
fprintf( file, "{\n" );
ATTRprint_access_methods_entity_logging( entnm, funcnm, nm, attrnm, "returned", file);
fprintf( file, " if( !_%s ) {\n _%s = new %s;\n }\n", attrnm, attrnm, TypeName( a->type ) );
fprintf( file, " return (%s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n" );
ATTRprint_access_methods_entity_logging( entnm, funcnm, nm, attrnm, "returned", file);
fprintf( file, " return (%s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
ATTRprint_access_methods_entity_logging( entnm, funcnm, nm, 0, "assigned", file);
fprintf( file, " _%s = x;\n}\n", attrnm );
return;
}
/** logging code for string and binary attribute access methods */
void ATTRprint_access_methods_str_bin_logging( const char * entnm, const char * attrnm, const char * funcnm, FILE * file, bool setter ) {
if( print_logging ) {
const char * direction = ( setter ? "assigned" : "returned" );
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
if( setter ) {
fprintf( file, " if(!_%s.is_null())\n {\n", attrnm );
} else {
fprintf( file, " if(x)\n {\n" );
}
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, direction );
if( setter ) {
fprintf( file, " *logStream << _%s << std::endl;\n", attrnm );
} else {
fprintf( file, " *logStream << x << std::endl;\n" );
}
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, direction );
fprintf( file, " *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
}
}
/** print access methods for string or bin attribute */
void ATTRprint_access_methods_str_bin( const char * entnm, const char * attrnm, const char * funcnm,
const char * ctype, Variable a, FILE * file ) {
fprintf( file, "{\n" );
ATTRprint_access_methods_str_bin_logging( entnm, attrnm, funcnm, file, true );
fprintf( file, " return _%s;\n}\n", attrnm );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n" );
ATTRprint_access_methods_str_bin_logging( entnm, attrnm, funcnm, file, true );
fprintf( file, " return (const %s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
ATTRprint_access_methods_str_bin_logging( entnm, attrnm, funcnm, file, false );
fprintf( file, " _%s = x;\n}\n", attrnm );
return;
}
/** print logging code for access methods for enumeration attribute */
void ATTRprint_access_methods_enum_logging( const char * entnm, const char * attrnm, const char * funcnm, FILE * file, bool setter ) {
if( print_logging ) {
const char * direction = ( setter ? "assigned" : "returned" );
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
if( !setter ) {
fprintf( file, " if(!_%s.is_null())\n {\n", attrnm );
}
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, direction );
if( setter ) {
fprintf( file, " *logStream << _%s.element_at(x) << std::endl;\n", attrnm );
} else {
fprintf( file, " *logStream << _%s.element_at(_%s.asInt()) << std::endl;\n", attrnm, attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, direction );
fprintf( file, " *logStream << \"unset\" << std::endl;\n }\n" );
}
fprintf( file, " }\n#endif\n" );
}
}
/** print access methods for enumeration attribute */
void ATTRprint_access_methods_enum( const char * entnm, const char * attrnm, const char * funcnm,
Variable a, Type t, FILE * file ) {
fprintf( file, "{\n" );
ATTRprint_access_methods_enum_logging( entnm, attrnm, funcnm, file, false );
fprintf( file, " return (%s) _%s;\n}\n", EnumName( TYPEget_name( t ) ), attrnm );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n" );
ATTRprint_access_methods_enum_logging( entnm, attrnm, funcnm, file, false );
fprintf( file, " return (const %s) _%s;\n}\n", EnumName( TYPEget_name( t ) ), attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
ATTRprint_access_methods_enum_logging( entnm, attrnm, funcnm, file, true );
fprintf( file, " _%s.put( x );\n}\n", attrnm );
return;
}
/** print logging code for access methods for logical or boolean attribute */
void ATTRprint_access_methods_log_bool_logging( const char * entnm, const char * attrnm, const char * funcnm, FILE * file, bool setter ) {
if( print_logging ) {
const char * direction = ( setter ? "assigned" : "returned" );
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
if( !setter ) {
/* fprintf( file, " logStream->open(SCLLOGFILE,ios::app);\n" ); */
fprintf( file, " if(!_%s.is_null())\n {\n", attrnm );
}
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, direction );
if( setter ) {
fprintf( file, " *logStream << _%s.element_at(x) << std::endl;\n", attrnm );
} else {
fprintf( file, " *logStream << _%s.element_at(_%s.asInt()) << std::endl;\n", attrnm, attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() %s: \";\n", entnm, funcnm, direction );
fprintf( file, " *logStream << \"unset\" << std::endl;\n }\n" );
/* fprintf( file, " logStream->close();\n" ); */
}
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
}
/** print access methods for logical or boolean attribute */
void ATTRprint_access_methods_log_bool( const char * entnm, const char * attrnm, const char * funcnm,
const char * ctype, Variable a, FILE * file ) {
fprintf( file, "const {\n" );
ATTRprint_access_methods_log_bool_logging( entnm, attrnm, funcnm, file, false );
fprintf( file, " return (const %s) _%s;\n}\n", ctype, attrnm );
/* don't need a const method for logical or boolean
* ATTRprint_access_methods_get_head( entnm, a, file, true );
* fprintf( file, "const {\n" );
* ATTRprint_access_methods_log_bool_logging( entnm, attrnm, funcnm, file, false );
* fprintf( file, " return (const %s) _%s;\n}\n", ctype, attrnm );
*/
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
ATTRprint_access_methods_log_bool_logging( entnm, attrnm, funcnm, file, true );
fprintf( file, " _%s.put (x);\n}\n", attrnm );
return;
}
/** print access methods for inverse attrs, using iAMap */
void INVprint_access_methods( const char * entnm, const char * attrnm, const char * funcnm, const char * nm,
const char * ctype, Variable a, FILE * file, Schema schema ) {
char iaName[BUFSIZ] = {0};
snprintf( iaName, BUFSIZ - 1, "%s::%s%d%s%s", SCHEMAget_name( schema ), ATTR_PREFIX, a->idx,
/* can it ever be anything but "I"? */
( VARis_derived( a ) ? "D" : ( VARis_type_shifter( a ) ? "R" : ( VARget_inverse( a ) ? "I" : "" ) ) ), attrnm );
if( isAggregate( a ) ) {
/* following started as AGGRprint_access_methods() */
ATTRprint_access_methods_get_head( entnm, a, file, false );
fprintf( file, "{\n iAstruct ias = getInvAttr( %s );\n if( !ias.a ) {\n", iaName );
fprintf( file, " ias.a = new EntityAggregate;\n setInvAttr( %s, ias );\n }\n", iaName );
fprintf( file, " return ias.a;\n}\n" );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n" );
fprintf( file, " return getInvAttr( %s ).a;\n}\n", iaName );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n iAstruct ias;\n ias.a = x;\n setInvAttr( %s, ias );\n}\n", iaName );
} else {
ATTRprint_access_methods_get_head( entnm, a, file, false );
/* following started as ATTRprint_access_methods_entity() */
fprintf( file, "{\n" );
ATTRprint_access_methods_entity_logging( entnm, funcnm, nm, attrnm, "returned", file);
fprintf( file, " iAstruct ias = getInvAttr( %s );\n", iaName );
fprintf( file, " /* no 'new' - doesn't make sense to create an SDAI_Application_instance\n * since it isn't generic like EntityAggregate */\n");
fprintf( file, " return (%s) ias.i;\n}\n", ctype );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n" );
ATTRprint_access_methods_entity_logging( entnm, funcnm, nm, attrnm, "returned", file);
fprintf( file, " iAstruct ias = getInvAttr( %s );\n", iaName );
fprintf( file, " return (%s) ias.i;\n}\n", ctype );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
ATTRprint_access_methods_entity_logging( entnm, funcnm, nm, 0, "assigned", file);
fprintf( file, " iAstruct ias;\n ias.i = x; setInvAttr( %s, ias );\n}\n", iaName );
}
}
/** prints the access method based on the attribute type
* i.e. get and put value access functions defined in a class
* generated for an entity.
* \param entnm the name of the current entity
* \param a attribute to print methods for
* \param file file being written to
*/
void ATTRprint_access_methods( const char * entnm, Variable a, FILE * file, Schema schema ) {
Type t = VARget_type( a );
Class_Of_Type class;
Class_Of_Type classType;
char ctype [BUFSIZ]; /* type of data member */
char attrnm [BUFSIZ];
char membernm[BUFSIZ];
char funcnm [BUFSIZ]; /* name of member function */
char nm [BUFSIZ];
/* I believe nm has the name of the underlying type without Sdai in
front of it */
/* I believe nm has the name of the underlying type without Sdai in front of it */
if( TYPEget_name( t ) ) {
strncpy( nm, FirstToUpper( TYPEget_name( t ) ), BUFSIZ - 1 );
}
@@ -204,152 +500,38 @@ void ATTRprint_access_methods( CONST char * entnm, Variable a, FILE * file ) {
generate_attribute_name( a, attrnm );
strcpy( membernm, attrnm );
membernm[0] = toupper( membernm[0] );
class = TYPEget_type( t );
classType = TYPEget_type( t );
strncpy( ctype, AccessType( t ), BUFSIZ );
if( VARget_inverse( a ) ) {
INVprint_access_methods( entnm, attrnm, funcnm, nm, ctype, a, file, schema );
return;
}
if( isAggregate( a ) ) {
AGGRprint_access_methods( entnm, a, file, ctype, attrnm );
return;
}
ATTRprint_access_methods_get_head( entnm, a, file );
ATTRprint_access_methods_get_head( entnm, a, file, false );
/* case TYPE_ENTITY: */
if( class == entity_ ) {
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " logStream->open(SCLLOGFILE,ios::app);\n" );
fprintf( file, " if(! (_%s == S_ENTITY_NULL) )\n {\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"reference to Sdai%s entity #\" << _%s->STEPfile_id << std::endl;\n",
nm, attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"null entity\" << std::endl;\n }\n" );
fprintf( file, " logStream->close();\n" );
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " return (%s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "\n" );
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " logStream->open(SCLLOGFILE,ios::app);\n" );
fprintf( file, " if(! (x == S_ENTITY_NULL) )\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() assigned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"reference to Sdai%s entity #\" << x->STEPfile_id << std::endl;\n",
nm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() assigned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"null entity\" << std::endl;\n }\n" );
fprintf( file, " logStream->close();\n" );
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " _%s = x;\n}\n", attrnm );
if( classType == entity_ ) {
ATTRprint_access_methods_entity( entnm, attrnm, funcnm, nm, ctype, a, file );
return;
}
/* case TYPE_LOGICAL: */
if( ( class == boolean_ ) || ( class == logical_ ) ) {
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " logStream->open(SCLLOGFILE,ios::app);\n" );
fprintf( file, " if(!_%s.is_null())\n {\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s.element_at(_%s.asInt()) << std::endl;\n",
attrnm, attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n" );
fprintf( file, " logStream->close();\n" );
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " return (%s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() assigned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s.element_at(x) << std::endl;\n", attrnm );
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " _%s.put (x);\n}\n", attrnm );
return;
if( ( classType == boolean_ ) || ( classType == logical_ ) ) {
ATTRprint_access_methods_log_bool( entnm, attrnm, funcnm, ctype, a, file );
}
/* case TYPE_ENUM: */
if( class == enumeration_ ) {
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " if(!_%s.is_null())\n {\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s.element_at(_%s.asInt()) << std::endl;\n",
attrnm, attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " return (%s) _%s;\n}\n",
EnumName( TYPEget_name( t ) ), attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() assigned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s.element_at(x) << std::endl;\n", attrnm );
fprintf( file, " }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " _%s.put (x);\n}\n", attrnm );
return;
if( classType == enumeration_ ) {
ATTRprint_access_methods_enum( entnm, attrnm, funcnm, a, t, file );
}
/* case TYPE_SELECT: */
if( class == select_ ) {
fprintf( file, " { return (const %s) &_%s; }\n", ctype, attrnm );
if( classType == select_ ) {
fprintf( file, " {\n return &_%s;\n}\n", attrnm );
ATTRprint_access_methods_get_head( entnm, a, file, true );
fprintf( file, "const {\n return (const %s) &_%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, " { _%s = x; }\n", attrnm );
fprintf( file, " {\n _%s = x;\n}\n", attrnm );
return;
}
/* case TYPE_AGGRETATES: */
@@ -358,48 +540,12 @@ void ATTRprint_access_methods( CONST char * entnm, Variable a, FILE * file ) {
/* case STRING:*/
/* case TYPE_BINARY: */
if( ( class == string_ ) || ( class == binary_ ) ) {
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " if(!_%s.is_null())\n {\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s << std::endl;\n", attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " return (const %s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " if(!x)\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << x << std::endl;\n" );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " _%s = x;\n}\n", attrnm );
return;
if( ( classType == string_ ) || ( classType == binary_ ) ) {
ATTRprint_access_methods_str_bin( entnm, attrnm, funcnm, ctype, a, file );
}
/* case TYPE_INTEGER: */
if( class == integer_ ) {
fprintf( file, "{\n" );
if( classType == integer_ ) {
fprintf( file, "const {\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
@@ -424,15 +570,11 @@ void ATTRprint_access_methods( CONST char * entnm, Variable a, FILE * file ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " if(!(x == S_INT_NULL) )\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << x << std::endl;\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n", entnm, funcnm );
fprintf( file, " *logStream << x << std::endl;\n" );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n", entnm, funcnm );
fprintf( file, " *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
/* default: INTEGER */
/* is the same type as the data member */
@@ -442,39 +584,31 @@ void ATTRprint_access_methods( CONST char * entnm, Variable a, FILE * file ) {
/* case TYPE_REAL:
case TYPE_NUMBER: */
if( ( class == number_ ) || ( class == real_ ) ) {
fprintf( file, "{\n" );
if( ( classType == number_ ) || ( classType == real_ ) ) {
fprintf( file, "const {\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " if(!(_%s == S_REAL_NULL) )\n {\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s << std::endl;\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n", entnm, funcnm );
fprintf( file, " *logStream << _%s << std::endl;\n", attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n", entnm, funcnm );
fprintf( file, " *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " return (const %s) _%s;\n}\n", ctype, attrnm );
fprintf( file, " return (%s) _%s;\n}\n", ctype, attrnm );
ATTRprint_access_methods_put_head( entnm, a, file );
fprintf( file, "{\n" );
if( print_logging ) {
fprintf( file, "#ifdef SC_LOGGING\n" );
fprintf( file, " if(*logStream)\n {\n" );
fprintf( file, " if(!(_%s == S_REAL_NULL) )\n {\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << _%s << std::endl;\n", attrnm );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n", entnm, funcnm );
fprintf( file, " *logStream << _%s << std::endl;\n", attrnm );
fprintf( file, " }\n else\n {\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n",
entnm, funcnm );
fprintf( file,
" *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, " *logStream << time(NULL) << \" SDAI %s::%s() returned: \";\n", entnm, funcnm );
fprintf( file, " *logStream << \"unset\" << std::endl;\n }\n }\n" );
fprintf( file, "#endif\n" );
}
fprintf( file, " _%s = x;\n}\n", attrnm );
+9 -2
View File
@@ -4,7 +4,14 @@
char * generate_attribute_name( Variable a, char * out );
char * generate_attribute_func_name( Variable a, char * out );
void ATTRsign_access_methods( Variable a, FILE * file );
void ATTRprint_access_methods( CONST char * entnm, Variable a, FILE * file );
void DataMemberPrintAttr( Entity entity, Variable a, FILE * file );
void ATTRnames_print( Entity entity, FILE * file );
void ATTRprint_access_methods_get_head( const char * classnm, Variable a, FILE * file, bool returnsConst );
void ATTRprint_access_methods_put_head( const char * entnm, Variable a, FILE * file );
void ATTRsign_access_methods( Variable a, FILE* file );
void ATTRprint_access_methods( const char * entnm, Variable a, FILE * file, Schema schema );
/** return true if attr needs const and non-const getters */
bool attrIsObj( Type t );
#endif
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -6,8 +6,7 @@ Entity ENTITYget_superclass( Entity entity );
Entity ENTITYput_superclass( Entity entity );
int ENTITYhas_explicit_attributes( Entity e );
void ENTITYget_first_attribs( Entity entity, Linked_List result );
void ENTITYPrint( Entity, FILES *, Schema );
void ENTITYprint_new( Entity, FILES *, Schema, int );
void ENTITYPrint( Entity entity, FILES * files, Schema schema, bool externMap );
void ENTITYprint_descriptors( Entity entity, FILE * createall, FILE * impl, Schema schema, bool externMap );
void ENTITYprint_classes( Entity entity, FILE * classes );
#endif
+50 -107
View File
@@ -7,7 +7,7 @@
#include "sc_version_string.h"
#include "class_strings.h"
/*******************************************************************
/** \file classes_misc.c
** FedEx parser output module for generating C++ class definitions
** December 5, 1989
** release 2 17-Feb-1992
@@ -26,16 +26,11 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7.
extern int multiple_inheritance;
/******************************************************************
** 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
******************************************************************/
/**
* creates a file for c++ header definitions, with name filename
* Returns: FILE* pointer to file created or NULL
* Status: complete
*/
FILE * FILEcreate( const char * filename ) {
FILE * file;
const char * fn;
@@ -56,54 +51,25 @@ FILE * FILEcreate( const char * filename ) {
}
/******************************************************************
** 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 ) {
/** closes a file opened with FILEcreate */
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
******************************************************************/
/** indicates whether the attribute is an aggregate */
int isAggregate( Variable a ) {
return( TYPEinherits_from( VARget_type( a ), aggregate_ ) );
}
/** indicates whether the attribute is an aggregate */
int isAggregateType( const Type t ) {
return( TYPEinherits_from( t, aggregate_ ) );
}
/******************************************************************
** 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 ) {
/** \returns a pointer to a static buffer, containing a string which is the type used by the c++ data member access functions */
const char * AccessType( Type t ) {
Class_Of_Type class;
static char nm [BUFSIZ];
strncpy( nm, TypeName( t ), BUFSIZ - 4 );
@@ -131,17 +97,11 @@ AccessType( Type t ) {
return nm;
}
/******************************************************************
** 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 ) {
/** \returns pointer to a static buffer, containing a new capitalized name
*
* creates a new name with first character's in caps
*/
const char * PrettyTmpName( const char * oldname ) {
int i = 0;
static char newname [BUFSIZ];
newname [0] = '\0';
@@ -162,8 +122,7 @@ PrettyTmpName( const char * oldname ) {
}
/* This function is out of date DAS */
const char *
EnumName( const char * oldname ) {
const char * EnumName( const char * oldname ) {
int j = 0;
static char newname [MAX_LEN];
if( !oldname ) {
@@ -179,8 +138,7 @@ EnumName( const char * oldname ) {
return ( newname );
}
const char *
SelectName( const char * oldname ) {
const char * SelectName( const char * oldname ) {
int j = 0;
static char newname [MAX_LEN];
if( !oldname ) {
@@ -197,11 +155,10 @@ SelectName( const char * oldname ) {
return ( newname );
}
/* return fundamental type but as the string which corresponds to */
/* the appropriate type descriptor */
/* if report_reftypes is true, report REFERENCE_TYPE when appropriate */
const char *
FundamentalType( const Type t, int report_reftypes ) {
/** \return fundamental type but as the string which corresponds to the appropriate type descriptor
* if report_reftypes is true, report REFERENCE_TYPE when appropriate
*/
const char * FundamentalType( const Type t, int report_reftypes ) {
if( report_reftypes && TYPEget_head( t ) ) {
return( "REFERENCE_TYPE" );
}
@@ -243,10 +200,9 @@ FundamentalType( const Type t, int report_reftypes ) {
}
}
/** 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. */
/** 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;
@@ -267,11 +223,10 @@ const char * TypeDescriptorName( Type 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 ) {
/** 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";
@@ -314,8 +269,7 @@ GetTypeDescriptorName( Type t ) {
return "";
}
int
ENTITYhas_explicit_attributes( Entity e ) {
int ENTITYhas_explicit_attributes( Entity e ) {
Linked_List l = ENTITYget_attributes( e );
int cnt = 0;
LISTdo( l, a, Variable )
@@ -327,8 +281,7 @@ ENTITYhas_explicit_attributes( Entity e ) {
}
Entity
ENTITYput_superclass( Entity entity ) {
Entity ENTITYput_superclass( Entity entity ) {
#define ENTITYget_type(e) ((e)->u.entity->type)
Linked_List l = ENTITYget_supertypes( entity );
@@ -380,8 +333,7 @@ ENTITYput_superclass( Entity entity ) {
return 0;
}
Entity
ENTITYget_superclass( Entity entity ) {
Entity ENTITYget_superclass( Entity entity ) {
EntityTag tag;
tag = ( EntityTag ) TYPEget_clientData( ENTITYget_type( entity ) );
return ( tag ? tag -> superclass : 0 );
@@ -403,6 +355,7 @@ void ENTITYget_first_attribs( Entity entity, Linked_List result ) {
** 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
**
@@ -415,28 +368,24 @@ void ENTITYget_first_attribs( Entity entity, Linked_List result ) {
** 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
** 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 ) {
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 */
@@ -447,14 +396,10 @@ VARis_type_shifter( Variable a ) {
return 0;
}
Variable
VARis_overrider( Entity e, Variable a ) {
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 ) {
@@ -464,12 +409,10 @@ VARis_overrider( Entity e, Variable a ) {
return 0;
}
/**
* For a renamed type, returns the original (ancestor) type from which t
* descends. Return NULL if t is top level.
/** For a renamed type, returns the original (ancestor) type
* from which t descends. Return NULL if t is top level.
*/
Type TYPEget_ancestor( Type t )
{
Type TYPEget_ancestor( Type t ) {
Type i = t;
if( !TYPEget_head( i ) ) {
+45 -169
View File
@@ -22,6 +22,7 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7.
#include "class_strings.h"
#include "genCxxFilenames.h"
#include <ordered_attrs.h>
#include "rules.h"
#include <sc_trace_fprintf.h>
@@ -205,7 +206,8 @@ void TYPEenum_inc_print( const Type type, FILE * inc ) {
/* end class definition */
fprintf( inc, "};\n" );
fprintf( inc, "\ntypedef %s * %s_ptr;\n", n, n );
fprintf( inc, "\ntypedef %s * %s_ptr;\n", n, n );
fprintf( inc, "\ntypedef const %s * %s_ptr_c;\n", n, n );
/* Print ObjectStore Access Hook function */
@@ -228,7 +230,8 @@ void TYPEenum_inc_print( const Type type, FILE * inc ) {
fprintf( inc, "};\n" );
fprintf( inc, "\ntypedef %s_agg * %s_agg_ptr;\n", n, n );
fprintf( inc, "\ntypedef %s_agg * %s_agg_ptr;\n", n, n );
fprintf( inc, "\ntypedef const %s_agg * %s_agg_ptr_c;\n", n, n );
/* DAS brandnew below */
@@ -320,6 +323,9 @@ void TYPEPrint_cc( const Type type, const filenames_t * names, FILE * hdr, FILE
}
fprintf( impl, "\nvoid init_%s( Registry& reg ) {\n", TYPEget_ctype( type ) );
fprintf( impl, " std::string str;\n" );
/* moved from SCOPEPrint in classes_wrapper */
TYPEprint_new( type, impl, schema, true );
TYPEprint_init( type, hdr, impl, schema );
fprintf( impl, "}\n\n" );
@@ -440,9 +446,11 @@ void TYPEprint_typedefs( Type t, FILE * classes ) {
strncpy( nm, SelectName( TYPEget_name( t ) ), BUFSIZ );
nm[BUFSIZ-1] = '\0';
fprintf( classes, "class %s;\n", nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef const %s * %s_ptr_c;\n", nm, nm );
fprintf( classes, "class %s_agg;\n", nm );
fprintf( classes, "typedef %s_agg * %s_agg_ptr;\n", nm, nm );
fprintf( classes, "typedef %s_agg * %s_agg_ptr;\n", nm, nm );
fprintf( classes, "typedef const %s_agg * %s_agg_ptr_c;\n", nm, nm );
}
} else {
if( TYPEis_aggregate( t ) ) {
@@ -465,11 +473,12 @@ void TYPEprint_typedefs( Type t, FILE * classes ) {
*/
strncpy( nm, ClassName( TYPEget_name( t ) ), BUFSIZ );
nm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s %s;\n", TYPEget_ctype( t ), nm );
fprintf( classes, "typedef %s %s;\n", TYPEget_ctype( t ), nm );
if( TYPEis_aggregate( t ) ) {
fprintf( classes, "typedef %s * %sH;\n", nm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef %s_ptr %s_var;\n", nm, nm );
fprintf( classes, "typedef %s * %sH;\n", nm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef const %s * %s_ptr_c;\n", nm, nm );
fprintf( classes, "typedef %s_ptr %s_var;\n", nm, nm );
}
}
}
@@ -531,18 +540,18 @@ void TYPEprint_descriptions( const Type type, FILES * files, Schema schema ) {
printEnumCreateHdr( files->inc, type );
printEnumCreateBody( files->lib, type );
fprintf( files->inc, "typedef %s_agg * %s_agg_ptr;\n", nm, nm );
fprintf( files->inc, "typedef const %s_agg * %s_agg_ptr_c;\n", nm, nm );
printEnumAggrCrHdr( files->inc, type );
printEnumAggrCrBody( files->lib, type );
return;
}
if( !TYPEget_RefTypeVarNm( type, typename_buf, schema ) ) {
if( TYPEget_body( type )->type == enumeration_ ) {
if( TYPEis_enumeration( type ) ) {
TYPEPrint( type, files, schema );
/*TYPEenum_inc_print( type, files -> inc );
TYPEenum_lib_print( type, files -> lib );*/
}
} /* so we don't do anything for non-enums??? */
} else {
TYPEprint_new( type, files->create, schema, false );
TYPEprint_init( type, files->inc, files->init, schema );
}
}
@@ -598,29 +607,18 @@ void TYPEprint_init( const Type type, FILE * header, FILE * impl, Schema schema
fprintf( impl, " reg.AddType (*%s);\n", tdnm );
}
/** print name, fundamental type, and description initialization function
calls */
/** print name, fundamental type, and description initialization function calls */
void TYPEprint_nm_ft_desc( Schema schema, const Type type, FILE * f, char * endChars ) {
fprintf( f, " \"%s\", // Name\n",
PrettyTmpName( TYPEget_name( type ) ) );
fprintf( f, " %s, // FundamentalType\n",
FundamentalType( type, 1 ) );
fprintf( f, " %s::schema, // Originating Schema\n",
SCHEMAget_name( schema ) );
fprintf( f, " \"%s\"%s // Description\n",
TypeDescription( type ), endChars );
fprintf( f, " \"%s\", // Name\n", PrettyTmpName( TYPEget_name( type ) ) );
fprintf( f, " %s, // FundamentalType\n", FundamentalType( type, 1 ) );
fprintf( f, " %s::schema, // Originating Schema\n", SCHEMAget_name( schema ) );
fprintf( f, " \"%s\"%s // Description\n", TypeDescription( type ), endChars );
}
/** new space for a variable of type TypeDescriptor (or subtype). This
* function is called for Types that have an Express name.
*/
void TYPEprint_new( const Type type, FILE * create, Schema schema ) {
Linked_List wheres;
char * whereRule, *whereRule_formatted = NULL;
size_t whereRule_formatted_size = 0;
char * ptr, *ptr2;
void TYPEprint_new( const Type type, FILE * create, Schema schema, bool needWR ) {
Type tmpType = TYPEget_head( type );
Type bodyType = tmpType;
@@ -630,179 +628,57 @@ void TYPEprint_new( const Type type, FILE * create, Schema schema ) {
if( TYPEis_select( type ) ) {
char * temp;
temp = non_unique_types_string( type );
fprintf( create,
" %s = new SelectTypeDescriptor (\n ~%s, //unique elements,\n",
TYPEtd_name( type ),
temp );
fprintf( create, " %s = new SelectTypeDescriptor (\n ~%s, //unique elements,\n", TYPEtd_name( type ), temp );
sc_free( temp );
TYPEprint_nm_ft_desc( schema, type, create, "," );
fprintf( create,
" (SelectCreator) create_%s); // Creator function\n",
SelectName( TYPEget_name( type ) ) );
} else
fprintf( create, " (SelectCreator) create_%s); // Creator function\n", SelectName( TYPEget_name( type ) ) );
} else {
switch( TYPEget_body( type )->type ) {
case boolean_:
fprintf( create, " %s = new EnumTypeDescriptor (\n",
TYPEtd_name( type ) );
/* fill in it's values */
fprintf( create, " %s = new EnumTypeDescriptor (\n", TYPEtd_name( type ) );
TYPEprint_nm_ft_desc( schema, type, create, "," );
fprintf( create,
" (EnumCreator) create_BOOLEAN); // Creator function\n" );
fprintf( create, " (EnumCreator) create_BOOLEAN); // Creator function\n" );
break;
case logical_:
fprintf( create, " %s = new EnumTypeDescriptor (\n",
TYPEtd_name( type ) );
/* fill in it's values */
fprintf( create, " %s = new EnumTypeDescriptor (\n", TYPEtd_name( type ) );
TYPEprint_nm_ft_desc( schema, type, create, "," );
fprintf( create,
" (EnumCreator) create_LOGICAL); // Creator function\n" );
fprintf( create, " (EnumCreator) create_LOGICAL); // Creator function\n" );
break;
case enumeration_:
fprintf( create, " %s = new EnumTypeDescriptor (\n",
TYPEtd_name( type ) );
/* fill in it's values */
fprintf( create, " %s = new EnumTypeDescriptor (\n", TYPEtd_name( type ) );
TYPEprint_nm_ft_desc( schema, type, create, "," );
/* get the type name of the underlying type - it is the type that
needs to get created */
/* get the type name of the underlying type - it is the type that needs to get created */
tmpType = TYPEget_head( type );
if( tmpType ) {
bodyType = tmpType;
while( tmpType ) {
bodyType = tmpType;
tmpType = TYPEget_head( tmpType );
}
fprintf( create,
" (EnumCreator) create_%s); // Creator function\n",
TYPEget_ctype( bodyType ) );
} else
fprintf( create,
" (EnumCreator) create_%s); // Creator function\n",
TYPEget_ctype( type ) );
fprintf( create, " (EnumCreator) create_%s); // Creator function\n", TYPEget_ctype( bodyType ) );
} else {
fprintf( create, " (EnumCreator) create_%s); // Creator function\n", TYPEget_ctype( type ) );
}
break;
case aggregate_:
case array_:
case bag_:
case set_:
case list_:
fprintf( create, "\n %s = new %s (\n",
TYPEtd_name( type ), GetTypeDescriptorName( type ) );
/* fill in it's values */
fprintf( create, "\n %s = new %s (\n", TYPEtd_name( type ), GetTypeDescriptorName( type ) );
TYPEprint_nm_ft_desc( schema, type, create, "," );
fprintf( create,
" (AggregateCreator) create_%s); // Creator function\n\n",
ClassName( TYPEget_name( type ) ) );
fprintf( create, " (AggregateCreator) create_%s); // Creator function\n\n", ClassName( TYPEget_name( type ) ) );
break;
default:
fprintf( create, " %s = new TypeDescriptor (\n",
TYPEtd_name( type ) );
/* fill in it's values */
fprintf( create, " %s = new TypeDescriptor (\n", TYPEtd_name( type ) );
TYPEprint_nm_ft_desc( schema, type, create, ");" );
break;
}
}
/* add the type to the Schema dictionary entry */
fprintf( create, " %s::schema->AddType(%s);\n", SCHEMAget_name( schema ), TYPEtd_name( type ) );
wheres = type->where;
if( wheres ) {
fprintf( create, " %s->_where_rules = new Where_rule__list;\n",
TYPEtd_name( type ) );
LISTdo( wheres, w, Where )
whereRule = EXPRto_string( w->expr );
ptr2 = whereRule;
if( whereRule_formatted_size == 0 ) {
whereRule_formatted_size = 3 * BUFSIZ;
whereRule_formatted = ( char * )sc_malloc( sizeof( char ) * whereRule_formatted_size );
} else if( ( strlen( whereRule ) + 300 ) > whereRule_formatted_size ) {
sc_free( whereRule_formatted );
whereRule_formatted_size = strlen( whereRule ) + BUFSIZ;
whereRule_formatted = ( char * )sc_malloc( sizeof( char ) * whereRule_formatted_size );
}
whereRule_formatted[0] = '\0';
if( w->label ) {
strcpy( whereRule_formatted, w->label->name );
strcat( whereRule_formatted, ": (" );
ptr = whereRule_formatted + strlen( whereRule_formatted );
while( *ptr2 ) {
if( *ptr2 == '\n' )
;
else if( *ptr2 == '\\' ) {
*ptr = '\\';
ptr++;
*ptr = '\\';
ptr++;
} else if( *ptr2 == '(' ) {
*ptr = *ptr2;
ptr++;
} else {
*ptr = *ptr2;
ptr++;
}
ptr2++;
}
*ptr = '\0';
strcat( ptr, ");\\n" );
} else {
/* no label */
strcpy( whereRule_formatted, "(" );
ptr = whereRule_formatted + strlen( whereRule_formatted );
while( *ptr2 ) {
if( *ptr2 == '\n' )
;
else if( *ptr2 == '\\' ) {
*ptr = '\\';
ptr++;
*ptr = '\\';
ptr++;
} else if( *ptr2 == '(' ) {
*ptr = *ptr2;
ptr++;
} else {
*ptr = *ptr2;
ptr++;
}
ptr2++;
}
*ptr = '\0';
strcat( ptr, ");\\n" );
}
fprintf( create, " wr = new Where_rule(\"%s\");\n", whereRule_formatted );
fprintf( create, " %s->_where_rules->Append(wr);\n",
TYPEtd_name( type ) );
sc_free( whereRule );
ptr2 = whereRule = 0;
LISTod
sc_free( whereRule_formatted );
}
WHEREprint( TYPEtd_name( type ), type->where, create, 0, needWR );
}
/** Get the TypeDescriptor variable name that t's TypeDescriptor references (if
+1 -1
View File
@@ -13,7 +13,7 @@ void TYPEPrint( const Type type, FILES *files, Schema schema );
void TYPEprint_descriptions( const Type, FILES *, Schema );
void TYPEprint_definition( Type, FILES *, Schema );
void TYPEprint_typedefs( Type, FILE * );
void TYPEprint_new( const Type, FILE *, Schema );
void TYPEprint_new( const Type type, FILE* create, Schema schema, bool needWR );
void TYPEprint_init( const Type type, FILE * header, FILE * impl, Schema schema );
void TYPEenum_inc_print( const Type type, FILE * inc );
+111 -122
View File
@@ -137,6 +137,19 @@ void print_file_trailer( FILES * files ) {
FILEclose( files->names );
}
/* set attribute index to simplify attrdescriptor name calculation
* and reduce/eliminate use of global attr_count
*/
void numberAttributes( Scope scope ) {
int count = 0;
Linked_List list = SCOPEget_entities_superclass_order( scope );
LISTdo( list, e, Entity ) {
LISTdo_n( ENTITYget_attributes( e ), v, Variable, b ) {
v->idx = count++;
} LISTod
} LISTod
}
/******************************************************************
** SCHEMA SECTION **/
@@ -173,30 +186,20 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, ComplexCollect * col
classes.h (files->classes)). */
fprintf( files->create, "\n // ***** Initialize the Types\n" );
fprintf( files->classes, "\n// Types:\n" );
SCOPEdo_types( scope, t, de )
TYPEprint_new( t, files->create, schema );
TYPEprint_typedefs( t, files->classes );
SCOPEdo_types( scope, t, de ) {
//TYPEprint_new moved to TYPEPrint_cc and TYPEprint_descriptions in classes_type.c
TYPEprint_typedefs( t, files->classes );
//print in namespace. Some logic copied from TypeDescriptorName()
fprintf( files->names, " extern SC_SCHEMA_EXPORT %s * %s%s;\n", GetTypeDescriptorName( t ), TYPEprefix( t ), TYPEget_name( t ) );
} SCOPEod
//print in namespace. Some logic copied from TypeDescriptorName()
fprintf( files->names, " extern SC_SCHEMA_EXPORT %s * %s%s;\n", GetTypeDescriptorName( t ), TYPEprefix( t ), TYPEget_name( t ) );
SCOPEod;
/* do \'new\'s for entity descriptors */
fprintf( files->create, "\n // ***** Initialize the Entities\n" );
fprintf( files->classes, "\n// Entities:" );
LISTdo( list, e, Entity );
/* Print in include file: class forward prototype, class typedefs,
and extern EntityDescriptor. (ENTITYprint_new() combines the
functionality of TYPEprint_new() & print_typedefs() above.) */
ENTITYprint_new( e, files, schema,
col->externMapping( ENTITYget_name( e ) ) );
LISTod;
fprintf( files->create, "\n" );
fprintf( files->classes, "\n// Entity class typedefs:" );
LISTdo( list, e, Entity ) {
ENTITYprint_classes( e, files->classes );
} LISTod
}
/* fill in the values for the type descriptors */
/* and print the enumerations */
/* fill in the values for the type descriptors and print the enumerations */
fprintf( files -> inc, "\n/* ************** TYPES */\n" );
fprintf( files -> lib, "\n/* ************** TYPES */\n" );
/* The following was `SCOPEdo_types( scope, t, de ) ... SCOPEod;`
@@ -220,18 +223,18 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, ComplexCollect * col
}
}
SCOPEdo_types( scope, t, de )
/* NOTE the following comment seems to contradict the logic below it (... && !( TYPEis_enumeration( t ) && ...)
// 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;
SCOPEdo_types( scope, t, de ) {
/* NOTE the following comment seems to contradict the logic below it (... && !( TYPEis_enumeration( t ) && ...)
// 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;
} SCOPEod
if( redefs ) {
// Here we process redefined enumerations. See note, 2 loops ago.
@@ -239,13 +242,11 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, ComplexCollect * col
/* The following was `SCOPEdo_types( scope, t, de ) ... SCOPEod;`
* Modified Jan 2012 by MAP - moving enums to own dictionary */
HASHlistinit_by_type( scope->enum_table, &de, OBJ_TYPE );
{
Type t;
while( 0 != ( t = ( Type ) DICTdo( &de ) ) ) {
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
t->search_id = PROCESSED;
}
Type t;
while( 0 != ( t = ( Type ) DICTdo( &de ) ) ) {
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
t->search_id = PROCESSED;
}
}
}
@@ -255,74 +256,65 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, ComplexCollect * col
// 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.
if( TYPEis_select( t ) ) {
TYPEselect_print( t, files, schema );
}
if( TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
}
SCOPEdo_types( scope, t, de ) {
if( t->search_id == CANPROCESS ) {
// Only selects haven't been processed yet and may still be set to
// CANPROCESS.
if( TYPEis_select( t ) ) {
TYPEselect_print( t, files, schema );
}
if( TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
}
t->search_id = PROCESSED;
}
SCOPEod;
t->search_id = PROCESSED;
}
} SCOPEod
fprintf( files -> inc, "\n/* ************** ENTITIES */\n" );
fprintf( files -> lib, "\n/* ************** ENTITIES */\n" );
fprintf( files->inc, "\n// ***** Print Entity Classes \n" );
LISTdo( list, e, Entity );
if( e->search_id == CANPROCESS ) {
ENTITYPrint( e, files, schema );
e->search_id = PROCESSED;
}
LISTod;
LISTdo( list, e, Entity ) {
if( e->search_id == CANPROCESS ) {
ENTITYPrint( e, files, schema, col->externMapping( ENTITYget_name( e ) ) );
e->search_id = PROCESSED;
}
} LISTod
if( cnt <= 1 ) {
int index = 0;
// Do the model stuff:
fprintf( files->inc, "\n// ***** generate Model related pieces\n" );
fprintf( files->inc,
"\nclass SdaiModel_contents_%s : public SDAI_Model_contents {\n",
SCHEMAget_name( schema ) );
fprintf( files->inc, "\nclass SdaiModel_contents_%s : public SDAI_Model_contents {\n", SCHEMAget_name( schema ) );
fprintf( files -> inc, "\n public:\n" );
fprintf( files -> inc, " SdaiModel_contents_%s();\n",
SCHEMAget_name( schema ) );
fprintf( files -> inc, " SdaiModel_contents_%s();\n", SCHEMAget_name( schema ) );
LISTdo( list, e, Entity ) {
MODELprint_new( e, files );
} LISTod;
} LISTod
fprintf( files->inc, "\n};\n" );
fprintf( files->inc, "\n};\n\n" );
fprintf( files->inc, "\n\ntypedef SdaiModel_contents_%s * SdaiModel_contents_%s_ptr;\n", SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files->inc, "typedef SdaiModel_contents_%s_ptr SdaiModel_contents_%s_var;\n", SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files->inc, "typedef SdaiModel_contents_%s * SdaiModel_contents_%s_ptr;\n", SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files->inc, "typedef const SdaiModel_contents_%s * SdaiModel_contents_%s_ptr_c;\n", SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files->inc, "typedef SdaiModel_contents_%s_ptr SdaiModel_contents_%s_var;\n", SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files->inc, "SDAI_Model_contents_ptr create_SdaiModel_contents_%s();\n", SCHEMAget_name( schema ) );
fprintf( files -> inc,
"SDAI_Model_contents_ptr create_SdaiModel_contents_%s();\n",
SCHEMAget_name( schema ) );
fprintf( files -> lib,
"\nSDAI_Model_contents_ptr create_SdaiModel_contents_%s()\n",
SCHEMAget_name( schema ) );
fprintf( files -> lib, "{ return new SdaiModel_contents_%s ; }\n",
SCHEMAget_name( schema ) );
fprintf( files->lib, "\nSDAI_Model_contents_ptr create_SdaiModel_contents_%s() {\n", SCHEMAget_name( schema ) );
fprintf( files->lib, " return new SdaiModel_contents_%s;\n}\n", SCHEMAget_name( schema ) );
fprintf( files -> lib, "\nSdaiModel_contents_%s::SdaiModel_contents_%s()\n",
SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files -> lib,
"{\n SDAI_Entity_extent_ptr eep = (SDAI_Entity_extent_ptr)0;\n\n" );
LISTdo( list, e, Entity );
MODELPrintConstructorBody( e, files, schema );
LISTod;
fprintf( files->lib, "\nSdaiModel_contents_%s::SdaiModel_contents_%s() {\n", SCHEMAget_name( schema ), SCHEMAget_name( schema ) );
fprintf( files->lib, " SDAI_Entity_extent_ptr eep = (SDAI_Entity_extent_ptr)0;\n\n" );
LISTdo( list, e, Entity ) {
MODELPrintConstructorBody( e, files, schema );
} LISTod
fprintf( files -> lib, "}\n" );
index = 0;
LISTdo( list, e, Entity );
MODELPrint( e, files, schema, index );
index++;
LISTod;
LISTdo( list, e, Entity ) {
MODELPrint( e, files, schema, index );
index++;
} LISTod
}
LISTfree( list );
@@ -369,6 +361,18 @@ void closeUnityFiles( FILES * files ) {
FILEclose( files->unity.entity.impl );
}
///write tail of initfile, close it
void INITFileFinish( FILE * initfile, Schema schema ) {
fprintf( initfile, "\n /* loop through any entities with inverse attrs, calling InitIAttrs */\n");
fprintf( initfile, " EntityDescItr edi( *%s::schema->EntsWInverse() );\n", SCHEMAget_name( schema ) );
fprintf( initfile, " EntityDescriptor * ed;\n");
fprintf( initfile, " const char * nm = %s::schema->Name();\n", SCHEMAget_name( schema ) );
fprintf( initfile, " while( 0 != ( ed = edi.NextEntityDesc_nc() ) ) {\n");
fprintf( initfile, " ed->InitIAttrs( reg, nm );\n");
fprintf( initfile, " }\n}\n" );
FILEclose( initfile );
}
/** ****************************************************************
** Procedure: SCHEMAprint
** Parameters: const Schema schema - schema to print
@@ -388,9 +392,9 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
FILE * libfile,
* incfile,
* schemafile = files->incall,
* schemainit = files->initall,
* initfile,
* createall = files->create;
* schemainit = files->initall,
* initfile,
* createall = files->create;
Rule r;
Function f;
Procedure p;
@@ -398,8 +402,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
/********** create files based on name of schema ***********/
/* return if failure */
/* 1. header file */
sprintf( schnm, "%s%s", SCHEMA_FILE_PREFIX,
StrToUpper( SCHEMAget_name( schema ) ) ); //TODO change file names to CamelCase?
sprintf( schnm, "%s%s", SCHEMA_FILE_PREFIX, StrToUpper( SCHEMAget_name( schema ) ) ); //TODO change file names to CamelCase?
if( suffix == 0 ) {
sprintf( sufnm, "%s", schnm );
} else {
@@ -486,8 +489,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
fprintf( initfile, "\nvoid %sInit (Registry& reg) {\n", schnm );
fprintf( createall, "// Schema: %s\n", schnm );
fprintf( createall, " %s::schema = new Schema(\"%s\");\n",
SCHEMAget_name( schema ), PrettyTmpName( SCHEMAget_name( schema ) ) );
fprintf( createall, " %s::schema = new Schema(\"%s\");\n", SCHEMAget_name( schema ), PrettyTmpName( SCHEMAget_name( schema ) ) );
/* Add the SdaiModel_contents_<schema_name> class constructor to the
schema descriptor create function for it */
@@ -501,8 +503,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
while( 0 != ( r = ( Rule )DICTdo( &de ) ) ) {
fprintf( createall, " str.clear();\n" );
format_for_std_stringout( createall, RULEto_string( r ) );
fprintf( createall, "gr = new Global_rule(\"%s\",%s::schema, str );\n",
r->symbol.name, SCHEMAget_name( schema ) );
fprintf( createall, "gr = new Global_rule(\"%s\",%s::schema, str );\n", r->symbol.name, SCHEMAget_name( schema ) );
fprintf( createall, "%s::schema->AddGlobal_rule(gr);\n", SCHEMAget_name( schema ) );
}
/**************/
@@ -544,8 +545,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
/********** do the schemas ***********/
/* really, create calls for entity constructors */
SCOPEPrint( schema, files, schema, ( ComplexCollect * )complexCol,
suffix );
SCOPEPrint( schema, files, schema, ( ComplexCollect * )complexCol, suffix );
/********** close the files ***********/
@@ -553,8 +553,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
FILEclose( libfile );
FILEclose( incfile );
if( schema->search_id == PROCESSED ) {
fprintf( initfile, "\n}\n" );
FILEclose( initfile );
INITFileFinish( initfile, schema );
} else {
fclose( initfile );
}
@@ -577,31 +576,21 @@ void getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) {
DictionaryEntry de;
Schema schema;
fprintf( schema_h,
"\nSDAI_Model_contents_ptr GetModelContents(char *schemaName);\n" );
fprintf( schema_h, "\nSDAI_Model_contents_ptr GetModelContents(char *schemaName);\n" );
fprintf( schema_cc, "/* Generated at %s:%d. */\n\n", __FILE__, __LINE__ );
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,
"\nSDAI_Model_contents_ptr GetModelContents(char *schemaName) {\n" );
fprintf( schema_cc, "\nSDAI_Model_contents_ptr GetModelContents(char *schemaName) {\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 (SDAI_Model_contents_ptr) new SdaiModel_contents_%s; \n",
SCHEMAget_name( schema ) );
fprintf( schema_cc, " if(!strcmp(schemaName, \"%s\"))\n", SCHEMAget_name( schema ) );
fprintf( schema_cc, " return (SDAI_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 (SDAI_Model_contents_ptr) new SdaiModel_contents_%s; \n",
SCHEMAget_name( schema ) );
fprintf( schema_cc, " else if(!strcmp(schemaName, \"%s\"))\n", SCHEMAget_name( schema ) );
fprintf( schema_cc, " return (SDAI_Model_contents_ptr) new SdaiModel_contents_%s; \n", SCHEMAget_name( schema ) );
}
fprintf( schema_cc, " else return (SDAI_Model_contents_ptr) 0;\n}\n" );
}
@@ -618,8 +607,7 @@ void getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) {
** Side Effects: generates code
** Status: 24-Feb-1992 new -kcm
******************************************************************/
void
EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
void EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
char fnm [MAX_LEN], *np;
const char * schnm; /* schnm is really "express name" */
FILE * libfile;
@@ -687,6 +675,11 @@ EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
fprintf( schemainit, " %sInit (reg);\n", schnm );
/********** do all schemas ***********/
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
numberAttributes( schema );
}
DICTdo_init( express->symbol_table, &de );
bool first = true;
while( 0 != ( schema = ( Scope )DICTdo( &de ) ) ) {
@@ -700,14 +693,11 @@ EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
SCOPEPrint( schema, files, schema, &col, 0 );
}
/********** close the files ***********/
closeUnityFiles( files );
FILEclose( libfile );
FILEclose( incfile );
fprintf( initfile, "\n}\n" );
FILEclose( initfile );
INITFileFinish( initfile, schema );
}
/**
@@ -728,7 +718,6 @@ void print_file( Express express ) {
extern void RESOLUTIONsucceed( void );
int separate_schemas = 1;
ComplexCollect col( express );
File_holder files;
resolution_success();
+1 -1
View File
@@ -412,7 +412,7 @@ class ComplexCollect {
// it's used elsewhere.
ComplexList * find( char * );
int supports( EntNode * );
int externMapping( const char * ent ) {
bool externMapping( const char * ent ) {
return ( clists ? clists->isDependent( ent ) : 0 );
}
// One of our clists shows that ent will have to be instantiated
+174 -178
View File
@@ -37,27 +37,23 @@
#include <sc_trace_fprintf.h>
#define FALSE 0
#define TRUE 1
int isAggregateType( const Type t );
/* Local function prototypes: */
static void initializeMarks( Express );
static void cleanupMarks( Express );
static void unsetObjs( Schema );
static int checkTypes( Schema );
static int checkEnts( Schema );
static bool checkTypes( Schema );
static bool checkEnts( Schema );
static void markDescs( Entity );
static int checkItem( Type, Scope, Schema, int *, int );
static bool 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
@@ -67,18 +63,24 @@ void print_schemas_separate( Express express, void * complexCol, FILES * files )
* select types which have enum or select items (or entities containing
* enums) which have not been processed.
*/
{
int complete = FALSE, val1, val2, suffix;
void print_schemas_separate( Express express, void * complexCol, FILES * files ) {
bool complete = false;
int val1, val2, suffix;
DictionaryEntry de;
Schema schema;
/* First set all marks we'll be using to UNPROCESSED/NOTKNOWN: */
initializeMarks( express );
fprintf( files->create, " Uniqueness_rule_ptr ur;\n Where_rule_ptr wr;\n Global_rule_ptr gr;\n"
" std::string str; //for large strings such as functions or global rules\n" );
/* TODO only print gr, wr, str as needed, from SCHEMAprint in classes_wrapper.cc? */
fprintf( files->create, " Global_rule_ptr gr;\n Where_rule_ptr wr;\n std::string str; //for large strings such as functions or global rules\n" );
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
numberAttributes( schema );
}
while( !complete ) {
complete = TRUE;
complete = true;
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
if( schema->search_id == UNPROCESSED ) {
@@ -236,8 +238,7 @@ static void unsetObjs( Schema schema )
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
@@ -249,97 +250,98 @@ static int checkTypes( Schema schema )
* CANTPROCESS. If some types in schema *can* be processed now, we return
* TRUE. (See relevant header comments of checkEnts() below.)
*/
{
static bool checkTypes( Schema schema ) {
DictionaryEntry de;
int retval = FALSE, unknowncnt;
bool retval = false;
int 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;
SCOPEdo_types( schema, type, de ) {
if( type->search_id != NOTKNOWN ) {
continue;
}
} else if( TYPEis_select( type ) ) {
LISTdo( SEL_TYPEget_items( type ), ii, Type ) {
if( !TYPEis_entity( ii ) ) {
if( checkItem( ii, 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 ii 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( ii );
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_n( attribs, attr, Variable, z ) {
if( checkItem( attr->type, type, schema,
&unknowncnt, 1 ) ) {
/* 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 ), ii, Type ) {
if( !TYPEis_entity( ii ) ) {
if( checkItem( ii, type, schema, &unknowncnt, 0 ) ) {
break;
}
} LISTod
LISTfree( attribs );
/* 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 ii 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( ii );
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_n( attribs, attr, Variable, z ) {
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;
}
} 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
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
@@ -358,8 +360,7 @@ static int checkTypes( Schema 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
@@ -375,9 +376,10 @@ static int checkEnts( Schema schema )
* of the inline commenting of checkTypes() is applicable here and is not
* repeated.)
*/
{
static bool checkEnts( Schema schema ) {
DictionaryEntry de;
int retval = FALSE, ignore = 0;
bool retval = false;
int ignore = 0;
/* Loop through schema's entities: */
SCOPEdo_entities( schema, ent, de )
@@ -420,7 +422,7 @@ static int checkEnts( Schema schema )
/* 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;
retval = true;
}
SCOPEod
/* NOTE - We don't have to loop here as in checkTypes() (see long comment
@@ -432,22 +434,19 @@ static int checkEnts( Schema schema )
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.
*/
{
static void markDescs( Entity ent ) {
ent->search_id = CANTPROCESS;
LISTdo( ENTITYget_subtypes( ent ), sub, Entity )
markDescs( sub );
LISTod
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.
@@ -469,7 +468,7 @@ static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt,
* noSel is set to 1 to tell it to worry about t if it's an enum but not
* if it's a select.
*/
{
static bool checkItem( Type t, Scope parent, Schema schema, int * unknowncnt, int noSel ) {
Type i = t;
if( isAggregateType( t ) ) {
@@ -496,7 +495,7 @@ static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt,
}
parent->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
return TRUE;
return true;
} else if( TYPEis_select( i ) && !noSel ) {
if( !sameSchema( i, parent ) ) {
if( i->search_id != PROCESSED ) {
@@ -505,7 +504,7 @@ static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt,
}
parent->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
return TRUE;
return true;
}
} else {
/* We have another sel in the same schema. This gets complicated -
@@ -518,7 +517,7 @@ static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt,
}
parent->search_id = CANTPROCESS;
schema->search_id = UNPROCESSED;
return TRUE;
return true;
} else if( i->search_id == NOTKNOWN ) {
/* We haven't processed i this pass. */
if( parent->search_id != NOTKNOWN ) {
@@ -533,7 +532,7 @@ static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt,
}
}
}
return FALSE;
return false;
}
static int ENUMcanBeProcessed( Type e, Schema s )
@@ -570,14 +569,14 @@ static int ENUMcanBeProcessed( Type e, Schema s )
// 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;
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 true;
}
return FALSE;
return false;
}
int sameSchema( Scope sc1, Scope sc2 )
@@ -599,90 +598,88 @@ static int inSchema( Scope scope, Scope super )
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).)
*/
{
static void addRenameTypedefs( Schema schema, FILE * classes ) {
DictionaryEntry de;
Type i;
char nm[BUFSIZ], basenm[BUFSIZ];
static int firsttime = TRUE;
static bool 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 ) {
fprintf( classes, "\n// Renamed enum and select" );
fprintf( classes, " types (from all schemas):\n" );
firsttime = FALSE;
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 ) {
fprintf( classes, "\n// Renamed enum and select" );
fprintf( classes, " types (from all schemas):\n" );
firsttime = false;
}
if( TYPEis_enumeration( t ) ) {
strncpy( nm, TYPEget_ctype( t ), BUFSIZ - 1 );
nm[BUFSIZ-1] = '\0';
strncpy( basenm, TYPEget_ctype( i ), BUFSIZ - 1 );
basenm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s_agg %s_agg;\n", basenm, nm );
} else {
strncpy( nm, SelectName( TYPEget_name( t ) ), BUFSIZ - 1 );
nm[BUFSIZ-1] = '\0';
strncpy( basenm, SelectName( TYPEget_name( i ) ), BUFSIZ - 1 );
basenm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s %s;\n", basenm, nm );
fprintf( classes, "typedef %s_agg %s_agg;\n\n", basenm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef const %s * %s_ptr_c;\n", nm, nm );
fprintf( classes, "typedef %s_agg * %s_agg_ptr;\n", nm, nm );
fprintf( classes, "typedef const %s_agg * %s_agg_ptr_c;\n", nm, nm );
}
}
if( TYPEis_enumeration( t ) ) {
strncpy( nm, TYPEget_ctype( t ), BUFSIZ - 1 );
nm[BUFSIZ-1] = '\0';
strncpy( basenm, TYPEget_ctype( i ), BUFSIZ - 1 );
basenm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s_agg %s_agg;\n", basenm, nm );
} else {
strncpy( nm, SelectName( TYPEget_name( t ) ), BUFSIZ - 1 );
nm[BUFSIZ-1] = '\0';
strncpy( basenm, SelectName( TYPEget_name( i ) ), BUFSIZ - 1 );
basenm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s %s;\n", basenm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef %s_agg %s_agg;\n", basenm, nm );
fprintf( classes, "typedef %s_agg * %s_agg_ptr;\n", nm, nm );
}
}
SCOPEod
} 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.
*/
{
static void addAggrTypedefs( Schema schema, FILE * classes ) {
DictionaryEntry de;
Type i;
static int firsttime = TRUE;
static bool 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;
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 schemas) which depend on other types:\n" );
firsttime = false;
}
strncpy( nm, ClassName( TYPEget_name( t ) ), BUFSIZ );
nm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s %s;\n", TYPEget_ctype( t ), nm );
fprintf( classes, "typedef %s * %sH;\n", nm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
fprintf( classes, "typedef const %s * %s_ptr_c;\n", nm, nm );
}
strncpy( nm, ClassName( TYPEget_name( t ) ), BUFSIZ );
nm[BUFSIZ-1] = '\0';
fprintf( classes, "typedef %s %s;\n",
TYPEget_ctype( t ), nm );
fprintf( classes, "typedef %s * %sH;\n", nm, nm );
fprintf( classes, "typedef %s * %s_ptr;\n", nm, nm );
}
}
SCOPEod
} 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
@@ -690,12 +687,12 @@ static void addUseRefNames( Schema schema, FILE * create )
* list will be used in the SCL to use the correct name of this type or
* entity when reading and writing files.
*/
{
static void addUseRefNames( Schema schema, FILE * create ) {
Dictionary useRefDict;
DictionaryEntry de;
Rename * rnm;
char * oldnm, schNm[BUFSIZ];
static int firsttime = TRUE;
static bool firsttime = true;
if( ( useRefDict = schema->u.schema->usedict ) != NULL ) {
DICTdo_init( useRefDict, &de );
@@ -709,9 +706,8 @@ static void addUseRefNames( Schema schema, FILE * create )
// from X. nnew would = old, but name would not be same
// as rnm->object's name. */
if( firsttime ) {
fprintf( create, " // Alternate names for types and " );
fprintf( create, "entities when used in other schemas:\n" );
firsttime = FALSE;
fprintf( create, " // Alternate names for types and entities when used in other schemas:\n" );
firsttime = false;
}
if( rnm->type == OBJ_TYPE ) {
fprintf( create, " %s", TYPEtd_name( ( Type )rnm->object ) );
@@ -735,7 +731,7 @@ static void addUseRefNames( Schema schema, FILE * create )
if( firsttime ) {
fprintf( create, " // Alternate names for types and " );
fprintf( create, "entities when used in other schemas:\n" );
firsttime = FALSE;
firsttime = false;
}
if( rnm->type == OBJ_TYPE ) {
fprintf( create, " %s", TYPEtd_name( ( Type )rnm->object ) );
+61
View File
@@ -0,0 +1,61 @@
#include "rules.h"
#include <express/type.h>
#include "classes.h"
#include <stdio.h>
/* print Where_rule's. for types, schema should be null - tename will include schema name */
void WHEREprint( const char * tename, Linked_List wheres, FILE * impl, Schema schema, bool needWR ) {
if( wheres ) {
fprintf( impl, " %s%s%s->_where_rules = new Where_rule__list;\n", ( schema ? SCHEMAget_name( schema ) : "" ), ( schema ? "::" ENT_PREFIX : "" ), tename );
if( needWR ) {
fprintf( impl, " Where_rule * wr;\n" );
}
LISTdo( wheres, w, Where ) {
fprintf( impl, " str.clear();\n");
if( w->label ) {
fprintf( impl, " str.append( \"%s: (\" );\n", w->label->name );
} else {
/* no label */
fprintf( impl, " str.append( \"(\" );\n");
}
format_for_std_stringout( impl, EXPRto_string( w->expr ) );
fprintf( impl, " str.append( \");\\n\" );\n");
fprintf( impl, " wr = new Where_rule( str.c_str() );\n" );
fprintf( impl, " %s%s%s->_where_rules->Append( wr );\n", ( schema ? SCHEMAget_name( schema ) : "" ), ( schema ? "::" ENT_PREFIX : "" ), tename );
} LISTod
}
}
/* print Uniqueness_rule's */
void UNIQUEprint( Entity entity, FILE * impl, Schema schema ) {
Linked_List uniqs = entity->u.entity->unique;
if( uniqs ) {
fprintf( impl, " %s::%s%s->_uniqueness_rules = new Uniqueness_rule__set;\n", SCHEMAget_name( schema ), ENT_PREFIX, ENTITYget_name( entity ) );
fprintf( impl, " Uniqueness_rule * ur;\n" );
LISTdo( uniqs, list, Linked_List ) {
int i = 0;
fprintf( impl, " str.clear();\n");
LISTdo_n( list, e, Expression, b ) {
i++;
if( i == 1 ) {
/* print label if present */
if( e ) {
fprintf( impl, " str.append( \"%s : \" );\n", StrToUpper( ( ( Symbol * )e )->name ) );
}
} else {
if( i > 2 ) {
fprintf( impl, " str.append( \", \" );\n");
}
format_for_std_stringout( impl, EXPRto_string( e ) );
}
} LISTod
fprintf( impl, " ur = new Uniqueness_rule( str.c_str() );\n" );
fprintf( impl, " %s::%s%s->_uniqueness_rules->Append(ur);\n", SCHEMAget_name( schema ), ENT_PREFIX, ENTITYget_name( entity ) );
} LISTod
}
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef RULES_H
#define RULES_H
#include <express/entity.h>
/** print Where_rule's. for types, schema should be null - tename will include schema name + type prefix */
void WHEREprint( const char * tename, Linked_List wheres, FILE * impl, Schema schema, bool needWR );
/** print Uniqueness_rule's. only Entity type has them? */
void UNIQUEprint( Entity entity, FILE * impl, Schema schema );
#endif /* RULES_H */
+135 -171
View File
@@ -20,16 +20,10 @@ extern int multiple_inheritance;
#include <stdlib.h>
#include "classes.h"
#include "classes_type.h"
#include "classes_attribute.h"
#include <sc_trace_fprintf.h>
int isAggregateType( const Type t );
char * generate_attribute_name( Variable a, char * out );
void ATTRsign_access_methods( Variable a, FILE * file );
char * generate_attribute_func_name( Variable a, char * out );
void ATTRprint_access_methods_get_head( const char * classnm, Variable a, FILE * file );
void ATTRprint_access_methods_put_head( const char * entnm, Variable a, FILE * file );
#define BASE_SELECT "SDAI_Select"
#define TYPEis_primitive(t) ( !( TYPEis_entity(t) || \
@@ -70,10 +64,7 @@ const char * TYPEget_utype( Type t ) {
return ( TYPEis_entity( t ) ? "SDAI_Application_instance_ptr" : TYPEget_ctype( t ) );
}
/**
LISTmember
determines if the given entity is a member of the list.
/** determines if the given entity is a member of the list.
RETURNS the member if it is a member; otherwise 0 is returned.
*/
Generic LISTmember( const Linked_List list, Generic e ) {
@@ -85,10 +76,7 @@ Generic LISTmember( const Linked_List list, Generic e ) {
return ( 0 );
}
/**
compareOrigTypes
Specialized function to catch if two enumerations, two selects, or two aggrs
/** Specialized function to catch if two enumerations, two selects, or two aggrs
of either, are of the same type. The issue is that e.g. select B may be a
rename of sel A (i.e., TYPE B = A;). Such renamed types are implemented by
exp2cxx with typedefs, so that they are in fact the same type. TYPEget_-
@@ -127,10 +115,7 @@ static int compareOrigTypes( Type a, Type b ) {
return ( !strcmp( TYPEget_name( t ), TYPEget_name( u ) ) );
}
/**
utype_member
determines if the given "link's" underlying type is a member of the list.
/** determines if the given "link's" underlying type is a member of the list.
RETURNS the underlying type if it is a member; otherwise 0 is returned.
If "rename" is TRUE, we also consider check to match in certain cases where
@@ -157,9 +142,7 @@ const char * utype_member( const Linked_List list, const Type check, int rename
return 0;
}
/**
* SELgetnew_dmlist (const Type type)
* Returns a list of types which have unique underlying types
/** Returns a list of types which have unique underlying types
* The returned list includes all the types which have a data members
* in the select type.
*
@@ -188,9 +171,7 @@ const char * SEL_ITEMget_dmtype( Type t, const Linked_List l ) {
}
/**
* SEL_ITEMget_dmname (Type t)
* Returns the name of the data member in the select class for the item of
/** Returns the name of the data member in the select class for the item of
* the select having the type t.
* Logical and boolean are handled as exceptions because TYPEget_utype()
* returns "PSDAI::..." for them which is not a legal variable name.
@@ -225,10 +206,7 @@ const char * SEL_ITEMget_dmname( Type t ) {
return ( StrToLower( TYPEget_utype( t ) ) );
}
/**
duplicate_in_express_list
determines if the given "link's" underlying type is a multiple member
/** determines if the given "link's" underlying type is a multiple member
of the list.
RETURNS 1 if true, else 0.
*/
@@ -248,10 +226,7 @@ int duplicate_in_express_list( const Linked_List list, const Type check ) {
return FALSE;
}
/**
unique_types ( const Linked_List list )
determines if any of the types in a select type resolve to the same
/** determines if any of the types in a select type resolve to the same
underlying Express type.
RETURNS 1 if true, else 0.
*/
@@ -265,10 +240,7 @@ int unique_types( const Linked_List list ) {
}
/**
duplicate_utype_member
determines if the given "link's" C++ representation is used again in the list.
/** determines if the given "link's" C++ representation is used again in the list.
RETURNS 1 if true, else 0.
*/
int duplicate_utype_member( const Linked_List list, const Type check ) {
@@ -303,10 +275,7 @@ int duplicate_utype_member( const Linked_List list, const Type check ) {
return FALSE;
}
/**
any_duplicates_in_select
determines if any of the types in a select type resolve to the same
/** determines if any of the types in a select type resolve to the same
C++ representation for the underlying Express type.
RETURNS 1 if true, else 0.
*/
@@ -319,10 +288,7 @@ int any_duplicates_in_select( const Linked_List list ) {
return FALSE;
}
/**
find_duplicate_list
finds an instance of each kind of duplicate type found in the given list.
/** finds an instance of each kind of duplicate type found in the given list.
This list is returned as dup_list. If a duplicate exists, the function
returns TRUE, else FALSE.
list should be unbound before calling, and freed afterwards.
@@ -350,12 +316,6 @@ int find_duplicate_list( const Type type, Linked_List * duplicate_list ) {
return FALSE;
}
/*******************
non_unique_types_string ( const Type type )
returns a string containing the non-unique EXPRESS types deriveable
from a select. the returned string is in the form (TYPE | TYPE |...)
*******************/
/** In the functions below, we use a vector of ints to count paths in the
select-graph to base types. The names in this enum correspond to the
indices in the vector, i.e., tvec[treal] == tvec[1], and contains the
@@ -374,7 +334,7 @@ enum __types {
tnumber /* NUMBER */
};
/* This function gets called recursively, to follow a select-graph to its
/** This function gets called recursively, to follow a select-graph to its
leaves. It passes around the vector described above, to track paths to
the leaf nodes.
*/
@@ -423,7 +383,7 @@ void non_unique_types_vector( const Type type, int * tvec ) {
LISTod;
}
/* Uses non_unique_types_vector on the select to get a vector of base-type
/** Uses non_unique_types_vector on the select to get a vector of base-type
reference counts, then uses that to make a string of types, of the form
(FOO_TYPE | BAR_TYPE | BAZ_TYPE), where FOO, BAR, and BAZ are EXPRESS
types. If all types are unique, the string (0) is generated.
@@ -574,12 +534,12 @@ void TYPEselect_inc_print_vars( const Type type, FILE * f, Linked_List dups ) {
fprintf( f, " virtual void STEPwrite_verbose (ostream& out =std::cout,\n"
" const char *currSch =0) const;\n" );
fprintf( f, " virtual Severity STEPread_content (istream& in =cin,\n"
" InstMgr * instances =0, const char *utype =0,\n"
" InstMgrBase * instances =0, const char *utype =0,\n"
" int addFileId =0, const char *currSch =0);\n" );
/* read StrToVal_content */
fprintf( f, " virtual Severity StrToVal_content "
"(const char *,\n InstMgr * instances =0);\n" );
"(const char *,\n InstMgrBase * instances =0);\n" );
/* constructor(s) */
fprintf( f, "\n// STEP Part 22: SDAI\n" );
@@ -971,6 +931,103 @@ static int memberOfEntPrimary( Entity ent, Variable uattr ) {
return result;
}
void TYPEselect_lib_part_three_getter( const Type type, const char * classnm, const char * attrnm, const char * utype, char * uent, char * funcnm,
Linked_List items, Variable a, Variable uattr, Entity ent, FILE * f, bool returnConst ) {
/* return a const value? */
const char * constStr = "const ";
const char * constReturn = ( returnConst ? constStr : "" );
/* method can be const or non-const? */
bool notAlwaysConst = attrIsObj( VARget_type( a ) );
ATTRprint_access_methods_get_head( classnm, a, f, returnConst );
/* if there will not be const and non-const getters, then this method should be const */
fprintf( f, "%s{\n", ( notAlwaysConst ? constReturn : constStr ) );
LISTdo( items, t, Type ) {
if( TYPEis_entity( t ) && ( uattr = ENTITYget_named_attribute(
( ent = ENT_TYPEget_entity( t ) ), ( char * ) StrToLower( attrnm ) ) ) ) {
/* for the select items which have the current attribute */
if( !multiple_inheritance ) {
if( !memberOfEntPrimary( ent, uattr ) ) {
/* If multiple inheritance is not supported, we must additionally check
* that uattr is a member of the entity's primary inheritance path
* (i.e., the entity, its first supertype, the super's first super,
* etc). The above `if' is commented out, because currently mult inher
* is not supported to the extent of handling accessor functions for
* non-primary supertypes. */
continue;
}
}
if( ! VARis_derived( uattr ) ) {
if( !strcmp( utype, TYPEget_ctype( VARget_type( uattr ) ) ) ) {
/* check to make sure the underlying attribute\'s type is
* the same as the current attribute. */
strncpy( uent, TYPEget_ctype( t ), BUFSIZ );
/* if the underlying type is that item's type, call the underlying_item's
* member function if it is the same attribute */
if( VARis_overrider( ENT_TYPEget_entity( t ), uattr ) ) {
/* update attribute_func_name because is has been overriden */
generate_attribute_func_name( uattr, funcnm );
} else {
generate_attribute_func_name( a, funcnm );
}
fprintf( f, " if( CurrentUnderlyingType () == %s ) \n // %s\n",
TYPEtd_name( t ), StrToUpper( TYPEget_name( t ) ) );
fprintf( f, " return ((%s%s) _%s) ->%s();\n", constReturn, uent, SEL_ITEMget_dmname( t ), funcnm );
} else {
/* types are not the same issue a warning */
fprintf( stderr,
"WARNING: in SELECT TYPE %s: ambiguous "
"attribute \"%s\" from underlying type \"%s\".\n\n",
TYPEget_name( type ), attrnm, TYPEget_name( t ) );
fprintf( f, " // %s\n // attribute access function"
" has a different return type\n",
StrToUpper( TYPEget_name( t ) ) );
}
} else /* derived attributes */
fprintf( f, " // for %s attribute is derived\n",
StrToUpper( TYPEget_name( t ) ) );
}
} LISTod;
PRINT_BUG_REPORT
/* If the return type is an enumeration class then you can\'t
* return NULL. Instead I made the return type the
* enumeration value. This causes a WARNING about going from
* int (NULL) to the enumeration type. To get rid of the
* WARNING you could add an explicit cast (using the code
* commented out below.
*
* Another option is to have the return type be the
* enumeration class and create special "NULL" instances of
* the class for every enumeration. This option was not
* implemented.
*
* kcm 28-Mar-1995
*/
/* EnumName (TYPEget_name (VARget_type (a)))*/
switch( TYPEget_body( VARget_type( a ) ) -> type ) {
case enumeration_:
fprintf( f, " return (%s) 0;\n}\n\n", EnumName( TYPEget_name( VARget_type( a ) ) ) );
break;
case boolean_:
fprintf( f, " return (Boolean) 0;\n}\n\n" );
break;
case logical_:
fprintf( f, " return (Logical) 0;\n}\n\n" );
break;
default:
fprintf( f, " return 0;\n}\n\n" );
}
}
/**
* TYPEselect_lib_print_part_three prints part 3) of the SDAI C++ binding for
* a select class -- access functions for the data members of underlying entity
@@ -993,8 +1050,9 @@ void TYPEselect_lib_print_part_three( const Type type, FILE * f,
fprintf( f, "\n // part 3\n" );
/* go through all the unique attributes */
LISTdo_n( attrs, a, Variable, b ) {
/* go through all the unique attributes */
bool putVarIsUsed = false; /* used to suppress unused var warning */
if( VARget_initializer( a ) == EXPRESSION_NULL ) {
/* only do for explicit attributes */
generate_attribute_func_name( a, funcnm );
@@ -1006,104 +1064,11 @@ void TYPEselect_lib_print_part_three( const Type type, FILE * f,
/* use the ctype since utype will be the same for all entities */
strncpy( utype, TYPEget_ctype( VARget_type( a ) ), BUFSIZ );
/* get method */
ATTRprint_access_methods_get_head( classnm, a, f );
fprintf( f, "{\n" );
LISTdo( items, t, Type ) {
if( TYPEis_entity( t ) && ( uattr = ENTITYget_named_attribute(
( ent = ENT_TYPEget_entity( t ) ), ( char * ) StrToLower( attrnm ) ) ) ) {
/* for the select items which have the current attribute */
if( !multiple_inheritance ) {
if( !memberOfEntPrimary( ent, uattr ) ) {
/* If multiple inheritance is not supported, we must addi-
tionally check that uattr is a member of the entity's
primary inheritance path (i.e., the entity, its first
supertype, the super's first super, etc). The above
`if' is commented out, because currently mult inher is
not supported to the extent of handling accessor func-
tions for non-primary supertypes. */
continue;
}
}
if( ! VARis_derived( uattr ) ) {
if( !strcmp( utype, TYPEget_ctype( VARget_type( uattr ) ) ) ) {
/* check to make sure the underlying attribute\'s type is
the same as the current attribute.
*/
strncpy( uent, TYPEget_ctype( t ), BUFSIZ );
/* if the underlying type is that item\'s type
call the underlying_item\'s member function */
/* if it is the same attribute */
if( VARis_overrider( ENT_TYPEget_entity( t ), uattr ) ) {
/* update attribute_func_name because is has been overrid */
generate_attribute_func_name( uattr, funcnm );
} else {
generate_attribute_func_name( a, funcnm );
}
fprintf( f,
" if( CurrentUnderlyingType () == %s ) \n // %s\n",
TYPEtd_name( t ), StrToUpper( TYPEget_name( t ) ) );
fprintf( f, " return ((%s) _%s) ->%s();\n",
uent, SEL_ITEMget_dmname( t ), funcnm );
} else {
/* types are not the same issue a warning */
fprintf( stderr,
"WARNING: in SELECT TYPE %s: ambiguous "
"attribute \"%s\" from underlying type \"%s\".\n\n",
TYPEget_name( type ), attrnm, TYPEget_name( t ) );
fprintf( f, " // %s\n // attribute access function"
" has a different return type\n",
StrToUpper( TYPEget_name( t ) ) );
}
} else /* derived attributes */
fprintf( f, " // for %s attribute is derived\n",
StrToUpper( TYPEget_name( t ) ) );
}
} LISTod;
PRINT_BUG_REPORT
/* If the return type is an enumeration class then you can\'t
return NULL. Instead I made the return type the
enumeration value. This causes a WARNING about going from
int (NULL) to the enumeration type. To get rid of the
WARNING you could add an explicit cast (using the code
commented out below.
Another option is to have the return type be the
enumeration class and create special "NULL" instances of
the class for every enumeration. This option was not
implemented.
kcm 28-Mar-1995
*/
/* EnumName (TYPEget_name (VARget_type (a)))*/
switch( TYPEget_body( VARget_type( a ) ) -> type ) {
case enumeration_:
fprintf( f, " return (%s) 0;\n}\n\n",
EnumName( TYPEget_name( VARget_type( a ) ) ) );
break;
case boolean_:
fprintf( f, " return (Boolean) 0;\n}\n\n" );
break;
case logical_:
fprintf( f, " return (Logical) 0;\n}\n\n" );
break;
default:
fprintf( f, " return 0;\n}\n\n" );
/* get methods */
TYPEselect_lib_part_three_getter( type, classnm, attrnm, utype, uent, funcnm, items, a, uattr, ent, f, false );
if( attrIsObj( VARget_type( a ) ) ) {
TYPEselect_lib_part_three_getter( type, classnm, attrnm, utype, uent, funcnm, items, a, uattr, ent, f, true );
}
/* put method */
ATTRprint_access_methods_put_head( classnm, a, f );
fprintf( f, "{\n" );
@@ -1146,6 +1111,7 @@ void TYPEselect_lib_print_part_three( const Type type, FILE * f,
TYPEtd_name( t ), StrToUpper( TYPEget_name( t ) ) );
fprintf( f, " { ((%s) _%s) ->%s( x );\n return;\n }\n",
uent, SEL_ITEMget_dmname( t ), funcnm );
putVarIsUsed = true;
} else {
/* warning printed above */
fprintf( f, " // for %s attribute access function"
@@ -1159,6 +1125,9 @@ void TYPEselect_lib_print_part_three( const Type type, FILE * f,
}
}
} LISTod;
if( !putVarIsUsed ) {
fprintf(f, " (void) x; //suppress unused var warning\n");
}
PRINT_SELECTBUG_WARNING( f );
fprintf( f, "}\n" );
}
@@ -1474,7 +1443,7 @@ void TYPEselect_lib_part21( const Type type, FILE * f ) {
fprintf( f, " return;\n}\n" );
/* Read part 21 */
fprintf( f, "\nSeverity\n%s::STEPread_content (istream& in, InstMgr * instances,\n"
fprintf( f, "\nSeverity\n%s::STEPread_content (istream& in, InstMgrBase * instances,\n"
" const char *utype, int addFileId, const char *currSch)\n{\n"
" (void)instances;\n (void)utype;\n (void)addFileId;\n (void)currSch;\n ", n );
@@ -1509,22 +1478,18 @@ void TYPEselect_lib_part21( const Type type, FILE * f ) {
/* if it's an entity, use Assign - done in Select class */
fprintf( f,
" // set Underlying Type in Select class\n"
" _%s = ReadEntityRef(in, &_error, \",)\", instances, addFileId);\n",
dm );
" _%s = ReadEntityRef(in, &_error, \",)\", instances, addFileId);\n", dm );
fprintf( f,
" if (_%s && (_%s != S_ENTITY_NULL)\n "
" && (CurrentUnderlyingType () -> CanBe (_%s -> eDesc )) )\n"
" return severity ();\n",
dm, dm, dm );
" if( _%s && ( _%s != S_ENTITY_NULL) &&\n "
" ( CurrentUnderlyingType()->CanBe( _%s->getEDesc() ) ) ) {\n"
" return severity();\n", dm, dm, dm );
fprintf( f,
" else {\n "
" } else {\n "
" Error (\"Reference to instance that is not indicated type\\n\");\n"
" _%s = 0;\n"
" nullify ();\n"
" return severity (SEVERITY_USERMSG);\n"
" }\n",
dm
);
" }\n", dm );
break;
case string_:
@@ -1586,7 +1551,7 @@ void TYPEselect_lib_StrToVal( const Type type, FILE * f ) {
/* read StrToVal_content */
fprintf( f, "\nSeverity\n%s::StrToVal_content "
"(const char * str, InstMgr * instances)"
"(const char * str, InstMgrBase * instances)"
"\n{\n (void)str;\n (void)instances;\n", n );
fprintf( f, " switch (base_type) {\n" );
@@ -1702,12 +1667,11 @@ void SELlib_print_protected( const Type type, FILE * f ) {
}
if( TYPEis_select( t ) ) {
fprintf( f,
" // %s\n" /* item name */
" if (%s -> CanBe (se -> eDesc))\n"
" { \n"
" _%s.AssignEntity (se);\n" /* underlying data member */
" return SetUnderlyingType (%s);\n" /* td */
" }\n",
" // %s\n" /* item name */
" if( %s->CanBe( se->getEDesc() ) ) {\n"
" _%s.AssignEntity (se);\n" /* underlying data member */
" return SetUnderlyingType (%s);\n" /* td */
" }\n",
StrToUpper( TYPEget_name( t ) ),
TYPEtd_name( t ),
SEL_ITEMget_dmname( t ),
+19
View File
@@ -0,0 +1,19 @@
SCHEMA missing_init;
TYPE surface_tolerance_deviation = positive_length_measure;
END_TYPE; -- 10303-46: presentation_appearance_schema
TYPE positive_length_measure = non_negative_length_measure;
WHERE
wr1 : SELF > 0.0;
END_TYPE; -- 10303-41: measure_schema
TYPE non_negative_length_measure = length_measure;
WHERE
wr1 : SELF >= 0.0;
END_TYPE; -- 10303-41: measure_schema
TYPE length_measure = REAL;
END_TYPE; -- 10303-41: measure_schema
END_SCHEMA;
+6 -2
View File
@@ -2,7 +2,8 @@ cmake_minimum_required( VERSION 2.8 )
# executable is ${EXE}, input file is ${INFILE}
set( ofile "SdaiAll.cc" )
# set( ofile "SdaiAll.cc" )
set(ofile "entity/SdaiConnection_zone_interface_plane_relationship.cc")
execute_process( COMMAND ${EXE} ${INFILE}
RESULT_VARIABLE CMD_RESULT )
if( NOT ${CMD_RESULT} EQUAL 0 )
@@ -12,7 +13,10 @@ endif( NOT ${CMD_RESULT} EQUAL 0 )
file( READ ${ofile} cxx LIMIT 4096 )
# ur = new Uniqueness_rule("UR1 : SELF\shape_aspect_relationship.name;\n");
string( REGEX MATCH "new *Uniqueness_rule *\\\( *\\\" *[uU][rR]1 *: *SELF *\\\\ *shape_aspect_relationship *\\. *name" match_result ${cxx} )
#entity/SdaiConnection_zone_interface_plane_relationship.cc:57: str.append( "SELF\\shape_aspect_relationship.name\n" );
# string( REGEX MATCH "new *Uniqueness_rule *\\\( *\\\" *[uU][rR]1 *: *SELF *\\\\ *shape_aspect_relationship *\\. *name" match_result ${cxx} )
string( REGEX MATCH "str.append *\\\( *\\\" *SELF *\\\\\\\\ *shape_aspect_relationship *\\. *name" match_result ${cxx} )
if( match_result STREQUAL "" )
message( FATAL_ERROR "exp2cxx output does not match input schema." )
+76
View File
@@ -0,0 +1,76 @@
This is an experimental alternate Parser implementation, with a view to facilitating the integration
of Part21 and Part28 exchange structures with other schema (such as AP203, AP214 and AP242).
The idea is to build a base Part21 parser implementation implemented using Ply (such as the one you
can now find in SCL.Part21 in this branch).
Exp2Python would be enhanced to subclass this parser and implement parser rules based on Part21
type / parameter mapping of schemas.
Exp2Python output Entity classes would be minimal, implementing all calculated attributes and
automatic type conversion from Part21 parameter types to the schema defined types. DERIVED
attributes would be implemented in the output class (as they are now).
Validating and non-validating versions of the parser would be generated.
For the validating parser all type checking / compatibility would be implemented by parser rules and
callbacks. Callbacks would be run after the first parser run, or sooner if a way could be found to
trigger them when appropriate.
Some pseudo code is given below (see comments):
import SCL.Part21
# entity classes would be fully implemented by exp2python
class RepresentationItem:
def __init__(self, name):
pass
# complete implementation not shown here!
class GeometricRepresentationItem(RepresentationItem):
def __init__(self, name):
RepresentationItem.__init__(self, name)
class Curve(GeometricRepresentationItem):
def __init__(self, name):
GeometricRepresentationItem.__init__(self, name)
class Conic(Curve):
def __init__(self, name, position):
Curve.__init__(self, name, position)
class Circle(Conic):
def __init__(self, name, position, radius):
Conic.__init__(self, name, position, radius)
class AP203Parser(SCL.Part21.Parser):
entities = ['ABSORBED_DOSE_MEASURE_WITH_UNIT',
'ABSORBED_DOSE_UNIT',
...,
'AXIS1_PLACEMENT',
'AXIS2_PLACEMENT_2D',
'AXIS2_PLACEMENT_3D',
...,
'CIRCLE',
'CIRCULAR_RUNOUT_TOLERANCE',
'YEAR_MONTH',
...,
'ZONE_STRUCTURAL_MAKEUP']
def __init__(self, ...):
SCL.Part21.Parser.__init__(self)
# schema entities would be passed to the underlying lexer to faciliate exact rule matches
self.lexer.register_entities(self.entities)
# validating form
def p_circle_entity(self, p):
r"""simple_record : CIRCLE '(' STRING ',' ENTITY_INSTANCE_NAME ',' REAL ')'"""
p[0] = Circle(p[3], p[5], p[7])
self.add_instance_validation(p[5], lambda x: isinstance(x, Axis2Placement))
# non validating form
def p_circle_entity(self, p):
r"""simple_record : CIRCLE '(' parameter_list ')'"""
p[0] = Circle(*p[3])
+2
View File
@@ -0,0 +1,2 @@
/build
+337 -165
View File
@@ -1,6 +1,11 @@
#
# STEP Part 21 Parser
#
# Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com)
# Copyright (c) 2014, Christopher HORLER (cshorler@googlemail.com)
#
# All rights reserved.
#
# This file is part of the StepClassLibrary (SCL).
#
# Redistribution and use in source and binary forms, with or without
@@ -29,179 +34,346 @@
# (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
import Utils
import sys
import logging
import ply.lex as lex
import ply.yacc as yacc
INSTANCE_DEFINITION_RE = re.compile("#(\d+)[^\S\n]?=[^\S\n]?(.*?)\((.*)\)[^\S\n]?;[\\r]?$")
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
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)
####################################################################################################
# Common Code for Lexer / Parser
####################################################################################################
class Base:
tokens = ('INTEGER', 'REAL', 'USER_DEFINED_KEYWORD', 'STANDARD_KEYWORD', 'STRING', 'BINARY',
'ENTITY_INSTANCE_NAME', 'ENUMERATION', 'PART21_END', 'PART21_START', 'HEADER_SEC',
'ENDSEC', 'DATA_SEC')
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
####################################################################################################
# Lexer
####################################################################################################
class Lexer(Base):
def __init__(self, debug=0, optimize=0, compatibility_mode=False, header_limit=1024):
self.lexer = lex.lex(module=self, debug=debug, debuglog=logger, optimize=optimize,
errorlog=logger)
self.entity_keywords = []
self.compatibility_mode = compatibility_mode
self.header_limit = header_limit
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]
states = (('compatibility', 'inclusive'),)
class Part21EntityInstance:
"""
A class to represent a Part21 instance as defined in one Part21 file
A Part21EntityInstance is defined by the following arguments:
entity_name: a string
entity_attributes: a list of strings to represent an attribute.
For instance, the following expression:
#4 = PRODUCT_DEFINITION_SHAPE('$','$',#5);
will result in :
entity : <class 'config_control_design.product_definition_shape'>
entity_instance_attributes: ['$','$','#5']
"""
def __init__(self,entity_name,attributes):
self._entity
self._attributes_definition = attributes
print self._entity_name
print self._attributes_definition
def __getattr__(self, name):
if name == 'lineno':
return self.lexer.lineno
elif name == 'lexpos':
return self.lexer.lexpos
else:
raise AttributeError
def input(self, s):
startidx = s.find('ISO-10303-21;', 0, self.header_limit)
if startidx == -1:
sys.exit('Aborting... ISO-10303-21; header not found')
self.lexer.input(s[startidx:])
self.lexer.lineno += s[0:startidx].count('\n')
if self.compatibility_mode:
self.lexer.begin('compatibility')
else:
self.lexer.begin('INITIAL')
def token(self):
try:
return next(self.lexer)
except StopIteration:
return None
def register_entities(self, entities):
self.entity_keywords.extend(entities)
class Part21Parser:
"""
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_name = ""
# 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]=[]
self.parse_file()
# 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]
# Comment (ignored)
def t_ANY_COMMENT(self, t):
r'/\*(.|\n)*?\*/'
t.lexer.lineno += t.value.count('\n')
def get_schema_name(self):
return self._schema_name
print schema_name
def get_number_of_instances(self):
return len(self._instances_definition.keys())
def t_ANY_PART21_START(self, t):
r'ISO-10303-21;'
return t
def parse_file(self):
init_time = time.time()
print "Parsing file %s..."%self._filename,
fp = open(self._filename)
while True:
line = fp.readline()
if not line:
break
# there may be a multline definition. In this case, we read lines untill we found
# a ;
#while (not line.endswith(";\r\n")): #its a multiline
# line = line.replace("\r\n","") + fp.readline()
# 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)
# parse attributes string
entity_attrs_list, str_len = Utils.process_nested_parent_str(entity_attrs)
# then finally append this instance to the disct instance
self._instances_definition[instance_int_id] = (entity_name,entity_attrs_list)
else: #does not match with entity instance definition, parse the header
if line.startswith('FILE_SCHEMA'):
#identify the schema name
self._schema_name = line.split("'")[1].split("'")[0].split(" ")[0].lower()
fp.close()
print 'done in %fs.'%(time.time()-init_time)
print 'schema: - %s entities %i'%(self._schema_name,len(self._instances_definition.keys()))
def t_ANY_PART21_END(self, t):
r'END-ISO-10303-21;'
return t
class EntityInstancesFactory(object):
'''
This class creates entity instances from the str definition
For instance, the definition:
20: ('CARTESIAN_POINT', ["''", '(5.,125.,20.)'])
will result in:
p = ARRAY(1,3,REAL)
p.[1] = REAL(5)
p.[2] = REAL(125)
p.[3] = REAL(20)
new_instance = cartesian_point(STRING(''),p)
'''
def __init__(self, schema_name, instance_definition):
# First try to import the schema module
def t_ANY_HEADER_SEC(self, t):
r'HEADER;'
return t
def t_ANY_ENDSEC(self, t):
r'ENDSEC;'
return t
# Keywords
def t_compatibility_STANDARD_KEYWORD(self, t):
r'(?:!|)[A-Z_][0-9A-Za-z_]*'
t.value = t.value.upper()
if t.value == 'DATA':
t.type = 'DATA_SEC'
elif t.value.startswith('!'):
t.type = 'USER_DEFINED_KEYWORD'
elif t.value in self.entity_keywords:
t.type = t.value
return t
def t_ANY_STANDARD_KEYWORD(self, t):
r'(?:!|)[A-Z_][0-9A-Z_]*'
if t.value == 'DATA':
t.type = 'DATA_SEC'
elif t.value.startswith('!'):
t.type = 'USER_DEFINED_KEYWORD'
elif t.value in self.entity_keywords:
t.type = t.value
return t
def t_ANY_newline(self, t):
r'\n+'
t.lexer.lineno += len(t.value)
# Simple Data Types
t_ANY_REAL = r'[+-]*[0-9][0-9]*\.[0-9]*(?:E[+-]*[0-9][0-9]*)?'
t_ANY_INTEGER = r'[+-]*[0-9][0-9]*'
t_ANY_STRING = r"'(?:[][!\"*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_\\ ]|'')*'"
t_ANY_BINARY = r'"[0-3][0-9A-F]*"'
t_ANY_ENTITY_INSTANCE_NAME = r'\#[0-9]+'
t_ANY_ENUMERATION = r'\.[A-Z_][A-Z0-9_]*\.'
# Punctuation
literals = '()=;,*$'
t_ANY_ignore = ' \t'
####################################################################################################
# Simple Model
####################################################################################################
class P21File:
def __init__(self, header, *sections):
self.header = header
self.sections = list(*sections)
class P21Header:
def __init__(self, file_description, file_name, file_schema):
self.file_description = file_description
self.file_name = file_name
self.file_schema = file_schema
self.extra_headers = []
class HeaderEntity:
def __init__(self, type_name, *params):
self.type_name = type_name
self.params = list(*params) if params else []
class Section:
def __init__(self, entities):
self.entities = entities
class SimpleEntity:
def __init__(self, ref, type_name, *params):
self.ref = ref
self.type_name = type_name
self.params = list(*params) if params else []
class ComplexEntity:
def __init__(self, ref, *params):
self.ref = ref
self.params = list(*params) if params else []
class TypedParameter:
def __init__(self, type_name, *params):
self.type_name = type_name
self.params = list(*params) if params else None
####################################################################################################
# Parser
####################################################################################################
class Parser(Base):
def __init__(self, lexer=None, debug=0):
self.parser = yacc.yacc(module=self, debug=debug, debuglog=logger, errorlog=logger)
if lexer is None:
lexer = Lexer()
self.lexer = lexer
def parse(self, p21_data, **kwargs):
self.lexer.input(p21_data)
self.refs = {}
if 'debug' in kwargs:
result = self.parser.parse(lexer=self.lexer, debug=logger,
**{ k: kwargs[k] for k in kwargs if k != 'debug'})
else:
result = self.parser.parse(lexer=self.lexer, **kwargs)
return result
def p_exchange_file(self, p):
"""exchange_file : PART21_START header_section data_section_list PART21_END"""
p[0] = P21File(p[2], p[3])
# TODO: Specialise the first 3 header entities
def p_header_section(self, p):
"""header_section : HEADER_SEC header_entity header_entity header_entity ENDSEC"""
p[0] = P21Header(p[2], p[3], p[4])
def p_header_section_with_entity_list(self, p):
"""header_section : HEADER_SEC header_entity header_entity header_entity header_entity_list ENDSEC"""
p[0] = P21Header(p[2], p[3], p[4])
p[0].extra_headers.extend(p[5])
def p_header_entity(self, p):
"""header_entity : keyword '(' parameter_list ')' ';'"""
p[0] = HeaderEntity(p[1], p[3])
def p_check_entity_instance_name(self, p):
"""check_entity_instance_name : ENTITY_INSTANCE_NAME"""
if p[1] in self.refs:
logger.error('Line %i, duplicate entity instance name: %s', p.lineno(1), p[1])
sys.exit('Aborting...')
else:
self.refs[p[1]] = None
p[0] = p[1]
def p_simple_entity_instance(self, p):
"""simple_entity_instance : check_entity_instance_name '=' simple_record ';'"""
p[0] = SimpleEntity(p[1], *p[3])
def p_complex_entity_instance(self, p):
"""complex_entity_instance : check_entity_instance_name '=' subsuper_record ';'"""
p[0] = ComplexEntity(p[1], p[3])
def p_subsuper_record(self, p):
"""subsuper_record : '(' simple_record_list ')'"""
p[0] = [TypedParameter(*x) for x in p[2]]
def p_data_section_list(self, p):
"""data_section_list : data_section_list data_section
| data_section"""
try: p[0] = p[1] + [p[2],]
except IndexError: p[0] = [p[1],]
def p_header_entity_list(self, p):
"""header_entity_list : header_entity_list header_entity
| header_entity"""
try: p[0] = p[1] + [p[2],]
except IndexError: p[0] = [p[1],]
def p_parameter_list(self, p):
"""parameter_list : parameter_list ',' parameter
| parameter"""
try: p[0] = p[1] + [p[3],]
except IndexError: p[0] = [p[1],]
def p_keyword(self, p):
"""keyword : USER_DEFINED_KEYWORD
| STANDARD_KEYWORD"""
p[0] = p[1]
def p_parameter_simple(self, p):
"""parameter : STRING
| INTEGER
| REAL
| ENTITY_INSTANCE_NAME
| ENUMERATION
| BINARY
| '*'
| '$'
| typed_parameter
| list_parameter"""
p[0] = p[1]
def p_list_parameter(self, p):
"""list_parameter : '(' parameter_list ')'"""
p[0] = p[2]
def p_typed_parameter(self, p):
"""typed_parameter : keyword '(' parameter ')'"""
p[0] = TypedParameter(p[1], p[3])
def p_parameter_empty_list(self, p):
"""parameter : '(' ')'"""
p[0] = []
def p_data_start(self, p):
"""data_start : DATA_SEC '(' parameter_list ')' ';'"""
pass
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
self.create_entity_instances()
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]
print "Instance definition to process",instance_definition
# first find class name
class_name = instance_definition[0].lower()
print "Class name:%s"%class_name
object_ = globals()[class_name]
# then attributes
#print object_.__doc__
instance_attributes = instance_definition[1]
print "instance_attributes:",instance_attributes
a = object_(*instance_attributes)
def p_data_start_empty(self, p):
"""data_start : DATA_SEC '(' ')' ';'
| DATA_SEC ';'"""
pass
def p_data_section(self, p):
"""data_section : data_start entity_instance_list ENDSEC"""
p[0] = Section(p[2])
def p_entity_instance_list(self, p):
"""entity_instance_list : entity_instance_list entity_instance
| empty"""
try: p[0] = p[1] + [p[2],]
except IndexError: pass # p[2] doesn't exist, p[1] is None
except TypeError: p[0] = [p[2],] # p[1] is None, p[2] is valid
def p_entity_instance(self, p):
"""entity_instance : simple_entity_instance
| complex_entity_instance"""
p[0] = p[1]
if __name__ == "__main__":
import time
import sys
from config_control_design import *
p21loader = Part21Parser("gasket1.p21")
print "Creating instances"
p21population = Part21Population(p21loader)
def p_simple_record_empty(self, p):
"""simple_record : keyword '(' ')'"""
p[0] = (p[1], [])
def p_simple_record_with_params(self, p):
"""simple_record : keyword '(' parameter_list ')'"""
p[0] = (p[1], p[3])
def p_simple_record_list(self, p):
"""simple_record_list : simple_record_list simple_record
| simple_record"""
try: p[0] = p[1] + [p[2],]
except IndexError: p[0] = [p[1],]
def p_empty(self, p):
"""empty :"""
pass
def test_debug():
logging.basicConfig()
logger.setLevel(logging.DEBUG)
s = open('io1-tu-203.stp', 'r').read()
parser = Parser()
try:
r = parser.parse(s, debug=1)
except SystemExit:
pass
return (parser, r)
def test():
logging.basicConfig()
logger.setLevel(logging.ERROR)
s = open('io1-tu-203.stp', 'r').read()
parser = Parser()
try:
r = parser.parse(s)
except SystemExit:
pass
return (parser, r)
if __name__ == '__main__':
test()
-1
View File
@@ -125,7 +125,6 @@ const char * PrettyTmpName( const char * oldname );
const char * EnumName( const char * oldname );
const char * TypeDescriptorName( Type );
char * TypeDescription( const Type t );
const char * TypeName( Type t );
const char * AccessType( Type t );
const char * TYPEget_ctype( const Type t );
void print_file( Express );
+39 -25
View File
@@ -640,6 +640,7 @@ LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) {
bool generate_constructor = true; /*by default, generates a python constructor */
bool single_inheritance = false;
bool multiple_inheritance = false;
bool rename_python_property = false;
Type t;
Linked_List list;
int num_parent = 0;
@@ -792,7 +793,7 @@ LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) {
LISTdo( ENTITYget_attributes( entity ), v, Variable )
generate_attribute_name( v, attrnm );
if( !VARis_derived( v ) && !VARget_inverse( v ) ) {
fprintf( file, "\t\tself.%s = %s\n", attrnm, attrnm );
fprintf( file, "\t\tself._%s = %s\n", attrnm, attrnm );
}
/*attr_count_tmp++; */
LISTod
@@ -801,22 +802,32 @@ LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) {
*/
LISTdo( ENTITYget_attributes( entity ), v, Variable )
generate_attribute_name( v, attrnm );
fprintf( file, "\n\t@apply\n" );
fprintf( file, "\tdef %s():\n", attrnm );
fprintf( file, "\n\t@property\n" );
if ( !strcmp(attrnm, "property") ) {
fprintf( file, "\tdef __%s(self):\n", attrnm );
rename_python_property = true;
} else {
fprintf( file, "\tdef %s(self):\n", attrnm );
}
/* fget */
fprintf( file, "\t\tdef fget( self ):\n" );
if( !VARis_derived( v ) ) {
fprintf( file, "\t\t\treturn self._%s\n", attrnm );
fprintf( file, "\t\treturn self._%s\n", attrnm );
} else {
/* evaluation of attribute */
fprintf( file, "\t\t\tattribute_eval = " );
fprintf( file, "\t\tattribute_eval = " );
/* outputs expression initializer */
ATTRIBUTE_INITIALIZER_out( v->initializer, 1, file );
/* then returns the value */
fprintf( file, "\n\t\t\treturn attribute_eval\n" );
fprintf( file, "\n\t\treturn attribute_eval\n" );
}
/* fset */
fprintf( file, "\t\tdef fset( self, value ):\n" );
if ( !strcmp(attrnm, "property") ) {
fprintf( file, "\t@__%s.setter\n", attrnm );
fprintf( file, "\tdef __%s(self, value):\n", attrnm );
} else {
fprintf( file, "\t@%s.setter\n", attrnm );
fprintf( file, "\tdef %s(self, value):\n", attrnm );
}
t = VARget_type( v );
/* find attr type name */
@@ -830,9 +841,8 @@ LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) {
/* if the argument is not optional */
if( !VARget_optional( v ) ) {
fprintf( file, "\t\t# Mandatory argument\n" );
fprintf( file, "\t\t\tif value==None:\n" );
fprintf( file, "\t\t\t\traise AssertionError('Argument %s is mantatory and can not be set to None')\n", attrnm );
fprintf( file, "\t\t\tif not check_type(value," );
fprintf( file, "\t\tassert value != None, 'Argument \"value\" is mantatory and cannot be set to None'\n" );
fprintf( file, "\t\tif not check_type(value," );
if( TYPEis_aggregate( t ) ) {
process_aggregate( file, t );
fprintf( file, "):\n" );
@@ -842,8 +852,8 @@ LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) {
fprintf( file, "%s):\n", attr_type );
}
} else {
fprintf( file, "\t\t\tif value != None: # OPTIONAL attribute\n\t" );
fprintf( file, "\t\t\tif not check_type(value," );
fprintf( file, "\t\tif value != None: # OPTIONAL attribute\n\t" );
fprintf( file, "\t\tif not check_type(value," );
if( TYPEis_aggregate( t ) ) {
process_aggregate( file, t );
fprintf( file, "):\n\t" );
@@ -855,34 +865,38 @@ LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) {
}
/* check wether attr_type is aggr or explicit */
if( TYPEis_aggregate( t ) ) {
fprintf( file, "\t\t\t\tself._%s = ", attrnm );
fprintf( file, "\t\t\tself._%s = ", attrnm );
print_aggregate_type( file, t );
fprintf( file, "(value)\n" );
} else if (attr_type && is_python_keyword(attr_type)) {
fprintf( file, "\t\t\t\tself._%s = %s_(value)\n", attrnm, attr_type );
fprintf( file, "\t\t\tself._%s = %s_(value)\n", attrnm, attr_type );
} else {
fprintf( file, "\t\t\t\tself._%s = %s(value)\n", attrnm, attr_type );
fprintf( file, "\t\t\tself._%s = %s(value)\n", attrnm, attr_type );
}
if( VARget_optional( v ) ) {
fprintf( file, "\t\t\t\telse:\n" );
fprintf( file, "\t\t\t\t\tself._%s = value\n", attrnm );
fprintf( file, "\t\t\telse:\n" );
fprintf( file, "\t\t\t\tself._%s = value\n", attrnm );
}
fprintf( file, "\t\t\telse:\n\t" );
fprintf( file, "\t\t\tself._%s = value\n", attrnm );
fprintf( file, "\t\telse:\n\t" );
fprintf( file, "\t\tself._%s = value\n", attrnm );
}
/* if the attribute is derived, prevent fset to attribute to be set */
/* TODO: this can be done by NOT writing the setter method */
else if( VARis_derived( v ) ) {
fprintf( file, "\t\t# DERIVED argument\n" );
fprintf( file, "\t\t\traise AssertionError('Argument %s is DERIVED. It is computed and can not be set to any value')\n", attrnm );
fprintf( file, "\t# DERIVED argument\n" );
fprintf( file, "\t\traise AssertionError('Argument %s is DERIVED. It is computed and can not be set to any value')\n", attrnm );
} else if( VARget_inverse( v ) ) {
fprintf( file, "\t\t# INVERSE argument\n" );
fprintf( file, "\t\t\traise AssertionError('Argument %s is INVERSE. It is computed and can not be set to any value')\n", attrnm );
fprintf( file, "\t# INVERSE argument\n" );
fprintf( file, "\t\traise AssertionError('Argument %s is INVERSE. It is computed and can not be set to any value')\n", attrnm );
}
fprintf( file, "\t\treturn property(**locals())\n" );
LISTod
}
/* before exiting, process where rules */
WHEREPrint( entity->where, 0, file );
if ( rename_python_property ) {
fprintf( file, "\tproperty = __property\n" );
}
}
int
+2 -1
View File
@@ -57,7 +57,8 @@ set_tests_properties( test_aggregate_bound_runtime_FAIL1 PROPERTIES
add_schema_dependent_test( "inverse_attr1" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" )
add_schema_dependent_test( "inverse_attr2" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" )
add_schema_dependent_test( "inverse_attr3" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" )
add_schema_dependent_test( "inverse_attr3" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21"
"-I${SC_SOURCE_DIR}/src/cllazyfile -I${SC_SOURCE_DIR}/src/base/judy/src" "steplazyfile" )
add_schema_dependent_test( "attribute" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" )
if(HAVE_STD_THREAD)
+3 -3
View File
@@ -45,7 +45,7 @@ bool findInverseAttrs1( InverseAItr iai, InstMgr & instList ) {
EntityNode * en = ( EntityNode * ) relObj->GetHead();
SdaiObject * obj = ( SdaiObject * ) en->node;
cout << "file id " << obj->StepFileId() << "; name "
<< instList.GetApplication_instance( obj->StepFileId() - 1 )->eDesc->Name() << endl;
<< instList.GetApplication_instance( obj->StepFileId() - 1 )->getEDesc()->Name() << endl;
}
ent_id = i;
}
@@ -73,7 +73,7 @@ int main( int argc, char * argv[] ) {
//find inverse attribute descriptors
//first, find inverse attrs unique to this entity (i.e. not inherited)
const EntityDescriptor * ed = registry.FindEntity( "window" );
InverseAItr iaIter( ed->InverseAttr() ); //iterator for inverse attributes
InverseAItr iaIter( &( ed->InverseAttr() ) ); //iterator for inverse attributes
if( findInverseAttrs1( iaIter, instance_list ) ) {
inverseAttrsFound = true;
}
@@ -84,7 +84,7 @@ int main( int argc, char * argv[] ) {
for( ; !iter.empty(); iter++ ) {
super = iter.current();
cout << "supertype " << super->Name() << endl;
InverseAItr superIaIter( super->InverseAttr() );
InverseAItr superIaIter( &( super->InverseAttr() ) );
if( findInverseAttrs1( superIaIter, instance_list ) ) {
inverseAttrsFound = true;
}
+4 -4
View File
@@ -1,4 +1,4 @@
/** \file inverse_attr.cc
/** \file inverse_attr2.cc
** 1-Jul-2012
** Test inverse attributes; uses a tiny schema similar to a subset of IFC2x3
**
@@ -55,7 +55,7 @@ bool findInverseAttrs2( InverseAItr iai, InstMgr & instList, Registry & reg ) {
STEPattribute sa = attrlist[k];
if( sa.getADesc()->DomainType()->Type() == SET_TYPE ) {
STEPaggregate * aggr = sa.Aggregate();
if( !aggr || aggr->is_null() != 0 ) { //this fails - and it appears that aggr is not initialized.
if( !aggr || aggr->is_null() != 0 ) {
cout << "findInverseAttrs2 FAILED" << endl;
return false;
}
@@ -91,7 +91,7 @@ int main( int argc, char * argv[] ) {
//find inverse attribute descriptors
//first, find inverse attrs unique to this entity (i.e. not inherited)
const EntityDescriptor * ed = registry.FindEntity( "window" );
InverseAItr iaIter( ed->InverseAttr() ); //iterator for inverse attributes
InverseAItr iaIter( &( ed->InverseAttr() ) ); //iterator for inverse attributes
if( findInverseAttrs2( iaIter, instance_list, registry ) ) {
inverseAttrsFound = true;
}
@@ -100,7 +100,7 @@ int main( int argc, char * argv[] ) {
const EntityDescriptor * super;
while( 0 != ( super = edi.NextEntityDesc() ) ) {
cout << "supertype " << super->Name() << endl;
InverseAItr superIaIter( super->InverseAttr() );
InverseAItr superIaIter( &( super->InverseAttr() ) );
if( findInverseAttrs2( superIaIter, instance_list, registry ) ) {
inverseAttrsFound = true;
}
+39 -25
View File
@@ -1,12 +1,13 @@
/** \file inverse_attr.cc
** 1-Jul-2012
** Test inverse attributes; uses a tiny schema similar to a subset of IFC2x3
**
*/
/** \file inverse_attr3.cc
* Oct 2013
* Test inverse attributes; uses a tiny schema similar to a subset of IFC2x3
*
* This test originally used STEPfile, which didn't work. Fixing STEPfile would have been very difficult, it uses lazyInstMgr now.
*/
#include <sc_cf.h>
extern void SchemaInit( class Registry & );
#include "sc_version_string.h"
#include <STEPfile.h>
#include <lazyInstMgr.h>
#include <lazyRefs.h>
#include <sdai.h>
#include <STEPattribute.h>
#include <ExpDict.h>
@@ -14,6 +15,8 @@ extern void SchemaInit( class Registry & );
#include <errordesc.h>
#include <algorithm>
#include <string>
#include <superInvAttrIter.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@@ -21,38 +24,49 @@ extern void SchemaInit( class Registry & );
#include "schema.h"
int main( int argc, char * argv[] ) {
Registry registry( SchemaInit );
InstMgr instance_list;
STEPfile sfile( registry, instance_list, "", false );
int exitStatus = EXIT_SUCCESS;
if( argc != 2 ) {
cerr << "Wrong number of args!" << endl;
exit( EXIT_FAILURE );
}
sfile.ReadExchangeFile( argv[1] );
lazyInstMgr lim;
lim.initRegistry( SchemaInit );
if( sfile.Error().severity() <= SEVERITY_INCOMPLETE ) {
sfile.Error().PrintContents( cout );
lim.openFile( argv[1] );
//find attributes
instanceTypes_t::cvector * insts = lim.getInstances( "window" );
if( !insts || insts->empty() ) {
cout << "No window instances found!" << endl;
exit( EXIT_FAILURE );
}
//find attributes
SdaiWindow * instance = ( SdaiWindow * ) instance_list.GetApplication_instance( "window" );
SdaiWindow * instance = dynamic_cast< SdaiWindow * >( lim.loadInstance( insts->at( 0 ) ) );
if( !instance ) {
cout << "NULL" << endl;
cout << "Problem loading instance" << endl;
exit( EXIT_FAILURE );
}
cout << "instance #" << instance->StepFileId() << endl;
/* The inverse could be set with
* const Inverse_attribute * ia =...;
* const EntityDescriptor * inv_ed = reg.FindEntity( ia->inverted_entity_id_() );
* instance->isdefinedby_(inv_ed);
*/
SDAI_Application_instance::iAMap_t::value_type v = instance->getInvAttr("isdefinedby");
iAstruct attr = v.second; //instance->getInvAttr(ia);
if( attr.a && attr.a->EntryCount() ) {
cout << "Map: found " << attr.a->EntryCount() << " inverse references." << endl;
} else {
cout << "Map: found no inverse references. ias " << (void *) &(v.second) << ", ia " << (void*) v.first << endl;
exitStatus = EXIT_FAILURE;
}
EntityAggregate * aggr = instance->isdefinedby_(); //should be filled in when the file is loaded? not sure how to do it using STEPfile...
if( aggr ) {
cout << aggr->EntryCount() << endl;
if( attr.a != aggr ) {
cout << "Error! got different EntityAggregate's when using map vs method" << endl;
exitStatus = EXIT_FAILURE;
}
if( aggr && aggr->EntryCount() ) {
cout << "Found " << aggr->EntryCount() << " inverse references." << endl;
} else {
cout << "inverse attr is not defined" << endl;
exit( EXIT_FAILURE );
exitStatus = EXIT_FAILURE;
}
exit( EXIT_SUCCESS );
exit( exitStatus );
}
+1 -1
View File
@@ -73,7 +73,7 @@ add_test(test_p21_entity_internal_comment ${p21read_ap214} ${CMAKE_CURRENT_SO
set_tests_properties(test_good_schema_name test_good_schema_name_asn test_mismatch_schema_name
test_ignore_schema_name test_missing_and_required test_missing_and_required_strict test_p21_entity_internal_comment
PROPERTIES DEPENDS build_cpp_sdai_AP214E3_2010 LABELS exchange_file)
PROPERTIES DEPENDS build_cpp_sdai_ap214e3 LABELS exchange_file)
set_tests_properties(test_mismatch_schema_name test_missing_and_required_strict PROPERTIES WILL_FAIL TRUE)
+14
View File
@@ -0,0 +1,14 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('SCL test file'),'2;1');
FILE_NAME('test_inherit_inverse.p21','2014-03-17T',('mp'),(''),'0','1','2');
FILE_SCHEMA(('test_inherit_inverse'));
ENDSEC;
DATA;
#1=GEOMETRIC_REPRESENTATION_CONTEXT(2,'ctx type',9);
#2=REPRESENTATION('rep',#1);
ENDSEC;
END-ISO-10303-21;
+25
View File
@@ -0,0 +1,25 @@
--derived from AP214E3
--schema to test inverse attributes when inherited
-- TODO what about ia's from 2nd or 3rd parent? must be handled differently...
SCHEMA test_inherit_inverse;
ENTITY representation;
name : STRING;
context_of_items : representation_context;
END_ENTITY;
ENTITY representation_context;
context_identifier : INTEGER;
context_type : STRING;
INVERSE
representations_in_context : SET [1:?] OF representation FOR context_of_items;
END_ENTITY;
ENTITY geometric_representation_context
SUBTYPE OF (representation_context);
coordinate_space_dimension : INTEGER;
END_ENTITY;
END_SCHEMA;
+22
View File
@@ -0,0 +1,22 @@
-- portion of IFC2X3_TC1.exp
SCHEMA inverse_bug;
ENTITY IfcFeatureElementAddition
SUBTYPE OF (IfcFeatureElement);
INVERSE
ProjectsElements : IfcRelProjectsElement FOR RelatedFeatureElement; --error about this
END_ENTITY;
ENTITY IfcFeatureElement
SUBTYPE OF (IfcElement);
END_ENTITY;
ENTITY IfcRelProjectsElement;
RelatingElement : IfcElement;
RelatedFeatureElement : IfcFeatureElementAddition;
END_ENTITY;
ENTITY IfcElement;
Tag : OPTIONAL INTEGER;
END_ENTITY;
END_SCHEMA;
@@ -0,0 +1,23 @@
-- derived from pdm schema 12
-- for debugging exp2cxx inverse attr numbering
SCHEMA numbered_inverse_attr;
ENTITY application_context;
application : STRING;
DERIVE
description : STRING := 'teststring';
id : INTEGER := 1234;
INVERSE
context_elements : SET[1:?] OF application_context_element FOR
frame_of_reference;
-- WHERE
-- wr1 : SIZEOF(USEDIN(SELF,'PDM_SCHEMA.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1;
-- wr2 : SIZEOF(USEDIN(SELF,'PDM_SCHEMA.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1;
END_ENTITY;
ENTITY application_context_element
(* SUPERTYPE OF (ONEOF(product_concept_context,product_context,
product_definition_context))*);
name : STRING;
frame_of_reference : application_context;
END_ENTITY;
END_SCHEMA;