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