Imported Upstream version 1.8.8
[platform/upstream/doxygen.git] / src / parserintf.h
1 /******************************************************************************
2  *
3  * 
4  *
5  * Copyright (C) 1997-2014 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 #ifndef PARSERINTF_H
19 #define PARSERINTF_H
20
21 #include <qdict.h>
22 #include <qstrlist.h>
23
24 #include "types.h"
25
26 class Entry;
27 class FileDef;
28 class CodeOutputInterface;
29 class MemberDef;
30 class Definition;
31
32 /** \brief Abstract interface for programming language parsers.
33  *
34  *  By implementing the methods of this interface one can add
35  *  a new language parser to doxygen. The parser can make use of the 
36  *  comment block parser to parse the contents of special comment blocks.
37  */
38 class ParserInterface
39 {
40   public:
41     virtual ~ParserInterface() {}
42
43     /** Starts processing a translation unit (source files + headers).
44      *  After this call parseInput() is called with sameTranslationUnit
45      *  set to FALSE. If parseInput() returns additional include files,
46      *  these are also processed using parseInput() with 
47      *  sameTranslationUnit set to TRUE. After that
48      *  finishTranslationUnit() is called.
49      */
50     virtual void startTranslationUnit(const char *fileName) = 0;
51
52     /** Called after all files in a translation unit have been 
53      *  processed.
54      */
55     virtual void finishTranslationUnit() = 0;
56
57     /** Parses a single input file with the goal to build an Entry tree. 
58      *  @param[in] fileName    The full name of the file.
59      *  @param[in] fileBuf     The contents of the file (zero terminated).
60      *  @param[in,out] root    The root of the tree of Entry *nodes 
61      *             representing the information extracted from the file.
62      *  @param[in] sameTranslationUnit TRUE if this file was found in the same
63      *             translation unit (in the filesInSameTranslationUnit list
64      *             returned for another file).
65      *  @param[in,out] filesInSameTranslationUnit other files expected to be
66      *              found in the same translation unit (used for libclang)
67      */
68     virtual void parseInput(const char *fileName,
69                             const char *fileBuf,
70                             Entry *root,
71                             bool sameTranslationUnit,
72                             QStrList &filesInSameTranslationUnit) = 0;
73
74     /** Returns TRUE if the language identified by \a extension needs
75      *  the C preprocessor to be run before feed the result to the input
76      *  parser.
77      *  @see parseInput()
78      */
79     virtual bool needsPreprocessing(const QCString &extension) = 0;
80     
81     /** Parses a source file or fragment with the goal to produce
82      *  highlighted and cross-referenced output.
83      *  @param[in] codeOutIntf Abstract interface for writing the result.
84      *  @param[in] lang The programming language of the code fragment.
85      *  @param[in] scopeName Name of scope to which the code belongs.
86      *  @param[in] input Actual code in the form of a string
87      *  @param[in] isExampleBlock TRUE iff the code is part of an example.
88      *  @param[in] exampleName Name of the example.
89      *  @param[in] fileDef File definition to which the code 
90      *             is associated.
91      *  @param[in] startLine Starting line in case of a code fragment. 
92      *  @param[in] endLine Ending line of the code fragment.
93      *  @param[in] inlineFragment Code fragment that is to be shown inline 
94      *             as part of the documentation.
95      *  @param[in] memberDef Member definition to which the code
96      *             is associated (non null in case of an inline fragment 
97      *             for a member).
98      *  @param[in] showLineNumbers if set to TRUE and also fileDef is not 0,
99      *             line numbers will be added to the source fragement
100      *  @param[in] searchCtx context under which search data has to be stored.
101      *  @param[in] collectXRefs collect cross-reference relations.
102      */
103     virtual void parseCode(CodeOutputInterface &codeOutIntf,
104                            const char *scopeName,
105                            const QCString &input,
106                            SrcLangExt lang,
107                            bool isExampleBlock,
108                            const char *exampleName=0,
109                            FileDef *fileDef=0,
110                            int startLine=-1,
111                            int endLine=-1,
112                            bool inlineFragment=FALSE,
113                            MemberDef *memberDef=0,
114                            bool showLineNumbers=TRUE,
115                            Definition *searchCtx=0,
116                            bool collectXRefs=TRUE
117                           ) = 0;
118
119     /** Resets the state of the code parser.
120      *  Since multiple code fragments can together form a single example, an
121      *  explicit function is used to reset the code parser state.
122      *  @see parseCode()
123      */
124     virtual void resetCodeParserState() = 0;
125
126     /** Callback function called by the comment block scanner.
127      *  It provides a string \a text containing the prototype of a function
128      *  or variable. The parser should parse this and store the information
129      *  in the Entry node that corresponds with the node for which the
130      *  comment block parser was invoked.
131      */
132     virtual void parsePrototype(const char *text) = 0;
133
134 };
135
136 //-----------------------------------------------------------------------------
137
138 /** \brief Manages programming language parsers.
139  *
140  *  This class manages the language parsers in the system. One can 
141  *  register parsers, and obtain a parser given a file extension.
142  */
143 class ParserManager
144 {
145   public:
146     /** Creates the parser manager object. 
147      */
148     ParserManager()
149       : m_defaultParser(0) { m_parsers.setAutoDelete(TRUE); }
150
151     void registerDefaultParser(ParserInterface *parser)
152     {
153       m_defaultParser = parser;
154     }
155
156     /** Registers an additional parser.
157      *  @param[in] name      A symbolic name of the parser, i.e. "c",
158      *                       "python", "fortran", "vhdl", ...
159      *  @param[in] parser    The parser that is to be used for the
160      *                       given name.
161      */
162     void registerParser(const char *name,ParserInterface *parser)
163     {
164       m_parsers.insert(name,parser);
165     }
166
167     /** Registers a file \a extension with a parser with name \a parserName. 
168      *  Returns TRUE if the extension was successfully registered.
169      */
170     bool registerExtension(const char *extension, const char *parserName)
171     {
172       if (parserName==0 || extension==0) return FALSE;
173       ParserInterface *intf = m_parsers.find(parserName);
174       if (intf==0) return FALSE;
175       if (m_extensions.find(extension)!=0) // extension already exists
176       {
177         m_extensions.remove(extension); // remove it
178       }
179       m_extensions.insert(extension,intf); // add new mapping
180       return TRUE;
181     }
182
183     /** Gets the interface to the parser associated with given \a extension.
184      *  If there is no parser explicitly registered for the supplied extension, 
185      *  the interface to the default parser will be returned.
186      */
187     ParserInterface *getParser(const char *extension)
188     {
189       QCString ext = QCString(extension).lower();
190       if (ext.isEmpty()) ext=".no_extension";
191       ParserInterface *intf = m_extensions.find(ext);
192       if (intf==0 && ext.length()>4)
193       {
194         intf = m_extensions.find(ext.left(4));
195       }
196       return intf ? intf : m_defaultParser;
197     }
198
199   private:
200     QDict<ParserInterface> m_parsers;
201     QDict<ParserInterface> m_extensions;
202     ParserInterface *m_defaultParser;
203 };
204
205 #endif