1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include <precomp.h>
23 #include "i2s_calculator.hxx"
24 
25 
26 // NOT FULLY DEFINED SERVICES
27 #include <algorithm>
28 #include <string.h>
29 #include <cosv/file.hxx>
30 //#include <adc_manager.hxx>
31 //#include <adc_options.hxx>
32 #include <ary/qualiname.hxx>
33 #include <ary/idl/i_enum.hxx>
34 #include <ary/idl/i_exception.hxx>
35 #include <ary/idl/i_function.hxx>
36 #include <ary/idl/i_gate.hxx>
37 #include <ary/idl/i_interface.hxx>
38 #include <ary/idl/ik_interface.hxx>
39 #include <ary/idl/i_module.hxx>
40 #include <ary/idl/i_property.hxx>
41 #include <ary/idl/i_service.hxx>
42 #include <ary/idl/i_singleton.hxx>
43 #include <ary/idl/i_siservice.hxx>
44 #include <ary/idl/i_sisingleton.hxx>
45 #include <ary/idl/i_struct.hxx>
46 #include <ary/idl/i_structelem.hxx>
47 #include <ary/idl/i_typedef.hxx>
48 #include <ary/idl/ip_ce.hxx>
49 #include <ary/idl/ip_type.hxx>
50 #include <ary/namesort.hxx>
51 #include <nametreenode.hxx>
52 #include "i_nnfinder.hxx"
53 #include "ia_ce.hxx"
54 #include "ia_type.hxx"
55 #include "is_ce.hxx"
56 #include "is_type.hxx"
57 #include "it_ce.hxx"
58 #include "it_explicit.hxx"
59 #include "it_sequence.hxx"
60 #include "it_xnameroom.hxx"
61 
62 
63 
64 namespace ary
65 {
66 namespace idl
67 {
68 
69 template <class DEST>
70 DEST *
SearchCe4Type(Type_id i_type)71 SecondariesCalculator::SearchCe4Type(Type_id i_type)
72 {
73     Ce_id
74         ce = lhf_Search_CeFromTypeId(i_type);
75     if (ce.IsValid())
76         return ary_cast<DEST>(& my_CeStorage()[ce]);
77     return 0;
78 }
79 
80 
81 typedef stg::const_iterator<CodeEntity> stg_citerator;
82 typedef stg::iterator<CodeEntity>       stg_iterator;
83 
84 typedef stg::filter_iterator<CodeEntity,Interface>
85                                         interface_iterator;
86 
87 typedef stg::filter_iterator<Type,ExplicitType>
88                                         explicittype_iterator;
89 
90 typedef ary::stg::const_filter_iterator<CodeEntity,Typedef>
91                                         typedef_citerator;
92 
93 
94 inline Service *
lhf_SearchService(Type_id i_nType)95 SecondariesCalculator::lhf_SearchService( Type_id i_nType )
96 {
97     return SearchCe4Type<Service>(i_nType);
98 }
99 
100 inline Interface *
lhf_SearchInterface(Type_id i_nType)101 SecondariesCalculator::lhf_SearchInterface( Type_id i_nType )
102 {
103     return SearchCe4Type<Interface>(i_nType);
104 }
105 
106 inline Struct *
lhf_SearchStruct(Type_id i_nType)107 SecondariesCalculator::lhf_SearchStruct( Type_id i_nType )
108 {
109     return SearchCe4Type<Struct>(i_nType);
110 }
111 
112 inline Exception *
lhf_SearchException(Type_id i_nType)113 SecondariesCalculator::lhf_SearchException( Type_id i_nType )
114 {
115     return SearchCe4Type<Exception>(i_nType);
116 }
117 
118 inline const Ce_Storage &
my_CeStorage() const119 SecondariesCalculator::my_CeStorage() const
120 {
121     csv_assert(pCes != 0);
122     return pCes->Storage();
123 }
124 
125 inline const Type_Storage &
my_TypeStorage() const126 SecondariesCalculator::my_TypeStorage() const
127 {
128     csv_assert(pTypes != 0);
129     return pTypes->Storage();
130 }
131 
132 inline Ce_Storage &
my_CeStorage()133 SecondariesCalculator::my_CeStorage()
134 {
135     csv_assert(pCes != 0);
136     return pCes->Storage();
137 }
138 
139 inline Type_Storage &
my_TypeStorage()140 SecondariesCalculator::my_TypeStorage()
141 {
142     csv_assert(pTypes != 0);
143     return pTypes->Storage();
144 }
145 
146 inline void
insert_into2sList(CodeEntity & o_out,int i_listIndex,Ce_id i_nCe)147 SecondariesCalculator::insert_into2sList( CodeEntity &        o_out,
148                                           int                 i_listIndex,
149                                           Ce_id               i_nCe )
150     { o_out.Secondaries().Access_List(i_listIndex).push_back(i_nCe); }
151 
152 
SecondariesCalculator(CeAdmin & i_ces,TypeAdmin & i_types)153 SecondariesCalculator::SecondariesCalculator( CeAdmin &      i_ces,
154                                               TypeAdmin &    i_types )
155     :   pCes(&i_ces),
156         pTypes(&i_types)
157 {
158 }
159 
~SecondariesCalculator()160 SecondariesCalculator::~SecondariesCalculator()
161 {
162 }
163 
164 
165 void
CheckAllInterfaceBases()166 SecondariesCalculator::CheckAllInterfaceBases()
167 {
168     Module &
169         rGlobalNamespace = pCes->GlobalNamespace();
170     QualifiedName
171         aXInterface("::com::sun::star::uno::XInterface","::");
172 
173     const Type &
174         rType = pTypes->CheckIn_Type(   aXInterface,
175                                         0,
176                                         rGlobalNamespace.CeId(),
177                                         0 );
178     Type_id
179         nTypeXInterface = rType.TypeId();
180     const ExplicitType &
181         rExplType = ary_cast<ExplicitType>(rType);
182     Ce_id
183         nCeXInterface = lhf_Search_CeForType(rExplType);
184 
185     interface_iterator itEnd( my_CeStorage().End() );
186     for ( interface_iterator it( my_CeStorage().BeginUnreserved() );
187           it != itEnd;
188           ++it )
189     {
190         if (NOT it.IsValid())
191             continue;
192 
193         Interface &
194             rInterface = *it;
195         if (     NOT rInterface.HasBase()               // According to UNO IDL syntax, an interface without base has com::sun::star::uno::XInterface as base.
196              AND rInterface.CeId() != nCeXInterface )   // XInterface must not be base of itself.
197         {
198             rInterface.Add_Base(nTypeXInterface, 0);
199         }
200     }   // end for
201 }
202 
203 void
Connect_Types2Ces()204 SecondariesCalculator::Connect_Types2Ces()
205 {
206     explicittype_iterator itEnd( my_TypeStorage().End() );
207     for ( explicittype_iterator it( my_TypeStorage().BeginUnreserved() );
208           it != itEnd;
209           ++it )
210     {
211         if (NOT it.IsValid())
212             continue;
213 
214         ExplicitType &
215             rType = ary_cast<ExplicitType>(*it);
216         Ce_id
217             nRelatedCe = lhf_Search_CeForType(rType);
218         if (nRelatedCe.IsValid())
219         {
220             Ce_Type *
221                 pNew = new Ce_Type(nRelatedCe, rType.TemplateParameters());
222             my_TypeStorage().Replace_Entity( rType.TypeId(),
223                                              *pNew );
224         }
225     }   // end for
226 }
227 
228 void
Gather_CrossReferences()229 SecondariesCalculator::Gather_CrossReferences()
230 {
231     gather_Synonyms();
232 
233     for ( stg_iterator it = my_CeStorage().Begin();
234           it != my_CeStorage().End();
235           ++it )
236     {
237         (*it).Accept( static_cast< SPInst_asHost& >(*this) );
238 
239     }   // end for
240 
241     sort_All2s();
242 }
243 
244 void
Make_Links2DeveloperManual(const String & i_devman_reffilepath)245 SecondariesCalculator::Make_Links2DeveloperManual(
246                                 const String &      i_devman_reffilepath )
247 {
248 //    const autodoc::Options &
249 //        rOptions = TheAutodocManager().TheOptions();
250 //
251 //    const String &
252 //        rDeveloperManual_URL
253 //            = rOptions.Get_Extra(autodoc::OPT_developer_guide);
254 //    const String
255 //        rDeveloperManual_ReferenceFile
256 //            = rOptions.Get_Extra(autodoc::OPT_developer_guide_refs_file);
257 
258 //    if ( rDeveloperManual_URL.length() == 0
259 //         OR
260 //         rDeveloperManual_ReferenceFile.length() == 0 )
261 //    {
262 //        return;
263 //    }
264 
265     csv::File
266         aFile(i_devman_reffilepath, csv::CFM_READ);
267     csv::OpenCloseGuard
268         aFileOpener(aFile);
269     if (aFileOpener)
270     {
271         Read_Links2DevManual(aFile);
272     }
273 }
274 
275 namespace
276 {
277 
278 enum E_LinkMode
279 {
280     link2descr,
281     link2ref
282 };
283 
284 struct OrderCeIdsByName
285 {
OrderCeIdsByNameary::idl::__anonef6b2ac70111::OrderCeIdsByName286                         OrderCeIdsByName(
287                             const Ce_Storage &      i_storage )
288                                 :   rStorage(i_storage),
289                                     aNameComparison() {}
operator ()ary::idl::__anonef6b2ac70111::OrderCeIdsByName290     bool                operator()(
291                             Ce_id                   i_ce1,
292                             Ce_id                   i_ce2 ) const
293     {
294         return aNameComparison( rStorage[i_ce1].LocalName(),
295                                 rStorage[i_ce2].LocalName() );
296     }
297 
298   private:
299     const Ce_Storage &  rStorage;
300     LesserName          aNameComparison;
301 };
302 
303 
304 }
305 
306 
307 
308 void
do_Process(const Service & i_rData)309 SecondariesCalculator::do_Process( const Service & i_rData )
310 {
311     const Service &
312         rService = ary_cast<Service>(i_rData);
313 
314     // Interfaces:
315     assignImplementation_toAServicesInterfaces( rService.CeId(),
316 												rService.CeId(),
317 												interface_2s_ExportingServices );
318     // Services and their interfaces:
319     recursive_AssignIncludingService(rService.CeId(), rService);
320 }
321 
322 void
do_Process(const Interface & i_rData)323 SecondariesCalculator::do_Process( const Interface & i_rData )
324 {
325     assign_AsDerivedInterface( ary_cast<Interface>(i_rData) );
326 }
327 
328 void
do_Process(const Struct & i_rData)329 SecondariesCalculator::do_Process( const Struct &  i_rData )
330 {
331     assign_AsDerivedStruct( ary_cast<Struct>(i_rData) );
332 }
333 
334 void
do_Process(const Exception & i_rData)335 SecondariesCalculator::do_Process( const Exception &  i_rData )
336 {
337     assign_AsDerivedException( ary_cast<Exception>(i_rData) );
338 }
339 
340 void
do_Process(const Typedef &)341 SecondariesCalculator::do_Process( const Typedef &  )
342 {
343     // KORR_FUTURE
344     // Find out what was meant here ???
345 
346 //    const Typedef &
347 //        rTypedef = ary_cast<Typedef>(i_rData);
348 }
349 
350 void
do_Process(const Singleton & i_rData)351 SecondariesCalculator::do_Process( const Singleton &  i_rData )
352 {
353     const Singleton &
354         rSingleton = ary_cast<Singleton>(i_rData);
355 
356     Service *
357         pServ = lhf_SearchService(rSingleton.AssociatedService());
358     if (pServ != 0)
359     {
360         insert_into2sUnique( *pServ,
361 							 service_2s_InstantiatingSingletons,
362 							 rSingleton.CeId() );
363     }
364 
365     // Interfaces:
366     assignImplementation_toAServicesInterfaces( rSingleton.CeId(),
367 												lhf_Search_CeFromTypeId(rSingleton.AssociatedService()),
368 												interface_2s_ExportingSingletons );
369 }
370 
371 void
do_Process(const SglIfcService & i_rData)372 SecondariesCalculator::do_Process( const SglIfcService &  i_rData )
373 {
374     const SglIfcService &
375         rSglIfcService = ary_cast<SglIfcService>(i_rData);
376 
377     assignImplementation_toAServicesInterfaces( rSglIfcService.CeId(),
378 												rSglIfcService.CeId(),
379 												interface_2s_ExportingServices );
380 }
381 
382 void
do_Process(const SglIfcSingleton & i_rData)383 SecondariesCalculator::do_Process( const SglIfcSingleton &  i_rData )
384 {
385     const SglIfcSingleton &
386         rSglIfcSingleton = ary_cast<SglIfcSingleton>(i_rData);
387 
388     Type_id nBase = rSglIfcSingleton.BaseInterface();
389     recursive_AssignImplementation_toExportedInterface( rSglIfcSingleton.CeId(),
390 														nBase,
391 														interface_2s_ExportingSingletons );
392 }
393 
394 void
do_Process(const Function & i_rData)395 SecondariesCalculator::do_Process( const Function & i_rData )
396 {
397     const Function &
398         rFunction = ary_cast<Function>(i_rData);
399 
400     recursive_AssignFunction_toCeAsReturn(rFunction.CeId(), rFunction.ReturnType());
401 
402     for ( Function::ParamList::const_iterator itp = rFunction.Parameters().begin();
403           itp != rFunction.Parameters().end();
404           ++itp )
405     {
406         recursive_AssignFunction_toCeAsParameter(rFunction.CeId(), (*itp).Type());
407     }   // end for (itp)
408 
409     for ( Function::ExceptionList::const_iterator itx = rFunction.Exceptions().begin();
410           itx != rFunction.Exceptions().end();
411           ++itx )
412     {
413         Exception *
414             pX = lhf_SearchException(*itx);
415         if (pX != 0)
416         {
417             insert_into2sUnique(*pX, exception_2s_RaisingFunctions, rFunction.CeId());
418         }
419     }   // end for (itx)
420 }
421 
422 void
do_Process(const StructElement & i_rData)423 SecondariesCalculator::do_Process( const StructElement & i_rData )
424 {
425     const StructElement &
426         rStructElement = ary_cast<StructElement>(i_rData);
427 
428     recursive_AssignStructElement_toCeAsDataType(rStructElement.CeId(), rStructElement.Type());
429 }
430 
431 void
do_Process(const Property & i_rData)432 SecondariesCalculator::do_Process( const Property & i_rData )
433 {
434     const Property &
435         rProperty = ary_cast<Property>(i_rData);
436 
437     recursive_AssignStructElement_toCeAsDataType(rProperty.CeId(), rProperty.Type());
438 }
439 
440 Ce_id
lhf_Search_CeForType(const ExplicitType & i_rType) const441 SecondariesCalculator::lhf_Search_CeForType( const ExplicitType & i_rType ) const
442 {
443     const ExplicitNameRoom &
444         rExplicitNameRoom = ary_cast<ExplicitNameRoom>(
445                                 my_TypeStorage()[i_rType.NameRoom()] );
446     Find_ModuleNode
447         rNodeFinder( my_CeStorage(),
448                      rExplicitNameRoom.NameChain_Begin(),
449                      rExplicitNameRoom.NameChain_End(),
450                      i_rType.Name() );
451 
452     if ( rExplicitNameRoom.IsAbsolute() )
453     {
454         const Module &
455             rGlobalNamespace = ary_cast<Module>(
456                                 my_CeStorage()[predefined::ce_GlobalNamespace]);
457         return Search_SubTree(  rGlobalNamespace,
458                                 rNodeFinder );
459     }
460     else
461     {
462         const Module &
463             rStartModule = ary_cast<Module>(
464                                 my_CeStorage()[i_rType.ModuleOfOccurrence()]);
465         Ce_id ret = Search_SubTree_UpTillRoot( rStartModule,
466 											   rNodeFinder );
467 		return ret;
468     }   // endif (rExplicitNameRoom.IsAbsolute()) else
469 }
470 
471 Ce_id
lhf_Search_CeFromTypeId(Type_id i_nType) const472 SecondariesCalculator::lhf_Search_CeFromTypeId( Type_id i_nType ) const
473 {
474     if (NOT i_nType.IsValid())
475         return Ce_id(0);
476     const Ce_Type *
477         pType = ary_cast<Ce_Type>( & my_TypeStorage()[i_nType] );
478     return pType != 0
479                 ?   pType->RelatedCe()
480                 :   Ce_id_Null();
481 }
482 
483 void
assign_CurLink(char * i_text,const String & i_link,const String & i_linkUI,bool i_isDescr,int i_lineCount)484 SecondariesCalculator::assign_CurLink( char *              i_text,
485                                        const String &      i_link,
486                                        const String &      i_linkUI,
487                                        bool                i_isDescr,
488                                        int                 i_lineCount )
489 {
490     csv_assert(i_text != 0);
491 
492     const ary::idl::Module *
493         pModule = & ary_cast<Module>(
494                         my_CeStorage()[predefined::ce_GlobalNamespace]);
495 
496     char * pPastNext = 0;
497     char * pNext = i_text;
498     for ( ;
499           (pPastNext = strstr(pNext,".")) != 0;
500           pNext = pPastNext + 1 )
501     {
502         String sNext(pNext, pPastNext-pNext);
503         Ce_id nModule = pModule->Search_Name(sNext);
504         if (nModule.IsValid())
505         {
506             pModule = ary_cast<Module>( & my_CeStorage()[nModule] );
507         }
508         else
509         {
510             pModule = 0;
511         }
512 
513         if (pModule == 0)
514         {
515             Cerr() << "Warning: Invalid line nr. "
516                    << i_lineCount
517                    << " in DevelopersGuide reference file:\n"
518                    << reinterpret_cast< const char* >(i_text)
519                    << "\n"
520                    << Endl();
521             return;
522         }
523     }   // end for
524 
525     pPastNext = strchr(pNext,':');
526     bool bMember = pPastNext != 0;
527     String sCe( pNext, (bMember ? csv::str::size(pPastNext-pNext) : csv::str::maxsize) );
528 
529 //  KORR_FUTURE
530 //  String sMember(bMember ? pPastNext+1, "");
531 
532     Ce_id nCe = pModule->Search_Name(sCe);
533     if (NOT nCe.IsValid())
534     {
535         Cerr() << "Warning: Invalid line nr. "
536                << i_lineCount
537                << " in DevelopersGuide reference file:\n"
538                << reinterpret_cast< const char* >(i_text)
539                << "\n"
540                << Endl();
541         return;
542     }
543 
544     CodeEntity &
545         rCe = my_CeStorage()[nCe];
546     if (NOT bMember)
547     {
548         if (i_isDescr)
549             rCe.Secondaries().Add_Link2DescriptionInManual(i_link, i_linkUI);
550         else
551             rCe.Secondaries().Add_Link2RefInManual(i_link, i_linkUI);
552         return;
553     }
554     else
555     {
556     // KORR_FUTURE
557     //   Provisorial just doing nothing (or may be
558     //   adding a link at main Ces lists).
559 //    if (i_isDescr)
560 //        rCe.Secondaries().Add_Link2DescriptionInManual(i_link);
561 //    else
562 //        rCe.Secondaries().Add_Link2RefInManual(i_link);
563     }
564 }
565 
566 void
gather_Synonyms()567 SecondariesCalculator::gather_Synonyms()
568 {
569     const Ce_Storage &
570         cstrg = my_CeStorage();
571     typedef_citerator itEnd(cstrg.End());
572     for ( typedef_citerator it(cstrg.Begin());
573           it != itEnd;
574           ++it )
575     {
576         if (NOT it.IsValid())
577             continue;
578 
579         const Typedef &
580             rTypedef = *it;
581         recursive_AssignAsSynonym(rTypedef.CeId(), rTypedef);
582     }   // end for (itTd)
583 }
584 
585 void
recursive_AssignAsSynonym(Ce_id i_synonymousTypedefsId,const Typedef & i_TypedefToCheck)586 SecondariesCalculator::recursive_AssignAsSynonym( Ce_id               i_synonymousTypedefsId,
587                                                   const Typedef &     i_TypedefToCheck )
588 {
589     Ce_id
590         nCe = lhf_Search_CeFromTypeId(i_TypedefToCheck.DefiningType());
591     if (NOT nCe.IsValid())
592         return;
593     CodeEntity &
594         rCe = my_CeStorage()[nCe];
595 
596     switch (rCe.AryClass())  // KORR_FUTURE: make this faster, remove switch.
597     {
598         case Interface::class_id:
599                     insert_into2sList( rCe,
600 									   interface_2s_SynonymTypedefs,
601 									   i_synonymousTypedefsId );
602                     break;
603         case Struct::class_id:
604                     insert_into2sList( rCe,
605 									   struct_2s_SynonymTypedefs,
606 									   i_synonymousTypedefsId );
607                     break;
608         case Enum::class_id:
609                     insert_into2sList( rCe,
610 									   enum_2s_SynonymTypedefs,
611 									   i_synonymousTypedefsId );
612                     break;
613         case Typedef::class_id:
614                     insert_into2sList( rCe,
615 									   typedef_2s_SynonymTypedefs,
616 									   i_synonymousTypedefsId );
617                     recursive_AssignAsSynonym( i_synonymousTypedefsId,
618                                                static_cast< Typedef& >(rCe) );
619                     break;
620                 // default: do nothing.
621     }
622 }
623 
624 void
recursive_AssignIncludingService(Ce_id i_includingServicesId,const Service & i_ServiceToCheckItsIncludes)625 SecondariesCalculator::recursive_AssignIncludingService( Ce_id               i_includingServicesId,
626                                                          const Service &     i_ServiceToCheckItsIncludes )
627 {
628     Dyn_StdConstIterator<CommentedRelation>
629         pIncludedServices;
630     i_ServiceToCheckItsIncludes.Get_IncludedServices(pIncludedServices);
631 
632     for ( StdConstIterator<CommentedRelation> &
633                 itServ = *pIncludedServices;
634           itServ;
635           ++itServ )
636     {
637         Service *
638             pServ = lhf_SearchService((*itServ).Type());
639         if (pServ != 0)
640         {
641             insert_into2sUnique( *pServ,
642 								 service_2s_IncludingServices,
643 								 i_includingServicesId
644 							   );
645             recursive_AssignIncludingService(i_includingServicesId, *pServ);
646 
647         }   // end if
648 
649         assignImplementation_toAServicesInterfaces( i_includingServicesId,
650 													lhf_Search_CeFromTypeId( (*itServ).Type() ),
651 													interface_2s_ExportingServices );
652     }   // end for
653 }
654 
655 void
assign_AsDerivedInterface(const Interface & i_rDerived)656 SecondariesCalculator::assign_AsDerivedInterface( const Interface & i_rDerived )
657 {
658     ary::Dyn_StdConstIterator<ary::idl::CommentedRelation>
659         pHelp;
660     ary::idl::ifc_interface::attr::Get_Bases(pHelp, i_rDerived);
661 
662     for ( ary::StdConstIterator<ary::idl::CommentedRelation> & it = *pHelp;
663           it.operator bool();
664           ++it )
665     {
666         Interface *
667             pIfc = lhf_SearchInterface( (*it).Type() );
668         if (pIfc == 0)
669             continue;
670 
671         insert_into2sList( *pIfc,
672                            interface_2s_Derivations,
673 						   i_rDerived.CeId() );
674     }   // end for
675 }
676 
677 void
assign_AsDerivedStruct(const Struct & i_rDerived)678 SecondariesCalculator::assign_AsDerivedStruct( const Struct &   i_rDerived )
679 {
680     Type_id
681         nBase = i_rDerived.Base();
682     if (nBase.IsValid())
683     {
684         Struct *
685             pParent = lhf_SearchStruct(nBase);
686         if (pParent != 0)
687         {
688             insert_into2sList( *pParent,
689 							   struct_2s_Derivations,
690 							   i_rDerived.CeId() );
691         }
692     }
693 }
694 
695 void
assign_AsDerivedException(const Exception & i_rDerived)696 SecondariesCalculator::assign_AsDerivedException( const Exception &   i_rDerived )
697 {
698     Type_id
699         nBase = i_rDerived.Base();
700     if (nBase.IsValid())
701     {
702         Exception *
703             pParent = lhf_SearchException(nBase);
704         if (pParent != 0)
705         {
706             insert_into2sList( *pParent,
707 							   exception_2s_Derivations,
708 							   i_rDerived.CeId() );
709         }   // end if
710     }   // end if
711 }
712 
713 void
assignImplementation_toAServicesInterfaces(Ce_id i_nImpl,Ce_id i_nService,E_2s_of_Interface i_eList)714 SecondariesCalculator::assignImplementation_toAServicesInterfaces(
715                                                     Ce_id               i_nImpl,
716                                                     Ce_id               i_nService,
717                                                     E_2s_of_Interface   i_eList )
718 {
719     if (NOT i_nService.IsValid())
720         return;
721     Service *
722         pService = ary_cast<Service>( & my_CeStorage()[i_nService] );
723     SglIfcService *
724         pSglIfcService = ary_cast<SglIfcService>( & my_CeStorage()[i_nService] );
725 
726     if (pService != 0)
727     {
728         Dyn_StdConstIterator<CommentedRelation>
729             pSupportedInterfaces;
730         pService->Get_SupportedInterfaces(pSupportedInterfaces);
731 
732         for ( StdConstIterator<CommentedRelation> &
733                     itInfc = *pSupportedInterfaces;
734               itInfc.operator bool();
735 			  ++itInfc )
736         {
737             recursive_AssignImplementation_toExportedInterface( i_nImpl,
738 																(*itInfc).Type(),
739 																i_eList );
740         }   // end for
741     }
742     else if (pSglIfcService != 0)
743     {
744         Type_id nBase = pSglIfcService->BaseInterface();
745         recursive_AssignImplementation_toExportedInterface( i_nImpl,
746 															nBase,
747 															i_eList );
748     }   // end if
749 }
750 
751 void
recursive_AssignImplementation_toExportedInterface(Ce_id i_nService,Type_id i_nExportedInterface,E_2s_of_Interface i_eList)752 SecondariesCalculator::recursive_AssignImplementation_toExportedInterface(
753                                                     Ce_id               i_nService,
754 													Type_id             i_nExportedInterface,
755 													E_2s_of_Interface   i_eList )
756 {
757     Interface *
758         pIfc = lhf_SearchInterface(i_nExportedInterface);
759     if (pIfc == 0)
760         return;
761 
762     insert_into2sUnique( *pIfc,
763 						 i_eList,
764 						 i_nService );
765     Dyn_StdConstIterator<CommentedRelation>
766         pBases;
767     ary::idl::ifc_interface::attr::Get_Bases(pBases, *pIfc);
768     for ( StdConstIterator<CommentedRelation> & it = *pBases;
769           it.operator bool();
770           ++it )
771     {
772         recursive_AssignImplementation_toExportedInterface(i_nService, (*it).Type(), i_eList);
773     }
774 }
775 
776 void
recursive_AssignFunction_toCeAsReturn(Ce_id i_nFunction,Type_id i_nReturnType)777 SecondariesCalculator::recursive_AssignFunction_toCeAsReturn( Ce_id         i_nFunction,
778                                                               Type_id       i_nReturnType )
779 {
780     Ce_id
781         nCe = lhf_Search_CeFromTypeId(i_nReturnType);
782     if (NOT nCe.IsValid())
783         return;
784 
785     CodeEntity &
786         rCe = my_CeStorage()[nCe];
787     switch (rCe.AryClass())  // KORR_FUTURE: make this faster, remove switch.
788     {
789         case Interface::class_id:
790                     insert_into2sList( rCe,
791 									   interface_2s_AsReturns,
792 									   i_nFunction );
793                     break;
794         case Struct::class_id:
795                     insert_into2sList( rCe,
796 									   struct_2s_AsReturns,
797 									   i_nFunction );
798                     break;
799         case Enum::class_id:
800                     insert_into2sList( rCe,
801 									   enum_2s_AsReturns,
802 									   i_nFunction );
803                     break;
804         case Typedef::class_id:
805                     insert_into2sList( rCe,
806 									   typedef_2s_AsReturns,
807 									   i_nFunction );
808                     recursive_AssignFunction_toCeAsReturn( i_nFunction,
809                                                            static_cast< Typedef& >(rCe).DefiningType() );
810                     break;
811         // default: do nothing.
812     }
813 }
814 
815 void
recursive_AssignFunction_toCeAsParameter(Ce_id i_nFunction,Type_id i_nParameterType)816 SecondariesCalculator::recursive_AssignFunction_toCeAsParameter( Ce_id      i_nFunction,
817                                                                  Type_id    i_nParameterType )
818 {
819     Ce_id
820         nCe = lhf_Search_CeFromTypeId(i_nParameterType);
821     if (NOT nCe.IsValid())
822         return;
823 
824     CodeEntity &
825         rCe = my_CeStorage()[nCe];
826     switch (rCe.AryClass())  // KORR_FUTURE: make this faster, remove switch.
827     {
828         case Interface::class_id:
829                     insert_into2sList( rCe,
830 									   interface_2s_AsParameters,
831 									   i_nFunction );
832                     break;
833         case Struct::class_id:
834                     insert_into2sList( rCe,
835 									   struct_2s_AsParameters,
836 									   i_nFunction );
837                     break;
838         case Enum::class_id:
839                     insert_into2sList( rCe,
840 									   enum_2s_AsParameters,
841 									   i_nFunction );
842                     break;
843         case Typedef::class_id:
844                     insert_into2sList( rCe,
845 									   typedef_2s_AsParameters,
846 									   i_nFunction );
847                     recursive_AssignFunction_toCeAsParameter( i_nFunction,
848                                                               static_cast< Typedef& >(rCe).DefiningType() );
849                     break;
850         // default: do nothing.
851     }
852 }
853 
854 void
recursive_AssignStructElement_toCeAsDataType(Ce_id i_nDataElement,Type_id i_nDataType)855 SecondariesCalculator::recursive_AssignStructElement_toCeAsDataType( Ce_id   i_nDataElement,
856                                                                      Type_id i_nDataType )
857 {
858     Ce_id
859         nCe = lhf_Search_CeFromTypeId(i_nDataType);
860     if (NOT nCe.IsValid())
861         return;
862 
863     CodeEntity &
864         rCe = my_CeStorage()[nCe];
865     switch (rCe.AryClass())  // KORR_FUTURE: make this faster, remove switch.
866     {
867         case Interface::class_id:
868                     insert_into2sList( rCe,
869 									   interface_2s_AsDataTypes,
870 									   i_nDataElement );
871                     break;
872         case Struct::class_id:
873                     insert_into2sList( rCe,
874 									   struct_2s_AsDataTypes,
875 									   i_nDataElement );
876                     break;
877         case Enum::class_id:
878                     insert_into2sList( rCe,
879 									   enum_2s_AsDataTypes,
880 									   i_nDataElement );
881                     break;
882         case Typedef::class_id:
883                     insert_into2sList( rCe,
884 									   typedef_2s_AsDataTypes,
885 									   i_nDataElement );
886                     recursive_AssignFunction_toCeAsParameter( i_nDataElement,
887                                                               static_cast< Typedef& >(rCe).DefiningType() );
888                     break;
889         // default: do nothing.
890     }   // end switch
891 }
892 
893 void
insert_into2sUnique(CodeEntity & o_out,int i_listIndex,Ce_id i_nCe)894 SecondariesCalculator::insert_into2sUnique( CodeEntity &        o_out,
895 											int                 i_listIndex,
896 											Ce_id               i_nCe )
897 {
898     std::vector<Ce_id> &
899         rOut = o_out.Secondaries().Access_List(i_listIndex);
900     if (std::find(rOut.begin(),rOut.end(),i_nCe) != rOut.end())
901         return;
902     rOut.push_back(i_nCe);
903 }
904 
905 void
sort_All2s()906 SecondariesCalculator::sort_All2s()
907 {
908     OrderCeIdsByName
909         aIdOrdering(my_CeStorage());
910 
911     for ( stg_iterator it = my_CeStorage().Begin();
912           it != my_CeStorage().End();
913           ++it )
914     {
915         Ce_2s &
916             r2s = (*it).Secondaries();
917         int iCount = r2s.CountXrefLists();
918         for (int i = 0; i < iCount; ++i)
919         {
920             std::sort( r2s.Access_List(i).begin(),
921                        r2s.Access_List(i).end(),
922                        aIdOrdering );
923         }   // end for (i)
924     }   // end for (it)
925 }
926 
927 void
Read_Links2DevManual(csv::bstream & i_file)928 SecondariesCalculator::Read_Links2DevManual( csv::bstream & i_file )
929 {
930     StreamLock  aLine(300);
931     StreamStr & rLine = aLine();
932 
933 
934     String      sCurLink;
935     String      sCurLinkUI;
936     E_LinkMode  eCurMode = link2ref;
937 
938 	int lineCount = 0;
939     const char * sLink = "LINK:";
940     const char * sDescr = "DESCR:";
941     const char * sTopic = "TOPIC:";
942     const char * sRef = "REF:";
943     const UINT8  cMaxASCIINumWhiteSpace = 32;
944 
945     while (NOT i_file.eod())
946     {
947 		++lineCount;
948 
949         rLine.reset();
950         rLine.operator_read_line(i_file);
951 
952         if ( *rLine.c_str() >= 'a' )
953         {
954             assign_CurLink(rLine.begin(), sCurLink, sCurLinkUI, eCurMode == link2descr, lineCount);
955         }
956         else if ( strncmp(rLine.c_str(), sLink, strlen(sLink)) == 0 )
957         {
958             sCurLink = rLine.c_str()+5;
959             sCurLinkUI.clear();
960         }
961         else if ( strncmp(rLine.c_str(), sDescr, strlen(sDescr)) == 0 )
962         {
963             sCurLinkUI = rLine.c_str()+6;
964         }
965         else if ( strncmp(rLine.c_str(), sTopic, strlen(sTopic)) == 0 )
966         {
967             eCurMode = link2descr;
968         }
969         else if ( strncmp(rLine.c_str(), sRef, strlen(sRef)) == 0 )
970         {
971             eCurMode = link2ref;
972         }
973         else if (static_cast<UINT8>(*rLine.c_str()) > cMaxASCIINumWhiteSpace)
974         {
975             assign_CurLink(rLine.begin(), sCurLink, sCurLinkUI, eCurMode == link2descr, lineCount);
976         }
977      // else
978         //  Ignore empty line.
979 
980     }   // end while
981 }
982 
983 
984 
985 }   // namespace idl
986 }   // namespace ary
987