Fix for UBSan build
[platform/upstream/doxygen.git] / src / outputlist.cpp
1 /******************************************************************************
2  *
3  * $Id: outputlist.cpp,v 1.35 2001/03/19 19:27:41 root Exp $
4  *
5  * Copyright (C) 1997-2012 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 #include "outputlist.h"
26 #include "outputgen.h"
27 #include "config.h"
28 #include "message.h"
29 #include "definition.h"
30
31 #include "docparser.h"
32
33 OutputList::OutputList(bool)
34 {
35   //printf("OutputList::OutputList()\n");
36   outputs = new QList<OutputGenerator>;
37   outputs->setAutoDelete(TRUE);
38 }
39
40 OutputList::~OutputList()
41 {
42   //printf("OutputList::~OutputList()\n");
43   delete outputs;
44 }
45
46 void OutputList::add(const OutputGenerator *og)
47 {
48   if (og) outputs->append(og);
49 }
50
51 void OutputList::disableAllBut(OutputGenerator::OutputType o)
52 {
53   OutputGenerator *og=outputs->first();
54   while (og)
55   {
56     og->disableIfNot(o);
57     og=outputs->next();
58   }
59 }
60
61 void OutputList::enableAll()
62 {
63   OutputGenerator *og=outputs->first();
64   while (og)
65   {
66     og->enable();
67     og=outputs->next();
68   }
69 }
70
71 void OutputList::disableAll()
72 {
73   OutputGenerator *og=outputs->first();
74   while (og)
75   {
76     og->disable();
77     og=outputs->next();
78   }
79 }
80
81 void OutputList::disable(OutputGenerator::OutputType o)
82 {
83   OutputGenerator *og=outputs->first();
84   while (og)
85   {
86     og->disableIf(o);
87     og=outputs->next();
88   }
89 }
90
91 void OutputList::enable(OutputGenerator::OutputType o)
92 {
93   OutputGenerator *og=outputs->first();
94   while (og)
95   {
96     og->enableIf(o);
97     og=outputs->next();
98   }
99 }
100
101 bool OutputList::isEnabled(OutputGenerator::OutputType o)
102 {
103   bool result=FALSE;
104   OutputGenerator *og=outputs->first();
105   while (og)
106   {
107     result=result || og->isEnabled(o);
108     og=outputs->next();
109   }
110   return result;
111 }
112
113 void OutputList::pushGeneratorState()
114 {
115   OutputGenerator *og=outputs->first();
116   while (og)
117   {
118     og->pushGeneratorState();
119     og=outputs->next();
120   }
121 }
122
123 void OutputList::popGeneratorState()
124 {
125   OutputGenerator *og=outputs->first();
126   while (og)
127   {
128     og->popGeneratorState();
129     og=outputs->next();
130   }
131 }
132
133 void OutputList::parseDoc(const char *fileName,int startLine,
134                   Definition *ctx,MemberDef * md,
135                   const QCString &docStr,bool indexWords,
136                   bool isExample,const char *exampleName,
137                   bool singleLine,bool linkFromIndex)
138 {
139   int count=0;
140   if (docStr.isEmpty()) return;
141   
142   OutputGenerator *og=outputs->first();
143   while (og)
144   {
145     if (og->isEnabled()) count++;
146     og=outputs->next();
147   }
148   if (count==0) return; // no output formats enabled.
149
150   DocNode *root=0;
151   if (docStr.at(docStr.length()-1)=='\n')
152   {
153     root = validatingParseDoc(fileName,startLine,
154                               ctx,md,docStr,indexWords,isExample,exampleName,
155                               singleLine,linkFromIndex);
156   }
157   else
158   {
159     root = validatingParseDoc(fileName,startLine,
160                               ctx,md,docStr+"\n",indexWords,isExample,exampleName,
161                               singleLine,linkFromIndex);
162   }
163
164   og=outputs->first();
165   while (og)
166   {
167     //printf("og->printDoc(extension=%s)\n",
168     //    ctx?ctx->getDefFileExtension().data():"<null>");
169     if (og->isEnabled()) og->writeDoc(root,ctx,md);
170     og=outputs->next();
171   }
172
173   delete root;
174 }
175
176 void OutputList::parseText(const QCString &textStr)
177 {
178   int count=0;
179   OutputGenerator *og=outputs->first();
180   while (og)
181   {
182     if (og->isEnabled()) count++;
183     og=outputs->next();
184   }
185   if (count==0) return; // no output formats enabled.
186
187   DocNode *root = validatingParseText(textStr);
188
189   og=outputs->first();
190   while (og)
191   {
192     if (og->isEnabled()) og->writeDoc(root,0,0);
193     og=outputs->next();
194   }
195
196   delete root;
197 }
198
199
200 //--------------------------------------------------------------------------
201 // Create some overloaded definitions of the forall function.
202 // Using template functions here would have made it a little less
203 // portable (I guess).
204
205 // zero arguments
206 void OutputList::forall(void (OutputGenerator::*func)())
207 {
208   OutputGenerator *og=outputs->first();
209   while (og)
210   {
211     if (og->isEnabled()) (og->*func)();
212     og=outputs->next();
213   }
214 }
215
216 // one argument
217 #define FORALL1(a1,p1)                                        \
218 void OutputList::forall(void (OutputGenerator::*func)(a1),a1) \
219 {                                                             \
220   OutputGenerator *og=outputs->first();                       \
221   while (og)                                                  \
222   {                                                           \
223     if (og->isEnabled()) (og->*func)(p1);                     \
224     og=outputs->next();                                       \
225   }                                                           \
226 }                     
227
228 // two arguments
229 #define FORALL2(a1,a2,p1,p2)                                        \
230 void OutputList::forall(void (OutputGenerator::*func)(a1,a2),a1,a2) \
231 {                                                                   \
232   OutputGenerator *og=outputs->first();                             \
233   while (og)                                                        \
234   {                                                                 \
235     if (og->isEnabled()) (og->*func)(p1,p2);                        \
236     og=outputs->next();                                             \
237   }                                                                 \
238 }                     
239
240 // three arguments
241 #define FORALL3(a1,a2,a3,p1,p2,p3)                                        \
242 void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3),a1,a2,a3) \
243 {                                                                         \
244   OutputGenerator *og=outputs->first();                                   \
245   while (og)                                                              \
246   {                                                                       \
247     if (og->isEnabled()) (og->*func)(p1,p2,p3);                           \
248     og=outputs->next();                                                   \
249   }                                                                       \
250 }                     
251
252 // four arguments
253 #define FORALL4(a1,a2,a3,a4,p1,p2,p3,p4)                                        \
254 void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4),a1,a2,a3,a4) \
255 {                                                                               \
256   OutputGenerator *og=outputs->first();                                         \
257   while (og)                                                                    \
258   {                                                                             \
259     if (og->isEnabled()) (og->*func)(p1,p2,p3,p4);                              \
260     og=outputs->next();                                                         \
261   }                                                                             \
262 }                     
263
264 // five arguments
265 #define FORALL5(a1,a2,a3,a4,a5,p1,p2,p3,p4,p5)                                        \
266 void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5),a1,a2,a3,a4,a5) \
267 {                                                                                     \
268   OutputGenerator *og=outputs->first();                                               \
269   while (og)                                                                          \
270   {                                                                                   \
271     if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5);                                 \
272     og=outputs->next();                                                               \
273   }                                                                                   \
274 }                     
275
276 // six arguments
277 #define FORALL6(a1,a2,a3,a4,a5,a6,p1,p2,p3,p4,p5,p6)                                  \
278 void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6),a1,a2,a3,a4,a5,a6) \
279 {                                                                                     \
280   OutputGenerator *og=outputs->first();                                               \
281   while (og)                                                                          \
282   {                                                                                   \
283     if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6);                              \
284     og=outputs->next();                                                               \
285   }                                                                                   \
286 }                     
287
288 // now instantiate only the ones we need.
289
290 FORALL1(const char *a1,a1)
291 FORALL1(char a1,a1)
292 FORALL1(int a1,a1)
293 FORALL1(const DotClassGraph &a1,a1)
294 FORALL1(const DotInclDepGraph &a1,a1)
295 FORALL1(const DotCallGraph &a1,a1)
296 FORALL1(const DotDirDeps &a1,a1)
297 FORALL1(const DotGfxHierarchyTable &a1,a1)
298 FORALL1(const DotGroupCollaboration &a1,a1)
299 FORALL1(SectionTypes a1,a1)
300 #if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
301 FORALL1(bool a1,a1)
302 FORALL2(bool a1,int a2,a1,a2)
303 FORALL2(bool a1,bool a2,a1,a2)
304 FORALL2(const char *a1,bool a2,a1,a2)
305 FORALL4(const char *a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4)
306 #endif
307 FORALL2(int a1,bool a2,a1,a2)
308 FORALL2(bool a1,const char *a2,a1,a2)
309 FORALL2(ParamListTypes a1,const char *a2,a1,a2)
310 FORALL1(IndexSections a1,a1)
311 FORALL2(const char *a1,const char *a2,a1,a2)
312 FORALL2(const char *a1,int a2,a1,a2)
313 FORALL2(const char *a1,SectionInfo::SectionType a2,a1,a2)
314 FORALL3(bool a1,HighlightedItem a2,const char *a3,a1,a2,a3)
315 FORALL3(bool a1,bool a2,bool a3,a1,a2,a3)
316 FORALL3(const ClassDiagram &a1,const char *a2,const char *a3,a1,a2,a3)
317 FORALL3(const char *a1,const char *a2,const char *a3,a1,a2,a3)
318 FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3)
319 FORALL3(const char *a1,int a2,const char *a3,a1,a2,a3)
320 FORALL3(const char *a1,const char *a2,SectionInfo::SectionType a3,a1,a2,a3)
321 FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3)
322 FORALL4(SectionTypes a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
323 FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
324 FORALL4(const char *a1,const char *a2,const char *a3,int a4,a1,a2,a3,a4)
325 FORALL5(const char *a1,const char *a2,const char *a3,const char *a4,const char *a5,a1,a2,a3,a4,a5)
326 FORALL5(const char *a1,const char *a2,const char *a3,const char *a4,bool a5,a1,a2,a3,a4,a5)
327 FORALL6(const char *a1,const char *a2,const char *a3,const char *a4,const char *a5,const char *a6,a1,a2,a3,a4,a5,a6)
328
329
330 //--------------------------------------------------------------------------