|
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 /*! \page preprocessing Preprocessing |
|
18 |
|
19 Source files that are used as input to doxygen can be parsed by doxygen's |
|
20 built-in C-preprocessor. |
|
21 |
|
22 By default doxygen does only partial preprocessing. That is, it |
|
23 evaluates conditional compilation statements (like \#if) and |
|
24 evaluates macro definitions, but it does not perform macro expansion. |
|
25 |
|
26 So if you have the following code fragment |
|
27 \verbatim |
|
28 #define VERSION 200 |
|
29 #define CONST_STRING const char * |
|
30 |
|
31 #if VERSION >= 200 |
|
32 static CONST_STRING version = "2.xx"; |
|
33 #else |
|
34 static CONST_STRING version = "1.xx"; |
|
35 #endif |
|
36 \endverbatim |
|
37 |
|
38 Then by default doxygen will feed the following to its parser: |
|
39 |
|
40 \verbatim |
|
41 #define VERSION |
|
42 #define CONST_STRING |
|
43 |
|
44 static CONST_STRING version = "2.xx"; |
|
45 \endverbatim |
|
46 |
|
47 You can disable all preprocessing by setting |
|
48 \ref cfg_enable_preprocessing "ENABLE_PREPROCESSING" to \c |
|
49 NO in the configuation file. In the case above doxygen will then read |
|
50 both statements, i.e: |
|
51 |
|
52 \verbatim |
|
53 static CONST_STRING version = "2.xx"; |
|
54 static CONST_STRING version = "1.xx"; |
|
55 \endverbatim |
|
56 |
|
57 In case you want to expand the \c CONST_STRING macro, you should set the |
|
58 \ref cfg_macro_expansion "MACRO_EXPANSION" tag in the config file |
|
59 to \c YES. Then the result after preprocessing becomes: |
|
60 |
|
61 \verbatim |
|
62 #define VERSION |
|
63 #define CONST_STRING |
|
64 |
|
65 static const char * version = "1.xx"; |
|
66 \endverbatim |
|
67 |
|
68 Note that doxygen will now expand \e all macro definitions |
|
69 (recursively if needed). This is often too much. Therefore, doxygen also |
|
70 allows you to expand only those defines that you explicitly |
|
71 specify. For this you have to set the |
|
72 \ref cfg_expand_only_predef "EXPAND_ONLY_PREDEF" tag to \c YES |
|
73 and specify the macro definitions after |
|
74 the \ref cfg_predefined "PREDEFINED" or |
|
75 \ref cfg_expand_as_defined "EXPAND_AS_DEFINED" tag. |
|
76 |
|
77 A typically example where some help from the preprocessor is needed is |
|
78 when dealing with Microsoft's __declspec language extension. Here is an |
|
79 example function. |
|
80 |
|
81 \verbatim |
|
82 extern "C" void __declspec(dllexport) ErrorMsg( String aMessage,...); |
|
83 \endverbatim |
|
84 |
|
85 When nothing is done, doxygen will be confused and see __declspec as |
|
86 some sort of function. To help doxygen one typically uses the following |
|
87 preprocessor settings: |
|
88 |
|
89 \verbatim |
|
90 ENABLE_PREPROCESSING = YES |
|
91 MACRO_EXPANSION = YES |
|
92 EXPAND_ONLY_PREDEF = YES |
|
93 PREDEFINED = __declspec(x)= |
|
94 \endverbatim |
|
95 |
|
96 This will make sure the __declspec(dllexport) is removed before doxygen |
|
97 parses the source code. |
|
98 |
|
99 For a more complex example, suppose you have the following obfuscated |
|
100 code fragment of an abstract base class called \c IUnknown: |
|
101 |
|
102 \verbatim |
|
103 /*! A reference to an IID */ |
|
104 #ifdef __cplusplus |
|
105 #define REFIID const IID & |
|
106 #else |
|
107 #define REFIID const IID * |
|
108 #endif |
|
109 |
|
110 |
|
111 /*! The IUnknown interface */ |
|
112 DECLARE_INTERFACE(IUnknown) |
|
113 { |
|
114 STDMETHOD(HRESULT,QueryInterface) (THIS_ REFIID iid, void **ppv) PURE; |
|
115 STDMETHOD(ULONG,AddRef) (THIS) PURE; |
|
116 STDMETHOD(ULONG,Release) (THIS) PURE; |
|
117 }; |
|
118 \endverbatim |
|
119 |
|
120 without macro expansion doxygen will get confused, but we may not want to |
|
121 expand the REFIID macro, because it is documented and the user that reads |
|
122 the documentation should use it when implementing the interface. |
|
123 |
|
124 By setting the following in the config file: |
|
125 |
|
126 \verbatim |
|
127 ENABLE_PREPROCESSING = YES |
|
128 MACRO_EXPANSION = YES |
|
129 EXPAND_ONLY_PREDEF = YES |
|
130 PREDEFINED = "DECLARE_INTERFACE(name)=class name" \ |
|
131 "STDMETHOD(result,name)=virtual result name" \ |
|
132 "PURE= = 0" \ |
|
133 THIS_= \ |
|
134 THIS= \ |
|
135 __cplusplus |
|
136 \endverbatim |
|
137 |
|
138 we can make sure that the proper result is fed to doxygen's parser: |
|
139 \verbatim |
|
140 /*! A reference to an IID */ |
|
141 #define REFIID |
|
142 |
|
143 /*! The IUnknown interface */ |
|
144 class IUnknown |
|
145 { |
|
146 virtual HRESULT QueryInterface ( REFIID iid, void **ppv) = 0; |
|
147 virtual ULONG AddRef () = 0; |
|
148 virtual ULONG Release () = 0; |
|
149 }; |
|
150 \endverbatim |
|
151 |
|
152 Note that the \ref cfg_predefined "PREDEFINED" tag accepts function |
|
153 like macro definitions |
|
154 (like \c DECLARE_INTERFACE ), normal macro |
|
155 substitutions (like \c PURE and \c THIS) and plain |
|
156 defines (like \c __cplusplus). |
|
157 |
|
158 Note also that preprocessor definitions that are normally defined |
|
159 automatically by the preprocessor (like \c __cplusplus), have to be defined |
|
160 by hand with doxygen's parser (this is done because these defines |
|
161 are often platform/compiler specific). |
|
162 |
|
163 In some cases you may want to substitute a macro name or function by |
|
164 something else without exposing the result to further macro substitution. |
|
165 You can do this but using the <code>:=</code> operator instead of |
|
166 <code>=</code> |
|
167 |
|
168 As an example suppose we have the following piece of code: |
|
169 \verbatim |
|
170 #define QList QListT |
|
171 class QListT |
|
172 { |
|
173 }; |
|
174 \endverbatim |
|
175 |
|
176 Then the only way to get doxygen interpret this as a class definition |
|
177 for class QList is to define: |
|
178 \verbatim |
|
179 PREDEFINED = QListT:=QList |
|
180 \endverbatim |
|
181 |
|
182 Here is an example provided by Valter Minute and Reyes Ponce that helps |
|
183 doxygen to wade through the boilerplate code in Microsoft's ATL \& MFC |
|
184 libraries: |
|
185 |
|
186 \verbatim |
|
187 PREDEFINED = "DECLARE_INTERFACE(name)=class name" \ |
|
188 "STDMETHOD(result,name)=virtual result name" \ |
|
189 "PURE= = 0" \ |
|
190 THIS_= \ |
|
191 THIS= \ |
|
192 DECLARE_REGISTRY_RESOURCEID=// \ |
|
193 DECLARE_PROTECT_FINAL_CONSTRUCT=// \ |
|
194 "DECLARE_AGGREGATABLE(Class)= " \ |
|
195 "DECLARE_REGISTRY_RESOURCEID(Id)= " \ |
|
196 DECLARE_MESSAGE_MAP= \ |
|
197 BEGIN_MESSAGE_MAP=/* \ |
|
198 END_MESSAGE_MAP=*/// \ |
|
199 BEGIN_COM_MAP=/* \ |
|
200 END_COM_MAP=*/// \ |
|
201 BEGIN_PROP_MAP=/* \ |
|
202 END_PROP_MAP=*/// \ |
|
203 BEGIN_MSG_MAP=/* \ |
|
204 END_MSG_MAP=*/// \ |
|
205 BEGIN_PROPERTY_MAP=/* \ |
|
206 END_PROPERTY_MAP=*/// \ |
|
207 BEGIN_OBJECT_MAP=/* \ |
|
208 END_OBJECT_MAP()=*/// \ |
|
209 DECLARE_VIEW_STATUS=// \ |
|
210 "STDMETHOD(a)=HRESULT a" \ |
|
211 "ATL_NO_VTABLE= " \ |
|
212 "__declspec(a)= " \ |
|
213 BEGIN_CONNECTION_POINT_MAP=/* \ |
|
214 END_CONNECTION_POINT_MAP=*/// \ |
|
215 "DECLARE_DYNAMIC(class)= " \ |
|
216 "IMPLEMENT_DYNAMIC(class1, class2)= " \ |
|
217 "DECLARE_DYNCREATE(class)= " \ |
|
218 "IMPLEMENT_DYNCREATE(class1, class2)= " \ |
|
219 "IMPLEMENT_SERIAL(class1, class2, class3)= " \ |
|
220 "DECLARE_MESSAGE_MAP()= " \ |
|
221 TRY=try \ |
|
222 "CATCH_ALL(e)= catch(...)" \ |
|
223 END_CATCH_ALL= \ |
|
224 "THROW_LAST()= throw"\ |
|
225 "RUNTIME_CLASS(class)=class" \ |
|
226 "MAKEINTRESOURCE(nId)=nId" \ |
|
227 "IMPLEMENT_REGISTER(v, w, x, y, z)= " \ |
|
228 "ASSERT(x)=assert(x)" \ |
|
229 "ASSERT_VALID(x)=assert(x)" \ |
|
230 "TRACE0(x)=printf(x)" \ |
|
231 "OS_ERR(A,B)={ #A, B }" \ |
|
232 __cplusplus \ |
|
233 "DECLARE_OLECREATE(class)= " \ |
|
234 "BEGIN_DISPATCH_MAP(class1, class2)= " \ |
|
235 "BEGIN_INTERFACE_MAP(class1, class2)= " \ |
|
236 "INTERFACE_PART(class, id, name)= " \ |
|
237 "END_INTERFACE_MAP()=" \ |
|
238 "DISP_FUNCTION(class, name, function, result, id)=" \ |
|
239 "END_DISPATCH_MAP()=" \ |
|
240 "IMPLEMENT_OLECREATE2(class, name, id1, id2, id3, id4,\ |
|
241 id5, id6, id7, id8, id9, id10, id11)=" |
|
242 \endverbatim |
|
243 |
|
244 As you can see doxygen's preprocessor is quite powerful, but if you want |
|
245 even more flexibility you can always write an input filter and specify it |
|
246 after the \ref cfg_input_filter "INPUT_FILTER" tag. |
|
247 |
|
248 If you are unsure what the effect of doxygen's preprocessing will be |
|
249 you can run doxygen as follows: |
|
250 \verbatim |
|
251 doxygen -d Preprocessor |
|
252 \endverbatim |
|
253 This will instruct doxygen to dump the input sources to standard output after |
|
254 preprocessing has been done (Hint: set <code>QUIET = YES</code> and |
|
255 <code>WARNINGS = NO</code> in the configuration file to disable any other |
|
256 output). |
|
257 |
|
258 \htmlonly |
|
259 Go to the <a href="external.html">next</a> section or return to the |
|
260 <a href="index.html">index</a>. |
|
261 \endhtmlonly |
|
262 |
|
263 */ |