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