Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / membergroup.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  * Copyright (C) 1997-2015 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 "membergroup.h"
19 #include "memberlist.h"
20 #include "outputlist.h"
21 #include "util.h"
22 #include "classdef.h"
23 #include "namespacedef.h"
24 #include "filedef.h"
25 #include "language.h"
26 #include "groupdef.h"
27 #include "doxygen.h"
28 #include "docparser.h"
29 #include "marshal.h"
30 #include "entry.h"
31 #include "md5.h"
32
33 //static QCString idToName(int id)
34 //{
35 //  QCString result;
36 //  result.sprintf("mgroup_%d",id);
37 //  return result;
38 //}
39
40 MemberGroup::MemberGroup()
41 {
42 }
43
44 MemberGroup::MemberGroup(Definition *parent,
45       int id,const char *hdr,const char *d,const char *docFile,int docLine)
46 {
47   //printf("New member group id=%d header=%s desc=%s\n",id,hdr,d);
48   memberList      = new MemberList(MemberListType_memberGroup);
49   grpId           = id;
50   grpHeader       = hdr;
51   doc             = d;
52   scope           = 0;
53   inSameSection   = TRUE;
54   inDeclSection   = 0;
55   m_numDecMembers = -1;
56   m_numDocMembers = -1;
57   m_parent        = parent;
58   m_docFile       = docFile;
59   m_docLine       = docLine;
60   m_xrefListItems = 0;
61   //printf("Member group docs=`%s'\n",doc.data());
62 }
63
64 MemberGroup::~MemberGroup()
65 {
66   delete memberList;
67 }
68
69 void MemberGroup::insertMember(MemberDef *md)
70 {
71   //printf("MemberGroup::insertMember m_parent=%s memberList=%p count=%d"
72   //       " member section list: %p: md=%p:%s\n",
73   //       m_parent ? m_parent->name().data() : "<null>",
74   //       memberList->first() ? memberList->first()->getSectionList(m_parent) : 0,
75   //       memberList->count(),
76   //       md->getSectionList(m_parent),
77   //       md,md->name().data());
78
79   MemberDef *firstMd = memberList->getFirst();
80   if (inSameSection && firstMd &&
81       firstMd->getSectionList(m_parent)!=md->getSectionList(m_parent))
82   {
83     inSameSection=FALSE;
84   }
85   else if (inDeclSection==0)
86   {
87     inDeclSection = md->getSectionList(m_parent);
88     //printf("inDeclSection=%p type=%d\n",inDeclSection,inDeclSection->listType());
89   }
90   memberList->append(md);
91
92   // copy the group of the first member in the memberGroup
93   GroupDef *gd;
94   if (firstMd && (gd=firstMd->getGroupDef()))
95   {
96     md->setGroupDef(gd, firstMd->getGroupPri(), 
97                     firstMd->getGroupFileName(), firstMd->getGroupStartLine(), 
98                     firstMd->getGroupHasDocs());
99     gd->insertMember(md);
100   }
101 }
102
103
104 void MemberGroup::setAnchors()
105 {
106   ::setAnchors(memberList);
107 }
108
109 void MemberGroup::writeDeclarations(OutputList &ol,
110                ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
111                bool showInline)
112 {
113   //printf("MemberGroup::writeDeclarations() %s\n",grpHeader.data());
114   QCString ldoc = doc;
115   if (!ldoc.isEmpty()) ldoc.prepend("<a name=\""+anchor()+"\" id=\""+anchor()+"\"></a>");
116   memberList->writeDeclarations(ol,cd,nd,fd,gd,grpHeader,ldoc,FALSE,showInline);
117 }
118
119 void MemberGroup::writePlainDeclarations(OutputList &ol,
120                ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
121                ClassDef *inheritedFrom,const char *inheritId
122               )
123 {
124   //printf("MemberGroup::writePlainDeclarations() memberList->count()=%d\n",memberList->count());
125   memberList->writePlainDeclarations(ol,cd,nd,fd,gd,inheritedFrom,inheritId);
126 }
127
128 void MemberGroup::writeDocumentation(OutputList &ol,const char *scopeName,
129                Definition *container,bool showEnumValues,bool showInline)
130 {
131   memberList->writeDocumentation(ol,scopeName,container,0,showEnumValues,showInline);
132 }
133
134 void MemberGroup::writeDocumentationPage(OutputList &ol,const char *scopeName,
135                Definition *container)
136 {
137   memberList->writeDocumentationPage(ol,scopeName,container);
138 }
139
140 void MemberGroup::addGroupedInheritedMembers(OutputList &ol,ClassDef *cd,
141                MemberListType lt,
142                ClassDef *inheritedFrom,const QCString &inheritId)
143 {
144   //printf("** addGroupedInheritedMembers()\n");
145   MemberListIterator li(*memberList);
146   MemberDef *md;
147   for (li.toFirst();(md=li.current());++li)
148   {
149     //printf("matching %d == %d\n",lt,md->getSectionList(m_parent)->listType());
150     MemberList *ml = md->getSectionList(m_parent);
151     if (ml && lt==ml->listType())
152     {
153       MemberList ml(lt);
154       ml.append(md);
155       ml.writePlainDeclarations(ol,cd,0,0,0,inheritedFrom,inheritId);
156     }
157   }
158 }
159
160 int MemberGroup::countGroupedInheritedMembers(MemberListType lt)
161 {
162   //printf("** countGroupedInheritedMembers()\n");
163   int count=0;
164   MemberListIterator li(*memberList);
165   MemberDef *md;
166   for (li.toFirst();(md=li.current());++li)
167   {
168     //printf("matching %d == %d\n",lt,md->getSectionList(m_parent)->listType());
169     MemberList *ml = md->getSectionList(m_parent);
170     if (ml && lt==ml->listType())
171     {
172       count++;
173     }
174   }
175   return count;
176 }
177
178
179 /*! Add this group as a subsection of the declaration section, instead
180  *  of rendering it in its own section
181  */
182 void MemberGroup::addToDeclarationSection()
183 {
184   if (inDeclSection)
185   {
186     //printf("Adding group %p to list %p (type=%d)\n",this,
187     //                              inDeclSection,inDeclSection->listType());
188     inDeclSection->addMemberGroup(this);
189   }
190 }
191
192 int MemberGroup::countDecMembers(GroupDef *gd)
193 {
194   if (m_numDecMembers==-1) /* number of member not cached */
195   {
196     memberList->countDecMembers(gd);
197     m_numDecMembers = memberList->numDecMembers();
198   }
199   return m_numDecMembers;
200 }
201
202 int MemberGroup::countDocMembers()
203 {
204   if (m_numDocMembers==-1)
205   {
206     memberList->countDocMembers();
207     m_numDocMembers = memberList->numDocMembers();
208   }
209   return m_numDocMembers;
210 }
211
212 int MemberGroup::countInheritableMembers(ClassDef *inheritedFrom) const
213 {
214   return memberList->countInheritableMembers(inheritedFrom);
215 }
216
217
218 void MemberGroup::distributeMemberGroupDocumentation()
219 {
220   //printf("MemberGroup::distributeMemberGroupDocumentation() %s\n",grpHeader.data());
221   MemberListIterator li(*memberList);
222   MemberDef *md;
223   for (li.toFirst();(md=li.current());++li)
224   {
225     //printf("checking md=%s\n",md->name().data());
226     // find the first member of the group with documentation
227     if (!md->documentation().isEmpty()       ||
228         !md->briefDescription().isEmpty()    ||
229         !md->inbodyDocumentation().isEmpty()
230        )
231     {
232       //printf("found it!\n");
233       break;
234     }
235   }
236   if (md) // distribute docs of md to other members of the list
237   {
238     //printf("Member %s has documentation!\n",md->name().data());
239     MemberDef *omd;
240     for (li.toFirst();(omd=li.current());++li)
241     {
242       if (md!=omd && omd->documentation().isEmpty() &&
243                      omd->briefDescription().isEmpty() &&
244                      omd->inbodyDocumentation().isEmpty()
245          )
246       {
247         //printf("Copying documentation to member %s\n",omd->name().data());
248         omd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
249         omd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
250         omd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
251       }
252     }
253   }
254 }
255
256 int MemberGroup::varCount() const
257 {
258   return memberList->varCount();
259 }
260
261 int MemberGroup::funcCount() const      
262
263   return memberList->funcCount(); 
264 }
265
266 int MemberGroup::enumCount() const      
267
268   return memberList->enumCount(); 
269 }
270
271 int MemberGroup::enumValueCount() const 
272
273   return memberList->enumValueCount(); 
274 }
275
276 int MemberGroup::typedefCount() const   
277
278   return memberList->typedefCount(); 
279 }
280
281 int MemberGroup::sequenceCount() const   
282
283   return memberList->sequenceCount(); 
284 }
285
286 int MemberGroup::dictionaryCount() const   
287
288   return memberList->dictionaryCount(); 
289 }
290
291 int MemberGroup::protoCount() const     
292
293   return memberList->protoCount(); 
294 }
295
296 int MemberGroup::defineCount() const    
297
298   return memberList->defineCount(); 
299 }
300
301 int MemberGroup::friendCount() const    
302
303   return memberList->friendCount(); 
304 }
305
306 int MemberGroup::numDecMembers() const  
307
308   return memberList->numDecMembers(); 
309 }
310
311 int MemberGroup::numDocMembers() const  
312
313   return memberList->numDocMembers(); 
314 }
315
316 void MemberGroup::setInGroup(bool b)
317 {
318   memberList->setInGroup(b);
319 }
320
321 QCString MemberGroup::anchor() const
322 {
323   uchar md5_sig[16];
324   QCString sigStr(33);
325   QCString locHeader = grpHeader;
326   if (locHeader.isEmpty()) locHeader="[NOHEADER]";
327   MD5Buffer((const unsigned char *)locHeader.data(),locHeader.length(),md5_sig);
328   MD5SigToString(md5_sig,sigStr.rawData(),33);
329   return "amgrp"+sigStr;
330 }
331
332 void MemberGroup::addListReferences(Definition *def)
333 {
334   memberList->addListReferences(def);
335   if (m_xrefListItems && def)
336   {
337     QCString name = def->getOutputFileBase()+"#"+anchor();
338     addRefItem(m_xrefListItems,
339         name,
340         theTranslator->trGroup(TRUE,TRUE),
341         name,
342         grpHeader,0,def);
343   }
344 }
345
346 void MemberGroup::findSectionsInDocumentation()
347 {
348   docFindSections(doc,0,this,m_docFile);
349   memberList->findSectionsInDocumentation();
350 }
351
352 void MemberGroup::marshal(StorageIntf *s)
353 {
354   marshalMemberList(s,memberList);
355   marshalObjPointer(s,inDeclSection); // reference only
356   marshalInt(s,grpId);
357   marshalQCString(s,grpHeader);
358   marshalQCString(s,fileName);
359   marshalObjPointer(s,scope);
360   marshalQCString(s,doc);
361   marshalBool(s,inSameSection);
362   marshalInt(s,m_numDecMembers);
363   marshalInt(s,m_numDocMembers);
364   marshalObjPointer(s,m_parent);
365   marshalQCString(s,m_docFile);
366   marshalItemInfoList (Doxygen::symbolStorage,m_xrefListItems);
367 }
368
369 void MemberGroup::unmarshal(StorageIntf *s)
370 {
371   memberList      = unmarshalMemberList(s);
372   inDeclSection   = (MemberList *)unmarshalObjPointer(s); 
373   grpId           = unmarshalInt(s);
374   grpHeader       = unmarshalQCString(s);
375   fileName        = unmarshalQCString(s);
376   scope           = (Definition *)unmarshalObjPointer(s);
377   doc             = unmarshalQCString(s);
378   inSameSection   = unmarshalBool(s);
379   m_numDecMembers = unmarshalInt(s);
380   m_numDocMembers = unmarshalInt(s);
381   m_parent        = (Definition *)unmarshalObjPointer(s);
382   m_docFile       = unmarshalQCString(s);
383   m_xrefListItems = unmarshalItemInfoList (Doxygen::symbolStorage);
384 }
385
386 void MemberGroup::setRefItems(const QList<ListItemInfo> *sli)
387 {
388   if (sli)
389   {
390     // deep copy the list
391     if (m_xrefListItems==0) 
392     {
393       m_xrefListItems=new QList<ListItemInfo>;
394       m_xrefListItems->setAutoDelete(TRUE);
395     }
396     QListIterator<ListItemInfo> slii(*sli);
397     ListItemInfo *lii;
398     for (slii.toFirst();(lii=slii.current());++slii)
399     {
400       m_xrefListItems->append(new ListItemInfo(*lii));
401     } 
402   }
403 }
404
405 void MemberGroup::writeTagFile(FTextStream &tagFile)
406 {
407   memberList->writeTagFile(tagFile);
408 }
409
410 //--------------------------------------------------------------------------
411
412 void MemberGroupInfo::setRefItems(const QList<ListItemInfo> *sli)
413 {
414   if (!sli) return;
415   if (m_sli==0)
416   {
417     m_sli = new QList<ListItemInfo>;
418     m_sli->setAutoDelete(TRUE);
419   }
420   QListIterator<ListItemInfo> slii(*sli);
421   ListItemInfo *ili;
422   for (slii.toFirst();(ili=slii.current());++slii)
423   {
424     m_sli->append(new ListItemInfo(*ili));
425   }
426 }