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