Doxygen
Loading...
Searching...
No Matches
outputlist.cpp
Go to the documentation of this file.
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/*! \file
19 * This class represents a list of output generators that work in "parallel".
20 * The class only knows about the abstract base class OutputGenerators.
21 * All output is produced by calling a method of this class, which forwards
22 * the call to all output generators.
23 */
24
25// own header
26#include "outputlist.h"
27
28// standard includes
29#include <atomic>
30
31// other includes
32#include "docparser.h"
33#include "doxygen.h"
34#include "message.h"
35
37
43
49
51{
52 if (this!=&ol)
53 {
54 m_id = ol.m_id;
57 }
58 return *this;
59}
60
62{
64 for (auto &e : m_outputGenList)
65 {
66 e.intf->addCodeGen(m_codeGenList);
67 }
69}
70
72{
73 m_id = ++g_outId;
74}
75
77{
78 for (const auto &e : m_outputGenList)
79 {
80 //printf("output %d isEnabled=%d\n",og->type(),og->isEnabled());
81 m_codeGenList.setEnabledFiltered(e.intf->type(),e.enabled);
82 }
83}
84
86{
87 //printf("disableAllBut(%d)\n",o);
88 for (auto &e : m_outputGenList)
89 {
90 if (e.intf->type()!=o) e.setEnabled(false);
91 }
93}
94
96{
97 //printf("enableAll()\n");
98 for (auto &e : m_outputGenList)
99 {
100 e.setEnabled(true);
101 }
102 syncEnabled();
103}
104
106{
107 //printf("enableAll()\n");
108 for (auto &e : m_outputGenList)
109 {
110 e.setEnabled(false);
111 }
112 syncEnabled();
113}
114
116{
117 //printf("disable(%d)\n",o);
118 for (auto &e : m_outputGenList)
119 {
120 if (e.intf->type()==o) e.setEnabled(false);
121 }
122 syncEnabled();
123}
124
126{
127 //printf("enable(%d)\n",o);
128 for (auto &e : m_outputGenList)
129 {
130 if (e.intf->type()==o) e.setEnabled(true);
131 }
132 syncEnabled();
133}
134
136{
137 for (const auto &e : m_outputGenList)
138 {
139 if (e.intf->type()==o) { return e.enabled; }
140 }
141 return false;
142}
143
145{
146 //printf("pushGeneratorState()\n");
147 for (auto &e : m_outputGenList)
148 {
149 e.enabledStack.push(e.enabled);
150 }
151 syncEnabled();
152}
153
155{
156 //printf("popGeneratorState()\n");
157 for (auto &e : m_outputGenList)
158 {
159 if (!e.enabledStack.empty())
160 {
161 e.enabled = e.enabledStack.top();
162 e.enabledStack.pop();
163 }
164 }
165 syncEnabled();
166}
167
168void OutputList::generateDoc(const DString &fileName,int startLine,
169 const Definition *ctx,const MemberDef * md,
170 const DString &docStr,const DocOptions &options)
171{
172 if (docStr.empty()) return;
173
174 auto count=std::count_if(m_outputGenList.begin(),m_outputGenList.end(),
175 [](const auto &e) { return e.enabled; });
176 // we want to validate irrespective of the number of output formats
177 // specified as:
178 // - when only XML format there should be warnings as well (XML has its own write routines)
179 // - no formats there should be warnings as well
180 auto parser { createDocParser() };
181 auto ast { validatingParseDoc(*parser.get(),
182 fileName,
183 startLine,
184 ctx,
185 md,
186 docStr,
187 options)
188 };
189 if (ast && count>0) writeDoc(ast.get(),ctx,md,options.sectionLevel());
190}
191
192void OutputList::startFile(const DString &name,bool isSource,const DString &manName,const DString &title, int hierarchyLevel)
193{
194 newId();
196 foreach(&OutputGenIntf::startFile,name,isSource,manName,title,m_id,hierarchyLevel);
197}
198
199void OutputList::parseText(const DString &textStr)
200{
201
202 auto count=std::count_if(m_outputGenList.begin(),m_outputGenList.end(),
203 [](const auto &e) { return e.enabled; });
204
205 // we want to validate irrespective of the number of output formats
206 // specified as:
207 // - when only XML format there should be warnings as well (XML has its own write routines)
208 // - no formats there should be warnings as well
209 auto parser { createDocParser() };
210 auto ast { validatingParseText(*parser.get(), textStr) };
211
212 if (ast && count>0) writeDoc(ast.get(),nullptr,nullptr);
213}
214
215//------------------------------------------------------------------------
216// TextGeneratorOLImpl implementation
217//------------------------------------------------------------------------
218
222
223void TextGeneratorOLImpl::writeString(std::string_view s,bool keepSpaces) const
224{
225 if (s.empty()) return;
226 //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces);
227 if (keepSpaces)
228 {
229 for (char c : s)
230 {
231 if (c == ' ')
232 {
234 }
235 else
236 {
237 m_ol.docify(std::string_view(&c, 1));
238 }
239 }
240 }
241 else
242 {
243 m_ol.docify(s);
244 }
245}
246
248{
249 m_ol.lineBreak("typebreak");
250 for (int i = 0; i < indent; ++i) m_ol.writeNonBreakableSpace(3);
251}
252
253void TextGeneratorOLImpl::writeLink(const DString &extRef,const DString &file,
254 const DString &anchor,std::string_view text
255 ) const
256{
257 //printf("TextGeneratorOlImpl::writeLink('%s')\n",text);
258 m_ol.writeObjectLink(extRef,file,anchor,text);
259}
260
261//--------------------------------------------------------------------------
262
264{
265 int orgSize = static_cast<int>(m_lineOffset.size());
266 if (orgSize<lineNr)
267 {
268 m_lineOffset.resize(lineNr);
269 for (int i=orgSize;i<lineNr;i++) // output lines can be skipped due to hidden comments so fill in the gap
270 {
271 //printf("%p: startCodeLine(%d) offset=%zu\n",(void*)this,i,m_calls.size());
272 m_lineOffset[i]=m_calls.size();
273 }
274 }
275}
276
278{
279 m_calls.emplace_back([]() { return true; },
280 [=](OutputCodeList *ol) { ol->codify(s); },
282 );
283}
284
286{
288 m_calls.emplace_back([]() { return true; },
289 [=](OutputCodeList *ol) { ol->startSpecialComment(); },
290 true
291 );
292}
293
295{
296 m_calls.emplace_back([]() { return true; },
297 [=](OutputCodeList *ol) { ol->endSpecialComment(); },
298 true
299 );
301}
302
304 const DString &ref,const DString &file,
305 const DString &anchor,const DString &name,
306 const DString &tooltip)
307{
308 m_calls.emplace_back([](){ return true; },
309 [=](OutputCodeList *ol) { ol->writeCodeLink(type,ref,file,anchor,name,tooltip); },
311 );
312}
313
314void OutputCodeRecorder::writeLineNumber(const DString &ref,const DString &file,const DString &anchor,
315 int lineNumber, bool writeLineAnchor)
316{
317 startNewLine(lineNumber);
318 m_calls.emplace_back([&]() { return m_showLineNumbers; },
319 [=](OutputCodeList *ol) { ol->writeLineNumber(ref,file,anchor,lineNumber,writeLineAnchor); },
321 );
322}
323
324void OutputCodeRecorder::writeTooltip(const DString &id, const DocLinkInfo &docInfo, const DString &decl,
325 const DString &desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo)
326{
327 m_calls.emplace_back([](){ return true; },
328 [=](OutputCodeList *ol) { ol->writeTooltip(id,docInfo,decl,desc,defInfo,declInfo); },
330 );
331}
332
334{
335 startNewLine(lineNr);
336 m_calls.emplace_back([](){ return true; },
337 [=](OutputCodeList *ol) { ol->startCodeLine(lineNr); },
339 );
340}
341
343{
344 m_calls.emplace_back([](){ return true; },
345 [=](OutputCodeList *ol) { ol->endCodeLine(); },
347 );
348}
349
351{
352 m_calls.emplace_back([]() { return true; },
353 [=](OutputCodeList *ol) { ol->startFontClass(c); },
355 );
356}
357
359{
360 m_calls.emplace_back([]() { return true; },
361 [=](OutputCodeList *ol){ ol->endFontClass(); },
363 );
364}
365
367{
368 m_calls.emplace_back([]() { return true; },
369 [=](OutputCodeList *ol){ ol->writeCodeAnchor(name); },
371 );
372}
373
377
379{
380}
381
382void OutputCodeRecorder::startFold(int lineNr,const DString &startMarker,const DString &endMarker)
383{
384 m_calls.emplace_back([]() { return true; },
385 [=](OutputCodeList *ol) { ol->startFold(lineNr,startMarker,endMarker); },
387 );
388}
389
391{
392 m_calls.emplace_back([]() { return true; },
393 [=](OutputCodeList *ol) { ol->endFold(); },
395 );
396}
397
398void OutputCodeRecorder::replay(OutputCodeList &ol,int startLine,int endLine,bool showLineNumbers,bool
399 stripCodeComments,size_t stripIndentAmount)
400{
401 size_t startIndex = startLine>0 && startLine<=(int)m_lineOffset.size() ? m_lineOffset[startLine-1] : 0;
402 size_t endIndex = endLine>0 && endLine <=(int)m_lineOffset.size() ? m_lineOffset[ endLine-1] : m_calls.size();
403 //printf("startIndex=%zu endIndex=%zu\n",startIndex,endIndex);
404
405 // configure run time properties of the rendering
407 ol.setStripIndentAmount(stripIndentAmount);
408 m_showLineNumbers = showLineNumbers;
409
410 bool insideSpecialComment = false;
411 // in case the start of the special comment marker is outside of the fragment, start it here
412 if (startIndex<endIndex && m_calls[startIndex].insideSpecialComment)
413 {
415 insideSpecialComment = true;
416 }
417
418 // render the requested fragment of the pre-recorded output
419 for (size_t i=startIndex; i<endIndex; i++)
420 {
421 if (m_calls[i].condition())
422 {
423 insideSpecialComment = m_calls[i].insideSpecialComment;
424 m_calls[i].function(&ol);
425 }
426 }
427
428 // if we end the fragment inside a special comment, make sure we end it,
429 // and also the code line
430 if (insideSpecialComment)
431 {
433 ol.endCodeLine();
434 }
435
436 ol.stripCodeComments(false);
438}
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
The common base class of all entity definitions found in the sources.
Definition definition.h:77
A model of a class/file/namespace member symbol.
Definition memberdef.h:45
Class representing a list of different code generators.
Definition outputlist.h:162
void endCodeLine()
Definition outputlist.h:264
void endSpecialComment()
Definition outputlist.h:241
void startSpecialComment()
Definition outputlist.h:238
void setStripIndentAmount(size_t amount)
Definition outputlist.h:244
void setEnabledFiltered(OutputType o, bool enabled)
Enable or disable a specific generator.
Definition outputlist.h:217
void setId(int id)
Definition outputlist.h:190
void stripCodeComments(bool b)
Definition outputlist.h:235
void codify(const DString &s) override
void endFold() override
void startFold(int lineNr, const DString &startMarker, const DString &endMarker) override
void endCodeFragment(const DString &style) override
void startCodeLine(int) override
void stripCodeComments(bool) override
Definition outputlist.h:114
void writeCodeLink(CodeSymbolType type, const DString &ref, const DString &file, const DString &anchor, const DString &name, const DString &tooltip) override
void endFontClass() override
void startNewLine(int lineNr)
void startFontClass(const DString &c) override
void startCodeFragment(const DString &style) override
std::vector< size_t > m_lineOffset
Definition outputlist.h:151
void writeCodeAnchor(const DString &name) override
std::vector< CallInfo > m_calls
Definition outputlist.h:150
void replay(OutputCodeList &ol, int startLine, int endLine, bool showLineNumbers, bool stripComment, size_t stripIndentAmount)
void startSpecialComment() override
OutputType type() const override
Definition outputlist.h:112
void endSpecialComment() override
void writeLineNumber(const DString &ref, const DString &file, const DString &anchor, int lineNumber, bool writeLineAnchor) override
void endCodeLine() override
void writeTooltip(const DString &id, const DocLinkInfo &docInfo, const DString &decl, const DString &desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo) override
virtual void startFile(const DString &name, bool isSource, const DString &manName, const DString &title, int id, int hierarchyLevel)=0
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:311
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md, int sectionLevel=-1)
Definition outputlist.h:379
bool isEnabled(OutputType o)
void parseText(const DString &textStr)
void disable(OutputType o)
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
Definition outputlist.h:435
OutputCodeList m_codeGenList
Definition outputlist.h:777
void enable(OutputType o)
std::vector< OutputGenElem > m_outputGenList
Definition outputlist.h:776
void docify(const DString &s)
Definition outputlist.h:433
void lineBreak(const DString &style=DString())
Definition outputlist.h:555
OutputList & operator=(const OutputList &ol)
void newId()
void disableAll()
void syncEnabled()
void pushGeneratorState()
void startFile(const DString &name, bool isSource, const DString &manName, const DString &title, int hierarchyLevel=0)
void disableAllBut(OutputType o)
void popGeneratorState()
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
void enableAll()
void refreshCodeGenerators()
void writeNonBreakableSpace(int num)
Definition outputlist.h:622
TextGeneratorOLImpl(OutputList &ol)
void writeBreak(int indent) const override
void writeLink(const DString &extRef, const DString &file, const DString &anchor, std::string_view text) const override
OutputList & m_ol
Definition outputlist.h:795
void writeString(std::string_view s, bool keepSpaces) const override
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:59
IDocNodeASTPtr validatingParseText(IDocParser &parserIntf, const DString &input)
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &input, const DocOptions &options)
#define AtomicInt
Definition doxygen.h:30
OutputType
Definition outputgen.h:56
static AtomicInt g_outId
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24
int sectionLevel() const
Definition docoptions.h:34
CodeSymbolType
Definition types.h:481