Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /******************************************************************************␊ |
2 | *␊ |
3 | * Copyright (C) 1997-2006 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 | /** @file␊ |
17 | * @brief Example of how to use doxygen as part of another GPL applications␊ |
18 | *␊ |
19 | * This example shows how to configure and run doxygen programmatically from␊ |
20 | * within an application without generating the usual output.␊ |
21 | * The example should work on any Unix like OS (including Linux and Mac OS X).␊ |
22 | * ␊ |
23 | * This example shows how to use to code parser to get cross-references information␊ |
24 | * and it also shows how to look up symbols in a program parsed by doxygen and␊ |
25 | * show some information about them.␊ |
26 | */␊ |
27 | ␊ |
28 | #include <stdlib.h>␊ |
29 | #include <unistd.h>␊ |
30 | #include "doxygen.h"␊ |
31 | #include "outputgen.h"␊ |
32 | #include "parserintf.h"␊ |
33 | ␊ |
34 | class XRefDummyCodeGenerator : public CodeOutputInterface␊ |
35 | {␊ |
36 | public:␊ |
37 | XRefDummyCodeGenerator(FileDef *fd) : m_fd(fd) {}␊ |
38 | ~XRefDummyCodeGenerator() {}␊ |
39 | ␊ |
40 | // these are just null functions, they can be used to produce a syntax highlighted␊ |
41 | // and cross-linked version of the source code, but who needs that anyway ;-)␊ |
42 | void codify(const char *) {}␊ |
43 | void writeCodeLink(const char *,const char *,const char *,const char *,const char *) {}␊ |
44 | void startCodeLine() {}␊ |
45 | void endCodeLine() {}␊ |
46 | void startCodeAnchor(const char *) {}␊ |
47 | void endCodeAnchor() {}␊ |
48 | void startFontClass(const char *) {}␊ |
49 | void endFontClass() {}␊ |
50 | void writeCodeAnchor(const char *) {}␊ |
51 | void writeLineNumber(const char *,const char *,const char *,int) {}␊ |
52 | ␊ |
53 | // here we are presented with the symbols found by the code parser␊ |
54 | void linkableSymbol(int l, const char *sym,Definition *symDef,Definition *context) ␊ |
55 | {␊ |
56 | QCString ctx;␊ |
57 | if (context) // the context of the symbol is known␊ |
58 | {␊ |
59 | if (context->definitionType()==Definition::TypeMember) // it is inside a member␊ |
60 | {␊ |
61 | Definition *parentContext = context->getOuterScope();␊ |
62 | if (parentContext && parentContext->definitionType()==Definition::TypeClass)␊ |
63 | // it is inside a member of a class␊ |
64 | {␊ |
65 | ctx.sprintf("inside %s %s of %s %s",␊ |
66 | ((MemberDef *)context)->memberTypeName().data(),␊ |
67 | context->name().data(),␊ |
68 | ((ClassDef*)parentContext)->compoundTypeString().data(),␊ |
69 | parentContext->name().data());␊ |
70 | }␊ |
71 | else if (parentContext==Doxygen::globalScope) // it is inside a global member␊ |
72 | {␊ |
73 | ctx.sprintf("inside %s %s",␊ |
74 | ((MemberDef *)context)->memberTypeName().data(),␊ |
75 | context->name().data());␊ |
76 | }␊ |
77 | }␊ |
78 | if (ctx.isEmpty()) // it is something else (class, or namespace member, ...)␊ |
79 | {␊ |
80 | ctx.sprintf("in %s",context->name().data());␊ |
81 | }␊ |
82 | }␊ |
83 | printf("Found symbol %s at line %d of %s %s\n",␊ |
84 | sym,l,m_fd->getDefFileName().data(),ctx.data());␊ |
85 | if (symDef && context) // in this case the definition of the symbol is␊ |
86 | // known to doxygen.␊ |
87 | {␊ |
88 | printf("-> defined at line %d of %s\n",␊ |
89 | symDef->getDefLine(),symDef->getDefFileName().data());␊ |
90 | }␊ |
91 | }␊ |
92 | private:␊ |
93 | FileDef *m_fd;␊ |
94 | };␊ |
95 | ␊ |
96 | static void findXRefSymbols(FileDef *fd)␊ |
97 | {␊ |
98 | // get the interface to a parser that matches the file extension␊ |
99 | ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());␊ |
100 | ␊ |
101 | // reset the parsers state␊ |
102 | pIntf->resetCodeParserState();␊ |
103 | ␊ |
104 | // create a new backend object ␊ |
105 | XRefDummyCodeGenerator *xrefGen = new XRefDummyCodeGenerator(fd);␊ |
106 | ␊ |
107 | // parse the source code␊ |
108 | pIntf->parseCode(*xrefGen,␊ |
109 | 0,␊ |
110 | fileToString(fd->absFilePath()),␊ |
111 | FALSE,␊ |
112 | 0,␊ |
113 | fd);␊ |
114 | ␊ |
115 | // dismiss the object.␊ |
116 | delete xrefGen;␊ |
117 | }␊ |
118 | ␊ |
119 | static void listSymbol(Definition *d)␊ |
120 | {␊ |
121 | if (d!=Doxygen::globalScope && // skip the global namespace symbol␊ |
122 | d->name().at(0)!='@' // skip anonymous stuff␊ |
123 | ) ␊ |
124 | {␊ |
125 | printf("%s\n",␊ |
126 | d->name().data());␊ |
127 | }␊ |
128 | }␊ |
129 | ␊ |
130 | static void listSymbols()␊ |
131 | {␊ |
132 | QDictIterator<DefinitionIntf> sli(*Doxygen::symbolMap);␊ |
133 | DefinitionIntf *di;␊ |
134 | for (sli.toFirst();(di=sli.current());++sli)␊ |
135 | {␊ |
136 | if (di->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols␊ |
137 | // with same name␊ |
138 | {␊ |
139 | DefinitionListIterator dli(*(DefinitionList*)di);␊ |
140 | Definition *d;␊ |
141 | // for each symbol␊ |
142 | for (dli.toFirst();(d=dli.current());++dli)␊ |
143 | {␊ |
144 | listSymbol(d);␊ |
145 | }␊ |
146 | }␊ |
147 | else // single symbol␊ |
148 | {␊ |
149 | listSymbol((Definition*)di);␊ |
150 | }␊ |
151 | }␊ |
152 | }␊ |
153 | ␊ |
154 | static void lookupSymbol(Definition *d)␊ |
155 | {␊ |
156 | if (d!=Doxygen::globalScope && // skip the global namespace symbol␊ |
157 | d->name().at(0)!='@' // skip anonymous stuff␊ |
158 | ) ␊ |
159 | {␊ |
160 | printf("Symbol info\n");␊ |
161 | printf("-----------\n");␊ |
162 | printf("Name: %s\n",d->name().data());␊ |
163 | printf("File: %s\n",d->getDefFileName().data());␊ |
164 | printf("Line: %d\n",d->getDefLine());␊ |
165 | // depending on the definition type we can case to the appropriate␊ |
166 | // derived to get additional information␊ |
167 | switch (d->definitionType())␊ |
168 | {␊ |
169 | case Definition::TypeClass:␊ |
170 | {␊ |
171 | ClassDef *cd = (ClassDef *)d;␊ |
172 | printf("Kind: %s\n",cd->compoundTypeString().data());␊ |
173 | }␊ |
174 | break;␊ |
175 | case Definition::TypeFile:␊ |
176 | {␊ |
177 | FileDef *fd = (FileDef *)d;␊ |
178 | printf("Kind: File: #includes %d other files\n",␊ |
179 | fd->includeFileList() ? fd->includeFileList()->count() : 0);␊ |
180 | }␊ |
181 | break;␊ |
182 | case Definition::TypeNamespace:␊ |
183 | {␊ |
184 | NamespaceDef *nd = (NamespaceDef *)d;␊ |
185 | printf("Kind: Namespace: contains %d classes and %d namespaces\n",␊ |
186 | nd->getClassSDict() ? nd->getClassSDict()->count() : 0,␊ |
187 | nd->getNamespaceSDict() ? nd->getNamespaceSDict()->count() : 0);␊ |
188 | }␊ |
189 | break;␊ |
190 | case Definition::TypeMember:␊ |
191 | {␊ |
192 | MemberDef *md = (MemberDef *)d;␊ |
193 | printf("Kind: %s\n",md->memberTypeName().data());␊ |
194 | }␊ |
195 | break;␊ |
196 | default:␊ |
197 | // ignore groups/pages/packages/dirs for now␊ |
198 | break;␊ |
199 | }␊ |
200 | }␊ |
201 | }␊ |
202 | ␊ |
203 | static void lookupSymbols(const QCString &sym)␊ |
204 | {␊ |
205 | if (!sym.isEmpty())␊ |
206 | {␊ |
207 | DefinitionIntf *di = Doxygen::symbolMap->find(sym);␊ |
208 | if (di)␊ |
209 | {␊ |
210 | if (di->definitionType()==DefinitionIntf::TypeSymbolList)␊ |
211 | {␊ |
212 | DefinitionListIterator dli(*(DefinitionList*)di);␊ |
213 | Definition *d;␊ |
214 | // for each symbol with the given name␊ |
215 | for (dli.toFirst();(d=dli.current());++dli)␊ |
216 | {␊ |
217 | lookupSymbol(d);␊ |
218 | }␊ |
219 | }␊ |
220 | else␊ |
221 | {␊ |
222 | lookupSymbol((Definition*)di);␊ |
223 | }␊ |
224 | }␊ |
225 | else␊ |
226 | {␊ |
227 | printf("Unknown symbol\n");␊ |
228 | }␊ |
229 | }␊ |
230 | }␊ |
231 | ␊ |
232 | int main(int argc,char **argv)␊ |
233 | {␊ |
234 | char cmd[256];␊ |
235 | ␊ |
236 | if (argc<2)␊ |
237 | {␊ |
238 | printf("Usage: %s [source_file | source_dir]\n",argv[0]);␊ |
239 | exit(1);␊ |
240 | }␊ |
241 | ␊ |
242 | // initialize data structures ␊ |
243 | initDoxygen();␊ |
244 | ␊ |
245 | // setup the non-default configuration options␊ |
246 | ␊ |
247 | // we need a place to put intermediate files␊ |
248 | Config_getString("OUTPUT_DIRECTORY")="/tmp/doxygen"; ␊ |
249 | // disable html output␊ |
250 | Config_getBool("GENERATE_HTML")=FALSE;␊ |
251 | // disable latex output␊ |
252 | Config_getBool("GENERATE_LATEX")=FALSE;␊ |
253 | // be quiet␊ |
254 | Config_getBool("QUIET")=TRUE;␊ |
255 | // turn off warnings␊ |
256 | Config_getBool("WARNINGS")=FALSE;␊ |
257 | Config_getBool("WARN_IF_UNDOCUMENTED")=FALSE;␊ |
258 | Config_getBool("WARN_IF_DOC_ERROR")=FALSE;␊ |
259 | // Extract as much as possible␊ |
260 | Config_getBool("EXTRACT_ALL")=TRUE;␊ |
261 | Config_getBool("EXTRACT_STATIC")=TRUE;␊ |
262 | Config_getBool("EXTRACT_PRIVATE")=TRUE;␊ |
263 | Config_getBool("EXTRACT_LOCAL_METHODS")=TRUE;␊ |
264 | // Extract source browse information, needed ␊ |
265 | // to make doxygen gather the cross reference info␊ |
266 | Config_getBool("SOURCE_BROWSER")=TRUE;␊ |
267 | ␊ |
268 | // set the input␊ |
269 | Config_getList("INPUT").append(argv[1]);␊ |
270 | ␊ |
271 | // check and finialize the configuration␊ |
272 | checkConfiguration();␊ |
273 | adjustConfiguration();␊ |
274 | ␊ |
275 | // parse the files␊ |
276 | parseInput();␊ |
277 | ␊ |
278 | // iterate over the input files␊ |
279 | FileNameListIterator fnli(*Doxygen::inputNameList); ␊ |
280 | FileName *fn;␊ |
281 | // foreach file with a certain name␊ |
282 | for (fnli.toFirst();(fn=fnli.current());++fnli)␊ |
283 | {␊ |
284 | FileNameIterator fni(*fn);␊ |
285 | FileDef *fd;␊ |
286 | // for each file definition␊ |
287 | for (;(fd=fni.current());++fni)␊ |
288 | {␊ |
289 | // get the references (linked and unlinked) found in this file␊ |
290 | findXRefSymbols(fd);␊ |
291 | }␊ |
292 | }␊ |
293 | ␊ |
294 | // remove temporary files␊ |
295 | if (!Doxygen::objDBFileName.isEmpty()) unlink(Doxygen::objDBFileName);␊ |
296 | if (!Doxygen::entryDBFileName.isEmpty()) unlink(Doxygen::entryDBFileName);␊ |
297 | // clean up after us␊ |
298 | rmdir("/tmp/doxygen");␊ |
299 | ␊ |
300 | while (1)␊ |
301 | {␊ |
302 | printf("> Type a symbol name or\n> .list for a list of symbols or\n> .quit to exit\n> ");␊ |
303 | fgets(cmd,256,stdin);␊ |
304 | QCString s(cmd);␊ |
305 | if (s.at(s.length()-1)=='\n') s=s.left(s.length()-1); // strip trailing \n␊ |
306 | if (s==".list") ␊ |
307 | listSymbols();␊ |
308 | else if (s==".quit") ␊ |
309 | exit(0);␊ |
310 | else ␊ |
311 | lookupSymbols(s);␊ |
312 | }␊ |
313 | }␊ |
314 | ␊ |
315 |