diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2003-07-25 12:37:34 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2003-07-25 12:37:34 (GMT) |
commit | 16a0bd88cfa8d3134b9b8dcae52652801595338c (patch) | |
tree | 5648b4ab8fb4ca6051647d47c3e8cf8d621e8782 | |
parent | aee36e26c595fa69c0bdbba3c470ba8b7b153dac (diff) | |
download | Doxygen-16a0bd88cfa8d3134b9b8dcae52652801595338c.zip Doxygen-16a0bd88cfa8d3134b9b8dcae52652801595338c.tar.gz Doxygen-16a0bd88cfa8d3134b9b8dcae52652801595338c.tar.bz2 |
Release-1.3.3
45 files changed, 2375 insertions, 481 deletions
@@ -141,7 +141,7 @@ MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- -GENERATE_XML = YES +GENERATE_XML = NO #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1,7 +1,7 @@ -DOXYGEN Version 1.3.2-20030717 +DOXYGEN Version 1.3.3 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (17 July 2003) +Dimitri van Heesch (25 July 2003) @@ -1,4 +1,4 @@ -DOXYGEN Version 1.3.2_20030717 +DOXYGEN Version 1.3.3 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (17 July 2003) +Dimitri van Heesch (dimitri@stack.nl) (25 July 2003) @@ -1 +1 @@ -1.3.2-20030717 +1.3.3 diff --git a/addon/doxmlparser/doxygen.dtd b/addon/doxmlparser/doxygen.dtd deleted file mode 100644 index 319b776..0000000 --- a/addon/doxmlparser/doxygen.dtd +++ /dev/null @@ -1,248 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!-- DTD describing the grammar used in doxygen's XML output --> -<!-- Version 0.1 December 25, 2001 --> -<!-- Defined by Angelo Hulshout, based on works of Dimitri van Heesch --> - -<!-- standard character entities --> -<!ENTITY lt "&#60;"> -<!ENTITY gt ">"> -<!ENTITY amp "&#38;"> -<!ENTITY apos "'"> -<!ENTITY quot """> - -<!-- - Document root ---> -<!ELEMENT doxygen (compounddef)*> - -<!-- - Compound related entities and elements ---> -<!ENTITY % compound-req.att - 'id ID #REQUIRED - kind (group|file|namespace| - class|struct|union| - interface|dispinterface| - valuetype|library) #REQUIRED' -> -<!ENTITY % ref-req.att 'idref IDREF #REQUIRED' -> -<!ENTITY % inheritcompref-req.att - '%ref-req.att; - prot (public|protected|private) #REQUIRED - virt (non-virtual|virtual) #REQUIRED' -> - -<!ELEMENT compounddef (compoundname, - basecompoundref*, - derivedcompoundref*, - sectiondef*, - briefdescription, - detaileddescription, - inheritancegraph?, - collaborationgraph?, - programlisting?, - sourcecode?, - location? - ) -> -<!ATTLIST compounddef %compound-req.att;> - -<!ELEMENT compoundname (#PCDATA)> - -<!ELEMENT location (#PCDATA)> -<!ATTLIST location file CDATA #REQUIRED line CDATA #REQUIRED > - -<!ELEMENT compoundref EMPTY> -<!ATTLIST compoundref %ref-req.att;> - -<!ELEMENT basecompoundref EMPTY> -<!ATTLIST basecompoundref %inheritcompref-req.att;> - -<!ELEMENT derivedcompoundref EMPTY> -<!ATTLIST derivedcompoundref %inheritcompref-req.att;> - -<!ELEMENT memberdef (#PCDATA|type|name|briefdescription|detaileddescription|location|param|initializer|enumvalue)*> -<!ATTLIST memberdef kind (define|property|variable|typedef|enum|function|signal|prototype|friend|dcop|slot) #REQUIRED id CDATA #REQUIRED virt (normal|virtual|pure-virtual) #REQUIRED prot (public|protected|private) #REQUIRED> - -<!ELEMENT briefdescription (#PCDATA|para)*> - -<!ELEMENT detaileddescription (#PCDATA|para)*> - -<!-- - Compound attributes related entities and elements ---> -<!-- required attributes for member sections --> -<!ENTITY % sec-req.att 'kind (user - |public-type - |public-func - |public-attrib - |public-slot - |public-static-func - |public-static-attrib - |protected-type - |protected-func - |protected-attrib - |protected-slot - |protected-static-func - |protected-static-attrib - |private-type - |private-func - |private-attrib - |private-slot - |private-static-func - |private-static-attrib - |signal - |friend - |related - |define|prototype|typedef|enum|func|var - |dcop-func - |property - ) #REQUIRED - ' -> -<!ENTITY % mem-req.att 'id ID #REQUIRED'> - -<!-- optional attributes for function --> -<!ENTITY % func-opt.att 'virt (virtual|pure-virtual) #IMPLIED'> - -<!ELEMENT memberref (#PCDATA)> -<!ATTLIST memberref %ref-req.att;> - -<!ELEMENT sectionlist (sectiondef)+> - -<!ELEMENT sectiondef (memberdef|memberlist)*> -<!ATTLIST sectiondef %sec-req.att;> - -<!ELEMENT memberlist (functiondef|variabledef|typedef|definedef|enumdef)+> - -<!ELEMENT functiondef (type?,name,parameterlist)> -<!ATTLIST functiondef %mem-req.att; %func-opt.att;> - -<!ELEMENT variabledef (type,name,array?,initializer?)> -<!ATTLIST variabledef %mem-req.att;> - -<!ELEMENT parameterlist (title|parametername|parameterdescription)*> -<!ATTLIST parameterlist kind (param|retval|exception) #REQUIRED> - -<!ELEMENT param (attributes?,type?,declname?,defname?,array?,defval?)> - -<!ELEMENT parametername (#PCDATA)> - -<!ELEMENT parameterdescription (#PCDATA|para)*> - -<!ELEMENT defparameterlist (defarg)*> - -<!ELEMENT defarg (#PCDATA)> - -<!-- - Programming language declaration related entities and elements ---> -<!ELEMENT name (#PCDATA)> - -<!ELEMENT typedef (type,name)> -<!ATTLIST typedef %mem-req.att;> - -<!ELEMENT definedef (name,defparameterlist?,initializer?)> -<!ATTLIST definedef %mem-req.att;> - -<!ELEMENT enumdef (name,enumvaluelist)> -<!ATTLIST enumdef %mem-req.att;> - -<!ELEMENT slotdef (type,name,parameterlist)> -<!ATTLIST slotdef %mem-req.att;> - -<!ELEMENT signaldef (type,name,parameterlist)> -<!ATTLIST signaldef %mem-req.att;> - -<!ELEMENT enumvaluelist (enumvalue)*> - -<!ELEMENT enumvalue (name,initializer?)> - -<!ELEMENT declname (#PCDATA)> - -<!ELEMENT defname (#PCDATA)> - -<!ELEMENT type (#PCDATA|memberref|compoundref|compounddef|ref)*> - -<!ELEMENT defval (#PCDATA|memberref|compoundref)*> - -<!ELEMENT initializer (#PCDATA|memberref|compoundref|ref)*> - -<!ELEMENT array (#PCDATA)> - -<!ELEMENT attributes (#PCDATA)> - -<!-- - Graph related entities and elements ---> -<!ELEMENT collaborationgraph (node)*> - -<!ELEMENT inheritancegraph (node)*> - -<!ELEMENT node (label|link|childnode)*> -<!ATTLIST node id CDATA #REQUIRED> - -<!ELEMENT childnode (edgelabel)*> -<!ATTLIST childnode id CDATA #REQUIRED relation CDATA #REQUIRED> - -<!ELEMENT label (#PCDATA)> - -<!ELEMENT link EMPTY> -<!ATTLIST link id CDATA #REQUIRED> - -<!ELEMENT edgelabel (#PCDATA)> - -<!-- - Source code listing related entities and elements ---> -<!ELEMENT codeline (#PCDATA|highlight|ref)*> - -<!ELEMENT linenumber (#PCDATA|anchor)*> -<!ATTLIST linenumber line CDATA #IMPLIED refid CDATA #IMPLIED> - -<!ELEMENT sourcecode (linenumber|codeline|highlight|ref)*> - -<!ELEMENT itemizedlist (listitem)*> - -<!ELEMENT listitem (#PCDATA|para)*> - -<!ELEMENT programlisting (#PCDATA|linenumber|codeline|linebreak|highlight)*> - -<!-- - Hypertext related entities and elements ---> -<!ELEMENT ulink (#PCDATA)> -<!ATTLIST ulink url CDATA #REQUIRED> - -<!ELEMENT anchor (ref)> -<!ATTLIST anchor id CDATA #REQUIRED> - -<!ELEMENT ref (#PCDATA)> -<!ATTLIST ref idref CDATA #REQUIRED anchor CDATA #IMPLIED> - -<!-- - Documentation layout entities and elements ---> -<!--ELEMENT highlight (#PCDATA|ref)*--> -<!ELEMENT highlight ANY> -<!ATTLIST highlight class (preprocessor|keyword|keywordtype|keywordflow|stringliteral|charliteral|comment) #REQUIRED> - -<!ELEMENT linebreak EMPTY> - -<!--ELEMENT simplesect (title|para)*--> -<!ELEMENT simplesect ANY> -<!ATTLIST simplesect kind (see|return|author|version|since|date|bug|note|warning|par|deprecated|pre|post|invariant|remark|attention|todo|test|rcs|enumvalues|examples) #REQUIRED> - -<!--ELEMENT computeroutput (#PCDATA)--> -<!ELEMENT computeroutput ANY> - -<!--ELEMENT emphasis (#PCDATA|ref)*--> -<!ELEMENT emphasis ANY> - -<!--ELEMENT title (#PCDATA|ref)*--> -<!ELEMENT title ANY> - -<!--ELEMENT para (#PCDATA|computeroutput|ref|emphasis|parameterlist|simplesect|ulink|programlisting|itemizedlist|linebreak)*--> -<!ELEMENT para ANY> - diff --git a/addon/doxmlparser/include/doxmlintf.h b/addon/doxmlparser/include/doxmlintf.h index 3f7762c..51a6191 100644 --- a/addon/doxmlparser/include/doxmlintf.h +++ b/addon/doxmlparser/include/doxmlintf.h @@ -32,6 +32,7 @@ class IDocIterator; class ICompound; class ISection; class INode; +class IDocInternal; /*! \brief Read only interface to a string. */ @@ -165,7 +166,8 @@ class IDoc TocItem, // 33 -> IDocTocItem Anchor, // 34 -> IDocAnchor Symbol, // 35 -> IDocSymbol - Root // 36 -> IDocRoot + Internal, // 36 -> IDocInternal + Root // 37 -> IDocRoot }; virtual Kind kind() const = 0; }; @@ -397,7 +399,17 @@ class IDocSection : public IDoc public: virtual const IString * id() const = 0; virtual int level() const = 0; - virtual IDocIterator *title() const = 0; + virtual IDocTitle *title() const = 0; + virtual IDocIterator *paragraphs() const = 0; + virtual IDocIterator *subSections() const = 0; + virtual IDocInternal *internal() const = 0; +}; + +class IDocInternal : public IDoc +{ + public: + virtual IDocIterator *paragraphs() const = 0; + virtual IDocIterator *subSections() const = 0; }; class IDocTocList : public IDoc diff --git a/addon/doxmlparser/src/dochandler.cpp b/addon/doxmlparser/src/dochandler.cpp index a44f7e1..7a2113a 100644 --- a/addon/doxmlparser/src/dochandler.cpp +++ b/addon/doxmlparser/src/dochandler.cpp @@ -2006,20 +2006,25 @@ IDocIterator *ParagraphHandler::contents() const //---------------------------------------------------------------------- DocSectionHandler::DocSectionHandler(IBaseHandler *parent,int level) - : m_parent(parent), m_level(level) + : m_parent(parent), m_internal(0), m_level(level), m_title(0) { - m_children.setAutoDelete(TRUE); - m_markupHandler = new MarkupHandler(m_children,m_curString); - setFallBackHandler(m_markupHandler); - addStartHandler("ref",this,&DocSectionHandler::startRef); QString sectionKey; + m_paragraphs.setAutoDelete(TRUE); + m_subsections.setAutoDelete(TRUE); + addStartHandler("title",this,&DocSectionHandler::startTitle); + addStartHandler("para",this,&DocSectionHandler::startParagraph); + if (level<6) + { + sectionKey.sprintf("sect%d",level+1); + addStartHandler(sectionKey,this,&DocSectionHandler::startSubSection); + } + addStartHandler("internal",this,&DocSectionHandler::startInternal); sectionKey.sprintf("sect%d",level); addEndHandler(sectionKey,this,&DocSectionHandler::endDocSection); } DocSectionHandler::~DocSectionHandler() { - delete m_markupHandler; } void DocSectionHandler::startDocSection(const QXmlAttributes& attrib) @@ -2027,44 +2032,112 @@ void DocSectionHandler::startDocSection(const QXmlAttributes& attrib) m_parent->setDelegate(this); debug(2,"Start docsection\n"); m_id = attrib.value("id"); - m_curString=""; } void DocSectionHandler::endDocSection() { - addTextNode(); m_parent->setDelegate(0); debug(2,"End docsection\n"); } -void DocSectionHandler::addTextNode() +void DocSectionHandler::startSubSection(const QXmlAttributes& attrib) { - if (!m_curString.isEmpty()) - { - m_children.append( - new TextNode(m_curString, - m_markupHandler->markup(), - m_markupHandler->headingLevel() - ) - ); - debug(2,"addTextNode() text=\"%s\" markup=%x headingLevel=%d\n", - m_curString.data(),m_markupHandler->markup(),m_markupHandler->headingLevel()); - m_curString=""; - } + DocSectionHandler *secHandler = new DocSectionHandler(this,m_level+1); + secHandler->startDocSection(attrib); + m_subsections.append(secHandler); } -void DocSectionHandler::startRef(const QXmlAttributes& attrib) +void DocSectionHandler::startParagraph(const QXmlAttributes& attrib) +{ + ParagraphHandler *parHandler = new ParagraphHandler(this); + parHandler->startParagraph(attrib); + m_paragraphs.append(parHandler); +} + +void DocSectionHandler::startInternal(const QXmlAttributes& attrib) +{ + m_internal = new DocInternalHandler(this,m_level); + m_internal->startInternal(attrib); +} + +void DocSectionHandler::startTitle(const QXmlAttributes& attrib) +{ + m_title = new TitleHandler(this); + m_title->startTitle(attrib); +} + +IDocIterator *DocSectionHandler::paragraphs() const +{ + return new DocSectionParaIterator(*this); +} + +IDocIterator *DocSectionHandler::subSections() const +{ + return new DocSectionSubIterator(*this); +} + +IDocInternal *DocSectionHandler::internal() const +{ + return m_internal; +} + +//---------------------------------------------------------------------- +// DocInternal +//---------------------------------------------------------------------- + +DocInternalHandler::DocInternalHandler(IBaseHandler *parent,int level) + : m_parent(parent), m_level(level) +{ + m_paragraphs.setAutoDelete(TRUE); + m_subsections.setAutoDelete(TRUE); + addStartHandler("para",this,&DocInternalHandler::startParagraph); + QString sectionKey; + sectionKey.sprintf("sect%d",level+1); + addStartHandler(sectionKey,this,&DocInternalHandler::startSubSection); + addEndHandler("internal",this,&DocInternalHandler::endInternal); +} + +DocInternalHandler::~DocInternalHandler() { - RefHandler *ref = new RefHandler(this); - ref->startRef(attrib); - m_children.append(ref); } -IDocIterator *DocSectionHandler::title() const +void DocInternalHandler::startInternal(const QXmlAttributes&) { - return new DocSectionIterator(*this); + m_parent->setDelegate(this); + debug(2,"Start internal\n"); +} + +void DocInternalHandler::endInternal() +{ + m_parent->setDelegate(0); + debug(2,"End internal\n"); +} + +void DocInternalHandler::startSubSection(const QXmlAttributes& attrib) +{ + DocSectionHandler *secHandler = new DocSectionHandler(this,m_level+1); + secHandler->startDocSection(attrib); + m_subsections.append(secHandler); } +void DocInternalHandler::startParagraph(const QXmlAttributes& attrib) +{ + ParagraphHandler *parHandler = new ParagraphHandler(this); + parHandler->startParagraph(attrib); + m_paragraphs.append(parHandler); +} + +IDocIterator *DocInternalHandler::paragraphs() const +{ + return new DocInternalParaIterator(*this); +} + +IDocIterator *DocInternalHandler::subSections() const +{ + return new DocInternalSubIterator(*this); +} + + //---------------------------------------------------------------------- // DocHandler //---------------------------------------------------------------------- @@ -2079,11 +2152,6 @@ DocHandler::DocHandler(IBaseHandler *parent) : m_parent(parent) addStartHandler("para",this,&DocHandler::startParagraph); addStartHandler("sect1",this,&DocHandler::startSect1); - addStartHandler("sect2",this,&DocHandler::startSect2); - addStartHandler("sect3",this,&DocHandler::startSect3); - addStartHandler("sect4",this,&DocHandler::startSect4); - addStartHandler("sect5",this,&DocHandler::startSect5); - addStartHandler("sect6",this,&DocHandler::startSect6); addStartHandler("title",this,&DocHandler::startTitle); addStartHandler("internal"); } @@ -2118,41 +2186,6 @@ void DocHandler::startSect1(const QXmlAttributes& attrib) m_children.append(secHandler); } -void DocHandler::startSect2(const QXmlAttributes& attrib) -{ - DocSectionHandler *secHandler = new DocSectionHandler(this,2); - secHandler->startDocSection(attrib); - m_children.append(secHandler); -} - -void DocHandler::startSect3(const QXmlAttributes& attrib) -{ - DocSectionHandler *secHandler = new DocSectionHandler(this,3); - secHandler->startDocSection(attrib); - m_children.append(secHandler); -} - -void DocHandler::startSect4(const QXmlAttributes& attrib) -{ - DocSectionHandler *secHandler = new DocSectionHandler(this,4); - secHandler->startDocSection(attrib); - m_children.append(secHandler); -} - -void DocHandler::startSect5(const QXmlAttributes& attrib) -{ - DocSectionHandler *secHandler = new DocSectionHandler(this,5); - secHandler->startDocSection(attrib); - m_children.append(secHandler); -} - -void DocHandler::startSect6(const QXmlAttributes& attrib) -{ - DocSectionHandler *secHandler = new DocSectionHandler(this,6); - secHandler->startDocSection(attrib); - m_children.append(secHandler); -} - void DocHandler::startTitle(const QXmlAttributes& attrib) { TitleHandler *titleHandler = new TitleHandler(this); diff --git a/addon/doxmlparser/src/dochandler.h b/addon/doxmlparser/src/dochandler.h index 349e955..e508bd6 100644 --- a/addon/doxmlparser/src/dochandler.h +++ b/addon/doxmlparser/src/dochandler.h @@ -26,6 +26,7 @@ #include "baseiterator.h" class ParagraphHandler; +class DocInternalHandler; class LinkedTextImpl; class LinkedTextHandler; @@ -72,6 +73,7 @@ DEFINE_CLS_IMPL(DocTocList); DEFINE_CLS_IMPL(DocTocItem); DEFINE_CLS_IMPL(DocAnchor); DEFINE_CLS_IMPL(DocSymbol); +DEFINE_CLS_IMPL(DocInternal); DEFINE_CLS_IMPL(DocRoot); //----------------------------------------------------------------------------- @@ -1186,44 +1188,97 @@ class SymbolHandler : public DocSymbolImpl, public BaseHandler<SymbolHandler> /*! \brief Node representing a section. * */ -// children: text, ref -// children handled by MarkupHandler: -// bold, computeroutput, emphasis, center, -// small, subscript, superscript. +// children: title, para, sect(n+1) class DocSectionHandler : public DocSectionImpl, public BaseHandler<DocSectionHandler> { - friend class DocSectionIterator; + friend class DocSectionParaIterator; + friend class DocSectionSubIterator; public: DocSectionHandler(IBaseHandler *parent,int level); virtual ~DocSectionHandler(); virtual void startDocSection(const QXmlAttributes& attrib); virtual void endDocSection(); - virtual void startRef(const QXmlAttributes& attrib); - void addTextNode(); + virtual void startTitle(const QXmlAttributes& attrib); + virtual void startSubSection(const QXmlAttributes& attrib); + virtual void startParagraph(const QXmlAttributes& attrib); + virtual void startInternal(const QXmlAttributes& attrib); // IDocSection virtual Kind kind() const { return DocImpl::Section; } virtual const IString *id() const { return &m_id; } virtual int level() const { return m_level; } - virtual IDocIterator *title() const; + virtual IDocTitle *title() const { return m_title; } + virtual IDocIterator *paragraphs() const; + virtual IDocIterator *subSections() const; + virtual IDocInternal *internal() const; private: - IBaseHandler *m_parent; - QList<DocImpl> m_children; - MarkupHandler *m_markupHandler; - StringImpl m_id; - int m_level; + IBaseHandler *m_parent; + QList<DocImpl> m_paragraphs; + QList<DocImpl> m_subsections; + DocInternalHandler *m_internal; + StringImpl m_id; + int m_level; + TitleHandler *m_title; }; -class DocSectionIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl> +class DocSectionParaIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl> { public: - DocSectionIterator(const DocSectionHandler &handler) : - BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_children) {} + DocSectionParaIterator(const DocSectionHandler &handler) : + BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_paragraphs) {} +}; + +class DocSectionSubIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl> +{ + public: + DocSectionSubIterator(const DocSectionHandler &handler) : + BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_subsections) {} }; //----------------------------------------------------------------------------- +class DocInternalHandler : public DocInternalImpl, public BaseHandler<DocInternalHandler> +{ + public: + friend class DocInternalParaIterator; + friend class DocInternalSubIterator; + DocInternalHandler(IBaseHandler *parent,int level); + virtual ~DocInternalHandler(); + virtual void startInternal(const QXmlAttributes& attrib); + virtual void endInternal(); + virtual void startSubSection(const QXmlAttributes& attrib); + virtual void startParagraph(const QXmlAttributes& attrib); + + // IDocInternal + virtual Kind kind() const { return DocImpl::Internal; } + virtual IDocIterator *paragraphs() const; + virtual IDocIterator *subSections() const; + + private: + IBaseHandler *m_parent; + QList<DocImpl> m_paragraphs; + QList<DocImpl> m_subsections; + int m_level; +}; + +class DocInternalParaIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl> +{ + public: + DocInternalParaIterator(const DocInternalHandler &handler) : + BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_paragraphs) {} +}; + +class DocInternalSubIterator : public BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl> +{ + public: + DocInternalSubIterator(const DocInternalHandler &handler) : + BaseIteratorVia<IDocIterator,IDoc,DocImpl,DocImpl>(handler.m_subsections) {} +}; + + +//----------------------------------------------------------------------------- + /*! \brief Node representing a documentation block. * */ @@ -1236,11 +1291,6 @@ class DocHandler : public DocRootImpl, public BaseHandler<DocHandler> virtual void endDoc(); virtual void startParagraph(const QXmlAttributes& attrib); virtual void startSect1(const QXmlAttributes& attrib); - virtual void startSect2(const QXmlAttributes& attrib); - virtual void startSect3(const QXmlAttributes& attrib); - virtual void startSect4(const QXmlAttributes& attrib); - virtual void startSect5(const QXmlAttributes& attrib); - virtual void startSect6(const QXmlAttributes& attrib); virtual void startTitle(const QXmlAttributes& attrib); DocHandler(IBaseHandler *parent); diff --git a/addon/doxmlparser/src/doxmlintf.h b/addon/doxmlparser/src/doxmlintf.h index 3f7762c..51a6191 100644 --- a/addon/doxmlparser/src/doxmlintf.h +++ b/addon/doxmlparser/src/doxmlintf.h @@ -32,6 +32,7 @@ class IDocIterator; class ICompound; class ISection; class INode; +class IDocInternal; /*! \brief Read only interface to a string. */ @@ -165,7 +166,8 @@ class IDoc TocItem, // 33 -> IDocTocItem Anchor, // 34 -> IDocAnchor Symbol, // 35 -> IDocSymbol - Root // 36 -> IDocRoot + Internal, // 36 -> IDocInternal + Root // 37 -> IDocRoot }; virtual Kind kind() const = 0; }; @@ -397,7 +399,17 @@ class IDocSection : public IDoc public: virtual const IString * id() const = 0; virtual int level() const = 0; - virtual IDocIterator *title() const = 0; + virtual IDocTitle *title() const = 0; + virtual IDocIterator *paragraphs() const = 0; + virtual IDocIterator *subSections() const = 0; + virtual IDocInternal *internal() const = 0; +}; + +class IDocInternal : public IDoc +{ + public: + virtual IDocIterator *paragraphs() const = 0; + virtual IDocIterator *subSections() const = 0; }; class IDocTocList : public IDoc diff --git a/addon/doxmlparser/src/graphhandler.cpp b/addon/doxmlparser/src/graphhandler.cpp index a11273d..7816970 100644 --- a/addon/doxmlparser/src/graphhandler.cpp +++ b/addon/doxmlparser/src/graphhandler.cpp @@ -110,7 +110,7 @@ void NodeHandler::endNode() void NodeHandler::startLink(const QXmlAttributes &attrib) { - m_link = attrib.value("id"); + m_link = attrib.value("refid"); } void NodeHandler::endLink() @@ -156,7 +156,7 @@ ChildNodeHandler::~ChildNodeHandler() void ChildNodeHandler::startChildNode(const QXmlAttributes &attrib) { debug(2,"startChildNode\n"); - m_id = attrib.value("id"); + m_id = attrib.value("refid"); m_relationString = attrib.value("relation"); m_relation = s_edgeRelationMapper->stringToNodeRelation(m_relationString); m_parent->setDelegate(this); diff --git a/addon/doxmlparser/src/mainhandler.cpp b/addon/doxmlparser/src/mainhandler.cpp index d6fcb2b..09d12c7 100644 --- a/addon/doxmlparser/src/mainhandler.cpp +++ b/addon/doxmlparser/src/mainhandler.cpp @@ -94,8 +94,8 @@ MainHandler::MainHandler() : m_compoundDict(2999), m_compoundNameDict(2999), { m_compounds.setAutoDelete(TRUE); m_memberNameDict.setAutoDelete(TRUE); - addStartHandler("doxygen"); - addEndHandler("doxygen"); + addStartHandler("doxygenindex"); + addEndHandler("doxygenindex"); addStartHandler("compound",this,&MainHandler::startCompound); addEndHandler("compound"); addStartHandler("member",this,&MainHandler::startMember); diff --git a/addon/doxmlparser/src/memberhandler.cpp b/addon/doxmlparser/src/memberhandler.cpp index 062ea4a..a46df85 100644 --- a/addon/doxmlparser/src/memberhandler.cpp +++ b/addon/doxmlparser/src/memberhandler.cpp @@ -285,7 +285,7 @@ void MemberHandler::startLocation(const QXmlAttributes& attrib) void MemberHandler::startReferences(const QXmlAttributes& attrib) { MemberReference *mr = new MemberReference; - mr->m_memId = attrib.value("id"); + mr->m_memId = attrib.value("refid"); m_references.append(mr); m_curString=""; } @@ -298,7 +298,7 @@ void MemberHandler::endReferences() void MemberHandler::startReferencedBy(const QXmlAttributes& attrib) { MemberReference *mr = new MemberReference; - mr->m_memId = attrib.value("id"); + mr->m_memId = attrib.value("refid"); m_referencedBy.append(mr); m_curString=""; } @@ -311,7 +311,7 @@ void MemberHandler::endReferencedBy() void MemberHandler::startReimplements(const QXmlAttributes& attrib) { m_reimplements = new MemberReference; - m_reimplements->m_memId = attrib.value("id"); + m_reimplements->m_memId = attrib.value("refid"); m_curString=""; } @@ -323,7 +323,7 @@ void MemberHandler::endReimplements() void MemberHandler::startReimplementedBy(const QXmlAttributes& attrib) { MemberReference *mr = new MemberReference; - mr->m_memId = attrib.value("id"); + mr->m_memId = attrib.value("refid"); m_reimplementedBy.append(mr); m_curString=""; } diff --git a/addon/doxmlparser/test/main.cpp b/addon/doxmlparser/test/main.cpp index c066a24..639cacb 100644 --- a/addon/doxmlparser/test/main.cpp +++ b/addon/doxmlparser/test/main.cpp @@ -372,15 +372,45 @@ void DumpDoc(IDoc *doc,int level) ASSERT(sec!=0); InPrint(("<section id=`%s' level=%d>\n", sec->id()->latin1(),sec->level())); - IDocIterator *di = sec->title(); + DumpDoc(sec->title(),level+1); + IDocIterator *di = sec->paragraphs(); IDoc *pdoc; for (di->toFirst();(pdoc=di->current());di->toNext()) { DumpDoc(pdoc,level+1); } + di=sec->subSections(); + for (di->toFirst();(pdoc=di->current());di->toNext()) + { + DumpDoc(pdoc,level+1); + } + IDocInternal *intern = sec->internal(); + if (intern) + { + DumpDoc(intern,level+1); + } InPrint(("</section>\n")); } break; + case IDoc::Internal: + { + IDocInternal *intern = dynamic_cast<IDocInternal*>(doc); + ASSERT(intern!=0); + InPrint(("<internal>\n")); + IDocIterator *di = intern->paragraphs(); + IDoc *pdoc; + for (di->toFirst();(pdoc=di->current());di->toNext()) + { + DumpDoc(pdoc,level+1); + } + di=intern->subSections(); + for (di->toFirst();(pdoc=di->current());di->toNext()) + { + DumpDoc(pdoc,level+1); + } + InPrint(("</internal>\n")); + } + break; case IDoc::Copy: { IDocCopy *cpy = dynamic_cast<IDocCopy*>(doc); diff --git a/doc/Doxyfile b/doc/Doxyfile index c25878e..acfec34 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -26,6 +26,7 @@ GENERATE_LATEX = YES GENERATE_HTML = YES GENERATE_HTMLHELP = YES GENERATE_RTF = NO +GENERATE_XML = NO ENABLED_SECTIONS = logo_on ENABLE_PREPROCESSING = NO CASE_SENSE_NAMES = NO diff --git a/doc/commands.doc b/doc/commands.doc index 950d4e5..073e3d9 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -391,8 +391,15 @@ doxygen. Unrecognized commands are treated as normal text. \addindex \\internal This command writes the message `For internal use only' to the output and - all text \e after a \c \\internal command until the end of the - comment block is ignored. + all text \e after an \c \\internal command until the end of the + comment block or the end of the section (whichever comes first) is + marked as "internal". + + If the \\internal command is put inside a section + (see for example \ref cmdsection "\\section") all subsection after the + command are considered to be internal as well. Only a new section at the + same level will be visible again. + You can use \ref cfg_internal_docs "INTERNAL_DOCS" in the config file to show or hide the internal documentation. diff --git a/doc/install.doc b/doc/install.doc index 2dbbf51..3dfc2e7 100644 --- a/doc/install.doc +++ b/doc/install.doc @@ -376,9 +376,21 @@ perl script in <code>wintools/make.pl</code> a bit. Let me know what you had to change if you got Doxygen working with another compiler. +If you have Visual C++ 6.0, and the source distribution, you can easily +build doxygen using the project files in the \c wintools directory. If +you want to build the CVS sources, or want to build from the command line, +or with another compiler, you have to follow the steps below. + +Thomas Baust reported that if you have Visual Studio.NET (2003) then +you should be aware that there is a problem with the _popen() and _pclose() +implementation, which currently leaks handles, so if you build doxygen with +it and use the INPUT_FILTER, you will run to risk of crashing Windows! +The problem is reported to and confirmed by Microsoft so maybe it will +fixed in the next service pack. + Since Windows comes without all the nice tools that Unix users are -used to, you need to install a number of these tools before you can compile -doxygen for Windows. +used to, you'll need to install a number of these tools before you can compile +doxygen for Windows from the command-line. Here is what is required: <ul> diff --git a/doc/language.doc b/doc/language.doc index 9b0e4dd..d3c9db1 100644 --- a/doc/language.doc +++ b/doc/language.doc @@ -25,7 +25,7 @@ Doxygen has built-in support for multiple languages. This means that the text fragments that doxygen generates can be produced in languages other than English (the default) at configuration time. -Currently (version 1.3.2), 28 languages +Currently (version 1.3.2-20030717), 28 languages are supported (sorted alphabetically): Brazilian Portuguese, Catalan, Chinese, Chinese Traditional, Croatian, Czech, Danish, Dutch, English, Finnish, @@ -55,7 +55,7 @@ when the translator was updated. <TD>Brazilian Portuguese</TD> <TD>Fabio "FJTC" Jun Takada Chino</TD> <TD>chino@NOSPAM.icmc.sc.usp.br</TD> - <TD>1.3.1</TD> + <TD>up-to-date</TD> </TR> <TR BGCOLOR="#ffffff"> <TD>Catalan</TD> @@ -71,9 +71,9 @@ when the translator was updated. </TR> <TR BGCOLOR="#ffffff"> <TD>Chinese Traditional</TD> - <TD>Gary Lee</TD> - <TD>garylee@NOSPAM.ecosine.com.tw</TD> - <TD>1.2.16</TD> + <TD>Daniel YC Lin<br>Gary Lee</TD> + <TD>daniel@NOSPAM.twpda.com<br>garylee@NOSPAM.ecosine.com.tw</TD> + <TD>up-to-date</TD> </TR> <TR BGCOLOR="#ffffff"> <TD>Croatian</TD> @@ -145,7 +145,7 @@ when the translator was updated. <TD>Japanese</TD> <TD>Ryunosuke Satoh<br>Kenji Nagamatsu</TD> <TD>sun594@NOSPAM.hotmail.com<br>naga@NOSPAM.joyful.club.ne.jp</TD> - <TD>strange</TD> + <TD>obsolete</TD> </TR> <TR BGCOLOR="#ffffff"> <TD>Korean</TD> @@ -169,7 +169,7 @@ when the translator was updated. <TD>Portuguese</TD> <TD>Rui Godinho Lopes</TD> <TD>ruiglopes@NOSPAM.yahoo.com</TD> - <TD>1.3.1</TD> + <TD>up-to-date</TD> </TR> <TR BGCOLOR="#ffffff"> <TD>Romanian</TD> @@ -187,7 +187,7 @@ when the translator was updated. <TD>Serbian</TD> <TD>Dejan Milosavljevic</TD> <TD>dmilos@NOSPAM.email.com</TD> - <TD>1.3.1</TD> + <TD>up-to-date</TD> </TR> <TR BGCOLOR="#ffffff"> <TD>Slovak</TD> @@ -230,14 +230,15 @@ when the translator was updated. {\bf Language} & {\bf Maintainer} & {\bf Contact address} & {\bf Status} \\ \hline \hline - Brazilian Portuguese & Fabio "FJTC" Jun Takada Chino & {\tt chino@icmc.sc.usp.br} & 1.3.1 \\ + Brazilian Portuguese & Fabio "FJTC" Jun Takada Chino & {\tt chino@icmc.sc.usp.br} & up-to-date \\ \hline Catalan & Albert Mora & {\tt amora@iua.upf.es} & 1.2.17 \\ \hline Chinese & Wei Liu & {\tt liuwei@asiainfo.com} & 1.2.13 \\ & Wang Weihan & {\tt wangweihan@capinfo.com.cn} & \\ \hline - Chinese Traditional & Gary Lee & {\tt garylee@ecosine.com.tw} & 1.2.16 \\ + Chinese Traditional & Daniel YC Lin & {\tt daniel@twpda.com} & up-to-date \\ + & Gary Lee & {\tt garylee@ecosine.com.tw} & \\ \hline Croatian & Boris Bralo & {\tt boris.bralo@zg.tel.hr} & 1.3.1 \\ \hline @@ -262,7 +263,7 @@ when the translator was updated. Italian & Alessandro Falappa & {\tt alessandro@falappa.net} & up-to-date \\ & Ahmed Aldo Faisal & {\tt aaf23@cam.ac.uk} & \\ \hline - Japanese & Ryunosuke Satoh & {\tt sun594@hotmail.com} & strange \\ + Japanese & Ryunosuke Satoh & {\tt sun594@hotmail.com} & obsolete \\ & Kenji Nagamatsu & {\tt naga@joyful.club.ne.jp} & \\ \hline Korean & Richard Kim & {\tt ryk@dspwiz.com} & strange \\ @@ -272,13 +273,13 @@ when the translator was updated. Polish & Piotr Kaminski & {\tt Piotr.Kaminski@ctm.gdynia.pl} & strange \\ & Grzegorz Kowal & {\tt g\_kowal@poczta.onet.pl} & \\ \hline - Portuguese & Rui Godinho Lopes & {\tt ruiglopes@yahoo.com} & 1.3.1 \\ + Portuguese & Rui Godinho Lopes & {\tt ruiglopes@yahoo.com} & up-to-date \\ \hline Romanian & Alexandru Iosup & {\tt aiosup@yahoo.com} & 1.2.16 \\ \hline Russian & Alexandr Chelpanov & {\tt cav@cryptopro.ru} & strange \\ \hline - Serbian & Dejan Milosavljevic & {\tt dmilos@email.com} & 1.3.1 \\ + Serbian & Dejan Milosavljevic & {\tt dmilos@email.com} & up-to-date \\ \hline Slovak & Stanislav Kudl\'{a}\v{c} & {\tt skudlac@pobox.sk} & 1.2.18 \\ \hline diff --git a/doc/translator.py b/doc/translator.py new file mode 100644 index 0000000..177db97 --- /dev/null +++ b/doc/translator.py @@ -0,0 +1,1119 @@ +"""Script to generate reports on translator classes from Doxygen sources. + + The main purpose of the script is to extract the information from sources + related to internationalization (the translator classes). It uses the + information to generate documentation (language.doc, + translator_report.txt) from templates (language.tpl, maintainers.txt). + + Simply run the script without parameters to get the reports and + documentation for all supported languages. If you want to generate the + translator report only for some languages, pass their codes as arguments + to the script. In that case, the language.doc will not be generated. + Example: + + python translator.py en nl cz + + Originally, the script was written in Perl and was known as translator.pl. + The last Perl version was dated 2002/05/21 + + Petr Prikryl (prikrylp@skil.cz) +""" + +# History: +# -------- +# 2002/05/21 +# - This was the last Perl version. +# 2003/05/16 +# - If the script is given list of languages, only the translator report +# is generated and only for those languages. +# +################################################################ + +import os, re, sys + +# Global informations are stored in the global 'info' dictionary. +# This dictionary should be accessed only via GetInfo() because the first +# call initializes the empty dictionary. (I was too lazy to create +# a singleton.) +# +info = {} + +def GetInfo(): + """Returns reference to the info dictionary. + + If the dictionary is empty, it will be filled with some initial values. + """ + + global info + + # If the dictionary with globally shared information is empty, then + # fill the static values. + if not info: + # Get the name of the script without the path and the path without name. + scriptpath, scriptname = os.path.split(os.path.abspath(sys.argv[0])) + info['scriptname'] = scriptname + + # Determine the Doxygen's doc directory. If the DOXYGEN_DOCDIR + # environment variable is defined, then it says where the directory + # is. If it is not, then it will be directory where this script is + # placed. + docdir = os.getenv('DOXYGEN_DOCDIR', '*') + if docdir == '*': + docdir = scriptpath + + docdir = os.path.abspath(docdir) + info['docdir'] = docdir + + # Doxygen's root directory is just one above the docdir. + doxygenrootdir = os.path.abspath(os.path.join(docdir, '..')) + info['doxygenrootdir'] = doxygenrootdir + + # Doxygen's src directory is just below its root. + info['srcdir'] = os.path.join(doxygenrootdir, 'src') + + # Doxygen's current version is read from the 'version' file in the root. + try: + fver = file(os.path.join(doxygenrootdir, 'version')) + doxversion = fver.readline().strip() + fver.close() + info['doxversion'] = doxversion + except IOError: + info['doxversion'] = 'unknown' + + + # Names of the template files and other intput files (template for + # language.doc and the database of local language maintainers). + info['flangtplname'] = 'language.tpl' + info['flangtpl'] = os.path.join(docdir, info['flangtplname']) + info['fmaintainersname'] = 'maintainers.txt' + info['fmaintainers'] = os.path.join(docdir, info['fmaintainersname']) + + # Names of the output files. + info['ftranslatortxtname'] = 'translator_rep.txt' + info['ftranslatortxt'] = os.path.join(docdir, info['ftranslatortxtname']) + info['flangdocname'] = 'language.doc' + info['flangdoc'] = os.path.join(docdir, info['flangdocname']) + + # If the script is given one or more arguments, they should be codes + # of languages (two letters). Convert them into lower case and + # build the list of them. Empty list will be interpreted as the request + # for processing all languages. + langlist = [] + if len(sys.argv) > 1: + langlist = sys.argv[1:] + info['languages'] = langlist + + # Create the dictionary of the required method. Keys will be the unified + # method prototypes, values will be True (for easy testing). + info['required_methods'] = {} + + return info + + +def CopyTemplateToLanguageDoc(): + """'flangtpl' + no src --> 'flangdoc' + + The function takes the 'flangtpl' template and generates 'flangdoc' + without using information from other sources. This function is called + when source files were not found. The marks inside the template are + replaced by warning-like explanations that something could not be done + because sources were not available. Writes directly to the file, returns + nothing. + + If the script was called only for selected languages, the documentation + is not generated. + """ + + # Get the reference to the initialized info dictionary. If the script was + # called for selected languages, return immediately. + info = GetInfo() + if not info['langlist']: + return + + # Read the content of the template file. + fin = file(info['flangtpl']) + cont = fin.read() + fin.close() + + # Replace the template marks by some notices. + cont = re.sub(r'(?s)<notice>.+?</notice>', + """Warning: this file was generated from the %(flangtplname)s template + * by the %(scriptname)s script. As doxygen sources were not available + * in that time, some information could not be extracted + * and inserted into this file. + * + * Do not edit this file. Edit the above mentioned files!""", cont) + + cont = re.sub(r'(?s)\$version', '%(doxversion)s', cont) + cont = re.sub(r'(?s)\$numlang', + '<b>[number of supported languages could not be extracted -- no sources]</b>', + cont) + + cont = re.sub(r'(?s)\$languages', + '<b>[names of languages could not be extracted -- no sources]</b>', cont) + + cont = re.sub(r'(?s)\$information_table', + '<b>[Information table could not be extracted -- no sources.]</b>', cont) + + cont = re.sub(r'(?s)\$translator_report_file_name', + '%(ftranslatortxt)s <b>[translator report could not be generated -- no sources]</b>', + cont) + + cont = re.sub(r'(?s)\$translator_report_link', + '<b>[no sources, no link]</b>', cont) + + # Replace the generated marks by the info from the info dictionary. + # + cont = cont % info + + # Write the template with replacements to the output doc. + fout = file(info['flangdoc'], 'w') + fout.write(cont) + fout.close() + + +def GetPureVirtualFrom(filename): + """Returns the list of pure virtual method prototypes from the filename. + + Each method prototype is returned as one string, one line, one list item). + The input argument is the full name of the source file.""" + + # Read the content of the file to one string and remove C comments, + # one line comments, leading text to the first 'virtual' keyword, + # text behind the class, and finally empty lines. + f = file(filename) + cont = f.read() + f.close() + + cont = re.sub(r'(?s)/\*.+?\*/', '', cont) # C comments + cont = re.sub(r'(?m)//.*$', '', cont) # C++ comments + cont = 'virtual ' + re.sub(r'(?s)^.+?virtual\s', '', cont) # prefix + cont = re.sub(r'(?s)};.+$', '', cont) # suffix + cont = re.sub(r'(?s)\n\s*\n', r'\n', cont) # empty lines + + # Remove the empty implementation of the updateNeededMessage() method + # which is to be implemented by adapters only, not by translators. + cont = re.sub(r'(?s)\s*virtual\s+QCString\s+updateNeededMessage.+?}.*?\n', + '', cont) + + # Erase anything between "=0;" and "virtual". Only the pure virtual + # methods will remain. Remove also the text behind the last "= 0;" + cont = re.sub(r'(?s)(=\s*0\s*;).*?(?P<vir>virtual)', r'=0;\n\g<vir>', cont) + cont = re.sub(r'(?s)^(?P<x>.+=\s*0\s*;).*$', r'\g<x>', cont) + + # Replace all consequent white spaces (including \n) by a single + # space. Strip also the leading and the trailing space. + cont = re.sub(r'(?s)\s+', ' ', cont) + cont = cont.strip() + + # Split internally the string into lines by replacing the '= 0;' by '\n'. + # Keep the string stil as one multiline string. + cont = re.sub(r'(?s)\s*=\s*0\s*;\s*', r'\n', cont) + + # Remove the keyword 'virtual' because the derived classes may not use it. + cont = re.sub(r'(?m)^virtual\s+', '', cont) + + # Split the string to the list of striped lines. Do strip the string + # first so that no empty line list item is generated. + L = cont.strip().split('\n') + + # Build the list of unified prototypes and return it. + return L + +def StripArgIdentifiers(prototype): + """Returns the method prototype without argument identifiers. + + The goal of the function is to get only the necessary, single form + of the method prototype. This way the prototypes from derived classes + can be compared one by one with the methods in the base class.""" + + # Parse the prototype, and split the string of arguments it can be empty). + m = re.match(r'^(?P<prefix>.+?)\((?P<args>.*?)\)(?P<suffix>.*)$', prototype) + str_prefix = m.group('prefix') + str_args = m.group('args') + str_suffix = m.group('suffix') + args = str_args.split(',') + + # Each argument will be stripped and put to the new list. Only the types + # are important. Using the spaces has to be normalized because people + # differ in opinion where to put spaces. Let's prepare regular + # expressions for the tasks. + rex_type = re.compile(r'''^(?P<type> # name of the type group + \s* # there can be spaces behind comma, + (const\s+)? # possibly const at the beginning + [A-Za-z0-9_:]+ # type identifier can be qualified + (\s*[*&])? # could be reference or pointer + ) # ... the above is important, + .*$''', # the rest contains the identifier + re.VERBOSE) + + # People may differ in opinion whether a space should or should not + # be written between a type identifier and the '*' or '&' (when + # the argument is a pointer or a reference). + rex_norm = re.compile(r'\s*(?P<x>[*&])') + + # Strip each of the arguments and put them to the 'stripped' list. + # Only the type of the identifier is important. Extract it, normalize + # the using of spaces, and append the result to the list of striped + # arguments. (Sequence of more than one space is solved later.) + stripped = [] + for arg in args: + arg = rex_type.sub(r'\g<type>', arg) + arg = rex_norm.sub(r' \g<x>', arg) + stripped.append(arg) + + # Join the stripped arguments into one line again, and build the striped + # form of the prototype. Remove the duplicit spaces. + result = re.sub(r'\s+', ' ', + str_prefix + '(' + ', '.join(stripped) + ')' + str_suffix) + + return result + +def GetInfoFrom(input_filename): + """Returns list of info related to the parsed file. + + GetInfoFrom returns the list of information related to the + parsed source file. The input argument is the name of the + translator_xx.h file including path. + + The output list contains the following items: + - class identifier + - base class identifier + - method prototypes (each in a separate item)""" + + # Let's open the file and read it into a single string. + f = file(input_filename) + cont = f.read() + f.close() + + # Remove comments and empty lines. + cont = re.sub(r'(?m)//.*$', '', cont) # C++ comments + cont = re.sub(r'(?s)/\*.+?\*/', '', cont) # C comments + cont = re.sub(r'(?s)\n\s*\n', r'\n', cont) # empty lines + + # Extract the class and base class identifiers. + rex = re.compile(r'''^.*class\s+ + (?P<class>Translator\w+?)\s*: + \s*public\s+(?P<base>\w+)\b + ''', re.VERBOSE | re.DOTALL) + m = rex.match(cont) + assert(m) + assert(m.group('class')) + assert(m.group('base')) + + # Put the class and the base class into the output list. + result = [m.group('class'), m.group('base')] + + # Remove the opening curly brace. Remove also the first "public:" + cont = re.sub(r'(?s)^.*?{', '', cont) + cont = re.sub(r'(?s)(^.*\spublic:\s+)?', '', cont) + + # Cut the things after the class. + cont = re.sub(r'(?s)}\s*;\s*#endif\s*$', '', cont) + + # Remove the "virtual" keyword, because the derived class is not forced + # to use it. + cont = re.sub(r'\bvirtual\s+', '', cont) + + # Remove all strings from lines. + cont = re.sub(r'(?s)".*?"', '', cont) + + # Remove all bodies of methods + while cont.find('{') >= 0: + cont = re.sub(r'(?s){[^{}]+?}', '', cont) + + # Remove all private methods, i.e. from "private:" to "public:" + # included. Later, remove also all from "private:" to the end. + cont = re.sub(r'(?s)\bprivate\s*:.*?\bpublic\s*:', '', cont) + cont = re.sub(r'(?s)\bprivate\s*:.*$', '', cont) + + # Some of the translators use conditional compilation where + # the branches define the body of the method twice. Remove + # the ifdef/endif block content. + cont = re.sub(r'(?s)#ifdef.*?#endif', '', cont) + + # Now the string should containt only method prototypes. Let's unify + # their format by removing all spaces that are not necessary. + cont = re.sub(r'\s+', ' ', cont) + cont = re.sub(r'^\s+', '', cont) + cont = re.sub(r'\s+$', '', cont) + + # Then let's put all of them on separate lines (one protototype -- + # one line; no empty lines). + cont = re.sub(r'\s+\(', '(', cont) + cont = re.sub(r'(?s)\)\s*', ')\n', cont) + + # Split the string, add it to the output list, and return the result. + result.extend(cont.strip().split('\n')) + return result + + +def GetAdapterClassesInfo(required): + """Returns the list of strings with information related to the adapter classes. + + Each one-line string contains the identifier of the adapter class and + the number of required methods that are implemented by the adapter. + + The function takes one agument -- the reference to the hash with + stripped prototypes of the required methods.""" + + # Let's open the file with the translator adapter classes. + info = GetInfo() + filename = os.path.join(info['srcdir'], 'translator_adapter.h') + f = file(filename) + cont = f.read() + f.close() + + # Remove the preprocessor directives. + cont = re.sub(r'(?m)^\s*#\w+.+$', '', cont) + + # Remove comments and empty lines. + cont = re.sub(r'(?m)//.*$', '', cont) # C++ comments + cont = re.sub(r'(?s)/\*.+?\*/', '', cont) # C comments + cont = re.sub(r'(?s)\n\s*\n', r'\n', cont) # empty lines + + # Place delimiters to separate the classes, and remove + # the TranslatorAdapterBase class. + # + cont = re.sub(r'(?s)};\s*class\s+', '<class>', cont) + cont = re.sub(r'(?s)class\s+TranslatorAdapterBase\s+.+?<class>', '<class>', cont) + cont = re.sub(r'(?s)};', '', cont) + + # Remove the base classes and the beginning of the the class definitions. + cont = re.sub(r'(?s)(TranslatorAdapter[_0-9]+)\s*:.+?{\s*(public\s*:)?', + '\g<1>', cont) + + # Remove all bodies of methods + while cont.find('{') >= 0: + cont = re.sub(r'(?s){[^{}]+?}', '', cont) + + # Remove the "virtual" keywords. + cont = re.sub(r'(?m)^\s*virtual\s+', '', cont) + + # Remove the empty lines. + cont = re.sub(r'(?s)\n\s*\n', '\n', cont) + + # Trim the spaces. + cont = re.sub(r'(?m)^\s+', '', cont) + cont = re.sub(r'(?m)\s+$', '', cont) + + # Split the string into the lines again. + content = cont.split('\n') + + # Now the list contains only two kinds of lines. The first + # kind of lines starts with the <class> tag and contains the + # identifier of the class. The following lines list the + # non-stripped prototypes of implemented methods without the + # "virtual" keyword. + # + # Now we will produce the result by looping through all the + # lines and counting the prototypes of the required methods + # that are implemented by the adapter class. + # + cinfo = '' + cnt = 0 + methods = '' + result = [] + + rex_class = re.compile(r'^<class>(?P<class>\w+)\s*$') + for line in content: + m = rex_class.match(line) + if m: + # Another adapter class found. + adapter_class = m.group('class') + + # If the cinfo is not empty then it contains partial + # information about the previously processed adapter. + if cinfo != '': + # Complete the cinfo and push it into the result. + s = '' + if cnt != 1: + s = 's' + cinfo += '\timplements %2d required method%s...\n' % (cnt, s) + result.append(cinfo + methods) + + # Initialize the counter and store the adapter class identifier + # in the cinfo. + # + cinfo = adapter_class + cnt = 0; + methods = '' + else: + # The line contains the prototype of the implemented method. + # If it is the required method, count it, and add it to the + # string of methods. + stripped_prototype = StripArgIdentifiers(line) + + if required.has_key(stripped_prototype): + cnt += 1 + methods += ' %s\n' % line + + # If the cinfo is not empty then it contains partial + # information about the last processed adapter. + if cinfo != '': + # Complete the cinfo and push it into the @result. + s = '' + if cnt != 1: + s = 's' + cinfo += '\timplements %2d required method%s...\n' % (cnt, s) + result.append(cinfo + methods) + + # Return the result list. + return result + + +def GetLanguagesInfo(seq_or_dic): + """Returns (numlang, langlst, formated langstr). + + The numlang is the number of supported languages. The langlst is the + list of pairs like ('TranslatorBrazilian', 'Brazilian Portuguese') + """ + + languages = [] + for k in seq_or_dic: + # Remove the 'Translator' prefix from the class name to obtain + # the brief name of the language. + assert(k[:len('Translator')] == 'Translator') + lang = k[len('Translator'):] + + # Do correction of the language name for the selected languages. + if lang == 'Brazilian': lang = 'Brazilian Portuguese' + if lang == 'Chinesetraditional': lang = 'Chinese Traditional' + + # Append the language to the list. + languages.append((k, lang)) + + # Sort the languages and construct the output string. Insert new line + # after each line. Add the 'and' before the last language + languages.sort() + count = 0 + output = '' + for L in languages: + output += L[1] # readable form of the language + count += 1 + + if count < len(languages) - 1: # separate by comma + output += ', ' + elif count == len(languages) - 1: # separate by comma and 'and' + output += ', and ' + + if count % 5 == 0: + output += '\n' + + return (len(languages), languages, output) + + +def GenerateLanguageDoc(cb): + """Generates the content as expected in the 'flangdoc' file. + + GenerateLanguageDoc takes document templates and code sources + generates the content as expected in the 'flangdoc' file (the + part of the Doxygen documentation), and returns the result as a + string. + + The input parameter is the reference to the class/base dictionary.""" + + # Define templates for HTML table parts of the documentation. + htmlTableHead = r'''\htmlonly +<TABLE ALIGN=center CELLSPACING=0 CELLPADDING=0 BORDER=0> +<TR BGCOLOR="#000000"> +<TD> + <TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0> + <TR BGCOLOR="#4040c0"> + <TD ><b><font size=+1 color="#ffffff"> Language </font></b></TD> + <TD ><b><font size=+1 color="#ffffff"> Maintainer </font></b></TD> + <TD ><b><font size=+1 color="#ffffff"> Contact address </font> + <font size=-2 color="#ffffff">(remove the NOSPAM.)</font></b></TD> + <TD ><b><font size=+1 color="#ffffff"> Status </font></b></TD> + </TR> +''' + + htmlTableRow = r''' <TR BGCOLOR="#ffffff"> + <TD>$lang</TD> + <TD>$maintainer</TD> + <TD>$email</TD> + <TD>$status</TD> + </TR> +''' + + htmlTableFoot = r''' </TABLE> +</TD> +</TR> +</TABLE> +\endhtmlonly +''' + + # Define templates for LaTeX table parts of the documentation. + latexTableHead = r'''\latexonly +\begin{tabular}{|l|l|l|l|} + \hline + {\bf Language} & {\bf Maintainer} & {\bf Contact address} & {\bf Status} \\ + \hline +''' + + latexTableRow = r''' $lang & $maintainer & {\tt $email} & $status \\ +''' + + latexTableFoot = r''' \hline +\end{tabular} +\endlatexonly +''' + + # Read the template of the documentation, and join the content + # to a single string. + info = GetInfo() + filename = os.path.join(info['docdir'], info['flangtpl']) + f = file(filename) + output = f.read() + f.close() + + # Get the number of languages, list of their names and formated string + # with the list in human readable English form. + (numlang, langlst, langstr) = GetLanguagesInfo(cb) + + # Substitute the marks inside the template. + output = re.sub(r'(?s)\$version', info['doxversion'], output) + output = re.sub(r'(?s)\$numlang', str(numlang), output) + output = re.sub(r'(?s)\$languages', langstr, output) + + # Create the dictionary for info for each language. + langinfo = {} + for (trClass, langname) in langlst: + langinfo[langname] = cb[trClass] + '<msep/>unknown: unknown' + + # Read the information related to maintainers into the + # string using suitable separators -- one line, one language. #{{{ + filename = os.path.join(info['docdir'], info['fmaintainers']) + print filename + f = file(filename) + maintainers = f.read() + f.close() + + # Trim the spaces on the lines. Strip the comment lines that + # start with % sign. + maintainers = re.sub(r'(?m)^[ \t]+', '', maintainers) + maintainers = re.sub(r'(?m)[ \t]+$', '', maintainers) + maintainers = re.sub(r'(?m)^%.*$', '', maintainers) + + # Join the information for one language into one line, + # and remove empty lines. + maintainers = re.sub(r'(?s)\b\n\b', '<sep/>', maintainers) + maintainers = re.sub(r'(?s)\n{2,}', '\n', maintainers) + maintainers = re.sub(r'(?s)^\n+', '', maintainers) + maintainers = re.sub(r'(?s)\n+$', '', maintainers) + + # Split the string back to the list, and update the information + # in the hash with information for languages. + lst = maintainers.split('\n') + lst.sort() + for line in lst: + # Split the line for one language to separate lines for + # the language and one or more maintainers. Ensure that the language + # starts with uppercase and continues with lowercase. (It will be used + # for reconstructing the translator class identifier.) + linfo = line.split('<sep/>') + lang = linfo[0].capitalize() + del linfo[0] + + # Add information to the langinfo dictionary. If the language + # was not defined in sources, add the question mark to the + # language identifier. + # + if langinfo.has_key(lang): + langinfo[lang] = cb['Translator' + lang] + '<msep/>' + \ + '<sep/>'.join(linfo) + else: + lang += ' (?)' + langinfo[lang] = 'unknown<msep/>' + '<sep/>'.join(linfo) + + # Now, the langinfo dictionary contains all the information needed for + # generating the tables (HTML and LaTeX). Define string variables + # for each of the tables, and initialize them. + # + tableHTML = htmlTableHead + tableLATEX = latexTableHead + + # Loop through sorted keys for the languages, parse the + # information, and add it to the tables. + langs = langinfo.keys() + langs.sort() + for lang in langs: + # Transform the key for the language into more human readable + # form. Basically, only languages with two words are going to be + # corrected. + if lang == 'Brazilian': + lang_readable = 'Brazilian Portuguese' + elif lang == 'Chinesetraditional': + lang_readable = 'Chinese Traditional' + else: + lang_readable = lang + + print lang, lang_readable + """ + + # Read the line with info for the language and separate + # the status. #{{{ + # + my @list = split(/<msep\/>/, $language{$lang}); + my $status = shift @list; + + my $i = $status =~ s{^Translator$}{up-to-date}; + + if ($i == 0) { + $i = $status =~ s{^TranslatorAdapter_(\d)_(\d)_(\d)} + {$1.$2.$3}x; + } + + if ($i == 0) { + $i = $status =~ s{^TranslatorEnglish$} + {obsolete}x; + } + + if ($i == 0) { $status = 'strange'; } + + ##}}} + + # Split the rest of the list (should be a single item) into + # the list with one or more maintainers -- one line, one + # maintainer. #{{{ + # + my $rest = shift @list; + @list = split(/<sep\/>/, $rest); + ##}}} + + # In HTML table, maintainer names are placed in the same + # cell. Also their e-mails are placed in a single cell. + # Extract the string with concatenated names and the string + # with concatenated e-mails. Add the row to the HTML + # table. #{{{ + # + my $name = ''; + my $email = ''; + + foreach my $maintainer (@list) { + + if ($name ne '') { $name .= '<br>'; } + if ($email ne '') { $email .= '<br>'; } + + $maintainer =~ m{^\s*(.+?)\s*:\s*(.+?)\s*$}; + + $name .= $1; + $email .= $2; + } + + # Prepare the HTML row template, modify it, and add the + # result to the HTML table. + # + my $item = $htmlTableRow; + + $item =~ s{\$lang}{$lang_readable}; + $item =~ s{\$maintainer}{$name}; + $item =~ s{\$email}{$email}; + $item =~ s{\$status}{$status}; + + $tableHTML .= $item; + + ##}}} + + # For LaTeX, more maintainers for the same language are + # placed on separate rows in the table. The line separator + # in the table is placed explicitly above the first + # maintainer. Add rows for all maintainers to the LaTeX + # table. #{{{ + # + # Prepare the LATEX row template, modify it, and add the + # result to the LATEX table. + # + $item = $latexTableRow; + + my $first = shift @list; # the first maintainer. + $first =~ m{^\s*(.+?)\s*:\s*(.+?)\s*$}; + + $name = $1; + $email = $2; + + $item =~ s{\$lang}{$lang_readable}; + $item =~ s{\$maintainer}{$name}; + $item =~ s{\$email}{$email}; + $item =~ s{\$status}{$status}; + + $tableLATEX .= " \\hline\n" . $item; + + # List the other maintainers for the language. Do not set + # lang and status for them. + # + while (@list) { + my $next = shift @list; + $next =~ m{^\s*(.+?)\s*:\s*(.+?)\s*$}; + + my $name = $1; + my $email = $2; + my $item = $latexTableRow; + + $item =~ s{\$lang}{}; + $item =~ s{\$maintainer}{$name}; + $item =~ s{\$email}{$email}; + $item =~ s{\$status}{}; + + $tableLATEX .= $item; + } + ##}}} + } + ##}}} + + # Finish the tables, and substitute the mark in the doc + # template by the concatenation of the tables. Add NOSPAM to + # email addresses in the HTML table. Replace the special + # character sequences. #{{{ + # + $tableHTML .= $htmlTableFoot; + $tableLATEX .= $latexTableFoot; + + $tableHTML =~ s{@}{\@NOSPAM.}sg; + $tableHTML =~ s{č}{č}sg; + $tableHTML =~ s{ř}{ř}sg; + + $tableLATEX =~ s/á/\\'{a}/sg; + $tableLATEX =~ s/ä/\\"{a}/sg; + $tableLATEX =~ s/ö/\\"{o}/sg; + $tableLATEX =~ s/ø/\\o{}/sg; + $tableLATEX =~ s/č/\\v{c}/sg; + $tableLATEX =~ s/ř/\\v{r}/sg; + $tableLATEX =~ s/_/\\_/sg; + + $output =~ s{\$information_table}{$tableHTML$tableLATEX}; + + ##}}} + + # Replace the other symbols in the template by the expected + # information. ##{{{ + # + $output =~ s{\$version}{$doxversion}; + + $output =~ s{\$translator_report_file_name} + {<code>doxygen/doc/$ftranslatortxt</code>}x; + + $output =~ s{\$translator_report_link} + {<a href=\"../doc/$ftranslatortxt\"> + <code>doxygen/doc/$ftranslatortxt</code></a>}x; + ##}}} + + # Replace the introduction notice in the output. #{{{ + # + $output =~ s{<notice>.+?</notice>} +{Warning: this file was generated from the $flangtpl template + * and the $fmaintainers files by the $0 script. + * + * Do not edit this file. Edit the above mentioned files!}sx; + ##}}} + + # Return the content of the generated output file. + # + return $output; +} +""" + return output + + +################################################################# Body +if __name__ == '__main__': + # Get the reference to the initialized dictionary with the shared info. + info = GetInfo() + + # File with the translator base class must be present. Exit otherwise, + # but be kind to those who already have the documentation + # generated by this script ready, but who do not have sources. + # If no 'flangdoc' is present, copy the template to it. + if not os.path.isfile(os.path.join(info['srcdir'], 'translator.h')): + sys.stderr.write(('\nThe %(scriptname)s warning:\n' + + '\tThe translator.h not found in %(srcdir)s.\n' + + '\tThe %(ftranslatortxtname)s will not be ' + + "generated (you don't need it).\n") % info) + + # $flangdoc is not present, copy the template to it, and do the simplified + # replacement of the markers inside the template. Generate the warning + # about 'flangdoc' content. + if not os.path.isfile(info['flangdoc']): + CopyTemplateToLanguageDoc(); + sys.stderr.write(('\nThe %(scriptname)s warning:\n' + + "\tThe %(flangdoc)s not found in the '%(docdir)s' directory.\n" + + '\tThe %(flangtpl)s template content copied into it.\n' + + '\tAs the sources are not available, some information\n' + + '\tcould not be extracted and inserted into %(flangdoc)s.\n') % info) + + # Exit as if nothing happened. + sys.exit(0) + + # Create the list of all translator_xxxx.h file names. If the script was + # given a list of languages (two letters for each language), then fill + # the list only by the translator files for the languages. + directory = info['srcdir'] + langlist = info['languages'] + if langlist: + files = [os.path.join(directory, 'translator_%s.h' % lang) + for lang in langlist + if os.path.isfile(os.path.join(directory, + 'translator_%s.h' % lang))] + else: + rex_tr = re.compile(r'^translator_\w\w\w?\.h$', re.IGNORECASE) + files = [os.path.join(directory, f) + for f in os.listdir(directory) + if os.path.isfile(os.path.join(directory, f)) + and rex_tr.match(f)] + + # Get only the pure virtual methods from the Translator class + # into a list for later testing present/not present. + expected_lst = GetPureVirtualFrom(os.path.join(info['srcdir'], + 'translator.h')) + # Fill the 'required_methods' dictionary for unified form + # of the prototypes. + required = info['required_methods'] + for method in expected_lst: + prototype = StripArgIdentifiers(method) + required[prototype] = True + + # The details for translators will be collected into the output + # string. If some details are listed for a translator, the flag + # will be set to produce possible warning to the list of + # up-to-date translators. + output = '' + details = {} + + # Collect base classes of translators in the hash. CB stands + # for Class and Base. + cb = {} + + # Loop through all translator files. Extract the implemented + # virtual methods and compare it with the requirements. Prepare + # the output. + rex_trAdapter = re.compile(r'^TranslatorAdapter_') + rex_trEN = re.compile(r'^TranslatorEnglish$') + + for filename in files: + # Get the information from the sources. Remember the base + # class for each of the classes. Clear the flag for + # details for the class. + finfo = GetInfoFrom(filename) + (class_, base_) = finfo[0:2] + cb[class_] = base_ + details[class_] = False + + # Set the value of the required methods to 1 (true). Let + # this indicate that the method was not defined in the + # translator class. + for method in required: + required[method] = True + + # Loop through all items and compare the prototypes. Mark + # the implemented method and collect the old ones. + old_methods = [] + for method in finfo[2:]: + # Get only the necessary form of the prototype. + prototype = StripArgIdentifiers(method) + + # Mark as recognized when the prototype is required. + # Otherwise, remember it as old method which is + # implemented, but not required. + if (required.has_key(prototype)): + required[prototype] = False # satisfaction + else: + old_methods.append(method) + + # Loop through the list of expected methods and collect + # the missing (new) methods. Do this only when it derives + # from Translator or TranslatorAdapter classes (i.e. ignore + # any unusual kind of TranslatorXxxx implementation). + # Accept also deriving from TranslatorEnglish, that can + # be done by doxygen developers to solve problems with + # some really outdated translators. + missing_methods = [] + if rex_trAdapter.match(base_) or rex_trEN.match(base_): + + for method in expected_lst: + # Get the stripped version of the prototype. + prototype = StripArgIdentifiers(method) + + # If the prototype is stored in the required + # table, and if it was not marked as implemented, + # then it should be. It is a missing method. + #try: + if required[prototype]: + missing_methods.append(method) + + # The detailed output will be produced only when it is needed. + if old_methods or missing_methods or rex_trAdapter.match(base_): + output += '\n\n\n' + output += '%s (%s)\n%s\n' % (class_, base_, '-' * len(class_)) + + if rex_trEN.match(base_): + output += ''' +This translator is implemented via deriving from the English translator. +This should be done only in the case when the language maintainer +or the doxygen developers need to update some really old-dated translator. +Otherwise, deriving from the translator adapter classes should be used +for obsolete translators. If you still want some texts to be in English +copy the sources of the English translator. + +The obsolete and missing method lists (below) reflect what have to be done +to derive directly from the Translator class (i.e. to reach up-to-date status). +''' + + elif not rex_trAdapter.match(base_): + output += ''' +This is some unusual implementation of the translator class. It is derived +from the %s base class. The usual translator class derives +or from the Translator class or from some TranslatorAdapter_x_x_x classes. +Because of that, nothing can be guessed about missing or obsolete methods. +''' % base_ + + if missing_methods: + output += '\nMissing methods (should be implemented):\n\n' + for m in missing_methods: + output += ' ' + m + '\n' + + if old_methods: + output += '\nObsolete methods (should be removed):\n\n' + old_methods.sort() + for m in old_methods: + output += ' ' + m + '\n' + + # Some details were listed, set the details flag for the class. + details[class_] = 1; + + + # Generate the ASCII output file. + fout_name = info['ftranslatortxt'] + + # Open it first, and output the version information. + fout = file(fout_name, 'w') + fout.write('(version %s)\n\n' % info['doxversion']) + + # List the supported languages. + (numlang, langlst, langstr) = GetLanguagesInfo(cb) + fout.write('Doxygen supports the following (' + str(numlang) + + ') languages (sorted alphabetically):\n\n') + fout.write(langstr + '.\n') + + # If there are up-to-date translators, list them. + L = [k for k in cb if cb[k] == 'Translator'] + L.sort() + + if L: + fout.write('\n' + '-' * 70 + '\n') + fout.write('''The \ +following translator classes are up-to-date (sorted alphabetically). +This means that they derive from the Translator class. Anyway, there still +may be some details listed even for the up-to-date translators. +Please, check the text below if the translator is marked so. + +''') + for tr in L: + # Print the class name. If some details were listed for + # the translator class, add a notice. + fout.write(' ' + tr) + if details[tr]: + fout.write('\t-- see details below in the report') + fout.write('\n') + + # If there are obsolete translators, list them. + L = [k for k in cb if rex_trAdapter.match(cb[k])] + L.sort() + + if L: + fout.write('\n' + '-' * 70 + '\n') + fout.write('''The \ +following translator classes are obsolete (sorted alphabetically). +This means that they derive from some of the adapter classes. + +''') + for tr in L: + fout.write(' %s\t(%s)\n' % (tr, cb[tr])) + + # If there are translators derived from TranslatorEnglish, list them + # and name them as really obsolete. + L = [k for k in cb if cb[k] == 'TranslatorEnglish'] + L.sort() + if L: + fout.write('\n' + '-' * 70 + '\n') + fout.write('''The \ +following translator classes are implemented via deriving +from the English translator. This should be done only in the case +when the language maintainer or the doxygen developers need to update +some really outdated translator. Otherwise, deriving from +the translator adapter classes should be prefered for obsolete translators. +See details below in the report. + +''') + for tr in L: + fout.write(' %s\t(%s)\n' % (tr, cb[tr])) + + # If there are other translators, list them. #{{{ + # + L = [k for k in cb + if not rex_trAdapter.match(cb[k]) + and cb[k] != 'TranslatorEnglish' + and cb[k] != 'Translator' + ] + L.sort() + + if L: + fout.write('\n' + '-' * 70 + '\n') + fout.write('''The \ +following translator classes are somehow different +(sorted alphabetically). This means that they do not derive from +the Translator class, nor from some of the adapter classes, +nor from the TranslatorEnglish. Nothing can be guessed about the methods. + +''') + for tr in L: + fout.write(' %s\t(%s)\n' % (tr, cb[tr])) + + # List all the translator adapter classes to show for which versions + # the adapters had to be created. Show, how many and what new methods + # are implemented by the adapters. + # + fout.write('\n' + '-' * 70 + '\n') + fout.write('''The \ +following translator adapter classes are implemented -- the older (with +lower number) are always derived from the newer. They implement the +listed required methods. Notice that some versions of doxygen did not +introduce any changes related to the language translators. From here you may +guess how much work should be done to update your translator: + +''') + adapter_info = GetAdapterClassesInfo(required) + + for ad in adapter_info: + fout.write(' %s\n' % ad) + + # List the methods that are expected to be implemented. + fout.write('\n' + '-' * 70 + '\n') + fout.write('''Localized \ +translators are expected to implement the following methods +(prototypes sorted aplhabetically): + +''') + + expected_lst.sort() + for m in expected_lst: + fout.write('%s\n' % m) + + # If there are some details for the translators, show them. + if output != '': + fout.write('\n\n' + '=' * 70 + '\n') + fout.write('Details related to specific translator classes follow.\n') + fout.write(output + '\n') + + # Close the ASCII output file + fout.close() + + # Generate the same using the original perl script. + os.system('translator.pl') + + # Generate the language.doc file. + filename = os.path.join(info['docdir'], info['flangdoc']) + f = file(filename, 'w') + f.write(GenerateLanguageDoc(cb)) + f.close() + + sys.exit(0) diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index 4ebf89e..21bbd3f 100644 --- a/packages/rpm/doxygen.spec +++ b/packages/rpm/doxygen.spec @@ -1,6 +1,6 @@ Summary: A documentation system for C/C++. Name: doxygen -Version: 1.3.2_20030717 +Version: 1.3.3 Release: 1 Epoch: 1 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz diff --git a/src/classdef.cpp b/src/classdef.cpp index 72ec333..d6f5352 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -134,6 +134,10 @@ QCString ClassDef::displayName() const { n=qualifiedNameWithTemplateParameters(); } + if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) + { + n=substitute(n,"::","."); + } return n; } @@ -1117,7 +1121,6 @@ void ClassDef::writeDocumentation(OutputList &ol) // write link to list of all members (HTML only) if (m_allMemberNameInfoSDict->count()>0 && !Config_getBool("OPTIMIZE_OUTPUT_FOR_C") - /* && !Config_getBool("INLINE_INHERITED_MEMB") */ ) { ol.pushGeneratorState(); @@ -2587,14 +2590,6 @@ QCString ClassDef::qualifiedNameWithTemplateParameters( QCString ClassDef::className() const { - //QCString className=m_localName; - //Definition *p=getOuterScope(); - //while (p && p->definitionType()==TypeClass) - //{ - // className.prepend(p->localName()+"::"); - // p=p->getOuterScope(); - //} - //return className; return m_className; }; diff --git a/src/classlist.cpp b/src/classlist.cpp index d234312..c370196 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -95,6 +95,7 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f } ol.startMemberItem(FALSE); QCString tmp = cd->compoundTypeString(); + QCString cname = substitute(cd->className(),"::","."); ol.writeString(tmp); ol.writeString(" "); ol.insertMemberAlign(); @@ -103,13 +104,13 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f ol.writeObjectLink(cd->getReference(), cd->getOutputFileBase(), 0, - cd->className() + cname ); } else { ol.startBold(); - ol.docify(cd->className()); + ol.docify(cname); ol.endBold(); } ol.endMemberItem(); diff --git a/src/commentcnv.l b/src/commentcnv.l index 5df9adf..6faafd5 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -198,7 +198,7 @@ void replaceComment(int offset); <CComment>[^\\@*\n]* { /* anything that is not a '*' */ copyToOutput(yytext,yyleng); } -<CComment>"*"+[^*/\n]* { /* stars without slashes */ +<CComment>"*"+[^*/\\@\n]* { /* stars without slashes */ copyToOutput(yytext,yyleng); } <CComment>\n { /* new line in comment */ diff --git a/src/compound.xsd b/src/compound.xsd index 042f8f5..9fb394a 100644 --- a/src/compound.xsd +++ b/src/compound.xsd @@ -120,9 +120,11 @@ <xsd:attribute name="mutable" type="DoxBool" /> </xsd:complexType> - <xsd:complexType name="descriptionType" mixed="true"> + <xsd:complexType name="descriptionType"> <xsd:sequence> - <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="internal" type="docInternalType" minOccurs="0" /> </xsd:sequence> </xsd:complexType> @@ -226,6 +228,312 @@ <xsd:attribute name="bodyend" type="xsd:integer" /> </xsd:complexType> + <xsd:complexType name="docSect1Type" mixed="true"> + <xsd:sequence> + <xsd:element name="title" type="xsd:string" /> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="internal" type="docInternalS1Type" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docSect2Type" mixed="true"> + <xsd:sequence> + <xsd:element name="title" type="xsd:string" /> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="internal" type="docInternalS2Type" minOccurs="0" /> + </xsd:sequencee + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docSect3Type" mixed="true"> + <xsd:sequence> + <xsd:element name="title" type="xsd:string" /> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="internal" type="docInternalS3Type" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docSect4Type" mixed="true"> + <xsd:sequence> + <xsd:element name="title" type="xsd:string" /> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="internal" type="docInternalS4Type" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docInternalType" mixed="true"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docInternalS1Type" mixed="true"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docInternalS2Type" mixed="true"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docInternalS3Type" mixed="true"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docInternalS4Type" mixed="true"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:group name="docTitleCmdGroup"> + <xsd:choice> + <xsd:element name="ulink" type="docURLLink" /> + <xsd:element name="bold" type="docMarkupType" /> + <xsd:element name="emphasis" type="docMarkupType" /> + <xsd:element name="computeroutput" type="docMarkupType" /> + <xsd:element name="subscript" type="docMarkupType" /> + <xsd:element name="superscript" type="docMarkupType" /> + <xsd:element name="center" type="docMarkupType" /> + <xsd:element name="small" type="docMarkupType" /> + <xsd:element name="htmlonly" type="xsd:string" /> + <xsd:element name="latexonly" type="xsd:string" /> + <xsd:element name="anchor" type="docAnchorType" /> + <xsd:element name="formula" type="docFormulaType" /> + <xsd:element name="ref" type="docRefTextType" /> + <xsd:element name="copy" type="docEmptyType" /> + <xsd:element name="trademark" type="docEmptyType" /> + <xsd:element name="registered" type="docEmptyType" /> + <xsd:element name="umlaut" type="docCharType" /> + <xsd:element name="acute" type="docCharType" /> + <xsd:element name="grave" type="docCharType" /> + <xsd:element name="circ" type="docCharType" /> + <xsd:element name="tilde" type="docCharType" /> + <xsd:element name="cedil" type="docCharType" /> + <xsd:element name="ring" type="docCharType" /> + <xsd:element name="szlig" type="docEmptyType" /> + <xsd:element name="nonbreakablespace" type="docEmptyType" /> + </xsd:choice> + </xsd:group> + + <xsd:complexType name="docTitleType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + </xsd:complexType> + + <xsd:group name="docCmdGroup"> + <xsd:choice> + <xsd:group ref="docTitleCmdGroup"/> + <xsd:element name="linebreak" type="docEmptyType" /> + <xsd:element name="hruler" type="docEmptyType" /> + <xsd:element name="preformatted" type="docMarkupType" /> + <xsd:element name="programlisting" type="listingType" /> + <xsd:element name="verbatim" type="xsd:string" /> + <xsd:element name="indexentry" type="docIndexEntryType" /> + <xsd:element name="orderedlist" type="docListType" /> + <xsd:element name="itemizedlist" type="docListType" /> + <xsd:element name="simplesect" type="docSimpleSectType" /> + <xsd:element name="title" type="docTitleType" /> + <xsd:element name="variablelist" type="docVariableListType" /> + <xsd:element name="table" type="docTableType" /> + <xsd:element name="heading" type="docHeadingType" /> + <xsd:element name="image" type="docImageType" /> + <xsd:element name="dotfile" type="docDotFileType" /> + <xsd:element name="toclist" type="docTocListType" /> + <xsd:element name="language" type="docLanguageType" /> + <xsd:element name="parameterlist" type="docParamListType" /> + <xsd:element name="xrefsect" type="docXRefSectType" /> + <xsd:element name="copydoc" type="docCopyType" /> + </xsd:choice> + </xsd:group> + + <xsd:complexType name="docParaType" mixed="true"> + <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + </xsd:complexType> + + <xsd:complexType name="docMarkupType" mixed="true"> + <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + </xsd:complexType> + + <xsd:complexType name="docURLLink" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + <xsd:attribute name="url" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="docAnchorType" mixed="true"> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docFormulaType" mixed="true"> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docIndexEntryType"> + <xsd:sequence> + <xsd:element name="primaryie" type="xsd:string" /> + <xsd:element name="secondaryie" type="xsd:string" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docListType"> + <xsd:sequence> + <xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docListItemType"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docSimpleSectType"> + <xsd:sequence> + <xsd:element name="title" type="docTitleType" minOccurs="0" /> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + <xsd:attribute name="kind" type="DoxSimpleSectKind" /> + </xsd:complexType> + + <xsd:complexType name="docVarListEntryType"> + <xsd:sequence> + <xsd:element name="term" type="docTitleType" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:group name="docVariableListGroup"> + <xsd:sequence> + <xsd:element name="varlistentry" type="docVarListEntryType" /> + <xsd:element name="listitem" type="docListItemType" /> + </xsd:sequence> + </xsd:group> + + <xsd:complexType name="docVariableListType"> + <xsd:sequence> + <xsd:group ref="docVariableListGroup" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docRefTextType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + <xsd:attribute name="refid" /> + <xsd:attribute name="kindref" /> + <xsd:attribute name="external" /> + </xsd:complexType> + + <xsd:complexType name="docTableType"> + <xsd:sequence> + <xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="caption" type="docCaptionType" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="rows" type="xsd:integer" /> + <xsd:attribute name="cols" type="xsd:integer" /> + </xsd:complexType> + + <xsd:complexType name="docRowType"> + <xsd:sequence> + <xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docEntryType"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + <xsd:attribute name="thead" type="DoxBool" /> + </xsd:complexType> + + <xsd:complexType name="docCaptionType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + </xsd:complexType> + + <xsd:complexType name="docHeadingType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + <xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 --> + </xsd:complexType> + + <xsd:complexType name="docImageType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + <xsd:attribute name="type" type="DoxImageKind" /> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="width" type="xsd:string" /> + <xsd:attribute name="height" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="docDotFileType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + + <xsd:complexType name="docTocItemType" mixed="true"> + <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" /> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docTocListType"> + <xsd:sequence> + <xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="docLanguageType"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + <xsd:attribute name="langid" type="xsd:string" /> + </xsd:complexType> + + <xsd:group name="docParamListGroup"> + <xsd:sequence> + <xsd:element name="parametername" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="parameterdescription" type="descriptionType" /> + </xsd:sequence> + </xsd:group> + + <xsd:complexType name="docParamListType"> + <xsd:sequence> + <xsd:group ref="docParamListGroup" maxOccurs="unbounded" /> + </xsd:sequence> + <xsd:attribute name="kind" type="DoxParamListKind" /> + </xsd:complexType> + + <xsd:complexType name="docXRefSectType"> + <xsd:sequence> + <xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="xrefdescription" type="descriptionType" /> + </xsd:sequence> + <xsd:attribute name="id" /> + </xsd:complexType> + + <xsd:complexType name="docCopyType"> + <xsd:sequence> + <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="internal" type="docInternalType" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="link" /> + </xsd:complexType> + + <xsd:complexType name="docCharType"> + <xsd:attribute name="char" type="DoxCharRange"/> + </xsd:complexType> + + <xsd:complexType name="docEmptyType"/> + <!-- Simple types --> <xsd:simpleType name="DoxBool"> @@ -350,12 +658,54 @@ </xsd:restriction> </xsd:simpleType> + <xsd:simpleType name="DoxSimpleSectKind"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="see" /> + <xsd:enumeration value="return" /> + <xsd:enumeration value="author" /> + <xsd:enumeration value="authors" /> + <xsd:enumeration value="version" /> + <xsd:enumeration value="since" /> + <xsd:enumeration value="date" /> + <xsd:enumeration value="note" /> + <xsd:enumeration value="warning" /> + <xsd:enumeration value="pre" /> + <xsd:enumeration value="post" /> + <xsd:enumeration value="invariant" /> + <xsd:enumeration value="remark" /> + <xsd:enumeration value="attention" /> + <xsd:enumeration value="par" /> + <xsd:enumeration value="rcs" /> + </xsd:restriction> + </xsd:simpleType> + <xsd:simpleType name="DoxVersionNumber"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d+\.\d+.*" /> </xsd:restriction> </xsd:simpleType> + <xsd:simpleType name="DoxImageKind"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="html" /> + <xsd:enumeration value="latex" /> + <xsd:enumeration value="rtf" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="DoxParamListKind"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="param" /> + <xsd:enumeration value="retval" /> + <xsd:enumeration value="exception" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="DoxCharRange"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="[aeiouncAEIOUNC]" /> + </xsd:restriction> + </xsd:simpleType> </xsd:schema> diff --git a/src/compound_xsd.h b/src/compound_xsd.h index f914e0e..ca866bb 100644 --- a/src/compound_xsd.h +++ b/src/compound_xsd.h @@ -120,9 +120,11 @@ " <xsd:attribute name=\"mutable\" type=\"DoxBool\" />\n" " </xsd:complexType>\n" "\n" -" <xsd:complexType name=\"descriptionType\" mixed=\"true\">\n" +" <xsd:complexType name=\"descriptionType\">\n" " <xsd:sequence>\n" -" <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect1\" type=\"docSect1Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"internal\" type=\"docInternalType\" minOccurs=\"0\" />\n" " </xsd:sequence>\n" " </xsd:complexType>\n" "\n" @@ -226,6 +228,312 @@ " <xsd:attribute name=\"bodyend\" type=\"xsd:integer\" />\n" " </xsd:complexType>\n" "\n" +" <xsd:complexType name=\"docSect1Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"title\" type=\"xsd:string\" /> \n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect2\" type=\"docSect2Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"internal\" type=\"docInternalS1Type\" minOccurs=\"0\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"id\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docSect2Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"title\" type=\"xsd:string\" /> \n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect3\" type=\"docSect3Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"internal\" type=\"docInternalS2Type\" minOccurs=\"0\" />\n" +" </xsd:sequencee\n" +" <xsd:attribute name=\"id\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docSect3Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"title\" type=\"xsd:string\" /> \n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect4\" type=\"docSect4Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"internal\" type=\"docInternalS3Type\" minOccurs=\"0\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"id\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docSect4Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"title\" type=\"xsd:string\" /> \n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"internal\" type=\"docInternalS4Type\" minOccurs=\"0\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"id\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docInternalType\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect1\" type=\"docSect1Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docInternalS1Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect2\" type=\"docSect2Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docInternalS2Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect3\" type=\"docSect3Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docInternalS3Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect3\" type=\"docSect4Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docInternalS4Type\" mixed=\"true\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +" \n" +" <xsd:group name=\"docTitleCmdGroup\">\n" +" <xsd:choice>\n" +" <xsd:element name=\"ulink\" type=\"docURLLink\" />\n" +" <xsd:element name=\"bold\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"emphasis\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"computeroutput\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"subscript\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"superscript\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"center\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"small\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"htmlonly\" type=\"xsd:string\" />\n" +" <xsd:element name=\"latexonly\" type=\"xsd:string\" />\n" +" <xsd:element name=\"anchor\" type=\"docAnchorType\" />\n" +" <xsd:element name=\"formula\" type=\"docFormulaType\" />\n" +" <xsd:element name=\"ref\" type=\"docRefTextType\" />\n" +" <xsd:element name=\"copy\" type=\"docEmptyType\" />\n" +" <xsd:element name=\"trademark\" type=\"docEmptyType\" />\n" +" <xsd:element name=\"registered\" type=\"docEmptyType\" />\n" +" <xsd:element name=\"umlaut\" type=\"docCharType\" />\n" +" <xsd:element name=\"acute\" type=\"docCharType\" />\n" +" <xsd:element name=\"grave\" type=\"docCharType\" />\n" +" <xsd:element name=\"circ\" type=\"docCharType\" />\n" +" <xsd:element name=\"tilde\" type=\"docCharType\" />\n" +" <xsd:element name=\"cedil\" type=\"docCharType\" />\n" +" <xsd:element name=\"ring\" type=\"docCharType\" />\n" +" <xsd:element name=\"szlig\" type=\"docEmptyType\" />\n" +" <xsd:element name=\"nonbreakablespace\" type=\"docEmptyType\" />\n" +" </xsd:choice>\n" +" </xsd:group>\n" +"\n" +" <xsd:complexType name=\"docTitleType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:group name=\"docCmdGroup\">\n" +" <xsd:choice>\n" +" <xsd:group ref=\"docTitleCmdGroup\"/>\n" +" <xsd:element name=\"linebreak\" type=\"docEmptyType\" />\n" +" <xsd:element name=\"hruler\" type=\"docEmptyType\" />\n" +" <xsd:element name=\"preformatted\" type=\"docMarkupType\" />\n" +" <xsd:element name=\"programlisting\" type=\"listingType\" />\n" +" <xsd:element name=\"verbatim\" type=\"xsd:string\" />\n" +" <xsd:element name=\"indexentry\" type=\"docIndexEntryType\" />\n" +" <xsd:element name=\"orderedlist\" type=\"docListType\" />\n" +" <xsd:element name=\"itemizedlist\" type=\"docListType\" />\n" +" <xsd:element name=\"simplesect\" type=\"docSimpleSectType\" />\n" +" <xsd:element name=\"title\" type=\"docTitleType\" />\n" +" <xsd:element name=\"variablelist\" type=\"docVariableListType\" />\n" +" <xsd:element name=\"table\" type=\"docTableType\" />\n" +" <xsd:element name=\"heading\" type=\"docHeadingType\" />\n" +" <xsd:element name=\"image\" type=\"docImageType\" />\n" +" <xsd:element name=\"dotfile\" type=\"docDotFileType\" />\n" +" <xsd:element name=\"toclist\" type=\"docTocListType\" />\n" +" <xsd:element name=\"language\" type=\"docLanguageType\" />\n" +" <xsd:element name=\"parameterlist\" type=\"docParamListType\" />\n" +" <xsd:element name=\"xrefsect\" type=\"docXRefSectType\" />\n" +" <xsd:element name=\"copydoc\" type=\"docCopyType\" />\n" +" </xsd:choice>\n" +" </xsd:group>\n" +"\n" +" <xsd:complexType name=\"docParaType\" mixed=\"true\">\n" +" <xsd:group ref=\"docCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docMarkupType\" mixed=\"true\">\n" +" <xsd:group ref=\"docCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docURLLink\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:attribute name=\"url\" type=\"xsd:string\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docAnchorType\" mixed=\"true\">\n" +" <xsd:attribute name=\"id\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docFormulaType\" mixed=\"true\">\n" +" <xsd:attribute name=\"id\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docIndexEntryType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"primaryie\" type=\"xsd:string\" />\n" +" <xsd:element name=\"secondaryie\" type=\"xsd:string\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docListType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"listitem\" type=\"docListItemType\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docListItemType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docSimpleSectType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"title\" type=\"docTitleType\" minOccurs=\"0\" />\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"kind\" type=\"DoxSimpleSectKind\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docVarListEntryType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"term\" type=\"docTitleType\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:group name=\"docVariableListGroup\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"varlistentry\" type=\"docVarListEntryType\" />\n" +" <xsd:element name=\"listitem\" type=\"docListItemType\" />\n" +" </xsd:sequence>\n" +" </xsd:group>\n" +"\n" +" <xsd:complexType name=\"docVariableListType\">\n" +" <xsd:sequence>\n" +" <xsd:group ref=\"docVariableListGroup\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docRefTextType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:attribute name=\"refid\" />\n" +" <xsd:attribute name=\"kindref\" />\n" +" <xsd:attribute name=\"external\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docTableType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"row\" type=\"docRowType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"caption\" type=\"docCaptionType\" minOccurs=\"0\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"rows\" type=\"xsd:integer\" />\n" +" <xsd:attribute name=\"cols\" type=\"xsd:integer\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docRowType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"entry\" type=\"docEntryType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docEntryType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"thead\" type=\"DoxBool\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docCaptionType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docHeadingType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:attribute name=\"level\" type=\"xsd:integer\" /> <!-- todo: range 1-6 -->\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docImageType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:attribute name=\"type\" type=\"DoxImageKind\" /> \n" +" <xsd:attribute name=\"name\" type=\"xsd:string\" /> \n" +" <xsd:attribute name=\"width\" type=\"xsd:string\" /> \n" +" <xsd:attribute name=\"height\" type=\"xsd:string\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docDotFileType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:attribute name=\"name\" type=\"xsd:string\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docTocItemType\" mixed=\"true\">\n" +" <xsd:group ref=\"docTitleCmdGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:attribute name=\"id\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docTocListType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"tocitem\" type=\"docTocItemType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docLanguageType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"langid\" type=\"xsd:string\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:group name=\"docParamListGroup\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"parametername\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"parameterdescription\" type=\"descriptionType\" />\n" +" </xsd:sequence>\n" +" </xsd:group>\n" +"\n" +" <xsd:complexType name=\"docParamListType\">\n" +" <xsd:sequence>\n" +" <xsd:group ref=\"docParamListGroup\" maxOccurs=\"unbounded\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"kind\" type=\"DoxParamListKind\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docXRefSectType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"xreftitle\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"xrefdescription\" type=\"descriptionType\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"id\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docCopyType\">\n" +" <xsd:sequence>\n" +" <xsd:element name=\"para\" type=\"docParaType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"sect1\" type=\"docSect1Type\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n" +" <xsd:element name=\"internal\" type=\"docInternalType\" minOccurs=\"0\" />\n" +" </xsd:sequence>\n" +" <xsd:attribute name=\"link\" /> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docCharType\">\n" +" <xsd:attribute name=\"char\" type=\"DoxCharRange\"/> \n" +" </xsd:complexType>\n" +"\n" +" <xsd:complexType name=\"docEmptyType\"/>\n" +"\n" " <!-- Simple types -->\n" "\n" " <xsd:simpleType name=\"DoxBool\">\n" @@ -350,12 +658,54 @@ " </xsd:restriction>\n" " </xsd:simpleType>\n" "\n" +" <xsd:simpleType name=\"DoxSimpleSectKind\">\n" +" <xsd:restriction base=\"xsd:string\">\n" +" <xsd:enumeration value=\"see\" />\n" +" <xsd:enumeration value=\"return\" />\n" +" <xsd:enumeration value=\"author\" />\n" +" <xsd:enumeration value=\"authors\" />\n" +" <xsd:enumeration value=\"version\" />\n" +" <xsd:enumeration value=\"since\" />\n" +" <xsd:enumeration value=\"date\" />\n" +" <xsd:enumeration value=\"note\" />\n" +" <xsd:enumeration value=\"warning\" />\n" +" <xsd:enumeration value=\"pre\" />\n" +" <xsd:enumeration value=\"post\" />\n" +" <xsd:enumeration value=\"invariant\" />\n" +" <xsd:enumeration value=\"remark\" />\n" +" <xsd:enumeration value=\"attention\" />\n" +" <xsd:enumeration value=\"par\" />\n" +" <xsd:enumeration value=\"rcs\" />\n" +" </xsd:restriction>\n" +" </xsd:simpleType>\n" +"\n" " <xsd:simpleType name=\"DoxVersionNumber\">\n" " <xsd:restriction base=\"xsd:string\">\n" " <xsd:pattern value=\"\\d+\\.\\d+.*\" />\n" " </xsd:restriction>\n" " </xsd:simpleType>\n" "\n" +" <xsd:simpleType name=\"DoxImageKind\">\n" +" <xsd:restriction base=\"xsd:string\">\n" +" <xsd:enumeration value=\"html\" />\n" +" <xsd:enumeration value=\"latex\" />\n" +" <xsd:enumeration value=\"rtf\" />\n" +" </xsd:restriction>\n" +" </xsd:simpleType>\n" +"\n" +" <xsd:simpleType name=\"DoxParamListKind\">\n" +" <xsd:restriction base=\"xsd:string\">\n" +" <xsd:enumeration value=\"param\" />\n" +" <xsd:enumeration value=\"retval\" />\n" +" <xsd:enumeration value=\"exception\" />\n" +" </xsd:restriction>\n" +" </xsd:simpleType>\n" +"\n" +" <xsd:simpleType name=\"DoxCharRange\">\n" +" <xsd:restriction base=\"xsd:string\">\n" +" <xsd:pattern value=\"[aeiouncAEIOUNC]\" />\n" +" </xsd:restriction>\n" +" </xsd:simpleType>\n" "\n" "</xsd:schema>\n" "\n" diff --git a/src/definition.cpp b/src/definition.cpp index 1482ab7..75c2931 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -126,6 +126,7 @@ void Definition::setDocumentation(const char *d,const char *docFile,int docLine, { if (d==0) return; //printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace); + QCString doc; if (stripWhiteSpace) { // strip leading empty lines in front of the text, but not the @@ -141,20 +142,21 @@ void Definition::setDocumentation(const char *d,const char *docFile,int docLine, s++; } if (c=='\0') return; - m_doc=d+so; + doc=d+so; // zero any trailing whitespace - int e=m_doc.length()-1; - while (e>=0 && (c=m_doc.at(e)) && (c==' ' || c=='\r' || c=='\n')) + int e=doc.length()-1; + while (e>=0 && (c=doc.at(e)) && (c==' ' || c=='\r' || c=='\n')) { - m_doc.at(e)='\0'; + doc.at(e)='\0'; e--; } } else // don't strip whitespace { - m_doc=d; + doc=d; } //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data()); + m_doc=doc; m_docFile = docFile; m_docLine = docLine; } @@ -163,7 +165,7 @@ void Definition::setBriefDescription(const char *b,const char *briefFile,int bri { if (b==0) return; //printf("Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); - m_brief=QCString(b).stripWhiteSpace(); + m_brief=QCString(b).stripWhiteSpace(); int bl=m_brief.length(); if (bl>0) // add puntuation if needed { diff --git a/src/docparser.cpp b/src/docparser.cpp index 56f1f55..1b584b3 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -2143,7 +2143,7 @@ endhref: //--------------------------------------------------------------------------- -int DocInternal::parse() +int DocInternal::parse(int level) { int retval=RetVal_OK; g_nodeStack.push(this); @@ -2170,25 +2170,24 @@ int DocInternal::parse() { warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: Invalid list item found",doctokenizerYYlineno); } - } while (retval!=0 && retval!=RetVal_Section); + } while (retval!=0 && + retval!=RetVal_Section && + retval!=RetVal_Subsection && + retval!=RetVal_Subsubsection && + retval!=RetVal_Paragraph + ); if (lastPar) lastPar->markLast(); - // then parse any number of level1 sections - while (retval==RetVal_Section) + // then parse any number of level-n sections + while ((level==1 && retval==RetVal_Section) || + (level==2 && retval==RetVal_Subsection) || + (level==3 && retval==RetVal_Subsubsection) || + (level==4 && retval==RetVal_Paragraph) + ) { - //SectionInfo *sec=Doxygen::sectionDict[g_token->sectionId]; - //int secLev = sec->type==SectionInfo::Subsection ? 2 : 1; - //if (secLev!=1) // wrong level - //{ - // warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: Expected level 1 section, found a section with level %d.",secLev); - // break; - //} - //else - //{ - DocSection *s=new DocSection(this,1,g_token->sectionId); - m_children.append(s); - retval = s->parse(); - //} + DocSection *s=new DocSection(this,level,g_token->sectionId); + m_children.append(s); + retval = s->parse(); } if (retval==RetVal_Internal) @@ -2503,6 +2502,32 @@ getrow: return retval==RetVal_EndTable ? RetVal_OK : retval; } +uint DocHtmlTable::numCols() const +{ + uint cols=0; + QListIterator<DocNode> cli(m_children); + DocNode *n; + for (cli.toFirst();(n=cli.current());++cli) + { + ASSERT(n->kind()==DocNode::Kind_HtmlRow); + cols=QMAX(cols,((DocHtmlRow *)n)->numCells()); + } + return cols; +} + +void DocHtmlTable::accept(DocVisitor *v) +{ + v->visitPre(this); + // for HTML output we put the caption first + if (m_caption && v->id()==DocVisitor_Html) m_caption->accept(v); + QListIterator<DocNode> cli(m_children); + DocNode *n; + for (cli.toFirst();(n=cli.current());++cli) n->accept(v); + // for other output formats we put the caption last + if (m_caption && v->id()!=DocVisitor_Html) m_caption->accept(v); + v->visitPost(this); +} + //--------------------------------------------------------------------------- int DocHtmlDescTitle::parse() @@ -4496,6 +4521,12 @@ int DocSection::parse() retval=0; // stop parsing } + else if (retval==RetVal_Internal) + { + DocInternal *in = new DocInternal(this); + m_children.append(in); + retval = in->parse(m_level+1); + } else { } @@ -4659,7 +4690,7 @@ void DocRoot::parse() { DocInternal *in = new DocInternal(this); m_children.append(in); - retval = in->parse(); + retval = in->parse(1); } diff --git a/src/docparser.h b/src/docparser.h index 383f23c..1554037 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -821,7 +821,7 @@ class DocInternal : public CompAccept<DocInternal>, public DocNode { public: DocInternal(DocNode *parent) : m_parent(parent) {} - int parse(); + int parse(int); Kind kind() const { return Kind_Internal; } DocNode *parent() const { return m_parent; } void accept(DocVisitor *v) { CompAccept<DocInternal>::accept(this,v); } @@ -1103,6 +1103,7 @@ class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode private: DocNode * m_parent; HtmlAttribList m_attribs; + bool m_atTop; }; /*! @brief Node representing a HTML table row */ @@ -1137,27 +1138,8 @@ class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode bool hasCaption() { return m_caption!=0; } const HtmlAttribList &attribs() const { return m_attribs; } int parse(); - uint numCols() const - { - uint cols=0; - QListIterator<DocNode> cli(m_children); - DocNode *n; - for (cli.toFirst();(n=cli.current());++cli) - { - ASSERT(n->kind()==DocNode::Kind_HtmlRow); - cols=QMAX(cols,((DocHtmlRow *)n)->numCells()); - } - return cols; - } - void accept(DocVisitor *v) - { - v->visitPre(this); - QListIterator<DocNode> cli(m_children); - DocNode *n; - for (cli.toFirst();(n=cli.current());++cli) n->accept(v); - if (m_caption) m_caption->accept(v); - v->visitPost(this); - } + uint numCols() const; + void accept(DocVisitor *v); private: DocNode * m_parent; diff --git a/src/docvisitor.h b/src/docvisitor.h index 949781e..3815cbb 100644 --- a/src/docvisitor.h +++ b/src/docvisitor.h @@ -19,6 +19,14 @@ #ifndef _DOCVISITOR_H #define _DOCVISITOR_H +// ids +const int DocVisitor_Html = 0; +const int DocVisitor_Latex = 1; +const int DocVisitor_XML = 2; +const int DocVisitor_RTF = 3; +const int DocVisitor_Man = 4; +const int DocVisitor_Other = 5; + // forward declarations class DocWord; class DocWhiteSpace; @@ -38,7 +46,6 @@ class DocVerbatim; class DocXRefItem; class DocHtmlList; class DocHtmlListItem; -//class DocHtmlPre; class DocHtmlDescList; class DocHtmlDescTitle; class DocHtmlDescData; @@ -74,8 +81,12 @@ class DocText; */ class DocVisitor { + int m_id; public: + DocVisitor(int id) : m_id(id) {} virtual ~DocVisitor() {} + int id() const { return m_id; } + /*! @name Visitor functions for leaf nodes * @{ */ @@ -120,8 +131,6 @@ class DocVisitor virtual void visitPost(DocHtmlListItem *) = 0; virtual void visitPre(DocHtmlListItem *) = 0; virtual void visitPost(DocHtmlList *) = 0; - //virtual void visitPre(DocHtmlPre *) = 0; - //virtual void visitPost(DocHtmlPre *) = 0; virtual void visitPre(DocHtmlDescList *) = 0; virtual void visitPost(DocHtmlDescList *) = 0; virtual void visitPre(DocHtmlDescTitle *) = 0; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index c4c88a3..addf597 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -840,6 +840,34 @@ static void buildClassDocList(Entry *root) } } +Definition *buildScopeFromQualifiedName(const QCString name,int level) +{ + int i=0; + int p=0,l; + Definition *prevScope=Doxygen::globalScope; + QCString fullScope; + while (i<level) + { + int idx=getScopeFragment(name,p,&l); + QCString nsName = name.mid(idx,l); + if (!fullScope.isEmpty()) fullScope+="::"; + fullScope+=nsName; + //printf("adding dummy namespace %s to %s\n",nsName.data(),prevScope->name().data()); + // introduce bogus namespace + NamespaceDef *nd=new NamespaceDef( + "<generated>",1,fullScope); + + // add namespace to the list + Doxygen::namespaceSDict.inSort(fullScope,nd); + prevScope->addInnerCompound(nd); + nd->setOuterScope(prevScope); + p=idx+l+2; + prevScope=nd; + i++; + } + return prevScope; +} + static void resolveClassNestingRelations() { ClassSDict::Iterator cli(Doxygen::classSDict); @@ -986,13 +1014,11 @@ static void buildNamespaceList(Entry *root) //printf("adding namespace %s to context %s\n",nd->name().data(),d?d->name().data():"none"); if (d==0) { + Definition *d = buildScopeFromQualifiedName(fullName,fullName.contains("::")); + d->addInnerCompound(nd); + nd->setOuterScope(d); // TODO: Due to the order in which the tag file is written // a nested class can be found before its parent! - // - //warn(root->fileName,root->startLine, - // "Warning: Internal inconsistency: scope for namespace %s not " - // "found!\n",fullName.data() - // ); } else { @@ -2226,8 +2252,8 @@ static void buildFunctionList(Entry *root) ); // otherwise, allow a duplicate global member with the same argument list - //printf("combining function with prototype found=%d `%s'<->`%s'!\n", - // found,fd->absFilePath().data(),root->fileName.data()); + //printf("combining function with prototype found=%d in namespace %s\n", + // found,nsName.data()); // merge argument lists //mergeArguments(root->argList,md->argumentList()); @@ -2266,10 +2292,19 @@ static void buildFunctionList(Entry *root) md->setArgumentList(argList); } } + else if (!md->documentation().isEmpty() && !root->doc.isEmpty()) + { + warn(root->docFile,root->docLine,"Warning: ignoring the detailed description found here, since another one was found at line %d of file %s!",md->docLine(),md->docFile().data()); + } + if (md->briefDescription().isEmpty() && !root->brief.isEmpty()) { md->setBriefDescription(root->brief,root->briefFile,root->briefLine); } + else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty()) + { + warn(root->briefFile,root->briefLine,"Warning: ignoring the brief description found here, since another one was found at line %d of file %s!",md->briefLine(),md->briefFile().data()); + } md->addSectionsToDefinition(root->anchors); @@ -2279,10 +2314,17 @@ static void buildFunctionList(Entry *root) if (md->getGroupDef()==0 && root->groups->first()) { // if we do addMemberToGroups here an undocumented declaration may prevent - // the documented implementation below from being added + // the documented implementation below it from being added //addMemberToGroups(root,md); GroupDef *gd=Doxygen::groupSDict[root->groups->first()->groupname.data()]; - md->setGroupDef(gd, root->groups->first()->pri, root->fileName, root->startLine, !root->doc.isEmpty()); + if (gd) + { + bool success = gd->insertMember(md); + if (success) + { + md->setGroupDef(gd, root->groups->first()->pri, root->fileName, root->startLine, !root->doc.isEmpty()); + } + } } else if (md->getGroupDef()!=0 && root->groups->count()==0) { @@ -8198,7 +8240,7 @@ void generateOutput() cleanUpDoxygen(); if (Debug::isFlagSet(Debug::Time)) { - printf("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n", + msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n", ((double)Doxygen::runningTime.elapsed())/1000.0, Doxygen::sysElapsedTime ); diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 4fb2be5..8d75de9 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -43,7 +43,7 @@ static QString htmlAttribsToString(const HtmlAttribList &attribs) //------------------------------------------------------------------------- HtmlDocVisitor::HtmlDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) - : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) + : DocVisitor(DocVisitor_Html), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) { } diff --git a/src/index.cpp b/src/index.cpp index c76b5d6..c4d463a 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1485,6 +1485,15 @@ void writeAlphabeticalClassList(OutputList &ol) //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName(); //QCString cname=cd->className(); extractNamespaceName(cd->name(),cname,namesp); + QCString nsDispName; + if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) + { + nsDispName=substitute(namesp,"::","."); + } + else + { + nsDispName=namesp.copy(); + } ol.writeObjectLink(cd->getReference(), cd->getOutputFileBase(),0,cname); @@ -1495,11 +1504,11 @@ void writeAlphabeticalClassList(OutputList &ol) if (nd && nd->isLinkable()) { ol.writeObjectLink(nd->getReference(), - nd->getOutputFileBase(),0,namesp); + nd->getOutputFileBase(),0,nsDispName); } else { - ol.docify(namesp); + ol.docify(nsDispName); } ol.docify(")"); } diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 8b80907..bc20db5 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -80,7 +80,7 @@ QString LatexDocVisitor::escapeMakeIndexChars(const char *s) LatexDocVisitor::LatexDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) - : m_t(t), m_ci(ci), m_insidePre(FALSE), m_insideItem(FALSE), m_hide(FALSE) + : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE), m_insideItem(FALSE), m_hide(FALSE) { } @@ -99,7 +99,7 @@ void LatexDocVisitor::visit(DocLinkedWord *w) if (m_hide) return; startLink(w->ref(),w->file(),w->anchor()); filter(w->word()); - endLink(); + endLink(w->ref(),w->file(),w->anchor()); } void LatexDocVisitor::visit(DocWhiteSpace *w) @@ -797,10 +797,10 @@ void LatexDocVisitor::visitPre(DocLink *lnk) startLink(lnk->ref(),lnk->file(),lnk->anchor()); } -void LatexDocVisitor::visitPost(DocLink *) +void LatexDocVisitor::visitPost(DocLink *lnk) { if (m_hide) return; - endLink(); + endLink(lnk->ref(),lnk->file(),lnk->anchor()); } void LatexDocVisitor::visitPre(DocRef *ref) @@ -810,10 +810,10 @@ void LatexDocVisitor::visitPre(DocRef *ref) if (!ref->hasLinkText()) filter(ref->targetTitle()); } -void LatexDocVisitor::visitPost(DocRef *) +void LatexDocVisitor::visitPost(DocRef *ref) { if (m_hide) return; - endLink(); + endLink(ref->ref(),ref->file(),ref->anchor()); } void LatexDocVisitor::visitPre(DocSecRefItem *) @@ -942,10 +942,10 @@ void LatexDocVisitor::visitPre(DocInternalRef *ref) startLink(0,ref->file(),ref->anchor()); } -void LatexDocVisitor::visitPost(DocInternalRef *) +void LatexDocVisitor::visitPost(DocInternalRef *ref) { if (m_hide) return; - endLink(); + endLink(0,ref->file(),ref->anchor()); } void LatexDocVisitor::visitPre(DocCopy *) @@ -986,9 +986,16 @@ void LatexDocVisitor::startLink(const QString &ref,const QString &file,const QSt } } -void LatexDocVisitor::endLink() +void LatexDocVisitor::endLink(const QString &ref,const QString &file,const QString &anchor) { m_t << "}"; + if (ref.isEmpty() && !Config_getBool("PDF_HYPERLINKS")) + { + m_t << "{\\rm (" << theTranslator->trPageAbbreviation(); + m_t << "\\,\\pageref{" << file; + if (!anchor.isEmpty()) m_t << "_" << anchor; + m_t << "})}"; + } } void LatexDocVisitor::pushEnabled() diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h index f0a8204..0b168d5 100644 --- a/src/latexdocvisitor.h +++ b/src/latexdocvisitor.h @@ -135,7 +135,8 @@ class LatexDocVisitor : public DocVisitor void filter(const char *str); void startLink(const QString &ref,const QString &file, const QString &anchor); - void endLink(); + void endLink(const QString &ref,const QString &file, + const QString &anchor); QString escapeMakeIndexChars(const char *s); void pushEnabled(); diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index 3353182..2908460 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -27,7 +27,7 @@ #include "message.h" ManDocVisitor::ManDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) - : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(TRUE), + : DocVisitor(DocVisitor_Man), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_firstCol(TRUE), m_indent(0) { } diff --git a/src/memberdef.cpp b/src/memberdef.cpp index c9b36c8..dfa8d07 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -84,6 +84,7 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd, if (defArgList==0) return; // member has no function like argument list if (!md->isDefine()) ol.docify(" "); + //printf("writeDefArgList(%d)\n",defArgList->count()); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.endMemberDocName(); diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp index 8f38d2d..2574f6b 100644 --- a/src/perlmodgen.cpp +++ b/src/perlmodgen.cpp @@ -413,7 +413,7 @@ private: }; PerlModDocVisitor::PerlModDocVisitor(PerlModOutput &output) - : m_output(output), m_textmode(false) + : DocVisitor(DocVisitor_Other), m_output(output), m_textmode(false) { m_output.openList("doc"); } diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index b06e0a6..1241659 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -25,7 +25,8 @@ class PrintDocVisitor : public DocVisitor { public: - PrintDocVisitor() : m_indent(0), m_needsEnter(FALSE), m_insidePre(FALSE) {} + PrintDocVisitor() : DocVisitor(DocVisitor_Other), m_indent(0), + m_needsEnter(FALSE), m_insidePre(FALSE) {} //-------------------------------------- diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index ac1febb..2221d2d 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -28,7 +28,7 @@ #include "message.h" RTFDocVisitor::RTFDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) - : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_indentLevel(1) + : DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), m_indentLevel(1) { } diff --git a/src/scanner.l b/src/scanner.l index 8b47179..9d9d7e3 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -157,6 +157,7 @@ static QCString xrefItemKey; static QCString xrefItemTitle; static QCString xrefListTitle; +static QCString g_skipBlockName; //----------------------------------------------------------------------------- @@ -2809,6 +2810,10 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] lastCContext = YY_START; BEGIN(SkipCxxComment); } +<SkipInits>\" { + lastStringContext=YY_START; + BEGIN( SkipString ); + } <SkipInits>; { warn(yyFileName,yyLineNr, "Warning: Found ';' while parsing initializer list! " @@ -3855,31 +3860,37 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] <Doc,PageDoc,ClassDoc>{CMD}"verbatim"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->doc+="\\verbatim"; + g_skipBlockName="verbatim"; BEGIN(SkipVerbatim); } <JavaDoc>{CMD}"verbatim"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->brief+="\\verbatim"; + g_skipBlockName="verbatim"; BEGIN(SkipVerbatim); } <Doc,PageDoc,ClassDoc>{CMD}"latexonly"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->doc+="\\latexonly"; + g_skipBlockName="latexonly"; BEGIN(SkipVerbatim); } <JavaDoc>{CMD}"latexonly"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->brief+="\\latexonly"; + g_skipBlockName="latexonly"; BEGIN(SkipVerbatim); } <Doc,PageDoc,ClassDoc>{CMD}"htmlonly"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->doc+="\\htmlonly"; + g_skipBlockName="htmlonly"; BEGIN(SkipVerbatim); } <JavaDoc>{CMD}"htmlonly"/[^a-z_A-Z0-9] { lastVerbState=YY_START; current->brief+="\\htmlonly"; + g_skipBlockName="htmlonly"; BEGIN(SkipVerbatim); } <Doc,PageDoc,ClassDoc>{CMD}"addindex"{B}+[^\n]+ { @@ -3946,7 +3957,13 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] <SkipVerbatim>. { current->doc+=*yytext; } -<SkipCode>{CMD}"endcode" { +<SkipVerbatim><<EOF>> { + warn(yyFileName,yyLineNr, + "Warning: reached end of file while inside a @%s block; check for missing @end%s!",g_skipBlockName.data(),g_skipBlockName.data() + ); + yyterminate(); + } +<SkipCode>{CMD}"endcode"/[^a-z_A-Z0-9] { *pSkipDoc+="\\endcode"; BEGIN(lastCodeState); } @@ -3975,6 +3992,12 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] <SkipCode>. { *pSkipDoc+=*yytext; } +<SkipCode><<EOF>> { + warn(yyFileName,yyLineNr, + "Warning: reached end of file while inside a @code block; check for missing @endcode!" + ); + yyterminate(); + } <AnchorLabel>{LABELID} { SectionInfo *si = new SectionInfo(yyFileName,yytext,0,SectionInfo::Anchor); Doxygen::sectionDict.insert(yytext,si); @@ -4494,6 +4517,9 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] current->name = current->name.stripWhiteSpace(); newDocState(); } +<DefLineDoc,LineDoc,AfterDocLine>{SECTIONCMD} { + warn(yyFileName,yyLineNr,"Command %s not allowed in single-line C++ comment! Ignoring.",yytext); + } <Doc>[a-z_A-Z0-9]+ { current->doc += yytext; } <Doc,PageDoc,AfterDoc,LineDoc,ClassDoc>("\\\\"|"@@") { current->doc += yytext; } <Doc>. { current->doc += *yytext; } diff --git a/src/translator_br.h b/src/translator_br.h index a9066d7..2f433b3 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -16,6 +16,8 @@ * Version: 1.3 (2003/05/01) * * History: + * 1.3.2: + * - Updated to Doxygen 1.3.2 * 1.3: * - Updated to Doxygen 1.3.x. * 1.2.19: @@ -27,7 +29,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian: public TranslatorAdapter_1_3_1 +class TranslatorBrazilian: public Translator { public: @@ -1460,5 +1462,22 @@ class TranslatorBrazilian: public TranslatorAdapter_1_3_1 return "Atributos Estáticos do Pacote"; } +////////////////////////////////////////////////////////////////////////// +// new since 1.3.1 +////////////////////////////////////////////////////////////////////////// + + /*! Used in the quick index of a class/file/namespace member list page + * to link to the unfiltered list of all members. + */ + virtual QCString trAll() + { + return "Todos"; + } + /*! Put in front of the call graph for a function. */ + virtual QCString trCallGraph() + { + return "Este é o grafo de chamadas para esta função:"; + } + }; #endif diff --git a/src/translator_pt.h b/src/translator_pt.h index 7444a10..2bc323e 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -40,7 +40,7 @@ #ifndef TRANSLATOR_PT_H #define TRANSLATOR_PT_H -class TranslatorPortuguese : public TranslatorAdapter_1_3_1 +class TranslatorPortuguese : public Translator { public: diff --git a/src/translator_sr.h b/src/translator_sr.h index 532d54e..8fe5973 100644 --- a/src/translator_sr.h +++ b/src/translator_sr.h @@ -20,7 +20,7 @@ // translation by Dejan D. M. Milosavljevic <dmilos@email.com>;<dmilosx@ptt.yu> -class TranslatorSerbian : public TranslatorAdapter_1_3_1 +class TranslatorSerbian : public Translator { private: QCString decode(const QCString& sInput) diff --git a/src/translator_tw.h b/src/translator_tw.h index a22c39e..bccfece 100644 --- a/src/translator_tw.h +++ b/src/translator_tw.h @@ -41,7 +41,7 @@ // Translator class (by the local maintainer) when the localized // translator is made up-to-date again. -class TranslatorChinesetraditional : public TranslatorAdapter_1_2_16 +class TranslatorChinesetraditional : public Translator { public: diff --git a/src/util.cpp b/src/util.cpp index 9509c0a..832ff5f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -641,12 +641,49 @@ ClassDef *getResolvedClass( } else // not a typedef { - //printf(" not a typedef value\n"); + //printf(" %s is not a typedef value in scope %s\n",name.data(),scope?scope->name().data():"<global>"); if (pIsTypeDef) *pIsTypeDef=FALSE; if (scope!=Doxygen::globalScope) + { cd = Doxygen::classSDict.find(scope->name()+"::"+name); + } else + { cd = Doxygen::classSDict.find(name); + } + if (cd==0) + { + if (scope->definitionType()==Definition::TypeNamespace) + { + NamespaceDef *nscope = (NamespaceDef*)scope; + ClassList *cl = nscope->getUsedClasses(); + if (cl) // see if the class was imported via a using statement + { + ClassListIterator cli(*cl); + ClassDef *ucd; + for (cli.toFirst();(ucd=cli.current());++cli) + { + //printf("comparing %s<->%s\n",ucd->name().data(),name.data()); + if (rightScopeMatch(ucd->name(),name)) + { + cd=ucd; + break; + } + } + } + NamespaceList *nl = nscope->getUsedNamespaces(); + if (nl) // check used namespaces for the class + { + NamespaceListIterator nli(*nl); + NamespaceDef *und; + for (nli.toFirst();(und=nli.current());++nli) + { + cd = getResolvedClass(und,name,pIsTypeDef,pTemplSpec); + if (cd) break; + } + } + } + } if (cd) goto found; } @@ -831,7 +868,7 @@ void linkifyText(const TextGeneratorIntf &out,Definition *scope,const char * /*n //int scopeOffset=scopeName.length(); do // for each scope (starting with full scope and going to empty scope) { - //printf("Searching in %s...\n",curScope?curScope->name().data():"<global>"); + //printf("Searching %s in %s...\n",word.data(),curScope?curScope->name().data():"<global>"); QCString fullName = word; QCString prefix; replaceNamespaceAliases(fullName,fullName.length()); @@ -2749,7 +2786,7 @@ bool generateLink(OutputDocInterface &od,const char *clName, //PageDef *pageDef=0; QCString anchor,linkText=linkToText(lt); //printf("generateLink linkText=%s\n",linkText.data()); - if (resolveLink(clName,lr,inSeeBlock,&compound,/*&pageInfo,*/anchor)) + if (resolveLink(clName,lr,inSeeBlock,&compound,anchor)) { //if (pageInfo) // link to page //{ diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 4320d17..51dac52 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -28,7 +28,7 @@ #include "util.h" XmlDocVisitor::XmlDocVisitor(QTextStream &t,BaseCodeDocInterface &ci) - : m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) + : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) { } @@ -424,13 +424,15 @@ void XmlDocVisitor::visitPost(DocSimpleListItem *) void XmlDocVisitor::visitPre(DocSection *s) { if (m_hide) return; - m_t << "<sect" << s->level()+1 << " id=\"" << s->id() << "\">"; + m_t << "<sect" << s->level() << " id=\"" << s->id() << "\">" << endl; + m_t << "<title>"; filter(s->title()); - m_t << "</sect" << s->level()+1 << ">\n"; + m_t << "</title>" << endl; } -void XmlDocVisitor::visitPost(DocSection *) +void XmlDocVisitor::visitPost(DocSection *s) { + m_t << "</sect" << s->level() << ">\n"; } void XmlDocVisitor::visitPre(DocHtmlList *s) @@ -575,13 +577,13 @@ void XmlDocVisitor::visitPost(DocHRef *) void XmlDocVisitor::visitPre(DocHtmlHeader *header) { if (m_hide) return; - m_t << "<heading" << header->level() << ">"; + m_t << "<heading level=\"" << header->level() << "\">"; } -void XmlDocVisitor::visitPost(DocHtmlHeader *header) +void XmlDocVisitor::visitPost(DocHtmlHeader *) { if (m_hide) return; - m_t << "</heading" << header->level() << ">\n"; + m_t << "</heading>\n"; } void XmlDocVisitor::visitPre(DocImage *img) @@ -689,7 +691,7 @@ void XmlDocVisitor::visitPost(DocSecRefList *) void XmlDocVisitor::visitPre(DocLanguage *l) { if (m_hide) return; - m_t << "<language id=\"" << l->id() << "\">"; + m_t << "<language langid=\"" << l->id() << "\">"; } void XmlDocVisitor::visitPost(DocLanguage *) |