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