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 default: s=writeUtf8Char(t,s-1); col++; break;
152 static void writeXMLHeader(FTextStream &t)
154 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
155 t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
156 t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" ";
157 t << "version=\"" << versionString << "\">" << endl;
160 static void writeCombineScript()
162 QCString outputDirectory = Config_getString("XML_OUTPUT");
163 QCString fileName=outputDirectory+"/combine.xslt";
165 if (!f.open(IO_WriteOnly))
167 err("Cannot open file %s for writing!\n",fileName.data());
171 //t.setEncoding(FTextStream::UnicodeUTF8);
174 "<!-- XSLT script to combine the generated output into a single file. \n"
175 " If you have xsltproc you could use:\n"
176 " xsltproc combine.xslt index.xml >all.xml\n"
178 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
179 " <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n"
180 " <xsl:template match=\"/\">\n"
181 " <doxygen version=\"{doxygenindex/@version}\">\n"
182 " <!-- Load all doxgen generated xml files -->\n"
183 " <xsl:for-each select=\"doxygenindex/compound\">\n"
184 " <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n"
188 "</xsl:stylesheet>\n";
192 void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId,
193 const char *anchorId,const char *text,const char *tooltip)
195 t << "<ref refid=\"" << compoundId;
196 if (anchorId) t << "_1" << anchorId;
197 t << "\" kindref=\"";
198 if (anchorId) t << "member"; else t << "compound";
200 if (extRef) t << " external=\"" << extRef << "\"";
201 if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
203 writeXMLString(t,text);
207 /** Implements TextGeneratorIntf for an XML stream. */
208 class TextGeneratorXMLImpl : public TextGeneratorIntf
211 TextGeneratorXMLImpl(FTextStream &t): m_t(t) {}
212 void writeString(const char *s,bool /*keepSpaces*/) const
214 writeXMLString(m_t,s);
216 void writeBreak(int) const {}
217 void writeLink(const char *extRef,const char *file,
218 const char *anchor,const char *text
221 writeXMLLink(m_t,extRef,file,anchor,text,0);
228 /** Generator for producing XML formatted source code. */
229 class XMLCodeGenerator : public CodeOutputInterface
233 XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1),
234 m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE),
235 m_insideSpecialHL(FALSE) {}
236 virtual ~XMLCodeGenerator() { }
238 void codify(const char *text)
240 XML_DB(("(codify \"%s\")\n",text));
241 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
243 m_t << "<highlight class=\"normal\">";
244 m_normalHLNeedStartTag=FALSE;
246 writeXMLCodeString(m_t,text,col);
248 void writeCodeLink(const char *ref,const char *file,
249 const char *anchor,const char *name,
252 XML_DB(("(writeCodeLink)\n"));
253 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
255 m_t << "<highlight class=\"normal\">";
256 m_normalHLNeedStartTag=FALSE;
258 writeXMLLink(m_t,ref,file,anchor,name,tooltip);
261 void writeTooltip(const char *, const DocLinkInfo &, const char *,
262 const char *, const SourceLinkInfo &, const SourceLinkInfo &
265 XML_DB(("(writeToolTip)\n"));
267 void startCodeLine(bool)
269 XML_DB(("(startCodeLine)\n"));
271 if (m_lineNumber!=-1)
273 m_t << " lineno=\"" << m_lineNumber << "\"";
274 if (!m_refId.isEmpty())
276 m_t << " refid=\"" << m_refId << "\"";
279 m_t << " refkind=\"member\"";
283 m_t << " refkind=\"compound\"";
286 if (!m_external.isEmpty())
288 m_t << " external=\"" << m_external << "\"";
292 m_insideCodeLine=TRUE;
297 XML_DB(("(endCodeLine)\n"));
298 if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
300 m_t << "</highlight>";
301 m_normalHLNeedStartTag=TRUE;
303 m_t << "</codeline>" << endl; // non DocBook
306 m_external.resize(0);
307 m_insideCodeLine=FALSE;
309 void startFontClass(const char *colorClass)
311 XML_DB(("(startFontClass)\n"));
312 if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
314 m_t << "</highlight>";
315 m_normalHLNeedStartTag=TRUE;
317 m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
318 m_insideSpecialHL=TRUE;
322 XML_DB(("(endFontClass)\n"));
323 m_t << "</highlight>"; // non DocBook
324 m_insideSpecialHL=FALSE;
326 void writeCodeAnchor(const char *)
328 XML_DB(("(writeCodeAnchor)\n"));
330 void writeLineNumber(const char *extRef,const char *compId,
331 const char *anchorId,int l)
333 XML_DB(("(writeLineNumber)\n"));
334 // we remember the information provided here to use it
335 // at the <codeline> start tag.
340 if (anchorId) m_refId+=(QCString)"_1"+anchorId;
341 m_isMemberRef = anchorId!=0;
342 if (extRef) m_external=extRef;
345 void setCurrentDoc(Definition *,const char *,bool)
348 void addWord(const char *,bool)
354 if (m_insideCodeLine) endCodeLine();
365 bool m_insideCodeLine;
366 bool m_normalHLNeedStartTag;
367 bool m_insideSpecialHL;
371 static void writeTemplateArgumentList(ArgumentList *al,
378 indentStr.fill(' ',indent);
381 t << indentStr << "<templateparamlist>" << endl;
382 ArgumentListIterator ali(*al);
384 for (ali.toFirst();(a=ali.current());++ali)
386 t << indentStr << " <param>" << endl;
387 if (!a->type.isEmpty())
389 t << indentStr << " <type>";
390 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
391 t << "</type>" << endl;
393 if (!a->name.isEmpty())
395 t << indentStr << " <declname>" << a->name << "</declname>" << endl;
396 t << indentStr << " <defname>" << a->name << "</defname>" << endl;
398 if (!a->defval.isEmpty())
400 t << indentStr << " <defval>";
401 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
402 t << "</defval>" << endl;
404 t << indentStr << " </param>" << endl;
406 t << indentStr << "</templateparamlist>" << endl;
410 static void writeMemberTemplateLists(MemberDef *md,FTextStream &t)
412 ArgumentList *templMd = md->templateArguments();
413 if (templMd) // function template prefix
415 writeTemplateArgumentList(templMd,t,md->getClassDef(),md->getFileDef(),8);
419 static void writeTemplateList(ClassDef *cd,FTextStream &t)
421 writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
424 static void writeXMLDocBlock(FTextStream &t,
425 const QCString &fileName,
429 const QCString &text)
431 QCString stext = text.stripWhiteSpace();
432 if (stext.isEmpty()) return;
433 // convert the documentation string into an abstract syntax tree
434 DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
435 // create a code generator
436 XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
437 // create a parse tree visitor for XML
438 XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
440 root->accept(visitor);
448 void writeXMLCodeBlock(FTextStream &t,FileDef *fd)
450 ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
451 SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
452 pIntf->resetCodeParserState();
453 XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
454 pIntf->parseCode(*xmlGen, // codeOutIntf
456 fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")),
458 FALSE, // isExampleBlock
463 FALSE, // inlineFragement
465 TRUE // showLineNumbers
471 static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName)
473 QCString scope = rmd->getScopeString();
474 QCString name = rmd->name();
475 if (!scope.isEmpty() && scope!=def->name())
477 name.prepend(scope+getLanguageSpecificSeparator(rmd->getLanguage()));
479 t << " <" << tagName << " refid=\"";
480 t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\"";
481 if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
483 t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\"";
484 t << " startline=\"" << rmd->getStartBodyLine() << "\"";
485 if (rmd->getEndBodyLine()!=-1)
487 t << " endline=\"" << rmd->getEndBodyLine() << "\"";
490 t << ">" << convertToXML(name) << "</" << tagName << ">" << endl;
494 static void stripQualifiers(QCString &typeStr)
499 if (typeStr.stripPrefix("static "));
500 else if (typeStr.stripPrefix("virtual "));
501 else if (typeStr.stripPrefix("volatile "));
502 else if (typeStr=="virtual") typeStr="";
507 static QCString classOutputFileBase(ClassDef *cd)
509 //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
510 //if (inlineGroupedClasses && cd->partOfGroups()!=0)
511 return cd->getOutputFileBase();
513 // return cd->getOutputFileBase();
516 static QCString memberOutputFileBase(MemberDef *md)
518 //static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
519 //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
520 // return md->getClassDef()->getXmlOutputFileBase();
522 // return md->getOutputFileBase();
523 return md->getOutputFileBase();
527 static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def)
530 // + declaration/definition arg lists
534 // + const/volatile specifiers
536 // + source definition
537 // + source references
538 // + source referenced by
540 // + template arguments
541 // (templateArguments(), definitionTemplateParameterLists())
544 // enum values are written as part of the enum
545 if (md->memberType()==MemberType_EnumValue) return;
546 if (md->isHidden()) return;
547 //if (md->name().at(0)=='@') return; // anonymous member
549 // group members are only visible in their group
550 //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
554 switch (md->memberType())
556 case MemberType_Define: memType="define"; break;
557 case MemberType_Function: memType="function"; isFunc=TRUE; break;
558 case MemberType_Variable: memType="variable"; break;
559 case MemberType_Typedef: memType="typedef"; break;
560 case MemberType_Enumeration: memType="enum"; break;
561 case MemberType_EnumValue: ASSERT(0); break;
562 case MemberType_Signal: memType="signal"; isFunc=TRUE; break;
563 case MemberType_Slot: memType="slot"; isFunc=TRUE; break;
564 case MemberType_Friend: memType="friend"; isFunc=TRUE; break;
565 case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break;
566 case MemberType_Property: memType="property"; break;
567 case MemberType_Event: memType="event"; break;
568 case MemberType_Interface: memType="interface"; break;
569 case MemberType_Service: memType="service"; break;
572 ti << " <member refid=\"" << memberOutputFileBase(md)
573 << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>"
574 << convertToXML(md->name()) << "</name></member>" << endl;
577 if (md->getClassDef())
578 scopeName=md->getClassDef()->name();
579 else if (md->getNamespaceDef())
580 scopeName=md->getNamespaceDef()->name();
582 t << " <memberdef kind=\"";
583 //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t;
584 t << memType << "\" id=\"";
585 if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
587 t << md->getGroupDef()->getOutputFileBase();
591 t << memberOutputFileBase(md);
593 t << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
596 switch(md->protection())
598 case Public: t << "public"; break;
599 case Protected: t << "protected"; break;
600 case Private: t << "private"; break;
601 case Package: t << "package"; break;
606 if (md->isStatic()) t << "yes"; else t << "no";
611 ArgumentList *al = md->argumentList();
613 if (al!=0 && al->constSpecifier) t << "yes"; else t << "no";
617 if (md->isExplicit()) t << "yes"; else t << "no";
621 if (md->isInline()) t << "yes"; else t << "no";
626 t << " final=\"yes\"";
631 t << " sealed=\"yes\"";
639 if (md->isOptional())
641 t << " optional=\"yes\"";
644 if (md->isRequired())
646 t << " required=\"yes\"";
650 switch (md->virtualness())
652 case Normal: t << "non-virtual"; break;
653 case Virtual: t << "virtual"; break;
654 case Pure: t << "pure-virtual"; break;
660 if (md->memberType() == MemberType_Variable)
662 //ArgumentList *al = md->argumentList();
663 //t << " volatile=\"";
664 //if (al && al->volatileSpecifier) t << "yes"; else t << "no";
667 if (md->isMutable()) t << "yes"; else t << "no";
670 if (md->isInitonly())
672 t << " initonly=\"yes\"";
675 if (md->isAttribute())
677 t << " attribute=\"yes\"";
679 if (md->isUNOProperty())
681 t << " property=\"yes\"";
683 if (md->isReadonly())
685 t << " readonly=\"yes\"";
689 t << " bound=\"yes\"";
691 if (md->isRemovable())
693 t << " removable=\"yes\"";
695 if (md->isConstrained())
697 t << " constrained=\"yes\"";
699 if (md->isTransient())
701 t << " transient=\"yes\"";
703 if (md->isMaybeVoid())
705 t << " maybevoid=\"yes\"";
707 if (md->isMaybeDefault())
709 t << " maybedefault=\"yes\"";
711 if (md->isMaybeAmbiguous())
713 t << " maybeambiguous=\"yes\"";
716 else if (md->memberType() == MemberType_Property)
719 if (md->isReadable()) t << "yes"; else t << "no";
723 if (md->isWritable()) t << "yes"; else t << "no";
727 if (md->isGettable()) t << "yes"; else t << "no";
731 if (md->isSettable()) t << "yes"; else t << "no";
734 if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak())
737 if (md->isAssign()) t << "assign";
738 else if (md->isCopy()) t << "copy";
739 else if (md->isRetain()) t << "retain";
740 else if (md->isStrong()) t << "strong";
741 else if (md->isWeak()) t << "weak";
745 else if (md->memberType() == MemberType_Event)
748 if (md->isAddable()) t << "yes"; else t << "no";
752 if (md->isRemovable()) t << "yes"; else t << "no";
756 if (md->isRaisable()) t << "yes"; else t << "no";
762 if (md->memberType()!=MemberType_Define &&
763 md->memberType()!=MemberType_Enumeration
766 if (md->memberType()!=MemberType_Typedef)
768 writeMemberTemplateLists(md,t);
770 QCString typeStr = md->typeString(); //replaceAnonymousScopes(md->typeString());
771 stripQualifiers(typeStr);
773 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,typeStr);
774 t << "</type>" << endl;
775 t << " <definition>" << convertToXML(md->definition()) << "</definition>" << endl;
776 t << " <argsstring>" << convertToXML(md->argsString()) << "</argsstring>" << endl;
779 t << " <name>" << convertToXML(md->name()) << "</name>" << endl;
781 if (md->memberType() == MemberType_Property)
783 if (md->isReadable())
784 t << " <read>" << convertToXML(md->getReadAccessor()) << "</read>" << endl;
785 if (md->isWritable())
786 t << " <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
788 if (md->memberType()==MemberType_Variable && md->bitfieldString())
790 QCString bitfield = md->bitfieldString();
791 if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
792 t << " <bitfield>" << bitfield << "</bitfield>" << endl;
795 MemberDef *rmd = md->reimplements();
798 t << " <reimplements refid=\""
799 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
800 << convertToXML(rmd->name()) << "</reimplements>" << endl;
802 MemberList *rbml = md->reimplementedBy();
805 MemberListIterator mli(*rbml);
806 for (mli.toFirst();(rmd=mli.current());++mli)
808 t << " <reimplementedby refid=\""
809 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
810 << convertToXML(rmd->name()) << "</reimplementedby>" << endl;
814 if (isFunc) //function
816 ArgumentList *declAl = md->declArgumentList();
817 ArgumentList *defAl = md->argumentList();
818 if (declAl && declAl->count()>0)
820 ArgumentListIterator declAli(*declAl);
821 ArgumentListIterator defAli(*defAl);
823 for (declAli.toFirst();(a=declAli.current());++declAli)
825 Argument *defArg = defAli.current();
826 t << " <param>" << endl;
827 if (!a->attrib.isEmpty())
829 t << " <attributes>";
830 writeXMLString(t,a->attrib);
831 t << "</attributes>" << endl;
833 if (!a->type.isEmpty())
836 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->type);
837 t << "</type>" << endl;
839 if (!a->name.isEmpty())
842 writeXMLString(t,a->name);
843 t << "</declname>" << endl;
845 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
848 writeXMLString(t,defArg->name);
849 t << "</defname>" << endl;
851 if (!a->array.isEmpty())
854 writeXMLString(t,a->array);
855 t << "</array>" << endl;
857 if (!a->defval.isEmpty())
860 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->defval);
861 t << "</defval>" << endl;
863 if (defArg && defArg->hasDocumentation())
865 t << " <briefdescription>";
866 writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),
867 md->getOuterScope(),md,defArg->docs);
868 t << "</briefdescription>" << endl;
870 t << " </param>" << endl;
871 if (defArg) ++defAli;
875 else if (md->memberType()==MemberType_Define &&
876 md->argsString()) // define
878 if (md->argumentList()->count()==0) // special case for "foo()" to
879 // disguish it from "foo".
881 t << " <param></param>" << endl;
885 ArgumentListIterator ali(*md->argumentList());
887 for (ali.toFirst();(a=ali.current());++ali)
889 t << " <param><defname>" << a->type << "</defname></param>" << endl;
894 if (md->hasOneLineInitializer() || md->hasMultiLineInitializer())
896 t << " <initializer>";
897 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->initializer());
898 t << "</initializer>" << endl;
901 if (md->excpString())
903 t << " <exceptions>";
904 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString());
905 t << "</exceptions>" << endl;
908 if (md->memberType()==MemberType_Enumeration) // enum
910 MemberList *enumFields = md->enumFieldList();
913 MemberListIterator emli(*enumFields);
915 for (emli.toFirst();(emd=emli.current());++emli)
917 ti << " <member refid=\"" << memberOutputFileBase(emd)
918 << "_1" << emd->anchor() << "\" kind=\"enumvalue\"><name>"
919 << convertToXML(emd->name()) << "</name></member>" << endl;
921 t << " <enumvalue id=\"" << memberOutputFileBase(emd) << "_1"
922 << emd->anchor() << "\" prot=\"";
923 switch (emd->protection())
925 case Public: t << "public"; break;
926 case Protected: t << "protected"; break;
927 case Private: t << "private"; break;
928 case Package: t << "package"; break;
932 writeXMLString(t,emd->name());
933 t << "</name>" << endl;
934 if (!emd->initializer().isEmpty())
936 t << " <initializer>";
937 writeXMLString(t,emd->initializer());
938 t << "</initializer>" << endl;
940 t << " <briefdescription>" << endl;
941 writeXMLDocBlock(t,emd->briefFile(),emd->briefLine(),emd->getOuterScope(),emd,emd->briefDescription());
942 t << " </briefdescription>" << endl;
943 t << " <detaileddescription>" << endl;
944 writeXMLDocBlock(t,emd->docFile(),emd->docLine(),emd->getOuterScope(),emd,emd->documentation());
945 t << " </detaileddescription>" << endl;
946 t << " </enumvalue>" << endl;
950 t << " <briefdescription>" << endl;
951 writeXMLDocBlock(t,md->briefFile(),md->briefLine(),md->getOuterScope(),md,md->briefDescription());
952 t << " </briefdescription>" << endl;
953 t << " <detaileddescription>" << endl;
954 writeXMLDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
955 t << " </detaileddescription>" << endl;
956 t << " <inbodydescription>" << endl;
957 writeXMLDocBlock(t,md->docFile(),md->inbodyLine(),md->getOuterScope(),md,md->inbodyDocumentation());
958 t << " </inbodydescription>" << endl;
959 if (md->getDefLine()!=-1)
961 t << " <location file=\""
962 << md->getDefFileName() << "\" line=\""
963 << md->getDefLine() << "\"" << " column=\""
964 << md->getDefColumn() << "\"" ;
965 if (md->getStartBodyLine()!=-1)
967 FileDef *bodyDef = md->getBodyDef();
970 t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
972 t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\""
973 << md->getEndBodyLine() << "\"";
978 //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
979 MemberSDict *mdict = md->getReferencesMembers();
982 MemberSDict::Iterator mdi(*mdict);
984 for (mdi.toFirst();(rmd=mdi.current());++mdi)
986 writeMemberReference(t,def,rmd,"references");
989 mdict = md->getReferencedByMembers();
992 MemberSDict::Iterator mdi(*mdict);
994 for (mdi.toFirst();(rmd=mdi.current());++mdi)
996 writeMemberReference(t,def,rmd,"referencedby");
1000 t << " </memberdef>" << endl;
1003 static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t,
1004 MemberList *ml,const char *kind,const char *header=0,
1005 const char *documentation=0)
1008 MemberListIterator mli(*ml);
1011 for (mli.toFirst();(md=mli.current());++mli)
1013 // namespace members are also inserted in the file scope, but
1014 // to prevent this duplication in the XML output, we filter those here.
1015 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1020 if (count==0) return; // empty list
1022 t << " <sectiondef kind=\"" << kind << "\">" << endl;
1025 t << " <header>" << convertToXML(header) << "</header>" << endl;
1029 t << " <description>";
1030 writeXMLDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
1031 t << "</description>" << endl;
1033 for (mli.toFirst();(md=mli.current());++mli)
1035 // namespace members are also inserted in the file scope, but
1036 // to prevent this duplication in the XML output, we filter those here.
1037 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1039 generateXMLForMember(md,ti,t,d);
1042 t << " </sectiondef>" << endl;
1045 static void writeListOfAllMembers(ClassDef *cd,FTextStream &t)
1047 t << " <listofallmembers>" << endl;
1048 if (cd->memberNameInfoSDict())
1050 MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
1051 MemberNameInfo *mni;
1052 for (mnii.toFirst();(mni=mnii.current());++mnii)
1054 MemberNameInfoIterator mii(*mni);
1056 for (mii.toFirst();(mi=mii.current());++mii)
1058 MemberDef *md=mi->memberDef;
1059 if (md->name().at(0)!='@') // skip anonymous members
1061 Protection prot = mi->prot;
1062 Specifier virt=md->virtualness();
1063 t << " <member refid=\"" << memberOutputFileBase(md) << "_1" <<
1064 md->anchor() << "\" prot=\"";
1067 case Public: t << "public"; break;
1068 case Protected: t << "protected"; break;
1069 case Private: t << "private"; break;
1070 case Package: t << "package"; break;
1075 case Normal: t << "non-virtual"; break;
1076 case Virtual: t << "virtual"; break;
1077 case Pure: t << "pure-virtual"; break;
1080 if (!mi->ambiguityResolutionScope.isEmpty())
1082 t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\"";
1084 t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" <<
1085 convertToXML(md->name()) << "</name></member>" << endl;
1090 t << " </listofallmembers>" << endl;
1093 static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
1097 ClassSDict::Iterator cli(*cl);
1099 for (cli.toFirst();(cd=cli.current());++cli)
1101 if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
1103 t << " <innerclass refid=\"" << classOutputFileBase(cd)
1105 switch(cd->protection())
1107 case Public: t << "public"; break;
1108 case Protected: t << "protected"; break;
1109 case Private: t << "private"; break;
1110 case Package: t << "package"; break;
1112 t << "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
1118 static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
1122 NamespaceSDict::Iterator nli(*nl);
1124 for (nli.toFirst();(nd=nli.current());++nli)
1126 if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
1128 t << " <innernamespace refid=\"" << nd->getOutputFileBase()
1129 << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
1135 static void writeInnerFiles(const FileList *fl,FTextStream &t)
1139 QListIterator<FileDef> fli(*fl);
1141 for (fli.toFirst();(fd=fli.current());++fli)
1143 t << " <innerfile refid=\"" << fd->getOutputFileBase()
1144 << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl;
1149 static void writeInnerPages(const PageSDict *pl,FTextStream &t)
1153 PageSDict::Iterator pli(*pl);
1155 for (pli.toFirst();(pd=pli.current());++pli)
1157 t << " <innerpage refid=\"" << pd->getOutputFileBase();
1158 if (pd->getGroupDef())
1160 t << "_" << pd->name();
1162 t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
1167 static void writeInnerGroups(const GroupList *gl,FTextStream &t)
1171 GroupListIterator gli(*gl);
1173 for (gli.toFirst();(sgd=gli.current());++gli)
1175 t << " <innergroup refid=\"" << sgd->getOutputFileBase()
1176 << "\">" << convertToXML(sgd->groupTitle())
1177 << "</innergroup>" << endl;
1182 static void writeInnerDirs(const DirList *dl,FTextStream &t)
1186 QListIterator<DirDef> subdirs(*dl);
1188 for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
1190 t << " <innerdir refid=\"" << subdir->getOutputFileBase()
1191 << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl;
1196 static void generateXMLForClass(ClassDef *cd,FTextStream &ti)
1198 // + brief description
1199 // + detailed description
1200 // + template argument list(s)
1203 // + inheritance diagram
1204 // + list of direct super classes
1205 // + list of direct sub classes
1206 // + list of inner classes
1207 // + collaboration diagram
1208 // + list of all members
1209 // + user defined member sections
1210 // + standard member sections
1211 // + detailed member documentation
1212 // - examples using the class
1214 if (cd->isReference()) return; // skip external references.
1215 if (cd->isHidden()) return; // skip hidden classes.
1216 if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1217 if (cd->templateMaster()!=0) return; // skip generated template instances.
1218 if (cd->isArtificial()) return; // skip artificially created classes
1220 msg("Generating XML output for class %s\n",cd->name().data());
1222 ti << " <compound refid=\"" << classOutputFileBase(cd)
1223 << "\" kind=\"" << cd->compoundTypeString()
1224 << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
1226 QCString outputDirectory = Config_getString("XML_OUTPUT");
1227 QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
1229 if (!f.open(IO_WriteOnly))
1231 err("Cannot open file %s for writing!\n",fileName.data());
1235 //t.setEncoding(FTextStream::UnicodeUTF8);
1238 t << " <compounddef id=\""
1239 << classOutputFileBase(cd) << "\" kind=\""
1240 << cd->compoundTypeString() << "\" prot=\"";
1241 switch (cd->protection())
1243 case Public: t << "public"; break;
1244 case Protected: t << "protected"; break;
1245 case Private: t << "private"; break;
1246 case Package: t << "package"; break;
1248 if (cd->isFinal()) t << "\" final=\"yes";
1249 if (cd->isSealed()) t << "\" sealed=\"yes";
1250 if (cd->isAbstract()) t << "\" abstract=\"yes";
1252 t << " <compoundname>";
1253 writeXMLString(t,cd->name());
1254 t << "</compoundname>" << endl;
1255 if (cd->baseClasses())
1257 BaseClassListIterator bcli(*cd->baseClasses());
1259 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1261 t << " <basecompoundref ";
1262 if (bcd->classDef->isLinkable())
1264 t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
1269 case Public: t << "public"; break;
1270 case Protected: t << "protected"; break;
1271 case Private: t << "private"; break;
1272 case Package: ASSERT(0); break;
1277 case Normal: t << "non-virtual"; break;
1278 case Virtual: t << "virtual"; break;
1279 case Pure: t <<"pure-virtual"; break;
1282 if (!bcd->templSpecifiers.isEmpty())
1285 insertTemplateSpecifierInScope(
1286 bcd->classDef->name(),bcd->templSpecifiers)
1291 t << convertToXML(bcd->classDef->displayName());
1293 t << "</basecompoundref>" << endl;
1296 if (cd->subClasses())
1298 BaseClassListIterator bcli(*cd->subClasses());
1300 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1302 t << " <derivedcompoundref refid=\""
1303 << classOutputFileBase(bcd->classDef)
1307 case Public: t << "public"; break;
1308 case Protected: t << "protected"; break;
1309 case Private: t << "private"; break;
1310 case Package: ASSERT(0); break;
1315 case Normal: t << "non-virtual"; break;
1316 case Virtual: t << "virtual"; break;
1317 case Pure: t << "pure-virtual"; break;
1319 t << "\">" << convertToXML(bcd->classDef->displayName())
1320 << "</derivedcompoundref>" << endl;
1324 IncludeInfo *ii=cd->includeInfo();
1327 QCString nm = ii->includeName;
1328 if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1332 if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
1334 t << " refid=\"" << ii->fileDef->getOutputFileBase() << "\"";
1336 t << " local=\"" << (ii->local ? "yes" : "no") << "\">";
1338 t << "</includes>" << endl;
1342 writeInnerClasses(cd->getClassSDict(),t);
1344 writeTemplateList(cd,t);
1345 if (cd->getMemberGroupSDict())
1347 MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
1349 for (;(mg=mgli.current());++mgli)
1351 generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
1352 mg->documentation());
1356 QListIterator<MemberList> mli(cd->getMemberLists());
1358 for (mli.toFirst();(ml=mli.current());++mli)
1360 if ((ml->listType()&MemberListType_detailedLists)==0)
1362 generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1366 generateXMLSection(cd,ti,t,cd->pubTypes,"public-type");
1367 generateXMLSection(cd,ti,t,cd->pubMethods,"public-func");
1368 generateXMLSection(cd,ti,t,cd->pubAttribs,"public-attrib");
1369 generateXMLSection(cd,ti,t,cd->pubSlots,"public-slot");
1370 generateXMLSection(cd,ti,t,cd->signals,"signal");
1371 generateXMLSection(cd,ti,t,cd->dcopMethods,"dcop-func");
1372 generateXMLSection(cd,ti,t,cd->properties,"property");
1373 generateXMLSection(cd,ti,t,cd->events,"event");
1374 generateXMLSection(cd,ti,t,cd->pubStaticMethods,"public-static-func");
1375 generateXMLSection(cd,ti,t,cd->pubStaticAttribs,"public-static-attrib");
1376 generateXMLSection(cd,ti,t,cd->proTypes,"protected-type");
1377 generateXMLSection(cd,ti,t,cd->proMethods,"protected-func");
1378 generateXMLSection(cd,ti,t,cd->proAttribs,"protected-attrib");
1379 generateXMLSection(cd,ti,t,cd->proSlots,"protected-slot");
1380 generateXMLSection(cd,ti,t,cd->proStaticMethods,"protected-static-func");
1381 generateXMLSection(cd,ti,t,cd->proStaticAttribs,"protected-static-attrib");
1382 generateXMLSection(cd,ti,t,cd->pacTypes,"package-type");
1383 generateXMLSection(cd,ti,t,cd->pacMethods,"package-func");
1384 generateXMLSection(cd,ti,t,cd->pacAttribs,"package-attrib");
1385 generateXMLSection(cd,ti,t,cd->pacStaticMethods,"package-static-func");
1386 generateXMLSection(cd,ti,t,cd->pacStaticAttribs,"package-static-attrib");
1387 generateXMLSection(cd,ti,t,cd->priTypes,"private-type");
1388 generateXMLSection(cd,ti,t,cd->priMethods,"private-func");
1389 generateXMLSection(cd,ti,t,cd->priAttribs,"private-attrib");
1390 generateXMLSection(cd,ti,t,cd->priSlots,"private-slot");
1391 generateXMLSection(cd,ti,t,cd->priStaticMethods,"private-static-func");
1392 generateXMLSection(cd,ti,t,cd->priStaticAttribs,"private-static-attrib");
1393 generateXMLSection(cd,ti,t,cd->friends,"friend");
1394 generateXMLSection(cd,ti,t,cd->related,"related");
1397 t << " <briefdescription>" << endl;
1398 writeXMLDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
1399 t << " </briefdescription>" << endl;
1400 t << " <detaileddescription>" << endl;
1401 writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
1402 t << " </detaileddescription>" << endl;
1403 DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
1404 if (!inheritanceGraph.isTrivial())
1406 t << " <inheritancegraph>" << endl;
1407 inheritanceGraph.writeXML(t);
1408 t << " </inheritancegraph>" << endl;
1410 DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
1411 if (!collaborationGraph.isTrivial())
1413 t << " <collaborationgraph>" << endl;
1414 collaborationGraph.writeXML(t);
1415 t << " </collaborationgraph>" << endl;
1417 t << " <location file=\""
1418 << cd->getDefFileName() << "\" line=\""
1419 << cd->getDefLine() << "\"" << " column=\""
1420 << cd->getDefColumn() << "\"" ;
1421 if (cd->getStartBodyLine()!=-1)
1423 FileDef *bodyDef = cd->getBodyDef();
1426 t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
1428 t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
1429 << cd->getEndBodyLine() << "\"";
1432 writeListOfAllMembers(cd,t);
1433 t << " </compounddef>" << endl;
1434 t << "</doxygen>" << endl;
1436 ti << " </compound>" << endl;
1439 static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti)
1441 // + contained class definitions
1442 // + contained namespace definitions
1448 // - files containing (parts of) the namespace definition
1450 if (nd->isReference() || nd->isHidden()) return; // skip external references
1452 ti << " <compound refid=\"" << nd->getOutputFileBase()
1453 << "\" kind=\"namespace\"" << "><name>"
1454 << convertToXML(nd->name()) << "</name>" << endl;
1456 QCString outputDirectory = Config_getString("XML_OUTPUT");
1457 QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
1459 if (!f.open(IO_WriteOnly))
1461 err("Cannot open file %s for writing!\n",fileName.data());
1465 //t.setEncoding(FTextStream::UnicodeUTF8);
1468 t << " <compounddef id=\""
1469 << nd->getOutputFileBase() << "\" kind=\"namespace\">" << endl;
1470 t << " <compoundname>";
1471 writeXMLString(t,nd->name());
1472 t << "</compoundname>" << endl;
1474 writeInnerClasses(nd->getClassSDict(),t);
1475 writeInnerNamespaces(nd->getNamespaceSDict(),t);
1477 if (nd->getMemberGroupSDict())
1479 MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
1481 for (;(mg=mgli.current());++mgli)
1483 generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
1484 mg->documentation());
1488 QListIterator<MemberList> mli(nd->getMemberLists());
1490 for (mli.toFirst();(ml=mli.current());++mli)
1492 if ((ml->listType()&MemberListType_declarationLists)!=0)
1494 generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1498 generateXMLSection(nd,ti,t,&nd->decDefineMembers,"define");
1499 generateXMLSection(nd,ti,t,&nd->decProtoMembers,"prototype");
1500 generateXMLSection(nd,ti,t,&nd->decTypedefMembers,"typedef");
1501 generateXMLSection(nd,ti,t,&nd->decEnumMembers,"enum");
1502 generateXMLSection(nd,ti,t,&nd->decFuncMembers,"func");
1503 generateXMLSection(nd,ti,t,&nd->decVarMembers,"var");
1506 t << " <briefdescription>" << endl;
1507 writeXMLDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
1508 t << " </briefdescription>" << endl;
1509 t << " <detaileddescription>" << endl;
1510 writeXMLDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
1511 t << " </detaileddescription>" << endl;
1512 t << " <location file=\""
1513 << nd->getDefFileName() << "\" line=\""
1514 << nd->getDefLine() << "\"" << " column=\""
1515 << nd->getDefColumn() << "\"/>" << endl ;
1516 t << " </compounddef>" << endl;
1517 t << "</doxygen>" << endl;
1519 ti << " </compound>" << endl;
1522 static void generateXMLForFile(FileDef *fd,FTextStream &ti)
1525 // + includedby files
1527 // + included by graph
1528 // + contained class definitions
1529 // + contained namespace definitions
1536 // - number of lines
1538 if (fd->isReference()) return; // skip external references
1540 ti << " <compound refid=\"" << fd->getOutputFileBase()
1541 << "\" kind=\"file\"><name>" << convertToXML(fd->name())
1542 << "</name>" << endl;
1544 QCString outputDirectory = Config_getString("XML_OUTPUT");
1545 QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
1547 if (!f.open(IO_WriteOnly))
1549 err("Cannot open file %s for writing!\n",fileName.data());
1553 //t.setEncoding(FTextStream::UnicodeUTF8);
1556 t << " <compounddef id=\""
1557 << fd->getOutputFileBase() << "\" kind=\"file\">" << endl;
1558 t << " <compoundname>";
1559 writeXMLString(t,fd->name());
1560 t << "</compoundname>" << endl;
1564 if (fd->includeFileList())
1566 QListIterator<IncludeInfo> ili1(*fd->includeFileList());
1567 for (ili1.toFirst();(inc=ili1.current());++ili1)
1570 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1572 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1574 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1575 t << inc->includeName;
1576 t << "</includes>" << endl;
1580 if (fd->includedByFileList())
1582 QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
1583 for (ili2.toFirst();(inc=ili2.current());++ili2)
1585 t << " <includedby";
1586 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1588 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1590 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1591 t << inc->includeName;
1592 t << "</includedby>" << endl;
1596 DotInclDepGraph incDepGraph(fd,FALSE);
1597 if (!incDepGraph.isTrivial())
1599 t << " <incdepgraph>" << endl;
1600 incDepGraph.writeXML(t);
1601 t << " </incdepgraph>" << endl;
1604 DotInclDepGraph invIncDepGraph(fd,TRUE);
1605 if (!invIncDepGraph.isTrivial())
1607 t << " <invincdepgraph>" << endl;
1608 invIncDepGraph.writeXML(t);
1609 t << " </invincdepgraph>" << endl;
1612 if (fd->getClassSDict())
1614 writeInnerClasses(fd->getClassSDict(),t);
1616 if (fd->getNamespaceSDict())
1618 writeInnerNamespaces(fd->getNamespaceSDict(),t);
1621 if (fd->getMemberGroupSDict())
1623 MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
1625 for (;(mg=mgli.current());++mgli)
1627 generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
1628 mg->documentation());
1632 QListIterator<MemberList> mli(fd->getMemberLists());
1634 for (mli.toFirst();(ml=mli.current());++mli)
1636 if ((ml->listType()&MemberListType_declarationLists)!=0)
1638 generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1642 generateXMLSection(fd,ti,t,fd->decDefineMembers,"define");
1643 generateXMLSection(fd,ti,t,fd->decProtoMembers,"prototype");
1644 generateXMLSection(fd,ti,t,fd->decTypedefMembers,"typedef");
1645 generateXMLSection(fd,ti,t,fd->decEnumMembers,"enum");
1646 generateXMLSection(fd,ti,t,fd->decFuncMembers,"func");
1647 generateXMLSection(fd,ti,t,fd->decVarMembers,"var");
1650 t << " <briefdescription>" << endl;
1651 writeXMLDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
1652 t << " </briefdescription>" << endl;
1653 t << " <detaileddescription>" << endl;
1654 writeXMLDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
1655 t << " </detaileddescription>" << endl;
1656 if (Config_getBool("XML_PROGRAMLISTING"))
1658 t << " <programlisting>" << endl;
1659 writeXMLCodeBlock(t,fd);
1660 t << " </programlisting>" << endl;
1662 t << " <location file=\"" << fd->getDefFileName() << "\"/>" << endl;
1663 t << " </compounddef>" << endl;
1664 t << "</doxygen>" << endl;
1666 ti << " </compound>" << endl;
1669 static void generateXMLForGroup(GroupDef *gd,FTextStream &ti)
1680 // + brief description
1681 // + detailed description
1683 if (gd->isReference()) return; // skip external references
1685 ti << " <compound refid=\"" << gd->getOutputFileBase()
1686 << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
1688 QCString outputDirectory = Config_getString("XML_OUTPUT");
1689 QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
1691 if (!f.open(IO_WriteOnly))
1693 err("Cannot open file %s for writing!\n",fileName.data());
1698 //t.setEncoding(FTextStream::UnicodeUTF8);
1700 t << " <compounddef id=\""
1701 << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
1702 t << " <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
1703 t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
1705 writeInnerFiles(gd->getFiles(),t);
1706 writeInnerClasses(gd->getClasses(),t);
1707 writeInnerNamespaces(gd->getNamespaces(),t);
1708 writeInnerPages(gd->getPages(),t);
1709 writeInnerGroups(gd->getSubGroups(),t);
1711 if (gd->getMemberGroupSDict())
1713 MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
1715 for (;(mg=mgli.current());++mgli)
1717 generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
1718 mg->documentation());
1722 QListIterator<MemberList> mli(gd->getMemberLists());
1724 for (mli.toFirst();(ml=mli.current());++mli)
1726 if ((ml->listType()&MemberListType_declarationLists)!=0)
1728 generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1732 generateXMLSection(gd,ti,t,&gd->decDefineMembers,"define");
1733 generateXMLSection(gd,ti,t,&gd->decProtoMembers,"prototype");
1734 generateXMLSection(gd,ti,t,&gd->decTypedefMembers,"typedef");
1735 generateXMLSection(gd,ti,t,&gd->decEnumMembers,"enum");
1736 generateXMLSection(gd,ti,t,&gd->decFuncMembers,"func");
1737 generateXMLSection(gd,ti,t,&gd->decVarMembers,"var");
1740 t << " <briefdescription>" << endl;
1741 writeXMLDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
1742 t << " </briefdescription>" << endl;
1743 t << " <detaileddescription>" << endl;
1744 writeXMLDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
1745 t << " </detaileddescription>" << endl;
1746 t << " </compounddef>" << endl;
1747 t << "</doxygen>" << endl;
1749 ti << " </compound>" << endl;
1752 static void generateXMLForDir(DirDef *dd,FTextStream &ti)
1754 if (dd->isReference()) return; // skip external references
1755 ti << " <compound refid=\"" << dd->getOutputFileBase()
1756 << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName())
1757 << "</name>" << endl;
1759 QCString outputDirectory = Config_getString("XML_OUTPUT");
1760 QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
1762 if (!f.open(IO_WriteOnly))
1764 err("Cannot open file %s for writing!\n",fileName.data());
1769 //t.setEncoding(FTextStream::UnicodeUTF8);
1771 t << " <compounddef id=\""
1772 << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl;
1773 t << " <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl;
1775 writeInnerDirs(&dd->subDirs(),t);
1776 writeInnerFiles(dd->getFiles(),t);
1778 t << " <briefdescription>" << endl;
1779 writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
1780 t << " </briefdescription>" << endl;
1781 t << " <detaileddescription>" << endl;
1782 writeXMLDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
1783 t << " </detaileddescription>" << endl;
1784 t << " <location file=\"" << dd->name() << "\"/>" << endl;
1785 t << " </compounddef>" << endl;
1786 t << "</doxygen>" << endl;
1788 ti << " </compound>" << endl;
1791 static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
1797 const char *kindName = isExample ? "example" : "page";
1799 if (pd->isReference()) return;
1801 QCString pageName = pd->getOutputFileBase();
1802 if (pd->getGroupDef())
1804 pageName+=(QCString)"_"+pd->name();
1806 if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
1808 ti << " <compound refid=\"" << pageName
1809 << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name())
1810 << "</name>" << endl;
1812 QCString outputDirectory = Config_getString("XML_OUTPUT");
1813 QCString fileName=outputDirectory+"/"+pageName+".xml";
1815 if (!f.open(IO_WriteOnly))
1817 err("Cannot open file %s for writing!\n",fileName.data());
1822 //t.setEncoding(FTextStream::UnicodeUTF8);
1824 t << " <compounddef id=\"" << pageName;
1825 t << "\" kind=\"" << kindName << "\">" << endl;
1826 t << " <compoundname>" << convertToXML(pd->name())
1827 << "</compoundname>" << endl;
1829 if (pd==Doxygen::mainPage) // main page is special
1832 if (!pd->title().isEmpty() && pd->title().lower()!="notitle")
1834 title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()));
1838 title = Config_getString("PROJECT_NAME");
1840 t << " <title>" << convertToXML(convertCharEntitiesToUTF8(title))
1841 << "</title>" << endl;
1845 SectionInfo *si = Doxygen::sectionDict->find(pd->name());
1848 t << " <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title)))
1849 << "</title>" << endl;
1852 writeInnerPages(pd->getSubPages(),t);
1853 t << " <detaileddescription>" << endl;
1856 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1857 pd->documentation()+"\n\\include "+pd->name());
1861 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1862 pd->documentation());
1864 t << " </detaileddescription>" << endl;
1866 t << " </compounddef>" << endl;
1867 t << "</doxygen>" << endl;
1869 ti << " </compound>" << endl;
1881 QCString outputDirectory = Config_getString("XML_OUTPUT");
1882 QDir xmlDir(outputDirectory);
1883 createSubDirs(xmlDir);
1884 QCString fileName=outputDirectory+"/index.xsd";
1886 if (!f.open(IO_WriteOnly))
1888 err("Cannot open file %s for writing!\n",fileName.data());
1891 f.writeBlock(index_xsd,qstrlen(index_xsd));
1894 fileName=outputDirectory+"/compound.xsd";
1895 f.setName(fileName);
1896 if (!f.open(IO_WriteOnly))
1898 err("Cannot open file %s for writing!\n",fileName.data());
1902 // write compound.xsd, but replace special marker with the entities
1903 const char *startLine = compound_xsd;
1906 // find end of the line
1907 const char *endLine = startLine+1;
1908 while (*endLine && *(endLine-1)!='\n') endLine++; // skip to end of the line including \n
1909 int len=endLine-startLine;
1913 qstrncpy(s.data(),startLine,len);
1915 if (s.find("<!-- Automatically insert here the HTML entities -->")!=-1)
1918 HtmlEntityMapper::instance()->writeXMLSchema(t);
1922 f.writeBlock(startLine,len);
1929 fileName=outputDirectory+"/index.xml";
1930 f.setName(fileName);
1931 if (!f.open(IO_WriteOnly))
1933 err("Cannot open file %s for writing!\n",fileName.data());
1937 //t.setEncoding(FTextStream::UnicodeUTF8);
1939 // write index header
1940 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
1941 t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
1942 t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" ";
1943 t << "version=\"" << versionString << "\">" << endl;
1946 ClassSDict::Iterator cli(*Doxygen::classSDict);
1948 for (cli.toFirst();(cd=cli.current());++cli)
1950 generateXMLForClass(cd,t);
1954 // ClassSDict::Iterator cli(Doxygen::hiddenClasses);
1956 // for (cli.toFirst();(cd=cli.current());++cli)
1958 // msg("Generating XML output for class %s\n",cd->name().data());
1959 // generateXMLForClass(cd,t);
1962 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1964 for (nli.toFirst();(nd=nli.current());++nli)
1966 msg("Generating XML output for namespace %s\n",nd->name().data());
1967 generateXMLForNamespace(nd,t);
1969 FileNameListIterator fnli(*Doxygen::inputNameList);
1971 for (;(fn=fnli.current());++fnli)
1973 FileNameIterator fni(*fn);
1975 for (;(fd=fni.current());++fni)
1977 msg("Generating XML output for file %s\n",fd->name().data());
1978 generateXMLForFile(fd,t);
1981 GroupSDict::Iterator gli(*Doxygen::groupSDict);
1983 for (;(gd=gli.current());++gli)
1985 msg("Generating XML output for group %s\n",gd->name().data());
1986 generateXMLForGroup(gd,t);
1989 PageSDict::Iterator pdi(*Doxygen::pageSDict);
1991 for (pdi.toFirst();(pd=pdi.current());++pdi)
1993 msg("Generating XML output for page %s\n",pd->name().data());
1994 generateXMLForPage(pd,t,FALSE);
1999 DirSDict::Iterator sdi(*Doxygen::directories);
2000 for (sdi.toFirst();(dir=sdi.current());++sdi)
2002 msg("Generate XML output for dir %s\n",dir->name().data());
2003 generateXMLForDir(dir,t);
2007 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
2009 for (pdi.toFirst();(pd=pdi.current());++pdi)
2011 msg("Generating XML output for example %s\n",pd->name().data());
2012 generateXMLForPage(pd,t,TRUE);
2015 if (Doxygen::mainPage)
2017 msg("Generating XML output for the main page\n");
2018 generateXMLForPage(Doxygen::mainPage,t,FALSE);
2021 //t << " </compoundlist>" << endl;
2022 t << "</doxygenindex>" << endl;
2024 writeCombineScript();