/****************************************************************************** * * * * * Copyright (C) 1997-2001 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ #include #include "qtbc.h" #include "xmlgen.h" #include "doxygen.h" #include "message.h" #include "config.h" #include "classlist.h" #include "util.h" #include "defargs.h" #include "outputgen.h" #include "doc.h" #include "dot.h" #include "code.h" #include #include #include QCString sectionTypeToString(BaseOutputDocInterface::SectionTypes t) { switch (t) { case BaseOutputDocInterface::See: return "see"; case BaseOutputDocInterface::Return: return "return"; case BaseOutputDocInterface::Author: return "author"; case BaseOutputDocInterface::Version: return "version"; case BaseOutputDocInterface::Since: return "since"; case BaseOutputDocInterface::Date: return "date"; case BaseOutputDocInterface::Bug: return "bug"; case BaseOutputDocInterface::Note: return "note"; case BaseOutputDocInterface::Warning: return "warning"; case BaseOutputDocInterface::Par: return "par"; case BaseOutputDocInterface::Deprecated: return "deprecated"; case BaseOutputDocInterface::Pre: return "pre"; case BaseOutputDocInterface::Post: return "post"; case BaseOutputDocInterface::Invar: return "invariant"; case BaseOutputDocInterface::Remark: return "remark"; case BaseOutputDocInterface::Attention: return "attention"; case BaseOutputDocInterface::Todo: return "todo"; case BaseOutputDocInterface::Test: return "test"; case BaseOutputDocInterface::RCS: return "rcs"; case BaseOutputDocInterface::EnumValues: return "enumvalues"; case BaseOutputDocInterface::Examples: return "examples"; } return "illegal"; } inline void writeXMLString(QTextStream &t,const char *s) { t << convertToXML(s); } void writeXMLLink(QTextStream &t,const char *extRef,const char *compoundId, const char *anchorId,const char *text) { t << ""; writeXMLString(t,text); t << ""; } class TextGeneratorXMLImpl : public TextGeneratorIntf { public: TextGeneratorXMLImpl(QTextStream &t): m_t(t) {} void writeString(const char *s) const { writeXMLString(m_t,s); } void writeBreak() const {} void writeLink(const char *extRef,const char *file, const char *anchor,const char *text ) const { writeXMLLink(m_t,extRef,file,anchor,text); } private: QTextStream &m_t; }; template class ValStack { public: ValStack() : m_values(10), m_sp(0), m_size(10) {} virtual ~ValStack() {} ValStack(const ValStack &s) { m_values=s.m_values.copy(); m_sp=s.m_sp; m_size=s.m_size; } ValStack &operator=(const ValStack &s) { m_values=s.m_values.copy(); m_sp=s.m_sp; m_size=s.m_size; return *this; } void push(T v) { m_sp++; if (m_sp>=m_size) { m_size+=10; m_values.resize(m_size); } m_values[m_sp]=v; } T pop() { ASSERT(m_sp!=0); return m_values[m_sp--]; } T& top() { ASSERT(m_sp!=0); return m_values[m_sp]; } bool isEmpty() { return m_sp==0; } private: QArray m_values; int m_sp; int m_size; }; /*! This class is used by the documentation parser. * Its methods are called when some XML text or markup * needs to be written. */ class XMLGenerator : public OutputDocInterface { public: // helper functions void startParMode() { if (!m_inParStack.isEmpty() && !m_inParStack.top()) { m_inParStack.top() = TRUE; m_t << "" << endl; } else if (m_inParStack.isEmpty()) { m_inParStack.push(TRUE); m_t << "" << endl; } } void endParMode() { if (!m_inParStack.isEmpty() && m_inParStack.top()) { m_inParStack.top() = FALSE; m_t << "" << endl; } } void startNestedPar() { m_inParStack.push(FALSE); } void endNestedPar() { if (m_inParStack.pop()) { m_t << "" << endl; } } // Standard generator functions to be implemented by all generators void docify(const char *s) { startParMode(); writeXMLString(m_t,s); } void writeChar(char c) { startParMode(); char s[2];s[0]=c;s[1]=0; docify(s); } void writeString(const char *text) { startParMode(); m_t << text; } void startItemList() { startParMode(); m_t << "" << endl;; m_inListStack.push(TRUE); } void startEnumList() { startParMode(); m_t << ""; m_inListStack.push(TRUE); } void writeListItem() { if (!m_inListStack.isEmpty() && m_inListStack.top()) // first element { m_inListStack.top()=FALSE; } else // not first element, end previous element first { endParMode(); endNestedPar(); m_t << "" << endl; } m_t << ""; startNestedPar(); } void endItemList() { if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element { endParMode(); endNestedPar(); m_t << "" << endl; } m_t << "" << endl; } void endEnumList() { if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element { endParMode(); m_t << "" << endl; endNestedPar(); } m_t << "" << endl; } void newParagraph() { endParMode(); startParMode(); } void startBold() { startParMode(); m_t << ""; // non DocBook } void endBold() { m_t << ""; // non DocBook } void startTypewriter() { startParMode(); m_t << ""; } void endTypewriter() { m_t << ""; } void startEmphasis() { startParMode(); m_t << ""; } void endEmphasis() { m_t << ""; } void startCodeFragment() { m_t << ""; } void endCodeFragment() { m_t << ""; } void startPreFragment() { m_t << ""; } void endPreFragment() { m_t << ""; } void writeRuler() { startParMode(); m_t << ""; } void startDescription() { startParMode(); m_t << ""; m_inListStack.push(TRUE); } void endDescription() { if (!m_inListStack.isEmpty() && !m_inListStack.pop()) // first element { endNestedPar(); m_t << "" << endl; } m_t << ""; if (!m_inListStack.isEmpty()) m_inListStack.pop(); } void startDescItem() { if (!m_inListStack.isEmpty() && m_inListStack.top()) // first element { m_inListStack.top()=FALSE; } else // not first element, end previous element first { endNestedPar(); m_t << ""; } m_t << ""; } void endDescItem() { m_t << ""; startNestedPar(); } void startDescList(SectionTypes st) { startParMode(); m_t << ""; } void endDescList() { endNestedPar(); m_t << "</simplesect>"; } void startParamList(ParamListTypes t) { startParMode(); QCString kind; switch(t) { case Param: kind="param"; break; case RetVal: kind="retval"; break; case Exception: kind="exception"; break; } m_t << "<parameterlist kind=\"" << kind << "\"><title>"; // non DocBook m_inParamList = TRUE; } void endParamList() { m_inParamList = FALSE; m_t << "</parameterlist>"; } void endDescTitle() { m_t << ""; if (!m_inParamList) startNestedPar(); } void writeDescItem() { } void startDescTable() { } void endDescTable() { } void startDescTableTitle() { m_t << ""; // non docbook } void endDescTableTitle() { m_t << ""; // non docbook } void startDescTableData() { m_t << ""; // non docbook startNestedPar(); } void endDescTableData() { endNestedPar(); m_t << ""; // non docbook } void lineBreak() { startParMode(); m_t << ""; // non docbook } void writeNonBreakableSpace(int num) { int i;for (i=0;i"; } void endHtmlLink() { m_t << ""; } void writeMailLink(const char *url) { startParMode(); m_t << ""; docify(url); m_t << ""; } void startSection(const char *id,const char *,bool) { m_t << ""; } void endSection(const char *,bool) { m_t << ""; } void startSubsection() { m_t << ""; } void endSubsection() { m_t << ""; } void startSubsubsection() { m_t << ""; } void endSubsubsection() { m_t << ""; } void startCenter() { startParMode(); m_t << "
"; // non docbook } void endCenter() { m_t << "
"; // non docbook } void startSmall() { startParMode(); m_t << ""; // non docbook } void endSmall() { m_t << ""; // non docbook } void startSubscript() { startParMode(); m_t << ""; } void endSubscript() { m_t << ""; } void startSuperscript() { startParMode(); m_t << ""; } void endSuperscript() { m_t << ""; } void startTable(int cols) { startParMode(); m_t << "\n"; } void endTable() { m_t << "\n
"; } void nextTableRow() { m_t << ""; } void endTableRow() { m_t << "" << endl; } void nextTableColumn() { m_t << ""; } void endTableColumn() { m_t << ""; } void writeQuote() { m_t << "\""; } void writeCopyright() { m_t << "©"; } void writeUmlaut(char c) { m_t << "&" << c << "uml;"; } void writeAcute(char c) { m_t << "&" << c << "acute;"; } void writeGrave(char c) { m_t << "&" << c << "grave;"; } void writeCirc(char c) { m_t << "&" << c << "circ;"; } void writeTilde(char c) { m_t << "&" << c << "tilde;"; } void writeRing(char c) { m_t << "&" << c << "ring;"; } void writeSharpS() { m_t << "ß"; } void writeCCedil(char c) { m_t << "&" << c << "cedil;"; } void startTitle() { m_t << ""; } void endTitle() { m_t << "" << endl; } void writeAnchor(const char *id,const char *name) { startParMode(); m_t << ""; } void writeSectionRef(const char *,const char *id, const char *name,const char *text) { startParMode(); m_t << ""; docify(text); m_t << ""; } void writeSectionRefItem(const char *,const char *,const char *) { m_t << "(writeSectionRefItem)"; } void addIndexItem(const char *primaryie,const char *secondaryie) { startParMode(); m_t << ""; docify(primaryie); m_t << ""; docify(secondaryie); m_t << ""; } void writeFormula(const char *id,const char *text) { startParMode(); m_t << ""; // non Docbook docify(text); m_t << ""; } void startImage(const char *name,const char *size,bool caption) { startParMode(); m_t << ""; // non docbook } void endImage(bool) { m_t << ""; } void startDotFile(const char *name,bool caption) { startParMode(); m_t << ""; // non docbook } void endDotFile(bool) { m_t << ""; } void startTextLink(const char *name,const char *anchor) { startParMode(); m_t << ""; } void endTextLink() { m_t << ""; } void startPageRef() { } void endPageRef(const char *,const char *) { } void startLineNumber() { m_t << ""; } void endLineNumber() { m_t << ""; } void startCodeLine() { startParMode(); m_t << ""; // non DocBook } void endCodeLine() { m_t << "" << endl; // non DocBook } void startCodeAnchor(const char *id) { startParMode(); m_t << ""; } void endCodeAnchor() { m_t << ""; } void startFontClass(const char *colorClass) { m_t << ""; // non DocBook } void endFontClass() { m_t << ""; // non DocBook } void codify(const char *text) { docify(text); } // Generator specific functions /*! Create a clone of this generator. Uses the copy constructor */ OutputDocInterface *clone() { return new XMLGenerator(this); } /*! Append the output written to generator \a g to this generator */ void append(const OutputDocInterface *g) { const XMLGenerator *xg = (const XMLGenerator *)g; //if (m_inPar && !mifgen->m_inParStart) //{ // endParMode(); //} //else if (!m_inPar && mifgen->m_inParStart) //{ // startParMode(); //} //printf("Appending \n>>>>\n`%s'\n<<<<\n and \n>>>>\n`%s'\n<<<<\n",getContents().data(),mifgen->getContents().data()); m_t << xg->getContents(); m_inParStack = xg->m_inParStack; m_inListStack = xg->m_inListStack; m_inParamList = xg->m_inParamList; } /*! constructor. */ XMLGenerator() { m_b.setBuffer(m_a); m_b.open( IO_WriteOnly ); m_t.setDevice(&m_b); m_t.setEncoding(QTextStream::Latin1); m_inParamList = FALSE; } /*! copy constructor */ XMLGenerator(const XMLGenerator *xg) { m_b.setBuffer(m_a); m_b.open( IO_WriteOnly ); m_t.setDevice(&m_b); m_t.setEncoding(QTextStream::Latin1); // copy state variables m_inParStack = xg->m_inParStack; m_inListStack = xg->m_inListStack; m_inParamList = xg->m_inParamList; } /*! destructor */ virtual ~XMLGenerator() { } /*! Returns the output written to this generator as a string */ QCString getContents() const { QCString s; s.resize(m_a.size()+1); memcpy(s.data(),m_a.data(),m_a.size()); s.at(m_a.size())='\0'; return s; } private: // only one destination stream, so these do not have to be implemented void pushGeneratorState() {} void popGeneratorState() {} void disableAllBut(OutputGenerator::OutputType) {} void enableAll() {} void disableAll() {} void disable(OutputGenerator::OutputType) {} void enable(OutputGenerator::OutputType) {} bool isEnabled(OutputGenerator::OutputType) { return TRUE; } QTextStream m_t; QByteArray m_a; QBuffer m_b; ValStack m_inParStack; ValStack m_inListStack; bool m_inParamList; friend void writeXMLCodeBlock(QTextStream &t,FileDef *fd); }; void writeXMLDocBlock(QTextStream &t, const QCString &fileName, int lineNr, const QCString &scope, const QCString &name, const QCString &text) { if (text.stripWhiteSpace().isEmpty()) return; XMLGenerator *xmlGen = new XMLGenerator; xmlGen->startParMode(); parseDoc(*xmlGen, fileName, // input definition file lineNr, // input definition line scope, // scope (which should not be linked to) name, // member (which should not be linked to) text+"\n" // actual text ); xmlGen->endParMode(); t << xmlGen->getContents(); delete xmlGen; } void writeXMLCodeBlock(QTextStream &t,FileDef *fd) { initParseCodeContext(); XMLGenerator *xmlGen = new XMLGenerator; xmlGen->m_inParStack.push(TRUE); parseCode(*xmlGen, 0, fileToString(fd->absFilePath(),Config_getBool("FILTER_SOURCE_FILES")), FALSE, 0, fd); t << xmlGen->getContents(); delete xmlGen; } void generateXMLForMember(MemberDef *md,QTextStream &t,Definition *def) { if (md->memberType()==MemberDef::EnumValue) return; QCString scopeName; if (md->getClassDef()) scopeName=md->getClassDef()->name(); else if (md->getNamespaceDef()) scopeName=md->getNamespaceDef()->name(); t << " memberType()) { case MemberDef::Define: memType="define"; break; case MemberDef::EnumValue: ASSERT(0); break; case MemberDef::Property: memType="property"; break; case MemberDef::Variable: memType="variable"; break; case MemberDef::Typedef: memType="typedef"; break; case MemberDef::Enumeration: memType="enum"; break; case MemberDef::Function: memType="function"; isFunc=TRUE; break; case MemberDef::Signal: memType="signal"; isFunc=TRUE; break; case MemberDef::Prototype: memType="prototype"; isFunc=TRUE; break; case MemberDef::Friend: memType="friend"; isFunc=TRUE; break; case MemberDef::DCOP: memType="dcop"; isFunc=TRUE; break; case MemberDef::Slot: memType="slot"; isFunc=TRUE; break; } t << memType << "\" id=\""; t << def->getOutputFileBase() << "_1" // encoded `:' character (see util.cpp:convertNameToFile) << md->anchor(); t << "\""; t << " virt=\""; switch (md->virtualness()) { case Normal: t << "normal"; break; case Virtual: t << "virtual"; break; case Pure: t << "pure-virtual"; break; default: ASSERT(0); } t << "\" prot=\""; switch(md->protection()) { case Public: t << "public"; break; case Protected: t << "protected"; break; case Private: t << "private"; break; } t << "\">" << endl; if (md->memberType()!=MemberDef::Define && md->memberType()!=MemberDef::Enumeration ) { QCString typeStr = replaceAnonymousScopes(md->typeString()); t << " "; linkifyText(TextGeneratorXMLImpl(t),scopeName,md->name(),typeStr); t << "" << endl; } t << " "; writeXMLString(t,md->name()); t << "" << endl; if (isFunc) //function { ArgumentList *declAl = new ArgumentList; ArgumentList *defAl = md->argumentList(); stringToArgumentList(md->argsString(),declAl); if (declAl->count()>0) { ArgumentListIterator declAli(*declAl); ArgumentListIterator defAli(*defAl); Argument *a; for (declAli.toFirst();(a=declAli.current());++declAli) { Argument *defArg = defAli.current(); t << " " << endl; if (!a->attrib.isEmpty()) { t << " "; writeXMLString(t,a->attrib); t << "" << endl; } if (!a->type.isEmpty()) { t << " "; linkifyText(TextGeneratorXMLImpl(t),scopeName,md->name(),a->type); t << "" << endl; } if (!a->name.isEmpty()) { t << " "; writeXMLString(t,a->name); t << "" << endl; } if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name) { t << " "; writeXMLString(t,defArg->name); t << "" << endl; } if (!a->array.isEmpty()) { t << " "; writeXMLString(t,a->array); t << "" << endl; } if (!a->defval.isEmpty()) { t << " "; linkifyText(TextGeneratorXMLImpl(t),scopeName,md->name(),a->defval); t << "" << endl; } t << " " << endl; if (defArg) ++defAli; } } delete declAl; } else if (md->memberType()==MemberDef::Define && md->argsString()!=0) // define { ArgumentListIterator ali(*md->argumentList()); Argument *a; for (ali.toFirst();(a=ali.current());++ali) { t << " " << a->type << "" << endl; } } if (!md->initializer().isEmpty()) { t << " "; linkifyText(TextGeneratorXMLImpl(t),scopeName,md->name(),md->initializer()); t << "" << endl; } // TODO: exceptions, const volatile if (md->memberType()==MemberDef::Enumeration) // enum { if (md->enumFieldList()) { MemberListIterator emli(*md->enumFieldList()); MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { t << " " << endl; t << " "; writeXMLString(t,emd->name()); t << "" << endl; if (!emd->initializer().isEmpty()) { t << " "; writeXMLString(t,emd->initializer()); t << "" << endl; } t << " " << endl; } } } t << " " << endl; writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),scopeName,md->name(),md->briefDescription()); t << " " << endl; t << " " << endl; writeXMLDocBlock(t,md->getDefFileName(),md->getDefLine(),scopeName,md->name(),md->documentation()); t << " " << endl; t << " getDefFileName() << "\" line=\"" << md->getDefLine() << "\"/>" << endl; t << " " << endl; } void generateXMLClassSection(ClassDef *cd,QTextStream &t,MemberList *ml,const char *kind) { if (ml->count()>0) { t << " " << endl; //t << " " << endl; MemberListIterator mli(*ml); MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { generateXMLForMember(md,t,cd); } //t << " " << endl; t << " " << endl; } } void generateXMLForClass(ClassDef *cd,QTextStream &t) { // + brief description // + detailed description // - template arguments // - include files // + inheritance diagram // + list of direct super classes // + list of direct sub classes // + collaboration diagram // - list of all members // + user defined member sections // + standard member sections // + detailed member documentation if (cd->isReference()) return; // skip external references. if (cd->name().find('@')!=-1) return; // skip anonymous compounds. if (cd->templateMaster()!=0) return; // skip generated template instances. t << " getOutputFileBase() << "\" kind=\"" << cd->compoundTypeString() << "\">" << endl; t << " "; writeXMLString(t,cd->name()); t << "" << endl; if (cd->baseClasses()->count()>0) { BaseClassListIterator bcli(*cd->baseClasses()); BaseClassDef *bcd; for (bcli.toFirst();(bcd=bcli.current());++bcli) { t << " classDef->getOutputFileBase() << "\" prot=\""; switch (bcd->prot) { case Public: t << "public"; break; case Protected: t << "protected"; break; case Private: t << "private"; break; } t << "\" virt=\""; switch(bcd->virt) { case Normal: t << "non-virtual"; break; case Virtual: t << "virtual"; break; case Pure: t <<"pure-virtual"; break; } t << "\"/>" << endl; } } if (cd->subClasses()->count()>0) { BaseClassListIterator bcli(*cd->subClasses()); BaseClassDef *bcd; for (bcli.toFirst();(bcd=bcli.current());++bcli) { t << " classDef->getOutputFileBase() << "\" prot=\""; switch (bcd->prot) { case Public: t << "public"; break; case Protected: t << "protected"; break; case Private: t << "private"; break; } t << "\" virt=\""; switch(bcd->virt) { case Normal: t << "non-virtual"; break; case Virtual: t << "virtual"; break; case Pure: t << "pure-virtual"; break; } t << "\"/>" << endl; } } int numMembers = cd->pubTypes.count()+cd->pubMembers.count()+cd->pubAttribs.count()+ cd->pubSlots.count()+cd->signals.count()+cd->dcopMethods.count()+ cd->pubStaticMembers.count()+ cd->pubStaticAttribs.count()+cd->proTypes.count()+cd->proMembers.count()+ cd->proAttribs.count()+cd->proSlots.count()+cd->proStaticMembers.count()+ cd->proStaticAttribs.count()+cd->priTypes.count()+cd->priMembers.count()+ cd->priAttribs.count()+cd->priSlots.count()+cd->priStaticMembers.count()+ cd->priStaticAttribs.count()+cd->friends.count()+cd->related.count(); if (numMembers>0) { //t << " " << endl; generateXMLClassSection(cd,t,&cd->pubTypes,"public-type"); generateXMLClassSection(cd,t,&cd->pubMembers,"public-func"); generateXMLClassSection(cd,t,&cd->pubAttribs,"public-attrib"); generateXMLClassSection(cd,t,&cd->pubSlots,"public-slot"); generateXMLClassSection(cd,t,&cd->signals,"signal"); generateXMLClassSection(cd,t,&cd->dcopMethods,"dcop-func"); generateXMLClassSection(cd,t,&cd->properties,"property"); generateXMLClassSection(cd,t,&cd->pubStaticMembers,"public-static-func"); generateXMLClassSection(cd,t,&cd->pubStaticAttribs,"public-static-attrib"); generateXMLClassSection(cd,t,&cd->proTypes,"protected-type"); generateXMLClassSection(cd,t,&cd->proMembers,"protected-func"); generateXMLClassSection(cd,t,&cd->proAttribs,"protected-attrib"); generateXMLClassSection(cd,t,&cd->proSlots,"protected-slot"); generateXMLClassSection(cd,t,&cd->proStaticMembers,"protected-static-func"); generateXMLClassSection(cd,t,&cd->proStaticAttribs,"protected-static-attrib"); generateXMLClassSection(cd,t,&cd->priTypes,"private-type"); generateXMLClassSection(cd,t,&cd->priMembers,"private-func"); generateXMLClassSection(cd,t,&cd->priAttribs,"private-attrib"); generateXMLClassSection(cd,t,&cd->priSlots,"private-slot"); generateXMLClassSection(cd,t,&cd->priStaticMembers,"private-static-func"); generateXMLClassSection(cd,t,&cd->priStaticAttribs,"private-static-attrib"); generateXMLClassSection(cd,t,&cd->friends,"signal"); generateXMLClassSection(cd,t,&cd->related,"related"); //t << " " << endl; } t << " " << endl; writeXMLDocBlock(t,cd->getDefFileName(),cd->getDefLine(),cd->name(),0,cd->briefDescription()); t << " " << endl; t << " " << endl; writeXMLDocBlock(t,cd->getDefFileName(),cd->getDefLine(),cd->name(),0,cd->documentation()); t << " " << endl; DotClassGraph inheritanceGraph(cd,DotClassGraph::Inheritance); if (!inheritanceGraph.isTrivial()) { t << " " << endl; inheritanceGraph.writeXML(t); t << " " << endl; } DotClassGraph collaborationGraph(cd,DotClassGraph::Implementation); if (!collaborationGraph.isTrivial()) { t << " " << endl; collaborationGraph.writeXML(t); t << " " << endl; } t << " getDefFileName() << "\" line=\"" << cd->getDefLine() << "\"/>" << endl; t << " " << endl; } void generateXMLSection(Definition *d,QTextStream &t,MemberList *ml,const char *kind) { if (ml->count()>0) { t << " " << endl; MemberListIterator mli(*ml); MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { generateXMLForMember(md,t,d); } t << " " << endl; } } void generateXMLForNamespace(NamespaceDef *nd,QTextStream &t) { if (nd->isReference()) return; // skip external references t << " getOutputFileBase() << "\" kind=\"namespace\">" << endl; t << " "; writeXMLString(t,nd->name()); t << "" << endl; int numMembers = nd->decDefineMembers.count()+nd->decProtoMembers.count()+ nd->decTypedefMembers.count()+nd->decEnumMembers.count()+ nd->decFuncMembers.count()+nd->decVarMembers.count(); if (numMembers>0) { generateXMLSection(nd,t,&nd->decDefineMembers,"define"); generateXMLSection(nd,t,&nd->decProtoMembers,"prototype"); generateXMLSection(nd,t,&nd->decTypedefMembers,"typedef"); generateXMLSection(nd,t,&nd->decEnumMembers,"enum"); generateXMLSection(nd,t,&nd->decFuncMembers,"func"); generateXMLSection(nd,t,&nd->decVarMembers,"var"); } t << " " << endl; writeXMLDocBlock(t,nd->getDefFileName(),nd->getDefLine(),0,0,nd->briefDescription()); t << " " << endl; t << " " << endl; writeXMLDocBlock(t,nd->getDefFileName(),nd->getDefLine(),0,0,nd->documentation()); t << " " << endl; t << " getDefFileName() << "\" line=\"" << nd->getDefLine() << "\"/>" << endl; t << " " << endl; } void generateXMLForFile(FileDef *fd,QTextStream &t) { if (fd->isReference()) return; // skip external references t << " getOutputFileBase() << "\" kind=\"file\">" << endl; t << " "; writeXMLString(t,fd->name()); t << "" << endl; int numMembers = fd->decDefineMembers.count()+fd->decProtoMembers.count()+ fd->decTypedefMembers.count()+fd->decEnumMembers.count()+ fd->decFuncMembers.count()+fd->decVarMembers.count(); if (numMembers>0) { generateXMLSection(fd,t,&fd->decDefineMembers,"define"); generateXMLSection(fd,t,&fd->decProtoMembers,"prototype"); generateXMLSection(fd,t,&fd->decTypedefMembers,"typedef"); generateXMLSection(fd,t,&fd->decEnumMembers,"enum"); generateXMLSection(fd,t,&fd->decFuncMembers,"func"); generateXMLSection(fd,t,&fd->decVarMembers,"var"); } t << " " << endl; writeXMLDocBlock(t,fd->getDefFileName(),fd->getDefLine(),0,0,fd->briefDescription()); t << " " << endl; t << " " << endl; writeXMLDocBlock(t,fd->getDefFileName(),fd->getDefLine(),0,0,fd->documentation()); t << " " << endl; t << " " << endl; writeXMLCodeBlock(t,fd); t << " " << endl; t << " getDefFileName() << "\" line=\"" << fd->getDefLine() << "\"/>" << endl; t << " " << endl; } void generateXML() { QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY"); if (outputDirectory.isEmpty()) { outputDirectory=QDir::currentDirPath(); } else { QDir dir(outputDirectory); if (!dir.exists()) { dir.setPath(QDir::currentDirPath()); if (!dir.mkdir(outputDirectory)) { err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not " "exist and cannot be created\n",outputDirectory.data()); exit(1); } else if (!Config_getBool("QUIET")) { err("Notice: Output directory `%s' does not exist. " "I have created it for you.\n", outputDirectory.data()); } dir.cd(outputDirectory); } outputDirectory=dir.absPath(); } QDir dir(outputDirectory); if (!dir.exists()) { dir.setPath(QDir::currentDirPath()); if (!dir.mkdir(outputDirectory)) { err("Cannot create directory %s\n",outputDirectory.data()); return; } } QDir xmlDir(outputDirectory+"/xml"); if (!xmlDir.exists() && !xmlDir.mkdir(outputDirectory+"/xml")) { err("Could not create xml directory in %s\n",outputDirectory.data()); return; } QCString fileName=outputDirectory+"/xml/doxygen.xml"; QFile f(fileName); if (!f.open(IO_WriteOnly)) { err("Cannot open file %s for writing!\n",fileName.data()); return; } QTextStream t(&f); t << "" << endl; //t << "" << endl; t << "" << endl; if (Doxygen::classSDict.count()+Doxygen::inputNameList.count()>0) { //t << " " << endl; ClassSDict::Iterator cli(Doxygen::classSDict); ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { generateXMLForClass(cd,t); } FileNameListIterator fnli(Doxygen::inputNameList); FileName *fn; for (;(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (;(fd=fni.current());++fni) { generateXMLForFile(fd,t); } } //t << " " << endl; } t << "" << endl; }