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 "entry.h"
30 #include "md5.h"
31
MemberGroup(const Definition * container,int id,const QCString & hdr,const QCString & d,const QCString & docFile,int docLine,MemberListContainer con)32 MemberGroup::MemberGroup(const Definition *container,int id,const QCString &hdr,
33 const QCString &d,const QCString &docFile,int docLine,
34 MemberListContainer con)
35 : m_container(container),
36 memberList(std::make_unique<MemberList>(MemberListType_memberGroup,con)),
37 grpId(id), grpHeader(hdr), doc(d), m_docFile(docFile), m_docLine(docLine)
38 {
39 //printf("New member group id=%d header=%s desc=%s\n",id,hdr,d);
40 memberList->setNeedsSorting(Config_getBool(SORT_BRIEF_DOCS)); // detailed sections are already sorted elsewhere.
41 //printf("Member group docs='%s'\n",qPrint(doc));
42 }
43
~MemberGroup()44 MemberGroup::~MemberGroup()
45 {
46 }
47
insertMember(const MemberDef * md)48 void MemberGroup::insertMember(const MemberDef *md)
49 {
50 //printf("MemberGroup::insertMember memberList=%p count=%d"
51 // " member section list: %p: md=%p:%s\n",
52 // memberList->first() ? memberList->first()->getSectionList() : 0,
53 // memberList->count(),
54 // md->getSectionList(),
55 // md,qPrint(md->name()));
56
57 const MemberDef *firstMd = memberList->empty() ? 0 : memberList->front();
58 if (inSameSection && firstMd &&
59 firstMd->getSectionList(m_container)!=md->getSectionList(m_container))
60 {
61 inSameSection=FALSE;
62 }
63 else if (inDeclSection==0)
64 {
65 inDeclSection = const_cast<MemberList*>(md->getSectionList(m_container));
66 //printf("inDeclSection=%p type=%d\n",inDeclSection,inDeclSection->listType());
67 }
68 memberList->push_back(md);
69
70 // copy the group of the first member in the memberGroup
71 GroupDef *gd;
72 if (firstMd && !firstMd->isAlias() && (gd=const_cast<GroupDef*>(firstMd->getGroupDef())))
73 {
74 MemberDefMutable *mdm = toMemberDefMutable(md);
75 if (mdm)
76 {
77 mdm->setGroupDef(gd, firstMd->getGroupPri(),
78 firstMd->getGroupFileName(),
79 firstMd->getGroupStartLine(),
80 firstMd->getGroupHasDocs());
81 }
82 gd->insertMember(md);
83 }
84 }
85
86
setAnchors()87 void MemberGroup::setAnchors()
88 {
89 memberList->setAnchors();
90 }
91
writeDeclarations(OutputList & ol,const ClassDef * cd,const NamespaceDef * nd,const FileDef * fd,const GroupDef * gd,bool showInline) const92 void MemberGroup::writeDeclarations(OutputList &ol,
93 const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
94 bool showInline) const
95 {
96 //printf("MemberGroup::writeDeclarations() %s\n",qPrint(grpHeader));
97 QCString ldoc = doc;
98 if (!ldoc.isEmpty()) ldoc.prepend("<a name=\""+anchor()+"\" id=\""+anchor()+"\"></a>");
99 memberList->writeDeclarations(ol,cd,nd,fd,gd,grpHeader,ldoc,FALSE,showInline);
100 }
101
writePlainDeclarations(OutputList & ol,bool inGroup,const ClassDef * cd,const NamespaceDef * nd,const FileDef * fd,const GroupDef * gd,int indentLevel,const ClassDef * inheritedFrom,const QCString & inheritId) const102 void MemberGroup::writePlainDeclarations(OutputList &ol,bool inGroup,
103 const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
104 int indentLevel,const ClassDef *inheritedFrom,const QCString &inheritId
105 ) const
106 {
107 //printf("MemberGroup::writePlainDeclarations() memberList->count()=%d\n",memberList->count());
108 memberList->writePlainDeclarations(ol,inGroup,cd,nd,fd,gd,indentLevel,inheritedFrom,inheritId);
109 }
110
writeDocumentation(OutputList & ol,const QCString & scopeName,const Definition * container,bool showEnumValues,bool showInline) const111 void MemberGroup::writeDocumentation(OutputList &ol,const QCString &scopeName,
112 const Definition *container,bool showEnumValues,bool showInline) const
113 {
114 //printf("MemberGroup::writeDocumentation() %s\n",qPrint(grpHeader));
115 memberList->writeDocumentation(ol,scopeName,container,QCString(),showEnumValues,showInline);
116 }
117
writeDocumentationPage(OutputList & ol,const QCString & scopeName,const DefinitionMutable * container) const118 void MemberGroup::writeDocumentationPage(OutputList &ol,const QCString &scopeName,
119 const DefinitionMutable *container) const
120 {
121 memberList->writeDocumentationPage(ol,scopeName,container);
122 }
123
setAnonymousEnumType()124 void MemberGroup::setAnonymousEnumType()
125 {
126 memberList->setAnonymousEnumType();
127 }
128
addGroupedInheritedMembers(OutputList & ol,const ClassDef * cd,MemberListType lt,const ClassDef * inheritedFrom,const QCString & inheritId) const129 void MemberGroup::addGroupedInheritedMembers(OutputList &ol,const ClassDef *cd,
130 MemberListType lt,
131 const ClassDef *inheritedFrom,const QCString &inheritId) const
132 {
133 //printf("** addGroupedInheritedMembers()\n");
134 for (const auto &md : *memberList)
135 {
136 //printf("matching %d == %d\n",lt,md->getSectionList()->listType());
137 const MemberList *ml = md->getSectionList(m_container);
138 if (ml && lt==ml->listType())
139 {
140 MemberList mml(lt,MemberListContainer::Class);
141 mml.push_back(md);
142 mml.countDecMembers();
143 mml.writePlainDeclarations(ol,false,cd,0,0,0,0,inheritedFrom,inheritId);
144 }
145 }
146 }
147
countGroupedInheritedMembers(MemberListType lt)148 int MemberGroup::countGroupedInheritedMembers(MemberListType lt)
149 {
150 //printf("** countGroupedInheritedMembers()\n");
151 int count=0;
152 for (const auto &md : *memberList)
153 {
154 //printf("matching %d == %d\n",lt,md->getSectionList()->listType());
155 const MemberList *ml = md->getSectionList(m_container);
156 if (ml && lt==ml->listType())
157 {
158 count++;
159 }
160 }
161 return count;
162 }
163
164
165 /*! Add this group as a subsection of the declaration section, instead
166 * of rendering it in its own section
167 */
addToDeclarationSection()168 void MemberGroup::addToDeclarationSection()
169 {
170 if (inDeclSection)
171 {
172 //printf("Adding group %p to list %p (type=%d) memberList=%p\n",this,
173 // inDeclSection,inDeclSection->listType(),memberList);
174 inDeclSection->addMemberGroup(this);
175 }
176 }
177
countDecMembers()178 void MemberGroup::countDecMembers()
179 {
180 memberList->countDecMembers();
181 }
182
countDocMembers()183 void MemberGroup::countDocMembers()
184 {
185 memberList->countDocMembers();
186 }
187
container() const188 const Definition *MemberGroup::container() const
189 {
190 return m_container;
191 }
192
countInheritableMembers(const ClassDef * inheritedFrom) const193 int MemberGroup::countInheritableMembers(const ClassDef *inheritedFrom) const
194 {
195 return memberList->countInheritableMembers(inheritedFrom);
196 }
197
198
distributeMemberGroupDocumentation()199 void MemberGroup::distributeMemberGroupDocumentation()
200 {
201 //printf("MemberGroup::distributeMemberGroupDocumentation() %s\n",qPrint(grpHeader));
202 const MemberDef *md = 0;
203 for (const auto &smd : *memberList)
204 {
205 //printf("checking md=%s\n",qPrint(md->name()));
206 // find the first member of the group with documentation
207 if (!smd->documentation().isEmpty() ||
208 !smd->briefDescription().isEmpty() ||
209 !smd->inbodyDocumentation().isEmpty()
210 )
211 {
212 //printf("found it!\n");
213 md = smd;
214 break;
215 }
216 }
217 if (md) // distribute docs of md to other members of the list
218 {
219 //printf("Member %s has documentation!\n",qPrint(md->name()));
220 for (const auto &iomd : *memberList)
221 {
222 MemberDefMutable *omd = toMemberDefMutable(iomd);
223 if (omd && md!=omd && omd->documentation().isEmpty() &&
224 omd->briefDescription().isEmpty() &&
225 omd->inbodyDocumentation().isEmpty()
226 )
227 {
228 //printf("Copying documentation to member %s\n",qPrint(omd->name()));
229 omd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
230 omd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
231 omd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
232 }
233 }
234 }
235 }
236
237
numDecMembers() const238 int MemberGroup::numDecMembers() const
239 {
240 return memberList->numDecMembers();
241 }
242
numDecEnumValues() const243 int MemberGroup::numDecEnumValues() const
244 {
245 return memberList->numDecEnumValues();
246 }
247
numDocMembers() const248 int MemberGroup::numDocMembers() const
249 {
250 return memberList->numDocMembers();
251 }
252
numDocEnumValues() const253 int MemberGroup::numDocEnumValues() const
254 {
255 return memberList->numDocEnumValues();
256 }
257
anchor() const258 QCString MemberGroup::anchor() const
259 {
260 uchar md5_sig[16];
261 char sigStr[33];
262 QCString locHeader = grpHeader;
263 if (locHeader.isEmpty()) locHeader="[NOHEADER]";
264 MD5Buffer((const unsigned char *)locHeader.data(),locHeader.length(),md5_sig);
265 MD5SigToString(md5_sig,sigStr);
266 return QCString("amgrp")+sigStr;
267 }
268
addListReferences(Definition * def)269 void MemberGroup::addListReferences(Definition *def)
270 {
271 memberList->addListReferences(def);
272 if (def)
273 {
274 QCString name = def->getOutputFileBase()+"#"+anchor();
275 addRefItem(m_xrefListItems,
276 name,
277 theTranslator->trGroup(TRUE,TRUE),
278 name,
279 grpHeader,QCString(),def);
280 }
281 }
282
findSectionsInDocumentation(const Definition * d)283 void MemberGroup::findSectionsInDocumentation(const Definition *d)
284 {
285 docFindSections(doc,d,m_docFile);
286 memberList->findSectionsInDocumentation(d);
287 }
288
setRefItems(const RefItemVector & sli)289 void MemberGroup::setRefItems(const RefItemVector &sli)
290 {
291 m_xrefListItems.insert(m_xrefListItems.end(), sli.cbegin(), sli.cend());
292 }
293
writeTagFile(TextStream & tagFile)294 void MemberGroup::writeTagFile(TextStream &tagFile)
295 {
296 memberList->writeTagFile(tagFile);
297 }
298
299 //--------------------------------------------------------------------------
300
setRefItems(const RefItemVector & sli)301 void MemberGroupInfo::setRefItems(const RefItemVector &sli)
302 {
303 m_sli.insert(m_sli.end(), sli.cbegin(), sli.cend());
304 }
305