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 "hfi_typetext.hxx"
24 
25 
26 // NOT FULLY DEFINED SERVICES
27 #include <string.h>
28 #include <ary/idl/i_type.hxx>
29 #include <ary/idl/i_ce.hxx>
30 #include <ary/idl/i_module.hxx>
31 #include <ary/idl/i_module.hxx>
32 #include <ary/idl/ik_ce.hxx>
33 #include <adc_cl.hxx>
34 #include <adc_msg.hxx>
35 #include "hi_linkhelper.hxx"
36 
37 
38 
39 
40 
41 
42 inline const ary::idl::Module *
referingModule() const43 HF_IdlTypeText::referingModule() const
44 {
45     if (pReferingCe == 0)
46         return Env().Linker().Search_CurModule();
47     else
48         return &Env().Data().Find_Module(pReferingCe->NameRoom());
49 }
50 
51 inline const HF_IdlTypeText::client *
referingCe() const52 HF_IdlTypeText::referingCe() const
53 {
54     return pReferingCe;
55 }
56 
57 
HF_IdlTypeText(Environment & io_rEnv,Xml::Element & o_rOut,bool i_bWithLink,const client * i_pScopeGivingCe)58 HF_IdlTypeText::HF_IdlTypeText( Environment &       io_rEnv,
59                                 Xml::Element &      o_rOut,
60                                 bool                i_bWithLink,
61                                 const client *      i_pScopeGivingCe )
62     :   HtmlFactory_Idl(io_rEnv, &o_rOut),
63         pReferingCe( i_pScopeGivingCe ),
64         bWithLink(i_bWithLink)
65 {
66 }
67 
HF_IdlTypeText(Environment & io_rEnv,E_Index)68 HF_IdlTypeText::HF_IdlTypeText( Environment &       io_rEnv,
69                                 E_Index             )
70     :   HtmlFactory_Idl(io_rEnv, 0),
71         pReferingCe( 0 ),
72         bWithLink(true)
73 {
74 }
75 
~HF_IdlTypeText()76 HF_IdlTypeText::~HF_IdlTypeText()
77 {
78 }
79 
80 void
Produce_byData(ary::idl::Type_id i_idType) const81 HF_IdlTypeText::Produce_byData(ary::idl::Type_id i_idType) const
82 {
83     StringVector        aModule_;
84     String              sName;
85     ce_id               nCe;
86 	int                 nSequenceCount = 0;
87     csv::erase_container(aModule_);
88 
89     const ary::idl::Type &
90         rType = Env().Data().Find_Type(i_idType);
91     Env().Data().Get_TypeText(aModule_, sName, nCe, nSequenceCount, rType);
92 
93     if ( Env().Data().IsBuiltInOrRelated(rType) )
94     {
95         produce_BuiltIn(sName,nSequenceCount);
96     }
97     else
98     {
99         produce_FromStd( aModule_,
100                          sName,
101                          String::Null_(),
102                          nSequenceCount,
103                          (nCe.IsValid() ? exists_yes : exists_no),
104                          rType.FirstEnclosedNonSequenceType(Env().Gate()).TemplateParameters() );
105     }
106 }
107 
108 void
Produce_byData(ary::idl::Ce_id i_idCe) const109 HF_IdlTypeText::Produce_byData( ary::idl::Ce_id i_idCe ) const
110 {
111     StringVector        aModule_;
112     String              sCe;
113     String              sMember;
114     csv::erase_container(aModule_);
115 
116     const ary::idl::CodeEntity &
117         rCe = Env().Data().Find_Ce(i_idCe);
118     Env().Data().Get_CeText(aModule_, sCe, sMember, rCe);
119     produce_FromStd(aModule_, sCe, sMember, 0, exists_yes);
120 }
121 
122 void
Produce_byData(const String & i_sFullName) const123 HF_IdlTypeText::Produce_byData( const String & i_sFullName ) const
124 {
125     if ( strncmp(i_sFullName,"http://", 7) == 0 )
126     {
127         CurOut()
128             >> *new Html::Link(i_sFullName)
129                 << i_sFullName;
130         return;
131     }
132 
133     StringVector        aModule_;
134     String              sCe,
135 		                sMember;
136     int                 nSequence = 0;
137     String              sTypeText;
138     csv::erase_container(aModule_);
139 
140     const ary::idl::Module *
141         pScopeModule = referingModule();
142     if (pScopeModule == 0)
143     {
144         // SYNTAX_ERR, but rather logical error: Missing module.
145         CurOut() << i_sFullName;
146         // KORR_FUTURE
147         // How to put a message about this?
148         // errorOut_UnresolvedLink(i_sFullName);
149         return;
150     }
151 
152     const char * sTypeStart = strrchr(i_sFullName,'<');
153     if ( sTypeStart != 0 )
154     {
155         const char * sTypeEnd = strchr(i_sFullName,'>');
156         if (sTypeEnd == 0)
157         {   // SYNTAX_ERR
158             CurOut() << i_sFullName;
159             // KORR_FUTURE
160             // How to put a message about this?
161             // errorOut_UnresolvedLink(i_sFullName);
162             return;
163         }
164 
165         nSequence = count_Sequences(i_sFullName);
166         sTypeStart++;
167         sTypeText.assign(sTypeStart, sTypeEnd-sTypeStart);
168     }
169     else
170     {
171         sTypeText = i_sFullName;
172     }
173 
174     csv::erase_container(aModule_);
175     bool bFound =   // KORR : Check the semantics of this, see if ce really exists, if it is a member?
176         Env().Data().Search_Ce( aModule_,
177                                 sCe,sMember,
178                                 sTypeText,
179                                 *pScopeModule );
180     if (NOT bFound)
181     {
182         if ( strchr(sTypeText,':') == 0
183              AND
184              *sTypeText.c_str() != 'X' )    // This is a HACK, make this correct!
185         {
186             Produce_LocalLinkInDocu(sTypeText);
187             return;
188         }
189         CurOut() << i_sFullName;
190         // KORR
191         // How to put a message about this?
192         // errorOut_UnresolvedLink(i_sFullName);
193         return;
194     }
195 
196     produce_FromStd(aModule_, sCe, sMember, nSequence, exists_yes);
197 }
198 
199 void
Produce_LinkInDocu(const String & i_scope,const String & i_name,const String & i_member) const200 HF_IdlTypeText::Produce_LinkInDocu( const String &      i_scope,
201 	                                const String &      i_name,
202 	                                const String &      i_member ) const
203 {
204     StringVector        aModule_;
205     String              sName;
206     csv::erase_container(aModule_);
207 
208     const ary::idl::Module *
209         pScopeModule = referingModule();
210     if (pScopeModule == 0)
211     {
212         // SYNTAX_ERR, but rather logical error: Missing module.
213         CurOut() << i_scope << "::" << i_name;
214         if (NOT i_member.empty())
215             CurOut() << "::" << i_member;
216         return;
217     }
218 
219     bool
220         bFound = Env().Data().Search_CesModule( aModule_,
221                                                 i_scope,
222                                                 i_name,
223                                                 *pScopeModule );
224     if (NOT bFound)
225     {
226         CurOut() << i_scope << "::" << i_name;
227         if (NOT i_member.empty())
228             CurOut() << "::" << i_member;
229         return;
230     }
231     produce_FromStd(aModule_, i_name, i_member, 0, exists_yes);
232 }
233 
234 void
Produce_LocalLinkInDocu(const String & i_member) const235 HF_IdlTypeText::Produce_LocalLinkInDocu( const String & i_member ) const
236 {
237     StringVector        aModule_;
238     String              sName;
239     csv::erase_container(aModule_);
240 
241     csv_assert(referingCe() != 0);
242     if ( referingModule() == Env().Linker().Search_CurModule() )
243     {
244         StreamLock slLink(200);
245         if (referingCe()->SightLevel() == ary::idl::sl_Member)
246         {
247             slLink() << "#" << i_member;
248         }
249         else
250         {
251             slLink() << referingCe()->LocalName()
252                      << ".html#"
253                      << i_member;
254         }
255         CurOut()
256             >> *new Html::Link(slLink().c_str())
257                << i_member;
258         return;
259     }
260 
261     String sDummyMember;
262     Env().Data().Get_CeText(aModule_, sName, sDummyMember, *referingCe());
263     produce_FromStd(aModule_, sName, i_member, 0, exists_yes);
264 }
265 
266 void
Produce_IndexLink(Xml::Element & o_out,const client & i_ce) const267 HF_IdlTypeText::Produce_IndexLink( Xml::Element &   o_out,
268                                    const client &   i_ce ) const
269 {
270     StringVector        aModule_;
271     String              sCe;
272     String              sMember;
273     csv::erase_container(aModule_);
274 
275     Out().Enter(o_out);
276 
277     Env().Data().Get_CeText(aModule_, sCe, sMember, i_ce);
278     produce_IndexLink(aModule_, sCe, sMember, false);
279 
280     Out().Leave();
281 }
282 
283 void
Produce_IndexOwnerLink(Xml::Element & o_out,const client & i_owner) const284 HF_IdlTypeText::Produce_IndexOwnerLink( Xml::Element &  o_out,
285                                         const client &  i_owner ) const
286 {
287     StringVector        aModule_;
288     String              sCe;
289     String              sMember;
290     csv::erase_container(aModule_);
291 
292     Out().Enter(o_out);
293 
294     if (i_owner.Owner().IsValid())
295     {
296         Env().Data().Get_CeText(aModule_, sCe, sMember, i_owner);
297         produce_IndexLink(aModule_, sCe, sMember, true);
298     }
299     else
300     {   // global namespace:
301 
302         CurOut()
303             << "."
304             >> *new Html::Link("../module-ix.html")
305                << "global namespace";
306     }
307 
308 
309     Out().Leave();
310 }
311 
312 void
Produce_IndexSecondEntryLink(Xml::Element & o_out,const client & i_ce) const313 HF_IdlTypeText::Produce_IndexSecondEntryLink( Xml::Element &      o_out,
314                                               const client &      i_ce ) const
315 {
316     StringVector        aModule_;
317     String              sCe;
318     String              sMember;
319     csv::erase_container(aModule_);
320 
321     Out().Enter(o_out);
322 
323     Env().Data().Get_CeText(aModule_, sCe, sMember, i_ce);
324     produce_IndexLink(aModule_, sCe, sMember, true);
325     Out().Leave();
326 }
327 
328 
329 void
produce_FromStd(const StringVector & i_module,const String & i_ce,const String & i_member,int i_sequenceCount,E_Existence i_ceExists,const std::vector<ary::idl::Type_id> * i_templateParameters) const330 HF_IdlTypeText::produce_FromStd( const StringVector & i_module,
331                                  const String &       i_ce,
332                                  const String &       i_member,
333                                  int                  i_sequenceCount,
334                                  E_Existence          i_ceExists,
335                                  const std::vector<ary::idl::Type_id> *
336                                                       i_templateParameters ) const
337 {
338     if (i_ceExists == exists_no)
339     {
340         if ( is_ExternLink(i_module) )
341         {
342             produce_ExternLink(i_module,i_ce,i_member,i_sequenceCount,i_templateParameters);
343             return;
344         }
345         errorOut_UnresolvedLink(i_module, i_ce, i_member);
346     }
347 
348     output::Node &
349         rCeNode = Env().OutputTree().Provide_Node(i_module);
350     output::Position
351         aTargetPos(rCeNode);
352     bool
353         bShowModule = rCeNode != Env().CurPosition().RelatedNode()
354                             ?   i_module.size() > 0
355                             :   false;
356     bool
357         bUseMember = NOT i_member.empty();
358     bool
359         bLink2Module = i_ceExists == exists_yes;
360     bool
361         bLink2Ce = i_ceExists == exists_yes;
362     bool
363         bLink2Member = NOT Env().Is_MemberExistenceCheckRequired()
364                        AND i_ceExists == exists_yes;
365     bool
366         bHasCeOrName = NOT i_ce.empty();
367 
368     if (i_sequenceCount > 0)
369         start_Sequence(i_sequenceCount);
370 
371     StreamLock  aLink(300);
372     StreamStr & rLink = aLink();
373 
374     // Produce output: module
375     if (bShowModule)
376     {
377         int nMax = i_module.size() - 1;
378         int nCount = 0;
379         StringVector::const_iterator
380             itm = i_module.begin();
381         for ( ;
382               nCount < nMax;
383               ++itm, ++nCount )
384         {
385             CurOut() << "::" << *itm;
386         }
387 
388         CurOut() << "::";
389         if (bLink2Module)
390         {
391             aTargetPos.Set_File(output::ModuleFileName());
392             Env().Linker().Get_Link2Position(rLink, aTargetPos);
393             CurOut()
394                 >> *new Html::Link( rLink.c_str() )
395                     << *itm;
396             rLink.reset();
397         }
398         else
399         {
400             CurOut() << *itm;
401         }
402 
403         if (bHasCeOrName)
404             CurOut() << "::";
405     }   // end if (bShowModule)
406 
407     // CodeEntity and member:
408     aTargetPos.Set_File( rLink << i_ce << ".html" << c_str );
409     rLink.reset();
410 
411     if (bHasCeOrName)
412     {
413         if (bLink2Ce)
414         {
415             Env().Linker().Get_Link2Position(rLink, aTargetPos);
416             CurOut()
417                 >> *new Html::Link(rLink.c_str())
418                     << i_ce;
419             rLink.reset();
420         }
421         else
422         {
423             CurOut() << i_ce;
424         }
425 
426         if (i_templateParameters != 0)
427             write_TemplateParameterList(*i_templateParameters);
428 
429         if (bUseMember)
430         {
431             CurOut() << "::";
432 
433             if (bLink2Member)
434             {
435     			bool bFunction = strstr(i_member,"()") != 0;
436 			    String sMember( i_member );
437 			    if (bFunction)
438 				    sMember.assign(i_member.c_str(), sMember.length()-2);
439 
440                 Env().Linker().Get_Link2Member(rLink, aTargetPos, sMember);
441                 CurOut()
442                     >> *new Html::Link(rLink.c_str())
443                         << i_member;
444                 rLink.reset();
445             }
446             else
447             {
448                 CurOut()
449                     << i_member;
450             }
451         }   // endif (bUseMember)
452     }   // endif (bHasCeOrName)
453 
454     if (i_sequenceCount > 0)
455         finish_Sequence(i_sequenceCount);
456 }
457 
458 void
produce_BuiltIn(const String & i_type,int i_sequenceCount) const459 HF_IdlTypeText::produce_BuiltIn( const String &      i_type,
460                                  int                 i_sequenceCount ) const
461 {
462     if (i_sequenceCount > 0)
463         start_Sequence(i_sequenceCount);
464     CurOut() << i_type;
465     if (i_sequenceCount > 0)
466         finish_Sequence(i_sequenceCount);
467 }
468 
469 void
produce_IndexLink(const StringVector & i_module,const String & i_ce,const String & i_member,bool i_bIsOwner) const470 HF_IdlTypeText::produce_IndexLink( const StringVector & i_module,
471                                    const String &       i_ce,
472                                    const String &       i_member,
473                                    bool                 i_bIsOwner ) const
474 {
475     output::Node &
476         rCeNode = Env().OutputTree().Provide_Node(i_module);
477     output::Position
478         aTargetPos(rCeNode);
479     bool
480         bShowModule = i_bIsOwner OR (i_module.size() > 0 AND i_ce.empty());
481     bool
482         bShowNonModule = NOT bShowModule OR (i_bIsOwner AND NOT i_ce.empty());
483     bool
484         bUseMember = NOT i_member.empty();
485 
486     StreamLock  aLink(300);
487     StreamStr & rLink = aLink();
488 
489     // Produce output: module
490     if (bShowModule)
491     {
492         if (i_bIsOwner)
493         {
494             int nMax = bShowNonModule ? i_module.size() : i_module.size() - 1;
495             int nCount = 0;
496             for ( StringVector::const_iterator itm = i_module.begin();
497                   nCount < nMax;
498                   ++itm, ++nCount )
499             {
500                 CurOut() << "::" << *itm;
501             }
502             CurOut() << ":: .";
503         }
504 
505         if (NOT bShowNonModule)
506         {
507             aTargetPos.Set_File(output::ModuleFileName());
508             Env().Linker().Get_Link2Position(rLink, aTargetPos);
509             CurOut()
510                 >> *new Html::Link( rLink.c_str() )
511                     >> *new Html::Bold
512                         << i_module.back();
513             rLink.reset();
514         }
515     }   // end if (bShowModule)
516 
517 	if (bShowNonModule)
518     {
519         aTargetPos.Set_File( rLink << i_ce << ".html" << c_str );
520         rLink.reset();
521 
522         if (bUseMember)
523         {
524 			bool bFunction = strstr(i_member,"()") != 0;
525 			String sMember( i_member );
526 			if (bFunction)
527 				sMember.assign(i_member.c_str(), sMember.length()-2);
528             Env().Linker().Get_Link2Member(rLink, aTargetPos, sMember);
529             CurOut()
530                 >> *new Html::Link(rLink.c_str())
531                     >> *new Html::Bold
532                         << i_member;
533             rLink.reset();
534         }
535         else
536         {
537             Env().Linker().Get_Link2Position(rLink, aTargetPos);
538             if (i_bIsOwner)
539             {
540                 CurOut()
541                     >> *new Html::Link(rLink.c_str())
542                        << i_ce;
543             }
544             else
545             {
546                 CurOut()
547                     >> *new Html::Link(rLink.c_str())
548    	                    >> *new Html::Bold
549                             << i_ce;
550             }
551             rLink.reset();
552         }
553     }   // endif (bHasCeOrName)
554 }
555 
556 int
count_Sequences(const char * i_sFullType) const557 HF_IdlTypeText::count_Sequences( const char * i_sFullType ) const
558 {
559     int ret = 0;
560 
561     for ( const char * pCount = i_sFullType;
562           *pCount != 0;
563            )
564     {
565         pCount = strstr(pCount,"sequence");
566         if (pCount != 0)
567         {
568             pCount += sizeof("sequence");   // = strlen(sequence) + 1 for '<'.
569             if ( *(pCount-1) == '\0' )
570             {
571                 // SYNTAX_ERR
572                 return 0;
573             }
574             ++ret;
575         }
576     }   // end for
577 
578     return ret;
579 }
580 
581 void
start_Sequence(int i_count) const582 HF_IdlTypeText::start_Sequence( int i_count ) const
583 {
584     csv_assert( i_count > 0 );
585     for (int i = 0; i < i_count; ++i )
586     {
587         CurOut() << "sequence< ";
588     }
589 }
590 
591 void
finish_Sequence(int i_count) const592 HF_IdlTypeText::finish_Sequence( int i_count ) const
593 {
594     csv_assert( i_count > 0 );
595     for (int i = 0; i < i_count; ++i )
596     {
597         CurOut() << " >";
598     }
599 }
600 
601 void
errorOut_UnresolvedLink(const char * i_name) const602 HF_IdlTypeText::errorOut_UnresolvedLink( const char *        i_name ) const
603 {
604     StreamLock slFile(1000);
605 
606     // KORR
607     // Handle links in cited documentation from other entities.
608     slFile() << Env().CurPageCe_AsText();
609     slFile().pop_back(5);
610     slFile() << ".idl";
611 
612     // KORR
613     // Retrieve, correct line number.
614     TheMessages().Out_UnresolvedLink( i_name,
615                                       slFile().c_str(),
616                                       0 );
617 }
618 
619 void
errorOut_UnresolvedLink(const StringVector & i_module,const String & i_ce,const String & i_member) const620 HF_IdlTypeText::errorOut_UnresolvedLink( const StringVector & i_module,
621                                          const String &       i_ce,
622                                          const String &       i_member ) const
623 {
624     StreamLock slName(500);
625 
626     if (i_module.size() > 0)
627     {
628         slName().operator_join(i_module.begin(), i_module.end(), "::");
629      	if (NOT i_ce.empty())
630             slName() << "::";
631     }
632     if (NOT i_ce.empty())
633     {
634         slName() << i_ce;
635         if (NOT i_member.empty())
636             slName() << "::" << i_member;
637     }
638     errorOut_UnresolvedLink(slName().c_str());
639 }
640 
641 bool
is_ExternLink(const StringVector & i_module) const642 HF_IdlTypeText::is_ExternLink( const StringVector & i_module ) const
643 {
644     const autodoc::CommandLine &
645         rCmdLine = autodoc::CommandLine::Get_();
646     uintt nExtNspLength = rCmdLine.ExternNamespace().length();
647     if (nExtNspLength == 0)
648         return false;
649 
650     StreamStr s(1000);
651     s << "::";
652     s.operator_join( i_module.begin(),
653                      i_module.end(),
654                      "::" );
655 
656     if (s.length() < nExtNspLength)
657         return false;
658     return ( strncmp( rCmdLine.ExternNamespace().c_str(),
659                       s.c_str(),
660                       nExtNspLength ) == 0 );
661 }
662 
663 void
produce_ExternLink(const StringVector & i_module,const String & i_ce,const String & i_member,int i_sequenceCount,const std::vector<ary::idl::Type_id> * i_templateParameters) const664 HF_IdlTypeText::produce_ExternLink( const StringVector & i_module,
665                                     const String &       i_ce,
666                                     const String &       i_member,
667                                     int                  i_sequenceCount,
668                                     const std::vector<ary::idl::Type_id> *
669                                                          i_templateParameters ) const
670 {
671     // KORR
672     // Look again at this code and take some time.
673 
674     StreamLock  aLink(1000);
675     StreamStr & rLink = aLink();
676 
677     rLink << autodoc::CommandLine::Get_().ExternRoot();
678     rLink.operator_join( i_module.begin(),
679                          i_module.end(),
680                          "/" );
681     rLink << '/'
682           << i_ce
683           << ".html";
684     if (i_member.length() > 0)
685         rLink << "/#" << i_member;
686 
687     if (i_sequenceCount > 0)
688         start_Sequence(i_sequenceCount);
689 
690     // module
691     int nMax = i_module.size();
692     int nCount = 0;
693     StringVector::const_iterator
694         itm = i_module.begin();
695     for ( ;
696           nCount < nMax;
697           ++itm, ++nCount )
698     {
699         CurOut() << "::" << *itm;
700     }
701     CurOut() << "::";
702 
703 
704     // CodeEntity
705     if (i_member.length() == 0)
706     {
707         CurOut()
708            >> *new Html::Link(rLink.c_str())
709               << i_ce;
710     }
711     else
712     {
713         CurOut()
714             << i_ce;
715     }
716 
717     if (i_templateParameters != 0)
718         write_TemplateParameterList(*i_templateParameters);
719 
720     // Member
721     if (i_member.length() > 0)
722     {
723         CurOut()
724             >> *new Html::Link(rLink.c_str())
725                 << i_member;
726     }
727 
728     if (i_sequenceCount > 0)
729         finish_Sequence(i_sequenceCount);
730 }
731 
732 void
write_TemplateParameterList(const std::vector<ary::idl::Type_id> & i_templateParameters) const733 HF_IdlTypeText::write_TemplateParameterList(
734                     const std::vector<ary::idl::Type_id> & i_templateParameters ) const
735 {
736     if (i_templateParameters.size() == 0)
737         return;
738 
739     HF_IdlTypeText
740         aTemplateParamWriter(Env(), CurOut(), true, pReferingCe);
741     CurOut() << "< ";
742     std::vector<ary::idl::Type_id>::const_iterator
743         it = i_templateParameters.begin();
744     aTemplateParamWriter.Produce_byData(*it);
745     for ( ++it; it != i_templateParameters.end(); ++it )
746     {
747         CurOut() << ", ";
748         aTemplateParamWriter.Produce_byData(*it);
749     }
750     CurOut() << " >";
751 }
752