Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/src/filedef.cpp

Source at commit 1322 created 9 years 5 months ago.
By meklort, Add doxygen to utils folder
1/******************************************************************************
2 *
3 * $Id: filedef.cpp,v 1.55 2001/03/19 19:27:40 root Exp $
4 *
5 * Copyright (C) 1997-2011 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 "memberlist.h"
20#include "classlist.h"
21#include "filedef.h"
22#include "doxygen.h"
23#include "memberdef.h"
24#include "classdef.h"
25#include "namespacedef.h"
26#include "util.h"
27#include "language.h"
28#include "outputlist.h"
29#include "dot.h"
30#include "message.h"
31#include "docparser.h"
32#include "searchindex.h"
33#include "htags.h"
34#include "parserintf.h"
35#include "portable.h"
36#include "vhdldocgen.h"
37#include "debug.h"
38#include "layout.h"
39
40//---------------------------------------------------------------------------
41
42class DevNullCodeDocInterface : public CodeOutputInterface
43{
44 public:
45 virtual void codify(const char *) {}
46 virtual void writeCodeLink(const char *,const char *,
47 const char *,const char *,
48 const char *) {}
49 virtual void writeLineNumber(const char *,const char *,
50 const char *,int) {}
51 virtual void startCodeLine() {}
52 virtual void endCodeLine() {}
53 virtual void startCodeAnchor(const char *) {}
54 virtual void endCodeAnchor() {}
55 virtual void startFontClass(const char *) {}
56 virtual void endFontClass() {}
57 virtual void writeCodeAnchor(const char *) {}
58 virtual void linkableSymbol(int, const char *,Definition *,Definition *) {}
59};
60
61//---------------------------------------------------------------------------
62
63/*! create a new file definition, where \a p is the file path,
64 \a nm the file name, and \a lref is an HTML anchor name if the
65 file was read from a tag file or 0 otherwise
66*/
67FileDef::FileDef(const char *p,const char *nm,
68 const char *lref,const char *dn)
69 : Definition((QCString)p+nm,1,nm)
70{
71 path=p;
72 filepath=path+nm;
73 filename=nm;
74 diskname=dn;
75 if (diskname.isEmpty()) diskname=nm;
76 setReference(lref);
77 classSDict = 0;
78 includeList = 0;
79 includeDict = 0;
80 includedByList = 0;
81 includedByDict = 0;
82 namespaceSDict = 0;
83 srcDefDict = 0;
84 srcMemberDict = 0;
85 usingDirList = 0;
86 usingDeclList = 0;
87 package = 0;
88 isSource = FALSE;
89 docname = nm;
90 dir = 0;
91 if (Config_getBool("FULL_PATH_NAMES"))
92 {
93 docname.prepend(stripFromPath(path.copy()));
94 }
95 SrcLangExt lang = getLanguageFromFileName(name());
96 m_isJava = lang==SrcLangExt_Java;
97 m_isCSharp = lang==SrcLangExt_CSharp;
98 memberGroupSDict = 0;
99 acquireFileVersion();
100 m_subGrouping=Config_getBool("SUBGROUPING");
101}
102
103/*! destroy the file definition */
104FileDef::~FileDef()
105{
106 delete classSDict;
107 delete includeDict;
108 delete includeList;
109 delete includedByDict;
110 delete includedByList;
111 delete namespaceSDict;
112 delete srcDefDict;
113 delete srcMemberDict;
114 delete usingDirList;
115 delete usingDeclList;
116 delete memberGroupSDict;
117}
118
119/*! Compute the HTML anchor names for all members in the class */
120void FileDef::computeAnchors()
121{
122 MemberList *ml = getMemberList(MemberList::allMembersList);
123 if (ml) setAnchors(0,'a',ml);
124}
125
126void FileDef::distributeMemberGroupDocumentation()
127{
128 //printf("FileDef::distributeMemberGroupDocumentation()\n");
129 if (memberGroupSDict)
130 {
131 MemberGroupSDict::Iterator mgli(*memberGroupSDict);
132 MemberGroup *mg;
133 for (;(mg=mgli.current());++mgli)
134 {
135 mg->distributeMemberGroupDocumentation();
136 }
137 }
138}
139
140void FileDef::findSectionsInDocumentation()
141{
142 docFindSections(documentation(),this,0,docFile());
143 if (memberGroupSDict)
144 {
145 MemberGroupSDict::Iterator mgli(*memberGroupSDict);
146 MemberGroup *mg;
147 for (;(mg=mgli.current());++mgli)
148 {
149 mg->findSectionsInDocumentation();
150 }
151 }
152
153 QListIterator<MemberList> mli(m_memberLists);
154 MemberList *ml;
155 for (mli.toFirst();(ml=mli.current());++mli)
156 {
157 if (ml->listType()&MemberList::declarationLists)
158 {
159 ml->findSectionsInDocumentation();
160 }
161 }
162}
163
164void FileDef::writeDetailedDescription(OutputList &ol,const QCString &title)
165{
166 if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) ||
167 !documentation().isEmpty() ||
168 (Config_getBool("SOURCE_BROWSER") && getStartBodyLine()!=-1 && getBodyDef())
169 )
170 {
171 ol.writeRuler();
172 ol.pushGeneratorState();
173 ol.disableAllBut(OutputGenerator::Html);
174 ol.writeAnchor(0,"details");
175 ol.popGeneratorState();
176 ol.startGroupHeader();
177 ol.parseText(title);
178 ol.endGroupHeader();
179
180 ol.startTextBlock();
181 if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
182 {
183 ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
184 }
185 if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
186 !documentation().isEmpty())
187 {
188 ol.pushGeneratorState();
189 ol.disable(OutputGenerator::Man);
190 ol.disable(OutputGenerator::RTF);
191 // ol.newParagraph(); // FIXME:PARA
192 ol.enableAll();
193 ol.disableAllBut(OutputGenerator::Man);
194 ol.writeString("\n\n");
195 ol.popGeneratorState();
196 }
197 if (!documentation().isEmpty())
198 {
199 ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
200 }
201 //printf("Writing source ref for file %s\n",name().data());
202 if (Config_getBool("SOURCE_BROWSER"))
203 {
204 ol.startParagraph();
205 QCString refText = theTranslator->trDefinedInSourceFile();
206 int fileMarkerPos = refText.find("@0");
207 if (fileMarkerPos!=-1) // should always pass this.
208 {
209 ol.parseText(refText.left(fileMarkerPos)); //text left from marker 1
210 ol.writeObjectLink(0,getSourceFileBase(),
211 0,name());
212 ol.parseText(refText.right(
213 refText.length()-fileMarkerPos-2)); // text right from marker 2
214 }
215 ol.endParagraph();
216 }
217 ol.endTextBlock();
218 }
219}
220
221void FileDef::writeBriefDescription(OutputList &ol)
222{
223 if (!briefDescription().isEmpty())
224 {
225 ol.startParagraph();
226 ol.parseDoc(briefFile(),briefLine(),this,0,
227 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
228 ol.pushGeneratorState();
229 ol.disable(OutputGenerator::RTF);
230 ol.writeString(" \n");
231 ol.enable(OutputGenerator::RTF);
232
233 if (Config_getBool("REPEAT_BRIEF") ||
234 !documentation().isEmpty()
235 )
236 {
237 ol.disableAllBut(OutputGenerator::Html);
238 ol.startTextLink(0,"details");
239 ol.parseText(theTranslator->trMore());
240 ol.endTextLink();
241 }
242 ol.popGeneratorState();
243 ol.endParagraph();
244
245 //ol.pushGeneratorState();
246 //ol.disable(OutputGenerator::RTF);
247 //ol.newParagraph();
248 //ol.popGeneratorState();
249 }
250 ol.writeSynopsis();
251}
252
253void FileDef::writeIncludeFiles(OutputList &ol)
254{
255 if (/*Config_getBool("SHOW_INCLUDE_FILES") &&*/ includeList &&
256 includeList->count()>0)
257 {
258 ol.startTextBlock(TRUE);
259 QListIterator<IncludeInfo> ili(*includeList);
260 IncludeInfo *ii;
261 for (;(ii=ili.current());++ili)
262 {
263 FileDef *fd=ii->fileDef;
264 bool isIDLorJava = FALSE;
265 if (fd)
266 {
267 SrcLangExt lang = getLanguageFromFileName(fd->name());
268 isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
269 }
270 ol.startTypewriter();
271 if (isIDLorJava) // IDL/Java include
272 {
273 ol.docify("import ");
274 }
275 else if (ii->imported) // Objective-C include
276 {
277 ol.docify("#import ");
278 }
279 else // C/C++ include
280 {
281 ol.docify("#include ");
282 }
283 if (ii->local || isIDLorJava)
284 ol.docify("\"");
285 else
286 ol.docify("<");
287 ol.disable(OutputGenerator::Html);
288 ol.docify(ii->includeName);
289 ol.enableAll();
290 ol.disableAllBut(OutputGenerator::Html);
291
292 // Here we use the include file name as it appears in the file.
293 // we could also we the name as it is used within doxygen,
294 // then we should have used fd->docName() instead of ii->includeName
295 if (fd && fd->isLinkable())
296 {
297 ol.writeObjectLink(fd->getReference(),
298 fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(),
299 0,ii->includeName);
300 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fd->isReference())
301 {
302 const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no";
303 const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no";
304 Doxygen::tagFile << " <includes id=\""
305 << convertToXML(fd->getOutputFileBase()) << "\" "
306 << "name=\"" << convertToXML(fd->name()) << "\" "
307 << "local=\"" << locStr << "\" "
308 << "imported=\"" << impStr << "\">"
309 << convertToXML(ii->includeName)
310 << "</includes>"
311 << endl;
312 }
313 }
314 else
315 {
316 ol.docify(ii->includeName);
317 }
318
319 ol.enableAll();
320 if (ii->local || isIDLorJava)
321 ol.docify("\"");
322 else
323 ol.docify(">");
324 if (isIDLorJava)
325 ol.docify(";");
326 ol.endTypewriter();
327 ol.lineBreak();
328 }
329 ol.endTextBlock();
330 }
331}
332
333void FileDef::writeIncludeGraph(OutputList &ol)
334{
335 if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDE_GRAPH")*/)
336 {
337 //printf("Graph for file %s\n",name().data());
338 DotInclDepGraph incDepGraph(this,FALSE);
339 if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig())
340 {
341 ol.startTextBlock();
342 ol.disable(OutputGenerator::Man);
343 ol.startInclDepGraph();
344 ol.parseText(theTranslator->trInclDepGraph(name()));
345 ol.endInclDepGraph(incDepGraph);
346 ol.enableAll();
347 ol.endTextBlock(TRUE);
348 }
349 //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
350 }
351}
352
353void FileDef::writeIncludedByGraph(OutputList &ol)
354{
355 if (Config_getBool("HAVE_DOT") /*&& Config_getBool("INCLUDED_BY_GRAPH")*/)
356 {
357 //printf("Graph for file %s\n",name().data());
358 DotInclDepGraph incDepGraph(this,TRUE);
359 if (!incDepGraph.isTrivial() && !incDepGraph.isTooBig())
360 {
361 ol.startTextBlock();
362 ol.disable(OutputGenerator::Man);
363 ol.startInclDepGraph();
364 ol.parseText(theTranslator->trInclByDepGraph());
365 ol.endInclDepGraph(incDepGraph);
366 ol.enableAll();
367 ol.endTextBlock(TRUE);
368 }
369 //incDepGraph.writeGraph(Config_getString("HTML_OUTPUT"),fd->getOutputFileBase());
370 }
371}
372
373
374void FileDef::writeSourceLink(OutputList &ol)
375{
376 //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile());
377 if (generateSourceFile())
378 {
379 ol.disableAllBut(OutputGenerator::Html);
380 ol.startParagraph();
381 ol.startTextLink(includeName(),0);
382 ol.parseText(theTranslator->trGotoSourceCode());
383 ol.endTextLink();
384 ol.endParagraph();
385 ol.enableAll();
386 }
387}
388
389void FileDef::writeNamespaceDeclarations(OutputList &ol,const QCString &title)
390{
391 // write list of namespaces
392 if (namespaceSDict) namespaceSDict->writeDeclaration(ol,title);
393}
394
395void FileDef::writeClassDeclarations(OutputList &ol,const QCString &title)
396{
397 // write list of classes
398 if (classSDict) classSDict->writeDeclaration(ol,0,title,FALSE);
399}
400
401void FileDef::startMemberDeclarations(OutputList &ol)
402{
403 ol.startMemberSections();
404}
405
406void FileDef::endMemberDeclarations(OutputList &ol)
407{
408 ol.endMemberSections();
409}
410
411void FileDef::startMemberDocumentation(OutputList &ol)
412{
413 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
414 {
415 ol.disable(OutputGenerator::Html);
416 Doxygen::suppressDocWarnings = TRUE;
417 }
418}
419
420void FileDef::endMemberDocumentation(OutputList &ol)
421{
422 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
423 {
424 ol.enable(OutputGenerator::Html);
425 Doxygen::suppressDocWarnings = FALSE;
426 }
427}
428
429void FileDef::writeMemberGroups(OutputList &ol)
430{
431 /* write user defined member groups */
432 if (memberGroupSDict)
433 {
434 memberGroupSDict->sort();
435 MemberGroupSDict::Iterator mgli(*memberGroupSDict);
436 MemberGroup *mg;
437 for (;(mg=mgli.current());++mgli)
438 {
439 if ((!mg->allMembersInSameSection() || !m_subGrouping)
440 && mg->header()!="[NOHEADER]")
441 {
442 mg->writeDeclarations(ol,0,0,this,0);
443 }
444 }
445 }
446}
447
448void FileDef::writeAuthorSection(OutputList &ol)
449{
450 // write Author section (Man only)
451 ol.pushGeneratorState();
452 ol.disableAllBut(OutputGenerator::Man);
453 ol.startGroupHeader();
454 ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
455 ol.endGroupHeader();
456 ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
457 ol.popGeneratorState();
458}
459
460void FileDef::writeSummaryLinks(OutputList &ol)
461{
462 ol.pushGeneratorState();
463 ol.disableAllBut(OutputGenerator::Html);
464 QListIterator<LayoutDocEntry> eli(
465 LayoutDocManager::instance().docEntries(LayoutDocManager::File));
466 LayoutDocEntry *lde;
467 bool first=TRUE;
468 for (eli.toFirst();(lde=eli.current());++eli)
469 {
470 if ((lde->kind()==LayoutDocEntry::FileClasses && classSDict && classSDict->declVisible()) ||
471 (lde->kind()==LayoutDocEntry::FileNamespaces && namespaceSDict && namespaceSDict->declVisible())
472 )
473 {
474 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
475 QCString label = lde->kind()==LayoutDocEntry::FileClasses ? "nested-classes" : "namespaces";
476 writeSummaryLink(ol,label,ls->title,first);
477 }
478 else if (lde->kind()==LayoutDocEntry::MemberDecl)
479 {
480 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
481 MemberList * ml = getMemberList(lmd->type);
482 if (ml && ml->declVisible())
483 {
484 writeSummaryLink(ol,ml->listTypeAsString(),lmd->title,first);
485 }
486 }
487 }
488 if (!first)
489 {
490 ol.writeString(" </div>\n");
491 }
492 ol.popGeneratorState();
493}
494
495/*! Write the documentation page for this file to the file of output
496 generators \a ol.
497*/
498void FileDef::writeDocumentation(OutputList &ol)
499{
500 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
501 //funcList->countDecMembers();
502
503 //QCString fn = name();
504 //if (Config_getBool("FULL_PATH_NAMES"))
505 //{
506 // fn.prepend(stripFromPath(getPath().copy()));
507 //}
508
509 //printf("WriteDocumentation diskname=%s\n",diskname.data());
510
511 QCString versionTitle;
512 if (!fileVersion.isEmpty())
513 {
514 versionTitle=("("+fileVersion+")");
515 }
516 QCString title = docname+versionTitle;
517 QCString pageTitle=theTranslator->trFileReference(docname);
518
519 if (Config_getBool("SHOW_DIRECTORIES") && getDirDef())
520 {
521 startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView);
522 if (!generateTreeView)
523 {
524 getDirDef()->writeNavigationPath(ol);
525 ol.endQuickIndices();
526 }
527 QCString pageTitleShort=theTranslator->trFileReference(name());
528 startTitle(ol,getOutputFileBase(),this);
529 ol.pushGeneratorState();
530 ol.disableAllBut(OutputGenerator::Html);
531 ol.parseText(pageTitleShort); // Html only
532 ol.enableAll();
533 ol.disable(OutputGenerator::Html);
534 ol.parseText(pageTitle); // other output formats
535 ol.popGeneratorState();
536 addGroupListToTitle(ol,this);
537 endTitle(ol,getOutputFileBase(),title);
538 }
539 else
540 {
541 startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_FileVisible,!generateTreeView);
542 if (!generateTreeView)
543 {
544 ol.endQuickIndices();
545 }
546 startTitle(ol,getOutputFileBase(),this);
547 ol.parseText(pageTitle);
548 addGroupListToTitle(ol,this);
549 endTitle(ol,getOutputFileBase(),title);
550 }
551
552 ol.startContents();
553
554 if (!fileVersion.isEmpty())
555 {
556 ol.disableAllBut(OutputGenerator::Html);
557 ol.startProjectNumber();
558 ol.docify(versionTitle);
559 ol.endProjectNumber();
560 ol.enableAll();
561 }
562
563 if (Doxygen::searchIndex)
564 {
565 Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase());
566 Doxygen::searchIndex->addWord(localName(),TRUE);
567 }
568
569 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
570 {
571 Doxygen::tagFile << " <compound kind=\"file\">" << endl;
572 Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
573 Doxygen::tagFile << " <path>" << convertToXML(getPath()) << "</path>" << endl;
574 Doxygen::tagFile << " <filename>"
575 << convertToXML(getOutputFileBase())
576 << "</filename>" << endl;
577 }
578
579 //---------------------------------------- start flexible part -------------------------------
580
581 QListIterator<LayoutDocEntry> eli(
582 LayoutDocManager::instance().docEntries(LayoutDocManager::File));
583 LayoutDocEntry *lde;
584 for (eli.toFirst();(lde=eli.current());++eli)
585 {
586 switch (lde->kind())
587 {
588 case LayoutDocEntry::BriefDesc:
589 writeBriefDescription(ol);
590 break;
591 case LayoutDocEntry::MemberDeclStart:
592 startMemberDeclarations(ol);
593 break;
594 case LayoutDocEntry::FileIncludes:
595 writeIncludeFiles(ol);
596 break;
597 case LayoutDocEntry::FileIncludeGraph:
598 writeIncludeGraph(ol);
599 break;
600 case LayoutDocEntry::FileIncludedByGraph:
601 writeIncludedByGraph(ol);
602 break;
603 case LayoutDocEntry::FileSourceLink:
604 writeSourceLink(ol);
605 break;
606 case LayoutDocEntry::FileClasses:
607 {
608 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
609 writeClassDeclarations(ol,ls->title);
610 }
611 break;
612 case LayoutDocEntry::FileNamespaces:
613 {
614 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
615 writeNamespaceDeclarations(ol,ls->title);
616 }
617 break;
618 case LayoutDocEntry::MemberGroups:
619 writeMemberGroups(ol);
620 break;
621 case LayoutDocEntry::MemberDecl:
622 {
623 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
624 writeMemberDeclarations(ol,lmd->type,lmd->title);
625 }
626 break;
627 case LayoutDocEntry::MemberDeclEnd:
628 endMemberDeclarations(ol);
629 break;
630 case LayoutDocEntry::DetailedDesc:
631 {
632 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
633 writeDetailedDescription(ol,ls->title);
634 }
635 break;
636 case LayoutDocEntry::MemberDefStart:
637 startMemberDocumentation(ol);
638 break;
639 case LayoutDocEntry::MemberDef:
640 {
641 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
642 writeMemberDocumentation(ol,lmd->type,lmd->title);
643 }
644 break;
645 case LayoutDocEntry::MemberDefEnd:
646 endMemberDocumentation(ol);
647 break;
648 case LayoutDocEntry::AuthorSection:
649 writeAuthorSection(ol);
650 break;
651 case LayoutDocEntry::ClassIncludes:
652 case LayoutDocEntry::ClassInheritanceGraph:
653 case LayoutDocEntry::ClassNestedClasses:
654 case LayoutDocEntry::ClassCollaborationGraph:
655 case LayoutDocEntry::ClassAllMembersLink:
656 case LayoutDocEntry::ClassUsedFiles:
657 case LayoutDocEntry::NamespaceNestedNamespaces:
658 case LayoutDocEntry::NamespaceClasses:
659 case LayoutDocEntry::GroupClasses:
660 case LayoutDocEntry::GroupInlineClasses:
661 case LayoutDocEntry::GroupNamespaces:
662 case LayoutDocEntry::GroupDirs:
663 case LayoutDocEntry::GroupNestedGroups:
664 case LayoutDocEntry::GroupFiles:
665 case LayoutDocEntry::GroupGraph:
666 case LayoutDocEntry::GroupPageDocs:
667 case LayoutDocEntry::DirSubDirs:
668 case LayoutDocEntry::DirFiles:
669 case LayoutDocEntry::DirGraph:
670 err("Internal inconsistency: member %d should not be part of "
671 "LayoutDocManager::File entry list\n",lde->kind());
672 break;
673 }
674 }
675
676 //---------------------------------------- end flexible part -------------------------------
677
678 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
679 {
680 writeDocAnchorsToTagFile();
681 Doxygen::tagFile << " </compound>" << endl;
682 }
683
684 ol.endContents();
685
686 if (generateTreeView)
687 {
688 writeNavigationPath(ol);
689 }
690
691 endFile(ol,TRUE);
692
693 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
694 {
695 MemberList *ml = getMemberList(MemberList::allMembersList);
696 if (ml) ml->sort();
697 writeMemberPages(ol);
698 }
699}
700
701void FileDef::writeMemberPages(OutputList &ol)
702{
703 ol.pushGeneratorState();
704 ol.disableAllBut(OutputGenerator::Html);
705
706 QListIterator<MemberList> mli(m_memberLists);
707 MemberList *ml;
708 for (mli.toFirst();(ml=mli.current());++mli)
709 {
710 if (ml->listType()&MemberList::documentationLists)
711 {
712 ml->writeDocumentationPage(ol,name(),this);
713 }
714 }
715
716 ol.popGeneratorState();
717}
718
719void FileDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
720{
721 static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
722
723 ol.writeString(" <div class=\"navtab\">\n");
724 ol.writeString(" <table>\n");
725
726 MemberList *allMemberList = getMemberList(MemberList::allMembersList);
727 if (allMemberList)
728 {
729 MemberListIterator mli(*allMemberList);
730 MemberDef *md;
731 for (mli.toFirst();(md=mli.current());++mli)
732 {
733 if (md->getFileDef()==this && md->getNamespaceDef()==0 && md->isLinkable())
734 {
735 ol.writeString(" <tr><td class=\"navtab\">");
736 if (md->isLinkableInProject())
737 {
738 if (md==currentMd) // selected item => highlight
739 {
740 ol.writeString("<a class=\"qindexHL\" ");
741 }
742 else
743 {
744 ol.writeString("<a class=\"qindex\" ");
745 }
746 ol.writeString("href=\"");
747 if (createSubDirs) ol.writeString("../../");
748 ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
749 ol.writeString("\">");
750 ol.writeString(md->localName());
751 ol.writeString("</a>");
752 }
753 ol.writeString("</td></tr>\n");
754 }
755 }
756 }
757
758 ol.writeString(" </table>\n");
759 ol.writeString(" </div>\n");
760}
761
762/*! Write a source listing of this file to the output */
763void FileDef::writeSource(OutputList &ol)
764{
765 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
766 static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
767 static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
768 QCString title = docname;
769 if (!fileVersion.isEmpty())
770 {
771 title+=(" ("+fileVersion+")");
772 }
773 QCString pageTitle = theTranslator->trSourceFile(title);
774 ol.disable(OutputGenerator::Man);
775 ol.disable(OutputGenerator::RTF);
776 if (!latexSourceCode) ol.disable(OutputGenerator::Latex);
777
778 if (Config_getBool("SHOW_DIRECTORIES") && getDirDef())
779 {
780 startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,
781 !generateTreeView,getOutputFileBase());
782 if (!generateTreeView)
783 {
784 getDirDef()->writeNavigationPath(ol);
785 ol.endQuickIndices();
786 }
787 startTitle(ol,getOutputFileBase());
788 ol.parseText(name());
789 endTitle(ol,getOutputFileBase(),title);
790 }
791 else
792 {
793 startFile(ol,getSourceFileBase(),0,pageTitle,HLI_FileVisible,
794 !generateTreeView,getOutputFileBase());
795 startTitle(ol,getSourceFileBase());
796 ol.parseText(title);
797 endTitle(ol,getSourceFileBase(),0);
798 }
799
800 ol.startContents();
801
802 if (isLinkable())
803 {
804 if (latexSourceCode) ol.disable(OutputGenerator::Latex);
805 ol.startTextLink(getOutputFileBase(),0);
806 ol.parseText(theTranslator->trGotoDocumentation());
807 ol.endTextLink();
808 if (latexSourceCode) ol.enable(OutputGenerator::Latex);
809 }
810
811 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
812 pIntf->resetCodeParserState();
813 ol.startCodeFragment();
814 pIntf->parseCode(ol,0,
815 fileToString(absFilePath(),filterSourceFiles,TRUE),
816 FALSE,0,this
817 );
818 ol.endCodeFragment();
819 ol.endContents();
820 if (generateTreeView)
821 {
822 writeNavigationPath(ol);
823 endFile(ol,TRUE);
824 }
825 else
826 {
827 endFile(ol);
828 }
829 ol.enableAll();
830}
831
832void FileDef::parseSource()
833{
834 static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
835 DevNullCodeDocInterface devNullIntf;
836 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
837 pIntf->resetCodeParserState();
838 pIntf->parseCode(
839 devNullIntf,0,
840 fileToString(absFilePath(),filterSourceFiles,TRUE),
841 FALSE,0,this
842 );
843}
844
845void FileDef::addMembersToMemberGroup()
846{
847 QListIterator<MemberList> mli(m_memberLists);
848 MemberList *ml;
849 for (mli.toFirst();(ml=mli.current());++mli)
850 {
851 if (ml->listType()&MemberList::declarationLists)
852 {
853 ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
854 }
855 }
856
857 // add members inside sections to their groups
858 if (memberGroupSDict)
859 {
860 MemberGroupSDict::Iterator mgli(*memberGroupSDict);
861 MemberGroup *mg;
862 for (;(mg=mgli.current());++mgli)
863 {
864 if (mg->allMembersInSameSection() && m_subGrouping)
865 {
866 //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
867 mg->addToDeclarationSection();
868 }
869 }
870 }
871}
872
873/*! Adds member definition \a md to the list of all members of this file */
874void FileDef::insertMember(MemberDef *md)
875{
876 if (md->isHidden()) return;
877 //printf("%s:FileDef::insertMember(%s (=%p) list has %d elements)\n",
878 // name().data(),md->name().data(),md,allMemberList.count());
879 MemberList *allMemberList = getMemberList(MemberList::allMembersList);
880 if (allMemberList && allMemberList->findRef(md)!=-1) // TODO optimize the findRef!
881 {
882 return;
883 }
884
885 if (allMemberList==0)
886 {
887 allMemberList = new MemberList(MemberList::allMembersList);;
888 m_memberLists.append(allMemberList);
889 }
890 allMemberList->append(md);
891 //::addFileMemberNameToIndex(md);
892 switch (md->memberType())
893 {
894 case MemberDef::Variable:
895 case MemberDef::Property:
896 addMemberToList(MemberList::decVarMembers,md);
897 addMemberToList(MemberList::docVarMembers,md);
898 break;
899 case MemberDef::Function:
900 addMemberToList(MemberList::decFuncMembers,md);
901 addMemberToList(MemberList::docFuncMembers,md);
902 break;
903 case MemberDef::Typedef:
904 addMemberToList(MemberList::decTypedefMembers,md);
905 addMemberToList(MemberList::docTypedefMembers,md);
906 break;
907 case MemberDef::Enumeration:
908 addMemberToList(MemberList::decEnumMembers,md);
909 addMemberToList(MemberList::docEnumMembers,md);
910 break;
911 case MemberDef::EnumValue: // enum values are shown inside their enums
912 break;
913 case MemberDef::Define:
914 addMemberToList(MemberList::decDefineMembers,md);
915 addMemberToList(MemberList::docDefineMembers,md);
916 break;
917 default:
918 err("FileDef::insertMembers(): "
919 "member `%s' with class scope `%s' inserted in file scope `%s'!\n",
920 md->name().data(),
921 md->getClassDef() ? md->getClassDef()->name().data() : "<global>",
922 name().data());
923 }
924 //addMemberToGroup(md,groupId);
925}
926
927/*! Adds compound definition \a cd to the list of all compounds of this file */
928void FileDef::insertClass(ClassDef *cd)
929{
930 if (cd->isHidden()) return;
931 if (classSDict==0)
932 {
933 classSDict = new ClassSDict(17);
934 }
935 if (Config_getBool("SORT_BRIEF_DOCS"))
936 classSDict->inSort(cd->name(),cd);
937 else
938 classSDict->append(cd->name(),cd);
939}
940
941/*! Adds namespace definition \a nd to the list of all compounds of this file */
942void FileDef::insertNamespace(NamespaceDef *nd)
943{
944 if (nd->isHidden()) return;
945 if (!nd->name().isEmpty() &&
946 (namespaceSDict==0 || namespaceSDict->find(nd->name())==0))
947 {
948 if (namespaceSDict==0)
949 {
950 namespaceSDict = new NamespaceSDict;
951 }
952 if (Config_getBool("SORT_BRIEF_DOCS"))
953 namespaceSDict->inSort(nd->name(),nd);
954 else
955 namespaceSDict->append(nd->name(),nd);
956 }
957}
958
959void FileDef::addSourceRef(int line,Definition *d,MemberDef *md)
960{
961 //printf("FileDef::addSourceDef(%d,%p,%p)\n",line,d,md);
962 if (d)
963 {
964 if (srcDefDict==0) srcDefDict = new QIntDict<Definition>(257);
965 if (srcMemberDict==0) srcMemberDict = new QIntDict<MemberDef>(257);
966 srcDefDict->insert(line,d);
967 if (md) srcMemberDict->insert(line,md);
968 //printf("Adding member %s with anchor %s at line %d to file %s\n",
969 // md->name().data(),md->anchor().data(),line,name().data());
970 }
971}
972
973Definition *FileDef::getSourceDefinition(int lineNr)
974{
975 Definition *result=0;
976 if (srcDefDict)
977 {
978 result = srcDefDict->find(lineNr);
979 }
980 return result;
981}
982
983MemberDef *FileDef::getSourceMember(int lineNr)
984{
985 MemberDef *result=0;
986 if (srcMemberDict)
987 {
988 result = srcMemberDict->find(lineNr);
989 }
990 return result;
991}
992
993
994void FileDef::addUsingDirective(NamespaceDef *nd)
995{
996 if (usingDirList==0)
997 {
998 usingDirList = new NamespaceSDict;
999 }
1000 if (usingDirList->find(nd->qualifiedName())==0)
1001 {
1002 usingDirList->append(nd->qualifiedName(),nd);
1003 }
1004 //printf("%p: FileDef::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count());
1005}
1006
1007NamespaceSDict *FileDef::getUsedNamespaces() const
1008{
1009 //printf("%p: FileDef::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0);
1010 return usingDirList;
1011}
1012
1013void FileDef::addUsingDeclaration(Definition *d)
1014{
1015 if (usingDeclList==0)
1016 {
1017 usingDeclList = new SDict<Definition>(17);
1018 }
1019 if (usingDeclList->find(d->qualifiedName())==0)
1020 {
1021 usingDeclList->append(d->qualifiedName(),d);
1022 }
1023}
1024
1025void FileDef::addIncludeDependency(FileDef *fd,const char *incName,bool local,
1026 bool imported)
1027{
1028 //printf("FileDef::addIncludeDependency(%p,%s,%d)\n",fd,incName,local);
1029 QCString iName = fd ? fd->absFilePath().data() : incName;
1030 if (!iName.isEmpty() && (!includeDict || includeDict->find(iName)==0))
1031 {
1032 if (includeDict==0)
1033 {
1034 includeDict = new QDict<IncludeInfo>(61);
1035 includeList = new QList<IncludeInfo>;
1036 includeList->setAutoDelete(TRUE);
1037 }
1038 IncludeInfo *ii = new IncludeInfo;
1039 ii->fileDef = fd;
1040 ii->includeName = incName;
1041 ii->local = local;
1042 ii->imported = imported;
1043 includeList->append(ii);
1044 includeDict->insert(iName,ii);
1045 }
1046}
1047
1048void FileDef::addIncludedUsingDirectives()
1049{
1050 if (visited) return;
1051 visited=TRUE;
1052 //printf("( FileDef::addIncludedUsingDirectives for file %s\n",name().data());
1053
1054 NamespaceList nl;
1055 if (includeList) // file contains #includes
1056 {
1057 {
1058 QListIterator<IncludeInfo> iii(*includeList);
1059 IncludeInfo *ii;
1060 for (iii.toFirst();(ii=iii.current());++iii) // foreach #include...
1061 {
1062 if (ii->fileDef && !ii->fileDef->visited) // ...that is a known file
1063 {
1064 // recurse into this file
1065 ii->fileDef->addIncludedUsingDirectives();
1066 }
1067 }
1068 }
1069 {
1070 QListIterator<IncludeInfo> iii(*includeList);
1071 IncludeInfo *ii;
1072 // iterate through list from last to first
1073 for (iii.toLast();(ii=iii.current());--iii)
1074 {
1075 if (ii->fileDef && ii->fileDef!=this)
1076 {
1077 // add using directives
1078 NamespaceSDict *unl = ii->fileDef->usingDirList;
1079 if (unl)
1080 {
1081 NamespaceSDict::Iterator nli(*unl);
1082 NamespaceDef *nd;
1083 for (nli.toLast();(nd=nli.current());--nli)
1084 {
1085 // append each using directive found in a #include file
1086 if (usingDirList==0) usingDirList = new NamespaceSDict;
1087 //printf("Prepending used namespace %s to the list of file %s\n",
1088 // nd->name().data(),name().data());
1089 if (usingDirList->find(nd->qualifiedName())==0) // not yet added
1090 {
1091 usingDirList->prepend(nd->qualifiedName(),nd);
1092 }
1093 }
1094 }
1095 // add using declarations
1096 SDict<Definition> *udl = ii->fileDef->usingDeclList;
1097 if (udl)
1098 {
1099 SDict<Definition>::Iterator udi(*udl);
1100 Definition *d;
1101 for (udi.toLast();(d=udi.current());--udi)
1102 {
1103 //printf("Adding using declaration %s\n",d->name().data());
1104 if (usingDeclList==0)
1105 {
1106 usingDeclList = new SDict<Definition>(17);
1107 }
1108 if (usingDeclList->find(d->qualifiedName())==0)
1109 {
1110 usingDeclList->prepend(d->qualifiedName(),d);
1111 }
1112 }
1113 }
1114 }
1115 }
1116 }
1117 }
1118 //printf(") end FileDef::addIncludedUsingDirectives for file %s\n",name().data());
1119}
1120
1121
1122void FileDef::addIncludedByDependency(FileDef *fd,const char *incName,
1123 bool local,bool imported)
1124{
1125 //printf("FileDef::addIncludedByDependency(%p,%s,%d)\n",fd,incName,local);
1126 QCString iName = fd ? fd->absFilePath().data() : incName;
1127 if (!iName.isEmpty() && (includedByDict==0 || includedByDict->find(iName)==0))
1128 {
1129 if (includedByDict==0)
1130 {
1131 includedByDict = new QDict<IncludeInfo>(61);
1132 includedByList = new QList<IncludeInfo>;
1133 includedByList->setAutoDelete(TRUE);
1134 }
1135 IncludeInfo *ii = new IncludeInfo;
1136 ii->fileDef = fd;
1137 ii->includeName = incName;
1138 ii->local = local;
1139 ii->imported = imported;
1140 includedByList->append(ii);
1141 includedByDict->insert(iName,ii);
1142 }
1143}
1144
1145bool FileDef::isIncluded(const QCString &name) const
1146{
1147 if (name.isEmpty()) return FALSE;
1148 return includeDict!=0 && includeDict->find(name)!=0;
1149}
1150
1151bool FileDef::generateSourceFile() const
1152{
1153 QCString extension = name().right(4);
1154 return !isReference() &&
1155 (Config_getBool("SOURCE_BROWSER") ||
1156 (Config_getBool("VERBATIM_HEADERS") && guessSection(name())==Entry::HEADER_SEC)
1157 ) &&
1158 extension!=".doc" && extension!=".txt" && extension!=".dox";
1159}
1160
1161
1162void FileDef::addListReferences()
1163{
1164 {
1165 LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
1166 addRefItem(xrefItems.pointer(),
1167 getOutputFileBase(),
1168 theTranslator->trFile(TRUE,TRUE),
1169 getOutputFileBase(),name(),
1170 0
1171 );
1172 }
1173 if (memberGroupSDict)
1174 {
1175 MemberGroupSDict::Iterator mgli(*memberGroupSDict);
1176 MemberGroup *mg;
1177 for (;(mg=mgli.current());++mgli)
1178 {
1179 mg->addListReferences(this);
1180 }
1181 }
1182 QListIterator<MemberList> mli(m_memberLists);
1183 MemberList *ml;
1184 for (mli.toFirst();(ml=mli.current());++mli)
1185 {
1186 if (ml->listType()&MemberList::documentationLists)
1187 {
1188 ml->addListReferences(this);
1189 }
1190 }
1191}
1192
1193//-------------------------------------------------------------------
1194
1195static int findMatchingPart(const QCString &path,const QCString dir)
1196{
1197 int si1;
1198 int pos1=0,pos2=0;
1199 while ((si1=path.find('/',pos1))!=-1)
1200 {
1201 int si2=dir.find('/',pos2);
1202 //printf(" found slash at pos %d in path %d: %s<->%s\n",si1,si2,
1203 // path.mid(pos1,si1-pos2).data(),dir.mid(pos2).data());
1204 if (si2==-1 && path.mid(pos1,si1-pos2)==dir.mid(pos2)) // match at end
1205 {
1206 return dir.length();
1207 }
1208 if (si1!=si2 || path.mid(pos1,si1-pos2)!=dir.mid(pos2,si2-pos2)) // no match in middle
1209 {
1210 return QMAX(pos1-1,0);
1211 }
1212 pos1=si1+1;
1213 pos2=si2+1;
1214 }
1215 return 0;
1216}
1217
1218static Directory *findDirNode(Directory *root,const QCString &name)
1219{
1220 QListIterator<DirEntry> dli(root->children());
1221 DirEntry *de;
1222 for (dli.toFirst();(de=dli.current());++dli)
1223 {
1224 if (de->kind()==DirEntry::Dir)
1225 {
1226 Directory *dir = (Directory *)de;
1227 QCString dirName=dir->name();
1228 int sp=findMatchingPart(name,dirName);
1229 //printf("findMatchingPart(%s,%s)=%d\n",name.data(),dirName.data(),sp);
1230 if (sp>0) // match found
1231 {
1232 if ((uint)sp==dirName.length()) // whole directory matches
1233 {
1234 // recurse into the directory
1235 return findDirNode(dir,name.mid(dirName.length()+1));
1236 }
1237 else // partial match => we need to split the path into three parts
1238 {
1239 QCString baseName =dirName.left(sp);
1240 QCString oldBranchName=dirName.mid(sp+1);
1241 QCString newBranchName=name.mid(sp+1);
1242 // strip file name from path
1243 int newIndex=newBranchName.findRev('/');
1244 if (newIndex>0) newBranchName=newBranchName.left(newIndex);
1245
1246 //printf("Splitting off part in new branch \n"
1247 // "base=%s old=%s new=%s\n",
1248 // baseName.data(),
1249 // oldBranchName.data(),
1250 // newBranchName.data()
1251 // );
1252 Directory *base = new Directory(root,baseName);
1253 Directory *newBranch = new Directory(base,newBranchName);
1254 dir->reParent(base);
1255 dir->rename(oldBranchName);
1256 base->addChild(dir);
1257 base->addChild(newBranch);
1258 dir->setLast(FALSE);
1259 // remove DirEntry container from list (without deleting it)
1260 root->children().setAutoDelete(FALSE);
1261 root->children().removeRef(dir);
1262 root->children().setAutoDelete(TRUE);
1263 // add new branch to the root
1264 if (!root->children().isEmpty())
1265 {
1266 root->children().last()->setLast(FALSE);
1267 }
1268 root->addChild(base);
1269 return newBranch;
1270 }
1271 }
1272 }
1273 }
1274 int si=name.findRev('/');
1275 if (si==-1) // no subdir
1276 {
1277 return root; // put the file under the root node.
1278 }
1279 else // need to create a subdir
1280 {
1281 QCString baseName = name.left(si);
1282 //printf("new subdir %s\n",baseName.data());
1283 Directory *newBranch = new Directory(root,baseName);
1284 if (!root->children().isEmpty())
1285 {
1286 root->children().last()->setLast(FALSE);
1287 }
1288 root->addChild(newBranch);
1289 return newBranch;
1290 }
1291}
1292
1293static void mergeFileDef(Directory *root,FileDef *fd)
1294{
1295 QCString rootPath = root->name();
1296 QCString filePath = fd->absFilePath();
1297 //printf("merging %s\n",filePath.data());
1298 Directory *dirNode = findDirNode(root,filePath);
1299 if (!dirNode->children().isEmpty())
1300 {
1301 dirNode->children().last()->setLast(FALSE);
1302 }
1303 DirEntry *e=new DirEntry(dirNode,fd);
1304 dirNode->addChild(e);
1305}
1306
1307#if 0
1308static void generateIndent(QTextStream &t,DirEntry *de,int level)
1309{
1310 if (de->parent())
1311 {
1312 generateIndent(t,de->parent(),level+1);
1313 }
1314 // from the root up to node n do...
1315 if (level==0) // item before a dir or document
1316 {
1317 if (de->isLast())
1318 {
1319 if (de->kind()==DirEntry::Dir)
1320 {
1321 t << "<img " << FTV_IMGATTRIBS(plastnode) << "/>";
1322 }
1323 else
1324 {
1325 t << "<img " << FTV_IMGATTRIBS(lastnode) << "/>";
1326 }
1327 }
1328 else
1329 {
1330 if (de->kind()==DirEntry::Dir)
1331 {
1332 t << "<img " << FTV_IMGATTRIBS(pnode) << "/>";
1333 }
1334 else
1335 {
1336 t << "<img " << FTV_IMGATTRIBS(node) << "/>";
1337 }
1338 }
1339 }
1340 else // item at another level
1341 {
1342 if (de->isLast())
1343 {
1344 t << "<img " << FTV_IMGATTRIBS(blank) << "/>";
1345 }
1346 else
1347 {
1348 t << "<img " << FTV_IMGATTRIBS(vertline) << "/>";
1349 }
1350 }
1351}
1352
1353static void writeDirTreeNode(QTextStream &t,Directory *root,int level)
1354{
1355 QCString indent;
1356 indent.fill(' ',level*2);
1357 QListIterator<DirEntry> dli(root->children());
1358 DirEntry *de;
1359 for (dli.toFirst();(de=dli.current());++dli)
1360 {
1361 t << indent << "<p>";
1362 generateIndent(t,de,0);
1363 if (de->kind()==DirEntry::Dir)
1364 {
1365 Directory *dir=(Directory *)de;
1366 //printf("%s [dir]: %s (last=%d,dir=%d)\n",indent.data(),dir->name().data(),dir->isLast(),dir->kind()==DirEntry::Dir);
1367 t << "<img " << FTV_IMGATTRIBS(folderclosed) << "/>";
1368 t << dir->name();
1369 t << "</p>\n";
1370 t << indent << "<div>\n";
1371 writeDirTreeNode(t,dir,level+1);
1372 t << indent << "</div>\n";
1373 }
1374 else
1375 {
1376 //printf("%s [file]: %s (last=%d,dir=%d)\n",indent.data(),de->file()->name().data(),de->isLast(),de->kind()==DirEntry::Dir);
1377 t << "<img " << FTV_IMGATTRIBS(doc) << "/>";
1378 t << de->file()->name();
1379 t << "</p>\n";
1380 }
1381 }
1382}
1383#endif
1384
1385static void addDirsAsGroups(Directory *root,GroupDef *parent,int level)
1386{
1387 GroupDef *gd=0;
1388 if (root->kind()==DirEntry::Dir)
1389 {
1390 gd = new GroupDef("[generated]",
1391 1,
1392 root->path(), // name
1393 root->name() // title
1394 );
1395 if (parent)
1396 {
1397 parent->addGroup(gd);
1398 gd->makePartOfGroup(parent);
1399 }
1400 else
1401 {
1402 Doxygen::groupSDict->append(root->path(),gd);
1403 }
1404 }
1405 QListIterator<DirEntry> dli(root->children());
1406 DirEntry *de;
1407 for (dli.toFirst();(de=dli.current());++dli)
1408 {
1409 if (de->kind()==DirEntry::Dir)
1410 {
1411 addDirsAsGroups((Directory *)de,gd,level+1);
1412 }
1413 }
1414}
1415
1416void generateFileTree()
1417{
1418 Directory *root=new Directory(0,"root");
1419 root->setLast(TRUE);
1420 FileNameListIterator fnli(*Doxygen::inputNameList);
1421 FileName *fn;
1422 for (fnli.toFirst();(fn=fnli.current());++fnli)
1423 {
1424 FileNameIterator fni(*fn);
1425 FileDef *fd;
1426 for (;(fd=fni.current());++fni)
1427 {
1428 mergeFileDef(root,fd);
1429 }
1430 }
1431 //t << "<div class=\"directory\">\n";
1432 //writeDirTreeNode(t,root,0);
1433 //t << "</div>\n";
1434 addDirsAsGroups(root,0,0);
1435 delete root;
1436}
1437
1438//-------------------------------------------------------------------
1439
1440void FileDef::combineUsingRelations()
1441{
1442 if (visited) return; // already done
1443 visited=TRUE;
1444 if (usingDirList)
1445 {
1446 NamespaceSDict::Iterator nli(*usingDirList);
1447 NamespaceDef *nd;
1448 for (nli.toFirst();(nd=nli.current());++nli)
1449 {
1450 nd->combineUsingRelations();
1451 }
1452 for (nli.toFirst();(nd=nli.current());++nli)
1453 {
1454 // add used namespaces of namespace nd to this namespace
1455 if (nd->getUsedNamespaces())
1456 {
1457 NamespaceSDict::Iterator unli(*nd->getUsedNamespaces());
1458 NamespaceDef *und;
1459 for (unli.toFirst();(und=unli.current());++unli)
1460 {
1461 //printf("Adding namespace %s to the using list of %s\n",und->qualifiedName().data(),qualifiedName().data());
1462 addUsingDirective(und);
1463 }
1464 }
1465 // add used classes of namespace nd to this namespace
1466 if (nd->getUsedClasses())
1467 {
1468 SDict<Definition>::Iterator cli(*nd->getUsedClasses());
1469 Definition *ucd;
1470 for (cli.toFirst();(ucd=cli.current());++cli)
1471 {
1472 //printf("Adding class %s to the using list of %s\n",cd->qualifiedName().data(),qualifiedName().data());
1473 addUsingDeclaration(ucd);
1474 }
1475 }
1476 }
1477 }
1478}
1479
1480bool FileDef::isDocumentationFile() const
1481{
1482 return name().right(4)==".doc" ||
1483 name().right(4)==".txt" ||
1484 name().right(4)==".dox";
1485}
1486
1487void FileDef::acquireFileVersion()
1488{
1489 QCString vercmd = Config_getString("FILE_VERSION_FILTER");
1490 if (!vercmd.isEmpty() && filepath!="generated")
1491 {
1492 msg("Version of %s : ",filepath.data());
1493 QCString cmd = vercmd+" \""+filepath+"\"";
1494 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
1495 FILE *f=portable_popen(cmd,"r");
1496 if (!f)
1497 {
1498 err("error: could not execute %s\n",vercmd.data());
1499 return;
1500 }
1501 const int bufSize=1024;
1502 char buf[bufSize];
1503 int numRead = fread(buf,1,bufSize,f);
1504 portable_pclose(f);
1505 if (numRead > 0)
1506 {
1507 fileVersion = QCString(buf,numRead).stripWhiteSpace();
1508 msg("%s\n",fileVersion.data());
1509 }
1510 else
1511 {
1512 msg("no version available\n");
1513 }
1514 }
1515}
1516
1517
1518QCString FileDef::getSourceFileBase() const
1519{
1520 if (Htags::useHtags)
1521 {
1522 return Htags::path2URL(filepath);
1523 }
1524 else
1525 {
1526 return convertNameToFile(diskname)+"_source";
1527 }
1528}
1529
1530/*! Returns the name of the verbatim copy of this file (if any). */
1531QCString FileDef::includeName() const
1532{
1533 if (Htags::useHtags)
1534 {
1535 return Htags::path2URL(filepath);
1536 }
1537 else
1538 {
1539 return convertNameToFile(diskname)+"_source";
1540 }
1541}
1542
1543MemberList *FileDef::createMemberList(MemberList::ListType lt)
1544{
1545 m_memberLists.setAutoDelete(TRUE);
1546 QListIterator<MemberList> mli(m_memberLists);
1547 MemberList *ml;
1548 for (mli.toFirst();(ml=mli.current());++mli)
1549 {
1550 if (ml->listType()==lt)
1551 {
1552 return ml;
1553 }
1554 }
1555 // not found, create a new member list
1556 ml = new MemberList(lt);
1557 m_memberLists.append(ml);
1558 return ml;
1559}
1560
1561void FileDef::addMemberToList(MemberList::ListType lt,MemberDef *md)
1562{
1563 static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
1564 static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
1565 MemberList *ml = createMemberList(lt);
1566 ml->setNeedsSorting(
1567 ((ml->listType()&MemberList::declarationLists) && sortBriefDocs) ||
1568 ((ml->listType()&MemberList::documentationLists) && sortMemberDocs));
1569 ml->append(md);
1570#if 0
1571 if (ml->needsSorting())
1572 ml->inSort(md);
1573 else
1574 ml->append(md);
1575#endif
1576 if (lt&MemberList::documentationLists)
1577 {
1578 ml->setInFile(TRUE);
1579 }
1580 if (ml->listType()&MemberList::declarationLists) md->setSectionList(this,ml);
1581}
1582
1583void FileDef::sortMemberLists()
1584{
1585 MemberList *ml = m_memberLists.first();
1586 while (ml)
1587 {
1588 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
1589 ml = m_memberLists.next();
1590 }
1591}
1592
1593MemberList *FileDef::getMemberList(MemberList::ListType lt) const
1594{
1595 FileDef *that = (FileDef*)this;
1596 MemberList *ml = that->m_memberLists.first();
1597 while (ml)
1598 {
1599 if (ml->listType()==lt)
1600 {
1601 return ml;
1602 }
1603 ml = that->m_memberLists.next();
1604 }
1605 return 0;
1606}
1607
1608void FileDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title)
1609{
1610 static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1611 MemberList * ml = getMemberList(lt);
1612 if (ml)
1613 {
1614 if (optVhdl) // use specific declarations function
1615 {
1616 VhdlDocGen::writeVhdlDeclarations(ml,ol,0,0,this);
1617 }
1618 else
1619 {
1620 ml->writeDeclarations(ol,0,0,this,0,title,0);
1621 }
1622 }
1623}
1624
1625void FileDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title)
1626{
1627 MemberList * ml = getMemberList(lt);
1628 if (ml) ml->writeDocumentation(ol,name(),this,title);
1629}
1630
1631bool FileDef::isLinkableInProject() const
1632{
1633 static bool showFiles = Config_getBool("SHOW_FILES");
1634 return hasDocumentation() && !isReference() && showFiles;
1635}
1636
1637bool FileDef::includes(FileDef *incFile,QDict<FileDef> *includedFiles) const
1638{
1639 if (incFile==this) return TRUE;
1640 //printf("%s::includes(%s)\n",name().data(),incFile->name().data());
1641 includedFiles->insert(absFilePath(),this);
1642 if (includeList)
1643 {
1644 QListIterator<IncludeInfo> ili(*includeList);
1645 IncludeInfo *ii;
1646 for (;(ii=ili.current());++ili)
1647 {
1648 if (ii->fileDef &&
1649 includedFiles->find(ii->fileDef->absFilePath())==0 &&
1650 ii->fileDef->includes(incFile,includedFiles)) return TRUE;
1651 }
1652 }
1653 return FALSE;
1654}
1655
1656
1657

Archive Download this file

Revision: 1322