1 /******************************************************************************
3 * Copyright (C) 1997-2015 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"
49 #include "resourcemgr.h"
52 #define XML_DB(x) do {} while(0)
54 //#define XML_DB(x) printf x
55 // debug inside output
56 //#define XML_DB(x) QCString __t;__t.sprintf x;m_t << __t
60 /** Helper class mapping MemberList::ListType to a string representing */
61 class XmlSectionMapper : public QIntDict<char>
64 XmlSectionMapper() : QIntDict<char>(47)
66 insert(MemberListType_pubTypes,"public-type");
67 insert(MemberListType_pubMethods,"public-func");
68 insert(MemberListType_pubAttribs,"public-attrib");
69 insert(MemberListType_pubSlots,"public-slot");
70 insert(MemberListType_signals,"signal");
71 insert(MemberListType_dcopMethods,"dcop-func");
72 insert(MemberListType_properties,"property");
73 insert(MemberListType_events,"event");
74 insert(MemberListType_interfaces,"interfaces");
75 insert(MemberListType_services,"services");
76 insert(MemberListType_pubStaticMethods,"public-static-func");
77 insert(MemberListType_pubStaticAttribs,"public-static-attrib");
78 insert(MemberListType_proTypes,"protected-type");
79 insert(MemberListType_proMethods,"protected-func");
80 insert(MemberListType_proAttribs,"protected-attrib");
81 insert(MemberListType_proSlots,"protected-slot");
82 insert(MemberListType_proStaticMethods,"protected-static-func");
83 insert(MemberListType_proStaticAttribs,"protected-static-attrib");
84 insert(MemberListType_pacTypes,"package-type");
85 insert(MemberListType_pacMethods,"package-func");
86 insert(MemberListType_pacAttribs,"package-attrib");
87 insert(MemberListType_pacStaticMethods,"package-static-func");
88 insert(MemberListType_pacStaticAttribs,"package-static-attrib");
89 insert(MemberListType_priTypes,"private-type");
90 insert(MemberListType_priMethods,"private-func");
91 insert(MemberListType_priAttribs,"private-attrib");
92 insert(MemberListType_priSlots,"private-slot");
93 insert(MemberListType_priStaticMethods,"private-static-func");
94 insert(MemberListType_priStaticAttribs,"private-static-attrib");
95 insert(MemberListType_friends,"friend");
96 insert(MemberListType_related,"related");
97 insert(MemberListType_decDefineMembers,"define");
98 insert(MemberListType_decProtoMembers,"prototype");
99 insert(MemberListType_decTypedefMembers,"typedef");
100 insert(MemberListType_decEnumMembers,"enum");
101 insert(MemberListType_decFuncMembers,"func");
102 insert(MemberListType_decVarMembers,"var");
106 static XmlSectionMapper g_xmlSectionMapper;
109 inline void writeXMLString(FTextStream &t,const char *s)
111 t << convertToXML(s);
114 inline void writeXMLCodeString(FTextStream &t,const char *s, int &col)
123 static int tabSize = Config_getInt(TAB_SIZE);
124 int spacesToNextTabStop = tabSize - (col%tabSize);
125 col+=spacesToNextTabStop;
126 while (spacesToNextTabStop--) t << "<sp/>";
129 case ' ': t << "<sp/>"; col++; break;
130 case '<': t << "<"; col++; break;
131 case '>': t << ">"; col++; break;
132 case '&': t << "&"; col++; break;
133 case '\'': t << "'"; col++; break;
134 case '"': t << """; col++; break;
135 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
136 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
137 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
138 case 27: case 28: case 29: case 30: case 31:
139 // encode invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
140 t << "<sp value=\"" << int(c) << "\"/>";
142 default: s=writeUtf8Char(t,s-1); col++; break;
148 static void writeXMLHeader(FTextStream &t)
150 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
151 t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
152 t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" ";
153 t << "version=\"" << versionString << "\">" << endl;
156 static void writeCombineScript()
158 QCString outputDirectory = Config_getString(XML_OUTPUT);
159 QCString fileName=outputDirectory+"/combine.xslt";
161 if (!f.open(IO_WriteOnly))
163 err("Cannot open file %s for writing!\n",fileName.data());
167 //t.setEncoding(FTextStream::UnicodeUTF8);
170 "<!-- XSLT script to combine the generated output into a single file. \n"
171 " If you have xsltproc you could use:\n"
172 " xsltproc combine.xslt index.xml >all.xml\n"
174 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
175 " <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n"
176 " <xsl:template match=\"/\">\n"
177 " <doxygen version=\"{doxygenindex/@version}\">\n"
178 " <!-- Load all doxgen generated xml files -->\n"
179 " <xsl:for-each select=\"doxygenindex/compound\">\n"
180 " <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n"
184 "</xsl:stylesheet>\n";
188 void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId,
189 const char *anchorId,const char *text,const char *tooltip)
191 t << "<ref refid=\"" << compoundId;
192 if (anchorId) t << "_1" << anchorId;
193 t << "\" kindref=\"";
194 if (anchorId) t << "member"; else t << "compound";
196 if (extRef) t << " external=\"" << extRef << "\"";
197 if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
199 writeXMLString(t,text);
203 /** Implements TextGeneratorIntf for an XML stream. */
204 class TextGeneratorXMLImpl : public TextGeneratorIntf
207 TextGeneratorXMLImpl(FTextStream &t): m_t(t) {}
208 void writeString(const char *s,bool /*keepSpaces*/) const
210 writeXMLString(m_t,s);
212 void writeBreak(int) const {}
213 void writeLink(const char *extRef,const char *file,
214 const char *anchor,const char *text
217 writeXMLLink(m_t,extRef,file,anchor,text,0);
224 /** Generator for producing XML formatted source code. */
225 class XMLCodeGenerator : public CodeOutputInterface
229 XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1), m_isMemberRef(FALSE), m_col(0),
230 m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE), m_insideSpecialHL(FALSE) {}
231 virtual ~XMLCodeGenerator() { }
233 void codify(const char *text)
235 XML_DB(("(codify \"%s\")\n",text));
236 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
238 m_t << "<highlight class=\"normal\">";
239 m_normalHLNeedStartTag=FALSE;
241 writeXMLCodeString(m_t,text,m_col);
243 void writeCodeLink(const char *ref,const char *file,
244 const char *anchor,const char *name,
247 XML_DB(("(writeCodeLink)\n"));
248 if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
250 m_t << "<highlight class=\"normal\">";
251 m_normalHLNeedStartTag=FALSE;
253 writeXMLLink(m_t,ref,file,anchor,name,tooltip);
254 m_col+=qstrlen(name);
256 void writeTooltip(const char *, const DocLinkInfo &, const char *,
257 const char *, const SourceLinkInfo &, const SourceLinkInfo &
260 XML_DB(("(writeToolTip)\n"));
262 void startCodeLine(bool)
264 XML_DB(("(startCodeLine)\n"));
266 if (m_lineNumber!=-1)
268 m_t << " lineno=\"" << m_lineNumber << "\"";
269 if (!m_refId.isEmpty())
271 m_t << " refid=\"" << m_refId << "\"";
274 m_t << " refkind=\"member\"";
278 m_t << " refkind=\"compound\"";
281 if (!m_external.isEmpty())
283 m_t << " external=\"" << m_external << "\"";
287 m_insideCodeLine=TRUE;
292 XML_DB(("(endCodeLine)\n"));
293 if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
295 m_t << "</highlight>";
296 m_normalHLNeedStartTag=TRUE;
298 m_t << "</codeline>" << endl; // non DocBook
301 m_external.resize(0);
302 m_insideCodeLine=FALSE;
304 void startFontClass(const char *colorClass)
306 XML_DB(("(startFontClass)\n"));
307 if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
309 m_t << "</highlight>";
310 m_normalHLNeedStartTag=TRUE;
312 m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
313 m_insideSpecialHL=TRUE;
317 XML_DB(("(endFontClass)\n"));
318 m_t << "</highlight>"; // non DocBook
319 m_insideSpecialHL=FALSE;
321 void writeCodeAnchor(const char *)
323 XML_DB(("(writeCodeAnchor)\n"));
325 void writeLineNumber(const char *extRef,const char *compId,
326 const char *anchorId,int l)
328 XML_DB(("(writeLineNumber)\n"));
329 // we remember the information provided here to use it
330 // at the <codeline> start tag.
335 if (anchorId) m_refId+=(QCString)"_1"+anchorId;
336 m_isMemberRef = anchorId!=0;
337 if (extRef) m_external=extRef;
340 void setCurrentDoc(Definition *,const char *,bool)
343 void addWord(const char *,bool)
349 if (m_insideCodeLine) endCodeLine();
360 bool m_insideCodeLine;
361 bool m_normalHLNeedStartTag;
362 bool m_insideSpecialHL;
366 static void writeTemplateArgumentList(ArgumentList *al,
373 indentStr.fill(' ',indent);
376 t << indentStr << "<templateparamlist>" << endl;
377 ArgumentListIterator ali(*al);
379 for (ali.toFirst();(a=ali.current());++ali)
381 t << indentStr << " <param>" << endl;
382 if (!a->type.isEmpty())
384 t << indentStr << " <type>";
385 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
386 t << "</type>" << endl;
388 if (!a->name.isEmpty())
390 t << indentStr << " <declname>" << a->name << "</declname>" << endl;
391 t << indentStr << " <defname>" << a->name << "</defname>" << endl;
393 if (!a->defval.isEmpty())
395 t << indentStr << " <defval>";
396 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
397 t << "</defval>" << endl;
399 if (!a->typeConstraint.isEmpty())
401 t << indentStr << " <typeconstraint>";
402 linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->typeConstraint);
403 t << "</typeconstraint>" << endl;
405 t << indentStr << " </param>" << endl;
407 t << indentStr << "</templateparamlist>" << endl;
411 static void writeMemberTemplateLists(MemberDef *md,FTextStream &t)
413 ArgumentList *templMd = md->templateArguments();
414 if (templMd) // function template prefix
416 writeTemplateArgumentList(templMd,t,md->getClassDef(),md->getFileDef(),8);
420 static void writeTemplateList(ClassDef *cd,FTextStream &t)
422 writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
425 static void writeXMLDocBlock(FTextStream &t,
426 const QCString &fileName,
430 const QCString &text)
432 QCString stext = text.stripWhiteSpace();
433 if (stext.isEmpty()) return;
434 // convert the documentation string into an abstract syntax tree
435 DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
436 // create a code generator
437 XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
438 // create a parse tree visitor for XML
439 XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
441 root->accept(visitor);
449 void writeXMLCodeBlock(FTextStream &t,FileDef *fd)
451 ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
452 SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
453 pIntf->resetCodeParserState();
454 XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
455 pIntf->parseCode(*xmlGen, // codeOutIntf
457 fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)),
459 FALSE, // isExampleBlock
464 FALSE, // inlineFragement
466 TRUE // showLineNumbers
472 static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName)
474 QCString scope = rmd->getScopeString();
475 QCString name = rmd->name();
476 if (!scope.isEmpty() && scope!=def->name())
478 name.prepend(scope+getLanguageSpecificSeparator(rmd->getLanguage()));
480 t << " <" << tagName << " refid=\"";
481 t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\"";
482 if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
484 t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\"";
485 t << " startline=\"" << rmd->getStartBodyLine() << "\"";
486 if (rmd->getEndBodyLine()!=-1)
488 t << " endline=\"" << rmd->getEndBodyLine() << "\"";
491 t << ">" << convertToXML(name) << "</" << tagName << ">" << endl;
495 static void stripQualifiers(QCString &typeStr)
500 if (typeStr.stripPrefix("static "));
501 else if (typeStr.stripPrefix("virtual "));
502 else if (typeStr.stripPrefix("volatile "));
503 else if (typeStr=="virtual") typeStr="";
508 static QCString classOutputFileBase(ClassDef *cd)
510 //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
511 //if (inlineGroupedClasses && cd->partOfGroups()!=0)
512 return cd->getOutputFileBase();
514 // return cd->getOutputFileBase();
517 static QCString memberOutputFileBase(MemberDef *md)
519 //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
520 //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
521 // return md->getClassDef()->getXmlOutputFileBase();
523 // return md->getOutputFileBase();
524 return md->getOutputFileBase();
528 static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def)
531 // + declaration/definition arg lists
535 // + const/volatile specifiers
537 // + source definition
538 // + source references
539 // + source referenced by
541 // + template arguments
542 // (templateArguments(), definitionTemplateParameterLists())
545 // enum values are written as part of the enum
546 if (md->memberType()==MemberType_EnumValue) return;
547 if (md->isHidden()) return;
548 //if (md->name().at(0)=='@') return; // anonymous member
550 // group members are only visible in their group
551 //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
555 switch (md->memberType())
557 case MemberType_Define: memType="define"; break;
558 case MemberType_Function: memType="function"; isFunc=TRUE; break;
559 case MemberType_Variable: memType="variable"; break;
560 case MemberType_Typedef: memType="typedef"; break;
561 case MemberType_Enumeration: memType="enum"; break;
562 case MemberType_EnumValue: ASSERT(0); break;
563 case MemberType_Signal: memType="signal"; isFunc=TRUE; break;
564 case MemberType_Slot: memType="slot"; isFunc=TRUE; break;
565 case MemberType_Friend: memType="friend"; isFunc=TRUE; break;
566 case MemberType_DCOP: memType="dcop"; isFunc=TRUE; break;
567 case MemberType_Property: memType="property"; break;
568 case MemberType_Event: memType="event"; break;
569 case MemberType_Interface: memType="interface"; break;
570 case MemberType_Service: memType="service"; break;
573 ti << " <member refid=\"" << memberOutputFileBase(md)
574 << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>"
575 << convertToXML(md->name()) << "</name></member>" << endl;
578 if (md->getClassDef())
579 scopeName=md->getClassDef()->name();
580 else if (md->getNamespaceDef())
581 scopeName=md->getNamespaceDef()->name();
583 t << " <memberdef kind=\"";
584 //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t;
585 t << memType << "\" id=\"";
586 if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
588 t << md->getGroupDef()->getOutputFileBase();
592 t << memberOutputFileBase(md);
594 t << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
597 switch(md->protection())
599 case Public: t << "public"; break;
600 case Protected: t << "protected"; break;
601 case Private: t << "private"; break;
602 case Package: t << "package"; break;
607 if (md->isStatic()) t << "yes"; else t << "no";
612 ArgumentList *al = md->argumentList();
614 if (al!=0 && al->constSpecifier) t << "yes"; else t << "no";
618 if (md->isExplicit()) t << "yes"; else t << "no";
622 if (md->isInline()) t << "yes"; else t << "no";
625 if (al!=0 && al->refQualifier!=RefQualifierNone)
628 if (al->refQualifier==RefQualifierLValue) t << "lvalue"; else t << "rvalue";
634 t << " final=\"yes\"";
639 t << " sealed=\"yes\"";
647 if (md->isOptional())
649 t << " optional=\"yes\"";
652 if (md->isRequired())
654 t << " required=\"yes\"";
657 if (al && al->volatileSpecifier)
659 t << " volatile=\"yes\"";
663 switch (md->virtualness())
665 case Normal: t << "non-virtual"; break;
666 case Virtual: t << "virtual"; break;
667 case Pure: t << "pure-virtual"; break;
673 if (md->memberType() == MemberType_Enumeration)
676 if (md->isStrong()) t << "yes"; else t << "no";
680 if (md->memberType() == MemberType_Variable)
682 //ArgumentList *al = md->argumentList();
683 //t << " volatile=\"";
684 //if (al && al->volatileSpecifier) t << "yes"; else t << "no";
687 if (md->isMutable()) t << "yes"; else t << "no";
690 if (md->isInitonly())
692 t << " initonly=\"yes\"";
694 if (md->isAttribute())
696 t << " attribute=\"yes\"";
698 if (md->isUNOProperty())
700 t << " property=\"yes\"";
702 if (md->isReadonly())
704 t << " readonly=\"yes\"";
708 t << " bound=\"yes\"";
710 if (md->isRemovable())
712 t << " removable=\"yes\"";
714 if (md->isConstrained())
716 t << " constrained=\"yes\"";
718 if (md->isTransient())
720 t << " transient=\"yes\"";
722 if (md->isMaybeVoid())
724 t << " maybevoid=\"yes\"";
726 if (md->isMaybeDefault())
728 t << " maybedefault=\"yes\"";
730 if (md->isMaybeAmbiguous())
732 t << " maybeambiguous=\"yes\"";
735 else if (md->memberType() == MemberType_Property)
738 if (md->isReadable()) t << "yes"; else t << "no";
742 if (md->isWritable()) t << "yes"; else t << "no";
746 if (md->isGettable()) t << "yes"; else t << "no";
749 t << " privategettable=\"";
750 if (md->isPrivateGettable()) t << "yes"; else t << "no";
753 t << " protectedgettable=\"";
754 if (md->isProtectedGettable()) t << "yes"; else t << "no";
758 if (md->isSettable()) t << "yes"; else t << "no";
761 t << " privatesettable=\"";
762 if (md->isPrivateSettable()) t << "yes"; else t << "no";
765 t << " protectedsettable=\"";
766 if (md->isProtectedSettable()) t << "yes"; else t << "no";
769 if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak())
772 if (md->isAssign()) t << "assign";
773 else if (md->isCopy()) t << "copy";
774 else if (md->isRetain()) t << "retain";
775 else if (md->isStrong()) t << "strong";
776 else if (md->isWeak()) t << "weak";
780 else if (md->memberType() == MemberType_Event)
783 if (md->isAddable()) t << "yes"; else t << "no";
787 if (md->isRemovable()) t << "yes"; else t << "no";
791 if (md->isRaisable()) t << "yes"; else t << "no";
797 if (md->memberType()!=MemberType_Define &&
798 md->memberType()!=MemberType_Enumeration
801 writeMemberTemplateLists(md,t);
802 QCString typeStr = md->typeString(); //replaceAnonymousScopes(md->typeString());
803 stripQualifiers(typeStr);
805 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,typeStr);
806 t << "</type>" << endl;
807 t << " <definition>" << convertToXML(md->definition()) << "</definition>" << endl;
808 t << " <argsstring>" << convertToXML(md->argsString()) << "</argsstring>" << endl;
811 if (md->memberType() == MemberType_Enumeration)
814 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->enumBaseType());
815 t << "</type>" << endl;
818 t << " <name>" << convertToXML(md->name()) << "</name>" << endl;
820 if (md->memberType() == MemberType_Property)
822 if (md->isReadable())
823 t << " <read>" << convertToXML(md->getReadAccessor()) << "</read>" << endl;
824 if (md->isWritable())
825 t << " <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
828 if (md->memberType()==MemberType_Variable && md->bitfieldString())
830 QCString bitfield = md->bitfieldString();
831 if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
832 t << " <bitfield>" << convertToXML(bitfield) << "</bitfield>" << endl;
835 MemberDef *rmd = md->reimplements();
838 t << " <reimplements refid=\""
839 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
840 << convertToXML(rmd->name()) << "</reimplements>" << endl;
842 MemberList *rbml = md->reimplementedBy();
845 MemberListIterator mli(*rbml);
846 for (mli.toFirst();(rmd=mli.current());++mli)
848 t << " <reimplementedby refid=\""
849 << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
850 << convertToXML(rmd->name()) << "</reimplementedby>" << endl;
854 if (isFunc) //function
856 ArgumentList *declAl = md->declArgumentList();
857 ArgumentList *defAl = md->argumentList();
858 if (declAl && defAl && declAl->count()>0)
860 ArgumentListIterator declAli(*declAl);
861 ArgumentListIterator defAli(*defAl);
863 for (declAli.toFirst();(a=declAli.current());++declAli)
865 Argument *defArg = defAli.current();
866 t << " <param>" << endl;
867 if (!a->attrib.isEmpty())
869 t << " <attributes>";
870 writeXMLString(t,a->attrib);
871 t << "</attributes>" << endl;
873 if (!a->type.isEmpty())
876 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->type);
877 t << "</type>" << endl;
879 if (!a->name.isEmpty())
882 writeXMLString(t,a->name);
883 t << "</declname>" << endl;
885 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
888 writeXMLString(t,defArg->name);
889 t << "</defname>" << endl;
891 if (!a->array.isEmpty())
894 writeXMLString(t,a->array);
895 t << "</array>" << endl;
897 if (!a->defval.isEmpty())
900 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->defval);
901 t << "</defval>" << endl;
903 if (defArg && defArg->hasDocumentation())
905 t << " <briefdescription>";
906 writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),
907 md->getOuterScope(),md,defArg->docs);
908 t << "</briefdescription>" << endl;
910 t << " </param>" << endl;
911 if (defArg) ++defAli;
915 else if (md->memberType()==MemberType_Define &&
916 md->argsString()) // define
918 if (md->argumentList()->count()==0) // special case for "foo()" to
919 // disguish it from "foo".
921 t << " <param></param>" << endl;
925 ArgumentListIterator ali(*md->argumentList());
927 for (ali.toFirst();(a=ali.current());++ali)
929 t << " <param><defname>" << a->type << "</defname></param>" << endl;
934 if (md->hasOneLineInitializer() || md->hasMultiLineInitializer())
936 t << " <initializer>";
937 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->initializer());
938 t << "</initializer>" << endl;
941 if (md->excpString())
943 t << " <exceptions>";
944 linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString());
945 t << "</exceptions>" << endl;
948 if (md->memberType()==MemberType_Enumeration) // enum
950 MemberList *enumFields = md->enumFieldList();
953 MemberListIterator emli(*enumFields);
955 for (emli.toFirst();(emd=emli.current());++emli)
957 ti << " <member refid=\"" << memberOutputFileBase(emd)
958 << "_1" << emd->anchor() << "\" kind=\"enumvalue\"><name>"
959 << convertToXML(emd->name()) << "</name></member>" << endl;
961 t << " <enumvalue id=\"" << memberOutputFileBase(emd) << "_1"
962 << emd->anchor() << "\" prot=\"";
963 switch (emd->protection())
965 case Public: t << "public"; break;
966 case Protected: t << "protected"; break;
967 case Private: t << "private"; break;
968 case Package: t << "package"; break;
972 writeXMLString(t,emd->name());
973 t << "</name>" << endl;
974 if (!emd->initializer().isEmpty())
976 t << " <initializer>";
977 writeXMLString(t,emd->initializer());
978 t << "</initializer>" << endl;
980 t << " <briefdescription>" << endl;
981 writeXMLDocBlock(t,emd->briefFile(),emd->briefLine(),emd->getOuterScope(),emd,emd->briefDescription());
982 t << " </briefdescription>" << endl;
983 t << " <detaileddescription>" << endl;
984 writeXMLDocBlock(t,emd->docFile(),emd->docLine(),emd->getOuterScope(),emd,emd->documentation());
985 t << " </detaileddescription>" << endl;
986 t << " </enumvalue>" << endl;
990 t << " <briefdescription>" << endl;
991 writeXMLDocBlock(t,md->briefFile(),md->briefLine(),md->getOuterScope(),md,md->briefDescription());
992 t << " </briefdescription>" << endl;
993 t << " <detaileddescription>" << endl;
994 writeXMLDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
995 t << " </detaileddescription>" << endl;
996 t << " <inbodydescription>" << endl;
997 writeXMLDocBlock(t,md->docFile(),md->inbodyLine(),md->getOuterScope(),md,md->inbodyDocumentation());
998 t << " </inbodydescription>" << endl;
999 if (md->getDefLine()!=-1)
1001 t << " <location file=\""
1002 << stripFromPath(md->getDefFileName()) << "\" line=\""
1003 << md->getDefLine() << "\"" << " column=\""
1004 << md->getDefColumn() << "\"" ;
1005 if (md->getStartBodyLine()!=-1)
1007 FileDef *bodyDef = md->getBodyDef();
1010 t << " bodyfile=\"" << stripFromPath(bodyDef->absFilePath()) << "\"";
1012 t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\""
1013 << md->getEndBodyLine() << "\"";
1018 //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
1019 MemberSDict *mdict = md->getReferencesMembers();
1022 MemberSDict::Iterator mdi(*mdict);
1024 for (mdi.toFirst();(rmd=mdi.current());++mdi)
1026 writeMemberReference(t,def,rmd,"references");
1029 mdict = md->getReferencedByMembers();
1032 MemberSDict::Iterator mdi(*mdict);
1034 for (mdi.toFirst();(rmd=mdi.current());++mdi)
1036 writeMemberReference(t,def,rmd,"referencedby");
1040 t << " </memberdef>" << endl;
1043 static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t,
1044 MemberList *ml,const char *kind,const char *header=0,
1045 const char *documentation=0)
1048 MemberListIterator mli(*ml);
1051 for (mli.toFirst();(md=mli.current());++mli)
1053 // namespace members are also inserted in the file scope, but
1054 // to prevent this duplication in the XML output, we filter those here.
1055 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1060 if (count==0) return; // empty list
1062 t << " <sectiondef kind=\"" << kind << "\">" << endl;
1065 t << " <header>" << convertToXML(header) << "</header>" << endl;
1069 t << " <description>";
1070 writeXMLDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
1071 t << "</description>" << endl;
1073 for (mli.toFirst();(md=mli.current());++mli)
1075 // namespace members are also inserted in the file scope, but
1076 // to prevent this duplication in the XML output, we filter those here.
1077 if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
1079 generateXMLForMember(md,ti,t,d);
1082 t << " </sectiondef>" << endl;
1085 static void writeListOfAllMembers(ClassDef *cd,FTextStream &t)
1087 t << " <listofallmembers>" << endl;
1088 if (cd->memberNameInfoSDict())
1090 MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
1091 MemberNameInfo *mni;
1092 for (mnii.toFirst();(mni=mnii.current());++mnii)
1094 MemberNameInfoIterator mii(*mni);
1096 for (mii.toFirst();(mi=mii.current());++mii)
1098 MemberDef *md=mi->memberDef;
1099 if (md->name().at(0)!='@') // skip anonymous members
1101 Protection prot = mi->prot;
1102 Specifier virt=md->virtualness();
1103 t << " <member refid=\"" << memberOutputFileBase(md) << "_1" <<
1104 md->anchor() << "\" prot=\"";
1107 case Public: t << "public"; break;
1108 case Protected: t << "protected"; break;
1109 case Private: t << "private"; break;
1110 case Package: t << "package"; break;
1115 case Normal: t << "non-virtual"; break;
1116 case Virtual: t << "virtual"; break;
1117 case Pure: t << "pure-virtual"; break;
1120 if (!mi->ambiguityResolutionScope.isEmpty())
1122 t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\"";
1124 t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" <<
1125 convertToXML(md->name()) << "</name></member>" << endl;
1130 t << " </listofallmembers>" << endl;
1133 static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
1137 ClassSDict::Iterator cli(*cl);
1139 for (cli.toFirst();(cd=cli.current());++cli)
1141 if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
1143 t << " <innerclass refid=\"" << classOutputFileBase(cd)
1145 switch(cd->protection())
1147 case Public: t << "public"; break;
1148 case Protected: t << "protected"; break;
1149 case Private: t << "private"; break;
1150 case Package: t << "package"; break;
1152 t << "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
1158 static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
1162 NamespaceSDict::Iterator nli(*nl);
1164 for (nli.toFirst();(nd=nli.current());++nli)
1166 if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
1168 t << " <innernamespace refid=\"" << nd->getOutputFileBase()
1169 << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
1175 static void writeInnerFiles(const FileList *fl,FTextStream &t)
1179 QListIterator<FileDef> fli(*fl);
1181 for (fli.toFirst();(fd=fli.current());++fli)
1183 t << " <innerfile refid=\"" << fd->getOutputFileBase()
1184 << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl;
1189 static void writeInnerPages(const PageSDict *pl,FTextStream &t)
1193 PageSDict::Iterator pli(*pl);
1195 for (pli.toFirst();(pd=pli.current());++pli)
1197 t << " <innerpage refid=\"" << pd->getOutputFileBase();
1198 if (pd->getGroupDef())
1200 t << "_" << pd->name();
1202 t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
1207 static void writeInnerGroups(const GroupList *gl,FTextStream &t)
1211 GroupListIterator gli(*gl);
1213 for (gli.toFirst();(sgd=gli.current());++gli)
1215 t << " <innergroup refid=\"" << sgd->getOutputFileBase()
1216 << "\">" << convertToXML(sgd->groupTitle())
1217 << "</innergroup>" << endl;
1222 static void writeInnerDirs(const DirList *dl,FTextStream &t)
1226 QListIterator<DirDef> subdirs(*dl);
1228 for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
1230 t << " <innerdir refid=\"" << subdir->getOutputFileBase()
1231 << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl;
1236 static void generateXMLForClass(ClassDef *cd,FTextStream &ti)
1238 // + brief description
1239 // + detailed description
1240 // + template argument list(s)
1243 // + inheritance diagram
1244 // + list of direct super classes
1245 // + list of direct sub classes
1246 // + list of inner classes
1247 // + collaboration diagram
1248 // + list of all members
1249 // + user defined member sections
1250 // + standard member sections
1251 // + detailed member documentation
1252 // - examples using the class
1254 if (cd->isReference()) return; // skip external references.
1255 if (cd->isHidden()) return; // skip hidden classes.
1256 if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1257 if (cd->templateMaster()!=0) return; // skip generated template instances.
1258 if (cd->isArtificial()) return; // skip artificially created classes
1260 msg("Generating XML output for class %s\n",cd->name().data());
1262 ti << " <compound refid=\"" << classOutputFileBase(cd)
1263 << "\" kind=\"" << cd->compoundTypeString()
1264 << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
1266 QCString outputDirectory = Config_getString(XML_OUTPUT);
1267 QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
1269 if (!f.open(IO_WriteOnly))
1271 err("Cannot open file %s for writing!\n",fileName.data());
1275 //t.setEncoding(FTextStream::UnicodeUTF8);
1278 t << " <compounddef id=\""
1279 << classOutputFileBase(cd) << "\" kind=\""
1280 << cd->compoundTypeString() << "\" language=\""
1281 << langToString(cd->getLanguage()) << "\" prot=\"";
1282 switch (cd->protection())
1284 case Public: t << "public"; break;
1285 case Protected: t << "protected"; break;
1286 case Private: t << "private"; break;
1287 case Package: t << "package"; break;
1289 if (cd->isFinal()) t << "\" final=\"yes";
1290 if (cd->isSealed()) t << "\" sealed=\"yes";
1291 if (cd->isAbstract()) t << "\" abstract=\"yes";
1293 t << " <compoundname>";
1294 writeXMLString(t,cd->name());
1295 t << "</compoundname>" << endl;
1296 if (cd->baseClasses())
1298 BaseClassListIterator bcli(*cd->baseClasses());
1300 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1302 t << " <basecompoundref ";
1303 if (bcd->classDef->isLinkable())
1305 t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
1310 case Public: t << "public"; break;
1311 case Protected: t << "protected"; break;
1312 case Private: t << "private"; break;
1313 case Package: ASSERT(0); break;
1318 case Normal: t << "non-virtual"; break;
1319 case Virtual: t << "virtual"; break;
1320 case Pure: t <<"pure-virtual"; break;
1323 if (!bcd->templSpecifiers.isEmpty())
1326 insertTemplateSpecifierInScope(
1327 bcd->classDef->name(),bcd->templSpecifiers)
1332 t << convertToXML(bcd->classDef->displayName());
1334 t << "</basecompoundref>" << endl;
1337 if (cd->subClasses())
1339 BaseClassListIterator bcli(*cd->subClasses());
1341 for (bcli.toFirst();(bcd=bcli.current());++bcli)
1343 t << " <derivedcompoundref refid=\""
1344 << classOutputFileBase(bcd->classDef)
1348 case Public: t << "public"; break;
1349 case Protected: t << "protected"; break;
1350 case Private: t << "private"; break;
1351 case Package: ASSERT(0); break;
1356 case Normal: t << "non-virtual"; break;
1357 case Virtual: t << "virtual"; break;
1358 case Pure: t << "pure-virtual"; break;
1360 t << "\">" << convertToXML(bcd->classDef->displayName())
1361 << "</derivedcompoundref>" << endl;
1365 IncludeInfo *ii=cd->includeInfo();
1368 QCString nm = ii->includeName;
1369 if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1373 if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
1375 t << " refid=\"" << ii->fileDef->getOutputFileBase() << "\"";
1377 t << " local=\"" << (ii->local ? "yes" : "no") << "\">";
1379 t << "</includes>" << endl;
1383 writeInnerClasses(cd->getClassSDict(),t);
1385 writeTemplateList(cd,t);
1386 if (cd->getMemberGroupSDict())
1388 MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
1390 for (;(mg=mgli.current());++mgli)
1392 generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
1393 mg->documentation());
1397 QListIterator<MemberList> mli(cd->getMemberLists());
1399 for (mli.toFirst();(ml=mli.current());++mli)
1401 if ((ml->listType()&MemberListType_detailedLists)==0)
1403 generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1407 t << " <briefdescription>" << endl;
1408 writeXMLDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
1409 t << " </briefdescription>" << endl;
1410 t << " <detaileddescription>" << endl;
1411 writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
1412 t << " </detaileddescription>" << endl;
1413 DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
1414 if (!inheritanceGraph.isTrivial())
1416 t << " <inheritancegraph>" << endl;
1417 inheritanceGraph.writeXML(t);
1418 t << " </inheritancegraph>" << endl;
1420 DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
1421 if (!collaborationGraph.isTrivial())
1423 t << " <collaborationgraph>" << endl;
1424 collaborationGraph.writeXML(t);
1425 t << " </collaborationgraph>" << endl;
1427 t << " <location file=\""
1428 << stripFromPath(cd->getDefFileName()) << "\" line=\""
1429 << cd->getDefLine() << "\"" << " column=\""
1430 << cd->getDefColumn() << "\"" ;
1431 if (cd->getStartBodyLine()!=-1)
1433 FileDef *bodyDef = cd->getBodyDef();
1436 t << " bodyfile=\"" << stripFromPath(bodyDef->absFilePath()) << "\"";
1438 t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
1439 << cd->getEndBodyLine() << "\"";
1442 writeListOfAllMembers(cd,t);
1443 t << " </compounddef>" << endl;
1444 t << "</doxygen>" << endl;
1446 ti << " </compound>" << endl;
1449 static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti)
1451 // + contained class definitions
1452 // + contained namespace definitions
1458 // - files containing (parts of) the namespace definition
1460 if (nd->isReference() || nd->isHidden()) return; // skip external references
1462 ti << " <compound refid=\"" << nd->getOutputFileBase()
1463 << "\" kind=\"namespace\"" << "><name>"
1464 << convertToXML(nd->name()) << "</name>" << endl;
1466 QCString outputDirectory = Config_getString(XML_OUTPUT);
1467 QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
1469 if (!f.open(IO_WriteOnly))
1471 err("Cannot open file %s for writing!\n",fileName.data());
1475 //t.setEncoding(FTextStream::UnicodeUTF8);
1478 t << " <compounddef id=\"" << nd->getOutputFileBase()
1479 << "\" kind=\"namespace\" language=\""
1480 << langToString(nd->getLanguage()) << "\">" << endl;
1481 t << " <compoundname>";
1482 writeXMLString(t,nd->name());
1483 t << "</compoundname>" << endl;
1485 writeInnerClasses(nd->getClassSDict(),t);
1486 writeInnerNamespaces(nd->getNamespaceSDict(),t);
1488 if (nd->getMemberGroupSDict())
1490 MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
1492 for (;(mg=mgli.current());++mgli)
1494 generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
1495 mg->documentation());
1499 QListIterator<MemberList> mli(nd->getMemberLists());
1501 for (mli.toFirst();(ml=mli.current());++mli)
1503 if ((ml->listType()&MemberListType_declarationLists)!=0)
1505 generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1509 t << " <briefdescription>" << endl;
1510 writeXMLDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
1511 t << " </briefdescription>" << endl;
1512 t << " <detaileddescription>" << endl;
1513 writeXMLDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
1514 t << " </detaileddescription>" << endl;
1515 t << " <location file=\""
1516 << stripFromPath(nd->getDefFileName()) << "\" line=\""
1517 << nd->getDefLine() << "\"" << " column=\""
1518 << nd->getDefColumn() << "\"/>" << endl ;
1519 t << " </compounddef>" << endl;
1520 t << "</doxygen>" << endl;
1522 ti << " </compound>" << endl;
1525 static void generateXMLForFile(FileDef *fd,FTextStream &ti)
1528 // + includedby files
1530 // + included by graph
1531 // + contained class definitions
1532 // + contained namespace definitions
1539 // - number of lines
1541 if (fd->isReference()) return; // skip external references
1543 ti << " <compound refid=\"" << fd->getOutputFileBase()
1544 << "\" kind=\"file\"><name>" << convertToXML(fd->name())
1545 << "</name>" << endl;
1547 QCString outputDirectory = Config_getString(XML_OUTPUT);
1548 QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
1550 if (!f.open(IO_WriteOnly))
1552 err("Cannot open file %s for writing!\n",fileName.data());
1556 //t.setEncoding(FTextStream::UnicodeUTF8);
1559 t << " <compounddef id=\"" << fd->getOutputFileBase()
1560 << "\" kind=\"file\" language=\""
1561 << langToString(fd->getLanguage()) << "\">" << endl;
1562 t << " <compoundname>";
1563 writeXMLString(t,fd->name());
1564 t << "</compoundname>" << endl;
1568 if (fd->includeFileList())
1570 QListIterator<IncludeInfo> ili1(*fd->includeFileList());
1571 for (ili1.toFirst();(inc=ili1.current());++ili1)
1574 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1576 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1578 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1579 t << inc->includeName;
1580 t << "</includes>" << endl;
1584 if (fd->includedByFileList())
1586 QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
1587 for (ili2.toFirst();(inc=ili2.current());++ili2)
1589 t << " <includedby";
1590 if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1592 t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1594 t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1595 t << inc->includeName;
1596 t << "</includedby>" << endl;
1600 DotInclDepGraph incDepGraph(fd,FALSE);
1601 if (!incDepGraph.isTrivial())
1603 t << " <incdepgraph>" << endl;
1604 incDepGraph.writeXML(t);
1605 t << " </incdepgraph>" << endl;
1608 DotInclDepGraph invIncDepGraph(fd,TRUE);
1609 if (!invIncDepGraph.isTrivial())
1611 t << " <invincdepgraph>" << endl;
1612 invIncDepGraph.writeXML(t);
1613 t << " </invincdepgraph>" << endl;
1616 if (fd->getClassSDict())
1618 writeInnerClasses(fd->getClassSDict(),t);
1620 if (fd->getNamespaceSDict())
1622 writeInnerNamespaces(fd->getNamespaceSDict(),t);
1625 if (fd->getMemberGroupSDict())
1627 MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
1629 for (;(mg=mgli.current());++mgli)
1631 generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
1632 mg->documentation());
1636 QListIterator<MemberList> mli(fd->getMemberLists());
1638 for (mli.toFirst();(ml=mli.current());++mli)
1640 if ((ml->listType()&MemberListType_declarationLists)!=0)
1642 generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1646 t << " <briefdescription>" << endl;
1647 writeXMLDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
1648 t << " </briefdescription>" << endl;
1649 t << " <detaileddescription>" << endl;
1650 writeXMLDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
1651 t << " </detaileddescription>" << endl;
1652 if (Config_getBool(XML_PROGRAMLISTING))
1654 t << " <programlisting>" << endl;
1655 writeXMLCodeBlock(t,fd);
1656 t << " </programlisting>" << endl;
1658 t << " <location file=\"" << stripFromPath(fd->getDefFileName()) << "\"/>" << endl;
1659 t << " </compounddef>" << endl;
1660 t << "</doxygen>" << endl;
1662 ti << " </compound>" << endl;
1665 static void generateXMLForGroup(GroupDef *gd,FTextStream &ti)
1676 // + brief description
1677 // + detailed description
1679 if (gd->isReference()) return; // skip external references
1681 ti << " <compound refid=\"" << gd->getOutputFileBase()
1682 << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
1684 QCString outputDirectory = Config_getString(XML_OUTPUT);
1685 QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
1687 if (!f.open(IO_WriteOnly))
1689 err("Cannot open file %s for writing!\n",fileName.data());
1694 //t.setEncoding(FTextStream::UnicodeUTF8);
1696 t << " <compounddef id=\""
1697 << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
1698 t << " <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
1699 t << " <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
1701 writeInnerFiles(gd->getFiles(),t);
1702 writeInnerClasses(gd->getClasses(),t);
1703 writeInnerNamespaces(gd->getNamespaces(),t);
1704 writeInnerPages(gd->getPages(),t);
1705 writeInnerGroups(gd->getSubGroups(),t);
1707 if (gd->getMemberGroupSDict())
1709 MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
1711 for (;(mg=mgli.current());++mgli)
1713 generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
1714 mg->documentation());
1718 QListIterator<MemberList> mli(gd->getMemberLists());
1720 for (mli.toFirst();(ml=mli.current());++mli)
1722 if ((ml->listType()&MemberListType_declarationLists)!=0)
1724 generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1728 t << " <briefdescription>" << endl;
1729 writeXMLDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
1730 t << " </briefdescription>" << endl;
1731 t << " <detaileddescription>" << endl;
1732 writeXMLDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
1733 t << " </detaileddescription>" << endl;
1734 t << " </compounddef>" << endl;
1735 t << "</doxygen>" << endl;
1737 ti << " </compound>" << endl;
1740 static void generateXMLForDir(DirDef *dd,FTextStream &ti)
1742 if (dd->isReference()) return; // skip external references
1743 ti << " <compound refid=\"" << dd->getOutputFileBase()
1744 << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName())
1745 << "</name>" << endl;
1747 QCString outputDirectory = Config_getString(XML_OUTPUT);
1748 QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
1750 if (!f.open(IO_WriteOnly))
1752 err("Cannot open file %s for writing!\n",fileName.data());
1757 //t.setEncoding(FTextStream::UnicodeUTF8);
1759 t << " <compounddef id=\""
1760 << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl;
1761 t << " <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl;
1763 writeInnerDirs(&dd->subDirs(),t);
1764 writeInnerFiles(dd->getFiles(),t);
1766 t << " <briefdescription>" << endl;
1767 writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
1768 t << " </briefdescription>" << endl;
1769 t << " <detaileddescription>" << endl;
1770 writeXMLDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
1771 t << " </detaileddescription>" << endl;
1772 t << " <location file=\"" << stripFromPath(dd->name()) << "\"/>" << endl;
1773 t << " </compounddef>" << endl;
1774 t << "</doxygen>" << endl;
1776 ti << " </compound>" << endl;
1779 static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
1785 const char *kindName = isExample ? "example" : "page";
1787 if (pd->isReference()) return;
1789 QCString pageName = pd->getOutputFileBase();
1790 if (pd->getGroupDef())
1792 pageName+=(QCString)"_"+pd->name();
1794 if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
1796 ti << " <compound refid=\"" << pageName
1797 << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name())
1798 << "</name>" << endl;
1800 QCString outputDirectory = Config_getString(XML_OUTPUT);
1801 QCString fileName=outputDirectory+"/"+pageName+".xml";
1803 if (!f.open(IO_WriteOnly))
1805 err("Cannot open file %s for writing!\n",fileName.data());
1810 //t.setEncoding(FTextStream::UnicodeUTF8);
1812 t << " <compounddef id=\"" << pageName;
1813 t << "\" kind=\"" << kindName << "\">" << endl;
1814 t << " <compoundname>" << convertToXML(pd->name())
1815 << "</compoundname>" << endl;
1817 if (pd==Doxygen::mainPage) // main page is special
1820 if (!pd->title().isEmpty() && pd->title().lower()!="notitle")
1822 title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()));
1826 title = Config_getString(PROJECT_NAME);
1828 t << " <title>" << convertToXML(convertCharEntitiesToUTF8(title))
1829 << "</title>" << endl;
1833 SectionInfo *si = Doxygen::sectionDict->find(pd->name());
1836 t << " <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title)))
1837 << "</title>" << endl;
1840 writeInnerPages(pd->getSubPages(),t);
1843 t << " <tableofcontents/>" << endl;
1845 t << " <briefdescription>" << endl;
1846 writeXMLDocBlock(t,pd->briefFile(),pd->briefLine(),pd,0,pd->briefDescription());
1847 t << " </briefdescription>" << endl;
1848 t << " <detaileddescription>" << endl;
1851 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1852 pd->documentation()+"\n\\include "+pd->name());
1856 writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1857 pd->documentation());
1859 t << " </detaileddescription>" << endl;
1861 t << " </compounddef>" << endl;
1862 t << "</doxygen>" << endl;
1864 ti << " </compound>" << endl;
1876 QCString outputDirectory = Config_getString(XML_OUTPUT);
1877 QDir xmlDir(outputDirectory);
1878 createSubDirs(xmlDir);
1880 ResourceMgr::instance().copyResource("index.xsd",outputDirectory);
1882 QCString fileName=outputDirectory+"/compound.xsd";
1884 if (!f.open(IO_WriteOnly))
1886 err("Cannot open file %s for writing!\n",fileName.data());
1890 // write compound.xsd, but replace special marker with the entities
1891 QCString compound_xsd = ResourceMgr::instance().getAsString("compound.xsd");
1892 const char *startLine = compound_xsd.data();
1895 // find end of the line
1896 const char *endLine = startLine+1;
1897 while (*endLine && *(endLine-1)!='\n') endLine++; // skip to end of the line including \n
1898 int len=endLine-startLine;
1902 qstrncpy(s.rawData(),startLine,len);
1904 if (s.find("<!-- Automatically insert here the HTML entities -->")!=-1)
1907 HtmlEntityMapper::instance()->writeXMLSchema(t);
1911 f.writeBlock(startLine,len);
1918 fileName=outputDirectory+"/index.xml";
1919 f.setName(fileName);
1920 if (!f.open(IO_WriteOnly))
1922 err("Cannot open file %s for writing!\n",fileName.data());
1926 //t.setEncoding(FTextStream::UnicodeUTF8);
1928 // write index header
1929 t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
1930 t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
1931 t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" ";
1932 t << "version=\"" << versionString << "\">" << endl;
1935 ClassSDict::Iterator cli(*Doxygen::classSDict);
1937 for (cli.toFirst();(cd=cli.current());++cli)
1939 generateXMLForClass(cd,t);
1943 // ClassSDict::Iterator cli(Doxygen::hiddenClasses);
1945 // for (cli.toFirst();(cd=cli.current());++cli)
1947 // msg("Generating XML output for class %s\n",cd->name().data());
1948 // generateXMLForClass(cd,t);
1951 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1953 for (nli.toFirst();(nd=nli.current());++nli)
1955 msg("Generating XML output for namespace %s\n",nd->name().data());
1956 generateXMLForNamespace(nd,t);
1958 FileNameListIterator fnli(*Doxygen::inputNameList);
1960 for (;(fn=fnli.current());++fnli)
1962 FileNameIterator fni(*fn);
1964 for (;(fd=fni.current());++fni)
1966 msg("Generating XML output for file %s\n",fd->name().data());
1967 generateXMLForFile(fd,t);
1970 GroupSDict::Iterator gli(*Doxygen::groupSDict);
1972 for (;(gd=gli.current());++gli)
1974 msg("Generating XML output for group %s\n",gd->name().data());
1975 generateXMLForGroup(gd,t);
1978 PageSDict::Iterator pdi(*Doxygen::pageSDict);
1980 for (pdi.toFirst();(pd=pdi.current());++pdi)
1982 msg("Generating XML output for page %s\n",pd->name().data());
1983 generateXMLForPage(pd,t,FALSE);
1988 DirSDict::Iterator sdi(*Doxygen::directories);
1989 for (sdi.toFirst();(dir=sdi.current());++sdi)
1991 msg("Generate XML output for dir %s\n",dir->name().data());
1992 generateXMLForDir(dir,t);
1996 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
1998 for (pdi.toFirst();(pd=pdi.current());++pdi)
2000 msg("Generating XML output for example %s\n",pd->name().data());
2001 generateXMLForPage(pd,t,TRUE);
2004 if (Doxygen::mainPage)
2006 msg("Generating XML output for the main page\n");
2007 generateXMLForPage(Doxygen::mainPage,t,FALSE);
2010 //t << " </compoundlist>" << endl;
2011 t << "</doxygenindex>" << endl;
2013 writeCombineScript();