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