1 /******************************************************************************
3 * Copyright (C) 1997-2012 by Dimitri van Heesch.
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
23 #include "classlist.h"
26 #include "outputgen.h"
31 #include "xmldocvisitor.h"
32 #include "docparser.h"
34 #include "parserintf.h"
35 #include "arguments.h"
39 #include <qtextstream.h>
43 #define XML_DB(x) do {} while(0)
45 //#define XML_DB(x) printf x
46 // debug inside output
47 //#define XML_DB(x) QCString __t;__t.sprintf x;m_t << __t
51 static const char index_xsd[] =
52 #include "index_xsd.h"
57 static const char compound_xsd[] =
58 #include "compound_xsd.h"
63 /** Helper class mapping MemberList::ListType to a string representing */
64 class XmlSectionMapper : public QIntDict<char>
67 XmlSectionMapper() : QIntDict<char>(47)
69 insert(MemberList::pubTypes,"public-type");
70 insert(MemberList::pubMethods,"public-func");
71 insert(MemberList::pubAttribs,"public-attrib");
72 insert(MemberList::pubSlots,"public-slot");
73 insert(MemberList::signals,"signal");
74 insert(MemberList::dcopMethods,"dcop-func");
75 insert(MemberList::properties,"property");
76 insert(MemberList::events,"event");
77 insert(MemberList::pubStaticMethods,"public-static-func");
78 insert(MemberList::pubStaticAttribs,"public-static-attrib");
79 insert(MemberList::proTypes,"protected-type");
80 insert(MemberList::proMethods,"protected-func");
81 insert(MemberList::proAttribs,"protected-attrib");
82 insert(MemberList::proSlots,"protected-slot");
83 insert(MemberList::proStaticMethods,"protected-static-func");
84 insert(MemberList::proStaticAttribs,"protected-static-attrib");
85 insert(MemberList::pacTypes,"package-type");
86 insert(MemberList::pacMethods,"package-func");
87 insert(MemberList::pacAttribs,"package-attrib");
88 insert(MemberList::pacStaticMethods,"package-static-func");
89 insert(MemberList::pacStaticAttribs,"package-static-attrib");
90 insert(MemberList::priTypes,"private-type");
91 insert(MemberList::priMethods,"private-func");
92 insert(MemberList::priAttribs,"private-attrib");
93 insert(MemberList::priSlots,"private-slot");
94 insert(MemberList::priStaticMethods,"private-static-func");
95 insert(MemberList::priStaticAttribs,"private-static-attrib");
96 insert(MemberList::friends,"friend");
97 insert(MemberList::related,"related");
98 insert(MemberList::decDefineMembers,"define");
99 insert(MemberList::decProtoMembers,"prototype");
100 insert(MemberList::decTypedefMembers,"typedef");
101 insert(MemberList::decEnumMembers,"enum");
102 insert(MemberList::decFuncMembers,"func");
103 insert(MemberList::decVarMembers,"var");
107 static XmlSectionMapper g_xmlSectionMapper;
110 inline void writeXMLString(FTextStream &t,const char *s)
112 t << convertToXML(s);
115 inline void writeXMLCodeString(FTextStream &t,const char *s, int &col)
124 static int tabSize = Config_getInt("TAB_SIZE");
125 int spacesToNextTabStop = tabSize - (col%tabSize);
126 col+=spacesToNextTabStop;
127 while (spacesToNextTabStop--) t << "<sp/>";
130 case ' ': t << "<sp/>"; col++; break;
131 case '<': t << "<"; col++; break;
132 case '>': t << ">"; col++; break;
133 case '&': t << "&"; col++; break;
134 case '\'': t << "'"; col++; break;
135 case '"': t << """; col++; break;
136 default: t << c; col++; break;
142 static void writeXMLHeader(FTextStream &t)
144 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
145 t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
146 t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" ";
147 t << "version=\"" << versionString << "\">" << endl;
150 static void writeCombineScript()
152 QCString outputDirectory = Config_getString("XML_OUTPUT");
153 QCString fileName=outputDirectory+"/combine.xslt";
155 if (!f.open(IO_WriteOnly))
157 err("Cannot open file %s for writing!\n",fileName.data());
161 //t.setEncoding(FTextStream::UnicodeUTF8);
164 "<!-- XSLT script to combine the generated output into a single file. \n"
165 " If you have xsltproc you could use:\n"
166 " xsltproc combine.xslt index.xml >all.xml\n"
168 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
169 " <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n"
170 " <xsl:template match=\"/\">\n"
171 " <doxygen version=\"{doxygenindex/@version}\">\n"
172 " <!-- Load all doxgen generated xml files -->\n"
173 " <xsl:for-each select=\"doxygenindex/compound\">\n"
174 " <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n"
178 "</xsl:stylesheet>\n";
182 void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId,
183 const char *anchorId,const char *text,const char *tooltip)
185 t << "<ref refid=\"" << compoundId;
186 if (anchorId) t << "_1" << anchorId;
187 t << "\" kindref=\"";
188 if (anchorId) t << "member"; else t << "compound";
190 if (extRef) t << " external=\"" << extRef << "\"";
191 if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
193 writeXMLString(t,text);
197 /** Implements TextGeneratorIntf for an XML stream. */
198 class TextGeneratorXMLImpl : public TextGeneratorIntf
201 TextGeneratorXMLImpl(FTextStream &t): m_t(t) {}
202 void writeString(const char *s,bool /*keepSpaces*/) const
204 writeXMLString(m_t,s);
206 void writeBreak(int) const {}
207 void writeLink(const char *extRef,const char *file,
208 const char *anchor,const char *text
211 writeXMLLink(m_t,extRef,file,anchor,text,0);
217 /** Helper class representing a stack of objects stored by value */
218 template<class T> class ValStack
221 ValStack() : m_values(10), m_sp(0), m_size(10) {}
222 virtual ~ValStack() {}
223 ValStack(const ValStack<T> &s)
225 m_values=s.m_values.copy();
229 ValStack &operator=(const ValStack<T> &s)
231 m_values=s.m_values.copy();
242 m_values.resize(m_size);
249 return m_values[m_sp--];
254 return m_values[m_sp];
271 /** Generator for producing XML formatted source code. */
272 class XMLCodeGenerator : public CodeOutputInterface
276 XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1),
277 m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE),
278 m_insideSpecialHL(FALSE) {}
279 virtual ~XMLCodeGenerator() { }
281 void codify(const char *text)
283 XML_DB(("(codify \"%s\")\n",text));
284 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
286 m_t << "<highlight class=\"normal\">";
287 m_normalHLNeedStartTag=FALSE;
289 writeXMLCodeString(m_t,text,col);
291 void writeCodeLink(const char *ref,const char *file,
292 const char *anchor,const char *name,
295 XML_DB(("(writeCodeLink)\n"));
296 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
298 m_t << "<highlight class=\"normal\">";
299 m_normalHLNeedStartTag=FALSE;
301 writeXMLLink(m_t,ref,file,anchor,name,tooltip);
304 void startCodeLine(bool)
306 XML_DB(("(startCodeLine)\n"));
308 if (m_lineNumber!=-1)
310 m_t << " lineno=\"" << m_lineNumber << "\"";
311 if (!m_refId.isEmpty())
313 m_t << " refid=\"" << m_refId << "\"";
316 m_t << " refkind=\"member\"";
320 m_t << " refkind=\"compound\"";
323 if (!m_external.isEmpty())
325 m_t << " external=\"" << m_external << "\"";
329 m_insideCodeLine=TRUE;
334 XML_DB(("(endCodeLine)\n"));
335 if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
337 m_t << "</highlight>";
338 m_normalHLNeedStartTag=TRUE;
340 m_t << "</codeline>" << endl; // non DocBook
343 m_external.resize(0);
344 m_insideCodeLine=FALSE;
346 void startCodeAnchor(const char *id)
348 XML_DB(("(startCodeAnchor)\n"));
349 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
351 m_t << "<highlight class=\"normal\">";
352 m_normalHLNeedStartTag=FALSE;
354 m_t << "<anchor id=\"" << id << "\">";
358 XML_DB(("(endCodeAnchor)\n"));
361 void startFontClass(const char *colorClass)
363 XML_DB(("(startFontClass)\n"));
364 if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
366 m_t << "</highlight>";
367 m_normalHLNeedStartTag=TRUE;
369 m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
370 m_insideSpecialHL=TRUE;
374 XML_DB(("(endFontClass)\n"));
375 m_t << "</highlight>"; // non DocBook
376 m_insideSpecialHL=FALSE;
378 void writeCodeAnchor(const char *)
380 XML_DB(("(writeCodeAnchor)\n"));
382 void writeLineNumber(const char *extRef,const char *compId,
383 const char *anchorId,int l)
385 XML_DB(("(writeLineNumber)\n"));
386 // we remember the information provided here to use it
387 // at the <codeline> start tag.
392 if (anchorId) m_refId+=(QCString)"_1"+anchorId;
393 m_isMemberRef = anchorId!=0;
394 if (extRef) m_external=extRef;
397 void linkableSymbol(int, const char *,Definition *,Definition *)
403 if (m_insideCodeLine) endCodeLine();
414 bool m_insideCodeLine;
415 bool m_normalHLNeedStartTag;
416 bool m_insideSpecialHL;
420 static void writeTemplateArgumentList(ArgumentList *al,
427 indentStr.fill(' ',indent);
430 t << indentStr << "<templateparamlist>" << endl;
431 ArgumentListIterator ali(*al);
433 for (ali.toFirst();(a=ali.current());++ali)
435 t << indentStr << " <param>" << endl;
436 if (!a->type.isEmpty())
438 t << indentStr << " <type>";
439 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
440 t << "</type>" << endl;
442 if (!a->name.isEmpty())
444 t << indentStr << " <declname>" << a->name << "</declname>" << endl;
445 t << indentStr << " <defname>" << a->name << "</defname>" << endl;
447 if (!a->defval.isEmpty())
449 t << indentStr << " <defval>";
450 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
451 t << "</defval>" << endl;
453 t << indentStr << " </param>" << endl;
455 t << indentStr << "</templateparamlist>" << endl;
459 static void writeMemberTemplateLists(MemberDef *md,FTextStream &t)
461 LockingPtr<ArgumentList> templMd = md->templateArguments();
462 if (templMd!=0) // function template prefix
464 writeTemplateArgumentList(templMd.pointer(),t,md->getClassDef(),md->getFileDef(),8);
468 static void writeTemplateList(ClassDef *cd,FTextStream &t)
470 writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
473 static void writeXMLDocBlock(FTextStream &t,
474 const QCString &fileName,
478 const QCString &text)
480 QCString stext = text.stripWhiteSpace();
481 if (stext.isEmpty()) return;
482 // convert the documentation string into an abstract syntax tree
483 DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text+"\n",FALSE,FALSE);
484 // create a code generator
485 XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
486 // create a parse tree visitor for XML
487 XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
489 root->accept(visitor);
497 void writeXMLCodeBlock(FTextStream &t,FileDef *fd)
499 ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
500 pIntf->resetCodeParserState();
501 XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
502 pIntf->parseCode(*xmlGen, // codeOutIntf
504 fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
505 FALSE, // isExampleBlock
510 FALSE, // inlineFragement
512 TRUE // showLineNumbers
518 static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName)
520 QCString scope = rmd->getScopeString();
521 QCString name = rmd->name();
522 if (!scope.isEmpty() && scope!=def->name())
524 name.prepend(scope+getLanguageSpecificSeparator(rmd->getLanguage()));
526 t << " <" << tagName << " refid=\"";
527 t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\"";
528 if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
530 t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\"";
531 t << " startline=\"" << rmd->getStartBodyLine() << "\"";
532 if (rmd->getEndBodyLine()!=-1)
534 t << " endline=\"" << rmd->getEndBodyLine() << "\"";
537 t << ">" << convertToXML(name) << "</" << tagName << ">" << endl;
541 static void stripQualifiers(QCString &typeStr)
546 if (typeStr.stripPrefix("static "));
547 else if (typeStr.stripPrefix("virtual "));
548 else if (typeStr.stripPrefix("volatile "));
549 else if (typeStr=="virtual") typeStr="";
554 static QCString classOutputFileBase(ClassDef *cd)
556 //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
557 //if (inlineGroupedClasses && cd->partOfGroups()!=0)
558 return cd->getOutputFileBase();
560 // return cd->getOutputFileBase();
563 static QCString memberOutputFileBase(MemberDef *md)
565 //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
566 //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
567 // return md->getClassDef()->getXmlOutputFileBase();
569 // return md->getOutputFileBase();
570 return md->getOutputFileBase();
574 static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def)
577 // + declaration/definition arg lists
581 // + const/volatile specifiers
583 // + source definition
584 // + source references
585 // + source referenced by
587 // + template arguments
588 // (templateArguments(), definitionTemplateParameterLists())
591 // enum values are written as part of the enum
592 if (md->memberType()==MemberDef::EnumValue) return;
593 if (md->isHidden()) return;
594 //if (md->name().at(0)=='@') return; // anonymous member
596 // group members are only visible in their group
597 //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
601 switch (md->memberType())
603 case MemberDef::Define: memType="define"; break;
604 case MemberDef::EnumValue: ASSERT(0); break;
605 case MemberDef::Property: memType="property"; break;
606 case MemberDef::Event: memType="event"; break;
607 case MemberDef::Variable: memType="variable"; break;
608 case MemberDef::Typedef: memType="typedef"; break;
609 case MemberDef::Enumeration: memType="enum"; break;
610 case MemberDef::Function: memType="function"; isFunc=TRUE; break;
611 case MemberDef::Signal: memType="signal"; isFunc=TRUE; break;
612 case MemberDef::Friend: memType="friend"; isFunc=TRUE; break;
613 case MemberDef::DCOP: memType="dcop"; isFunc=TRUE; break;
614 case MemberDef::Slot: memType="slot"; isFunc=TRUE; break;
617 ti << " <member refid=\"" << memberOutputFileBase(md)
618 << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>"
619 << convertToXML(md->name()) << "</name></member>" << endl;
622 if (md->getClassDef())
623 scopeName=md->getClassDef()->name();
624 else if (md->getNamespaceDef())
625 scopeName=md->getNamespaceDef()->name();
627 t << " <memberdef kind=\"";
628 //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t;
629 t << memType << "\" id=\"";
630 if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
632 t << md->getGroupDef()->getOutputFileBase();
636 t << memberOutputFileBase(md);
638 t << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
641 switch(md->protection())
643 case Public: t << "public"; break;
644 case Protected: t << "protected"; break;
645 case Private: t << "private"; break;
646 case Package: t << "package"; break;
651 if (md->isStatic()) t << "yes"; else t << "no";
656 LockingPtr<ArgumentList> al = md->argumentList();
658 if (al!=0 && al->constSpecifier) t << "yes"; else t << "no";
662 if (md->isExplicit()) t << "yes"; else t << "no";
666 if (md->isInline()) t << "yes"; else t << "no";
671 t << " final=\"yes\"";
676 t << " sealed=\"yes\"";
684 if (md->isOptional())
686 t << " optional=\"yes\"";
689 if (md->isRequired())
691 t << " required=\"yes\"";
695 switch (md->virtualness())
697 case Normal: t << "non-virtual"; break;
698 case Virtual: t << "virtual"; break;
699 case Pure: t << "pure-virtual"; break;
705 if (md->memberType() == MemberDef::Variable)
707 //ArgumentList *al = md->argumentList();
708 //t << " volatile=\"";
709 //if (al && al->volatileSpecifier) t << "yes"; else t << "no";
712 if (md->isMutable()) t << "yes"; else t << "no";
715 if (md->isInitonly())
717 t << " initonly=\"yes\"";
721 else if (md->memberType() == MemberDef::Property)
724 if (md->isReadable()) t << "yes"; else t << "no";
728 if (md->isWritable()) t << "yes"; else t << "no";
732 if (md->isGettable()) t << "yes"; else t << "no";
736 if (md->isSettable()) t << "yes"; else t << "no";
739 if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak())
742 if (md->isAssign()) t << "assign";
743 else if (md->isCopy()) t << "copy";
744 else if (md->isRetain()) t << "retain";
745 else if (md->isStrong()) t << "strong";
746 else if (md->isWeak()) t << "weak";
750 else if (md->memberType() == MemberDef::Event)
753 if (md->isAddable()) t << "yes"; else t << "no";
757 if (md->isRemovable()) t << "yes"; else t << "no";
761 if (md->isRaisable()) t << "yes"; else t << "no";
767 if (md->memberType()!=MemberDef::Define &&
768 md->memberType()!=MemberDef::Enumeration
771 if (md->memberType()!=MemberDef::Typedef)
773 writeMemberTemplateLists(md,t);
775 QCString typeStr = md->typeString(); //replaceAnonymousScopes(md->typeString());
776 stripQualifiers(typeStr);
778 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,typeStr);
779 t << "</type>" << endl;
780 t << " <definition>" << convertToXML(md->definition()) << "</definition>" << endl;
781 t << " <argsstring>" << convertToXML(md->argsString()) << "</argsstring>" << endl;
784 t << " <name>" << convertToXML(md->name()) << "</name>" << endl;
786 if (md->memberType() == MemberDef::Property)
788 if (md->isReadable())
789 t << " <read>" << convertToXML(md->getReadAccessor()) << "</read>" << endl;
790 if (md->isWritable())
791 t << " <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
793 if (md->memberType()==MemberDef::Variable && md->bitfieldString())
795 QCString bitfield = md->bitfieldString();
796 if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
797 t << " <bitfield>" << bitfield << "</bitfield>" << endl;
800 MemberDef *rmd = md->reimplements();
803 t << " <reimplements refid=\""
804 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
805 << convertToXML(rmd->name()) << "</reimplements>" << endl;
807 LockingPtr<MemberList> rbml = md->reimplementedBy();
810 MemberListIterator mli(*rbml);
811 for (mli.toFirst();(rmd=mli.current());++mli)
813 t << " <reimplementedby refid=\""
814 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
815 << convertToXML(rmd->name()) << "</reimplementedby>" << endl;
819 if (isFunc) //function
821 LockingPtr<ArgumentList> declAl = md->declArgumentList();
822 LockingPtr<ArgumentList> defAl = md->argumentList();
823 if (declAl!=0 && declAl->count()>0)
825 ArgumentListIterator declAli(*declAl);
826 ArgumentListIterator defAli(*defAl);
828 for (declAli.toFirst();(a=declAli.current());++declAli)
830 Argument *defArg = defAli.current();
831 t << " <param>" << endl;
832 if (!a->attrib.isEmpty())
834 t << " <attributes>";
835 writeXMLString(t,a->attrib);
836 t << "</attributes>" << endl;
838 if (!a->type.isEmpty())
841 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->type);
842 t << "</type>" << endl;
844 if (!a->name.isEmpty())
847 writeXMLString(t,a->name);
848 t << "</declname>" << endl;
850 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
853 writeXMLString(t,defArg->name);
854 t << "</defname>" << endl;
856 if (!a->array.isEmpty())
859 writeXMLString(t,a->array);
860 t << "</array>" << endl;
862 if (!a->defval.isEmpty())
865 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->defval);
866 t << "</defval>" << endl;
868 if (defArg && defArg->hasDocumentation())
870 t << " <briefdescription>";
871 writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),
872 md->getOuterScope(),md,defArg->docs);
873 t << "</briefdescription>" << endl;
875 t << " </param>" << endl;
876 if (defArg) ++defAli;
880 else if (md->memberType()==MemberDef::Define &&
881 md->argsString()) // define
883 if (md->argumentList()->count()==0) // special case for "foo()" to
884 // disguish it from "foo".
886 t << " <param></param>" << endl;
890 ArgumentListIterator ali(*md->argumentList());
892 for (ali.toFirst();(a=ali.current());++ali)
894 t << " <param><defname>" << a->type << "</defname></param>" << endl;
898 // avoid that extremely large tables are written to the output.
899 // todo: it's better to adhere to MAX_INITIALIZER_LINES.
900 if (!md->initializer().isEmpty() && md->initializer().length()<2000)
902 t << " <initializer>";
903 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->initializer());
904 t << "</initializer>" << endl;
907 if (md->excpString())
909 t << " <exceptions>";
910 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString());
911 t << "</exceptions>" << endl;
914 if (md->memberType()==MemberDef::Enumeration) // enum
916 LockingPtr<MemberList> enumFields = md->enumFieldList();
919 MemberListIterator emli(*enumFields);
921 for (emli.toFirst();(emd=emli.current());++emli)
923 ti << " <member refid=\"" << memberOutputFileBase(emd)
924 << "_1" << emd->anchor() << "\" kind=\"enumvalue\"><name>"
925 << convertToXML(emd->name()) << "</name></member>" << endl;
927 t << " <enumvalue id=\"" << memberOutputFileBase(emd) << "_1"
928 << emd->anchor() << "\" prot=\"";
929 switch (emd->protection())
931 case Public: t << "public"; break;
932 case Protected: t << "protected"; break;
933 case Private: t << "private"; break;
934 case Package: t << "package"; break;
938 writeXMLString(t,emd->name());
939 t << "</name>" << endl;
940 if (!emd->initializer().isEmpty())
942 t << " <initializer>";
943 writeXMLString(t,emd->initializer());
944 t << "</initializer>" << endl;
946 t << " <briefdescription>" << endl;
947 writeXMLDocBlock(t,emd->briefFile(),emd->briefLine(),emd->getOuterScope(),emd,emd->briefDescription());
948 t << " </briefdescription>" << endl;
949 t << " <detaileddescription>" << endl;
950 writeXMLDocBlock(t,emd->docFile(),emd->docLine(),emd->getOuterScope(),emd,emd->documentation());
951 t << " </detaileddescription>" << endl;
952 t << " </enumvalue>" << endl;
956 t << " <briefdescription>" << endl;
957 writeXMLDocBlock(t,md->briefFile(),md->briefLine(),md->getOuterScope(),md,md->briefDescription());
958 t << " </briefdescription>" << endl;
959 t << " <detaileddescription>" << endl;
960 writeXMLDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
961 t << " </detaileddescription>" << endl;
962 t << " <inbodydescription>" << endl;
963 writeXMLDocBlock(t,md->docFile(),md->inbodyLine(),md->getOuterScope(),md,md->inbodyDocumentation());
964 t << " </inbodydescription>" << endl;
965 if (md->getDefLine()!=-1)
967 t << " <location file=\""
968 << md->getDefFileName() << "\" line=\""
969 << md->getDefLine() << "\"";
970 if (md->getStartBodyLine()!=-1)
972 FileDef *bodyDef = md->getBodyDef();
975 t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
977 t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\""
978 << md->getEndBodyLine() << "\"";
983 //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
984 LockingPtr<MemberSDict> mdict = md->getReferencesMembers();
987 MemberSDict::Iterator mdi(*mdict);
989 for (mdi.toFirst();(rmd=mdi.current());++mdi)
991 writeMemberReference(t,def,rmd,"references");
994 mdict = md->getReferencedByMembers();
997 MemberSDict::Iterator mdi(*mdict);
999 for (mdi.toFirst();(rmd=mdi.current());++mdi)
1001 writeMemberReference(t,def,rmd,"referencedby");
1005 t << " </memberdef>" << endl;
1008 static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t,
1009 MemberList *ml,const char *kind,const char *header=0,
1010 const char *documentation=0)
1013 MemberListIterator mli(*ml);
1016 for (mli.toFirst();(md=mli.current());++mli)
1018 // namespace members are also inserted in the file scope, but
1019 // to prevent this duplication in the XML output, we filter those here.
1020 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1025 if (count==0) return; // empty list
1027 t << " <sectiondef kind=\"" << kind << "\">" << endl;
1030 t << " <header>" << convertToXML(header) << "</header>" << endl;
1034 t << " <description>";
1035 writeXMLDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
1036 t << "</description>" << endl;
1038 for (mli.toFirst();(md=mli.current());++mli)
1040 // namespace members are also inserted in the file scope, but
1041 // to prevent this duplication in the XML output, we filter those here.
1042 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1044 generateXMLForMember(md,ti,t,d);
1047 t << " </sectiondef>" << endl;
1050 static void writeListOfAllMembers(ClassDef *cd,FTextStream &t)
1052 t << " <listofallmembers>" << endl;
1053 if (cd->memberNameInfoSDict())
1055 MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
1056 MemberNameInfo *mni;
1057 for (mnii.toFirst();(mni=mnii.current());++mnii)
1059 MemberNameInfoIterator mii(*mni);
1061 for (mii.toFirst();(mi=mii.current());++mii)
1063 MemberDef *md=mi->memberDef;
1064 if (md->name().at(0)!='@') // skip anonymous members
1066 Protection prot = mi->prot;
1067 Specifier virt=md->virtualness();
1068 t << " <member refid=\"" << memberOutputFileBase(md) << "_1" <<
1069 md->anchor() << "\" prot=\"";
1072 case Public: t << "public"; break;
1073 case Protected: t << "protected"; break;
1074 case Private: t << "private"; break;
1075 case Package: t << "package"; break;
1080 case Normal: t << "non-virtual"; break;
1081 case Virtual: t << "virtual"; break;
1082 case Pure: t << "pure-virtual"; break;
1085 if (!mi->ambiguityResolutionScope.isEmpty())
1087 t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\"";
1089 t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" <<
1090 convertToXML(md->name()) << "</name></member>" << endl;
1095 t << " </listofallmembers>" << endl;
1098 static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
1102 ClassSDict::Iterator cli(*cl);
1104 for (cli.toFirst();(cd=cli.current());++cli)
1106 if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
1108 t << " <innerclass refid=\"" << classOutputFileBase(cd)
1110 switch(cd->protection())
1112 case Public: t << "public"; break;
1113 case Protected: t << "protected"; break;
1114 case Private: t << "private"; break;
1115 case Package: t << "package"; break;
1117 t << "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
1123 static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
1127 NamespaceSDict::Iterator nli(*nl);
1129 for (nli.toFirst();(nd=nli.current());++nli)
1131 if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
1133 t << " <innernamespace refid=\"" << nd->getOutputFileBase()
1134 << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
1140 static void writeInnerFiles(const FileList *fl,FTextStream &t)
1144 QListIterator<FileDef> fli(*fl);
1146 for (fli.toFirst();(fd=fli.current());++fli)
1148 t << " <innerfile refid=\"" << fd->getOutputFileBase()
1149 << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl;
1154 static void writeInnerPages(const PageSDict *pl,FTextStream &t)
1158 PageSDict::Iterator pli(*pl);
1160 for (pli.toFirst();(pd=pli.current());++pli)
1162 t << " <innerpage refid=\"" << pd->getOutputFileBase();
1163 if (pd->getGroupDef())
1165 t << "_" << pd->name();
1167 t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
1172 static void writeInnerGroups(const GroupList *gl,FTextStream &t)
1176 GroupListIterator gli(*gl);
1178 for (gli.toFirst();(sgd=gli.current());++gli)
1180 t << " <innergroup refid=\"" << sgd->getOutputFileBase()
1181 << "\">" << convertToXML(sgd->groupTitle())
1182 << "</innergroup>" << endl;
1187 static void writeInnerDirs(const DirList *dl,FTextStream &t)
1191 QListIterator<DirDef> subdirs(*dl);
1193 for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
1195 t << " <innerdir refid=\"" << subdir->getOutputFileBase()
1196 << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl;
1201 static void generateXMLForClass(ClassDef *cd,FTextStream &ti)
1203 // + brief description
1204 // + detailed description
1205 // + template argument list(s)
1208 // + inheritance diagram
1209 // + list of direct super classes
1210 // + list of direct sub classes
1211 // + list of inner classes
1212 // + collaboration diagram
1213 // + list of all members
1214 // + user defined member sections
1215 // + standard member sections
1216 // + detailed member documentation
1217 // - examples using the class
1219 if (cd->isReference()) return; // skip external references.
1220 if (cd->isHidden()) return; // skip hidden classes.
1221 if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1222 if (cd->templateMaster()!=0) return; // skip generated template instances.
1223 if (cd->isArtificial()) return; // skip artificially created classes
1225 msg("Generating XML output for class %s\n",cd->name().data());
1227 ti << " <compound refid=\"" << classOutputFileBase(cd)
1228 << "\" kind=\"" << cd->compoundTypeString()
1229 << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
1231 QCString outputDirectory = Config_getString("XML_OUTPUT");
1232 QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
1234 if (!f.open(IO_WriteOnly))
1236 err("Cannot open file %s for writing!\n",fileName.data());
1240 //t.setEncoding(FTextStream::UnicodeUTF8);
1243 t << " <compounddef id=\""
1244 << classOutputFileBase(cd) << "\" kind=\""
1245 << cd->compoundTypeString() << "\" prot=\"";
1246 switch (cd->protection())
1248 case Public: t << "public"; break;
1249 case Protected: t << "protected"; break;
1250 case Private: t << "private"; break;
1251 case Package: t << "package"; break;
1253 if (cd->isFinal()) t << "\" final=\"yes";
1254 if (cd->isSealed()) t << "\" sealed=\"yes";
1255 if (cd->isAbstract()) t << "\" abstract=\"yes";
1257 t << " <compoundname>";
1258 writeXMLString(t,cd->name());
1259 t << "</compoundname>" << endl;
1260 if (cd->baseClasses())
1262 BaseClassListIterator bcli(*cd->baseClasses());
1264 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1266 t << " <basecompoundref ";
1267 if (bcd->classDef->isLinkable())
1269 t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
1274 case Public: t << "public"; break;
1275 case Protected: t << "protected"; break;
1276 case Private: t << "private"; break;
1277 case Package: ASSERT(0); break;
1282 case Normal: t << "non-virtual"; break;
1283 case Virtual: t << "virtual"; break;
1284 case Pure: t <<"pure-virtual"; break;
1287 if (!bcd->templSpecifiers.isEmpty())
1290 insertTemplateSpecifierInScope(
1291 bcd->classDef->name(),bcd->templSpecifiers)
1296 t << convertToXML(bcd->classDef->displayName());
1298 t << "</basecompoundref>" << endl;
1301 if (cd->subClasses())
1303 BaseClassListIterator bcli(*cd->subClasses());
1305 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1307 t << " <derivedcompoundref refid=\""
1308 << classOutputFileBase(bcd->classDef)
1312 case Public: t << "public"; break;
1313 case Protected: t << "protected"; break;
1314 case Private: t << "private"; break;
1315 case Package: ASSERT(0); break;
1320 case Normal: t << "non-virtual"; break;
1321 case Virtual: t << "virtual"; break;
1322 case Pure: t << "pure-virtual"; break;
1324 t << "\">" << convertToXML(bcd->classDef->displayName())
1325 << "</derivedcompoundref>" << endl;
1329 IncludeInfo *ii=cd->includeInfo();
1332 QCString nm = ii->includeName;
1333 if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1337 if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
1339 t << " refid=\"" << ii->fileDef->getOutputFileBase() << "\"";
1341 t << " local=\"" << (ii->local ? "yes" : "no") << "\">";
1343 t << "</includes>" << endl;
1347 writeInnerClasses(cd->getClassSDict(),t);
1349 writeTemplateList(cd,t);
1350 if (cd->getMemberGroupSDict())
1352 MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
1354 for (;(mg=mgli.current());++mgli)
1356 generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
1357 mg->documentation());
1361 QListIterator<MemberList> mli(cd->getMemberLists());
1363 for (mli.toFirst();(ml=mli.current());++mli)
1365 if ((ml->listType()&MemberList::detailedLists)==0)
1367 generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1371 generateXMLSection(cd,ti,t,cd->pubTypes,"public-type");
1372 generateXMLSection(cd,ti,t,cd->pubMethods,"public-func");
1373 generateXMLSection(cd,ti,t,cd->pubAttribs,"public-attrib");
1374 generateXMLSection(cd,ti,t,cd->pubSlots,"public-slot");
1375 generateXMLSection(cd,ti,t,cd->signals,"signal");
1376 generateXMLSection(cd,ti,t,cd->dcopMethods,"dcop-func");
1377 generateXMLSection(cd,ti,t,cd->properties,"property");
1378 generateXMLSection(cd,ti,t,cd->events,"event");
1379 generateXMLSection(cd,ti,t,cd->pubStaticMethods,"public-static-func");
1380 generateXMLSection(cd,ti,t,cd->pubStaticAttribs,"public-static-attrib");
1381 generateXMLSection(cd,ti,t,cd->proTypes,"protected-type");
1382 generateXMLSection(cd,ti,t,cd->proMethods,"protected-func");
1383 generateXMLSection(cd,ti,t,cd->proAttribs,"protected-attrib");
1384 generateXMLSection(cd,ti,t,cd->proSlots,"protected-slot");
1385 generateXMLSection(cd,ti,t,cd->proStaticMethods,"protected-static-func");
1386 generateXMLSection(cd,ti,t,cd->proStaticAttribs,"protected-static-attrib");
1387 generateXMLSection(cd,ti,t,cd->pacTypes,"package-type");
1388 generateXMLSection(cd,ti,t,cd->pacMethods,"package-func");
1389 generateXMLSection(cd,ti,t,cd->pacAttribs,"package-attrib");
1390 generateXMLSection(cd,ti,t,cd->pacStaticMethods,"package-static-func");
1391 generateXMLSection(cd,ti,t,cd->pacStaticAttribs,"package-static-attrib");
1392 generateXMLSection(cd,ti,t,cd->priTypes,"private-type");
1393 generateXMLSection(cd,ti,t,cd->priMethods,"private-func");
1394 generateXMLSection(cd,ti,t,cd->priAttribs,"private-attrib");
1395 generateXMLSection(cd,ti,t,cd->priSlots,"private-slot");
1396 generateXMLSection(cd,ti,t,cd->priStaticMethods,"private-static-func");
1397 generateXMLSection(cd,ti,t,cd->priStaticAttribs,"private-static-attrib");
1398 generateXMLSection(cd,ti,t,cd->friends,"friend");
1399 generateXMLSection(cd,ti,t,cd->related,"related");
1402 t << " <briefdescription>" << endl;
1403 writeXMLDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
1404 t << " </briefdescription>" << endl;
1405 t << " <detaileddescription>" << endl;
1406 writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
1407 t << " </detaileddescription>" << endl;
1408 DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
1409 if (!inheritanceGraph.isTrivial())
1411 t << " <inheritancegraph>" << endl;
1412 inheritanceGraph.writeXML(t);
1413 t << " </inheritancegraph>" << endl;
1415 DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
1416 if (!collaborationGraph.isTrivial())
1418 t << " <collaborationgraph>" << endl;
1419 collaborationGraph.writeXML(t);
1420 t << " </collaborationgraph>" << endl;
1422 t << " <location file=\""
1423 << cd->getDefFileName() << "\" line=\""
1424 << cd->getDefLine() << "\"";
1425 if (cd->getStartBodyLine()!=-1)
1427 FileDef *bodyDef = cd->getBodyDef();
1430 t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
1432 t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
1433 << cd->getEndBodyLine() << "\"";
1436 writeListOfAllMembers(cd,t);
1437 t << " </compounddef>" << endl;
1438 t << "</doxygen>" << endl;
1440 ti << " </compound>" << endl;
1443 static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti)
1445 // + contained class definitions
1446 // + contained namespace definitions
1452 // - files containing (parts of) the namespace definition
1454 if (nd->isReference() || nd->isHidden()) return; // skip external references
1456 ti << " <compound refid=\"" << nd->getOutputFileBase()
1457 << "\" kind=\"namespace\"" << "><name>"
1458 << convertToXML(nd->name()) << "</name>" << endl;
1460 QCString outputDirectory = Config_getString("XML_OUTPUT");
1461 QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
1463 if (!f.open(IO_WriteOnly))
1465 err("Cannot open file %s for writing!\n",fileName.data());
1469 //t.setEncoding(FTextStream::UnicodeUTF8);
1472 t << " <compounddef id=\""
1473 << nd->getOutputFileBase() << "\" kind=\"namespace\">" << endl;
1474 t << " <compoundname>";
1475 writeXMLString(t,nd->name());
1476 t << "</compoundname>" << endl;
1478 writeInnerClasses(nd->getClassSDict(),t);
1479 writeInnerNamespaces(nd->getNamespaceSDict(),t);
1481 if (nd->getMemberGroupSDict())
1483 MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
1485 for (;(mg=mgli.current());++mgli)
1487 generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
1488 mg->documentation());
1492 QListIterator<MemberList> mli(nd->getMemberLists());
1494 for (mli.toFirst();(ml=mli.current());++mli)
1496 if ((ml->listType()&MemberList::declarationLists)!=0)
1498 generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1502 generateXMLSection(nd,ti,t,&nd->decDefineMembers,"define");
1503 generateXMLSection(nd,ti,t,&nd->decProtoMembers,"prototype");
1504 generateXMLSection(nd,ti,t,&nd->decTypedefMembers,"typedef");
1505 generateXMLSection(nd,ti,t,&nd->decEnumMembers,"enum");
1506 generateXMLSection(nd,ti,t,&nd->decFuncMembers,"func");
1507 generateXMLSection(nd,ti,t,&nd->decVarMembers,"var");
1510 t << " <briefdescription>" << endl;
1511 writeXMLDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
1512 t << " </briefdescription>" << endl;
1513 t << " <detaileddescription>" << endl;
1514 writeXMLDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
1515 t << " </detaileddescription>" << endl;
1516 t << " <location file=\""
1517 << nd->getDefFileName() << "\" line=\""
1518 << nd->getDefLine() << "\"/>" << endl;
1519 t << " </compounddef>" << endl;
1520 t << "</doxygen>" << endl;
1522 ti << " </compound>" << endl;
1525 static void generateXMLForFile(FileDef *fd,FTextStream &ti)
1528 // + includedby files
1530 // + included by graph
1531 // + contained class definitions
1532 // + contained namespace definitions
1539 // - number of lines
1541 if (fd->isReference()) return; // skip external references
1543 ti << " <compound refid=\"" << fd->getOutputFileBase()
1544 << "\" kind=\"file\"><name>" << convertToXML(fd->name())
1545 << "</name>" << endl;
1547 QCString outputDirectory = Config_getString("XML_OUTPUT");
1548 QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
1550 if (!f.open(IO_WriteOnly))
1552 err("Cannot open file %s for writing!\n",fileName.data());
1556 //t.setEncoding(FTextStream::UnicodeUTF8);
1559 t << " <compounddef id=\""
1560 << fd->getOutputFileBase() << "\" kind=\"file\">" << endl;
1561 t << " <compoundname>";
1562 writeXMLString(t,fd->name());
1563 t << "</compoundname>" << endl;
1567 if (fd->includeFileList())
1569 QListIterator<IncludeInfo> ili1(*fd->includeFileList());
1570 for (ili1.toFirst();(inc=ili1.current());++ili1)
1573 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1575 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1577 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1578 t << inc->includeName;
1579 t << "</includes>" << endl;
1583 if (fd->includedByFileList())
1585 QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
1586 for (ili2.toFirst();(inc=ili2.current());++ili2)
1588 t << " <includedby";
1589 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1591 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1593 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1594 t << inc->includeName;
1595 t << "</includedby>" << endl;
1599 DotInclDepGraph incDepGraph(fd,FALSE);
1600 if (!incDepGraph.isTrivial())
1602 t << " <incdepgraph>" << endl;
1603 incDepGraph.writeXML(t);
1604 t << " </incdepgraph>" << endl;
1607 DotInclDepGraph invIncDepGraph(fd,TRUE);
1608 if (!invIncDepGraph.isTrivial())
1610 t << " <invincdepgraph>" << endl;
1611 invIncDepGraph.writeXML(t);
1612 t << " </invincdepgraph>" << endl;
1615 if (fd->getClassSDict())
1617 writeInnerClasses(fd->getClassSDict(),t);
1619 if (fd->getNamespaceSDict())
1621 writeInnerNamespaces(fd->getNamespaceSDict(),t);
1624 if (fd->getMemberGroupSDict())
1626 MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
1628 for (;(mg=mgli.current());++mgli)
1630 generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
1631 mg->documentation());
1635 QListIterator<MemberList> mli(fd->getMemberLists());
1637 for (mli.toFirst();(ml=mli.current());++mli)
1639 if ((ml->listType()&MemberList::declarationLists)!=0)
1641 generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1645 generateXMLSection(fd,ti,t,fd->decDefineMembers,"define");
1646 generateXMLSection(fd,ti,t,fd->decProtoMembers,"prototype");
1647 generateXMLSection(fd,ti,t,fd->decTypedefMembers,"typedef");
1648 generateXMLSection(fd,ti,t,fd->decEnumMembers,"enum");
1649 generateXMLSection(fd,ti,t,fd->decFuncMembers,"func");
1650 generateXMLSection(fd,ti,t,fd->decVarMembers,"var");
1653 t << " <briefdescription>" << endl;
1654 writeXMLDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
1655 t << " </briefdescription>" << endl;
1656 t << " <detaileddescription>" << endl;
1657 writeXMLDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
1658 t << " </detaileddescription>" << endl;
1659 if (Config_getBool("XML_PROGRAMLISTING"))
1661 t << " <programlisting>" << endl;
1662 writeXMLCodeBlock(t,fd);
1663 t << " </programlisting>" << endl;
1665 t << " <location file=\"" << fd->getDefFileName() << "\"/>" << endl;
1666 t << " </compounddef>" << endl;
1667 t << "</doxygen>" << endl;
1669 ti << " </compound>" << endl;
1672 static void generateXMLForGroup(GroupDef *gd,FTextStream &ti)
1683 // + brief description
1684 // + detailed description
1686 if (gd->isReference()) return; // skip external references
1688 ti << " <compound refid=\"" << gd->getOutputFileBase()
1689 << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
1691 QCString outputDirectory = Config_getString("XML_OUTPUT");
1692 QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
1694 if (!f.open(IO_WriteOnly))
1696 err("Cannot open file %s for writing!\n",fileName.data());
1701 //t.setEncoding(FTextStream::UnicodeUTF8);
1703 t << " <compounddef id=\""
1704 << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
1705 t << " <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
1706 t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
1708 writeInnerFiles(gd->getFiles(),t);
1709 writeInnerClasses(gd->getClasses(),t);
1710 writeInnerNamespaces(gd->getNamespaces(),t);
1711 writeInnerPages(gd->getPages(),t);
1712 writeInnerGroups(gd->getSubGroups(),t);
1714 if (gd->getMemberGroupSDict())
1716 MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
1718 for (;(mg=mgli.current());++mgli)
1720 generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
1721 mg->documentation());
1725 QListIterator<MemberList> mli(gd->getMemberLists());
1727 for (mli.toFirst();(ml=mli.current());++mli)
1729 if ((ml->listType()&MemberList::declarationLists)!=0)
1731 generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1735 generateXMLSection(gd,ti,t,&gd->decDefineMembers,"define");
1736 generateXMLSection(gd,ti,t,&gd->decProtoMembers,"prototype");
1737 generateXMLSection(gd,ti,t,&gd->decTypedefMembers,"typedef");
1738 generateXMLSection(gd,ti,t,&gd->decEnumMembers,"enum");
1739 generateXMLSection(gd,ti,t,&gd->decFuncMembers,"func");
1740 generateXMLSection(gd,ti,t,&gd->decVarMembers,"var");
1743 t << " <briefdescription>" << endl;
1744 writeXMLDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
1745 t << " </briefdescription>" << endl;
1746 t << " <detaileddescription>" << endl;
1747 writeXMLDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
1748 t << " </detaileddescription>" << endl;
1749 t << " </compounddef>" << endl;
1750 t << "</doxygen>" << endl;
1752 ti << " </compound>" << endl;
1755 static void generateXMLForDir(DirDef *dd,FTextStream &ti)
1757 if (dd->isReference()) return; // skip external references
1758 ti << " <compound refid=\"" << dd->getOutputFileBase()
1759 << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName())
1760 << "</name>" << endl;
1762 QCString outputDirectory = Config_getString("XML_OUTPUT");
1763 QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
1765 if (!f.open(IO_WriteOnly))
1767 err("Cannot open file %s for writing!\n",fileName.data());
1772 //t.setEncoding(FTextStream::UnicodeUTF8);
1774 t << " <compounddef id=\""
1775 << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl;
1776 t << " <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl;
1778 writeInnerDirs(&dd->subDirs(),t);
1779 writeInnerFiles(dd->getFiles(),t);
1781 t << " <briefdescription>" << endl;
1782 writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
1783 t << " </briefdescription>" << endl;
1784 t << " <detaileddescription>" << endl;
1785 writeXMLDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
1786 t << " </detaileddescription>" << endl;
1787 t << " <location file=\"" << dd->name() << "\"/>" << endl;
1788 t << " </compounddef>" << endl;
1789 t << "</doxygen>" << endl;
1791 ti << " </compound>" << endl;
1794 static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
1800 const char *kindName = isExample ? "example" : "page";
1802 if (pd->isReference()) return;
1804 QCString pageName = pd->getOutputFileBase();
1805 if (pd->getGroupDef())
1807 pageName+=(QCString)"_"+pd->name();
1809 if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
1811 ti << " <compound refid=\"" << pageName
1812 << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name())
1813 << "</name>" << endl;
1815 QCString outputDirectory = Config_getString("XML_OUTPUT");
1816 QCString fileName=outputDirectory+"/"+pageName+".xml";
1818 if (!f.open(IO_WriteOnly))
1820 err("Cannot open file %s for writing!\n",fileName.data());
1825 //t.setEncoding(FTextStream::UnicodeUTF8);
1827 t << " <compounddef id=\"" << pageName;
1828 t << "\" kind=\"" << kindName << "\">" << endl;
1829 t << " <compoundname>" << convertToXML(pd->name())
1830 << "</compoundname>" << endl;
1832 SectionInfo *si = Doxygen::sectionDict.find(pd->name());
1835 t << " <title>" << convertToXML(si->title) << "</title>" << endl;
1837 writeInnerPages(pd->getSubPages(),t);
1838 t << " <detaileddescription>" << endl;
1841 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1842 pd->documentation()+"\n\\include "+pd->name());
1846 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1847 pd->documentation());
1849 t << " </detaileddescription>" << endl;
1851 t << " </compounddef>" << endl;
1852 t << "</doxygen>" << endl;
1854 ti << " </compound>" << endl;
1867 QCString outputDirectory = Config_getString("XML_OUTPUT");
1868 if (outputDirectory.isEmpty())
1870 outputDirectory=QDir::currentDirPath().utf8();
1874 QDir dir(outputDirectory);
1877 dir.setPath(QDir::currentDirPath());
1878 if (!dir.mkdir(outputDirectory))
1880 err("error: tag XML_OUTPUT: Output directory `%s' does not "
1881 "exist and cannot be created\n",outputDirectory.data());
1884 else if (!Config_getBool("QUIET"))
1886 err("notice: Output directory `%s' does not exist. "
1887 "I have created it for you.\n", outputDirectory.data());
1889 dir.cd(outputDirectory);
1891 outputDirectory=dir.absPath().utf8();
1894 QDir dir(outputDirectory);
1897 dir.setPath(QDir::currentDirPath());
1898 if (!dir.mkdir(outputDirectory))
1900 err("Cannot create directory %s\n",outputDirectory.data());
1904 QDir xmlDir(outputDirectory);
1905 createSubDirs(xmlDir);
1906 QCString fileName=outputDirectory+"/index.xsd";
1908 if (!f.open(IO_WriteOnly))
1910 err("Cannot open file %s for writing!\n",fileName.data());
1913 f.writeBlock(index_xsd,strlen(index_xsd));
1916 fileName=outputDirectory+"/compound.xsd";
1917 f.setName(fileName);
1918 if (!f.open(IO_WriteOnly))
1920 err("Cannot open file %s for writing!\n",fileName.data());
1923 f.writeBlock(compound_xsd,strlen(compound_xsd));
1926 fileName=outputDirectory+"/index.xml";
1927 f.setName(fileName);
1928 if (!f.open(IO_WriteOnly))
1930 err("Cannot open file %s for writing!\n",fileName.data());
1934 //t.setEncoding(FTextStream::UnicodeUTF8);
1936 // write index header
1937 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
1938 t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
1939 t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" ";
1940 t << "version=\"" << versionString << "\">" << endl;
1943 ClassSDict::Iterator cli(*Doxygen::classSDict);
1945 for (cli.toFirst();(cd=cli.current());++cli)
1947 generateXMLForClass(cd,t);
1951 // ClassSDict::Iterator cli(Doxygen::hiddenClasses);
1953 // for (cli.toFirst();(cd=cli.current());++cli)
1955 // msg("Generating XML output for class %s\n",cd->name().data());
1956 // generateXMLForClass(cd,t);
1959 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1961 for (nli.toFirst();(nd=nli.current());++nli)
1963 msg("Generating XML output for namespace %s\n",nd->name().data());
1964 generateXMLForNamespace(nd,t);
1966 FileNameListIterator fnli(*Doxygen::inputNameList);
1968 for (;(fn=fnli.current());++fnli)
1970 FileNameIterator fni(*fn);
1972 for (;(fd=fni.current());++fni)
1974 msg("Generating XML output for file %s\n",fd->name().data());
1975 generateXMLForFile(fd,t);
1978 GroupSDict::Iterator gli(*Doxygen::groupSDict);
1980 for (;(gd=gli.current());++gli)
1982 msg("Generating XML output for group %s\n",gd->name().data());
1983 generateXMLForGroup(gd,t);
1986 PageSDict::Iterator pdi(*Doxygen::pageSDict);
1988 for (pdi.toFirst();(pd=pdi.current());++pdi)
1990 msg("Generating XML output for page %s\n",pd->name().data());
1991 generateXMLForPage(pd,t,FALSE);
1996 DirSDict::Iterator sdi(*Doxygen::directories);
1997 for (sdi.toFirst();(dir=sdi.current());++sdi)
1999 msg("Generate XML output for dir %s\n",dir->name().data());
2000 generateXMLForDir(dir,t);
2004 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
2006 for (pdi.toFirst();(pd=pdi.current());++pdi)
2008 msg("Generating XML output for example %s\n",pd->name().data());
2009 generateXMLForPage(pd,t,TRUE);
2012 if (Doxygen::mainPage)
2014 msg("Generating XML output for the main page\n");
2015 generateXMLForPage(Doxygen::mainPage,t,FALSE);
2018 //t << " </compoundlist>" << endl;
2019 t << "</doxygenindex>" << endl;
2021 writeCombineScript();