doxyapp.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 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 <qfile.h>
30 #include <qdir.h>
31 #include "doxygen.h"
32 #include "outputgen.h"
33 #include "parserintf.h"
34 #include "classdef.h"
35 #include "namespacedef.h"
36 #include "filedef.h"
37 #include "util.h"
38 #include "classlist.h"
39 #include "config.h"
40 #include "filename.h"
41 
43 {
44  public:
47 
48  // these are just null functions, they can be used to produce a syntax highlighted
49  // and cross-linked version of the source code, but who needs that anyway ;-)
50  void codify(const char *) {}
51  void writeCodeLink(const char *,const char *,const char *,const char *,const char *) {}
52  void writeLineNumber(const char *,const char *,const char *,int) {}
53  virtual void writeTooltip(const char *,const DocLinkInfo &,
54  const char *,const char *,const SourceLinkInfo &,
55  const SourceLinkInfo &) {}
56  void startCodeLine(bool) {}
57  void endCodeLine() {}
58  void startCodeAnchor(const char *) {}
59  void endCodeAnchor() {}
60  void startFontClass(const char *) {}
61  void endFontClass() {}
62  void writeCodeAnchor(const char *) {}
63  void setCurrentDoc(Definition *,const char *,bool) {}
64  void addWord(const char *,bool) {}
65 
66  // here we are presented with the symbols found by the code parser
67  void linkableSymbol(int l, const char *sym,Definition *symDef,Definition *context)
68  {
69  QCString ctx;
70  if (context) // the context of the symbol is known
71  {
72  if (context->definitionType()==Definition::TypeMember) // it is inside a member
73  {
74  Definition *parentContext = context->getOuterScope();
75  if (parentContext && parentContext->definitionType()==Definition::TypeClass)
76  // it is inside a member of a class
77  {
78  ctx.sprintf("inside %s %s of %s %s",
79  ((MemberDef *)context)->memberTypeName().data(),
80  context->name().data(),
81  ((ClassDef*)parentContext)->compoundTypeString().data(),
82  parentContext->name().data());
83  }
84  else if (parentContext==Doxygen::globalScope) // it is inside a global member
85  {
86  ctx.sprintf("inside %s %s",
87  ((MemberDef *)context)->memberTypeName().data(),
88  context->name().data());
89  }
90  }
91  if (ctx.isEmpty()) // it is something else (class, or namespace member, ...)
92  {
93  ctx.sprintf("in %s",context->name().data());
94  }
95  }
96  printf("Found symbol %s at line %d of %s %s\n",
97  sym,l,m_fd->getDefFileName().data(),ctx.data());
98  if (symDef && context) // in this case the definition of the symbol is
99  // known to doxygen.
100  {
101  printf("-> defined at line %d of %s\n",
102  symDef->getDefLine(),symDef->getDefFileName().data());
103  }
104  }
105  private:
107 };
108 
109 static void findXRefSymbols(FileDef *fd)
110 {
111  // get the interface to a parser that matches the file extension
113 
114  // get the programming language from the file name
116 
117  // reset the parsers state
118  pIntf->resetCodeParserState();
119 
120  // create a new backend object
122 
123  // parse the source code
124  pIntf->parseCode(*xrefGen,
125  0,
126  fileToString(fd->absFilePath()),
127  lang,
128  FALSE,
129  0,
130  fd);
131 
132  // dismiss the object.
133  delete xrefGen;
134 }
135 
136 static void listSymbol(Definition *d)
137 {
138  if (d!=Doxygen::globalScope && // skip the global namespace symbol
139  d->name().at(0)!='@' // skip anonymous stuff
140  )
141  {
142  printf("%s\n",
143  d->name().data());
144  }
145 }
146 
147 static void listSymbols()
148 {
149  QDictIterator<DefinitionIntf> sli(*Doxygen::symbolMap);
150  DefinitionIntf *di;
151  for (sli.toFirst();(di=sli.current());++sli)
152  {
153  if (di->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols
154  // with same name
155  {
157  Definition *d;
158  // for each symbol
159  for (dli.toFirst();(d=dli.current());++dli)
160  {
161  listSymbol(d);
162  }
163  }
164  else // single symbol
165  {
166  listSymbol((Definition*)di);
167  }
168  }
169 }
170 
171 static void lookupSymbol(Definition *d)
172 {
173  if (d!=Doxygen::globalScope && // skip the global namespace symbol
174  d->name().at(0)!='@' // skip anonymous stuff
175  )
176  {
177  printf("Symbol info\n");
178  printf("-----------\n");
179  printf("Name: %s\n",d->name().data());
180  printf("File: %s\n",d->getDefFileName().data());
181  printf("Line: %d\n",d->getDefLine());
182  // depending on the definition type we can case to the appropriate
183  // derived to get additional information
184  switch (d->definitionType())
185  {
187  {
188  ClassDef *cd = (ClassDef *)d;
189  printf("Kind: %s\n",cd->compoundTypeString().data());
190  }
191  break;
193  {
194  FileDef *fd = (FileDef *)d;
195  printf("Kind: File: #includes %d other files\n",
196  fd->includeFileList() ? fd->includeFileList()->count() : 0);
197  }
198  break;
200  {
201  NamespaceDef *nd = (NamespaceDef *)d;
202  printf("Kind: Namespace: contains %d classes and %d namespaces\n",
203  nd->getClassSDict() ? nd->getClassSDict()->count() : 0,
204  nd->getNamespaceSDict() ? nd->getNamespaceSDict()->count() : 0);
205  }
206  break;
208  {
209  MemberDef *md = (MemberDef *)d;
210  printf("Kind: %s\n",md->memberTypeName().data());
211  }
212  break;
213  default:
214  // ignore groups/pages/packages/dirs for now
215  break;
216  }
217  }
218 }
219 
220 static void lookupSymbols(const QCString &sym)
221 {
222  if (!sym.isEmpty())
223  {
224  DefinitionIntf *di = Doxygen::symbolMap->find(sym);
225  if (di)
226  {
228  {
230  Definition *d;
231  // for each symbol with the given name
232  for (dli.toFirst();(d=dli.current());++dli)
233  {
234  lookupSymbol(d);
235  }
236  }
237  else
238  {
239  lookupSymbol((Definition*)di);
240  }
241  }
242  else
243  {
244  printf("Unknown symbol\n");
245  }
246  }
247 }
248 
249 int main(int argc,char **argv)
250 {
251  char cmd[256];
252 
253  if (argc<2)
254  {
255  printf("Usage: %s [source_file | source_dir]\n",argv[0]);
256  exit(1);
257  }
258 
259  // initialize data structures
260  initDoxygen();
261 
262  // setup the non-default configuration options
263 
264  // we need a place to put intermediate files
265  Config_getString("OUTPUT_DIRECTORY")="/tmp/doxygen";
266  // disable html output
267  Config_getBool("GENERATE_HTML")=FALSE;
268  // disable latex output
269  Config_getBool("GENERATE_LATEX")=FALSE;
270  // be quiet
271  Config_getBool("QUIET")=TRUE;
272  // turn off warnings
273  Config_getBool("WARNINGS")=FALSE;
274  Config_getBool("WARN_IF_UNDOCUMENTED")=FALSE;
275  Config_getBool("WARN_IF_DOC_ERROR")=FALSE;
276  // Extract as much as possible
277  Config_getBool("EXTRACT_ALL")=TRUE;
278  Config_getBool("EXTRACT_STATIC")=TRUE;
279  Config_getBool("EXTRACT_PRIVATE")=TRUE;
280  Config_getBool("EXTRACT_LOCAL_METHODS")=TRUE;
281  // Extract source browse information, needed
282  // to make doxygen gather the cross reference info
283  Config_getBool("SOURCE_BROWSER")=TRUE;
284 
285  // set the input
286  Config_getList("INPUT").append(argv[1]);
287 
288  // check and finialize the configuration
291 
292  // parse the files
293  parseInput();
294 
295  // iterate over the input files
297  FileName *fn;
298  // foreach file with a certain name
299  for (fnli.toFirst();(fn=fnli.current());++fnli)
300  {
301  FileNameIterator fni(*fn);
302  FileDef *fd;
303  // for each file definition
304  for (;(fd=fni.current());++fni)
305  {
306  // get the references (linked and unlinked) found in this file
307  findXRefSymbols(fd);
308  }
309  }
310 
311  // remove temporary files
314  // clean up after us
315  QDir().rmdir("/tmp/doxygen");
316 
317  while (1)
318  {
319  printf("> Type a symbol name or\n> .list for a list of symbols or\n> .quit to exit\n> ");
320  fgets(cmd,256,stdin);
321  QCString s(cmd);
322  if (s.at(s.length()-1)=='\n') s=s.left(s.length()-1); // strip trailing \n
323  if (s==".list")
324  listSymbols();
325  else if (s==".quit")
326  exit(0);
327  else
328  lookupSymbols(s);
329  }
330 }
331 
void writeCodeLink(const char *, const char *, const char *, const char *, const char *)
Definition: doxyapp.cpp:51
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
ParserInterface * getParser(const char *extension)
Definition: parserintf.h:191
QCString fileToString(const char *name, bool filter, bool isSourceCode)
Definition: util.cpp:2418
bool isEmpty() const
Definition: qcstring.h:189
uint length() const
Definition: qcstring.h:195
Abstract interface for programming language parsers.
Definition: parserintf.h:38
void initDoxygen()
Definition: doxygen.cpp:9979
char & at(uint i) const
Definition: qcstring.h:326
QCString compoundTypeString() const
Definition: classdef.cpp:3499
void writeCodeAnchor(const char *)
Definition: doxyapp.cpp:62
const bool FALSE
Definition: qglobal.h:370
static FileNameList * inputNameList
Definition: doxygen.h:109
int main(int argc, char **argv)
Definition: doxyapp.cpp:249
void checkConfiguration()
Definition: doxygen.cpp:10493
static void lookupSymbol(Definition *d)
Definition: doxyapp.cpp:171
#define Config_getList(val)
Definition: config.cpp:662
QCString left(uint len) const
Definition: qcstring.cpp:213
int count() const
Definition: sortdict.h:284
SrcLangExt
Definition: types.h:41
static QStrList * l
Definition: config.cpp:1044
void addWord(const char *, bool)
Definition: doxyapp.cpp:64
static void findXRefSymbols(FileDef *fd)
Definition: doxyapp.cpp:109
QCString getDefFileName() const
QCString getDefFileExtension() const
void adjustConfiguration()
Definition: doxygen.cpp:10504
static NamespaceDef * globalScope
Definition: doxygen.h:128
static ParserManager * parserManager
Definition: doxygen.h:141
virtual DefType definitionType() const =0
uint count() const
Definition: qlist.h:66
QAsciiDict< Entry > fn
const QCString & name() const
Definition: definition.h:114
int getDefLine() const
Definition: definition.h:188
void setCurrentDoc(Definition *, const char *, bool)
Definition: doxyapp.cpp:63
QCString name() const
Definition: filedef.cpp:1193
QList< IncludeInfo > * includeFileList() const
Definition: filedef.h:124
static QCString objDBFileName
Definition: doxygen.h:144
void writeLineNumber(const char *, const char *, const char *, int)
Definition: doxyapp.cpp:52
XRefDummyCodeGenerator(FileDef *fd)
Definition: doxyapp.cpp:45
static QDict< DefinitionIntf > * symbolMap
Definition: doxygen.h:134
void startCodeAnchor(const char *)
Definition: doxyapp.cpp:58
A bunch of utility functions.
const char * data() const
Definition: qcstring.h:207
#define Config_getString(val)
Definition: config.cpp:660
type * current() const
Definition: qlist.h:146
#define Config_getBool(val)
Definition: config.cpp:664
QCString absFilePath() const
Definition: filedef.h:96
NamespaceSDict * getNamespaceSDict() const
Definition: namespacedef.h:101
QCString & sprintf(const char *format,...)
Definition: qcstring.cpp:27
static void lookupSymbols(const QCString &sym)
Definition: doxyapp.cpp:220
virtual Definition * getOuterScope() const
void codify(const char *)
Definition: doxyapp.cpp:50
SrcLangExt getLanguageFromFileName(const QCString fileName)
Definition: util.cpp:7061
static QCString entryDBFileName
Definition: doxygen.h:145
virtual bool rmdir(const QString &dirName, bool acceptAbsPath=TRUE) const
Definition: qdir_unix.cpp:104
static void listSymbol(Definition *d)
Definition: doxyapp.cpp:136
bool remove()
Definition: qfile.cpp:205
QCString memberTypeName() const
Definition: memberdef.cpp:3188
void parseInput()
Definition: doxygen.cpp:10880
list cmd
Definition: getreco.py:22
ClassSDict * getClassSDict() const
Definition: namespacedef.h:98
static void listSymbols()
Definition: doxyapp.cpp:147
void linkableSymbol(int l, const char *sym, Definition *symDef, Definition *context)
Definition: doxyapp.cpp:67
virtual void parseCode(CodeOutputInterface &codeOutIntf, const char *scopeName, const QCString &input, SrcLangExt lang, bool isExampleBlock, const char *exampleName=0, FileDef *fileDef=0, int startLine=-1, int endLine=-1, bool inlineFragment=FALSE, MemberDef *memberDef=0, bool showLineNumbers=TRUE, Definition *searchCtx=0, bool collectXRefs=TRUE)=0
static QCString * s
Definition: config.cpp:1042
void startCodeLine(bool)
Definition: doxyapp.cpp:56
const bool TRUE
Definition: qglobal.h:371
virtual void writeTooltip(const char *, const DocLinkInfo &, const char *, const char *, const SourceLinkInfo &, const SourceLinkInfo &)
Definition: doxyapp.cpp:53
type * toFirst()
Definition: qlist.h:135
virtual void resetCodeParserState()=0
void startFontClass(const char *)
Definition: doxyapp.cpp:60