Doxygen
Loading...
Searching...
No Matches
docgroup.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2019 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <atomic>
17#include "doxygen.h"
18#include "util.h"
19#include "entry.h"
20#include "message.h"
21#include "docgroup.h"
22
23static std::atomic_int g_groupId;
24static std::mutex g_memberGroupInfoMapMutex;
25
26void DocGroup::enterFile(const QCString &fileName,int)
27{
28 m_openCount = 0;
29 m_autoGroupStack.clear();
31 m_memberGroupDocs.clear();
33 m_compoundName=fileName;
34}
35
36void DocGroup::leaveFile(const QCString &fileName,int line)
37{
38 //if (m_memberGroupId!=DOX_NOGROUP)
39 //{
40 // warn(fileName,line,"end of file while inside a member group");
41 //}
44 m_memberGroupDocs.clear();
45 if (!m_autoGroupStack.empty())
46 {
47 warn(fileName,line,"end of file while inside a group");
48 }
49 else if (m_openCount > 0) // < 0 is already handled on close call
50 {
51 warn(fileName,line,"end of file with unbalanced grouping commands");
52 }
53}
54
55void DocGroup::enterCompound(const QCString &fileName,int line,const QCString &name)
56{
58 {
59 warn(fileName,line,"try to put compound %s inside a member group",qPrint(name));
60 }
63 m_memberGroupDocs.clear();
64 m_compoundName = name;
65 int i = m_compoundName.find('(');
66 if (i!=-1)
67 {
68 m_compoundName=m_compoundName.left(i); // strip category (Obj-C)
69 }
70 if (m_compoundName.isEmpty())
71 {
72 m_compoundName=fileName;
73 }
74 //printf("groupEnterCompound(%s)\n",qPrint(name));
75}
76
77void DocGroup::leaveCompound(const QCString &,int,const QCString &/* name */)
78{
79 //printf("groupLeaveCompound(%s)\n",qPrint(name));
80 //if (m_memberGroupId!=DOX_NOGROUP)
81 //{
82 // warn(fileName,line,"end of compound %s while inside a member group\n",qPrint(name));
83 //}
86 m_memberGroupDocs.clear();
87 m_compoundName.clear();
88}
89
91{
92 std::lock_guard<std::mutex> lock(g_memberGroupInfoMapMutex);
93 //printf("findExistingGroup %s:%s\n",qPrint(info->header),qPrint(info->compoundName));
94 for (const auto &[groupId,groupInfo] : Doxygen::memberGroupInfoMap)
95 {
96 if (m_compoundName==groupInfo->compoundName && // same file or scope
97 !groupInfo->header.isEmpty() && // not a nameless group
98 qstricmp(groupInfo->header,info->header)==0 // same header name
99 )
100 {
101 //printf("Found it!\n");
102 return groupId; // put the item in this group
103 }
104 }
105 return ++g_groupId; // start new group
106}
107
108void DocGroup::open(Entry *e,const QCString &,int, bool implicit)
109{
110 if (!implicit) m_openCount++;
111 //printf("==> openGroup(name=%s,sec=%x) m_autoGroupStack=%zu\n",
112 // qPrint(e->name),e->section,m_autoGroupStack.size());
113 if (e->section.isGroupDoc()) // auto group
114 {
115 m_autoGroupStack.emplace_back(e->name,e->groupingPri());
116 }
117 else // start of a member group
118 {
119 //printf(" membergroup id=%d %s\n",m_memberGroupId,qPrint(m_memberGroupHeader));
120 if (m_memberGroupId==DOX_NOGROUP) // no group started yet
121 {
122 auto info = std::make_unique<MemberGroupInfo>();
123 info->header = m_memberGroupHeader.stripWhiteSpace();
124 info->compoundName = m_compoundName;
126 {
127 std::lock_guard<std::mutex> lock(g_memberGroupInfoMapMutex);
130 {
131 //printf(" use membergroup %d\n",m_memberGroupId);
132 Doxygen::memberGroupInfoMap.emplace(m_memberGroupId,std::move(info));
133 }
134 }
137 }
138 }
139}
140
141void DocGroup::close(Entry *e,const QCString &fileName,int line,bool foundInline,bool implicit)
142{
143 if (!implicit)
144 {
145 if (m_openCount < 1)
146 {
147 warn(fileName,line,"unbalanced grouping commands");
148 }
149 else
150 {
151 m_openCount--;
152 }
153 }
154 //printf("==> closeGroup(name=%s,sec=%x,file=%s,line=%d) m_autoGroupStack=%zu\n",
155 // qPrint(e->name),e->section,qPrint(fileName),line,m_autoGroupStack.size());
156 if (m_memberGroupId!=DOX_NOGROUP) // end of member group
157 {
158 {
159 std::lock_guard<std::mutex> lock(g_memberGroupInfoMapMutex);
161 if (it!=Doxygen::memberGroupInfoMap.end()) // known group
162 {
163 auto &info = it->second;
164 info->doc = m_memberGroupDocs;
165 //info->docFile = fileName;
166 //info->docLine = line;
167 }
168 }
170 m_memberGroupRelates.clear();
171 m_memberGroupDocs.clear();
172 if (!foundInline)
173 {
175 e->relates="";
176 }
177 //printf("new group id=%d\n",m_memberGroupId);
178 }
179 else if (!m_autoGroupStack.empty()) // end of auto group
180 {
181 Grouping grp = m_autoGroupStack.back();
182 m_autoGroupStack.pop_back();
183 // see bug577005: we should not remove the last group for e
184 if (!foundInline && !e->groups.empty()) e->groups.pop_back();
185 //printf("Removing %s e=%p\n",qPrint(grp->groupname),e);
186 if (!foundInline) initGroupInfo(e);
187 }
188}
189
191{
192 //printf("==> initGroup(id=%d,related=%s,e=%p,#stack=%zu)\n",m_memberGroupId,
193 // qPrint(m_memberGroupRelates),(void*)e,m_autoGroupStack.size());
196 if (!m_autoGroupStack.empty())
197 {
198 //printf("Appending group %s to %s: count=%zu entry=%p\n",
199 // qPrint(m_autoGroupStack.back().groupname),
200 // qPrint(e->name),e->groups.size(),(void*)e);
201 e->groups.emplace_back(m_autoGroupStack.back());
202 }
203}
204
206{
207 if (e->section.isMemberGrp())
208 {
211 if (!m_memberGroupDocs.isEmpty() && !e->doc.isEmpty())
212 {
213 m_memberGroupDocs+="\n\n";
214 }
216 {
217 std::lock_guard<std::mutex> lock(g_memberGroupInfoMapMutex);
220 {
221 auto &info = it->second;
222 info->doc = m_memberGroupDocs;
223 info->docFile = e->docFile;
224 info->docLine = e->docLine;
225 info->setRefItems(e->sli);
226 }
227 }
228 e->doc.clear();
229 e->brief.clear();
230 }
231}
232
234{
236}
237
239{
240 m_memberGroupHeader.clear();
241}
242
243void DocGroup::appendHeader(const char text)
244{
245 m_memberGroupHeader += text;
246}
void leaveCompound(const QCString &, int, const QCString &)
Definition docgroup.cpp:77
void leaveFile(const QCString &fileName, int line)
Definition docgroup.cpp:36
int m_openCount
Definition docgroup.h:44
void initGroupInfo(Entry *e)
Definition docgroup.cpp:190
int m_memberGroupId
Definition docgroup.h:46
int findExistingGroup(const MemberGroupInfo *info)
Definition docgroup.cpp:90
void close(Entry *e, const QCString &fileName, int line, bool foundInline, bool implicit=false)
Definition docgroup.cpp:141
QCString m_memberGroupHeader
Definition docgroup.h:45
QCString m_memberGroupRelates
Definition docgroup.h:47
void addDocs(Entry *e)
Definition docgroup.cpp:205
void appendHeader(const char)
Definition docgroup.cpp:243
void open(Entry *e, const QCString &, int, bool implicit=false)
Definition docgroup.cpp:108
std::vector< Grouping > m_autoGroupStack
Definition docgroup.h:49
bool isEmpty() const
Definition docgroup.cpp:233
QCString m_memberGroupDocs
Definition docgroup.h:48
void clearHeader()
Definition docgroup.cpp:238
QCString m_compoundName
Definition docgroup.h:50
void enterCompound(const QCString &fileName, int line, const QCString &name)
Definition docgroup.cpp:55
void enterFile(const QCString &fileName, int)
Definition docgroup.cpp:26
static MemberGroupInfoMap memberGroupInfoMap
Definition doxygen.h:118
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:116
int docLine
line number at which the documentation was found
Definition entry.h:201
QCString relates
related class (doc block)
Definition entry.h:209
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:221
QCString name
member name
Definition entry.h:174
Grouping::GroupPri_t groupingPri() const
Definition entry.h:248
EntryType section
entry type (see Sections);
Definition entry.h:172
int mGrpId
member group id
Definition entry.h:219
QCString doc
documentation block (partly parsed)
Definition entry.h:200
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:226
QCString docFile
file in which the documentation was found
Definition entry.h:202
QCString brief
brief description (doc block)
Definition entry.h:203
This is an alternative implementation of QCString.
Definition qcstring.h:101
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
void clear()
Definition qcstring.h:169
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
static std::atomic_int g_groupId
Definition docgroup.cpp:23
static std::mutex g_memberGroupInfoMapMutex
Definition docgroup.cpp:24
#define DOX_NOGROUP
Definition membergroup.h:26
#define warn(file, line, fmt,...)
Definition message.h:59
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:442
const char * qPrint(const char *s)
Definition qcstring.h:672
Grouping info.
Definition types.h:65
Data collected for a member group.
QCString stripLeadingAndTrailingEmptyLines(const QCString &s, int &docLine)
Special version of QCString::stripWhiteSpace() that only strips completely blank lines.
Definition util.cpp:5368
A bunch of utility functions.