Fix for UBSan build
[platform/upstream/doxygen.git] / src / namespacedef.cpp
1 /******************************************************************************
2  *
3  * $Id: namespacedef.cpp,v 1.27 2001/03/19 19:27:41 root Exp $
4  *
5  * Copyright (C) 1997-2012 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby 
9  * granted. No representations are made about the suitability of this software 
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include "qtbc.h"
19 #include "namespacedef.h"
20 #include "outputlist.h"
21 #include "util.h"
22 #include "language.h"
23 #include "classdef.h"
24 #include "classlist.h"
25 #include "memberlist.h"
26 #include "doxygen.h"
27 #include "message.h"
28 #include "docparser.h"
29 #include "searchindex.h"
30 #include "vhdldocgen.h"
31 #include "layout.h"
32
33 //------------------------------------------------------------------
34
35 NamespaceDef::NamespaceDef(const char *df,int dl,
36                            const char *name,const char *lref,
37                            const char *fName) : 
38    Definition(df,dl,name)
39 {
40   if (fName)
41   {
42     fileName = stripExtension(fName);
43   }
44   else
45   {
46     fileName="namespace";
47     fileName+=name;
48   }
49   classSDict = new ClassSDict(17);
50   namespaceSDict = new NamespaceSDict(17);
51   m_innerCompounds = new SDict<Definition>(17);
52   usingDirList = 0;
53   usingDeclList = 0;
54   m_allMembersDict = 0;
55   setReference(lref);
56   memberGroupSDict = new MemberGroupSDict;
57   memberGroupSDict->setAutoDelete(TRUE);
58   visited=FALSE;
59   m_subGrouping=Config_getBool("SUBGROUPING");
60 }
61
62 NamespaceDef::~NamespaceDef()
63 {
64   delete classSDict;
65   delete namespaceSDict;
66   delete m_innerCompounds;
67   delete usingDirList;
68   delete usingDeclList;
69   delete memberGroupSDict;
70 }
71
72 void NamespaceDef::distributeMemberGroupDocumentation()
73 {
74   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
75   MemberGroup *mg;
76   for (;(mg=mgli.current());++mgli)
77   {
78     mg->distributeMemberGroupDocumentation();
79   }
80 }
81
82 void NamespaceDef::findSectionsInDocumentation()
83 {
84   docFindSections(documentation(),this,0,docFile());
85   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
86   MemberGroup *mg;
87   for (;(mg=mgli.current());++mgli)
88   {
89     mg->findSectionsInDocumentation();
90   }
91   QListIterator<MemberList> mli(m_memberLists);
92   MemberList *ml;
93   for (mli.toFirst();(ml=mli.current());++mli)
94   {
95     if (ml->listType()&MemberList::declarationLists)
96     {
97       ml->findSectionsInDocumentation();
98     }
99   }
100 }
101
102 void NamespaceDef::insertUsedFile(const char *f)
103 {
104   if (files.find(f)==-1) 
105   {
106     if (Config_getBool("SORT_MEMBER_DOCS"))
107       files.inSort(f);
108     else
109       files.append(f);
110   }
111 }
112
113 void NamespaceDef::addInnerCompound(Definition *d)
114 {
115   m_innerCompounds->append(d->localName(),d);
116   if (d->definitionType()==Definition::TypeNamespace)
117   {
118     insertNamespace((NamespaceDef *)d);
119   }
120   else if (d->definitionType()==Definition::TypeClass)
121   {
122     insertClass((ClassDef *)d);
123   }
124 }
125
126 void NamespaceDef::insertClass(ClassDef *cd)
127 {
128   if (classSDict->find(cd->name())==0)
129   {
130     if (Config_getBool("SORT_BRIEF_DOCS"))
131       classSDict->inSort(cd->name(),cd);
132     else
133       classSDict->append(cd->name(),cd);
134   }
135 }
136
137 void NamespaceDef::insertNamespace(NamespaceDef *nd)
138 {
139   if (namespaceSDict->find(nd->name())==0)
140   {
141     if (Config_getBool("SORT_MEMBER_DOCS"))
142       namespaceSDict->inSort(nd->name(),nd);
143     else
144       namespaceSDict->append(nd->name(),nd);
145   }
146 }
147
148
149 void NamespaceDef::addMembersToMemberGroup()
150 {
151   QListIterator<MemberList> mli(m_memberLists);
152   MemberList *ml;
153   for (mli.toFirst();(ml=mli.current());++mli)
154   {
155     if (ml->listType()&MemberList::declarationLists)
156     {
157       ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
158     }
159   }
160
161   // add members inside sections to their groups
162   if (memberGroupSDict)
163   {
164     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
165     MemberGroup *mg;
166     for (;(mg=mgli.current());++mgli)
167     {
168       if (mg->allMembersInSameSection() && m_subGrouping)
169       {
170         //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
171         mg->addToDeclarationSection();
172       }
173     }
174   }
175 }
176
177 void NamespaceDef::insertMember(MemberDef *md)
178 {
179   if (md->isHidden()) return;
180   MemberList *allMemberList = getMemberList(MemberList::allMembersList);
181   if (allMemberList==0)
182   {
183     allMemberList = new MemberList(MemberList::allMembersList);
184     m_memberLists.append(allMemberList);
185   }
186   allMemberList->append(md); 
187   if (m_allMembersDict==0)
188   {
189     m_allMembersDict = new MemberSDict;
190   }
191   //printf("%s::m_allMembersDict->append(%s)\n",name().data(),md->localName().data());
192   m_allMembersDict->append(md->localName(),md); 
193   //::addNamespaceMemberNameToIndex(md);
194   //static bool sortBriefDocs=Config_getBool("SORT_BRIEF_DOCS");
195   switch(md->memberType())
196   {
197     case MemberDef::Variable:     
198       addMemberToList(MemberList::decVarMembers,md);
199       addMemberToList(MemberList::docVarMembers,md);
200       break;
201     case MemberDef::Function: 
202       addMemberToList(MemberList::decFuncMembers,md);
203       addMemberToList(MemberList::docFuncMembers,md);
204       break;
205     case MemberDef::Typedef:      
206       addMemberToList(MemberList::decTypedefMembers,md);
207       addMemberToList(MemberList::docTypedefMembers,md);
208       break;
209     case MemberDef::Enumeration:  
210       addMemberToList(MemberList::decEnumMembers,md);
211       addMemberToList(MemberList::docEnumMembers,md);
212       break;
213     case MemberDef::EnumValue:    
214       break;
215     case MemberDef::Define:       
216       addMemberToList(MemberList::decDefineMembers,md);
217       addMemberToList(MemberList::docDefineMembers,md);
218       break;
219     default:
220       err("NamespaceDef::insertMembers(): "
221            "member `%s' with class scope `%s' inserted in namespace scope `%s'!\n",
222            md->name().data(),
223            md->getClassDef() ? md->getClassDef()->name().data() : "",
224            name().data());
225   }
226 }
227
228 void NamespaceDef::computeAnchors()
229 {
230   MemberList *allMemberList = getMemberList(MemberList::allMembersList);
231   if (allMemberList) setAnchors(0,'a',allMemberList);
232 }
233
234 void NamespaceDef::writeDetailedDescription(OutputList &ol,const QCString &title)
235 {
236   if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) || 
237       !documentation().isEmpty()
238      )
239   {
240     ol.pushGeneratorState();
241       ol.disable(OutputGenerator::Html);
242       ol.writeRuler();
243     ol.popGeneratorState();
244     ol.pushGeneratorState();
245       ol.disableAllBut(OutputGenerator::Html);
246       ol.writeAnchor(0,"details"); 
247     ol.popGeneratorState();
248     ol.startGroupHeader();
249     ol.parseText(title);
250     ol.endGroupHeader();
251
252     ol.startTextBlock();
253     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
254     {
255       ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
256     }
257     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
258         !documentation().isEmpty())
259     {
260       ol.pushGeneratorState();
261         ol.disable(OutputGenerator::Man);
262         ol.disable(OutputGenerator::RTF);
263         //ol.newParagraph(); // FIXME:PARA
264         ol.enableAll();
265         ol.disableAllBut(OutputGenerator::Man);
266         ol.writeString("\n\n");
267       ol.popGeneratorState();
268     }
269     if (!documentation().isEmpty())
270     {
271       ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
272     }
273     ol.endTextBlock();
274   }
275 }
276
277 void NamespaceDef::writeBriefDescription(OutputList &ol)
278 {
279   if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
280   {
281     ol.startParagraph();
282     ol.parseDoc(briefFile(),briefLine(),this,0,
283                 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
284     ol.pushGeneratorState();
285     ol.disable(OutputGenerator::RTF);
286     ol.writeString(" \n");
287     ol.enable(OutputGenerator::RTF);
288
289     if (Config_getBool("REPEAT_BRIEF") ||
290         !documentation().isEmpty()
291        )
292     {
293       ol.disableAllBut(OutputGenerator::Html);
294       ol.startTextLink(0,"details");
295       ol.parseText(theTranslator->trMore());
296       ol.endTextLink();
297     }
298     ol.popGeneratorState();
299     ol.endParagraph();
300
301     // FIXME:PARA
302     //ol.pushGeneratorState();
303     //ol.disable(OutputGenerator::RTF);
304     //ol.newParagraph();
305     //ol.popGeneratorState();
306   }
307   ol.writeSynopsis();
308 }
309
310 void NamespaceDef::startMemberDeclarations(OutputList &ol)
311 {
312   ol.startMemberSections();
313 }
314
315 void NamespaceDef::endMemberDeclarations(OutputList &ol)
316 {
317   ol.endMemberSections();
318 }
319
320 void NamespaceDef::startMemberDocumentation(OutputList &ol)
321 {
322   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
323   {
324     ol.disable(OutputGenerator::Html);
325     Doxygen::suppressDocWarnings = TRUE;
326   }
327 }
328
329 void NamespaceDef::endMemberDocumentation(OutputList &ol)
330 {
331   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
332   {
333     ol.enable(OutputGenerator::Html);
334     Doxygen::suppressDocWarnings = FALSE;
335   }
336 }
337
338 void NamespaceDef::writeClassDeclarations(OutputList &ol,const QCString &title)
339 {
340   if (classSDict) classSDict->writeDeclaration(ol,0,title,TRUE);
341 }
342
343 void NamespaceDef::writeInlineClasses(OutputList &ol)
344 {
345   if (classSDict) classSDict->writeDocumentation(ol,this);
346 }
347
348 void NamespaceDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title)
349 {
350   if (namespaceSDict) namespaceSDict->writeDeclaration(ol,title,TRUE);
351 }
352
353 void NamespaceDef::writeMemberGroups(OutputList &ol)
354 {
355   /* write user defined member groups */
356   if (memberGroupSDict)
357   {
358     memberGroupSDict->sort();
359     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
360     MemberGroup *mg;
361     for (;(mg=mgli.current());++mgli)
362     {
363       if ((!mg->allMembersInSameSection() || !m_subGrouping) 
364           && mg->header()!="[NOHEADER]")
365       {
366         mg->writeDeclarations(ol,0,this,0,0);
367       }
368     }
369   }
370 }
371   
372 void NamespaceDef::writeAuthorSection(OutputList &ol)
373 {
374   // write Author section (Man only)
375   ol.pushGeneratorState();
376   ol.disableAllBut(OutputGenerator::Man);
377   ol.startGroupHeader();
378   ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
379   ol.endGroupHeader();
380   ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
381   ol.popGeneratorState();
382 }
383
384 void NamespaceDef::writeSummaryLinks(OutputList &ol)
385 {
386   ol.pushGeneratorState();
387   ol.disableAllBut(OutputGenerator::Html);
388   QListIterator<LayoutDocEntry> eli(
389       LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace));
390   LayoutDocEntry *lde;
391   bool first=TRUE;
392   SrcLangExt lang = getLanguage();
393   for (eli.toFirst();(lde=eli.current());++eli)
394   {
395     if ((lde->kind()==LayoutDocEntry::NamespaceClasses && classSDict && classSDict->declVisible()) || 
396         (lde->kind()==LayoutDocEntry::NamespaceNestedNamespaces && namespaceSDict && namespaceSDict->declVisible())
397        )
398     {
399       LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
400       QCString label = lde->kind()==LayoutDocEntry::NamespaceClasses ? "nested-classes" : "namespaces";
401       ol.writeSummaryLink(0,label,ls->title(lang),first);
402       first=FALSE;
403     }
404     else if (lde->kind()== LayoutDocEntry::MemberDecl)
405     {
406       LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
407       MemberList * ml = getMemberList(lmd->type);
408       if (ml && ml->declVisible())
409       {
410         ol.writeSummaryLink(0,ml->listTypeAsString(),lmd->title(lang),first);
411         first=FALSE;
412       }
413     }
414   }
415   if (!first)
416   {
417     ol.writeString("  </div>\n");
418   }
419   ol.popGeneratorState();
420 }
421
422 void NamespaceDef::writeDocumentation(OutputList &ol)
423 {
424   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
425   //static bool outputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
426   //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
427   SrcLangExt lang = getLanguage();
428
429   QCString pageTitle;
430   if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
431   {
432     pageTitle = theTranslator->trPackage(displayName());
433   }
434   else if (lang==SrcLangExt_Fortran)
435   {
436     pageTitle = theTranslator->trModuleReference(displayName());
437   }
438   else
439   {
440     pageTitle = theTranslator->trNamespaceReference(displayName());
441   }
442   startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_NamespaceVisible,!generateTreeView);
443
444   if (!generateTreeView)
445   {
446     if (getOuterScope()!=Doxygen::globalScope)
447     {
448       writeNavigationPath(ol);
449     }
450     ol.endQuickIndices();
451   }
452
453   startTitle(ol,getOutputFileBase(),this);
454   ol.parseText(pageTitle);
455   addGroupListToTitle(ol,this);
456   endTitle(ol,getOutputFileBase(),displayName());
457   ol.startContents();
458   
459   if (Doxygen::searchIndex)
460   {
461     Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
462     Doxygen::searchIndex->addWord(localName(),TRUE);
463   }
464
465   bool generateTagFile = !Config_getString("GENERATE_TAGFILE").isEmpty();
466   if (generateTagFile)
467   {
468     Doxygen::tagFile << "  <compound kind=\"namespace\">" << endl;
469     Doxygen::tagFile << "    <name>" << convertToXML(name()) << "</name>" << endl;
470     Doxygen::tagFile << "    <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
471   }
472
473   Doxygen::indexList.addIndexItem(this,0);
474
475   //---------------------------------------- start flexible part -------------------------------
476
477   QListIterator<LayoutDocEntry> eli(
478       LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace));
479   LayoutDocEntry *lde;
480   for (eli.toFirst();(lde=eli.current());++eli)
481   {
482     switch (lde->kind())
483     {
484       case LayoutDocEntry::BriefDesc: 
485         writeBriefDescription(ol);
486         break; 
487       case LayoutDocEntry::MemberDeclStart: 
488         startMemberDeclarations(ol);
489         break; 
490       case LayoutDocEntry::NamespaceClasses: 
491         {
492           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
493           writeClassDeclarations(ol,ls->title(lang));
494         }
495         break; 
496       case LayoutDocEntry::NamespaceNestedNamespaces: 
497         {
498           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
499           writeNamespaceDeclarations(ol,ls->title(lang));
500         }
501         break; 
502       case LayoutDocEntry::MemberGroups: 
503         writeMemberGroups(ol);
504         break; 
505       case LayoutDocEntry::MemberDecl: 
506         {
507           LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
508           writeMemberDeclarations(ol,lmd->type,lmd->title(lang));
509         }
510         break; 
511       case LayoutDocEntry::MemberDeclEnd: 
512         endMemberDeclarations(ol);
513         break;
514       case LayoutDocEntry::DetailedDesc: 
515         {
516           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
517           writeDetailedDescription(ol,ls->title(lang));
518         }
519         break;
520       case LayoutDocEntry::MemberDefStart: 
521         startMemberDocumentation(ol);
522         break; 
523       case LayoutDocEntry::NamespaceInlineClasses:
524         writeInlineClasses(ol);
525         break;
526       case LayoutDocEntry::MemberDef: 
527         {
528           LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
529           writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
530         }
531         break;
532       case LayoutDocEntry::MemberDefEnd: 
533         endMemberDocumentation(ol);
534         break;
535       case LayoutDocEntry::AuthorSection: 
536         writeAuthorSection(ol);
537         break;
538       case LayoutDocEntry::ClassIncludes:
539       case LayoutDocEntry::ClassInheritanceGraph:
540       case LayoutDocEntry::ClassNestedClasses:
541       case LayoutDocEntry::ClassCollaborationGraph:
542       case LayoutDocEntry::ClassAllMembersLink:
543       case LayoutDocEntry::ClassUsedFiles:
544       case LayoutDocEntry::ClassInlineClasses:
545       case LayoutDocEntry::FileClasses:
546       case LayoutDocEntry::FileNamespaces:
547       case LayoutDocEntry::FileIncludes:
548       case LayoutDocEntry::FileIncludeGraph:
549       case LayoutDocEntry::FileIncludedByGraph: 
550       case LayoutDocEntry::FileSourceLink:
551       case LayoutDocEntry::FileInlineClasses:
552       case LayoutDocEntry::GroupClasses: 
553       case LayoutDocEntry::GroupInlineClasses: 
554       case LayoutDocEntry::GroupNamespaces:
555       case LayoutDocEntry::GroupDirs: 
556       case LayoutDocEntry::GroupNestedGroups: 
557       case LayoutDocEntry::GroupFiles:
558       case LayoutDocEntry::GroupGraph: 
559       case LayoutDocEntry::GroupPageDocs:
560       case LayoutDocEntry::DirSubDirs:
561       case LayoutDocEntry::DirFiles:
562       case LayoutDocEntry::DirGraph:
563         err("Internal inconsistency: member %d should not be part of "
564             "LayoutDocManager::Namespace entry list\n",lde->kind());
565         break;
566     }
567   }
568
569   //---------------------------------------- end flexible part -------------------------------
570
571   ol.endContents();
572
573   endFileWithNavPath(this,ol);
574
575   if (generateTagFile)
576   {
577     writeDocAnchorsToTagFile();
578     Doxygen::tagFile << "  </compound>" << endl;
579   }
580
581   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
582   {
583     MemberList *allMemberList = getMemberList(MemberList::allMembersList);
584     if (allMemberList) allMemberList->sort();
585     writeMemberPages(ol);
586   }
587 }
588
589 void NamespaceDef::writeMemberPages(OutputList &ol)
590 {
591   ol.pushGeneratorState();
592   ol.disableAllBut(OutputGenerator::Html);
593
594   QListIterator<MemberList> mli(m_memberLists);
595   MemberList *ml;
596   for (mli.toFirst();(ml=mli.current());++mli)
597   {
598     if (ml->listType()&MemberList::documentationLists)
599     {
600       ml->writeDocumentationPage(ol,displayName(),this);
601     }
602   }
603   ol.popGeneratorState();
604 }
605
606 void NamespaceDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
607 {
608   static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
609
610   ol.writeString("      <div class=\"navtab\">\n");
611   ol.writeString("        <table>\n");
612
613   MemberList *allMemberList = getMemberList(MemberList::allMembersList);
614   if (allMemberList)
615   {
616     MemberListIterator mli(*allMemberList);
617     MemberDef *md;
618     for (mli.toFirst();(md=mli.current());++mli)
619     {
620       if (md->getNamespaceDef()==this && md->isLinkable())
621       {
622         ol.writeString("          <tr><td class=\"navtab\">");
623         if (md->isLinkableInProject())
624         {
625           if (md==currentMd) // selected item => highlight
626           {
627             ol.writeString("<a class=\"qindexHL\" ");
628           }
629           else
630           {
631             ol.writeString("<a class=\"qindex\" ");
632           }
633           ol.writeString("href=\"");
634           if (createSubDirs) ol.writeString("../../");
635           ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
636           ol.writeString("\">");
637           ol.writeString(convertToHtml(md->localName()));
638           ol.writeString("</a>");
639         }
640         ol.writeString("</td></tr>\n");
641       }
642     }
643   }
644
645   ol.writeString("        </table>\n");
646   ol.writeString("      </div>\n");
647 }
648
649 int NamespaceDef::countMembers()
650 {
651   MemberList *allMemberList = getMemberList(MemberList::allMembersList);
652   if (allMemberList) allMemberList->countDocMembers();
653   return (allMemberList ? allMemberList->numDocMembers() : 0)+classSDict->count();
654 }
655
656 void NamespaceDef::addUsingDirective(NamespaceDef *nd)
657 {
658   if (usingDirList==0)
659   {
660     usingDirList = new NamespaceSDict;
661   }
662   if (usingDirList->find(nd->qualifiedName())==0)
663   {
664     usingDirList->append(nd->qualifiedName(),nd);
665   }
666   //printf("%p: NamespaceDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count());
667 }
668
669 NamespaceSDict *NamespaceDef::getUsedNamespaces() const 
670
671   //printf("%p: NamespaceDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0);
672   return usingDirList; 
673 }
674
675 void NamespaceDef::addUsingDeclaration(Definition *d)
676 {
677   if (usingDeclList==0)
678   {
679     usingDeclList = new SDict<Definition>(17);
680   }
681   if (usingDeclList->find(d->qualifiedName())==0)
682   {
683     usingDeclList->append(d->qualifiedName(),d);
684   }
685 }
686
687 QCString NamespaceDef::getOutputFileBase() const 
688
689   if (isReference())
690   {
691     return fileName;
692   }
693   else
694   {
695     return convertNameToFile(fileName); 
696   }
697 }
698
699 Definition *NamespaceDef::findInnerCompound(const char *n)
700 {
701   if (n==0) return 0;
702   Definition *d = m_innerCompounds->find(n);
703   if (d==0)
704   {
705     if (usingDirList)
706     {
707       d = usingDirList->find(n);
708     }
709     if (d==0 && usingDeclList)
710     {
711       d = usingDeclList->find(n);
712     }
713   }
714   return d;
715 }
716
717 void NamespaceDef::addListReferences()
718 {
719   //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
720   {
721     LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
722     addRefItem(xrefItems.pointer(),
723         qualifiedName(),
724         getLanguage()==SrcLangExt_Fortran ? 
725           theTranslator->trModule(TRUE,TRUE) : 
726           theTranslator->trNamespace(TRUE,TRUE),
727         getOutputFileBase(),displayName(),
728         0
729         );
730   }
731   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
732   MemberGroup *mg;
733   for (;(mg=mgli.current());++mgli)
734   {
735     mg->addListReferences(this);
736   }
737   QListIterator<MemberList> mli(m_memberLists);
738   MemberList *ml;
739   for (mli.toFirst();(ml=mli.current());++mli)
740   {
741     if (ml->listType()&MemberList::documentationLists)
742     {
743       ml->addListReferences(this);
744     }
745   }
746 }
747
748 QCString NamespaceDef::displayName(bool includeScope) const
749 {
750   QCString result=includeScope ? name() : localName();
751   SrcLangExt lang = getLanguage();
752   QCString sep = getLanguageSpecificSeparator(lang);
753   if (sep!="::")
754   {
755     result = substitute(result,"::",sep);
756   }
757   //printf("NamespaceDef::displayName() %s->%s lang=%d\n",name().data(),result.data(),lang);
758   return result; 
759 }
760
761 QCString NamespaceDef::localName() const
762 {
763   QCString result=name();
764   int i=result.findRev("::");
765   if (i!=-1)
766   {
767     result=result.mid(i+2);
768   }
769   return result;
770 }
771
772 void NamespaceDef::combineUsingRelations()
773 {
774   if (visited) return; // already done
775   visited=TRUE;
776   if (usingDirList)
777   {
778     NamespaceSDict::Iterator nli(*usingDirList);
779     NamespaceDef *nd;
780     for (nli.toFirst();(nd=nli.current());++nli)
781     {
782       nd->combineUsingRelations();
783     }
784     for (nli.toFirst();(nd=nli.current());++nli)
785     {
786       // add used namespaces of namespace nd to this namespace
787       if (nd->getUsedNamespaces())
788       {
789         NamespaceSDict::Iterator unli(*nd->getUsedNamespaces());
790         NamespaceDef *und;
791         for (unli.toFirst();(und=unli.current());++unli)
792         {
793           //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data());
794           addUsingDirective(und);
795         }
796       }
797       // add used classes of namespace nd to this namespace
798       if (nd->getUsedClasses())
799       {
800         SDict<Definition>::Iterator cli(*nd->getUsedClasses());
801         Definition *ucd;
802         for (cli.toFirst();(ucd=cli.current());++cli)
803         {
804           //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data());
805           addUsingDeclaration(ucd);
806         }
807       }
808     }
809   }
810 }
811
812 bool NamespaceSDict::declVisible() const
813 {
814   SDict<NamespaceDef>::Iterator ni(*this);
815   NamespaceDef *nd;
816   for (ni.toFirst();(nd=ni.current());++ni)
817   {
818     if (nd->isLinkable())
819     {
820       return TRUE;
821     }
822   }
823   return FALSE;
824 }
825
826 void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title,bool localName)
827 {
828  
829
830   if (count()==0) return; // no namespaces in the list
831
832   if (Config_getBool("OPTIMIZE_OUTPUT_VHDL")) return;
833  
834
835   SDict<NamespaceDef>::Iterator ni(*this);
836   NamespaceDef *nd;
837   bool found=FALSE;
838   for (ni.toFirst();(nd=ni.current()) && !found;++ni)
839   {
840     if (nd->isLinkable()) found=TRUE;
841   }
842   if (!found) return; // no linkable namespaces in the list
843
844   // write list of namespaces
845   ol.startMemberHeader("namespaces");
846   //bool javaOpt    = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
847   //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
848   ol.parseText(title);
849   ol.endMemberHeader();
850   ol.startMemberList();
851   for (ni.toFirst();(nd=ni.current());++ni)
852   {
853     if (nd->isLinkable())
854     {
855       SrcLangExt lang = nd->getLanguage();
856       ol.startMemberDeclaration();
857       ol.startMemberItem(nd->getOutputFileBase(),0);
858       if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
859       {
860         ol.docify("package ");
861       }
862       else if (lang==SrcLangExt_Fortran)
863       {
864         ol.docify("module ");
865       }
866       else
867       {
868         ol.docify("namespace ");
869       }
870       ol.insertMemberAlign();
871       QCString name;
872       if (localName)
873       {
874         name = nd->localName();
875       }
876       else
877       {
878         name = nd->displayName();
879       }
880       ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,name);
881       if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !nd->isReference()) 
882       {
883         Doxygen::tagFile << "    <namespace>" << convertToXML(nd->name()) << "</namespace>" << endl;
884       }
885       ol.endMemberItem();
886       if (!nd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
887       {
888         ol.startMemberDescription(nd->getOutputFileBase());
889         ol.parseDoc(nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription(),FALSE,FALSE,0,TRUE);
890         ol.endMemberDescription();
891       }
892       ol.endMemberDeclaration(0,0);
893     }
894   }
895   ol.endMemberList();
896 }
897
898 MemberList *NamespaceDef::createMemberList(MemberList::ListType lt)
899 {
900   m_memberLists.setAutoDelete(TRUE);
901   QListIterator<MemberList> mli(m_memberLists);
902   MemberList *ml;
903   for (mli.toFirst();(ml=mli.current());++mli)
904   {
905     if (ml->listType()==lt)
906     {
907       return ml;
908     }
909   }
910   // not found, create a new member list
911   ml = new MemberList(lt);
912   m_memberLists.append(ml);
913   return ml;
914 }
915
916 void NamespaceDef::addMemberToList(MemberList::ListType lt,MemberDef *md)
917 {
918   static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
919   static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
920   MemberList *ml = createMemberList(lt);
921   ml->setNeedsSorting(
922       ((ml->listType()&MemberList::declarationLists) && sortBriefDocs) ||
923       ((ml->listType()&MemberList::documentationLists) && sortMemberDocs));
924   ml->append(md);
925
926 #if 0
927   if (ml->needsSorting())
928     ml->inSort(md);
929   else
930     ml->append(md);
931 #endif
932
933   if (ml->listType()&MemberList::declarationLists) md->setSectionList(this,ml);
934 }
935
936 void NamespaceDef::sortMemberLists()
937 {
938   MemberList *ml = m_memberLists.first();
939   while (ml)
940   {
941     if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
942     ml = m_memberLists.next();
943   }
944 }
945
946
947
948 MemberList *NamespaceDef::getMemberList(MemberList::ListType lt) const
949 {
950   NamespaceDef *that = (NamespaceDef*)this;
951   MemberList *ml = that->m_memberLists.first();
952   while (ml)
953   {
954     if (ml->listType()==lt)
955     {
956       return ml;
957     }
958     ml = that->m_memberLists.next();
959   }
960   return 0;
961 }
962
963 void NamespaceDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title)
964 {
965   MemberList * ml = getMemberList(lt);
966   if (ml) ml->writeDeclarations(ol,0,this,0,0,title,0);
967 }
968
969 void NamespaceDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title)
970 {
971   MemberList * ml = getMemberList(lt);
972   if (ml) ml->writeDocumentation(ol,displayName(),this,title);
973 }
974
975
976 bool NamespaceDef::isLinkableInProject() const
977 {
978   int i = name().findRev("::");
979   if (i==-1) i=0; else i+=2;
980   static bool extractAnonNs = Config_getBool("EXTRACT_ANON_NSPACES");
981   if (extractAnonNs &&                             // extract anonymous ns
982       name().mid(i,20)=="anonymous_namespace{"     // correct prefix
983      )                                             // not disabled by config
984   {
985     return TRUE;
986   }
987   return !name().isEmpty() && name().at(i)!='@' && // not anonymous
988     (hasDocumentation() || getLanguage()==SrcLangExt_CSharp) &&  // documented
989     !isReference() &&      // not an external reference
990     !isHidden() &&         // not hidden
991     !isArtificial();       // or artificial
992 }
993
994 bool NamespaceDef::isLinkable() const
995 {
996   return isLinkableInProject() || isReference();
997 }
998
999 MemberDef * NamespaceDef::getMemberByName(const QCString &n) const
1000 {
1001   MemberDef *md = 0;
1002   if (m_allMembersDict && !n.isEmpty())
1003   {
1004     md = m_allMembersDict->find(n);
1005     //printf("%s::m_allMembersDict->find(%s)=%p\n",name().data(),n.data(),md);
1006   }
1007   return md;
1008 }
1009