Orb/Doxygen/src/memberlist.cpp
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 #include <qregexp.h>
       
    19 
       
    20 #include "memberlist.h"
       
    21 #include "classdef.h"
       
    22 #include "message.h"
       
    23 #include "util.h"
       
    24 #include "language.h"
       
    25 #include "doxygen.h"
       
    26 #include "outputlist.h"
       
    27 #include "groupdef.h"
       
    28 #include "marshal.h"
       
    29 #include "vhdldocgen.h"
       
    30 
       
    31 MemberList::MemberList()
       
    32 {
       
    33 }
       
    34 
       
    35 MemberList::MemberList(ListType lt) : m_listType(lt)
       
    36 {
       
    37   memberGroupList=0;
       
    38   m_numDecMembers=-1; // special value indicating that value needs to be computed
       
    39   m_numDocMembers=-1; // special value indicating that value needs to be computed
       
    40   m_inGroup=FALSE;
       
    41   m_inFile=FALSE;
       
    42 }
       
    43 
       
    44 MemberList::~MemberList()
       
    45 {
       
    46   delete memberGroupList;
       
    47 }
       
    48 
       
    49 int MemberList::compareItems(GCI item1, GCI item2)
       
    50 {
       
    51   static bool sortConstructorsFirst = Config_getBool("SORT_MEMBERS_CTORS_1ST");
       
    52   MemberDef *c1=(MemberDef *)item1;
       
    53   MemberDef *c2=(MemberDef *)item2;
       
    54   if (sortConstructorsFirst) {
       
    55     int ord1 = c1->isConstructor() ? 2 : (c1->isDestructor() ? 1 : 0);
       
    56     int ord2 = c2->isConstructor() ? 2 : (c2->isDestructor() ? 1 : 0);
       
    57     if (ord1 > ord2)
       
    58       return -1;
       
    59     else if (ord2 > ord1)
       
    60       return 1;
       
    61   }
       
    62   return stricmp(c1->name(),c2->name());
       
    63 }
       
    64 
       
    65 /*! Count the number of members in this list that are visible in
       
    66  *  the declaration part of a compound's documentation page.
       
    67  */
       
    68 void MemberList::countDecMembers(bool countEnumValues)
       
    69 {
       
    70   if (m_numDecMembers!=-1) return; 
       
    71   
       
    72   //printf("----- countDecMembers count=%d ----\n",count());
       
    73   m_varCnt=m_funcCnt=m_enumCnt=m_enumValCnt=0;
       
    74   m_typeCnt=m_protoCnt=m_defCnt=m_friendCnt=0;
       
    75   m_numDecMembers=0;
       
    76   QListIterator<MemberDef> mli(*this);
       
    77   MemberDef *md;
       
    78   for (mli.toFirst();(md=mli.current());++mli)
       
    79   {
       
    80     //printf("MemberList::countDecMembers(md=%s,%d)\n",md->name().data(),md->isBriefSectionVisible());
       
    81     if (md->isBriefSectionVisible())
       
    82     {
       
    83       switch(md->memberType())
       
    84       {
       
    85         case MemberDef::Variable:    // fall through
       
    86         case MemberDef::Event:       // fall through
       
    87         case MemberDef::Property:    m_varCnt++,m_numDecMembers++;  
       
    88                                      break;
       
    89         case MemberDef::Function:    // fall through
       
    90         case MemberDef::Signal:      // fall through
       
    91         case MemberDef::DCOP:        // fall through
       
    92         case MemberDef::Slot:        if (!md->isRelated() || md->getClassDef())
       
    93                                        m_funcCnt++,m_numDecMembers++; 
       
    94                                      break;
       
    95         case MemberDef::Enumeration: m_enumCnt++,m_numDecMembers++; break;
       
    96         case MemberDef::EnumValue:   if (countEnumValues)
       
    97                                        m_enumValCnt++,m_numDecMembers++; 
       
    98                                      break;
       
    99         case MemberDef::Typedef:     m_typeCnt++,m_numDecMembers++; break;
       
   100         //case MemberDef::Prototype:   m_protoCnt++,m_numDecMembers++; break;
       
   101         case MemberDef::Define:      if (Config_getBool("EXTRACT_ALL") || 
       
   102                                          md->argsString() || 
       
   103                                          !md->initializer().isEmpty() ||
       
   104                                          md->hasDocumentation() 
       
   105                                         ) m_defCnt++,m_numDecMembers++;     
       
   106                                      break;
       
   107         case MemberDef::Friend:      m_friendCnt++,m_numDecMembers++;  
       
   108                                      break;
       
   109         default:
       
   110           err("Error: Unknown member type found for member `%s'\n!",md->name().data());
       
   111       }
       
   112     }
       
   113   }
       
   114   if (memberGroupList)
       
   115   {
       
   116     MemberGroupListIterator mgli(*memberGroupList);
       
   117     MemberGroup *mg;
       
   118     for (;(mg=mgli.current());++mgli)
       
   119     {
       
   120       mg->countDecMembers();
       
   121       m_varCnt+=mg->varCount();
       
   122       m_funcCnt+=mg->funcCount();
       
   123       m_enumCnt+=mg->enumCount();
       
   124       m_enumValCnt+=mg->enumValueCount();
       
   125       m_typeCnt+=mg->typedefCount();
       
   126       m_protoCnt+=mg->protoCount();
       
   127       m_defCnt+=mg->defineCount();
       
   128       m_friendCnt+=mg->friendCount();
       
   129       m_numDecMembers+=mg->numDecMembers();
       
   130     }
       
   131   }
       
   132   //printf("----- end countDecMembers ----\n");
       
   133 
       
   134   //printf("MemberList::countDecMembers()=%d\n",m_numDecMembers);
       
   135 }
       
   136 
       
   137 void MemberList::countDocMembers(bool countEnumValues)
       
   138 {
       
   139   if (m_numDocMembers!=-1) return; // used cached value
       
   140   m_numDocMembers=0;
       
   141   QListIterator<MemberDef> mli(*this);
       
   142   MemberDef *md;
       
   143   for (mli.toFirst();(md=mli.current());++mli)
       
   144   {
       
   145     if (md->isDetailedSectionVisible(m_inGroup,m_inFile)) 
       
   146     {
       
   147       // do not count enum values, since they do not produce entries of their own
       
   148       if (countEnumValues || md->memberType()!=MemberDef::EnumValue) 
       
   149         m_numDocMembers++;
       
   150     }
       
   151   }
       
   152   if (memberGroupList)
       
   153   {
       
   154     MemberGroupListIterator mgli(*memberGroupList);
       
   155     MemberGroup *mg;
       
   156     for (;(mg=mgli.current());++mgli)
       
   157     {
       
   158       mg->countDocMembers();
       
   159       m_numDocMembers+=mg->numDocMembers();
       
   160     }
       
   161   }
       
   162   //printf("MemberList::countDocMembers()=%d memberGroupList=%p\n",m_numDocMembers,memberGroupList);
       
   163 }
       
   164 
       
   165 bool MemberList::insert(uint index,const MemberDef *md)
       
   166 {
       
   167   return QList<MemberDef>::insert(index,md);
       
   168 }
       
   169 
       
   170 void MemberList::inSort(const MemberDef *md)
       
   171 {
       
   172   QList<MemberDef>::inSort(md);
       
   173 }
       
   174 
       
   175 void MemberList::append(const MemberDef *md)
       
   176 {
       
   177   QList<MemberDef>::append(md);
       
   178 }
       
   179 
       
   180 MemberListIterator::MemberListIterator(const QList<MemberDef> &l) :
       
   181   QListIterator<MemberDef>(l) 
       
   182 {
       
   183 }
       
   184 
       
   185 void MemberList::writePlainDeclarations(OutputList &ol,
       
   186                        ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd
       
   187                       )
       
   188 {
       
   189   //printf("----- writePlainDeclaration() ----\n");
       
   190   countDecMembers();
       
   191   if (numDecMembers()==0) 
       
   192   {
       
   193     //printf("  --> no members!\n");
       
   194     return; // no members in this list
       
   195   }
       
   196   //printf("  --> writePlainDeclaration() numDecMembers()=%d\n",
       
   197   //     numDecMembers());
       
   198   
       
   199   ol.pushGeneratorState();
       
   200 
       
   201   bool first=TRUE;
       
   202   MemberDef *md;
       
   203   MemberListIterator mli(*this);
       
   204   for ( ; (md=mli.current()); ++mli )
       
   205   {
       
   206     //printf(">>> Member `%s' type=%d visible=%d\n",
       
   207     //    md->name().data(),md->memberType(),md->isBriefSectionVisible());
       
   208     if (md->isBriefSectionVisible())
       
   209     {
       
   210       switch(md->memberType())
       
   211       {
       
   212         case MemberDef::Define:    // fall through
       
   213         //case MemberDef::Prototype: // fall through
       
   214         case MemberDef::Typedef:   // fall through
       
   215         case MemberDef::Variable:  // fall through
       
   216         case MemberDef::Function:  // fall through
       
   217         case MemberDef::Signal:    // fall through
       
   218         case MemberDef::Slot:      // fall through
       
   219         case MemberDef::DCOP:      // fall through
       
   220         case MemberDef::Property:  // fall through
       
   221         case MemberDef::Event:  
       
   222           {
       
   223             if (first) ol.startMemberList(),first=FALSE;
       
   224             md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
       
   225             break;
       
   226           }
       
   227         case MemberDef::Enumeration: 
       
   228           {
       
   229             int enumVars=0;
       
   230             MemberListIterator vmli(*this);
       
   231             MemberDef *vmd;
       
   232             QCString name(md->name());
       
   233             int i=name.findRev("::");
       
   234             if (i!=-1) name=name.right(name.length()-i-2); // strip scope (TODO: is this needed?)
       
   235             if (name[0]=='@') // anonymous enum => append variables
       
   236             {
       
   237               for ( ; (vmd=vmli.current()) ; ++vmli)
       
   238               {
       
   239                 QCString vtype=vmd->typeString();
       
   240                 if ((vtype.find(name))!=-1) 
       
   241                 {
       
   242                   enumVars++;
       
   243                   vmd->setAnonymousEnumType(md);
       
   244                 }
       
   245               }
       
   246             }
       
   247             // if this is an anoymous enum and there are variables of this
       
   248             // enum type (i.e. enumVars>0), then we do not show the enum here.
       
   249             if (enumVars==0) // show enum here
       
   250             {
       
   251               //printf("Enum!!\n");
       
   252               if (first) ol.startMemberList(),first=FALSE;
       
   253               ol.startMemberItem(0);
       
   254               ol.writeString("enum ");
       
   255               ol.insertMemberAlign();
       
   256               md->writeEnumDeclaration(ol,cd,nd,fd,gd);
       
   257               ol.endMemberItem();
       
   258               if (!md->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
       
   259               {
       
   260                 ol.startMemberDescription();
       
   261                 ol.parseDoc(
       
   262                     md->briefFile(),md->briefLine(),
       
   263                     cd,md,
       
   264                     md->briefDescription(),
       
   265                     TRUE,
       
   266                     FALSE
       
   267                     );
       
   268                 if (md->isDetailedSectionLinkable())
       
   269                 {
       
   270                   ol.disableAllBut(OutputGenerator::Html);
       
   271                   ol.docify(" ");
       
   272                   ol.startTextLink(md->getOutputFileBase(),
       
   273                                    md->anchor());
       
   274                   ol.parseText(theTranslator->trMore());
       
   275                   ol.endTextLink();
       
   276                   ol.enableAll();
       
   277                 }
       
   278                 ol.endMemberDescription();
       
   279               }
       
   280             }
       
   281             md->warnIfUndocumented();
       
   282             break;
       
   283           }
       
   284         case MemberDef::Friend:
       
   285           {
       
   286             if (first) ol.startMemberList(),first=FALSE;
       
   287             md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
       
   288             break;
       
   289           }
       
   290         case MemberDef::EnumValue: 
       
   291           {
       
   292             if (m_inGroup)
       
   293             {
       
   294               //printf("EnumValue!\n");
       
   295               if (first) ol.startMemberList(),first=FALSE;
       
   296               md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
       
   297             }
       
   298           }
       
   299           break;
       
   300       }
       
   301     }
       
   302   }
       
   303 
       
   304   // handle members that are inside anonymous compounds and for which
       
   305   // no variables of the anonymous compound type exist.
       
   306   if (cd)
       
   307   {
       
   308     MemberListIterator mli(*this);
       
   309     for  ( ; (md=mli.current()) ; ++mli )
       
   310     {
       
   311       if (md->fromAnonymousScope() && !md->anonymousDeclShown())
       
   312       {
       
   313         md->setFromAnonymousScope(FALSE);
       
   314         //printf("anonymous compound members\n");
       
   315         if (md->isBriefSectionVisible())
       
   316         {
       
   317           if (first) ol.startMemberList(),first=FALSE;
       
   318           md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup);
       
   319         }
       
   320         md->setFromAnonymousScope(TRUE);
       
   321       }
       
   322     }
       
   323   }
       
   324  
       
   325   if (!first) ol.endMemberList(); 
       
   326 
       
   327   ol.popGeneratorState();
       
   328   //printf("----- end writePlainDeclaration() ----\n");
       
   329 }
       
   330 
       
   331 void MemberList::writeDeclarations(OutputList &ol,
       
   332              ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
       
   333              const char *title,const char *subtitle, bool showEnumValues
       
   334              /*, bool inGroup,bool countSubGroups*/)
       
   335 {
       
   336   //printf("----- writeDeclaration() this=%p ----\n",this);
       
   337   static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
   338 
       
   339   countDecMembers(showEnumValues); // count member not in group
       
   340   Definition *ctx = cd;
       
   341   if (ctx==0 && nd) ctx = nd;
       
   342   if (ctx==0 && gd) ctx = gd;
       
   343   if (ctx==0 && fd) ctx = fd;
       
   344 
       
   345   if (numDecMembers()==0) return;
       
   346   //printf("%p: MemberList::writeDeclaration(title=`%s',subtitle=`%s')=%d\n",
       
   347   //    this,title,subtitle,numDecMembers());
       
   348   if (title) 
       
   349   {
       
   350     ol.startMemberHeader();
       
   351     ol.parseText(title);
       
   352     ol.endMemberHeader();
       
   353   }
       
   354   if (subtitle) 
       
   355   {
       
   356     QCString st=subtitle;
       
   357     st = st.stripWhiteSpace();
       
   358     if (!st.isEmpty())
       
   359     {
       
   360       ol.startMemberSubtitle();
       
   361       ol.parseDoc("[generated]",-1,ctx,0,subtitle,FALSE,FALSE);
       
   362       ol.endMemberSubtitle();
       
   363     }
       
   364   }
       
   365 
       
   366   // TODO: Two things need to be worked out for proper VHDL output:
       
   367   // 1. Signals and types under the group need to be
       
   368   //    formatted to associate them with the group somehow
       
   369   //    indentation, or at the very least, extra space after
       
   370   //    the group is done
       
   371   // 2. This might need to be repeated below for memberGroupLists
       
   372   if (optimizeVhdl) // use specific declarations function
       
   373   {
       
   374     VhdlDocGen::writeVhdlDeclarations(this,ol,0,cd,0);
       
   375   }
       
   376   else
       
   377   {
       
   378     writePlainDeclarations(ol,cd,nd,fd,gd);
       
   379   }
       
   380  
       
   381   //printf("memberGroupList=%p\n",memberGroupList);
       
   382   if (memberGroupList)
       
   383   {
       
   384     MemberGroupListIterator mgli(*memberGroupList);
       
   385     MemberGroup *mg;
       
   386     while ((mg=mgli.current()))
       
   387     {
       
   388       //printf("mg->header=%s\n",mg->header().data());
       
   389       bool hasHeader=mg->header()!="[NOHEADER]";
       
   390       ol.startMemberGroupHeader(hasHeader);
       
   391       if (hasHeader)
       
   392       {
       
   393         ol.parseText(mg->header());
       
   394       }
       
   395       ol.endMemberGroupHeader();
       
   396       if (!mg->documentation().isEmpty())
       
   397       {
       
   398         //printf("Member group has docs!\n");
       
   399         ol.startMemberGroupDocs();
       
   400         ol.parseDoc("[generated]",-1,ctx,0,mg->documentation()+"\n",FALSE,FALSE);
       
   401         ol.endMemberGroupDocs();
       
   402       }
       
   403       ol.startMemberGroup();
       
   404       //printf("--- mg->writePlainDeclarations ---\n");
       
   405       mg->writePlainDeclarations(ol,cd,nd,fd,gd);
       
   406       ol.endMemberGroup(hasHeader);
       
   407       ++mgli;
       
   408     }
       
   409   }
       
   410   //printf("----- end writeDeclaration() ----\n");
       
   411 
       
   412 }
       
   413 
       
   414 void MemberList::writeDocumentation(OutputList &ol,
       
   415                      const char *scopeName, Definition *container,
       
   416                      const char *title,bool showEnumValues)
       
   417 {
       
   418   //printf("MemberList::writeDocumentation()\n");
       
   419 
       
   420   countDocMembers(showEnumValues);
       
   421   if (numDocMembers()==0) return;
       
   422 
       
   423   if (title)
       
   424   {
       
   425     ol.writeRuler();
       
   426     ol.startGroupHeader();
       
   427     ol.parseText(title);
       
   428     ol.endGroupHeader();
       
   429   }
       
   430   ol.startMemberDocList();
       
   431   
       
   432   MemberListIterator mli(*this);
       
   433   MemberDef *md;
       
   434   for ( ; (md=mli.current()) ; ++mli)
       
   435   {
       
   436     md->writeDocumentation(this,ol,scopeName,container,m_inGroup,showEnumValues);
       
   437   }
       
   438   if (memberGroupList)
       
   439   {
       
   440     //printf("MemberList::writeDocumentation()  --  member groups\n");
       
   441     MemberGroupListIterator mgli(*memberGroupList);
       
   442     MemberGroup *mg;
       
   443     for (;(mg=mgli.current());++mgli)
       
   444     {
       
   445       mg->writeDocumentation(ol,scopeName,container);
       
   446     }
       
   447   }
       
   448   ol.endMemberDocList();
       
   449 }
       
   450 
       
   451 void MemberList::writeDocumentationPage(OutputList &ol,
       
   452                      const char *scopeName, Definition *container)
       
   453 {
       
   454   MemberListIterator mli(*this);
       
   455   MemberDef *md;
       
   456   for ( ; (md=mli.current()) ; ++mli)
       
   457   {
       
   458     QCString diskName=md->getOutputFileBase();
       
   459     QCString title=md->qualifiedName();
       
   460     startFile(ol,diskName,md->name(),title);
       
   461     container->writeNavigationPath(ol);
       
   462 
       
   463     ol.writeString("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n"
       
   464                    "  <tr>\n"
       
   465                    "   <td valign=\"top\">\n");
       
   466 
       
   467     container->writeQuickMemberLinks(ol,md);
       
   468 
       
   469     ol.writeString("   </td>\n");
       
   470     ol.writeString("   <td valign=\"top\">\n");
       
   471     
       
   472     md->writeDocumentation(this,ol,scopeName,container,m_inGroup);
       
   473 
       
   474     ol.writeString("    </td>\n");
       
   475     ol.writeString("  </tr>\n");
       
   476     ol.writeString("</table>\n");
       
   477     
       
   478     endFile(ol);
       
   479   }
       
   480   if (memberGroupList)
       
   481   {
       
   482     //printf("MemberList::writeDocumentation()  --  member groups\n");
       
   483     MemberGroupListIterator mgli(*memberGroupList);
       
   484     MemberGroup *mg;
       
   485     for (;(mg=mgli.current());++mgli)
       
   486     {
       
   487       mg->writeDocumentationPage(ol,scopeName,container);
       
   488     }
       
   489   }
       
   490 }
       
   491 
       
   492 void MemberList::addMemberGroup(MemberGroup *mg)
       
   493 {
       
   494   if (memberGroupList==0)
       
   495   {
       
   496     memberGroupList=new MemberGroupList;
       
   497   }
       
   498   //printf("addMemberGroup: this=%p mg=%p\n",this,mg);
       
   499   memberGroupList->append(mg);
       
   500 }
       
   501 
       
   502 void MemberList::addListReferences(Definition *def)
       
   503 {
       
   504   MemberListIterator mli(*this);
       
   505   MemberDef *md;
       
   506   for ( ; (md=mli.current()) ; ++mli)
       
   507   {
       
   508     if (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup)
       
   509     {
       
   510       md->addListReference(def);
       
   511       LockingPtr<MemberList> enumFields = md->enumFieldList();
       
   512       if (md->memberType()==MemberDef::Enumeration && enumFields!=0)
       
   513       {
       
   514         MemberListIterator vmli(*enumFields);
       
   515         MemberDef *vmd;
       
   516         for ( ; (vmd=vmli.current()) ; ++vmli)
       
   517         {
       
   518           vmd->addListReference(def);
       
   519         }
       
   520       }
       
   521     }
       
   522   }
       
   523   if (memberGroupList)
       
   524   {
       
   525     MemberGroupListIterator mgli(*memberGroupList);
       
   526     MemberGroup *mg;
       
   527     for (;(mg=mgli.current());++mgli)
       
   528     {
       
   529       mg->addListReferences(def);
       
   530     }
       
   531   }
       
   532 }
       
   533 
       
   534 void MemberList::findSectionsInDocumentation()
       
   535 {
       
   536   MemberListIterator mli(*this);
       
   537   MemberDef *md;
       
   538   for ( ; (md=mli.current()) ; ++mli)
       
   539   {
       
   540     md->findSectionsInDocumentation();
       
   541   }
       
   542   if (memberGroupList)
       
   543   {
       
   544     MemberGroupListIterator mgli(*memberGroupList);
       
   545     MemberGroup *mg;
       
   546     for (;(mg=mgli.current());++mgli)
       
   547     {
       
   548       mg->findSectionsInDocumentation();
       
   549     }
       
   550   }
       
   551 }
       
   552 
       
   553 void MemberList::marshal(StorageIntf *s)
       
   554 {
       
   555   marshalInt(s,(int)m_listType);
       
   556   marshalInt(s,m_varCnt);
       
   557   marshalInt(s,m_funcCnt);
       
   558   marshalInt(s,m_enumCnt);
       
   559   marshalInt(s,m_enumValCnt);
       
   560   marshalInt(s,m_typeCnt);
       
   561   marshalInt(s,m_protoCnt);
       
   562   marshalInt(s,m_defCnt);
       
   563   marshalInt(s,m_friendCnt); 
       
   564   marshalInt(s,m_numDecMembers);
       
   565   marshalInt(s,m_numDocMembers);
       
   566   marshalBool(s,m_inGroup);
       
   567   marshalBool(s,m_inFile);
       
   568   if (memberGroupList==0)
       
   569   {
       
   570     marshalUInt(s,NULL_LIST); // null pointer representation
       
   571   }
       
   572   else
       
   573   {
       
   574     marshalUInt(s,memberGroupList->count());
       
   575     QListIterator<MemberGroup> mgi(*memberGroupList);
       
   576     MemberGroup *mg=0;
       
   577     for (mgi.toFirst();(mg=mgi.current());++mgi)
       
   578     {
       
   579       mg->marshal(s);
       
   580     }
       
   581   }
       
   582 }
       
   583 
       
   584 void MemberList::unmarshal(StorageIntf *s)
       
   585 {
       
   586   m_listType       = (MemberList::ListType)unmarshalInt(s);
       
   587   m_varCnt         = unmarshalInt(s);
       
   588   m_funcCnt        = unmarshalInt(s);
       
   589   m_enumCnt        = unmarshalInt(s);
       
   590   m_enumValCnt     = unmarshalInt(s);
       
   591   m_typeCnt        = unmarshalInt(s);
       
   592   m_protoCnt       = unmarshalInt(s);
       
   593   m_defCnt         = unmarshalInt(s);
       
   594   m_friendCnt      = unmarshalInt(s); 
       
   595   m_numDecMembers  = unmarshalInt(s);
       
   596   m_numDocMembers  = unmarshalInt(s);
       
   597   m_inGroup        = unmarshalBool(s);
       
   598   m_inFile         = unmarshalBool(s);
       
   599   uint i,count     = unmarshalUInt(s); 
       
   600   if (count==NULL_LIST) // empty list
       
   601   {
       
   602     memberGroupList = 0;
       
   603   }
       
   604   else // add member groups
       
   605   {
       
   606     memberGroupList = new MemberGroupList;
       
   607     for (i=0;i<count;i++)
       
   608     {
       
   609       MemberGroup *mg = new MemberGroup;
       
   610       mg->unmarshal(s);
       
   611       memberGroupList->append(mg);
       
   612     }
       
   613   }
       
   614 }
       
   615 
       
   616 //--------------------------------------------------------------------------
       
   617 
       
   618 int MemberSDict::compareItems(GCI item1, GCI item2)
       
   619 {
       
   620   MemberDef *c1=(MemberDef *)item1;
       
   621   MemberDef *c2=(MemberDef *)item2;
       
   622   return stricmp(c1->name(),c2->name());
       
   623 }
       
   624