1 // Created: Tue Nov 2 14:40:06 1999
2 // Author: Andrey BETENEV
3 // Copyright (c) 1999-2020 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Express_Select.hxx>
18 #include <Express.hxx>
19 #include <Express_Alias.hxx>
20 #include <Express_ComplexType.hxx>
21 #include <Express_Entity.hxx>
22 #include <Express_Enum.hxx>
23 #include <Express_HSequenceOfItem.hxx>
24 #include <Express_Type.hxx>
25 #include <Message.hxx>
26 #include <OSD_Directory.hxx>
27 #include <OSD_FileSystem.hxx>
28 #include <OSD_Path.hxx>
29 #include <OSD_Protection.hxx>
30 #include <TColStd_HSequenceOfHAsciiString.hxx>
32 IMPLEMENT_STANDARD_RTTIEXT(Express_Select, Express_Item)
34 //=======================================================================
35 // function : Express_Select
37 //=======================================================================
39 Express_Select::Express_Select ( const Standard_CString theName,
40 const Handle(TColStd_HSequenceOfHAsciiString)& theNames)
41 : Express_Item (theName), myNames (theNames)
43 myItems = new Express_HSequenceOfItem;
46 //=======================================================================
49 //=======================================================================
51 const Handle(TColStd_HSequenceOfHAsciiString)& Express_Select::Names() const
56 //=======================================================================
59 //=======================================================================
61 const Handle(Express_HSequenceOfItem)& Express_Select::Items() const
66 //=======================================================================
67 // function : GenerateClass
69 //=======================================================================
71 Standard_Boolean Express_Select::GenerateClass() const
73 const TCollection_AsciiString aCPPName = CPPName();
75 Handle(TColStd_HSequenceOfInteger) aSeqMember = new TColStd_HSequenceOfInteger;
76 Handle(TColStd_HSequenceOfInteger) aSeqEntities = new TColStd_HSequenceOfInteger;
77 for (Standard_Integer i = 1; i <= myItems->Length(); i++)
79 Handle(Express_Item) anItem = myItems->Value (i);
80 if (anItem->IsKind (STANDARD_TYPE(Express_Entity)) || anItem->IsKind (STANDARD_TYPE(Express_Select))
81 || anItem->IsKind (STANDARD_TYPE(Express_Alias)) || anItem->IsKind (STANDARD_TYPE(Express_ComplexType)))
83 aSeqEntities->Append (i);
87 aSeqMember->Append (i);
90 Message::SendInfo() << "Generating SELECT " << aCPPName;
91 if (!aSeqMember->IsEmpty())
93 Message::SendInfo() << "Generating SELECTMember " << aCPPName << "Member";
94 generateSelectMember (aSeqMember);
96 // create a package directory (if not yet exist)
97 OSD_Protection aProt (OSD_RWXD, OSD_RWXD, OSD_RX, OSD_RX);
98 TCollection_AsciiString aPack = GetPackageName();
99 OSD_Path aPath (aPack);
100 OSD_Directory aDir (aPath);
104 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
106 //===============================
107 // Step 1: generating HXX
110 std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".hxx"), std::ios::out | std::ios::binary);
111 Standard_OStream& anOS = *aStreamPtr;
114 Express::WriteFileStamp (anOS);
116 // write start define
117 anOS << "#ifndef _" << aCPPName << "_HeaderFile\n"
118 "#define _" << aCPPName << "_HeaderFile\n"
121 // write common includes
122 anOS << "#include <Standard.hxx>\n"
123 "#include <Standard_DefineAlloc.hxx>\n"
124 "#include <Standard_Handle.hxx>\n"
125 "#include <StepData_SelectType.hxx>\n"
126 "#include <Standard_Integer.hxx>\n"
129 anOS << "class Standard_Transient;\n";
130 if (!aSeqMember->IsEmpty())
131 anOS << "class StepData_SelectMember;\n";
133 Standard_Integer jj = 1;
134 for (Standard_Integer i = 1; i <= myItems->Length(); i++)
136 Handle(Express_Item) anItem = myItems->Value (i);
138 if (anItem->IsKind (STANDARD_TYPE(Express_Alias)))
140 Handle(Express_Type) aType = Handle(Express_Alias)::DownCast (anItem)->Type();
141 if (aType->IsStandard())
146 anOS << "class " << anItem->CPPName() << ";\n";
152 anOS << "//! Representation of STEP SELECT type " << Name() << "\n"
153 "class " << aCPPName << " : public StepData_SelectType\n"
158 " DEFINE_STANDARD_ALLOC\n"
161 // default constructor
162 anOS << " //! Empty constructor\n"
163 " Standard_EXPORT " << aCPPName << "();\n"
166 // write common methods section
167 anOS << " //! Recognizes a kind of " << Name() << " select type\n";
168 for (Standard_Integer i = 1; i <= aSeqEntities->Length(); i++)
170 Standard_Integer anIdx = aSeqEntities->Value (i);
171 anOS << " //! -- " << i << " -> " << myNames->Value (anIdx)->String() << "\n";
173 anOS << " Standard_EXPORT Standard_Integer CaseNum (const Handle(Standard_Transient)& theEnt) const Standard_OVERRIDE;\n"
176 if (!aSeqMember->IsEmpty())
178 anOS << " //! Recognizes items of select member " << Name() << "Member\n";
179 for (Standard_Integer i = 1; i <= aSeqMember->Length(); i++)
181 Standard_Integer anIdx = aSeqMember->Value (i);
182 anOS << " //! -- " << i << " -> " << myNames->Value (anIdx)->String() << "\n";
184 anOS << " //! -- 0 else\n"
185 " Standard_EXPORT virtual Standard_Integer CaseMem (const Handle(StepData_SelectMember)& theEnt) const Standard_OVERRIDE;\n"
187 " //! Returns a new select member the type " << Name() << "Member\n"
188 " Standard_EXPORT virtual Handle(StepData_SelectMember) NewMember() const Standard_OVERRIDE;\n"
192 // write methods get for entities
193 for (Standard_Integer i = 1; i <= aSeqEntities->Length(); i++)
195 Standard_Integer anIdx = aSeqEntities->Value (i);
196 Handle(Express_Item) anItem = myItems->Value (anIdx);
197 const TCollection_AsciiString& aName = anItem->Name();
198 anOS << " //! Returns Value as " << aName << " (or Null if another type)\n"
199 " Standard_EXPORT Handle(" << anItem->CPPName() << ") " << aName << "() const;\n"
203 // writes method set and get for enum , integer, real and string.
204 for (Standard_Integer i = 1; i <= aSeqMember->Length(); i++)
206 Standard_Integer anIdx = aSeqMember->Value (i);
207 Handle(Express_Item) anItem = myItems->Value (anIdx);
208 const TCollection_AsciiString& aName = anItem->Name();
209 const TCollection_AsciiString& anItemCPPName = anItem->CPPName();
210 anOS << " //! Set Value for " << aName << "\n"
211 " Standard_EXPORT void Set" << aName << " (const " << anItemCPPName << " theVal);\n"
213 " //! Returns Value as " << aName << " (or Null if another type)\n"
214 " " << anItemCPPName << " " << aName << "() const;\n"
220 "#endif // _" << aCPPName << "_HeaderFile\n";
223 //===============================
224 // Step 2: generating CXX
227 std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".cxx"), std::ios::out | std::ios::binary);
228 Standard_OStream& anOS = *aStreamPtr;
231 Express::WriteFileStamp (anOS);
233 // write include section
234 anOS << "#include <" << aCPPName << ".hxx>\n";
235 if (!aSeqMember->IsEmpty())
237 anOS << "#include <" << aCPPName << "Member.hxx>\n"
238 "#include <TCollection_HAsciiString.hxx>\n";
240 for (Standard_Integer i = 1; i <= aSeqEntities->Length(); i++)
242 Standard_Integer anIdx = aSeqEntities->Value (i);
243 anOS << "#include <" << myItems->Value (anIdx)->CPPName() << ".hxx>\n";
247 Express::WriteMethodStamp (anOS, aCPPName);
248 anOS << aCPPName << "::" << aCPPName << "()\n"
252 // write CaseNum method
253 Express::WriteMethodStamp (anOS, "CaseNum");
254 anOS << "Standard_Integer " << aCPPName << "::CaseNum (const Handle(Standard_Transient)& theEnt) const\n"
257 if (!aSeqEntities->IsEmpty())
259 anOS << " if (theEnt.IsNull()) return 0;\n";
260 for (Standard_Integer i = 1; i <= aSeqEntities->Length(); i++)
262 Standard_Integer anIdx = aSeqEntities->Value (i);
263 anOS << " if (theEnt->IsKind (STANDARD_TYPE(" << myItems->Value (anIdx)->CPPName() << "))) return " << i << ";\n";
265 anOS << " return 0;\n"
270 anOS << " return 0;\n"
274 if (!aSeqMember->IsEmpty())
276 // write CaseMem method
277 Express::WriteMethodStamp (anOS, "CaseMem");
278 anOS << "Standard_Integer " << aCPPName << "::CaseMem (const Handle(StepData_SelectMember)& theEnt) const\n"
280 " if (theEnt.IsNull()) return 0;\n";
281 for (int j = 1; j <= aSeqMember->Length(); j++)
283 Standard_Integer anIdx = aSeqMember->Value (j);
286 anOS << " if (theEnt->Matches (\"" << myNames->Value (anIdx)->String() << "\")) return " << j << ";\n";
290 anOS << " else if (theEnt->Matches (\"" << myNames->Value (anIdx)->String() << "\")) return " << j << ";\n";
293 anOS << " else return 0;\n"
296 // write NewMember method
297 Express::WriteMethodStamp (anOS, "NewMember");
298 anOS << "Handle(StepData_SelectMember) " << aCPPName << "::NewMember() const\n"
300 " return new " << aCPPName << "Member;\n"
304 // write methods Get for entities.
305 for (Standard_Integer i = 1; i <= aSeqEntities->Length(); i++)
307 Standard_Integer anIdx = aSeqEntities->Value (i);
308 Handle(Express_Item) anItem = myItems->Value (anIdx);
309 const TCollection_AsciiString& aName = anItem->Name();
310 const TCollection_AsciiString& anItemCPPName = anItem->CPPName();
311 Express::WriteMethodStamp (anOS, aName);
312 anOS << "Handle(" << anItemCPPName << ") " << aCPPName << "::" << aName << "() const\n"
314 " return Handle(" << anItemCPPName << ")::DownCast(Value());\n"
318 // write methods Set and Get for Integer, Real, String and Enum
319 for (Standard_Integer i = 1; i <= aSeqMember->Length(); i++)
321 Standard_Integer anIdx = aSeqMember->Value (i);
322 Handle(Express_Item) anItem = myItems->Value (anIdx);
323 const TCollection_AsciiString& aName = anItem->Name();
324 const TCollection_AsciiString& anItemCPPName = anItem->CPPName();
325 TCollection_AsciiString aStamp = "Set";
327 Express::WriteMethodStamp (anOS, aStamp);
329 Standard_Boolean isString = (anItemCPPName.Location ("HAsciiString", 1, anItemCPPName.Length()) > 0);
330 TCollection_AsciiString aNameFunc;
331 TCollection_AsciiString aFunc;
332 Standard_Boolean isEnum = anItem->IsKind (STANDARD_TYPE(Express_Enum));
341 aNameFunc += anItemCPPName;
343 Standard_Integer aSplitInd = aNameFunc.Location ("_", 1, anItemCPPName.Length());
346 aFunc = aNameFunc.Split (aSplitInd);
354 anOS << "void " << aCPPName << "::Set" << aName << " (const Handle(" << anItemCPPName << ") &theVal)\n";
358 anOS << "void " << aCPPName << "::Set" << aName << " (const " << anItemCPPName << " theVal)\n";
362 " Handle(" << aCPPName << "Member) SelMem = Handle(" << aCPPName << "Member)::DownCast(Value());\n"
363 " if (SelMem.IsNull()) return;\n"
364 " Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString(\"" << aName << "\");\n"
365 " SelMem->SetName (aName->ToCString());\n";
368 anOS << " SelMem->SetEnum ((Standard_Integer)theVal);\n";
372 anOS << " SelMem->Set" << aFunc << " (theVal->ToCString());\n";
376 anOS << " SelMem->Set" << aFunc << " (theVal);\n";
381 Express::WriteMethodStamp (anOS, aName);
384 anOS << "Handle(" << anItemCPPName << ") " << aCPPName << "::" << aName << "() const\n";
388 anOS << anItemCPPName << " " << aCPPName << "::" << aName << "() const\n";
392 " Handle(" << aCPPName << "Member) SelMem = Handle(" << aCPPName << "Member)::DownCast (Value());\n"
393 " if (SelMem.IsNull()) return 0;\n"
394 " Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString;\n"
395 " aName->AssignCat (SelMem->Name());\n"
396 " Handle(TCollection_HAsciiString) aNameItem = new TCollection_HAsciiString(\"" << aName << "\");\n"
397 " if (aName->IsDifferent (aNameItem)) return 0;\n";
400 anOS << " Standard_Integer aNumIt = SelMem->Enum();\n"
401 " " << anItemCPPName << " aVal;\n"
404 Handle(Express_Enum) anEnum = Handle(Express_Enum)::DownCast (anItem);
405 Handle(TColStd_HSequenceOfHAsciiString) anEnItems = anEnum->Names();
406 TCollection_AsciiString aPrefix = Express::EnumPrefix (aName);
407 for (Standard_Integer k = 1; k <= anEnItems->Length(); k++)
409 anOS << " case " << k << " : aVal = " << aName << "_" << aPrefix << anEnItems->Value (k)->String() << "; break;\n";
411 anOS << " default : return 0; break;\n"
416 anOS << " Handle(TCollection_HAsciiString) aVal = new TCollection_HAsciiString;\n"
417 " aVal->AssignCat (SelMem->String());\n";
421 anOS << " " << anItemCPPName << " aVal = SelMem->" << aFunc << "();\n";
424 anOS << " return aVal;\n"
431 return Standard_True;
434 //=======================================================================
435 // function : PropagateUse
437 //=======================================================================
439 void Express_Select::PropagateUse() const
441 const TCollection_AsciiString& aPack = GetPackageName();
442 const TCollection_AsciiString& aName = Name();
444 for (Standard_Integer i = 1; i <= myItems->Length(); i++)
446 Handle(Express_Item) anItem = myItems->Value (i);
447 anItem->Use2 (aName, aPack);
451 //=======================================================================
452 // function : GenerateSelectMember
454 //=======================================================================
456 Standard_Boolean Express_Select::generateSelectMember (const Handle(TColStd_HSequenceOfInteger)& theSeqMember) const
458 TCollection_AsciiString aCPPname = CPPName();
459 aCPPname += "Member";
461 // create a package directory (if not yet exist)
462 OSD_Protection aProt (OSD_RWXD, OSD_RWXD, OSD_RX, OSD_RX);
463 TCollection_AsciiString aPack = GetPackageName();
464 OSD_Path aPath (aPack);
465 OSD_Directory aDir (aPath);
469 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
471 // Step 1: generating HXX
474 std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".hxx"), std::ios::out | std::ios::binary);
475 Standard_OStream& anOS = *aStreamPtr;
477 Express::WriteFileStamp (anOS);
479 // write start define
480 anOS << "#ifndef _" << aCPPname << "_HeaderFile\n"
481 "#define _" << aCPPname << "_HeaderFile\n"
485 anOS << "#include <Standard.hxx>\n"
486 "#include <Standard_Type.hxx>\n"
487 "#include <Standard_Boolean.hxx>\n"
488 "#include <Standard_CString.hxx>\n"
489 "#include <Standard_Integer.hxx>\n"
490 "#include <StepData_SelectNamed.hxx>\n"
492 "DEFINE_STANDARD_HANDLE(" << aCPPname << ", StepData_SelectNamed)\n"
495 // write start of declaration (inheritance)
496 anOS << " //! Representation of member for STEP SELECT type " << Name() << "\n"
497 "class " << aCPPname << " : public StepData_SelectNamed\n"
502 anOS << " //! Empty constructor\n"
503 " Standard_EXPORT " << aCPPname << "();\n"
505 " //! Returns True if has name\n"
506 " Standard_EXPORT virtual Standard_Boolean HasName() const Standard_OVERRIDE;\n"
508 " //! Returns name\n"
509 " Standard_EXPORT virtual Standard_CString Name() const Standard_OVERRIDE;\n"
512 " Standard_EXPORT virtual Standard_Boolean SetName(const Standard_CString name) Standard_OVERRIDE;\n"
514 " //! Tells if the name of a SelectMember matches a given one;\n"
515 " Standard_EXPORT virtual Standard_Boolean Matches (const Standard_CString name) const Standard_OVERRIDE;\n"
520 " Standard_Integer myCase;\n"
524 "#endif // _" << aCPPname << "_HeaderFile\n";
527 //===============================
528 // Step 2: generating CXX
531 std::shared_ptr<std::ostream> aStreamPtr = aFileSystem->OpenOStream (aPack.Cat (".cxx"), std::ios::out | std::ios::binary);
532 Standard_OStream& anOS = *aStreamPtr;
535 Express::WriteFileStamp (anOS);
537 // write include section
538 anOS << "#include <" << aCPPname << ".hxx>\n"
539 "#include <TCollection_HAsciiString.hxx>\n";
541 Express::WriteMethodStamp (anOS, aCPPname);
542 anOS << aCPPname << "::" << aCPPname << "() : myCase(0) \n"
546 // write method HasName
547 Express::WriteMethodStamp (anOS, "HasName");
548 anOS << "Standard_Boolean " << aCPPname << "::HasName() const\n"
550 " return myCase > 0;\n"
553 Standard_Boolean hasEnum = Standard_False;
555 Express::WriteMethodStamp (anOS, "Name");
556 anOS << "Standard_CString " << aCPPname << "::Name() const\n"
558 " Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString;\n"
561 for (Standard_Integer i = 1; i <= theSeqMember->Length(); i++)
563 Standard_Integer anIdx = theSeqMember->Value (i);
564 Handle(Express_Item) anItem = myItems->Value (anIdx);
565 if (anItem->IsKind (STANDARD_TYPE(Express_Enum)))
567 hasEnum = Standard_True;
569 anOS << " case " << i << " : aName->AssignCat (\"" << myNames->Value (anIdx)->String() << "\"); break;\n";
571 anOS << " default : break;\n"
573 " return aName->String();\n"
576 // write static method for compare name
577 Express::WriteMethodStamp (anOS, "CompareNames");
578 anOS << "static Standard_Integer CompareNames (const Standard_CString theName";
581 anOS << ", Standard_Integer &theNumEn)\n";
588 " Standard_Integer aCase = 0;\n"
589 " if (!theName || theName[0] == \'/0\') aCase = 0;\n";
590 for (Standard_Integer i = 1; i <= theSeqMember->Length(); i++)
592 Standard_Integer anIdx = theSeqMember->Value (i);
593 Handle(Express_Item) anItem = myItems->Value (anIdx);
594 if (anItem->IsKind (STANDARD_TYPE(Express_Enum)))
596 Handle(Express_Enum) en = Handle(Express_Enum)::DownCast (anItem);
597 for (Standard_Integer k = 1; k <= en->Names()->Length(); k++)
599 anOS << " else if (!strcmp (theName, \"" << en->Names()->Value (k)->String() << "\"))\n"
601 " aCase = " << i << ";\n"
602 " theNumEn = " << k << ";\n"
608 anOS << " else if (!strcmp (theName, \"" << myNames->Value (anIdx)->String() << "\")) aCase = " << i << ";\n";
611 anOS << " return aCase;\n"
614 // write method SetName
615 Express::WriteMethodStamp (anOS, "SetName");
616 anOS << "Standard_Boolean " << aCPPname << "::SetName (const Standard_CString theName) \n"
620 anOS << " Standard_Integer aNumIt = 0;\n"
621 " myCase = CompareNames (theName, aNumIt);\n"
622 " if (aNumIt) SetInteger (aNumIt);\n";
626 anOS << " myCase = CompareNames (theName);\n";
628 anOS << " return (myCase > 0);\n"
631 // write method Matches
632 Express::WriteMethodStamp (anOS, "Matches");
633 anOS << "Standard_Boolean " << aCPPname << "::Matches (const Standard_CString theName) const\n"
637 anOS << " Standard_Integer aNumIt = 0;\n"
638 " Standard_Integer aCase = CompareNames (theName, aNumIt);\n";
642 anOS << " Standard_Integer aCase = CompareNames (theName);\n";
644 anOS << " return (aCase > 0);\n"
649 return Standard_True;