Orb/Doxygen/addon/doxyapp/doxyapp.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     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