Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / xmlgen.cpp
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
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.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15
16 #include <stdlib.h>
17
18 #include <qdir.h>
19 #include <qfile.h>
20 #include <qtextstream.h>
21 #include <qintdict.h>
22
23 #include "xmlgen.h"
24 #include "doxygen.h"
25 #include "message.h"
26 #include "config.h"
27 #include "classlist.h"
28 #include "util.h"
29 #include "defargs.h"
30 #include "outputgen.h"
31 #include "dot.h"
32 #include "pagedef.h"
33 #include "filename.h"
34 #include "version.h"
35 #include "xmldocvisitor.h"
36 #include "docparser.h"
37 #include "language.h"
38 #include "parserintf.h"
39 #include "arguments.h"
40 #include "memberlist.h"
41 #include "groupdef.h"
42 #include "memberdef.h"
43 #include "namespacedef.h"
44 #include "membername.h"
45 #include "membergroup.h"
46 #include "dirdef.h"
47 #include "section.h"
48 #include "htmlentity.h"
49 #include "resourcemgr.h"
50
51 // no debug info
52 #define XML_DB(x) do {} while(0)
53 // debug to stdout
54 //#define XML_DB(x) printf x
55 // debug inside output
56 //#define XML_DB(x) QCString __t;__t.sprintf x;m_t << __t
57
58 //------------------
59
60 /** Helper class mapping MemberList::ListType to a string representing */
61 class XmlSectionMapper : public QIntDict<char>
62 {
63   public:
64     XmlSectionMapper() : QIntDict<char>(47)
65     {
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_decSequenceMembers,"sequence");
101       insert(MemberListType_decDictionaryMembers,"dictionary");
102       insert(MemberListType_decEnumMembers,"enum");
103       insert(MemberListType_decFuncMembers,"func");
104       insert(MemberListType_decVarMembers,"var");
105     }
106 };
107
108 static XmlSectionMapper g_xmlSectionMapper;
109
110
111 inline void writeXMLString(FTextStream &t,const char *s)
112 {
113   t << convertToXML(s);
114 }
115
116 inline void writeXMLCodeString(FTextStream &t,const char *s, int &col)
117 {
118   char c;
119   while ((c=*s++))
120   {
121     switch(c)
122     {
123       case '\t':
124       {
125         static int tabSize = Config_getInt(TAB_SIZE);
126         int spacesToNextTabStop = tabSize - (col%tabSize);
127         col+=spacesToNextTabStop;
128         while (spacesToNextTabStop--) t << "<sp/>";
129         break;
130         }
131       case ' ':  t << "<sp/>"; col++;  break;
132       case '<':  t << "&lt;"; col++;   break;
133       case '>':  t << "&gt;"; col++;   break;
134       case '&':  t << "&amp;"; col++;  break;
135       case '\'': t << "&apos;"; col++; break;
136       case '"':  t << "&quot;"; col++; break;
137       case  1: case  2: case  3: case  4: case  5: case  6: case  7: case  8:
138       case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
139       case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
140       case 27: case 28: case 29: case 30: case 31:
141         // encode invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
142         t << "<sp value=\"" << int(c) << "\"/>";
143         break;
144       default:   s=writeUtf8Char(t,s-1); col++; break;
145     }
146   }
147 }
148
149
150 static void writeXMLHeader(FTextStream &t)
151 {
152   t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
153   t << "<doxygen xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
154   t << "xsi:noNamespaceSchemaLocation=\"compound.xsd\" ";
155   t << "version=\"" << versionString << "\">" << endl;
156 }
157
158 static void writeCombineScript()
159 {
160   QCString outputDirectory = Config_getString(XML_OUTPUT);
161   QCString fileName=outputDirectory+"/combine.xslt";
162   QFile f(fileName);
163   if (!f.open(IO_WriteOnly))
164   {
165     err("Cannot open file %s for writing!\n",fileName.data());
166     return;
167   }
168   FTextStream t(&f);
169   //t.setEncoding(FTextStream::UnicodeUTF8);
170
171   t <<
172   "<!-- XSLT script to combine the generated output into a single file. \n"
173   "     If you have xsltproc you could use:\n"
174   "     xsltproc combine.xslt index.xml >all.xml\n"
175   "-->\n"
176   "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
177   "  <xsl:output method=\"xml\" version=\"1.0\" indent=\"no\" standalone=\"yes\" />\n"
178   "  <xsl:template match=\"/\">\n"
179   "    <doxygen version=\"{doxygenindex/@version}\">\n"
180   "      <!-- Load all doxygen generated xml files -->\n"
181   "      <xsl:for-each select=\"doxygenindex/compound\">\n"
182   "        <xsl:copy-of select=\"document( concat( @refid, '.xml' ) )/doxygen/*\" />\n"
183   "      </xsl:for-each>\n"
184   "    </doxygen>\n"
185   "  </xsl:template>\n"
186   "</xsl:stylesheet>\n";
187
188 }
189
190 void writeXMLLink(FTextStream &t,const char *extRef,const char *compoundId,
191                   const char *anchorId,const char *text,const char *tooltip)
192 {
193   t << "<ref refid=\"" << compoundId;
194   if (anchorId) t << "_1" << anchorId;
195   t << "\" kindref=\"";
196   if (anchorId) t << "member"; else t << "compound"; 
197   t << "\"";
198   if (extRef) t << " external=\"" << extRef << "\"";
199   if (tooltip) t << " tooltip=\"" << convertToXML(tooltip) << "\"";
200   t << ">";
201   writeXMLString(t,text);
202   t << "</ref>";
203 }
204
205 /** Implements TextGeneratorIntf for an XML stream. */
206 class TextGeneratorXMLImpl : public TextGeneratorIntf
207 {
208   public:
209     TextGeneratorXMLImpl(FTextStream &t): m_t(t) {}
210     void writeString(const char *s,bool /*keepSpaces*/) const
211     {
212       writeXMLString(m_t,s); 
213     }
214     void writeBreak(int) const {}
215     void writeLink(const char *extRef,const char *file,
216                    const char *anchor,const char *text
217                   ) const
218     {
219       writeXMLLink(m_t,extRef,file,anchor,text,0);
220     }
221   private:
222     FTextStream &m_t;
223 };
224
225
226 /** Generator for producing XML formatted source code. */
227 void XMLCodeGenerator::codify(const char *text)
228 {
229   XML_DB(("(codify \"%s\")\n",text));
230   if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
231   {
232     m_t << "<highlight class=\"normal\">";
233     m_normalHLNeedStartTag=FALSE;
234   }
235   writeXMLCodeString(m_t,text,m_col);
236 }
237 void XMLCodeGenerator::writeCodeLink(const char *ref,const char *file,
238                    const char *anchor,const char *name,
239                    const char *tooltip)
240 {
241   XML_DB(("(writeCodeLink)\n"));
242   if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
243   {
244     m_t << "<highlight class=\"normal\">";
245     m_normalHLNeedStartTag=FALSE;
246   }
247   writeXMLLink(m_t,ref,file,anchor,name,tooltip);
248   m_col+=qstrlen(name);
249 }
250 void XMLCodeGenerator::writeTooltip(const char *, const DocLinkInfo &, const char *,
251                   const char *, const SourceLinkInfo &, const SourceLinkInfo &
252                  )
253 {
254   XML_DB(("(writeToolTip)\n"));
255 }
256 void XMLCodeGenerator::startCodeLine(bool)
257 {
258   XML_DB(("(startCodeLine)\n"));
259   m_t << "<codeline";
260   if (m_lineNumber!=-1)
261   {
262     m_t << " lineno=\"" << m_lineNumber << "\"";
263     if (!m_refId.isEmpty())
264     {
265       m_t << " refid=\"" << m_refId << "\"";
266       if (m_isMemberRef)
267       {
268         m_t << " refkind=\"member\"";
269       }
270       else
271       {
272         m_t << " refkind=\"compound\"";
273       }
274     }
275     if (!m_external.isEmpty())
276     {
277       m_t << " external=\"" << m_external << "\"";
278     }
279   }
280   m_t << ">";
281   m_insideCodeLine=TRUE;
282   m_col=0;
283 }
284 void XMLCodeGenerator::endCodeLine()
285 {
286   XML_DB(("(endCodeLine)\n"));
287   if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
288   {
289     m_t << "</highlight>";
290     m_normalHLNeedStartTag=TRUE;
291   }
292   m_t << "</codeline>" << endl; // non DocBook
293   m_lineNumber = -1;
294   m_refId.resize(0);
295   m_external.resize(0);
296   m_insideCodeLine=FALSE;
297 }
298 void XMLCodeGenerator::startFontClass(const char *colorClass)
299 {
300   XML_DB(("(startFontClass)\n"));
301   if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
302   {
303     m_t << "</highlight>";
304     m_normalHLNeedStartTag=TRUE;
305   }
306   m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
307   m_insideSpecialHL=TRUE;
308 }
309 void XMLCodeGenerator::endFontClass()
310 {
311   XML_DB(("(endFontClass)\n"));
312   m_t << "</highlight>"; // non DocBook
313   m_insideSpecialHL=FALSE;
314 }
315 void XMLCodeGenerator::writeCodeAnchor(const char *)
316 {
317   XML_DB(("(writeCodeAnchor)\n"));
318 }
319 void XMLCodeGenerator::writeLineNumber(const char *extRef,const char *compId,
320                      const char *anchorId,int l)
321 {
322   XML_DB(("(writeLineNumber)\n"));
323   // we remember the information provided here to use it
324   // at the <codeline> start tag.
325   m_lineNumber = l;
326   if (compId)
327   {
328     m_refId=compId;
329     if (anchorId) m_refId+=(QCString)"_1"+anchorId;
330     m_isMemberRef = anchorId!=0;
331     if (extRef) m_external=extRef;
332   }
333 }
334 void XMLCodeGenerator::finish()
335 {
336   if (m_insideCodeLine) endCodeLine();
337 }
338
339 static void writeTemplateArgumentList(ArgumentList *al,
340                                       FTextStream &t,
341                                       Definition *scope,
342                                       FileDef *fileScope,
343                                       int indent)
344 {
345   QCString indentStr;
346   indentStr.fill(' ',indent);
347   if (al)
348   {
349     t << indentStr << "<templateparamlist>" << endl;
350     ArgumentListIterator ali(*al);
351     Argument *a;
352     for (ali.toFirst();(a=ali.current());++ali)
353     {
354       t << indentStr << "  <param>" << endl;
355       if (!a->type.isEmpty())
356       {
357         t << indentStr <<  "    <type>";
358         linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
359         t << "</type>" << endl;
360       }
361       if (!a->name.isEmpty())
362       {
363         t << indentStr <<  "    <declname>" << a->name << "</declname>" << endl;
364         t << indentStr <<  "    <defname>" << a->name << "</defname>" << endl;
365       }
366       if (!a->defval.isEmpty())
367       {
368         t << indentStr << "    <defval>";
369         linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
370         t << "</defval>" << endl;
371       }
372       if (!a->typeConstraint.isEmpty())
373       {
374         t << indentStr << "    <typeconstraint>";
375         linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->typeConstraint);
376         t << "</typeconstraint>" << endl;
377       }
378       t << indentStr << "  </param>" << endl;
379     }
380     t << indentStr << "</templateparamlist>" << endl;
381   }
382 }
383
384 static void writeMemberTemplateLists(MemberDef *md,FTextStream &t)
385 {
386   ArgumentList *templMd = md->templateArguments();
387   if (templMd) // function template prefix
388   {
389     writeTemplateArgumentList(templMd,t,md->getClassDef(),md->getFileDef(),8);
390   }
391 }
392
393 static void writeTemplateList(ClassDef *cd,FTextStream &t)
394 {
395   writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
396 }
397
398 static void writeXMLDocBlock(FTextStream &t,
399                       const QCString &fileName,
400                       int lineNr,
401                       Definition *scope,
402                       MemberDef * md,
403                       const QCString &text)
404 {
405   QCString stext = text.stripWhiteSpace();
406   if (stext.isEmpty()) return;
407   // convert the documentation string into an abstract syntax tree
408   DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
409   // create a code generator
410   XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
411   // create a parse tree visitor for XML
412   XmlDocVisitor *visitor = new XmlDocVisitor(t,*xmlCodeGen);
413   // visit all nodes
414   root->accept(visitor);
415   // clean up
416   delete visitor;
417   delete xmlCodeGen;
418   delete root;
419   
420 }
421
422 void writeXMLCodeBlock(FTextStream &t,FileDef *fd)
423 {
424   ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
425   SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
426   pIntf->resetCodeParserState();
427   XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t);
428   pIntf->parseCode(*xmlGen,  // codeOutIntf
429                 0,           // scopeName
430                 fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)),
431                 langExt,     // lang
432                 FALSE,       // isExampleBlock
433                 0,           // exampleName
434                 fd,          // fileDef
435                 -1,          // startLine
436                 -1,          // endLine
437                 FALSE,       // inlineFragement
438                 0,           // memberDef
439                 TRUE         // showLineNumbers
440                 );
441   xmlGen->finish();
442   delete xmlGen;
443 }
444
445 static void writeMemberReference(FTextStream &t,Definition *def,MemberDef *rmd,const char *tagName)
446 {
447   QCString scope = rmd->getScopeString();
448   QCString name = rmd->name();
449   if (!scope.isEmpty() && scope!=def->name())
450   {
451     name.prepend(scope+getLanguageSpecificSeparator(rmd->getLanguage()));
452   }
453   t << "        <" << tagName << " refid=\"";
454   t << rmd->getOutputFileBase() << "_1" << rmd->anchor() << "\"";
455   if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef()) 
456   {
457     t << " compoundref=\"" << rmd->getBodyDef()->getOutputFileBase() << "\"";
458     t << " startline=\"" << rmd->getStartBodyLine() << "\"";
459     if (rmd->getEndBodyLine()!=-1)
460     {
461       t << " endline=\"" << rmd->getEndBodyLine() << "\"";
462     }
463   }
464   t << ">" << convertToXML(name) << "</" << tagName << ">" << endl;
465   
466 }
467
468 static void stripQualifiers(QCString &typeStr)
469 {
470   bool done=FALSE;
471   while (!done)
472   {
473     if (typeStr.stripPrefix("static "));
474     else if (typeStr.stripPrefix("virtual "));
475     else if (typeStr.stripPrefix("volatile "));
476     else if (typeStr=="virtual") typeStr="";
477     else done=TRUE;
478   }
479 }
480
481 static QCString classOutputFileBase(ClassDef *cd)
482 {
483   //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
484   //if (inlineGroupedClasses && cd->partOfGroups()!=0) 
485   return cd->getOutputFileBase();
486   //else 
487   //  return cd->getOutputFileBase();
488 }
489
490 static QCString memberOutputFileBase(MemberDef *md)
491 {
492   //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
493   //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0) 
494   //  return md->getClassDef()->getXmlOutputFileBase();
495   //else 
496   //  return md->getOutputFileBase();
497   return md->getOutputFileBase();
498 }
499
500
501 static void generateXMLForMember(MemberDef *md,FTextStream &ti,FTextStream &t,Definition *def)
502 {
503
504   // + declaration/definition arg lists
505   // + reimplements
506   // + reimplementedBy
507   // + exceptions
508   // + const/volatile specifiers
509   // - examples
510   // + source definition
511   // + source references
512   // + source referenced by
513   // - body code 
514   // + template arguments 
515   //     (templateArguments(), definitionTemplateParameterLists())
516   // - call graph
517   
518   // enum values are written as part of the enum
519   if (md->memberType()==MemberType_EnumValue) return;
520   if (md->isHidden()) return;
521   //if (md->name().at(0)=='@') return; // anonymous member
522
523   // group members are only visible in their group
524   //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
525
526   QCString memType;
527   bool isFunc=FALSE;
528   switch (md->memberType())
529   {
530     case MemberType_Define:      memType="define";      break;
531     case MemberType_Function:    memType="function";    isFunc=TRUE; break;
532     case MemberType_Variable:    memType="variable";    break;
533     case MemberType_Typedef:     memType="typedef";     break;
534     case MemberType_Enumeration: memType="enum";        break;
535     case MemberType_EnumValue:   ASSERT(0);             break;
536     case MemberType_Signal:      memType="signal";      isFunc=TRUE; break;
537     case MemberType_Slot:        memType="slot";        isFunc=TRUE; break;
538     case MemberType_Friend:      memType="friend";      isFunc=TRUE; break;
539     case MemberType_DCOP:        memType="dcop";        isFunc=TRUE; break;
540     case MemberType_Property:    memType="property";    break;
541     case MemberType_Event:       memType="event";       break;
542     case MemberType_Interface:   memType="interface";   break;
543     case MemberType_Service:     memType="service";     break;
544     case MemberType_Sequence:    memType="sequence";    break;
545     case MemberType_Dictionary:  memType="dictionary";  break;
546   }
547
548   ti << "    <member refid=\"" << memberOutputFileBase(md) 
549      << "_1" << md->anchor() << "\" kind=\"" << memType << "\"><name>" 
550      << convertToXML(md->name()) << "</name></member>" << endl;
551   
552   QCString scopeName;
553   if (md->getClassDef()) 
554     scopeName=md->getClassDef()->name();
555   else if (md->getNamespaceDef()) 
556     scopeName=md->getNamespaceDef()->name();
557     
558   t << "      <memberdef kind=\"";
559   //enum { define_t,variable_t,typedef_t,enum_t,function_t } xmlType = function_t;
560   t << memType << "\" id=\"";
561   if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
562   {
563     t << md->getGroupDef()->getOutputFileBase();
564   }
565   else
566   {
567     t << memberOutputFileBase(md);
568   }
569   t << "_1"      // encoded `:' character (see util.cpp:convertNameToFile)
570     << md->anchor();
571   t << "\" prot=\"";
572   switch(md->protection())
573   {
574     case Public:    t << "public";     break;
575     case Protected: t << "protected";  break;
576     case Private:   t << "private";    break;
577     case Package:   t << "package";    break;
578   }
579   t << "\"";
580
581   t << " static=\"";
582   if (md->isStatic()) t << "yes"; else t << "no";
583   t << "\"";
584
585   if (isFunc)
586   {
587     ArgumentList *al = md->argumentList();
588     t << " const=\"";
589     if (al!=0 && al->constSpecifier)    t << "yes"; else t << "no"; 
590     t << "\"";
591
592     t << " explicit=\"";
593     if (md->isExplicit()) t << "yes"; else t << "no";
594     t << "\"";
595
596     t << " inline=\"";
597     if (md->isInline()) t << "yes"; else t << "no";
598     t << "\"";
599
600     if (al!=0 && al->refQualifier!=RefQualifierNone)
601     {
602       t << " refqual=\"";
603       if (al->refQualifier==RefQualifierLValue) t << "lvalue"; else t << "rvalue";
604       t << "\"";
605     }
606
607     if (md->isFinal())
608     {
609       t << " final=\"yes\"";
610     }
611
612     if (md->isSealed())
613     {
614       t << " sealed=\"yes\"";
615     }
616
617     if (md->isNew())
618     {
619       t << " new=\"yes\"";
620     }
621
622     if (md->isOptional())
623     {
624       t << " optional=\"yes\"";
625     }
626
627     if (md->isRequired())
628     {
629       t << " required=\"yes\"";
630     }
631
632     if (al && al->volatileSpecifier)
633     {
634       t << " volatile=\"yes\"";
635     }
636
637     t << " virt=\"";
638     switch (md->virtualness())
639     {
640       case Normal:  t << "non-virtual";  break;
641       case Virtual: t << "virtual";      break;
642       case Pure:    t << "pure-virtual"; break;
643       default: ASSERT(0);
644     }
645     t << "\"";
646   }
647
648   if (md->memberType() == MemberType_Enumeration)
649   {
650     t << " strong=\"";
651     if (md->isStrong()) t << "yes"; else t << "no";
652     t << "\"";
653   }
654
655   if (md->memberType() == MemberType_Variable)
656   {
657     //ArgumentList *al = md->argumentList();
658     //t << " volatile=\"";
659     //if (al && al->volatileSpecifier) t << "yes"; else t << "no"; 
660
661     t << " mutable=\"";
662     if (md->isMutable()) t << "yes"; else t << "no";
663     t << "\"";
664     
665     if (md->isInitonly())
666     {
667       t << " initonly=\"yes\"";
668     }
669     if (md->isAttribute())
670     {
671       t << " attribute=\"yes\"";
672     }
673     if (md->isUNOProperty())
674     {
675       t << " property=\"yes\"";
676     }
677     if (md->isReadonly())
678     {
679       t << " readonly=\"yes\"";
680     }
681     if (md->isBound())
682     {
683       t << " bound=\"yes\"";
684     }
685     if (md->isRemovable())
686     {
687       t << " removable=\"yes\"";
688     }
689     if (md->isConstrained())
690     {
691       t << " constrained=\"yes\"";
692     }
693     if (md->isTransient())
694     {
695       t << " transient=\"yes\"";
696     }
697     if (md->isMaybeVoid())
698     {
699       t << " maybevoid=\"yes\"";
700     }
701     if (md->isMaybeDefault())
702     {
703       t << " maybedefault=\"yes\"";
704     }
705     if (md->isMaybeAmbiguous())
706     {
707       t << " maybeambiguous=\"yes\"";
708     }
709   }
710   else if (md->memberType() == MemberType_Property)
711   {
712     t << " readable=\"";
713     if (md->isReadable()) t << "yes"; else t << "no";
714     t << "\"";
715
716     t << " writable=\"";
717     if (md->isWritable()) t << "yes"; else t << "no";
718     t << "\"";
719
720     t << " gettable=\"";
721     if (md->isGettable()) t << "yes"; else t << "no";
722     t << "\"";
723
724     t << " privategettable=\"";
725     if (md->isPrivateGettable()) t << "yes"; else t << "no";
726     t << "\"";
727
728     t << " protectedgettable=\"";
729     if (md->isProtectedGettable()) t << "yes"; else t << "no";
730     t << "\"";
731
732     t << " settable=\"";
733     if (md->isSettable()) t << "yes"; else t << "no";
734     t << "\"";
735
736     t << " privatesettable=\"";
737     if (md->isPrivateSettable()) t << "yes"; else t << "no";
738     t << "\"";
739
740     t << " protectedsettable=\"";
741     if (md->isProtectedSettable()) t << "yes"; else t << "no";
742     t << "\"";
743
744     if (md->isAssign() || md->isCopy() || md->isRetain() || md->isStrong() || md->isWeak())
745     {
746       t << " accessor=\"";
747       if (md->isAssign())      t << "assign";
748       else if (md->isCopy())   t << "copy";
749       else if (md->isRetain()) t << "retain";
750       else if (md->isStrong()) t << "strong";
751       else if (md->isWeak())   t << "weak";
752       t << "\"";
753     }
754   }
755   else if (md->memberType() == MemberType_Event)
756   {
757     t << " add=\"";
758     if (md->isAddable()) t << "yes"; else t << "no";
759     t << "\"";
760
761     t << " remove=\"";
762     if (md->isRemovable()) t << "yes"; else t << "no";
763     t << "\"";
764
765     t << " raise=\"";
766     if (md->isRaisable()) t << "yes"; else t << "no";
767     t << "\"";
768   }
769
770   t << ">" << endl;
771
772   if (md->memberType()!=MemberType_Define &&
773       md->memberType()!=MemberType_Enumeration
774      )
775   {
776     writeMemberTemplateLists(md,t);
777     QCString typeStr = md->typeString(); //replaceAnonymousScopes(md->typeString());
778     stripQualifiers(typeStr);
779     t << "        <type>";
780     linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,typeStr);
781     t << "</type>" << endl;
782     t << "        <definition>" << convertToXML(md->definition()) << "</definition>" << endl;
783     t << "        <argsstring>" << convertToXML(md->argsString()) << "</argsstring>" << endl;
784   }
785
786   if (md->memberType() == MemberType_Enumeration)
787   {
788     t << "        <type>";
789     linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->enumBaseType());
790     t << "</type>" << endl;
791   }
792
793   t << "        <name>" << convertToXML(md->name()) << "</name>" << endl;
794   
795   if (md->memberType() == MemberType_Property)
796   {
797     if (md->isReadable())
798       t << "        <read>" << convertToXML(md->getReadAccessor()) << "</read>" << endl;
799     if (md->isWritable())
800       t << "        <write>" << convertToXML(md->getWriteAccessor()) << "</write>" << endl;
801   }
802
803   if (md->memberType()==MemberType_Variable && md->bitfieldString())
804   {
805     QCString bitfield = md->bitfieldString();
806     if (bitfield.at(0)==':') bitfield=bitfield.mid(1);
807     t << "        <bitfield>" << convertToXML(bitfield) << "</bitfield>" << endl;
808   }
809   
810   MemberDef *rmd = md->reimplements();
811   if (rmd)
812   {
813     t << "        <reimplements refid=\"" 
814       << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
815       << convertToXML(rmd->name()) << "</reimplements>" << endl;
816   }
817   MemberList *rbml = md->reimplementedBy();
818   if (rbml)
819   {
820     MemberListIterator mli(*rbml);
821     for (mli.toFirst();(rmd=mli.current());++mli)
822     {
823       t << "        <reimplementedby refid=\"" 
824         << memberOutputFileBase(rmd) << "_1" << rmd->anchor() << "\">"
825         << convertToXML(rmd->name()) << "</reimplementedby>" << endl;
826     }
827   }
828
829   if (isFunc) //function
830   {
831     ArgumentList *declAl = md->declArgumentList();
832     ArgumentList *defAl = md->argumentList();
833     if (declAl && defAl && declAl->count()>0)
834     {
835       ArgumentListIterator declAli(*declAl);
836       ArgumentListIterator defAli(*defAl);
837       Argument *a;
838       for (declAli.toFirst();(a=declAli.current());++declAli)
839       {
840         Argument *defArg = defAli.current();
841         t << "        <param>" << endl;
842         if (!a->attrib.isEmpty())
843         {
844           t << "          <attributes>";
845           writeXMLString(t,a->attrib);
846           t << "</attributes>" << endl;
847         }
848         if (!a->type.isEmpty())
849         {
850           t << "          <type>";
851           linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->type);
852           t << "</type>" << endl;
853         }
854         if (!a->name.isEmpty())
855         {
856           t << "          <declname>";
857           writeXMLString(t,a->name); 
858           t << "</declname>" << endl;
859         }
860         if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
861         {
862           t << "          <defname>";
863           writeXMLString(t,defArg->name);
864           t << "</defname>" << endl;
865         }
866         if (!a->array.isEmpty())
867         {
868           t << "          <array>"; 
869           writeXMLString(t,a->array); 
870           t << "</array>" << endl;
871         }
872         if (!a->defval.isEmpty())
873         {
874           t << "          <defval>";
875           linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,a->defval);
876           t << "</defval>" << endl;
877         }
878         if (defArg && defArg->hasDocumentation())
879         {
880           t << "          <briefdescription>";
881           writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),
882                            md->getOuterScope(),md,defArg->docs);
883           t << "</briefdescription>" << endl;
884         }
885         t << "        </param>" << endl;
886         if (defArg) ++defAli;
887       }
888     }
889   }
890   else if (md->memberType()==MemberType_Define && 
891           md->argsString()) // define
892   {
893     if (md->argumentList()->count()==0) // special case for "foo()" to
894                                         // disguish it from "foo".
895     {
896       t << "        <param></param>" << endl;
897     }
898     else
899     {
900       ArgumentListIterator ali(*md->argumentList());
901       Argument *a;
902       for (ali.toFirst();(a=ali.current());++ali)
903       {
904         t << "        <param><defname>" << a->type << "</defname></param>" << endl;
905       }
906     }
907   }
908
909   if (md->hasOneLineInitializer() || md->hasMultiLineInitializer())
910   {
911     t << "        <initializer>";
912     linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->initializer());
913     t << "</initializer>" << endl;
914   }
915
916   if (md->excpString())
917   {
918     t << "        <exceptions>";
919     linkifyText(TextGeneratorXMLImpl(t),def,md->getBodyDef(),md,md->excpString());
920     t << "</exceptions>" << endl;
921   }
922   
923   if (md->memberType()==MemberType_Enumeration) // enum
924   {
925     MemberList *enumFields = md->enumFieldList();
926     if (enumFields)
927     {
928       MemberListIterator emli(*enumFields);
929       MemberDef *emd;
930       for (emli.toFirst();(emd=emli.current());++emli)
931       {
932         ti << "    <member refid=\"" << memberOutputFileBase(md)
933            << "_1" << emd->anchor() << "\" kind=\"enumvalue\"><name>"
934            << convertToXML(emd->name()) << "</name></member>" << endl;
935
936         t << "        <enumvalue id=\"" << memberOutputFileBase(md) << "_1"
937           << emd->anchor() << "\" prot=\"";
938         switch (emd->protection())
939         {
940           case Public:    t << "public";    break;
941           case Protected: t << "protected"; break;
942           case Private:   t << "private";   break;
943           case Package:   t << "package";   break;
944         }
945         t << "\">" << endl;
946         t << "          <name>";
947         writeXMLString(t,emd->name());
948         t << "</name>" << endl;
949         if (!emd->initializer().isEmpty())
950         {
951           t << "          <initializer>";
952           writeXMLString(t,emd->initializer());
953           t << "</initializer>" << endl;
954         }
955         t << "          <briefdescription>" << endl;
956         writeXMLDocBlock(t,emd->briefFile(),emd->briefLine(),emd->getOuterScope(),emd,emd->briefDescription());
957         t << "          </briefdescription>" << endl;
958         t << "          <detaileddescription>" << endl;
959         writeXMLDocBlock(t,emd->docFile(),emd->docLine(),emd->getOuterScope(),emd,emd->documentation());
960         t << "          </detaileddescription>" << endl;
961         t << "        </enumvalue>" << endl;
962       }
963     }
964   }
965   t << "        <briefdescription>" << endl;
966   writeXMLDocBlock(t,md->briefFile(),md->briefLine(),md->getOuterScope(),md,md->briefDescription());
967   t << "        </briefdescription>" << endl;
968   t << "        <detaileddescription>" << endl;
969   writeXMLDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
970   t << "        </detaileddescription>" << endl;
971   t << "        <inbodydescription>" << endl;
972   writeXMLDocBlock(t,md->docFile(),md->inbodyLine(),md->getOuterScope(),md,md->inbodyDocumentation());
973   t << "        </inbodydescription>" << endl;
974   if (md->getDefLine()!=-1)
975   {
976     t << "        <location file=\"" 
977       << stripFromPath(md->getDefFileName()) << "\" line=\"" 
978       << md->getDefLine() << "\"" << " column=\"" 
979       << md->getDefColumn() << "\"" ;
980     if (md->getStartBodyLine()!=-1)
981     {
982       FileDef *bodyDef = md->getBodyDef();
983       if (bodyDef)
984       {
985         t << " bodyfile=\"" << stripFromPath(bodyDef->absFilePath()) << "\"";
986       }
987       t << " bodystart=\"" << md->getStartBodyLine() << "\" bodyend=\"" 
988         << md->getEndBodyLine() << "\"";
989     }
990     t << "/>" << endl;
991   }
992
993   //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
994   MemberSDict *mdict = md->getReferencesMembers();
995   if (mdict)
996   {
997     MemberSDict::Iterator mdi(*mdict);
998     MemberDef *rmd;
999     for (mdi.toFirst();(rmd=mdi.current());++mdi)
1000     {
1001       writeMemberReference(t,def,rmd,"references");
1002     }
1003   }
1004   mdict = md->getReferencedByMembers();
1005   if (mdict)
1006   {
1007     MemberSDict::Iterator mdi(*mdict);
1008     MemberDef *rmd;
1009     for (mdi.toFirst();(rmd=mdi.current());++mdi)
1010     {
1011       writeMemberReference(t,def,rmd,"referencedby");
1012     }
1013   }
1014   
1015   t << "      </memberdef>" << endl;
1016 }
1017
1018 // namespace members are also inserted in the file scope, but
1019 // to prevent this duplication in the XML output, we optionally filter those here.
1020 static bool memberVisible(Definition *d,MemberDef *md)
1021 {
1022     return Config_getBool(XML_NS_MEMB_FILE_SCOPE) ||
1023            d->definitionType()!=Definition::TypeFile ||
1024            md->getNamespaceDef()==0;
1025 }
1026
1027 static void generateXMLSection(Definition *d,FTextStream &ti,FTextStream &t,
1028                       MemberList *ml,const char *kind,const char *header=0,
1029                       const char *documentation=0)
1030 {
1031   if (ml==0) return;
1032   MemberListIterator mli(*ml);
1033   MemberDef *md;
1034   int count=0;
1035   for (mli.toFirst();(md=mli.current());++mli)
1036   {
1037     if (memberVisible(d,md))
1038     {
1039       count++;
1040     }
1041   }
1042   if (count==0) return; // empty list
1043
1044   t << "      <sectiondef kind=\"" << kind << "\">" << endl;
1045   if (header)
1046   {
1047     t << "      <header>" << convertToXML(header) << "</header>" << endl;
1048   }
1049   if (documentation)
1050   {
1051     t << "      <description>";
1052     writeXMLDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
1053     t << "</description>" << endl;
1054   }
1055   for (mli.toFirst();(md=mli.current());++mli)
1056   {
1057     if (memberVisible(d,md))
1058     {
1059       generateXMLForMember(md,ti,t,d);
1060     }
1061   }
1062   t << "      </sectiondef>" << endl;
1063 }
1064
1065 static void writeListOfAllMembers(ClassDef *cd,FTextStream &t)
1066 {
1067   t << "    <listofallmembers>" << endl;
1068   if (cd->memberNameInfoSDict())
1069   {
1070     MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
1071     MemberNameInfo *mni;
1072     for (mnii.toFirst();(mni=mnii.current());++mnii)
1073     {
1074       MemberNameInfoIterator mii(*mni);
1075       MemberInfo *mi;
1076       for (mii.toFirst();(mi=mii.current());++mii)
1077       {
1078         MemberDef *md=mi->memberDef;
1079         if (md->name().at(0)!='@') // skip anonymous members
1080         {
1081           Protection prot = mi->prot;
1082           Specifier virt=md->virtualness();
1083           t << "      <member refid=\"" << memberOutputFileBase(md) << "_1" <<
1084             md->anchor() << "\" prot=\"";
1085           switch (prot)
1086           {
1087             case Public:    t << "public";    break;
1088             case Protected: t << "protected"; break;
1089             case Private:   t << "private";   break;
1090             case Package:   t << "package";   break;
1091           }
1092           t << "\" virt=\"";
1093           switch(virt)
1094           {
1095             case Normal:  t << "non-virtual";  break;
1096             case Virtual: t << "virtual";      break;
1097             case Pure:    t << "pure-virtual"; break;
1098           }
1099           t << "\"";
1100           if (!mi->ambiguityResolutionScope.isEmpty())
1101           {
1102             t << " ambiguityscope=\"" << convertToXML(mi->ambiguityResolutionScope) << "\"";
1103           }
1104           t << "><scope>" << convertToXML(cd->name()) << "</scope><name>" << 
1105             convertToXML(md->name()) << "</name></member>" << endl;
1106         }
1107       }
1108     }
1109   }
1110   t << "    </listofallmembers>" << endl;
1111 }
1112
1113 static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
1114 {
1115   if (cl)
1116   {
1117     ClassSDict::Iterator cli(*cl);
1118     ClassDef *cd;
1119     for (cli.toFirst();(cd=cli.current());++cli)
1120     {
1121       if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
1122       {
1123         t << "    <innerclass refid=\"" << classOutputFileBase(cd)
1124           << "\" prot=\"";
1125         switch(cd->protection())
1126         {
1127            case Public:    t << "public";     break;
1128            case Protected: t << "protected";  break;
1129            case Private:   t << "private";    break;
1130            case Package:   t << "package";    break;
1131         }
1132         t << "\">" << convertToXML(cd->name()) << "</innerclass>" << endl;
1133       }
1134     }
1135   }
1136 }
1137
1138 static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
1139 {
1140   if (nl)
1141   {
1142     NamespaceSDict::Iterator nli(*nl);
1143     NamespaceDef *nd;
1144     for (nli.toFirst();(nd=nli.current());++nli)
1145     {
1146       if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymous scopes
1147       {
1148         t << "    <innernamespace refid=\"" << nd->getOutputFileBase()
1149           << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
1150       }
1151     }
1152   }
1153 }
1154
1155 static void writeInnerFiles(const FileList *fl,FTextStream &t)
1156 {
1157   if (fl)
1158   {
1159     QListIterator<FileDef> fli(*fl);
1160     FileDef *fd;
1161     for (fli.toFirst();(fd=fli.current());++fli)
1162     {
1163       t << "    <innerfile refid=\"" << fd->getOutputFileBase() 
1164         << "\">" << convertToXML(fd->name()) << "</innerfile>" << endl;
1165     }
1166   }
1167 }
1168
1169 static void writeInnerPages(const PageSDict *pl,FTextStream &t)
1170 {
1171   if (pl)
1172   {
1173     PageSDict::Iterator pli(*pl);
1174     PageDef *pd;
1175     for (pli.toFirst();(pd=pli.current());++pli)
1176     {
1177       t << "    <innerpage refid=\"" << pd->getOutputFileBase();
1178       if (pd->getGroupDef())
1179       {
1180         t << "_" << pd->name();
1181       }
1182       t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
1183     }
1184   }
1185 }
1186
1187 static void writeInnerGroups(const GroupList *gl,FTextStream &t)
1188 {
1189   if (gl)
1190   {
1191     GroupListIterator gli(*gl);
1192     GroupDef *sgd;
1193     for (gli.toFirst();(sgd=gli.current());++gli)
1194     {
1195       t << "    <innergroup refid=\"" << sgd->getOutputFileBase()
1196         << "\">" << convertToXML(sgd->groupTitle()) 
1197         << "</innergroup>" << endl;
1198     }
1199   }
1200 }
1201
1202 static void writeInnerDirs(const DirList *dl,FTextStream &t)
1203 {
1204   if (dl)
1205   {
1206     QListIterator<DirDef> subdirs(*dl);
1207     DirDef *subdir;
1208     for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
1209     {
1210       t << "    <innerdir refid=\"" << subdir->getOutputFileBase() 
1211         << "\">" << convertToXML(subdir->displayName()) << "</innerdir>" << endl;
1212     }
1213   }
1214 }
1215   
1216 static void generateXMLForClass(ClassDef *cd,FTextStream &ti)
1217 {
1218   // + brief description
1219   // + detailed description
1220   // + template argument list(s)
1221   // - include file
1222   // + member groups
1223   // + inheritance diagram
1224   // + list of direct super classes
1225   // + list of direct sub classes
1226   // + list of inner classes
1227   // + collaboration diagram
1228   // + list of all members
1229   // + user defined member sections
1230   // + standard member sections
1231   // + detailed member documentation
1232   // - examples using the class
1233
1234   if (cd->isReference())        return; // skip external references.
1235   if (cd->isHidden())           return; // skip hidden classes.
1236   if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
1237   if (cd->templateMaster()!=0)  return; // skip generated template instances.
1238   if (cd->isArtificial())       return; // skip artificially created classes
1239
1240   msg("Generating XML output for class %s\n",cd->name().data());
1241
1242   ti << "  <compound refid=\"" << classOutputFileBase(cd) 
1243      << "\" kind=\"" << cd->compoundTypeString()
1244      << "\"><name>" << convertToXML(cd->name()) << "</name>" << endl;
1245   
1246   QCString outputDirectory = Config_getString(XML_OUTPUT);
1247   QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
1248   QFile f(fileName);
1249   if (!f.open(IO_WriteOnly))
1250   {
1251     err("Cannot open file %s for writing!\n",fileName.data());
1252     return;
1253   }
1254   FTextStream t(&f);
1255   //t.setEncoding(FTextStream::UnicodeUTF8);
1256
1257   writeXMLHeader(t);
1258   t << "  <compounddef id=\"" 
1259     << classOutputFileBase(cd) << "\" kind=\"" 
1260     << cd->compoundTypeString() << "\" language=\""
1261     << langToString(cd->getLanguage()) << "\" prot=\"";
1262   switch (cd->protection())
1263   {
1264     case Public:    t << "public";    break;
1265     case Protected: t << "protected"; break;
1266     case Private:   t << "private";   break;
1267     case Package:   t << "package";   break;
1268   }
1269   if (cd->isFinal()) t << "\" final=\"yes";
1270   if (cd->isSealed()) t << "\" sealed=\"yes";
1271   if (cd->isAbstract()) t << "\" abstract=\"yes";
1272   t << "\">" << endl;
1273   t << "    <compoundname>"; 
1274   writeXMLString(t,cd->name()); 
1275   t << "</compoundname>" << endl;
1276   if (cd->baseClasses())
1277   {
1278     BaseClassListIterator bcli(*cd->baseClasses());
1279     BaseClassDef *bcd;
1280     for (bcli.toFirst();(bcd=bcli.current());++bcli)
1281     {
1282       t << "    <basecompoundref ";
1283       if (bcd->classDef->isLinkable())
1284       {
1285         t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
1286       }
1287       t << "prot=\"";
1288       switch (bcd->prot)
1289       {
1290         case Public:    t << "public";    break;
1291         case Protected: t << "protected"; break;
1292         case Private:   t << "private";   break;
1293         case Package: ASSERT(0); break;
1294       }
1295       t << "\" virt=\"";
1296       switch(bcd->virt)
1297       {
1298         case Normal:  t << "non-virtual";  break;
1299         case Virtual: t << "virtual";      break;
1300         case Pure:    t <<"pure-virtual"; break;
1301       }
1302       t << "\">";
1303       if (!bcd->templSpecifiers.isEmpty())
1304       {
1305         t << convertToXML(
1306               insertTemplateSpecifierInScope(
1307               bcd->classDef->name(),bcd->templSpecifiers)
1308            );
1309       }
1310       else
1311       {
1312         t << convertToXML(bcd->classDef->displayName());
1313       }
1314       t  << "</basecompoundref>" << endl;
1315     }
1316   }
1317   if (cd->subClasses())
1318   {
1319     BaseClassListIterator bcli(*cd->subClasses());
1320     BaseClassDef *bcd;
1321     for (bcli.toFirst();(bcd=bcli.current());++bcli)
1322     {
1323       t << "    <derivedcompoundref refid=\"" 
1324         << classOutputFileBase(bcd->classDef)
1325         << "\" prot=\"";
1326       switch (bcd->prot)
1327       {
1328         case Public:    t << "public";    break;
1329         case Protected: t << "protected"; break;
1330         case Private:   t << "private";   break;
1331         case Package: ASSERT(0); break;
1332       }
1333       t << "\" virt=\"";
1334       switch(bcd->virt)
1335       {
1336         case Normal:  t << "non-virtual";  break;
1337         case Virtual: t << "virtual";      break;
1338         case Pure:    t << "pure-virtual"; break;
1339       }
1340       t << "\">" << convertToXML(bcd->classDef->displayName()) 
1341         << "</derivedcompoundref>" << endl;
1342     }
1343   }
1344
1345   IncludeInfo *ii=cd->includeInfo();
1346   if (ii)
1347   {
1348     QCString nm = ii->includeName;
1349     if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
1350     if (!nm.isEmpty())
1351     {
1352       t << "    <includes";
1353       if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
1354       {
1355         t << " refid=\"" << ii->fileDef->getOutputFileBase() << "\"";
1356       }
1357       t << " local=\"" << (ii->local ? "yes" : "no") << "\">";
1358       t << nm;
1359       t << "</includes>" << endl;
1360     }
1361   }
1362
1363   writeInnerClasses(cd->getClassSDict(),t);
1364
1365   writeTemplateList(cd,t);
1366   if (cd->getMemberGroupSDict())
1367   {
1368     MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
1369     MemberGroup *mg;
1370     for (;(mg=mgli.current());++mgli)
1371     {
1372       generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
1373           mg->documentation());
1374     }
1375   }
1376
1377   QListIterator<MemberList> mli(cd->getMemberLists());
1378   MemberList *ml;
1379   for (mli.toFirst();(ml=mli.current());++mli)
1380   {
1381     if ((ml->listType()&MemberListType_detailedLists)==0)
1382     {
1383       generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1384     }
1385   }
1386
1387   t << "    <briefdescription>" << endl;
1388   writeXMLDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
1389   t << "    </briefdescription>" << endl;
1390   t << "    <detaileddescription>" << endl;
1391   writeXMLDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
1392   t << "    </detaileddescription>" << endl;
1393   DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
1394   if (!inheritanceGraph.isTrivial())
1395   {
1396     t << "    <inheritancegraph>" << endl;
1397     inheritanceGraph.writeXML(t);
1398     t << "    </inheritancegraph>" << endl;
1399   }
1400   DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
1401   if (!collaborationGraph.isTrivial())
1402   {
1403     t << "    <collaborationgraph>" << endl;
1404     collaborationGraph.writeXML(t);
1405     t << "    </collaborationgraph>" << endl;
1406   }
1407   t << "    <location file=\"" 
1408     << stripFromPath(cd->getDefFileName()) << "\" line=\"" 
1409     << cd->getDefLine() << "\"" << " column=\"" 
1410     << cd->getDefColumn() << "\"" ;
1411     if (cd->getStartBodyLine()!=-1)
1412     {
1413       FileDef *bodyDef = cd->getBodyDef();
1414       if (bodyDef)
1415       {
1416         t << " bodyfile=\"" << stripFromPath(bodyDef->absFilePath()) << "\"";
1417       }
1418       t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\"" 
1419         << cd->getEndBodyLine() << "\"";
1420     }
1421   t << "/>" << endl;
1422   writeListOfAllMembers(cd,t);
1423   t << "  </compounddef>" << endl;
1424   t << "</doxygen>" << endl;
1425
1426   ti << "  </compound>" << endl;
1427 }
1428
1429 static void generateXMLForNamespace(NamespaceDef *nd,FTextStream &ti)
1430 {
1431   // + contained class definitions
1432   // + contained namespace definitions
1433   // + member groups
1434   // + normal members
1435   // + brief desc
1436   // + detailed desc
1437   // + location
1438   // - files containing (parts of) the namespace definition
1439
1440   if (nd->isReference() || nd->isHidden()) return; // skip external references
1441
1442   ti << "  <compound refid=\"" << nd->getOutputFileBase() 
1443      << "\" kind=\"namespace\"" << "><name>" 
1444      << convertToXML(nd->name()) << "</name>" << endl;
1445   
1446   QCString outputDirectory = Config_getString(XML_OUTPUT);
1447   QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
1448   QFile f(fileName);
1449   if (!f.open(IO_WriteOnly))
1450   {
1451     err("Cannot open file %s for writing!\n",fileName.data());
1452     return;
1453   }
1454   FTextStream t(&f);
1455   //t.setEncoding(FTextStream::UnicodeUTF8);
1456   
1457   writeXMLHeader(t);
1458   t << "  <compounddef id=\"" << nd->getOutputFileBase() 
1459     << "\" kind=\"namespace\" language=\"" 
1460     << langToString(nd->getLanguage()) << "\">" << endl;
1461   t << "    <compoundname>";
1462   writeXMLString(t,nd->name());
1463   t << "</compoundname>" << endl;
1464
1465   writeInnerClasses(nd->getClassSDict(),t);
1466   writeInnerNamespaces(nd->getNamespaceSDict(),t);
1467
1468   if (nd->getMemberGroupSDict())
1469   {
1470     MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
1471     MemberGroup *mg;
1472     for (;(mg=mgli.current());++mgli)
1473     {
1474       generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
1475           mg->documentation());
1476     }
1477   }
1478
1479   QListIterator<MemberList> mli(nd->getMemberLists());
1480   MemberList *ml;
1481   for (mli.toFirst();(ml=mli.current());++mli)
1482   {
1483     if ((ml->listType()&MemberListType_declarationLists)!=0)
1484     {
1485       generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1486     }
1487   }
1488
1489   t << "    <briefdescription>" << endl;
1490   writeXMLDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
1491   t << "    </briefdescription>" << endl;
1492   t << "    <detaileddescription>" << endl;
1493   writeXMLDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
1494   t << "    </detaileddescription>" << endl;
1495   t << "    <location file=\""
1496     << stripFromPath(nd->getDefFileName()) << "\" line=\""
1497     << nd->getDefLine() << "\"" << " column=\""
1498     << nd->getDefColumn() << "\"/>" << endl ;
1499   t << "  </compounddef>" << endl;
1500   t << "</doxygen>" << endl;
1501
1502   ti << "  </compound>" << endl;
1503 }
1504
1505 static void generateXMLForFile(FileDef *fd,FTextStream &ti)
1506 {
1507   // + includes files
1508   // + includedby files
1509   // + include graph
1510   // + included by graph
1511   // + contained class definitions
1512   // + contained namespace definitions
1513   // + member groups
1514   // + normal members
1515   // + brief desc
1516   // + detailed desc
1517   // + source code
1518   // + location
1519   // - number of lines
1520   
1521   if (fd->isReference()) return; // skip external references
1522   
1523   ti << "  <compound refid=\"" << fd->getOutputFileBase() 
1524      << "\" kind=\"file\"><name>" << convertToXML(fd->name()) 
1525      << "</name>" << endl;
1526   
1527   QCString outputDirectory = Config_getString(XML_OUTPUT);
1528   QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
1529   QFile f(fileName);
1530   if (!f.open(IO_WriteOnly))
1531   {
1532     err("Cannot open file %s for writing!\n",fileName.data());
1533     return;
1534   }
1535   FTextStream t(&f);
1536   //t.setEncoding(FTextStream::UnicodeUTF8);
1537
1538   writeXMLHeader(t);
1539   t << "  <compounddef id=\"" << fd->getOutputFileBase()
1540     << "\" kind=\"file\" language=\"" 
1541     << langToString(fd->getLanguage()) << "\">" << endl;
1542   t << "    <compoundname>";
1543   writeXMLString(t,fd->name());
1544   t << "</compoundname>" << endl;
1545
1546   IncludeInfo *inc;
1547
1548   if (fd->includeFileList())
1549   {
1550     QListIterator<IncludeInfo> ili1(*fd->includeFileList());
1551     for (ili1.toFirst();(inc=ili1.current());++ili1)
1552     {
1553       t << "    <includes";
1554       if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1555       {
1556         t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1557       }
1558       t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1559       t << inc->includeName;
1560       t << "</includes>" << endl;
1561     }
1562   }
1563
1564   if (fd->includedByFileList())
1565   {
1566     QListIterator<IncludeInfo> ili2(*fd->includedByFileList());
1567     for (ili2.toFirst();(inc=ili2.current());++ili2)
1568     {
1569       t << "    <includedby";
1570       if (inc->fileDef && !inc->fileDef->isReference()) // TODO: support external references
1571       {
1572         t << " refid=\"" << inc->fileDef->getOutputFileBase() << "\"";
1573       }
1574       t << " local=\"" << (inc->local ? "yes" : "no") << "\">";
1575       t << inc->includeName;
1576       t << "</includedby>" << endl;
1577     }
1578   }
1579
1580   DotInclDepGraph incDepGraph(fd,FALSE);
1581   if (!incDepGraph.isTrivial())
1582   {
1583     t << "    <incdepgraph>" << endl;
1584     incDepGraph.writeXML(t);
1585     t << "    </incdepgraph>" << endl;
1586   }
1587
1588   DotInclDepGraph invIncDepGraph(fd,TRUE);
1589   if (!invIncDepGraph.isTrivial())
1590   {
1591     t << "    <invincdepgraph>" << endl;
1592     invIncDepGraph.writeXML(t);
1593     t << "    </invincdepgraph>" << endl;
1594   }
1595
1596   if (fd->getClassSDict())
1597   {
1598     writeInnerClasses(fd->getClassSDict(),t);
1599   }
1600   if (fd->getNamespaceSDict())
1601   {
1602     writeInnerNamespaces(fd->getNamespaceSDict(),t);
1603   }
1604
1605   if (fd->getMemberGroupSDict())
1606   {
1607     MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
1608     MemberGroup *mg;
1609     for (;(mg=mgli.current());++mgli)
1610     {
1611       generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
1612           mg->documentation());
1613     }
1614   }
1615
1616   QListIterator<MemberList> mli(fd->getMemberLists());
1617   MemberList *ml;
1618   for (mli.toFirst();(ml=mli.current());++mli)
1619   {
1620     if ((ml->listType()&MemberListType_declarationLists)!=0)
1621     {
1622       generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1623     }
1624   }
1625
1626   t << "    <briefdescription>" << endl;
1627   writeXMLDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
1628   t << "    </briefdescription>" << endl;
1629   t << "    <detaileddescription>" << endl;
1630   writeXMLDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
1631   t << "    </detaileddescription>" << endl;
1632   if (Config_getBool(XML_PROGRAMLISTING))
1633   {
1634     t << "    <programlisting>" << endl;
1635     writeXMLCodeBlock(t,fd);
1636     t << "    </programlisting>" << endl;
1637   }
1638   t << "    <location file=\"" << stripFromPath(fd->getDefFileName()) << "\"/>" << endl;
1639   t << "  </compounddef>" << endl;
1640   t << "</doxygen>" << endl;
1641
1642   ti << "  </compound>" << endl;
1643 }
1644
1645 static void generateXMLForGroup(GroupDef *gd,FTextStream &ti)
1646 {
1647   // + members
1648   // + member groups
1649   // + files
1650   // + classes
1651   // + namespaces
1652   // - packages
1653   // + pages
1654   // + child groups
1655   // - examples
1656   // + brief description
1657   // + detailed description
1658
1659   if (gd->isReference()) return; // skip external references
1660
1661   ti << "  <compound refid=\"" << gd->getOutputFileBase() 
1662      << "\" kind=\"group\"><name>" << convertToXML(gd->name()) << "</name>" << endl;
1663   
1664   QCString outputDirectory = Config_getString(XML_OUTPUT);
1665   QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
1666   QFile f(fileName);
1667   if (!f.open(IO_WriteOnly))
1668   {
1669     err("Cannot open file %s for writing!\n",fileName.data());
1670     return;
1671   }
1672
1673   FTextStream t(&f);
1674   //t.setEncoding(FTextStream::UnicodeUTF8);
1675   writeXMLHeader(t);
1676   t << "  <compounddef id=\"" 
1677     << gd->getOutputFileBase() << "\" kind=\"group\">" << endl;
1678   t << "    <compoundname>" << convertToXML(gd->name()) << "</compoundname>" << endl;
1679   t << "    <title>" << convertToXML(gd->groupTitle()) << "</title>" << endl;
1680
1681   writeInnerFiles(gd->getFiles(),t);
1682   writeInnerClasses(gd->getClasses(),t);
1683   writeInnerNamespaces(gd->getNamespaces(),t);
1684   writeInnerPages(gd->getPages(),t);
1685   writeInnerGroups(gd->getSubGroups(),t);
1686
1687   if (gd->getMemberGroupSDict())
1688   {
1689     MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
1690     MemberGroup *mg;
1691     for (;(mg=mgli.current());++mgli)
1692     {
1693       generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
1694           mg->documentation());
1695     }
1696   }
1697
1698   QListIterator<MemberList> mli(gd->getMemberLists());
1699   MemberList *ml;
1700   for (mli.toFirst();(ml=mli.current());++mli)
1701   {
1702     if ((ml->listType()&MemberListType_declarationLists)!=0)
1703     {
1704       generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
1705     }
1706   }
1707
1708   t << "    <briefdescription>" << endl;
1709   writeXMLDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
1710   t << "    </briefdescription>" << endl;
1711   t << "    <detaileddescription>" << endl;
1712   writeXMLDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
1713   t << "    </detaileddescription>" << endl;
1714   t << "  </compounddef>" << endl;
1715   t << "</doxygen>" << endl;
1716
1717   ti << "  </compound>" << endl;
1718 }
1719
1720 static void generateXMLForDir(DirDef *dd,FTextStream &ti)
1721 {
1722   if (dd->isReference()) return; // skip external references
1723   ti << "  <compound refid=\"" << dd->getOutputFileBase() 
1724      << "\" kind=\"dir\"><name>" << convertToXML(dd->displayName()) 
1725      << "</name>" << endl;
1726
1727   QCString outputDirectory = Config_getString(XML_OUTPUT);
1728   QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
1729   QFile f(fileName);
1730   if (!f.open(IO_WriteOnly))
1731   {
1732     err("Cannot open file %s for writing!\n",fileName.data());
1733     return;
1734   }
1735
1736   FTextStream t(&f);
1737   //t.setEncoding(FTextStream::UnicodeUTF8);
1738   writeXMLHeader(t);
1739   t << "  <compounddef id=\"" 
1740     << dd->getOutputFileBase() << "\" kind=\"dir\">" << endl;
1741   t << "    <compoundname>" << convertToXML(dd->displayName()) << "</compoundname>" << endl;
1742
1743   writeInnerDirs(&dd->subDirs(),t);
1744   writeInnerFiles(dd->getFiles(),t);
1745
1746   t << "    <briefdescription>" << endl;
1747   writeXMLDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
1748   t << "    </briefdescription>" << endl;
1749   t << "    <detaileddescription>" << endl;
1750   writeXMLDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
1751   t << "    </detaileddescription>" << endl;
1752   t << "    <location file=\"" << stripFromPath(dd->name()) << "\"/>" << endl; 
1753   t << "  </compounddef>" << endl;
1754   t << "</doxygen>" << endl;
1755
1756   ti << "  </compound>" << endl;
1757 }
1758
1759 static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
1760 {
1761   // + name
1762   // + title
1763   // + documentation
1764
1765   const char *kindName = isExample ? "example" : "page";
1766
1767   if (pd->isReference()) return;
1768   
1769   QCString pageName = pd->getOutputFileBase();
1770   if (pd->getGroupDef())
1771   {
1772     pageName+=(QCString)"_"+pd->name();
1773   }
1774   if (pageName=="index") pageName="indexpage"; // to prevent overwriting the generated index page.
1775   
1776   ti << "  <compound refid=\"" << pageName
1777      << "\" kind=\"" << kindName << "\"><name>" << convertToXML(pd->name()) 
1778      << "</name>" << endl;
1779   
1780   QCString outputDirectory = Config_getString(XML_OUTPUT);
1781   QCString fileName=outputDirectory+"/"+pageName+".xml";
1782   QFile f(fileName);
1783   if (!f.open(IO_WriteOnly))
1784   {
1785     err("Cannot open file %s for writing!\n",fileName.data());
1786     return;
1787   }
1788
1789   FTextStream t(&f);
1790   //t.setEncoding(FTextStream::UnicodeUTF8);
1791   writeXMLHeader(t);
1792   t << "  <compounddef id=\"" << pageName;
1793   t << "\" kind=\"" << kindName << "\">" << endl;
1794   t << "    <compoundname>" << convertToXML(pd->name()) 
1795     << "</compoundname>" << endl;
1796
1797   if (pd==Doxygen::mainPage) // main page is special
1798   {
1799     QCString title;
1800     if (!pd->title().isEmpty() && pd->title().lower()!="notitle")
1801     {
1802       title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()));
1803     }
1804     else 
1805     {
1806       title = Config_getString(PROJECT_NAME);
1807     }
1808     t << "    <title>" << convertToXML(convertCharEntitiesToUTF8(title)) 
1809       << "</title>" << endl;
1810   }
1811   else
1812   {
1813     SectionInfo *si = Doxygen::sectionDict->find(pd->name());
1814     if (si)
1815     {
1816       t << "    <title>" << convertToXML(convertCharEntitiesToUTF8(filterTitle(si->title))) 
1817         << "</title>" << endl;
1818     }
1819   }
1820   writeInnerPages(pd->getSubPages(),t);
1821   if (pd->localToc().isXmlEnabled())
1822   {
1823     t << "    <tableofcontents>" << endl;
1824     SectionDict *sectionDict = pd->getSectionDict();
1825     SDict<SectionInfo>::Iterator li(*sectionDict);
1826     SectionInfo *si;
1827     int level=1,l;
1828     bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE };
1829     int maxLevel = pd->localToc().xmlLevel();
1830     for (li.toFirst();(si=li.current());++li)
1831     {
1832       if (si->type==SectionInfo::Section       ||
1833           si->type==SectionInfo::Subsection    ||
1834           si->type==SectionInfo::Subsubsection ||
1835           si->type==SectionInfo::Paragraph)
1836       {
1837         //printf("  level=%d title=%s\n",level,si->title.data());
1838         int nextLevel = (int)si->type;
1839         if (nextLevel>level)
1840         {
1841           for (l=level;l<nextLevel;l++)
1842           {
1843             if (l < maxLevel) t << "    <tableofcontents>" << endl;
1844           }
1845         }
1846         else if (nextLevel<level)
1847         {
1848           for (l=level;l>nextLevel;l--)
1849           {
1850             if (l <= maxLevel && inLi[l]) t << "    </tocsect>" << endl;
1851             inLi[l]=FALSE;
1852             if (l <= maxLevel) t << "    </tableofcontents>" << endl;
1853           }
1854         }
1855         if (nextLevel <= maxLevel)
1856         {
1857           if (inLi[nextLevel]) t << "    </tocsect>" << endl;
1858           QCString titleDoc = convertToXML(si->title);
1859           t << "      <tocsect>" << endl;
1860           t << "        <name>" << (si->title.isEmpty()?si->label:titleDoc) << "</name>" << endl;
1861           t << "        <reference>"  <<  convertToXML(pageName) << "_1" << convertToXML(si -> label) << "</reference>" << endl;
1862           inLi[nextLevel]=TRUE;
1863           level = nextLevel;
1864         }
1865       }
1866     }
1867     while (level>1 && level <= maxLevel)
1868     {
1869       if (inLi[level]) t << "    </tocsect>" << endl;
1870       inLi[level]=FALSE;
1871       t << "    </tableofcontents>" << endl;
1872       level--;
1873     }
1874     if (level <= maxLevel && inLi[level]) t << "    </tocsect>" << endl;
1875     inLi[level]=FALSE;
1876     t << "    </tableofcontents>" << endl;
1877   }
1878   t << "    <briefdescription>" << endl;
1879   writeXMLDocBlock(t,pd->briefFile(),pd->briefLine(),pd,0,pd->briefDescription());
1880   t << "    </briefdescription>" << endl;
1881   t << "    <detaileddescription>" << endl;
1882   if (isExample)
1883   {
1884     writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1885         pd->documentation()+"\n\\include "+pd->name());
1886   }
1887   else
1888   {
1889     writeXMLDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
1890         pd->documentation());
1891   }
1892   t << "    </detaileddescription>" << endl;
1893
1894   t << "  </compounddef>" << endl;
1895   t << "</doxygen>" << endl;
1896
1897   ti << "  </compound>" << endl;
1898 }
1899
1900 void generateXML()
1901 {
1902   // + classes
1903   // + namespaces
1904   // + files
1905   // + groups
1906   // + related pages
1907   // - examples
1908   
1909   QCString outputDirectory = Config_getString(XML_OUTPUT);
1910   QDir xmlDir(outputDirectory);
1911   createSubDirs(xmlDir);
1912
1913   ResourceMgr::instance().copyResource("index.xsd",outputDirectory);
1914
1915   QCString fileName=outputDirectory+"/compound.xsd";
1916   QFile f(fileName);
1917   if (!f.open(IO_WriteOnly))
1918   {
1919     err("Cannot open file %s for writing!\n",fileName.data());
1920     return;
1921   }
1922
1923   // write compound.xsd, but replace special marker with the entities
1924   QCString compound_xsd = ResourceMgr::instance().getAsString("compound.xsd");
1925   const char *startLine = compound_xsd.data();
1926   while (*startLine)
1927   {
1928     // find end of the line
1929     const char *endLine = startLine+1;
1930     while (*endLine && *(endLine-1)!='\n') endLine++; // skip to end of the line including \n
1931     int len=endLine-startLine;
1932     if (len>0)
1933     {
1934       QCString s(len+1);
1935       qstrncpy(s.rawData(),startLine,len);
1936       s[len]='\0';
1937       if (s.find("<!-- Automatically insert here the HTML entities -->")!=-1)
1938       {
1939         FTextStream t(&f);
1940         HtmlEntityMapper::instance()->writeXMLSchema(t);
1941       }
1942       else
1943       {
1944         f.writeBlock(startLine,len);
1945       }
1946     }
1947     startLine=endLine;
1948   }
1949   f.close();
1950
1951   fileName=outputDirectory+"/index.xml";
1952   f.setName(fileName);
1953   if (!f.open(IO_WriteOnly))
1954   {
1955     err("Cannot open file %s for writing!\n",fileName.data());
1956     return;
1957   }
1958   FTextStream t(&f);
1959   //t.setEncoding(FTextStream::UnicodeUTF8);
1960
1961   // write index header
1962   t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
1963   t << "<doxygenindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
1964   t << "xsi:noNamespaceSchemaLocation=\"index.xsd\" ";
1965   t << "version=\"" << versionString << "\">" << endl;
1966
1967   {
1968     ClassSDict::Iterator cli(*Doxygen::classSDict);
1969     ClassDef *cd;
1970     for (cli.toFirst();(cd=cli.current());++cli)
1971     {
1972       generateXMLForClass(cd,t);
1973     }
1974   }
1975   //{
1976   //  ClassSDict::Iterator cli(Doxygen::hiddenClasses);
1977   //  ClassDef *cd;
1978   //  for (cli.toFirst();(cd=cli.current());++cli)
1979   //  {
1980   //    msg("Generating XML output for class %s\n",cd->name().data());
1981   //    generateXMLForClass(cd,t);
1982   //  }
1983   //}
1984   NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1985   NamespaceDef *nd;
1986   for (nli.toFirst();(nd=nli.current());++nli)
1987   {
1988     msg("Generating XML output for namespace %s\n",nd->name().data());
1989     generateXMLForNamespace(nd,t);
1990   }
1991   FileNameListIterator fnli(*Doxygen::inputNameList);
1992   FileName *fn;
1993   for (;(fn=fnli.current());++fnli)
1994   {
1995     FileNameIterator fni(*fn);
1996     FileDef *fd;
1997     for (;(fd=fni.current());++fni)
1998     {
1999       msg("Generating XML output for file %s\n",fd->name().data());
2000       generateXMLForFile(fd,t);
2001     }
2002   }
2003   GroupSDict::Iterator gli(*Doxygen::groupSDict);
2004   GroupDef *gd;
2005   for (;(gd=gli.current());++gli)
2006   {
2007     msg("Generating XML output for group %s\n",gd->name().data());
2008     generateXMLForGroup(gd,t);
2009   }
2010   {
2011     PageSDict::Iterator pdi(*Doxygen::pageSDict);
2012     PageDef *pd=0;
2013     for (pdi.toFirst();(pd=pdi.current());++pdi)
2014     {
2015       msg("Generating XML output for page %s\n",pd->name().data());
2016       generateXMLForPage(pd,t,FALSE);
2017     }
2018   }
2019   {
2020     DirDef *dir;
2021     DirSDict::Iterator sdi(*Doxygen::directories);
2022     for (sdi.toFirst();(dir=sdi.current());++sdi)
2023     {
2024       msg("Generate XML output for dir %s\n",dir->name().data());
2025       generateXMLForDir(dir,t);
2026     }
2027   }
2028   {
2029     PageSDict::Iterator pdi(*Doxygen::exampleSDict);
2030     PageDef *pd=0;
2031     for (pdi.toFirst();(pd=pdi.current());++pdi)
2032     {
2033       msg("Generating XML output for example %s\n",pd->name().data());
2034       generateXMLForPage(pd,t,TRUE);
2035     }
2036   }
2037   if (Doxygen::mainPage)
2038   {
2039     msg("Generating XML output for the main page\n");
2040     generateXMLForPage(Doxygen::mainPage,t,FALSE);
2041   }
2042
2043   //t << "  </compoundlist>" << endl;
2044   t << "</doxygenindex>" << endl;
2045
2046   writeCombineScript();
2047 }
2048
2049