--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/Doxygen/src/memberlist.cpp Thu Jan 21 17:29:01 2010 +0000
@@ -0,0 +1,624 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2008 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qregexp.h>
+
+#include "memberlist.h"
+#include "classdef.h"
+#include "message.h"
+#include "util.h"
+#include "language.h"
+#include "doxygen.h"
+#include "outputlist.h"
+#include "groupdef.h"
+#include "marshal.h"
+#include "vhdldocgen.h"
+
+MemberList::MemberList()
+{
+}
+
+MemberList::MemberList(ListType lt) : m_listType(lt)
+{
+ memberGroupList=0;
+ m_numDecMembers=-1; // special value indicating that value needs to be computed
+ m_numDocMembers=-1; // special value indicating that value needs to be computed
+ m_inGroup=FALSE;
+ m_inFile=FALSE;
+}
+
+MemberList::~MemberList()
+{
+ delete memberGroupList;
+}
+
+int MemberList::compareItems(GCI item1, GCI item2)
+{
+ static bool sortConstructorsFirst = Config_getBool("SORT_MEMBERS_CTORS_1ST");
+ MemberDef *c1=(MemberDef *)item1;
+ MemberDef *c2=(MemberDef *)item2;
+ if (sortConstructorsFirst) {
+ int ord1 = c1->isConstructor() ? 2 : (c1->isDestructor() ? 1 : 0);
+ int ord2 = c2->isConstructor() ? 2 : (c2->isDestructor() ? 1 : 0);
+ if (ord1 > ord2)
+ return -1;
+ else if (ord2 > ord1)
+ return 1;
+ }
+ return stricmp(c1->name(),c2->name());
+}
+
+/*! Count the number of members in this list that are visible in
+ * the declaration part of a compound's documentation page.
+ */
+void MemberList::countDecMembers(bool countEnumValues)
+{
+ if (m_numDecMembers!=-1) return;
+
+ //printf("----- countDecMembers count=%d ----\n",count());
+ m_varCnt=m_funcCnt=m_enumCnt=m_enumValCnt=0;
+ m_typeCnt=m_protoCnt=m_defCnt=m_friendCnt=0;
+ m_numDecMembers=0;
+ QListIterator<MemberDef> mli(*this);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ //printf("MemberList::countDecMembers(md=%s,%d)\n",md->name().data(),md->isBriefSectionVisible());
+ if (md->isBriefSectionVisible())
+ {
+ switch(md->memberType())
+ {
+ case MemberDef::Variable: // fall through
+ case MemberDef::Event: // fall through
+ case MemberDef::Property: m_varCnt++,m_numDecMembers++;
+ break;
+ case MemberDef::Function: // fall through
+ case MemberDef::Signal: // fall through
+ case MemberDef::DCOP: // fall through
+ case MemberDef::Slot: if (!md->isRelated() || md->getClassDef())
+ m_funcCnt++,m_numDecMembers++;
+ break;
+ case MemberDef::Enumeration: m_enumCnt++,m_numDecMembers++; break;
+ case MemberDef::EnumValue: if (countEnumValues)
+ m_enumValCnt++,m_numDecMembers++;
+ break;
+ case MemberDef::Typedef: m_typeCnt++,m_numDecMembers++; break;
+ //case MemberDef::Prototype: m_protoCnt++,m_numDecMembers++; break;
+ case MemberDef::Define: if (Config_getBool("EXTRACT_ALL") ||
+ md->argsString() ||
+ !md->initializer().isEmpty() ||
+ md->hasDocumentation()
+ ) m_defCnt++,m_numDecMembers++;
+ break;
+ case MemberDef::Friend: m_friendCnt++,m_numDecMembers++;
+ break;
+ default:
+ err("Error: Unknown member type found for member `%s'\n!",md->name().data());
+ }
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->countDecMembers();
+ m_varCnt+=mg->varCount();
+ m_funcCnt+=mg->funcCount();
+ m_enumCnt+=mg->enumCount();
+ m_enumValCnt+=mg->enumValueCount();
+ m_typeCnt+=mg->typedefCount();
+ m_protoCnt+=mg->protoCount();
+ m_defCnt+=mg->defineCount();
+ m_friendCnt+=mg->friendCount();
+ m_numDecMembers+=mg->numDecMembers();
+ }
+ }
+ //printf("----- end countDecMembers ----\n");
+
+ //printf("MemberList::countDecMembers()=%d\n",m_numDecMembers);
+}
+
+void MemberList::countDocMembers(bool countEnumValues)
+{
+ if (m_numDocMembers!=-1) return; // used cached value
+ m_numDocMembers=0;
+ QListIterator<MemberDef> mli(*this);
+ MemberDef *md;
+ for (mli.toFirst();(md=mli.current());++mli)
+ {
+ if (md->isDetailedSectionVisible(m_inGroup,m_inFile))
+ {
+ // do not count enum values, since they do not produce entries of their own
+ if (countEnumValues || md->memberType()!=MemberDef::EnumValue)
+ m_numDocMembers++;
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->countDocMembers();
+ m_numDocMembers+=mg->numDocMembers();
+ }
+ }
+ //printf("MemberList::countDocMembers()=%d memberGroupList=%p\n",m_numDocMembers,memberGroupList);
+}
+
+bool MemberList::insert(uint index,const MemberDef *md)
+{
+ return QList<MemberDef>::insert(index,md);
+}
+
+void MemberList::inSort(const MemberDef *md)
+{
+ QList<MemberDef>::inSort(md);
+}
+
+void MemberList::append(const MemberDef *md)
+{
+ QList<MemberDef>::append(md);
+}
+
+MemberListIterator::MemberListIterator(const QList<MemberDef> &l) :
+ QListIterator<MemberDef>(l)
+{
+}
+
+void MemberList::writePlainDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd
+ )
+{
+ //printf("----- writePlainDeclaration() ----\n");
+ countDecMembers();
+ if (numDecMembers()==0)
+ {
+ //printf(" --> no members!\n");
+ return; // no members in this list
+ }
+ //printf(" --> writePlainDeclaration() numDecMembers()=%d\n",
+ // numDecMembers());
+
+ ol.pushGeneratorState();
+
+ bool first=TRUE;
+ MemberDef *md;
+ MemberListIterator mli(*this);
+ for ( ; (md=mli.current()); ++mli )
+ {
+ //printf(">>> Member `%s' type=%d visible=%d\n",
+ // md->name().data(),md->memberType(),md->isBriefSectionVisible());
+ if (md->isBriefSectionVisible())
+ {
+ switch(md->memberType())
+ {
+ case MemberDef::Define: // fall through
+ //case MemberDef::Prototype: // fall through
+ case MemberDef::Typedef: // fall through
+ case MemberDef::Variable: // fall through
+ case MemberDef::Function: // fall through
+ case MemberDef::Signal: // fall through
+ case MemberDef::Slot: // fall through
+ case MemberDef::DCOP: // fall through
+ case MemberDef::Property: // fall through
+ case MemberDef::Event:
+ {
+ if (first) ol.startMemberList(),first=FALSE;
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
+ break;
+ }
+ case MemberDef::Enumeration:
+ {
+ int enumVars=0;
+ MemberListIterator vmli(*this);
+ MemberDef *vmd;
+ QCString name(md->name());
+ int i=name.findRev("::");
+ if (i!=-1) name=name.right(name.length()-i-2); // strip scope (TODO: is this needed?)
+ if (name[0]=='@') // anonymous enum => append variables
+ {
+ for ( ; (vmd=vmli.current()) ; ++vmli)
+ {
+ QCString vtype=vmd->typeString();
+ if ((vtype.find(name))!=-1)
+ {
+ enumVars++;
+ vmd->setAnonymousEnumType(md);
+ }
+ }
+ }
+ // if this is an anoymous enum and there are variables of this
+ // enum type (i.e. enumVars>0), then we do not show the enum here.
+ if (enumVars==0) // show enum here
+ {
+ //printf("Enum!!\n");
+ if (first) ol.startMemberList(),first=FALSE;
+ ol.startMemberItem(0);
+ ol.writeString("enum ");
+ ol.insertMemberAlign();
+ md->writeEnumDeclaration(ol,cd,nd,fd,gd);
+ ol.endMemberItem();
+ if (!md->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startMemberDescription();
+ ol.parseDoc(
+ md->briefFile(),md->briefLine(),
+ cd,md,
+ md->briefDescription(),
+ TRUE,
+ FALSE
+ );
+ if (md->isDetailedSectionLinkable())
+ {
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ ol.startTextLink(md->getOutputFileBase(),
+ md->anchor());
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ ol.enableAll();
+ }
+ ol.endMemberDescription();
+ }
+ }
+ md->warnIfUndocumented();
+ break;
+ }
+ case MemberDef::Friend:
+ {
+ if (first) ol.startMemberList(),first=FALSE;
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
+ break;
+ }
+ case MemberDef::EnumValue:
+ {
+ if (m_inGroup)
+ {
+ //printf("EnumValue!\n");
+ if (first) ol.startMemberList(),first=FALSE;
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ // handle members that are inside anonymous compounds and for which
+ // no variables of the anonymous compound type exist.
+ if (cd)
+ {
+ MemberListIterator mli(*this);
+ for ( ; (md=mli.current()) ; ++mli )
+ {
+ if (md->fromAnonymousScope() && !md->anonymousDeclShown())
+ {
+ md->setFromAnonymousScope(FALSE);
+ //printf("anonymous compound members\n");
+ if (md->isBriefSectionVisible())
+ {
+ if (first) ol.startMemberList(),first=FALSE;
+ md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
+ }
+ md->setFromAnonymousScope(TRUE);
+ }
+ }
+ }
+
+ if (!first) ol.endMemberList();
+
+ ol.popGeneratorState();
+ //printf("----- end writePlainDeclaration() ----\n");
+}
+
+void MemberList::writeDeclarations(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ const char *title,const char *subtitle, bool showEnumValues
+ /*, bool inGroup,bool countSubGroups*/)
+{
+ //printf("----- writeDeclaration() this=%p ----\n",this);
+ static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+
+ countDecMembers(showEnumValues); // count member not in group
+ Definition *ctx = cd;
+ if (ctx==0 && nd) ctx = nd;
+ if (ctx==0 && gd) ctx = gd;
+ if (ctx==0 && fd) ctx = fd;
+
+ if (numDecMembers()==0) return;
+ //printf("%p: MemberList::writeDeclaration(title=`%s',subtitle=`%s')=%d\n",
+ // this,title,subtitle,numDecMembers());
+ if (title)
+ {
+ ol.startMemberHeader();
+ ol.parseText(title);
+ ol.endMemberHeader();
+ }
+ if (subtitle)
+ {
+ QCString st=subtitle;
+ st = st.stripWhiteSpace();
+ if (!st.isEmpty())
+ {
+ ol.startMemberSubtitle();
+ ol.parseDoc("[generated]",-1,ctx,0,subtitle,FALSE,FALSE);
+ ol.endMemberSubtitle();
+ }
+ }
+
+ // TODO: Two things need to be worked out for proper VHDL output:
+ // 1. Signals and types under the group need to be
+ // formatted to associate them with the group somehow
+ // indentation, or at the very least, extra space after
+ // the group is done
+ // 2. This might need to be repeated below for memberGroupLists
+ if (optimizeVhdl) // use specific declarations function
+ {
+ VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd,0);
+ }
+ else
+ {
+ writePlainDeclarations(ol,cd,nd,fd,gd);
+ }
+
+ //printf("memberGroupList=%p\n",memberGroupList);
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ while ((mg=mgli.current()))
+ {
+ //printf("mg->header=%s\n",mg->header().data());
+ bool hasHeader=mg->header()!="[NOHEADER]";
+ ol.startMemberGroupHeader(hasHeader);
+ if (hasHeader)
+ {
+ ol.parseText(mg->header());
+ }
+ ol.endMemberGroupHeader();
+ if (!mg->documentation().isEmpty())
+ {
+ //printf("Member group has docs!\n");
+ ol.startMemberGroupDocs();
+ ol.parseDoc("[generated]",-1,ctx,0,mg->documentation()+"\n",FALSE,FALSE);
+ ol.endMemberGroupDocs();
+ }
+ ol.startMemberGroup();
+ //printf("--- mg->writePlainDeclarations ---\n");
+ mg->writePlainDeclarations(ol,cd,nd,fd,gd);
+ ol.endMemberGroup(hasHeader);
+ ++mgli;
+ }
+ }
+ //printf("----- end writeDeclaration() ----\n");
+
+}
+
+void MemberList::writeDocumentation(OutputList &ol,
+ const char *scopeName, Definition *container,
+ const char *title,bool showEnumValues)
+{
+ //printf("MemberList::writeDocumentation()\n");
+
+ countDocMembers(showEnumValues);
+ if (numDocMembers()==0) return;
+
+ if (title)
+ {
+ ol.writeRuler();
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+ }
+ ol.startMemberDocList();
+
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ md->writeDocumentation(this,ol,scopeName,container,m_inGroup,showEnumValues);
+ }
+ if (memberGroupList)
+ {
+ //printf("MemberList::writeDocumentation() -- member groups\n");
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->writeDocumentation(ol,scopeName,container);
+ }
+ }
+ ol.endMemberDocList();
+}
+
+void MemberList::writeDocumentationPage(OutputList &ol,
+ const char *scopeName, Definition *container)
+{
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ QCString diskName=md->getOutputFileBase();
+ QCString title=md->qualifiedName();
+ startFile(ol,diskName,md->name(),title);
+ container->writeNavigationPath(ol);
+
+ ol.writeString("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n"
+ " <tr>\n"
+ " <td valign=\"top\">\n");
+
+ container->writeQuickMemberLinks(ol,md);
+
+ ol.writeString(" </td>\n");
+ ol.writeString(" <td valign=\"top\">\n");
+
+ md->writeDocumentation(this,ol,scopeName,container,m_inGroup);
+
+ ol.writeString(" </td>\n");
+ ol.writeString(" </tr>\n");
+ ol.writeString("</table>\n");
+
+ endFile(ol);
+ }
+ if (memberGroupList)
+ {
+ //printf("MemberList::writeDocumentation() -- member groups\n");
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->writeDocumentationPage(ol,scopeName,container);
+ }
+ }
+}
+
+void MemberList::addMemberGroup(MemberGroup *mg)
+{
+ if (memberGroupList==0)
+ {
+ memberGroupList=new MemberGroupList;
+ }
+ //printf("addMemberGroup: this=%p mg=%p\n",this,mg);
+ memberGroupList->append(mg);
+}
+
+void MemberList::addListReferences(Definition *def)
+{
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ if (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup)
+ {
+ md->addListReference(def);
+ LockingPtr<MemberList> enumFields = md->enumFieldList();
+ if (md->memberType()==MemberDef::Enumeration && enumFields!=0)
+ {
+ MemberListIterator vmli(*enumFields);
+ MemberDef *vmd;
+ for ( ; (vmd=vmli.current()) ; ++vmli)
+ {
+ vmd->addListReference(def);
+ }
+ }
+ }
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(def);
+ }
+ }
+}
+
+void MemberList::findSectionsInDocumentation()
+{
+ MemberListIterator mli(*this);
+ MemberDef *md;
+ for ( ; (md=mli.current()) ; ++mli)
+ {
+ md->findSectionsInDocumentation();
+ }
+ if (memberGroupList)
+ {
+ MemberGroupListIterator mgli(*memberGroupList);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+ }
+}
+
+void MemberList::marshal(StorageIntf *s)
+{
+ marshalInt(s,(int)m_listType);
+ marshalInt(s,m_varCnt);
+ marshalInt(s,m_funcCnt);
+ marshalInt(s,m_enumCnt);
+ marshalInt(s,m_enumValCnt);
+ marshalInt(s,m_typeCnt);
+ marshalInt(s,m_protoCnt);
+ marshalInt(s,m_defCnt);
+ marshalInt(s,m_friendCnt);
+ marshalInt(s,m_numDecMembers);
+ marshalInt(s,m_numDocMembers);
+ marshalBool(s,m_inGroup);
+ marshalBool(s,m_inFile);
+ if (memberGroupList==0)
+ {
+ marshalUInt(s,NULL_LIST); // null pointer representation
+ }
+ else
+ {
+ marshalUInt(s,memberGroupList->count());
+ QListIterator<MemberGroup> mgi(*memberGroupList);
+ MemberGroup *mg=0;
+ for (mgi.toFirst();(mg=mgi.current());++mgi)
+ {
+ mg->marshal(s);
+ }
+ }
+}
+
+void MemberList::unmarshal(StorageIntf *s)
+{
+ m_listType = (MemberList::ListType)unmarshalInt(s);
+ m_varCnt = unmarshalInt(s);
+ m_funcCnt = unmarshalInt(s);
+ m_enumCnt = unmarshalInt(s);
+ m_enumValCnt = unmarshalInt(s);
+ m_typeCnt = unmarshalInt(s);
+ m_protoCnt = unmarshalInt(s);
+ m_defCnt = unmarshalInt(s);
+ m_friendCnt = unmarshalInt(s);
+ m_numDecMembers = unmarshalInt(s);
+ m_numDocMembers = unmarshalInt(s);
+ m_inGroup = unmarshalBool(s);
+ m_inFile = unmarshalBool(s);
+ uint i,count = unmarshalUInt(s);
+ if (count==NULL_LIST) // empty list
+ {
+ memberGroupList = 0;
+ }
+ else // add member groups
+ {
+ memberGroupList = new MemberGroupList;
+ for (i=0;i<count;i++)
+ {
+ MemberGroup *mg = new MemberGroup;
+ mg->unmarshal(s);
+ memberGroupList->append(mg);
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+
+int MemberSDict::compareItems(GCI item1, GCI item2)
+{
+ MemberDef *c1=(MemberDef *)item1;
+ MemberDef *c2=(MemberDef *)item2;
+ return stricmp(c1->name(),c2->name());
+}
+