memberlist.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: memberlist.cpp,v 1.35 2001/03/19 19:27:41 root Exp $
00004  *
00005  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and its
00008  * documentation under the terms of the GNU General Public License is hereby 
00009  * granted. No representations are made about the suitability of this software 
00010  * for any purpose. It is provided "as is" without express or implied warranty.
00011  * See the GNU General Public License for more details.
00012  *
00013  * Documents produced by Doxygen are derivative works derived from the
00014  * input used in their production; they are not affected by this license.
00015  *
00016  */
00017 
00018 #include <qregexp.h>
00019 
00020 #include "memberlist.h"
00021 #include "classdef.h"
00022 #include "message.h"
00023 #include "util.h"
00024 #include "language.h"
00025 #include "doxygen.h"
00026 #include "outputlist.h"
00027 #include "groupdef.h"
00028 #include "marshal.h"
00029 
00030 MemberList::MemberList()
00031 {
00032 }
00033 
00034 MemberList::MemberList(ListType lt) : m_listType(lt)
00035 {
00036   memberGroupList=0;
00037   m_numDecMembers=-1; // special value indicating that value needs to be computed
00038   m_numDocMembers=-1; // special value indicating that value needs to be computed
00039   m_inGroup=FALSE;
00040   m_inFile=FALSE;
00041 }
00042 
00043 MemberList::~MemberList()
00044 {
00045   delete memberGroupList;
00046 }
00047 
00048 int MemberList::compareItems(GCI item1, GCI item2)
00049 {
00050   MemberDef *c1=(MemberDef *)item1;
00051   MemberDef *c2=(MemberDef *)item2;
00052   return stricmp(c1->name(),c2->name());
00053 }
00054 
00058 void MemberList::countDecMembers(bool countEnumValues)
00059 {
00060   if (m_numDecMembers!=-1) return; 
00061   
00062   //printf("----- countDecMembers count=%d ----\n",count());
00063   m_varCnt=m_funcCnt=m_enumCnt=m_enumValCnt=0;
00064   m_typeCnt=m_protoCnt=m_defCnt=m_friendCnt=0;
00065   m_numDecMembers=0;
00066   QListIterator<MemberDef> mli(*this);
00067   MemberDef *md;
00068   for (mli.toFirst();(md=mli.current());++mli)
00069   {
00070     //printf("MemberList::countDecMembers(md=%s,%d)\n",md->name().data(),md->isBriefSectionVisible());
00071     if (md->isBriefSectionVisible())
00072     {
00073       switch(md->memberType())
00074       {
00075         case MemberDef::Variable:    // fall through
00076         case MemberDef::Event:       // fall through
00077         case MemberDef::Property:    m_varCnt++,m_numDecMembers++;  
00078                                      break;
00079         case MemberDef::Function:    // fall through
00080         case MemberDef::Signal:      // fall through
00081         case MemberDef::DCOP:        // fall through
00082         case MemberDef::Slot:        if (!md->isRelated() || md->getClassDef())
00083                                        m_funcCnt++,m_numDecMembers++; 
00084                                      break;
00085         case MemberDef::Enumeration: m_enumCnt++,m_numDecMembers++; break;
00086         case MemberDef::EnumValue:   if (countEnumValues)
00087                                        m_enumValCnt++,m_numDecMembers++; 
00088                                      break;
00089         case MemberDef::Typedef:     m_typeCnt++,m_numDecMembers++; break;
00090         case MemberDef::Prototype:   m_protoCnt++,m_numDecMembers++; break;
00091         case MemberDef::Define:      if (Config_getBool("EXTRACT_ALL") || 
00092                                          md->argsString() || 
00093                                          !md->initializer().isEmpty() ||
00094                                          md->hasDocumentation() 
00095                                         ) m_defCnt++,m_numDecMembers++;     
00096                                      break;
00097         case MemberDef::Friend:      m_friendCnt++,m_numDecMembers++;  
00098                                      break;
00099         default:
00100           err("Error: Unknown member type found for member `%s'\n!",md->name().data());
00101       }
00102     }
00103   }
00104   if (memberGroupList)
00105   {
00106     MemberGroupListIterator mgli(*memberGroupList);
00107     MemberGroup *mg;
00108     for (;(mg=mgli.current());++mgli)
00109     {
00110       mg->countDecMembers();
00111       m_varCnt+=mg->varCount();
00112       m_funcCnt+=mg->funcCount();
00113       m_enumCnt+=mg->enumCount();
00114       m_enumValCnt+=mg->enumValueCount();
00115       m_typeCnt+=mg->typedefCount();
00116       m_protoCnt+=mg->protoCount();
00117       m_defCnt+=mg->defineCount();
00118       m_friendCnt+=mg->friendCount();
00119       m_numDecMembers+=mg->numDecMembers();
00120     }
00121   }
00122   //printf("----- end countDecMembers ----\n");
00123 
00124   //printf("MemberList::countDecMembers()=%d\n",m_numDecMembers);
00125 }
00126 
00127 void MemberList::countDocMembers(bool countEnumValues)
00128 {
00129   if (m_numDocMembers!=-1) return; // used cached value
00130   m_numDocMembers=0;
00131   QListIterator<MemberDef> mli(*this);
00132   MemberDef *md;
00133   for (mli.toFirst();(md=mli.current());++mli)
00134   {
00135     if (md->isDetailedSectionVisible(m_inGroup,m_inFile)) 
00136     {
00137       // do not count enum values, since they do not produce entries of their own
00138       if (countEnumValues || md->memberType()!=MemberDef::EnumValue) 
00139         m_numDocMembers++;
00140     }
00141   }
00142   if (memberGroupList)
00143   {
00144     MemberGroupListIterator mgli(*memberGroupList);
00145     MemberGroup *mg;
00146     for (;(mg=mgli.current());++mgli)
00147     {
00148       mg->countDocMembers();
00149       m_numDocMembers+=mg->numDocMembers();
00150     }
00151   }
00152   //printf("MemberList::countDocMembers()=%d memberGroupList=%p\n",m_numDocMembers,memberGroupList);
00153 }
00154 
00155 bool MemberList::insert(uint index,const MemberDef *md)
00156 {
00157   return QList<MemberDef>::insert(index,md);
00158 }
00159 
00160 void MemberList::inSort(const MemberDef *md)
00161 {
00162   QList<MemberDef>::inSort(md);
00163 }
00164 
00165 void MemberList::append(const MemberDef *md)
00166 {
00167   QList<MemberDef>::append(md);
00168 }
00169 
00170 MemberListIterator::MemberListIterator(const QList<MemberDef> &l) :
00171   QListIterator<MemberDef>(l) 
00172 {
00173 }
00174 
00175 void MemberList::writePlainDeclarations(OutputList &ol,
00176                        ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd
00177                       )
00178 {
00179   //printf("----- writePlainDeclaration() ----\n");
00180   countDecMembers();
00181   if (numDecMembers()==0) 
00182   {
00183     //printf("  --> no members!\n");
00184     return; // no members in this list
00185   }
00186   //printf("  --> writePlainDeclaration() numDecMembers()=%d\n",
00187   //     numDecMembers());
00188   
00189   ol.pushGeneratorState();
00190 
00191   bool first=TRUE;
00192   MemberDef *md;
00193   MemberListIterator mli(*this);
00194   for ( ; (md=mli.current()); ++mli )
00195   {
00196     //printf(">>> Member `%s' type=%d visible=%d\n",
00197     //    md->name().data(),md->memberType(),md->isBriefSectionVisible());
00198     if (md->isBriefSectionVisible())
00199     {
00200       switch(md->memberType())
00201       {
00202         case MemberDef::Define:    // fall through
00203         case MemberDef::Prototype: // fall through
00204         case MemberDef::Typedef:   // fall through
00205         case MemberDef::Variable:  // fall through
00206         case MemberDef::Function:  // fall through
00207         case MemberDef::Signal:    // fall through
00208         case MemberDef::Slot:      // fall through
00209         case MemberDef::DCOP:      // fall through
00210         case MemberDef::Property:  // fall through
00211         case MemberDef::Event:  
00212           {
00213             if (first) ol.startMemberList(),first=FALSE;
00214             md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
00215             break;
00216           }
00217         case MemberDef::Enumeration: 
00218           {
00219             if (first) ol.startMemberList(),first=FALSE;
00220             int enumVars=0;
00221             MemberListIterator vmli(*this);
00222             MemberDef *vmd;
00223             QCString name(md->name());
00224             int i=name.findRev("::");
00225             if (i!=-1) name=name.right(name.length()-i-2); // strip scope (TODO: is this needed?)
00226             if (name[0]=='@') // anonymous enum => append variables
00227             {
00228               for ( ; (vmd=vmli.current()) ; ++vmli)
00229               {
00230                 QCString vtype=vmd->typeString();
00231                 if ((vtype.find(name))!=-1) 
00232                 {
00233                   enumVars++;
00234                   vmd->setAnonymousEnumType(md);
00235                 }
00236               }
00237             }
00238             // if this is an anoymous enum and there are variables of this
00239             // enum type (i.e. enumVars>0), then we do not show the enum here.
00240             if (enumVars==0) // show enum here
00241             {
00242               ol.startMemberItem(0);
00243               ol.writeString("enum ");
00244               ol.insertMemberAlign();
00245               md->writeEnumDeclaration(ol,cd,nd,fd,gd);
00246               ol.endMemberItem();
00247               if (!md->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
00248               {
00249                 ol.startMemberDescription();
00250                 ol.parseDoc(
00251                     md->briefFile(),md->briefLine(),
00252                     cd,md,
00253                     md->briefDescription(),
00254                     TRUE,
00255                     FALSE
00256                     );
00257                 if (md->isDetailedSectionLinkable())
00258                 {
00259                   ol.disableAllBut(OutputGenerator::Html);
00260                   ol.docify(" ");
00261                   ol.startTextLink(md->getOutputFileBase(),
00262                                    md->anchor());
00263                   ol.parseText(theTranslator->trMore());
00264                   ol.endTextLink();
00265                   ol.enableAll();
00266                 }
00267                 ol.endMemberDescription();
00268               }
00269             }
00270             md->warnIfUndocumented();
00271             break;
00272           }
00273         case MemberDef::Friend:
00274           {
00275             if (first) ol.startMemberList(),first=FALSE;
00276             md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
00277             break;
00278           }
00279         case MemberDef::EnumValue: 
00280           {
00281             if (first) ol.startMemberList(),first=FALSE;
00282             md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
00283           }
00284           break;
00285       }
00286     }
00287   }
00288 
00289   // handle members that are inside anonymous compounds and for which
00290   // no variables of the anonymous compound type exist.
00291   if (cd)
00292   {
00293     MemberListIterator mli(*this);
00294     for  ( ; (md=mli.current()) ; ++mli )
00295     {
00296       if (md->fromAnonymousScope() && !md->anonymousDeclShown())
00297       {
00298         md->setFromAnonymousScope(FALSE);
00299         //printf("anonymous compound members\n");
00300         if (md->isBriefSectionVisible())
00301         {
00302           if (first) ol.startMemberList(),first=FALSE;
00303           md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
00304         }
00305         md->setFromAnonymousScope(TRUE);
00306       }
00307     }
00308   }
00309  
00310   if (!first) ol.endMemberList(); 
00311 
00312   ol.popGeneratorState();
00313   //printf("----- end writePlainDeclaration() ----\n");
00314 }
00315 
00316 void MemberList::writeDeclarations(OutputList &ol,
00317              ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
00318              const char *title,const char *subtitle, bool showEnumValues
00319              /*, bool inGroup,bool countSubGroups*/)
00320 {
00321   //printf("----- writeDeclaration() this=%p ----\n",this);
00322   countDecMembers(showEnumValues); // count member not in group
00323   if (numDecMembers()==0) return;
00324   //printf("%p: MemberList::writeDeclaration(title=`%s',subtitle=`%s')=%d\n",
00325   //    this,title,subtitle,numDecMembers());
00326   if (title) 
00327   {
00328     ol.startMemberHeader();
00329     ol.parseText(title);
00330     ol.endMemberHeader();
00331   }
00332   if (subtitle && subtitle[0]!=0) 
00333   {
00334     //printf("subtitle=`%s'\n",subtitle);
00335     ol.startMemberSubtitle();
00336     ol.parseDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE);
00337     ol.endMemberSubtitle();
00338   }
00339 
00340   writePlainDeclarations(ol,cd,nd,fd,gd);
00341   
00342   //printf("memberGroupList=%p\n",memberGroupList);
00343   if (memberGroupList)
00344   {
00345     MemberGroupListIterator mgli(*memberGroupList);
00346     MemberGroup *mg;
00347     while ((mg=mgli.current()))
00348     {
00349       //printf("mg->header=%s\n",mg->header().data());
00350       bool hasHeader=mg->header()!="[NOHEADER]";
00351       ol.startMemberGroupHeader(hasHeader);
00352       if (hasHeader)
00353       {
00354         ol.parseText(mg->header());
00355       }
00356       ol.endMemberGroupHeader();
00357       if (!mg->documentation().isEmpty())
00358       {
00359         //printf("Member group has docs!\n");
00360         ol.startMemberGroupDocs();
00361         ol.parseDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
00362         ol.endMemberGroupDocs();
00363       }
00364       ol.startMemberGroup();
00365       //printf("--- mg->writePlainDeclarations ---\n");
00366       mg->writePlainDeclarations(ol,cd,nd,fd,gd);
00367       ol.endMemberGroup(hasHeader);
00368       ++mgli;
00369     }
00370   }
00371   //printf("----- end writeDeclaration() ----\n");
00372 
00373 }
00374 
00375 void MemberList::writeDocumentation(OutputList &ol,
00376                      const char *scopeName, Definition *container,
00377                      const char *title,bool showEnumValues)
00378 {
00379   //printf("MemberList::writeDocumentation()\n");
00380 
00381   countDocMembers(showEnumValues);
00382   if (numDocMembers()==0) return;
00383 
00384   if (title)
00385   {
00386     ol.writeRuler();
00387     ol.startGroupHeader();
00388     ol.parseText(title);
00389     ol.endGroupHeader();
00390   }
00391   ol.startMemberDocList();
00392   
00393   MemberListIterator mli(*this);
00394   MemberDef *md;
00395   for ( ; (md=mli.current()) ; ++mli)
00396   {
00397     md->writeDocumentation(this,ol,scopeName,container,m_inGroup,showEnumValues);
00398   }
00399   if (memberGroupList)
00400   {
00401     //printf("MemberList::writeDocumentation()  --  member groups\n");
00402     MemberGroupListIterator mgli(*memberGroupList);
00403     MemberGroup *mg;
00404     for (;(mg=mgli.current());++mgli)
00405     {
00406       mg->writeDocumentation(ol,scopeName,container);
00407     }
00408   }
00409   ol.endMemberDocList();
00410 }
00411 
00412 void MemberList::writeDocumentationPage(OutputList &ol,
00413                      const char *scopeName, Definition *container)
00414 {
00415   MemberListIterator mli(*this);
00416   MemberDef *md;
00417   for ( ; (md=mli.current()) ; ++mli)
00418   {
00419     QCString diskName=md->getOutputFileBase();
00420     QCString title=md->qualifiedName();
00421     startFile(ol,diskName,md->name(),title);
00422     container->writeNavigationPath(ol);
00423 
00424     ol.writeString("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n"
00425                    "  <tr>\n"
00426                    "   <td valign=\"top\">\n");
00427 
00428     container->writeQuickMemberLinks(ol,md);
00429 
00430     ol.writeString("   </td>\n");
00431     ol.writeString("   <td valign=\"top\">\n");
00432     
00433     md->writeDocumentation(this,ol,scopeName,container,m_inGroup);
00434 
00435     ol.writeString("    </td>\n");
00436     ol.writeString("  </tr>\n");
00437     ol.writeString("</table>\n");
00438     
00439     endFile(ol);
00440   }
00441   if (memberGroupList)
00442   {
00443     //printf("MemberList::writeDocumentation()  --  member groups\n");
00444     MemberGroupListIterator mgli(*memberGroupList);
00445     MemberGroup *mg;
00446     for (;(mg=mgli.current());++mgli)
00447     {
00448       mg->writeDocumentationPage(ol,scopeName,container);
00449     }
00450   }
00451 }
00452 
00453 void MemberList::addMemberGroup(MemberGroup *mg)
00454 {
00455   if (memberGroupList==0)
00456   {
00457     memberGroupList=new MemberGroupList;
00458   }
00459   //printf("addMemberGroup: this=%p mg=%p\n",this,mg);
00460   memberGroupList->append(mg);
00461 }
00462 
00463 void MemberList::addListReferences(Definition *def)
00464 {
00465   MemberListIterator mli(*this);
00466   MemberDef *md;
00467   for ( ; (md=mli.current()) ; ++mli)
00468   {
00469     if (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup)
00470     {
00471       md->addListReference(def);
00472       LockingPtr<MemberList> enumFields = md->enumFieldList();
00473       if (md->memberType()==MemberDef::Enumeration && enumFields!=0)
00474       {
00475         MemberListIterator vmli(*enumFields);
00476         MemberDef *vmd;
00477         for ( ; (vmd=vmli.current()) ; ++vmli)
00478         {
00479           vmd->addListReference(def);
00480         }
00481       }
00482     }
00483   }
00484   if (memberGroupList)
00485   {
00486     MemberGroupListIterator mgli(*memberGroupList);
00487     MemberGroup *mg;
00488     for (;(mg=mgli.current());++mgli)
00489     {
00490       mg->addListReferences(def);
00491     }
00492   }
00493 }
00494 
00495 void MemberList::findSectionsInDocumentation()
00496 {
00497   MemberListIterator mli(*this);
00498   MemberDef *md;
00499   for ( ; (md=mli.current()) ; ++mli)
00500   {
00501     md->findSectionsInDocumentation();
00502   }
00503   if (memberGroupList)
00504   {
00505     MemberGroupListIterator mgli(*memberGroupList);
00506     MemberGroup *mg;
00507     for (;(mg=mgli.current());++mgli)
00508     {
00509       mg->findSectionsInDocumentation();
00510     }
00511   }
00512 }
00513 
00514 void MemberList::marshal(StorageIntf *s)
00515 {
00516   marshalInt(s,(int)m_listType);
00517   marshalInt(s,m_varCnt);
00518   marshalInt(s,m_funcCnt);
00519   marshalInt(s,m_enumCnt);
00520   marshalInt(s,m_enumValCnt);
00521   marshalInt(s,m_typeCnt);
00522   marshalInt(s,m_protoCnt);
00523   marshalInt(s,m_defCnt);
00524   marshalInt(s,m_friendCnt); 
00525   marshalInt(s,m_numDecMembers);
00526   marshalInt(s,m_numDocMembers);
00527   marshalBool(s,m_inGroup);
00528   marshalBool(s,m_inFile);
00529   if (memberGroupList==0)
00530   {
00531     marshalUInt(s,NULL_LIST); // null pointer representation
00532   }
00533   else
00534   {
00535     marshalUInt(s,memberGroupList->count());
00536     QListIterator<MemberGroup> mgi(*memberGroupList);
00537     MemberGroup *mg=0;
00538     for (mgi.toFirst();(mg=mgi.current());++mgi)
00539     {
00540       mg->marshal(s);
00541     }
00542   }
00543 }
00544 
00545 void MemberList::unmarshal(StorageIntf *s)
00546 {
00547   m_listType       = (MemberList::ListType)unmarshalInt(s);
00548   m_varCnt         = unmarshalInt(s);
00549   m_funcCnt        = unmarshalInt(s);
00550   m_enumCnt        = unmarshalInt(s);
00551   m_enumValCnt     = unmarshalInt(s);
00552   m_typeCnt        = unmarshalInt(s);
00553   m_protoCnt       = unmarshalInt(s);
00554   m_defCnt         = unmarshalInt(s);
00555   m_friendCnt      = unmarshalInt(s); 
00556   m_numDecMembers  = unmarshalInt(s);
00557   m_numDocMembers  = unmarshalInt(s);
00558   m_inGroup        = unmarshalBool(s);
00559   m_inFile         = unmarshalBool(s);
00560   uint i,count     = unmarshalUInt(s); 
00561   if (count==NULL_LIST) // empty list
00562   {
00563     memberGroupList = 0;
00564   }
00565   else // add member groups
00566   {
00567     memberGroupList = new MemberGroupList;
00568     for (i=0;i<count;i++)
00569     {
00570       MemberGroup *mg = new MemberGroup;
00571       mg->unmarshal(s);
00572       memberGroupList->append(mg);
00573     }
00574   }
00575 }
00576 
00577 //--------------------------------------------------------------------------
00578 
00579 int MemberSDict::compareItems(GCI item1, GCI item2)
00580 {
00581   MemberDef *c1=(MemberDef *)item1;
00582   MemberDef *c2=(MemberDef *)item2;
00583   return stricmp(c1->name(),c2->name());
00584 }
00585 



Generated on Mon Mar 31 10:58:40 2008 by  doxygen 1.5.1