1 /******************************************************************************
3 * Copyright (C) 1997-2014 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.
20 #include <qtextstream.h>
27 #include "classlist.h"
30 #include "outputgen.h"
35 #include "xmldocvisitor.h"
36 #include "docparser.h"
38 #include "parserintf.h"
39 #include "arguments.h"
40 #include "memberlist.h"
42 #include "memberdef.h"
43 #include "namespacedef.h"
44 #include "membername.h"
45 #include "membergroup.h"
48 #include "htmlentity.h"
51 #define XML_DB(x) do {} while(0)
53 //#define XML_DB(x) printf x
54 // debug inside output
55 //#define XML_DB(x) QCString __t;__t.sprintf x;m_t << __t
59 static const char index_xsd[] =
60 #include "index.xsd.h"
65 static const char compound_xsd[] =
66 #include "compound.xsd.h"
71 /** Helper class mapping MemberList::ListType to a string representing */
72 class XmlSectionMapper : public QIntDict<char>
75 XmlSectionMapper() : QIntDict<char>(47)
77 insert(MemberListType_pubTypes,"public-type");
78 insert(MemberListType_pubMethods,"public-func");
79 insert(MemberListType_pubAttribs,"public-attrib");
80 insert(MemberListType_pubSlots,"public-slot");
81 insert(MemberListType_signals,"signal");
82 insert(MemberListType_dcopMethods,"dcop-func");
83 insert(MemberListType_properties,"property");
84 insert(MemberListType_events,"event");
85 insert(MemberListType_interfaces,"interfaces");
86 insert(MemberListType_services,"services");
87 insert(MemberListType_pubStaticMethods,"public-static-func");
88 insert(MemberListType_pubStaticAttribs,"public-static-attrib");
89 insert(MemberListType_proTypes,"protected-type");
90 insert(MemberListType_proMethods,"protected-func");
91 insert(MemberListType_proAttribs,"protected-attrib");
92 insert(MemberListType_proSlots,"protected-slot");
93 insert(MemberListType_proStaticMethods,"protected-static-func");
94 insert(MemberListType_proStaticAttribs,"protected-static-attrib");
95 insert(MemberListType_pacTypes,"package-type");
96 insert(MemberListType_pacMethods,"package-func");
97 insert(MemberListType_pacAttribs,"package-attrib");
98 insert(MemberListType_pacStaticMethods,"package-static-func");
99 insert(MemberListType_pacStaticAttribs,"package-static-attrib");
100 insert(MemberListType_priTypes,"private-type");
101 insert(MemberListType_priMethods,"private-func");
102 insert(MemberListType_priAttribs,"private-attrib");
103 insert(MemberListType_priSlots,"private-slot");
104 insert(MemberListType_priStaticMethods,"private-static-func");
105 insert(MemberListType_priStaticAttribs,"private-static-attrib");
106 insert(MemberListType_friends,"friend");
107 insert(MemberListType_related,"related");
108 insert(MemberListType_decDefineMembers,"define");
109 insert(MemberListType_decProtoMembers,"prototype");
110 insert(MemberListType_decTypedefMembers,"typedef");
111 insert(MemberListType_decEnumMembers,"enum");
112 insert(MemberListType_decFuncMembers,"func");
113 insert(MemberListType_decVarMembers,"var");
117 static XmlSectionMapper g_xmlSectionMapper;
120 inline void writeXMLString(FTextStream &t,const char *s)
122 t << convertToXML(s);
125 inline void writeXMLCodeString(FTextStream &t,const char *s, int &col)
134 static int tabSize = Config_getInt("TAB_SIZE");
135 int spacesToNextTabStop = tabSize - (col%tabSize);
136 col+=spacesToNextTabStop;
137 while (spacesToNextTabStop--) t << "<sp/>";
140 case ' ': t << "<sp/>"; col++; break;
141 case '<': t << "<"; col++; break;
142 case '>': t << ">"; col++; break;
143 case '&': t << "&"; col++; break;
144 case '\'': t << "'"; col++; break;
145 case '"': t << """; col++; break;
146 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
147 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
148 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
149 case 27: case 28: case 29: case 30: case 31:
150 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
151 default: s=writeUtf8Char(t,s-1); col++; break;
157 static void writeXMLHeader(FTextStream &t)
159 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
160 t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
161 t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" ";
162 t << "version=\"" << versionString << "\">" << endl;
165 static void writeCombineScript()
167 QCString outputDirectory = Config_getString("XML_OUTPUT");
168 QCString fileName=outputDirectory+"/combine.xslt";
170 if (!f.open(IO_WriteOnly))
172 err("Cannot open file %s for writing!\n",fileName.data());
176 //t.setEncoding(FTextStream::UnicodeUTF8);
179 "<!-- XSLT script to combine the generated output into a single file. \n"
180 " If you have xsltproc you could use:\n"
181 " xsltproc combine.xslt index.xml >all.xml\n"
183 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
184 " <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n"
185 " <xsl:template match=\"/\">\n"
186 " <doxygen version=\"{doxygenindex/@version}\">\n"
187 " <!-- Load all doxgen generated xml files -->\n"
188 " <xsl:for-each select=\"doxygenindex/compound\">\n"
189 " <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n"
193 "</xsl:stylesheet>\n";
197 void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId,
198 const char *anchorId,const char *text,const char *tooltip)
200 t << "<ref refid=\"" << compoundId;
201 if (anchorId) t << "_1" << anchorId;
202 t << "\" kindref=\"";
203 if (anchorId) t << "member"; else t << "compound";
205 if (extRef) t << " external=\"" << extRef << "\"";
206 if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
208 writeXMLString(t,text);
212 /** Implements TextGeneratorIntf for an XML stream. */
213 class TextGeneratorXMLImpl : public TextGeneratorIntf
216 TextGeneratorXMLImpl(FTextStream &t): m_t(t) {}
217 void writeString(const char *s,bool /*keepSpaces*/) const
219 writeXMLString(m_t,s);
221 void writeBreak(int) const {}
222 void writeLink(const char *extRef,const char *file,
223 const char *anchor,const char *text
226 writeXMLLink(m_t,extRef,file,anchor,text,0);
233 /** Generator for producing XML formatted source code. */
234 class XMLCodeGenerator : public CodeOutputInterface
238 XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1),
239 m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE),
240 m_insideSpecialHL(FALSE) {}
241 virtual ~XMLCodeGenerator() { }
243 void codify(const char *text)
245 XML_DB(("(codify \"%s\")\n",text));
246 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
248 m_t << "<highlight class=\"normal\">";
249 m_normalHLNeedStartTag=FALSE;
251 writeXMLCodeString(m_t,text,col);
253 void writeCodeLink(const char *ref,const char *file,
254 const char *anchor,const char *name,
257 XML_DB(("(writeCodeLink)\n"));
258 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
260 m_t << "<highlight class=\"normal\">";
261 m_normalHLNeedStartTag=FALSE;
263 writeXMLLink(m_t,ref,file,anchor,name,tooltip);
266 void writeTooltip(const char *, const DocLinkInfo &, const char *,
267 const char *, const SourceLinkInfo &, const SourceLinkInfo &
270 XML_DB(("(writeToolTip)\n"));
272 void startCodeLine(bool)
274 XML_DB(("(startCodeLine)\n"));
276 if (m_lineNumber!=-1)
278 m_t << " lineno=\"" << m_lineNumber << "\"";
279 if (!m_refId.isEmpty())
281 m_t << " refid=\"" << m_refId << "\"";
284 m_t << " refkind=\"member\"";
288 m_t << " refkind=\"compound\"";
291 if (!m_external.isEmpty())
293 m_t << " external=\"" << m_external << "\"";
297 m_insideCodeLine=TRUE;
302 XML_DB(("(endCodeLine)\n"));
303 if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
305 m_t << "</highlight>";
306 m_normalHLNeedStartTag=TRUE;
308 m_t << "</codeline>" << endl; // non DocBook
311 m_external.resize(0);
312 m_insideCodeLine=FALSE;
314 void startFontClass(const char *colorClass)
316 XML_DB(("(startFontClass)\n"));
317 if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
319 m_t << "</highlight>";
320 m_normalHLNeedStartTag=TRUE;
322 m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
323 m_insideSpecialHL=TRUE;
327 XML_DB(("(endFontClass)\n"));
328 m_t << "</highlight>"; // non DocBook
329 m_insideSpecialHL=FALSE;
331 void writeCodeAnchor(const char *)
333 XML_DB(("(writeCodeAnchor)\n"));
335 void writeLineNumber(const char *extRef,const char *compId,
336 const char *anchorId,int l)
338 XML_DB(("(writeLineNumber)\n"));
339 // we remember the information provided here to use it
340 // at the <codeline> start tag.
345 if (anchorId) m_refId+=(QCString)"_1"+anchorId;
346 m_isMemberRef = anchorId!=0;
347 if (extRef) m_external=extRef;
350 void setCurrentDoc(Definition *,const char *,bool)
353 void addWord(const char *,bool)
359 if (m_insideCodeLine) endCodeLine();
370 bool m_insideCodeLine;
371 bool m_normalHLNeedStartTag;
372 bool m_insideSpecialHL;
376 static void writeTemplateArgumentList(ArgumentList *al,
383 indentStr.fill(' ',indent);
386 t << indentStr << "<templateparamlist>" << endl;
387 ArgumentListIterator ali(*al);
389 for (ali.toFirst();(a=ali.current());++ali)
391 t << indentStr << " <param>" << endl;
392 if (!a->type.isEmpty())
394 t << indentStr << " <type>";
395 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
396 t << "</type>" << endl;
398 if (!a->name.isEmpty())
400 t << indentStr << " <declname>" << a->name << "</declname>" << endl;
401 t << indentStr << " <defname>" << a->name << "</defname>" << endl;
403 if (!a->defval.isEmpty())
405 t << indentStr << " <defval>";
406 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
407 t << "</defval>" << endl;
409 t << indentStr << " </param>" << endl;
411 t << indentStr << "</templateparamlist>" << endl;
415 static void writeMemberTemplateLists(MemberDef *md,FTextStream &t)
417 ArgumentList *templMd = md->templateArguments();
418 if (templMd) // function template prefix
420 writeTemplateArgumentList(templMd,t,md->getClassDef(),md->getFileDef(),8);
424 static void writeTemplateList(ClassDef *cd,FTextStream &t)
426 writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
429 static void writeXMLDocBlock(FTextStream &t,
430 const QCString &fileName,
434 const QCString &text)
436 QCString stext = text.stripWhiteSpace();
437 if (stext.isEmpty()) return;
438 // convert the documentation string into an abstract syntax tree
439 DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
440 // create a code generator
441 XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
442 // create a parse tree visitor for XML
443 XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
445 root->accept(visitor);
453 void writeXMLCodeBlock(FTextStream &t,FileDef *fd)
455 ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
456 SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
457 pIntf->resetCodeParserState();
458 XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
459 pIntf->parseCode(*xmlGen, // codeOutIntf
461 fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
463 FALSE, // isExampleBlock
468 FALSE, // inlineFragement
470 TRUE // showLineNumbers
476 static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName)
478 QCString scope = rmd->getScopeString();
479 QCString name = rmd->name();
480 if (!scope.isEmpty() && scope!=def->name())
482 name.prepend(scope+getLanguageSpecificSeparator(rmd->getLanguage()));
484 t << " <" << tagName << " refid=\"";
485 t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\"";
486 if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
488 t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\"";
489 t << " startline=\"" << rmd->getStartBodyLine() << "\"";
490 if (rmd->getEndBodyLine()!=-1)
492 t << " endline=\"" << rmd->getEndBodyLine() << "\"";
495 t << ">" << convertToXML(name) << "</" << tagName << ">" << endl;
499 static void stripQualifiers(QCString &typeStr)
504 if (typeStr.stripPrefix("static "));
505 else if (typeStr.stripPrefix("virtual "));
506 else if (typeStr.stripPrefix("volatile "));
507 else if (typeStr=="virtual") typeStr="";
512 static QCString classOutputFileBase(ClassDef *cd)
514 //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
515 //if (inlineGroupedClasses && cd->partOfGroups()!=0)
516 return cd->getOutputFileBase();
518 // return cd->getOutputFileBase();
521 static QCString memberOutputFileBase(MemberDef *md)
523 //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
524 //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
525 // return md->getClassDef()->getXmlOutputFileBase();
527 // return md->getOutputFileBase();
528 return md->getOutputFileBase();
532 static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def)
535 // + declaration/definition arg lists
539 // + const/volatile specifiers
541 // + source definition
542 // + source references
543 // + source referenced by
545 // + template arguments
546 // (templateArguments(), definitionTemplateParameterLists())
549 // enum values are written as part of the enum
550 if (md->memberType()==MemberType_EnumValue) return;
551 if (md->isHidden()) return;
552 //if (md->name().at(0)=='@') return; // anonymous member
554 // group members are only visible in their group
555 //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
559 switch (md->memberType())
561 case MemberType_Define: memType="define"; break;
562 case MemberType_Function: memType="function"; isFunc=TRUE; break;
563 case MemberType_Variable: memType="variable"; break;
564 case MemberType_Typedef: memType="typedef"; break;
565 case MemberType_Enumeration: memType="enum"; break;
566 case MemberType_EnumValue: ASSERT(0); break;
567 case MemberType_Signal: memType="signal"; isFunc=TRUE; break;
568 case MemberType_Slot: memType="slot"; isFunc=TRUE; break;
569 case MemberType_Friend: memType="friend"; isFunc=TRUE; break;
570 case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break;
571 case MemberType_Property: memType="property"; break;
572 case MemberType_Event: memType="event"; break;
573 case MemberType_Interface: memType="interface"; break;
574 case MemberType_Service: memType="service"; break;
577 ti << " <member refid=\"" << memberOutputFileBase(md)
578 << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>"
579 << convertToXML(md->name()) << "</name></member>" << endl;
582 if (md->getClassDef())
583 scopeName=md->getClassDef()->name();
584 else if (md->getNamespaceDef())
585 scopeName=md->getNamespaceDef()->name();
587 t << " <memberdef kind=\"";
588 //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t;
589 t << memType << "\" id=\"";
590 if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
592 t << md->getGroupDef()->getOutputFileBase();
596 t << memberOutputFileBase(md);
598 t << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
601 switch(md->protection())
603 case Public: t << "public"; break;
604 case Protected: t << "protected"; break;
605 case Private: t << "private"; break;
606 case Package: t << "package"; break;
611 if (md->isStatic()) t << "yes"; else t << "no";
616 ArgumentList *al = md->argumentList();
618 if (al!=0 && al->constSpecifier) t << "yes"; else t << "no";
622 if (md->isExplicit()) t << "yes"; else t << "no";
626 if (md->isInline()) t << "yes"; else t << "no";
631 t << " final=\"yes\"";
636 t << " sealed=\"yes\"";
644 if (md->isOptional())
646 t << " optional=\"yes\"";
649 if (md->isRequired())
651 t << " required=\"yes\"";
654 if (al && al->volatileSpecifier)
656 t << " volatile=\"yes\"";
660 switch (md->virtualness())
662 case Normal: t << "non-virtual"; break;
663 case Virtual: t << "virtual"; break;
664 case Pure: t << "pure-virtual"; break;
670 if (md->memberType() == MemberType_Variable)
672 //ArgumentList *al = md->argumentList();
673 //t << " volatile=\"";
674 //if (al && al->volatileSpecifier) t << "yes"; else t << "no";
677 if (md->isMutable()) t << "yes"; else t << "no";
680 if (md->isInitonly())
682 t << " initonly=\"yes\"";
684 if (md->isAttribute())
686 t << " attribute=\"yes\"";
688 if (md->isUNOProperty())
690 t << " property=\"yes\"";
692 if (md->isReadonly())
694 t << " readonly=\"yes\"";
698 t << " bound=\"yes\"";
700 if (md->isRemovable())
702 t << " removable=\"yes\"";
704 if (md->isConstrained())
706 t << " constrained=\"yes\"";
708 if (md->isTransient())
710 t << " transient=\"yes\"";
712 if (md->isMaybeVoid())
714 t << " maybevoid=\"yes\"";
716 if (md->isMaybeDefault())
718 t << " maybedefault=\"yes\"";
720 if (md->isMaybeAmbiguous())
722 t << " maybeambiguous=\"yes\"";
725 else if (md->memberType() == MemberType_Property)
728 if (md->isReadable()) t << "yes"; else t << "no";
732 if (md->isWritable()) t << "yes"; else t << "no";
736 if (md->isGettable()) t << "yes"; else t << "no";
739 t << " privategettable=\"";
740 if (md->isPrivateGettable()) t << "yes"; else t << "no";
743 t << " protectedgettable=\"";
744 if (md->isProtectedGettable()) t << "yes"; else t << "no";
748 if (md->isSettable()) t << "yes"; else t << "no";
751 t << " privatesettable=\"";
752 if (md->isPrivateSettable()) t << "yes"; else t << "no";
755 t << " protectedsettable=\"";
756 if (md->isProtectedSettable()) t << "yes"; else t << "no";
759 if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak())
762 if (md->isAssign()) t << "assign";
763 else if (md->isCopy()) t << "copy";
764 else if (md->isRetain()) t << "retain";
765 else if (md->isStrong()) t << "strong";
766 else if (md->isWeak()) t << "weak";
770 else if (md->memberType() == MemberType_Event)
773 if (md->isAddable()) t << "yes"; else t << "no";
777 if (md->isRemovable()) t << "yes"; else t << "no";
781 if (md->isRaisable()) t << "yes"; else t << "no";
787 if (md->memberType()!=MemberType_Define &&
788 md->memberType()!=MemberType_Enumeration
791 if (md->memberType()!=MemberType_Typedef)
793 writeMemberTemplateLists(md,t);
795 QCString typeStr = md->typeString(); //replaceAnonymousScopes(md->typeString());
796 stripQualifiers(typeStr);
798 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,typeStr);
799 t << "</type>" << endl;
800 t << " <definition>" << convertToXML(md->definition()) << "</definition>" << endl;
801 t << " <argsstring>" << convertToXML(md->argsString()) << "</argsstring>" << endl;
804 t << " <name>" << convertToXML(md->name()) << "</name>" << endl;
806 if (md->memberType() == MemberType_Property)
808 if (md->isReadable())
809 t << " <read>" << convertToXML(md->getReadAccessor()) << "</read>" << endl;
810 if (md->isWritable())
811 t << " <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
813 if (md->memberType()==MemberType_Variable && md->bitfieldString())
815 QCString bitfield = md->bitfieldString();
816 if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
817 t << " <bitfield>" << bitfield << "</bitfield>" << endl;
820 MemberDef *rmd = md->reimplements();
823 t << " <reimplements refid=\""
824 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
825 << convertToXML(rmd->name()) << "</reimplements>" << endl;
827 MemberList *rbml = md->reimplementedBy();
830 MemberListIterator mli(*rbml);
831 for (mli.toFirst();(rmd=mli.current());++mli)
833 t << " <reimplementedby refid=\""
834 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
835 << convertToXML(rmd->name()) << "</reimplementedby>" << endl;
839 if (isFunc) //function
841 ArgumentList *declAl = md->declArgumentList();
842 ArgumentList *defAl = md->argumentList();
843 if (declAl && declAl->count()>0)
845 ArgumentListIterator declAli(*declAl);
846 ArgumentListIterator defAli(*defAl);
848 for (declAli.toFirst();(a=declAli.current());++declAli)
850 Argument *defArg = defAli.current();
851 t << " <param>" << endl;
852 if (!a->attrib.isEmpty())
854 t << " <attributes>";
855 writeXMLString(t,a->attrib);
856 t << "</attributes>" << endl;
858 if (!a->type.isEmpty())
861 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->type);
862 t << "</type>" << endl;
864 if (!a->name.isEmpty())
867 writeXMLString(t,a->name);
868 t << "</declname>" << endl;
870 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
873 writeXMLString(t,defArg->name);
874 t << "</defname>" << endl;
876 if (!a->array.isEmpty())
879 writeXMLString(t,a->array);
880 t << "</array>" << endl;
882 if (!a->defval.isEmpty())
885 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->defval);
886 t << "</defval>" << endl;
888 if (defArg && defArg->hasDocumentation())
890 t << " <briefdescription>";
891 writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),
892 md->getOuterScope(),md,defArg->docs);
893 t << "</briefdescription>" << endl;
895 t << " </param>" << endl;
896 if (defArg) ++defAli;
900 else if (md->memberType()==MemberType_Define &&
901 md->argsString()) // define
903 if (md->argumentList()->count()==0) // special case for "foo()" to
904 // disguish it from "foo".
906 t << " <param></param>" << endl;
910 ArgumentListIterator ali(*md->argumentList());
912 for (ali.toFirst();(a=ali.current());++ali)
914 t << " <param><defname>" << a->type << "</defname></param>" << endl;
919 if (md->hasOneLineInitializer() || md->hasMultiLineInitializer())
921 t << " <initializer>";
922 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->initializer());
923 t << "</initializer>" << endl;
926 if (md->excpString())
928 t << " <exceptions>";
929 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString());
930 t << "</exceptions>" << endl;
933 if (md->memberType()==MemberType_Enumeration) // enum
935 MemberList *enumFields = md->enumFieldList();
938 MemberListIterator emli(*enumFields);
940 for (emli.toFirst();(emd=emli.current());++emli)
942 ti << " <member refid=\"" << memberOutputFileBase(emd)
943 << "_1" << emd->anchor() << "\" kind=\"enumvalue\"><name>"
944 << convertToXML(emd->name()) << "</name></member>" << endl;
946 t << " <enumvalue id=\"" << memberOutputFileBase(emd) << "_1"
947 << emd->anchor() << "\" prot=\"";
948 switch (emd->protection())
950 case Public: t << "public"; break;
951 case Protected: t << "protected"; break;
952 case Private: t << "private"; break;
953 case Package: t << "package"; break;
957 writeXMLString(t,emd->name());
958 t << "</name>" << endl;
959 if (!emd->initializer().isEmpty())
961 t << " <initializer>";
962 writeXMLString(t,emd->initializer());
963 t << "</initializer>" << endl;
965 t << " <briefdescription>" << endl;
966 writeXMLDocBlock(t,emd->briefFile(),emd->briefLine(),emd->getOuterScope(),emd,emd->briefDescription());
967 t << " </briefdescription>" << endl;
968 t << " <detaileddescription>" << endl;
969 writeXMLDocBlock(t,emd->docFile(),emd->docLine(),emd->getOuterScope(),emd,emd->documentation());
970 t << " </detaileddescription>" << endl;
971 t << " </enumvalue>" << endl;
975 t << " <briefdescription>" << endl;
976 writeXMLDocBlock(t,md->briefFile(),md->briefLine(),md->getOuterScope(),md,md->briefDescription());
977 t << " </briefdescription>" << endl;
978 t << " <detaileddescription>" << endl;
979 writeXMLDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
980 t << " </detaileddescription>" << endl;
981 t << " <inbodydescription>" << endl;
982 writeXMLDocBlock(t,md->docFile(),md->inbodyLine(),md->getOuterScope(),md,md->inbodyDocumentation());
983 t << " </inbodydescription>" << endl;
984 if (md->getDefLine()!=-1)
986 t << " <location file=\""
987 << md->getDefFileName() << "\" line=\""
988 << md->getDefLine() << "\"" << " column=\""
989 << md->getDefColumn() << "\"" ;
990 if (md->getStartBodyLine()!=-1)
992 FileDef *bodyDef = md->getBodyDef();
995 t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
997 t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\""
998 << md->getEndBodyLine() << "\"";
1003 //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
1004 MemberSDict *mdict = md->getReferencesMembers();
1007 MemberSDict::Iterator mdi(*mdict);
1009 for (mdi.toFirst();(rmd=mdi.current());++mdi)
1011 writeMemberReference(t,def,rmd,"references");
1014 mdict = md->getReferencedByMembers();
1017 MemberSDict::Iterator mdi(*mdict);
1019 for (mdi.toFirst();(rmd=mdi.current());++mdi)
1021 writeMemberReference(t,def,rmd,"referencedby");
1025 t << " </memberdef>" << endl;
1028 static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t,
1029 MemberList *ml,const char *kind,const char *header=0,
1030 const char *documentation=0)
1033 MemberListIterator mli(*ml);
1036 for (mli.toFirst();(md=mli.current());++mli)
1038 // namespace members are also inserted in the file scope, but
1039 // to prevent this duplication in the XML output, we filter those here.
1040 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1045 if (count==0) return; // empty list
1047 t << " <sectiondef kind=\"" << kind << "\">" << endl;
1050 t << " <header>" << convertToXML(header) << "</header>" << endl;
1054 t << " <description>";
1055 writeXMLDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
1056 t << "</description>" << endl;
1058 for (mli.toFirst();(md=mli.current());++mli)
1060 // namespace members are also inserted in the file scope, but
1061 // to prevent this duplication in the XML output, we filter those here.
1062 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1064 generateXMLForMember(md,ti,t,d);
1067 t << " </sectiondef>" << endl;
1070 static void writeListOfAllMembers(ClassDef *cd,FTextStream &t)
1072 t << " <listofallmembers>" << endl;
1073 if (cd->memberNameInfoSDict())
1075 MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
1076 MemberNameInfo *mni;
1077 for (mnii.toFirst();(mni=mnii.current());++mnii)
1079 MemberNameInfoIterator mii(*mni);
1081 for (mii.toFirst();(mi=mii.current());++mii)
1083 MemberDef *md=mi->memberDef;
1084 if (md->name().at(0)!='@') // skip anonymous members
1086 Protection prot = mi->prot;
1087 Specifier virt=md->virtualness();
1088 t << " <member refid=\"" << memberOutputFileBase(md) << "_1" <<
1089 md->anchor() << "\" prot=\"";
1092 case Public: t << "public"; break;
1093 case Protected: t << "protected"; break;
1094 case Private: t << "private"; break;
1095 case Package: t << "package"; break;
1100 case Normal: t << "non-virtual"; break;
1101 case Virtual: t << "virtual"; break;
1102 case Pure: t << "pure-virtual"; break;
1105 if (!mi->ambiguityResolutionScope.isEmpty())
1107 t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\"";
1109 t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" <<
1110 convertToXML(md->name()) << "</name></member>" << endl;
1115 t << " </listofallmembers>" << endl;
1118 static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
1122 ClassSDict::Iterator cli(*cl);
1124 for (cli.toFirst();(cd=cli.current());++cli)
1126 if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
1128 t << " <innerclass refid=\"" << classOutputFileBase(cd)
1130 switch(cd->protection())
1132 case Public: t << "public"; break;
1133 case Protected: t << "protected"; break;
1134 case Private: t << "private"; break;
1135 case Package: t << "package"; break;
1137 t << "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
1143 static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
1147 NamespaceSDict::Iterator nli(*nl);
1149 for (nli.toFirst();(nd=nli.current());++nli)
1151 if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
1153 t << " <innernamespace refid=\"" << nd->getOutputFileBase()
1154 << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
1160 static void writeInnerFiles(const FileList *fl,FTextStream &t)
1164 QListIterator<FileDef> fli(*fl);
1166 for (fli.toFirst();(fd=fli.current());++fli)
1168 t << " <innerfile refid=\"" << fd->getOutputFileBase()
1169 << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl;
1174 static void writeInnerPages(const PageSDict *pl,FTextStream &t)
1178 PageSDict::Iterator pli(*pl);
1180 for (pli.toFirst();(pd=pli.current());++pli)
1182 t << " <innerpage refid=\"" << pd->getOutputFileBase();
1183 if (pd->getGroupDef())
1185 t << "_" << pd->name();
1187 t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
1192 static void writeInnerGroups(const GroupList *gl,FTextStream &t)
1196 GroupListIterator gli(*gl);
1198 for (gli.toFirst();(sgd=gli.current());++gli)
1200 t << " <innergroup refid=\"" << sgd->getOutputFileBase()
1201 << "\">" << convertToXML(sgd->groupTitle())
1202 << "</innergroup>" << endl;
1207 static void writeInnerDirs(const DirList *dl,FTextStream &t)
1211 QListIterator<DirDef> subdirs(*dl);
1213 for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
1215 t << " <innerdir refid=\"" << subdir->getOutputFileBase()
1216 << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl;
1221 static void generateXMLForClass(ClassDef *cd,FTextStream &ti)
1223 // + brief description
1224 // + detailed description
1225 // + template argument list(s)
1228 // + inheritance diagram
1229 // + list of direct super classes
1230 // + list of direct sub classes
1231 // + list of inner classes
1232 // + collaboration diagram
1233 // + list of all members
1234 // + user defined member sections
1235 // + standard member sections
1236 // + detailed member documentation
1237 // - examples using the class
1239 if (cd->isReference()) return; // skip external references.
1240 if (cd->isHidden()) return; // skip hidden classes.
1241 if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1242 if (cd->templateMaster()!=0) return; // skip generated template instances.
1243 if (cd->isArtificial()) return; // skip artificially created classes
1245 msg("Generating XML output for class %s\n",cd->name().data());
1247 ti << " <compound refid=\"" << classOutputFileBase(cd)
1248 << "\" kind=\"" << cd->compoundTypeString()
1249 << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
1251 QCString outputDirectory = Config_getString("XML_OUTPUT");
1252 QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
1254 if (!f.open(IO_WriteOnly))
1256 err("Cannot open file %s for writing!\n",fileName.data());
1260 //t.setEncoding(FTextStream::UnicodeUTF8);
1263 t << " <compounddef id=\""
1264 << classOutputFileBase(cd) << "\" kind=\""
1265 << cd->compoundTypeString() << "\" prot=\"";
1266 switch (cd->protection())
1268 case Public: t << "public"; break;
1269 case Protected: t << "protected"; break;
1270 case Private: t << "private"; break;
1271 case Package: t << "package"; break;
1273 if (cd->isFinal()) t << "\" final=\"yes";
1274 if (cd->isSealed()) t << "\" sealed=\"yes";
1275 if (cd->isAbstract()) t << "\" abstract=\"yes";
1277 t << " <compoundname>";
1278 writeXMLString(t,cd->name());
1279 t << "</compoundname>" << endl;
1280 if (cd->baseClasses())
1282 BaseClassListIterator bcli(*cd->baseClasses());
1284 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1286 t << " <basecompoundref ";
1287 if (bcd->classDef->isLinkable())
1289 t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
1294 case Public: t << "public"; break;
1295 case Protected: t << "protected"; break;
1296 case Private: t << "private"; break;
1297 case Package: ASSERT(0); break;
1302 case Normal: t << "non-virtual"; break;
1303 case Virtual: t << "virtual"; break;
1304 case Pure: t <<"pure-virtual"; break;
1307 if (!bcd->templSpecifiers.isEmpty())
1310 insertTemplateSpecifierInScope(
1311 bcd->classDef->name(),bcd->templSpecifiers)
1316 t << convertToXML(bcd->classDef->displayName());
1318 t << "</basecompoundref>" << endl;
1321 if (cd->subClasses())
1323 BaseClassListIterator bcli(*cd->subClasses());
1325 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1327 t << " <derivedcompoundref refid=\""
1328 << classOutputFileBase(bcd->classDef)
1332 case Public: t << "public"; break;
1333 case Protected: t << "protected"; break;
1334 case Private: t << "private"; break;
1335 case Package: ASSERT(0); break;
1340 case Normal: t << "non-virtual"; break;
1341 case Virtual: t << "virtual"; break;
1342 case Pure: t << "pure-virtual"; break;
1344 t << "\">" << convertToXML(bcd->classDef->displayName())
1345 << "</derivedcompoundref>" << endl;
1349 IncludeInfo *ii=cd->includeInfo();
1352 QCString nm = ii->includeName;
1353 if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1357 if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
1359 t << " refid=\"" << ii->fileDef->getOutputFileBase() << "\"";
1361 t << " local=\"" << (ii->local ? "yes" : "no") << "\">";
1363 t << "</includes>" << endl;
1367 writeInnerClasses(cd->getClassSDict(),t);
1369 writeTemplateList(cd,t);
1370 if (cd->getMemberGroupSDict())
1372 MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
1374 for (;(mg=mgli.current());++mgli)
1376 generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
1377 mg->documentation());
1381 QListIterator<MemberList> mli(cd->getMemberLists());
1383 for (mli.toFirst();(ml=mli.current());++mli)
1385 if ((ml->listType()&MemberListType_detailedLists)==0)
1387 generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1391 generateXMLSection(cd,ti,t,cd->pubTypes,"public-type");
1392 generateXMLSection(cd,ti,t,cd->pubMethods,"public-func");
1393 generateXMLSection(cd,ti,t,cd->pubAttribs,"public-attrib");
1394 generateXMLSection(cd,ti,t,cd->pubSlots,"public-slot");
1395 generateXMLSection(cd,ti,t,cd->signals,"signal");
1396 generateXMLSection(cd,ti,t,cd->dcopMethods,"dcop-func");
1397 generateXMLSection(cd,ti,t,cd->properties,"property");
1398 generateXMLSection(cd,ti,t,cd->events,"event");
1399 generateXMLSection(cd,ti,t,cd->pubStaticMethods,"public-static-func");
1400 generateXMLSection(cd,ti,t,cd->pubStaticAttribs,"public-static-attrib");
1401 generateXMLSection(cd,ti,t,cd->proTypes,"protected-type");
1402 generateXMLSection(cd,ti,t,cd->proMethods,"protected-func");
1403 generateXMLSection(cd,ti,t,cd->proAttribs,"protected-attrib");
1404 generateXMLSection(cd,ti,t,cd->proSlots,"protected-slot");
1405 generateXMLSection(cd,ti,t,cd->proStaticMethods,"protected-static-func");
1406 generateXMLSection(cd,ti,t,cd->proStaticAttribs,"protected-static-attrib");
1407 generateXMLSection(cd,ti,t,cd->pacTypes,"package-type");
1408 generateXMLSection(cd,ti,t,cd->pacMethods,"package-func");
1409 generateXMLSection(cd,ti,t,cd->pacAttribs,"package-attrib");
1410 generateXMLSection(cd,ti,t,cd->pacStaticMethods,"package-static-func");
1411 generateXMLSection(cd,ti,t,cd->pacStaticAttribs,"package-static-attrib");
1412 generateXMLSection(cd,ti,t,cd->priTypes,"private-type");
1413 generateXMLSection(cd,ti,t,cd->priMethods,"private-func");
1414 generateXMLSection(cd,ti,t,cd->priAttribs,"private-attrib");
1415 generateXMLSection(cd,ti,t,cd->priSlots,"private-slot");
1416 generateXMLSection(cd,ti,t,cd->priStaticMethods,"private-static-func");
1417 generateXMLSection(cd,ti,t,cd->priStaticAttribs,"private-static-attrib");
1418 generateXMLSection(cd,ti,t,cd->friends,"friend");
1419 generateXMLSection(cd,ti,t,cd->related,"related");
1422 t << " <briefdescription>" << endl;
1423 writeXMLDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
1424 t << " </briefdescription>" << endl;
1425 t << " <detaileddescription>" << endl;
1426 writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
1427 t << " </detaileddescription>" << endl;
1428 DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
1429 if (!inheritanceGraph.isTrivial())
1431 t << " <inheritancegraph>" << endl;
1432 inheritanceGraph.writeXML(t);
1433 t << " </inheritancegraph>" << endl;
1435 DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
1436 if (!collaborationGraph.isTrivial())
1438 t << " <collaborationgraph>" << endl;
1439 collaborationGraph.writeXML(t);
1440 t << " </collaborationgraph>" << endl;
1442 t << " <location file=\""
1443 << cd->getDefFileName() << "\" line=\""
1444 << cd->getDefLine() << "\"" << " column=\""
1445 << cd->getDefColumn() << "\"" ;
1446 if (cd->getStartBodyLine()!=-1)
1448 FileDef *bodyDef = cd->getBodyDef();
1451 t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
1453 t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
1454 << cd->getEndBodyLine() << "\"";
1457 writeListOfAllMembers(cd,t);
1458 t << " </compounddef>" << endl;
1459 t << "</doxygen>" << endl;
1461 ti << " </compound>" << endl;
1464 static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti)
1466 // + contained class definitions
1467 // + contained namespace definitions
1473 // - files containing (parts of) the namespace definition
1475 if (nd->isReference() || nd->isHidden()) return; // skip external references
1477 ti << " <compound refid=\"" << nd->getOutputFileBase()
1478 << "\" kind=\"namespace\"" << "><name>"
1479 << convertToXML(nd->name()) << "</name>" << endl;
1481 QCString outputDirectory = Config_getString("XML_OUTPUT");
1482 QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
1484 if (!f.open(IO_WriteOnly))
1486 err("Cannot open file %s for writing!\n",fileName.data());
1490 //t.setEncoding(FTextStream::UnicodeUTF8);
1493 t << " <compounddef id=\""
1494 << nd->getOutputFileBase() << "\" kind=\"namespace\">" << endl;
1495 t << " <compoundname>";
1496 writeXMLString(t,nd->name());
1497 t << "</compoundname>" << endl;
1499 writeInnerClasses(nd->getClassSDict(),t);
1500 writeInnerNamespaces(nd->getNamespaceSDict(),t);
1502 if (nd->getMemberGroupSDict())
1504 MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
1506 for (;(mg=mgli.current());++mgli)
1508 generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
1509 mg->documentation());
1513 QListIterator<MemberList> mli(nd->getMemberLists());
1515 for (mli.toFirst();(ml=mli.current());++mli)
1517 if ((ml->listType()&MemberListType_declarationLists)!=0)
1519 generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1523 generateXMLSection(nd,ti,t,&nd->decDefineMembers,"define");
1524 generateXMLSection(nd,ti,t,&nd->decProtoMembers,"prototype");
1525 generateXMLSection(nd,ti,t,&nd->decTypedefMembers,"typedef");
1526 generateXMLSection(nd,ti,t,&nd->decEnumMembers,"enum");
1527 generateXMLSection(nd,ti,t,&nd->decFuncMembers,"func");
1528 generateXMLSection(nd,ti,t,&nd->decVarMembers,"var");
1531 t << " <briefdescription>" << endl;
1532 writeXMLDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
1533 t << " </briefdescription>" << endl;
1534 t << " <detaileddescription>" << endl;
1535 writeXMLDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
1536 t << " </detaileddescription>" << endl;
1537 t << " <location file=\""
1538 << nd->getDefFileName() << "\" line=\""
1539 << nd->getDefLine() << "\"" << " column=\""
1540 << nd->getDefColumn() << "\"/>" << endl ;
1541 t << " </compounddef>" << endl;
1542 t << "</doxygen>" << endl;
1544 ti << " </compound>" << endl;
1547 static void generateXMLForFile(FileDef *fd,FTextStream &ti)
1550 // + includedby files
1552 // + included by graph
1553 // + contained class definitions
1554 // + contained namespace definitions
1561 // - number of lines
1563 if (fd->isReference()) return; // skip external references
1565 ti << " <compound refid=\"" << fd->getOutputFileBase()
1566 << "\" kind=\"file\"><name>" << convertToXML(fd->name())
1567 << "</name>" << endl;
1569 QCString outputDirectory = Config_getString("XML_OUTPUT");
1570 QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
1572 if (!f.open(IO_WriteOnly))
1574 err("Cannot open file %s for writing!\n",fileName.data());
1578 //t.setEncoding(FTextStream::UnicodeUTF8);
1581 t << " <compounddef id=\""
1582 << fd->getOutputFileBase() << "\" kind=\"file\">" << endl;
1583 t << " <compoundname>";
1584 writeXMLString(t,fd->name());
1585 t << "</compoundname>" << endl;
1589 if (fd->includeFileList())
1591 QListIterator<IncludeInfo> ili1(*fd->includeFileList());
1592 for (ili1.toFirst();(inc=ili1.current());++ili1)
1595 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1597 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1599 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1600 t << inc->includeName;
1601 t << "</includes>" << endl;
1605 if (fd->includedByFileList())
1607 QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
1608 for (ili2.toFirst();(inc=ili2.current());++ili2)
1610 t << " <includedby";
1611 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1613 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1615 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1616 t << inc->includeName;
1617 t << "</includedby>" << endl;
1621 DotInclDepGraph incDepGraph(fd,FALSE);
1622 if (!incDepGraph.isTrivial())
1624 t << " <incdepgraph>" << endl;
1625 incDepGraph.writeXML(t);
1626 t << " </incdepgraph>" << endl;
1629 DotInclDepGraph invIncDepGraph(fd,TRUE);
1630 if (!invIncDepGraph.isTrivial())
1632 t << " <invincdepgraph>" << endl;
1633 invIncDepGraph.writeXML(t);
1634 t << " </invincdepgraph>" << endl;
1637 if (fd->getClassSDict())
1639 writeInnerClasses(fd->getClassSDict(),t);
1641 if (fd->getNamespaceSDict())
1643 writeInnerNamespaces(fd->getNamespaceSDict(),t);
1646 if (fd->getMemberGroupSDict())
1648 MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
1650 for (;(mg=mgli.current());++mgli)
1652 generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
1653 mg->documentation());
1657 QListIterator<MemberList> mli(fd->getMemberLists());
1659 for (mli.toFirst();(ml=mli.current());++mli)
1661 if ((ml->listType()&MemberListType_declarationLists)!=0)
1663 generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1667 generateXMLSection(fd,ti,t,fd->decDefineMembers,"define");
1668 generateXMLSection(fd,ti,t,fd->decProtoMembers,"prototype");
1669 generateXMLSection(fd,ti,t,fd->decTypedefMembers,"typedef");
1670 generateXMLSection(fd,ti,t,fd->decEnumMembers,"enum");
1671 generateXMLSection(fd,ti,t,fd->decFuncMembers,"func");
1672 generateXMLSection(fd,ti,t,fd->decVarMembers,"var");
1675 t << " <briefdescription>" << endl;
1676 writeXMLDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
1677 t << " </briefdescription>" << endl;
1678 t << " <detaileddescription>" << endl;
1679 writeXMLDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
1680 t << " </detaileddescription>" << endl;
1681 if (Config_getBool("XML_PROGRAMLISTING"))
1683 t << " <programlisting>" << endl;
1684 writeXMLCodeBlock(t,fd);
1685 t << " </programlisting>" << endl;
1687 t << " <location file=\"" << fd->getDefFileName() << "\"/>" << endl;
1688 t << " </compounddef>" << endl;
1689 t << "</doxygen>" << endl;
1691 ti << " </compound>" << endl;
1694 static void generateXMLForGroup(GroupDef *gd,FTextStream &ti)
1705 // + brief description
1706 // + detailed description
1708 if (gd->isReference()) return; // skip external references
1710 ti << " <compound refid=\"" << gd->getOutputFileBase()
1711 << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
1713 QCString outputDirectory = Config_getString("XML_OUTPUT");
1714 QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
1716 if (!f.open(IO_WriteOnly))
1718 err("Cannot open file %s for writing!\n",fileName.data());
1723 //t.setEncoding(FTextStream::UnicodeUTF8);
1725 t << " <compounddef id=\""
1726 << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
1727 t << " <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
1728 t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
1730 writeInnerFiles(gd->getFiles(),t);
1731 writeInnerClasses(gd->getClasses(),t);
1732 writeInnerNamespaces(gd->getNamespaces(),t);
1733 writeInnerPages(gd->getPages(),t);
1734 writeInnerGroups(gd->getSubGroups(),t);
1736 if (gd->getMemberGroupSDict())
1738 MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
1740 for (;(mg=mgli.current());++mgli)
1742 generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
1743 mg->documentation());
1747 QListIterator<MemberList> mli(gd->getMemberLists());
1749 for (mli.toFirst();(ml=mli.current());++mli)
1751 if ((ml->listType()&MemberListType_declarationLists)!=0)
1753 generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1757 generateXMLSection(gd,ti,t,&gd->decDefineMembers,"define");
1758 generateXMLSection(gd,ti,t,&gd->decProtoMembers,"prototype");
1759 generateXMLSection(gd,ti,t,&gd->decTypedefMembers,"typedef");
1760 generateXMLSection(gd,ti,t,&gd->decEnumMembers,"enum");
1761 generateXMLSection(gd,ti,t,&gd->decFuncMembers,"func");
1762 generateXMLSection(gd,ti,t,&gd->decVarMembers,"var");
1765 t << " <briefdescription>" << endl;
1766 writeXMLDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
1767 t << " </briefdescription>" << endl;
1768 t << " <detaileddescription>" << endl;
1769 writeXMLDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
1770 t << " </detaileddescription>" << endl;
1771 t << " </compounddef>" << endl;
1772 t << "</doxygen>" << endl;
1774 ti << " </compound>" << endl;
1777 static void generateXMLForDir(DirDef *dd,FTextStream &ti)
1779 if (dd->isReference()) return; // skip external references
1780 ti << " <compound refid=\"" << dd->getOutputFileBase()
1781 << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName())
1782 << "</name>" << endl;
1784 QCString outputDirectory = Config_getString("XML_OUTPUT");
1785 QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
1787 if (!f.open(IO_WriteOnly))
1789 err("Cannot open file %s for writing!\n",fileName.data());
1794 //t.setEncoding(FTextStream::UnicodeUTF8);
1796 t << " <compounddef id=\""
1797 << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl;
1798 t << " <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl;
1800 writeInnerDirs(&dd->subDirs(),t);
1801 writeInnerFiles(dd->getFiles(),t);
1803 t << " <briefdescription>" << endl;
1804 writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
1805 t << " </briefdescription>" << endl;
1806 t << " <detaileddescription>" << endl;
1807 writeXMLDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
1808 t << " </detaileddescription>" << endl;
1809 t << " <location file=\"" << dd->name() << "\"/>" << endl;
1810 t << " </compounddef>" << endl;
1811 t << "</doxygen>" << endl;
1813 ti << " </compound>" << endl;
1816 static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
1822 const char *kindName = isExample ? "example" : "page";
1824 if (pd->isReference()) return;
1826 QCString pageName = pd->getOutputFileBase();
1827 if (pd->getGroupDef())
1829 pageName+=(QCString)"_"+pd->name();
1831 if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
1833 ti << " <compound refid=\"" << pageName
1834 << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name())
1835 << "</name>" << endl;
1837 QCString outputDirectory = Config_getString("XML_OUTPUT");
1838 QCString fileName=outputDirectory+"/"+pageName+".xml";
1840 if (!f.open(IO_WriteOnly))
1842 err("Cannot open file %s for writing!\n",fileName.data());
1847 //t.setEncoding(FTextStream::UnicodeUTF8);
1849 t << " <compounddef id=\"" << pageName;
1850 t << "\" kind=\"" << kindName << "\">" << endl;
1851 t << " <compoundname>" << convertToXML(pd->name())
1852 << "</compoundname>" << endl;
1854 if (pd==Doxygen::mainPage) // main page is special
1857 if (!pd->title().isEmpty() && pd->title().lower()!="notitle")
1859 title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()));
1863 title = Config_getString("PROJECT_NAME");
1865 t << " <title>" << convertToXML(convertCharEntitiesToUTF8(title))
1866 << "</title>" << endl;
1870 SectionInfo *si = Doxygen::sectionDict->find(pd->name());
1873 t << " <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title)))
1874 << "</title>" << endl;
1877 writeInnerPages(pd->getSubPages(),t);
1878 t << " <detaileddescription>" << endl;
1881 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1882 pd->documentation()+"\n\\include "+pd->name());
1886 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1887 pd->documentation());
1889 t << " </detaileddescription>" << endl;
1891 t << " </compounddef>" << endl;
1892 t << "</doxygen>" << endl;
1894 ti << " </compound>" << endl;
1906 QCString outputDirectory = Config_getString("XML_OUTPUT");
1907 QDir xmlDir(outputDirectory);
1908 createSubDirs(xmlDir);
1909 QCString fileName=outputDirectory+"/index.xsd";
1911 if (!f.open(IO_WriteOnly))
1913 err("Cannot open file %s for writing!\n",fileName.data());
1916 f.writeBlock(index_xsd,qstrlen(index_xsd));
1919 fileName=outputDirectory+"/compound.xsd";
1920 f.setName(fileName);
1921 if (!f.open(IO_WriteOnly))
1923 err("Cannot open file %s for writing!\n",fileName.data());
1927 // write compound.xsd, but replace special marker with the entities
1928 const char *startLine = compound_xsd;
1931 // find end of the line
1932 const char *endLine = startLine+1;
1933 while (*endLine && *(endLine-1)!='\n') endLine++; // skip to end of the line including \n
1934 int len=endLine-startLine;
1938 qstrncpy(s.data(),startLine,len);
1940 if (s.find("<!-- Automatically insert here the HTML entities -->")!=-1)
1943 HtmlEntityMapper::instance()->writeXMLSchema(t);
1947 f.writeBlock(startLine,len);
1954 fileName=outputDirectory+"/index.xml";
1955 f.setName(fileName);
1956 if (!f.open(IO_WriteOnly))
1958 err("Cannot open file %s for writing!\n",fileName.data());
1962 //t.setEncoding(FTextStream::UnicodeUTF8);
1964 // write index header
1965 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
1966 t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
1967 t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" ";
1968 t << "version=\"" << versionString << "\">" << endl;
1971 ClassSDict::Iterator cli(*Doxygen::classSDict);
1973 for (cli.toFirst();(cd=cli.current());++cli)
1975 generateXMLForClass(cd,t);
1979 // ClassSDict::Iterator cli(Doxygen::hiddenClasses);
1981 // for (cli.toFirst();(cd=cli.current());++cli)
1983 // msg("Generating XML output for class %s\n",cd->name().data());
1984 // generateXMLForClass(cd,t);
1987 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1989 for (nli.toFirst();(nd=nli.current());++nli)
1991 msg("Generating XML output for namespace %s\n",nd->name().data());
1992 generateXMLForNamespace(nd,t);
1994 FileNameListIterator fnli(*Doxygen::inputNameList);
1996 for (;(fn=fnli.current());++fnli)
1998 FileNameIterator fni(*fn);
2000 for (;(fd=fni.current());++fni)
2002 msg("Generating XML output for file %s\n",fd->name().data());
2003 generateXMLForFile(fd,t);
2006 GroupSDict::Iterator gli(*Doxygen::groupSDict);
2008 for (;(gd=gli.current());++gli)
2010 msg("Generating XML output for group %s\n",gd->name().data());
2011 generateXMLForGroup(gd,t);
2014 PageSDict::Iterator pdi(*Doxygen::pageSDict);
2016 for (pdi.toFirst();(pd=pdi.current());++pdi)
2018 msg("Generating XML output for page %s\n",pd->name().data());
2019 generateXMLForPage(pd,t,FALSE);
2024 DirSDict::Iterator sdi(*Doxygen::directories);
2025 for (sdi.toFirst();(dir=sdi.current());++sdi)
2027 msg("Generate XML output for dir %s\n",dir->name().data());
2028 generateXMLForDir(dir,t);
2032 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
2034 for (pdi.toFirst();(pd=pdi.current());++pdi)
2036 msg("Generating XML output for example %s\n",pd->name().data());
2037 generateXMLForPage(pd,t,TRUE);
2040 if (Doxygen::mainPage)
2042 msg("Generating XML output for the main page\n");
2043 generateXMLForPage(Doxygen::mainPage,t,FALSE);
2046 //t << " </compoundlist>" << endl;
2047 t << "</doxygenindex>" << endl;
2049 writeCombineScript();