1301 lines
36 KiB
C++
1301 lines
36 KiB
C++
|
|
/*
|
|
* NIST STEP Core Class Library
|
|
* clstepcore/sdaiApplication_instance.cc
|
|
* July, 1997
|
|
* K. C. Morris
|
|
* David Sauder
|
|
|
|
* Development of this software was funded by the United States Government,
|
|
* and is not subject to copyright.
|
|
*/
|
|
|
|
/* $Id: sdaiApplication_instance.cc,v 1.3 2003/06/06 17:07:35 gcosmo Exp $ */
|
|
|
|
//static char rcsid[] ="$Id: sdaiApplication_instance.cc,v 1.3 2003/06/06 17:07:35 gcosmo Exp $";
|
|
|
|
#include <sdai.h>
|
|
//#include <STEPentity.h>
|
|
#include <instmgr.h>
|
|
#include <STEPcomplex.h>
|
|
#include <STEPattribute.h>
|
|
|
|
SCLP23(Application_instance) NilSTEPentity;
|
|
|
|
/******************************************************************
|
|
** Functions for manipulating entities
|
|
|
|
** KNOWN BUGs: the SCLP23(Application_instance) is not aware of the STEPfile;
|
|
** therefore it can not read comments which may be embedded in the instance.
|
|
** The following are known problems:
|
|
** -- does not handle comments embedded in an instance ==> bombs
|
|
** -- ignores embedded entities ==> does not bomb
|
|
** -- error reporting does not include line number information
|
|
**/
|
|
|
|
SCLP23(Application_instance)::SCLP23_NAME(Application_instance) ()
|
|
: _cur(0), STEPfile_id(0), p21Comment(0), headMiEntity(0), nextMiEntity(0),
|
|
_complex(0)
|
|
{
|
|
}
|
|
|
|
SCLP23(Application_instance)::SCLP23_NAME(Application_instance) (int fileid, int complex)
|
|
: _cur(0), STEPfile_id(fileid), p21Comment(0),
|
|
headMiEntity(0), nextMiEntity(0), _complex (complex)
|
|
{
|
|
}
|
|
|
|
SCLP23(Application_instance)::~SCLP23_NAME(Application_instance) ()
|
|
{
|
|
STEPattribute * next =0;
|
|
ResetAttributes ();
|
|
while (next = NextAttribute ())
|
|
delete next;
|
|
|
|
if(MultipleInheritance())
|
|
{
|
|
delete nextMiEntity;
|
|
}
|
|
|
|
delete p21Comment;
|
|
|
|
/*
|
|
// this is not necessary since each will call delete on its
|
|
// own nextMiEntity - DAS
|
|
SCLP23(Application_instance) * nextMI = nextMiEntity;
|
|
SCLP23(Application_instance) * nextMItrail = 0;
|
|
while(nextMI)
|
|
{
|
|
nextMItrail = nextMI;
|
|
nextMI = nextMI->nextMiEntity;
|
|
// this is ok since STEPattribute doesn't explicitly delete its attr
|
|
delete nextMItrail;
|
|
}
|
|
*/
|
|
}
|
|
|
|
#ifdef PART26
|
|
//SCLP26(Application_instance_ptr)
|
|
IDL_Application_instance_ptr
|
|
SCLP23(Application_instance)::create_TIE()
|
|
{
|
|
G4cout << "ERROR SCLP23(Application_instance)::create_TIE() called." << G4endl;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
SCLP23(Application_instance) *
|
|
SCLP23(Application_instance)::Replicate()
|
|
{
|
|
char errStr[BUFSIZ];
|
|
if(IsComplex())
|
|
{
|
|
G4cerr << "STEPcomplex::Replicate() should be called: " << __FILE__
|
|
<< __LINE__ << "\n" << _POC_ "\n";
|
|
sprintf(errStr,
|
|
"SCLP23(Application_instance)::Replicate(): %s - entity #%d.\n",
|
|
"Programming ERROR - STEPcomplex::Replicate() should be called",
|
|
STEPfile_id);
|
|
_error.AppendToDetailMsg(errStr);
|
|
_error.AppendToUserMsg(errStr);
|
|
_error.GreaterSeverity(SEVERITY_BUG);
|
|
return S_ENTITY_NULL;
|
|
}
|
|
else
|
|
{
|
|
#ifdef __OSTORE__
|
|
SCLP23(Application_instance) *seNew = eDesc->NewSTEPentity(os_database::of(this));
|
|
#else
|
|
SCLP23(Application_instance) *seNew = eDesc->NewSTEPentity();
|
|
#endif
|
|
seNew -> CopyAs (this);
|
|
return seNew;
|
|
}
|
|
}
|
|
|
|
void SCLP23(Application_instance)::AddP21Comment(const char *s, int replace)
|
|
{
|
|
if(replace)
|
|
{
|
|
delete p21Comment;
|
|
p21Comment = 0;
|
|
}
|
|
if(s)
|
|
{
|
|
if(!p21Comment)
|
|
{
|
|
#ifdef __OSTORE__
|
|
p21Comment = new (os_segment::of(this), SCLstring::get_os_typespec())
|
|
SCLstring;
|
|
#else
|
|
p21Comment = new SCLstring;
|
|
#endif
|
|
}
|
|
else
|
|
p21Comment->set_null();
|
|
p21Comment->Append( s );
|
|
}
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::AddP21Comment(SCLstring &s, int replace)
|
|
{
|
|
if(replace)
|
|
{
|
|
delete p21Comment;
|
|
p21Comment = 0;
|
|
}
|
|
if(!s.is_null())
|
|
{
|
|
if(!p21Comment)
|
|
{
|
|
#ifdef __OSTORE__
|
|
p21Comment = new (os_segment::of(this),
|
|
SCLstring::get_os_typespec())
|
|
SCLstring;
|
|
#else
|
|
p21Comment = new SCLstring;
|
|
#endif
|
|
}
|
|
else
|
|
p21Comment->set_null();
|
|
p21Comment->Append( s.chars() );
|
|
}
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::STEPwrite_reference (std::ostream& out)
|
|
{
|
|
out << "#" << STEPfile_id;
|
|
}
|
|
|
|
const char *
|
|
SCLP23(Application_instance)::STEPwrite_reference (SCLstring &buf)
|
|
{
|
|
char tmp[64];
|
|
sprintf ( tmp,"#%d", STEPfile_id);
|
|
buf = tmp;
|
|
return buf.chars();
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::AppendMultInstance(SCLP23(Application_instance) *se)
|
|
{
|
|
if(nextMiEntity == 0)
|
|
nextMiEntity = se;
|
|
else
|
|
{
|
|
SCLP23(Application_instance) *link = nextMiEntity;
|
|
SCLP23(Application_instance) *linkTrailing = 0;
|
|
while(link)
|
|
{
|
|
linkTrailing = link;
|
|
link = link->nextMiEntity;
|
|
}
|
|
linkTrailing->nextMiEntity = se;
|
|
}
|
|
}
|
|
|
|
// BUG implement this
|
|
|
|
SCLP23(Application_instance) *
|
|
SCLP23(Application_instance)::GetMiEntity(char *EntityName)
|
|
{
|
|
SCLstring s1, s2;
|
|
|
|
const EntityDescLinkNode *edln = 0;
|
|
const EntityDescriptor *ed = eDesc;
|
|
|
|
// compare up the *leftmost* parent path
|
|
while(ed)
|
|
{
|
|
if( !strcmp( StrToLower(ed->Name(),s1), StrToLower(EntityName,s2) ) )
|
|
return this; // return this parent path
|
|
edln = (EntityDescLinkNode *)( ed->Supertypes().GetHead() );
|
|
if(edln)
|
|
ed = edln->EntityDesc();
|
|
else
|
|
ed = 0;
|
|
}
|
|
// search alternate parent path since didn't find it in this one.
|
|
if(nextMiEntity)
|
|
return nextMiEntity->GetMiEntity(EntityName);
|
|
return 0;
|
|
}
|
|
|
|
|
|
#ifdef __OSTORE__
|
|
void Application_instance_access_hook_in(void *object,
|
|
enum os_access_reason reason, void *user_data,
|
|
void *start_range, void *end_range)
|
|
{
|
|
G4cout << "ObjectStore called non-member function Application_instance Access_hook"
|
|
<< G4endl;
|
|
SCLP23(Application_instance) *ent = (SCLP23(Application_instance) *)object;
|
|
G4cout << "STEPfile_id: " << ent->STEPfile_id << G4endl;
|
|
ent->Access_hook_in(object, reason, user_data, start_range, end_range);
|
|
|
|
// SdaiEb_person *ent = (SdaiEb_person *)object;
|
|
// SdaiEb_person_access_hook_in(object, reason, user_data,
|
|
// start_range, end_range);
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::Access_hook_in(void *object,
|
|
enum os_access_reason reason, void *user_data,
|
|
void *start_range, void *end_range)
|
|
{
|
|
SCLP23(Application_instance) *ent = (SCLP23(Application_instance) *)object;
|
|
G4cout << "****WARNING: virtual SCLP23(Application_instance)::Access_hook_in() called" << G4endl;
|
|
ent->Access_hook_in(object, reason, user_data, start_range, end_range);
|
|
}
|
|
#endif
|
|
|
|
STEPattribute *
|
|
SCLP23(Application_instance)::GetSTEPattribute (const char * nm)
|
|
{
|
|
if (!nm) return 0;
|
|
STEPattribute *a =0;
|
|
|
|
ResetAttributes();
|
|
while ((a = NextAttribute () )
|
|
&& strcmp (nm, a ->Name()))
|
|
; // keep going until no more attributes or attribute is found
|
|
|
|
return a;
|
|
}
|
|
|
|
STEPattribute *
|
|
SCLP23(Application_instance)::MakeRedefined (STEPattribute *redefiningAttr, const char * nm)
|
|
{
|
|
// find the attribute being redefined
|
|
STEPattribute * a = GetSTEPattribute (nm);
|
|
|
|
// assign its pointer to the redefining attribute
|
|
if (a) a->RedefiningAttr(redefiningAttr);
|
|
return a;
|
|
}
|
|
|
|
STEPattribute *
|
|
SCLP23(Application_instance)::MakeDerived (const char * nm)
|
|
{
|
|
STEPattribute * a = GetSTEPattribute (nm);
|
|
if (a) a ->Derive ();
|
|
return a;
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::CopyAs (SCLP23(Application_instance) * other)
|
|
{
|
|
int numAttrs = AttributeCount();
|
|
ResetAttributes();
|
|
other -> ResetAttributes();
|
|
|
|
STEPattribute *this_attr = 0;
|
|
STEPattribute *other_attr = 0;
|
|
while((this_attr = NextAttribute()) && numAttrs)
|
|
{
|
|
other_attr = other -> NextAttribute();
|
|
this_attr -> ShallowCopy(other_attr);
|
|
numAttrs--;
|
|
}
|
|
}
|
|
|
|
|
|
const char *
|
|
SCLP23(Application_instance)::EntityName( const char *schnm) const
|
|
{
|
|
return eDesc->Name( schnm );
|
|
}
|
|
|
|
/*****************************************************************
|
|
Checks if a given SCLP23(Application_instance) is the same type as this one
|
|
****************************************************************/
|
|
|
|
const EntityDescriptor* SCLP23(Application_instance)::IsA(const EntityDescriptor *ed) const
|
|
{
|
|
return (eDesc->IsA(ed));
|
|
}
|
|
|
|
/******************************************************************
|
|
// Checks the validity of the current attribute values for the entity
|
|
******************************************************************/
|
|
|
|
Severity SCLP23(Application_instance)::ValidLevel(ErrorDescriptor *error, InstMgr *im,
|
|
int clearError)
|
|
{
|
|
ErrorDescriptor err;
|
|
if(clearError)
|
|
ClearError();
|
|
int n = attributes.list_length();
|
|
SCLstring tmp;
|
|
for (int i = 0 ; i < n; i++) {
|
|
if( !(attributes[i].aDesc->AttrType() == AttrType_Redefining) )
|
|
error->GreaterSeverity(attributes[i].ValidLevel(
|
|
attributes[i].asStr(tmp), &err, im, 0));
|
|
}
|
|
return error->severity();
|
|
}
|
|
|
|
/******************************************************************
|
|
// clears all attr's errors
|
|
******************************************************************/
|
|
void SCLP23(Application_instance)::ClearAttrError()
|
|
{
|
|
int n = attributes.list_length();
|
|
for (int i = 0 ; i < n; i++) {
|
|
attributes[i].Error().ClearErrorMsg();
|
|
}
|
|
}
|
|
|
|
/******************************************************************
|
|
// clears entity's error and optionally all attr's errors
|
|
******************************************************************/
|
|
|
|
void SCLP23(Application_instance)::ClearError(int clearAttrs)
|
|
{
|
|
_error.ClearErrorMsg();
|
|
if(clearAttrs)
|
|
ClearAttrError();
|
|
}
|
|
|
|
/******************************************************************
|
|
******************************************************************/
|
|
|
|
/*
|
|
void SCLP23(Application_instance)::EnforceOptionality(int on)
|
|
{
|
|
Enforcement e;
|
|
if(on) e = ENFORCE_OPTIONALITY;
|
|
else e = ENFORCE_OFF;
|
|
|
|
Error().enforcement(e);
|
|
int n = attributes.list_length();
|
|
for (int i = 0 ; i < n; i++) {
|
|
attributes[i].Error().enforcement(e);
|
|
}
|
|
}
|
|
*/
|
|
/******************************************************************
|
|
** Procedure: beginSTEPwrite
|
|
** Parameters: std::ostream& out -- stream to write to
|
|
** Returns:
|
|
** Side Effects: writes out the SCOPE section for an entity
|
|
** Status: stub
|
|
******************************************************************/
|
|
|
|
void SCLP23(Application_instance)::beginSTEPwrite(std::ostream& out)
|
|
{
|
|
out << "begin STEPwrite ... \n" ;
|
|
out.flush();
|
|
|
|
int n = attributes.list_length();
|
|
for (int i = 0 ; i < n; i++) {
|
|
if (attributes[i].Type () == ENTITY_TYPE
|
|
&& *(attributes[i].ptr.c) != S_ENTITY_NULL)
|
|
(*(attributes[i].ptr.c)) -> STEPwrite();
|
|
}
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: STEPwrite
|
|
** Parameters: std::ostream& out -- stream to write to
|
|
** Returns:
|
|
** Side Effects: writes out the data associated with an instance
|
|
in STEP format
|
|
** Problems: does not print out the SCOPE section of an entity
|
|
**
|
|
******************************************************************/
|
|
|
|
void
|
|
SCLP23(Application_instance)::STEPwrite(std::ostream& out, const char *currSch,
|
|
int writeComments)
|
|
{
|
|
SCLstring tmp;
|
|
if(writeComments && p21Comment && !p21Comment->is_null() )
|
|
out << p21Comment->chars();
|
|
out << "#" << STEPfile_id << "=" << StrToUpper(EntityName( currSch ), tmp)
|
|
<< "(";
|
|
int n = attributes.list_length();
|
|
|
|
for (int i = 0 ; i < n; i++) {
|
|
if( !(attributes[i].aDesc->AttrType() == AttrType_Redefining) )
|
|
{
|
|
if (i > 0) out << ",";
|
|
(attributes[i]).STEPwrite( out, currSch );
|
|
}
|
|
}
|
|
out << ");\n";
|
|
}
|
|
|
|
void SCLP23(Application_instance)::endSTEPwrite(std::ostream& out)
|
|
{
|
|
out << "end STEPwrite ... \n" ;
|
|
out.flush();
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::WriteValuePairs(std::ostream& out,
|
|
const char *currSch,
|
|
int writeComments, int mixedCase)
|
|
{
|
|
/*
|
|
const EntityDescriptorList &edl = eDesc->Supertypes();
|
|
EntityDescItr &edi((EntityDescriptorList &)(eDesc->Supertypes()));
|
|
|
|
int count = 1;
|
|
const EntityDescriptor * ed = 0;
|
|
while(ed = edi.NextEntityDesc())
|
|
{
|
|
if(count > 1)
|
|
{
|
|
out << "&";
|
|
}
|
|
out << ed->Name();
|
|
count++;
|
|
}
|
|
*/
|
|
|
|
// const AttrDescriptorList& adl = ed->ExplicitAttr();
|
|
|
|
/*
|
|
out << "Attributes are: " << G4endl;
|
|
edi.ResetItr();
|
|
AttrDescItr *adi = 0;
|
|
const AttrDescriptor * ad;
|
|
while(ed = edi.NextEntityDesc())
|
|
{
|
|
adi = new AttrDescItr((AttrDescriptorList&)ed->ExplicitAttr());
|
|
ad = 0;
|
|
while(ad = adi->NextAttrDesc())
|
|
{
|
|
out << ed->Name() << "." << ad->Name() << G4endl;
|
|
}
|
|
delete adi;
|
|
}
|
|
out << G4endl;
|
|
out << "finished writing attribute names." << G4endl;
|
|
edi.ResetItr();
|
|
*/
|
|
SCLstring s;
|
|
// out << eDesc->QualifiedName(s) << G4endl;
|
|
|
|
SCLstring tmp, tmp2;
|
|
if(writeComments && p21Comment && !p21Comment->is_null() )
|
|
out << p21Comment->chars();
|
|
if(mixedCase)
|
|
{
|
|
out << "#" << STEPfile_id << " "
|
|
<< eDesc->QualifiedName(s) << G4endl;
|
|
}
|
|
else
|
|
{
|
|
out << "#" << STEPfile_id << " "
|
|
<< StrToUpper(eDesc->QualifiedName(s),tmp) << G4endl;
|
|
}
|
|
int n = attributes.list_length();
|
|
|
|
for (int i = 0 ; i < n; i++) {
|
|
if( !(attributes[i].aDesc->AttrType() == AttrType_Redefining) )
|
|
{
|
|
// if (i > 0) out << ",";
|
|
if(mixedCase)
|
|
{
|
|
out << "\t"
|
|
<< attributes[i].aDesc->Owner().Name(s)
|
|
<< "." << attributes[i].aDesc->Name() << " ";
|
|
}
|
|
else
|
|
{
|
|
out << "\t"
|
|
<< StrToUpper(attributes[i].aDesc->Owner().Name(s),tmp)
|
|
<< "." << StrToUpper(attributes[i].aDesc->Name(),tmp2) << " ";
|
|
}
|
|
(attributes[i]).STEPwrite( out, currSch );
|
|
out << G4endl;
|
|
}
|
|
}
|
|
out << G4endl;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
** Procedure: STEPwrite
|
|
** Problems: does not print out the SCOPE section of an entity
|
|
**
|
|
******************************************************************/
|
|
|
|
const char *
|
|
SCLP23(Application_instance)::STEPwrite(SCLstring &buf, const char *currSch)
|
|
{
|
|
buf.set_null();
|
|
|
|
char instanceInfo[BUFSIZ];
|
|
|
|
SCLstring tmp;
|
|
sprintf(instanceInfo, "#%d=%s(", STEPfile_id,
|
|
(char *)StrToUpper( EntityName( currSch ), tmp ) );
|
|
buf.Append(instanceInfo);
|
|
|
|
int n = attributes.list_length();
|
|
|
|
for (int i = 0 ; i < n; i++) {
|
|
if( !(attributes[i].aDesc->AttrType() == AttrType_Redefining) )
|
|
{
|
|
if (i > 0) buf.Append( ',' );
|
|
attributes[i].asStr( tmp, currSch ) ;
|
|
buf.Append (tmp);
|
|
}
|
|
}
|
|
buf.Append( ");" );
|
|
return buf.chars();
|
|
}
|
|
|
|
void
|
|
SCLP23(Application_instance)::PrependEntityErrMsg()
|
|
{
|
|
char errStr[BUFSIZ];
|
|
errStr[0] = '\0';
|
|
|
|
if(_error.severity() == SEVERITY_NULL)
|
|
{ // if there is not an error already
|
|
sprintf(errStr, "\nERROR: ENTITY #%d %s\n", GetFileId(),
|
|
EntityName());
|
|
_error.PrependToDetailMsg(errStr);
|
|
}
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: SCLP23(Application_instance)::STEPread_error
|
|
** Parameters: char c -- character which caused error
|
|
** int i -- index of attribute which caused error
|
|
** std::istream& in -- input stream for recovery
|
|
** Returns:
|
|
** Description: reports the error found, reads until it finds the end of an
|
|
** instance. i.e. a close quote followed by a semicolon optionally having
|
|
** whitespace between them.
|
|
******************************************************************/
|
|
void
|
|
SCLP23(Application_instance)::STEPread_error(char c, int i, std::istream& in)
|
|
{
|
|
char errStr[BUFSIZ];
|
|
errStr[0] = '\0';
|
|
|
|
if(_error.severity() == SEVERITY_NULL)
|
|
{ // if there is not an error already
|
|
sprintf(errStr, "\nERROR: ENTITY #%d %s\n", GetFileId(),
|
|
EntityName());
|
|
_error.PrependToDetailMsg(errStr);
|
|
}
|
|
|
|
/* sprintf(errStr, " for instance #%d : %s\n", STEPfile_id, EntityName());*/
|
|
/* _error.AppendToDetailMsg(errStr);*/
|
|
|
|
if ( (i >= 0) && (i < attributes.list_length())) // i is an attribute
|
|
{
|
|
Error ().GreaterSeverity (SEVERITY_WARNING);
|
|
sprintf(errStr, " invalid data before type \'%s\'\n",
|
|
attributes[i].TypeName());
|
|
_error.AppendToDetailMsg(errStr);
|
|
}
|
|
else
|
|
{
|
|
Error ().GreaterSeverity (SEVERITY_INPUT_ERROR);
|
|
_error.AppendToDetailMsg(" No more attributes were expected.\n");
|
|
}
|
|
|
|
SCLstring tmp;
|
|
STEPwrite (tmp); // STEPwrite writes to a static buffer inside function
|
|
sprintf(errStr,
|
|
" The invalid instance to this point looks like :\n%s\n",
|
|
tmp.chars() );
|
|
_error.AppendToDetailMsg(errStr);
|
|
|
|
// _error.AppendToDetailMsg(" data lost looking for end of entity:");
|
|
|
|
// scan over the rest of the instance and echo it
|
|
// G4cerr << " ERROR Trying to find the end of the ENTITY to recover...\n";
|
|
// G4cerr << " skipping the following input:\n";
|
|
|
|
#ifdef OBSOLETE
|
|
in.clear();
|
|
int foundEnd = 0;
|
|
tmp = "";
|
|
|
|
// Search until a close paren is found followed by (skipping optional
|
|
// whitespace) a semicolon
|
|
while( in.good() && !foundEnd )
|
|
{
|
|
while ( in.good() && (c != ')') )
|
|
{
|
|
in.get(c);
|
|
tmp.Append(c);
|
|
// G4cerr << c;
|
|
}
|
|
if(in.good() && (c == ')') )
|
|
{
|
|
in >> std::ws; // skip whitespace
|
|
in.get(c);
|
|
tmp.Append(c);
|
|
// G4cerr << c;
|
|
// G4cerr << "\n";
|
|
if(c == ';')
|
|
{
|
|
foundEnd = 1;
|
|
}
|
|
}
|
|
}
|
|
_error.AppendToDetailMsg( tmp.chars() );
|
|
#endif
|
|
sprintf (errStr, "\nfinished reading #%d\n", STEPfile_id);
|
|
_error.AppendToDetailMsg(errStr);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: STEPread
|
|
** Returns: Severity, error information
|
|
** SEVERITY_NULL - no errors
|
|
** SEVERITY_USERMSG - checked as much as possible, could still
|
|
** be error - e.g. entity didn't match base entity type.
|
|
** SEVERITY_INCOMPLETE - data is missing and required.
|
|
** SEVERITY_WARNING - errors, but can recover
|
|
** <= SEVERITY_INPUT_ERROR - fatal error, can't recover
|
|
** Description: reads the values for an entity from an input stream
|
|
** in STEP file format starting at the open paren and
|
|
** ending with the semi-colon
|
|
** Parameters: int id
|
|
** int idIncrement
|
|
** InstMgr instances
|
|
** std::istream& in
|
|
** Side Effects: gobbles up input stream
|
|
** Status:
|
|
******************************************************************/
|
|
|
|
Severity
|
|
SCLP23(Application_instance)::STEPread(int id, int idIncr,
|
|
InstMgr * instance_set, std::istream& in,
|
|
const char *currSch, int useTechCor)
|
|
{
|
|
STEPfile_id = id;
|
|
char c ='\0';
|
|
char errStr[BUFSIZ];
|
|
errStr[0] = '\0';
|
|
Severity severe;
|
|
int i = 0;
|
|
|
|
ClearError(1);
|
|
|
|
in >> std::ws;
|
|
in >> c; // read the open paren
|
|
if( c != '(' )
|
|
{
|
|
PrependEntityErrMsg();
|
|
_error.AppendToDetailMsg(
|
|
" Missing initial open paren... Trying to recover.\n");
|
|
in.putback(c); // assume you can recover by reading 1st attr value
|
|
}
|
|
in >> std::ws;
|
|
|
|
int n = attributes.list_length();
|
|
if( n == 0) // no attributes
|
|
{
|
|
in >> c; // look for the close paren
|
|
if( c == ')' )
|
|
return _error.severity();
|
|
}
|
|
|
|
for (i = 0 ; i < n; i++) {
|
|
if( attributes[i].aDesc->AttrType() == AttrType_Redefining )
|
|
{
|
|
in >> std::ws;
|
|
c = in.peek();
|
|
if(!useTechCor) // i.e. use pre-technical corrigendum encoding
|
|
{
|
|
in >> c; // read what should be the '*'
|
|
in >> std::ws;
|
|
if(c == '*')
|
|
{
|
|
in >> c; // read the delimiter i.e. ',' or ')'
|
|
}
|
|
else
|
|
{
|
|
severe = SEVERITY_INCOMPLETE;
|
|
PrependEntityErrMsg(); // adds entity info if necessary
|
|
|
|
// set the severity for this entity
|
|
_error.GreaterSeverity(severe);
|
|
sprintf (errStr, " %s : ", attributes[i].Name());
|
|
_error.AppendToDetailMsg(errStr); // add attr name
|
|
_error.AppendToDetailMsg(
|
|
"Since using pre-technical corrigendum... missing asterisk for redefined attr.\n");
|
|
_error.AppendToUserMsg(
|
|
"Since using pre-technical corrigendum... missing asterisk for redefined attr. ");
|
|
}
|
|
/*
|
|
if( ! ( (c == ',') || (c == ')') ) )
|
|
{ // input is not a delimiter - an error
|
|
PrependEntityErrMsg();
|
|
|
|
_error.AppendToDetailMsg(
|
|
"Delimiter expected after redefined asterisk attribute encoding (since using pre-technical corregendum.\n");
|
|
CheckRemainingInput(in, &_error, "ENTITY", ",)");
|
|
if(!in.good())
|
|
return _error.severity();
|
|
if(_error.severity() <= SEVERITY_INPUT_ERROR)
|
|
{
|
|
// STEPread_error(c,i,in);
|
|
return _error.severity();
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
else // using technical corrigendum
|
|
{
|
|
// should be nothing to do except loop again unless...
|
|
// if at end need to have read the closing paren.
|
|
if(c == ')') // assume you are at the end so read last char
|
|
in >> c;
|
|
G4cout << "Entity #" << STEPfile_id
|
|
<< " skipping redefined attribute "
|
|
<< attributes[i].aDesc->Name() << G4endl << G4endl << std::flush;
|
|
}
|
|
// increment counter to read following attr since these attrs
|
|
// aren't written or read => there won't be a delimiter either
|
|
// i++;
|
|
}
|
|
else
|
|
{
|
|
attributes[i].STEPread(in, instance_set, idIncr, currSch);
|
|
in >> c; // read the , or ) following the attr read
|
|
|
|
severe = attributes[i].Error().severity();
|
|
|
|
if(severe <= SEVERITY_USERMSG)
|
|
{ // if there is some type of error
|
|
PrependEntityErrMsg();
|
|
|
|
// set the severity for this entity
|
|
_error.GreaterSeverity(severe);
|
|
sprintf (errStr, " %s : ", attributes[i].Name());
|
|
_error.AppendToDetailMsg(errStr); // add attr name
|
|
_error.AppendToDetailMsg((char *) // add attr error
|
|
attributes[i].Error().DetailMsg());
|
|
_error.AppendToUserMsg((char*)attributes[i].Error().UserMsg());
|
|
}
|
|
}
|
|
|
|
/*
|
|
if(severe <= SEVERITY_INPUT_ERROR)
|
|
{ // attribute\'s error is non-recoverable
|
|
// I believe if this error occurs then you cannot recover
|
|
|
|
// TODO: can you just read to the next comma and try to continue ?
|
|
STEPread_error(c,i,in);
|
|
return _error.severity();
|
|
}
|
|
*/
|
|
// if technical corrigendum redefined, input is at next attribute value
|
|
// if pre-technical corrigendum redefined, don't process
|
|
if ( (!( attributes[i].aDesc->AttrType() == AttrType_Redefining ) ||
|
|
!useTechCor) &&
|
|
! ((c == ',') || (c == ')' )) ) { // input is not a delimiter
|
|
PrependEntityErrMsg();
|
|
|
|
_error.AppendToDetailMsg(
|
|
"Delimiter expected after attribute value.\n");
|
|
if(!useTechCor)
|
|
{
|
|
_error.AppendToDetailMsg(
|
|
"I.e. since using pre-technical corrigendum, redefined ");
|
|
_error.AppendToDetailMsg(
|
|
"attribute is mapped as an asterisk so needs delimiter.\n");
|
|
}
|
|
CheckRemainingInput(in, &_error, "ENTITY", ",)");
|
|
if(!in.good())
|
|
return _error.severity();
|
|
if(_error.severity() <= SEVERITY_INPUT_ERROR)
|
|
{
|
|
// STEPread_error(c,i,in);
|
|
return _error.severity();
|
|
}
|
|
}
|
|
else if(c == ')')
|
|
{
|
|
while (i < n-1)
|
|
{
|
|
i++; // check if following attributes are redefined
|
|
if( !(attributes[i].aDesc->AttrType() == AttrType_Redefining) )
|
|
{
|
|
PrependEntityErrMsg();
|
|
_error.AppendToDetailMsg("Missing attribute value[s].\n");
|
|
// recoverable error
|
|
_error.GreaterSeverity(SEVERITY_WARNING);
|
|
return _error.severity();
|
|
}
|
|
i++;
|
|
}
|
|
return _error.severity();
|
|
}
|
|
}
|
|
STEPread_error(c,i,in);
|
|
// code fragment imported from STEPread_error
|
|
// for some currently unknown reason it was commented out of STEPread_error
|
|
errStr[0] = '\0';
|
|
in.clear();
|
|
int foundEnd = 0;
|
|
SCLstring tmp;
|
|
tmp = "";
|
|
|
|
// Search until a close paren is found followed by (skipping optional
|
|
// whitespace) a semicolon
|
|
while( in.good() && !foundEnd )
|
|
{
|
|
while ( in.good() && (c != ')') )
|
|
{
|
|
in.get(c);
|
|
tmp.Append(c);
|
|
// G4cerr << c;
|
|
}
|
|
if(in.good() && (c == ')') )
|
|
{
|
|
in >> std::ws; // skip whitespace
|
|
in.get(c);
|
|
tmp.Append(c);
|
|
// G4cerr << c;
|
|
// G4cerr << "\n";
|
|
if(c == ';')
|
|
{
|
|
foundEnd = 1;
|
|
}
|
|
}
|
|
}
|
|
_error.AppendToDetailMsg( tmp.chars() );
|
|
sprintf (errStr, "\nfinished reading #%d\n", STEPfile_id);
|
|
_error.AppendToDetailMsg(errStr);
|
|
// end of imported code
|
|
return _error.severity();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// read an entity reference and return a pointer to the SCLP23(Application_instance)
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
SCLP23(Application_instance) *
|
|
ReadEntityRef(std::istream &in, ErrorDescriptor *err, char *tokenList,
|
|
InstMgr * instances, int addFileId)
|
|
{
|
|
char c;
|
|
char errStr[BUFSIZ];
|
|
errStr[0] = '\0';
|
|
|
|
in >> std::ws;
|
|
in >> c;
|
|
switch (c)
|
|
{
|
|
case '@':
|
|
err->AppendToDetailMsg(
|
|
"Use of @ instead of # to identify entity.\n");
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
// no break statement here on purpose
|
|
case '#':
|
|
{
|
|
int id = -1;
|
|
// int n = 0;
|
|
in >> id;
|
|
if (in.fail ()) // there's been an error in input
|
|
{
|
|
// in.clear();
|
|
sprintf(errStr,"Invalid entity reference value.\n");
|
|
err->AppendToDetailMsg(errStr);
|
|
err->AppendToUserMsg(errStr);
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
CheckRemainingInput(in, err, "Entity Reference", tokenList);
|
|
return S_ENTITY_NULL;
|
|
}
|
|
else // found an entity id
|
|
{
|
|
// check to make sure garbage does not follow the id
|
|
CheckRemainingInput(in, err, "Entity Reference", tokenList);
|
|
|
|
id += addFileId;
|
|
if (!instances)
|
|
{
|
|
G4cerr << "Internal error: " << __FILE__ << __LINE__
|
|
<< "\n" << _POC_ "\n";
|
|
sprintf(errStr,
|
|
"STEPread_reference(): %s - entity #%d %s.\n",
|
|
"BUG - cannot read reference without the InstMgr",
|
|
id, "is unknown");
|
|
err->AppendToDetailMsg(errStr);
|
|
err->AppendToUserMsg(errStr);
|
|
err->GreaterSeverity(SEVERITY_BUG);
|
|
return S_ENTITY_NULL;
|
|
}
|
|
|
|
// lookup which object has id as its instance id
|
|
SCLP23(Application_instance)* inst;
|
|
/* If there is a ManagerNode it should have a SCLP23(Application_instance) */
|
|
MgrNode* mn =0;
|
|
mn = instances->FindFileId(id);
|
|
if (mn)
|
|
{
|
|
inst = mn->GetSTEPentity() ;
|
|
if (inst) { return (inst); }
|
|
else
|
|
{
|
|
G4cerr << "Internal error: " << __FILE__ << __LINE__
|
|
<< "\n" << _POC_ "\n";
|
|
sprintf(errStr,
|
|
"STEPread_reference(): %s - entity #%d %s.\n",
|
|
"BUG - MgrNode::GetSTEPentity returned NULL pointer",
|
|
id, "is unknown");
|
|
err->AppendToDetailMsg(errStr);
|
|
err->AppendToUserMsg(errStr);
|
|
err->GreaterSeverity(SEVERITY_BUG);
|
|
return S_ENTITY_NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(errStr,"Reference to non-existent ENTITY #%d.\n",
|
|
id);
|
|
err->AppendToDetailMsg(errStr);
|
|
err->AppendToUserMsg(errStr);
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
return S_ENTITY_NULL;
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
{
|
|
in.putback(c);
|
|
// read past garbage up to delim in tokenList
|
|
// if tokenList is null it will not read anything
|
|
CheckRemainingInput(in, err, "Entity Reference", tokenList);
|
|
return S_ENTITY_NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// same as above but reads from a const char *
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
SCLP23(Application_instance) *
|
|
ReadEntityRef(const char * s, ErrorDescriptor *err, char *tokenList,
|
|
InstMgr * instances, int addFileId)
|
|
{
|
|
std::istrstream in((char *)s);
|
|
return ReadEntityRef(in, err, tokenList, instances, addFileId);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// return SEVERITY_NULL if se's entity type matches the supplied entity type
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
Severity
|
|
EntityValidLevel(SCLP23(Application_instance) *se,
|
|
const TypeDescriptor *ed, // entity type that entity se needs
|
|
// to match. (this must be an
|
|
// EntityDescriptor)
|
|
ErrorDescriptor *err)
|
|
{
|
|
char messageBuf [BUFSIZ];
|
|
messageBuf[0] = '\0';
|
|
|
|
if( !ed || (ed->NonRefType() != ENTITY_TYPE) )
|
|
{
|
|
err->GreaterSeverity(SEVERITY_BUG);
|
|
sprintf(messageBuf,
|
|
" BUG: EntityValidLevel() called with %s",
|
|
"missing or invalid EntityDescriptor\n");
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
G4cerr << "Internal error: " << __FILE__ << __LINE__
|
|
<< "\n" << _POC_ "\n";
|
|
return SEVERITY_BUG;
|
|
}
|
|
if(!se || (se == S_ENTITY_NULL))
|
|
{
|
|
err->GreaterSeverity(SEVERITY_BUG);
|
|
sprintf(messageBuf,
|
|
" BUG: EntityValidLevel() called with null pointer %s\n",
|
|
"for SCLP23(Application_instance) argument.");
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
G4cerr << "Internal error: " << __FILE__ << __LINE__
|
|
<< "\n" << _POC_ "\n";
|
|
return SEVERITY_BUG;
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
// is se a descendant of ed?
|
|
if ( se->eDesc->IsA(ed) )
|
|
{
|
|
return SEVERITY_NULL;
|
|
}
|
|
else
|
|
{
|
|
if(se->IsComplex())
|
|
{
|
|
// This way assumes that the complex has all it's parts i.e. the
|
|
// complete hierarchy so it should be able to find ed's part if
|
|
// it is an ed.
|
|
STEPcomplex *sc = ((STEPcomplex *)se)->sc;
|
|
if(sc->EntityExists(ed->Name()))
|
|
return SEVERITY_NULL;
|
|
/*
|
|
*/
|
|
|
|
// This way checks to see if it is an ed based on the dictionary
|
|
// It is much less efficient but does not depend on the instance
|
|
// having all the parts it needs to be valid.
|
|
/*
|
|
STEPcomplex *sc = ((STEPcomplex *)se)->sc;
|
|
while (sc)
|
|
{
|
|
if( sc->eDesc->IsA(ed) )
|
|
return SEVERITY_NULL;
|
|
sc = sc->sc;
|
|
}
|
|
*/
|
|
}
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
sprintf(messageBuf,
|
|
" Entity #%d exists but is not a %s or descendant.\n",
|
|
se->STEPfile_id, ed->Name());
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
return SEVERITY_WARNING;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err->GreaterSeverity(SEVERITY_BUG);
|
|
sprintf(messageBuf,
|
|
" BUG: EntityValidLevel(): SCLP23(Application_instance) #%d has a %s",
|
|
se->STEPfile_id, "missing or invalid EntityDescriptor\n");
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
G4cerr << "Internal error: " << __FILE__ << __LINE__
|
|
<< "\n" << _POC_ "\n";
|
|
return SEVERITY_BUG;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// return 1 if attrValue has the equivalent of a null value.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
int
|
|
SetErrOnNull (const char *attrValue, ErrorDescriptor *error)
|
|
{
|
|
// DAVE: Is this needed will sscanf return 1 if assignment suppression is used?
|
|
char scanBuf[BUFSIZ];
|
|
scanBuf[0] = '\0';
|
|
|
|
int numFound = sscanf((char *)attrValue," %s", scanBuf);
|
|
if (numFound == EOF) {
|
|
/*
|
|
if(Nullable()) {
|
|
error->GreaterSeverity (SEVERITY_NULL);
|
|
}
|
|
else {
|
|
error->GreaterSeverity (SEVERITY_INCOMPLETE);
|
|
}
|
|
*/
|
|
error->GreaterSeverity (SEVERITY_INCOMPLETE);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// return SEVERITY_NULL if attrValue has a valid entity reference
|
|
// This function accepts an entity reference in two forms that is with or
|
|
// without the # sign: e.g. either #23 or 23 will be read.
|
|
// If non-whitespace characters follow the entity reference an error is set.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
Severity
|
|
EntityValidLevel(const char *attrValue, // string contain entity ref
|
|
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)
|
|
{
|
|
char tmp [BUFSIZ];
|
|
tmp[0] = '\0';
|
|
char messageBuf [BUFSIZ];
|
|
messageBuf[0] = '\0';
|
|
|
|
if(clearError)
|
|
err->ClearErrorMsg();
|
|
|
|
/*
|
|
// the problem with doing this is that it will require having a # in front
|
|
// of the entity ref.
|
|
SCLP23(Application_instance) se = ReadEntityRef(attrValue, err, 0, im, 0);
|
|
return EntityValidLevel(se, ed, err);
|
|
*/
|
|
|
|
int fileId;
|
|
MgrNode *mn = 0;
|
|
|
|
// check for both forms: #id or id
|
|
int found1 = sscanf((char *)attrValue, " #%d %s", &fileId, tmp);
|
|
int found2 = sscanf((char *)attrValue, " %d %s", &fileId, tmp);
|
|
|
|
if( (found1 > 0) || (found2 > 0) )
|
|
{
|
|
if ( (found1 == 2) || (found2 == 2) )
|
|
{
|
|
sprintf(messageBuf,
|
|
" Attribute's Entity Reference %s is %s data \'%s\'.\n",
|
|
attrValue, "followed by invalid", tmp);
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
}
|
|
mn = im->FindFileId(fileId);
|
|
if(mn)
|
|
{
|
|
SCLP23(Application_instance) *se = mn->GetSTEPentity();
|
|
return EntityValidLevel(se, ed, err);
|
|
}
|
|
else {
|
|
sprintf(messageBuf,
|
|
" Attribute's Entity Reference %s does not exist.\n",
|
|
attrValue);
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
return SEVERITY_WARNING;
|
|
}
|
|
}
|
|
|
|
// if the attrValue contains no value return
|
|
if (SetErrOnNull (attrValue, err))
|
|
return err->severity();
|
|
|
|
sprintf(messageBuf, "Invalid attribute entity reference value: '%s'.\n",
|
|
attrValue);
|
|
err->AppendToUserMsg(messageBuf);
|
|
err->AppendToDetailMsg(messageBuf);
|
|
err->GreaterSeverity(SEVERITY_WARNING);
|
|
return SEVERITY_WARNING;
|
|
}
|
|
|
|
/******************************************************************
|
|
** Procedure: NextAttribute
|
|
** Parameters:
|
|
** Returns: reference to an attribute pointer
|
|
** Description: used to cycle through the list of attributes
|
|
** Side Effects: increments the current position in the attribute list
|
|
** Status: untested 7/31/90
|
|
******************************************************************/
|
|
|
|
STEPattribute *
|
|
SCLP23(Application_instance)::NextAttribute () {
|
|
int i = AttributeCount ();
|
|
++_cur;
|
|
if (i < _cur) return 0;
|
|
return &attributes [_cur-1];
|
|
|
|
}
|
|
|
|
int
|
|
SCLP23(Application_instance)::AttributeCount () {
|
|
return attributes.list_length ();
|
|
}
|
|
|
|
#ifdef OBSOLETE
|
|
Severity
|
|
SCLP23(Application_instance)::ReadAttrs(int id, int addFileId,
|
|
class InstMgr * instance_set, std::istream& in)
|
|
{
|
|
char c ='\0';
|
|
char errStr[BUFSIZ];
|
|
errStr[0] = '\0';
|
|
Severity severe;
|
|
|
|
ClearError(1);
|
|
|
|
int n = attributes.list_length();
|
|
for (int i = 0 ; i < n; i++) {
|
|
attributes[i].STEPread(in, instance_set, addFileId);
|
|
|
|
severe = attributes[i].Error().severity();
|
|
|
|
if(severe <= SEVERITY_USERMSG)
|
|
{ // if there\'s some type of error
|
|
if(_error.severity() == SEVERITY_NULL)
|
|
{ // if there is not an error already
|
|
sprintf(errStr, "\nERROR: ENTITY #%d %s\n", GetFileId(),
|
|
EntityName());
|
|
_error.PrependToDetailMsg(errStr);
|
|
}
|
|
// set the severity for this entity
|
|
sprintf (errStr, " %s : ", attributes[i].Name());
|
|
_error.AppendToDetailMsg(errStr);
|
|
_error.GreaterSeverity(severe);
|
|
_error.AppendToDetailMsg((char *)
|
|
attributes[i].Error().DetailMsg());
|
|
_error.AppendToUserMsg((char *)attributes[i].Error().UserMsg());
|
|
|
|
}
|
|
/*
|
|
if(severe <= SEVERITY_INPUT_ERROR)
|
|
{ // attribute\'s error is non-recoverable
|
|
// I believe if this error occurs then you cannot recover
|
|
|
|
// TODO: can you just read to the next comma and try to continue ?
|
|
STEPread_error(c,i,in);
|
|
return _error.severity();
|
|
}
|
|
*/
|
|
in >> c;
|
|
if ( ! ((c == ',') || (c == ')' ))) { // input is not a delimiter
|
|
if(_error.severity() == SEVERITY_NULL)
|
|
{ // if there is not an error already
|
|
sprintf(errStr, "\nERROR: ENTITY #%d %s\n", GetFileId(),
|
|
EntityName());
|
|
_error.PrependToDetailMsg(errStr);
|
|
}
|
|
_error.AppendToDetailMsg(
|
|
"delimiter expected after attribute value.\n");
|
|
CheckRemainingInput(in, &_error, "ENTITY", ",)");
|
|
if(!in.good())
|
|
return _error.severity();
|
|
if(_error.severity() <= SEVERITY_INPUT_ERROR)
|
|
{
|
|
STEPread_error(c,i,in);
|
|
return _error.severity();
|
|
}
|
|
}
|
|
else if(c == ')')
|
|
{
|
|
in >> std::ws;
|
|
char z = in.peek();
|
|
if (z == ';')
|
|
{
|
|
in.get(c);
|
|
return _error.severity();
|
|
}
|
|
}
|
|
}
|
|
if(c != ')' )
|
|
{
|
|
STEPread_error(c,i,in);
|
|
return _error.severity();
|
|
}
|
|
return SEVERITY_NULL;
|
|
}
|
|
#endif
|