Fix for UBSan build
[platform/upstream/doxygen.git] / src / pagedef.cpp
1 #include "pagedef.h"
2 #include "groupdef.h"
3 #include "docparser.h"
4 #include "config.h"
5 #include "util.h"
6 #include "outputlist.h"
7 #include "doxygen.h"
8 #include "language.h"
9 #include <qregexp.h>
10
11
12 PageDef::PageDef(const char *f,int l,const char *n,
13                  const char *d,const char *t)
14  : Definition(f,l,n), m_title(t)
15 {
16   setDocumentation(d,f,l);
17   m_subPageDict = new PageSDict(7);
18   m_pageScope = 0;
19   m_nestingLevel = 0;
20   m_showToc = FALSE;
21 }
22
23 PageDef::~PageDef()
24 {
25   delete m_subPageDict;
26 }
27
28 void PageDef::findSectionsInDocumentation()
29 {
30   docFindSections(documentation(),this,0,docFile());
31 }
32
33 GroupDef *PageDef::getGroupDef() const 
34
35   LockingPtr<GroupList> groups = partOfGroups();
36   return groups!=0 ? groups->getFirst() : 0; 
37 }
38
39 QCString PageDef::getOutputFileBase() const 
40
41   if (getGroupDef()) 
42     return getGroupDef()->getOutputFileBase();
43   else 
44     return m_fileName; 
45 }
46
47 void PageDef::addInnerCompound(Definition *def)
48 {
49   if (def->definitionType()==Definition::TypePage)
50   {
51     PageDef *pd = (PageDef*)def;
52     m_subPageDict->append(pd->name(),pd);
53     def->setOuterScope(this);
54     if (this==Doxygen::mainPage)
55     {
56       pd->setNestingLevel(m_nestingLevel);
57     }
58     else
59     {
60       pd->setNestingLevel(m_nestingLevel+1);
61     }
62   }
63 }
64
65 bool PageDef::hasParentPage() const
66 {
67   return getOuterScope() && 
68          getOuterScope()->definitionType()==Definition::TypePage;
69 }
70
71 void PageDef::writeDocumentation(OutputList &ol)
72 {
73   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
74
75   //outputList->disable(OutputGenerator::Man);
76   QCString pageName;
77   pageName=escapeCharsInString(name(),FALSE,TRUE);
78
79   //printf("PageDef::writeDocumentation: %s\n",getOutputFileBase().data());
80
81   ol.pushGeneratorState();
82   //1.{ 
83
84   if (m_nestingLevel>0 
85       //&& // a sub page
86       //(Doxygen::mainPage==0 || getOuterScope()!=Doxygen::mainPage) // and not a subpage of the mainpage
87      )
88   {
89     // do not generate sub page output for RTF and LaTeX, as these are
90     // part of their parent page
91     ol.disableAll();
92     ol.enable(OutputGenerator::Man);
93     ol.enable(OutputGenerator::Html);
94   }
95
96   startFile(ol,getOutputFileBase(),pageName,title(),HLI_Pages,!generateTreeView);
97
98   if (!generateTreeView)
99   {
100     if (getOuterScope()!=Doxygen::globalScope && !Config_getBool("DISABLE_INDEX"))
101     {
102       getOuterScope()->writeNavigationPath(ol);
103     }
104     ol.endQuickIndices();
105   }
106   SectionInfo *si=Doxygen::sectionDict.find(name());
107
108   // save old generator state and write title only to Man generator
109   ol.pushGeneratorState();
110   //2.{
111   ol.disableAllBut(OutputGenerator::Man);
112   ol.startTitleHead(pageName);
113   ol.endTitleHead(pageName, pageName);
114   if (si)
115   {
116     ol.parseDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE);
117     ol.endSection(si->label,si->type);
118   }
119   ol.popGeneratorState();
120   //2.}
121
122   // for Latex the section is already generated as a chapter in the index!
123   ol.pushGeneratorState();
124   //2.{
125   ol.disable(OutputGenerator::Latex);
126   ol.disable(OutputGenerator::RTF);
127   ol.disable(OutputGenerator::Man);
128   if (!title().isEmpty() && !name().isEmpty() && si!=0)
129   {
130     //ol.startSection(si->label,si->title,si->type);
131     startTitle(ol,getOutputFileBase(),this);
132     ol.parseDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE);
133     //stringToSearchIndex(getOutputFileBase(),
134     //                    theTranslator->trPage(TRUE,TRUE)+" "+si->title,
135     //                    si->title);
136     //ol.endSection(si->label,si->type);
137     endTitle(ol,getOutputFileBase(),name());
138   }
139   ol.startContents();
140   ol.popGeneratorState();
141   //2.}
142
143   if (m_showToc && hasSections())
144   {
145     writeToc(ol);
146   }
147
148   writePageDocumentation(ol);
149
150   if (generateTreeView && getOuterScope()!=Doxygen::globalScope && !Config_getBool("DISABLE_INDEX"))
151   {
152     ol.endContents();
153     endFileWithNavPath(getOuterScope(),ol);
154   }
155   else
156   {
157     endFile(ol);
158   }
159
160   ol.popGeneratorState();
161   //1.}
162
163   if (!Config_getString("GENERATE_TAGFILE").isEmpty())
164   {
165     bool found=FALSE;
166     QDictIterator<RefList> rli(*Doxygen::xrefLists);
167     RefList *rl;
168     for (rli.toFirst();(rl=rli.current());++rli)
169     {
170       if (rl->listName()==name())
171       {
172         found=TRUE;
173         break;
174       }
175     }
176     if (!found) // not one of the generated related pages
177     {
178       Doxygen::tagFile << "  <compound kind=\"page\">" << endl;
179       Doxygen::tagFile << "    <name>" << name() << "</name>" << endl;
180       Doxygen::tagFile << "    <title>" << convertToXML(title()) << "</title>" << endl;
181       Doxygen::tagFile << "    <filename>" << getOutputFileBase() << "</filename>" << endl;
182       writeDocAnchorsToTagFile();
183       Doxygen::tagFile << "  </compound>" << endl;
184     }
185   }
186
187   Doxygen::indexList.addIndexItem(this,0,filterTitle(title()));
188 }
189
190 void PageDef::writePageDocumentation(OutputList &ol)
191 {
192
193   bool markdownEnabled = Doxygen::markdownSupport;
194   if (getLanguage()==SrcLangExt_Markdown)
195   {
196     Doxygen::markdownSupport = TRUE;
197   }
198
199   ol.startTextBlock();
200   ol.parseDoc(
201       docFile(),           // fileName
202       docLine(),           // startLine
203       this,                // context
204       0,                   // memberdef
205       documentation()+inbodyDocumentation(), // docStr
206       TRUE,                // index words
207       FALSE                // not an example
208       );
209   ol.endTextBlock();
210
211   Doxygen::markdownSupport = markdownEnabled;
212
213   if (hasSubPages())
214   {
215     // for printed documentation we write subpages as section's of the
216     // parent page.
217     ol.pushGeneratorState();
218     ol.disableAll();
219     ol.enable(OutputGenerator::Latex);
220     ol.enable(OutputGenerator::RTF);
221
222     PageSDict::Iterator pdi(*m_subPageDict);
223     PageDef *subPage=pdi.toFirst();
224     for (pdi.toFirst();(subPage=pdi.current());++pdi)
225     {
226       SectionInfo::SectionType sectionType = SectionInfo::Paragraph;
227       switch (m_nestingLevel)
228       {
229         case  0: sectionType = SectionInfo::Page;          break;
230         case  1: sectionType = SectionInfo::Section;       break;
231         case  2: sectionType = SectionInfo::Subsection;    break;
232         case  3: sectionType = SectionInfo::Subsubsection; break;
233         default: sectionType = SectionInfo::Paragraph;     break;
234       }
235       QCString title = subPage->title();
236       if (title.isEmpty()) title = subPage->name();
237       ol.startSection(subPage->name(),title,sectionType);
238       ol.parseText(title);
239       ol.endSection(subPage->name(),sectionType);
240       Doxygen::subpageNestingLevel++;
241       subPage->writePageDocumentation(ol);
242       Doxygen::subpageNestingLevel--;
243     }
244
245     ol.popGeneratorState();
246   }
247 }
248
249 bool PageDef::visibleInIndex() const
250 {
251   static bool allExternals = Config_getBool("ALLEXTERNALS");
252   return // not part of a group
253          !getGroupDef() && 
254          // not an externally defined page
255          (!isReference() || allExternals) 
256          // &&
257          // not a subpage
258          //(getOuterScope()==0 || 
259          // getOuterScope()->definitionType()!=Definition::TypePage
260          //)
261          ;
262 }
263
264 bool PageDef::documentedPage() const
265 {
266    return // not part of a group
267           !getGroupDef() && 
268           // not an externally defined page
269           !isReference();
270 }
271
272 bool PageDef::hasSubPages() const
273 {
274   return m_subPageDict->count()>0;
275 }
276
277 void PageDef::setNestingLevel(int l)
278 {
279   m_nestingLevel = l;
280 }
281
282 void PageDef::setShowToc(bool b)
283 {
284   m_showToc = b;
285 }
286