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