1 /******************************************************************************
5 * Copyright (C) 1997-2014 by Dimitri van Heesch.
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.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
28 class CodeOutputInterface;
32 /** \brief Abstract interface for programming language parsers.
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.
41 virtual ~ParserInterface() {}
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.
50 virtual void startTranslationUnit(const char *fileName) = 0;
52 /** Called after all files in a translation unit have been
55 virtual void finishTranslationUnit() = 0;
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)
68 virtual void parseInput(const char *fileName,
71 bool sameTranslationUnit,
72 QStrList &filesInSameTranslationUnit) = 0;
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
79 virtual bool needsPreprocessing(const QCString &extension) = 0;
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
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
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.
103 virtual void parseCode(CodeOutputInterface &codeOutIntf,
104 const char *scopeName,
105 const QCString &input,
108 const char *exampleName=0,
112 bool inlineFragment=FALSE,
113 MemberDef *memberDef=0,
114 bool showLineNumbers=TRUE,
115 Definition *searchCtx=0,
116 bool collectXRefs=TRUE
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.
124 virtual void resetCodeParserState() = 0;
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.
132 virtual void parsePrototype(const char *text) = 0;
136 //-----------------------------------------------------------------------------
138 /** \brief Manages programming language parsers.
140 * This class manages the language parsers in the system. One can
141 * register parsers, and obtain a parser given a file extension.
146 /** Creates the parser manager object.
149 : m_defaultParser(0) { m_parsers.setAutoDelete(TRUE); }
151 /** Registers an additional parser.
152 * @param[in] name A symbolic name of the parser, i.e. "c",
153 * "python", "fortran", "vhdl", ...
154 * @param[in] parser The parser that is to be used for the
156 * @param[in] defParser Use this parser as the default parser, used
157 * for unregistered file extensions.
159 void registerParser(const char *name,ParserInterface *parser,bool defParser=FALSE)
161 if (defParser && m_defaultParser==0) m_defaultParser=parser;
162 m_parsers.insert(name,parser);
165 /** Registers a file \a extension with a parser with name \a parserName.
166 * Returns TRUE if the extension was successfully registered.
168 bool registerExtension(const char *extension, const char *parserName)
170 if (parserName==0 || extension==0) return FALSE;
171 ParserInterface *intf = m_parsers.find(parserName);
172 if (intf==0) return FALSE;
173 if (m_extensions.find(extension)!=0) // extension already exists
175 m_extensions.remove(extension); // remove it
177 m_extensions.insert(extension,intf); // add new mapping
181 /** Gets the interface to the parser associated with given \a extension.
182 * If there is no parser explicitly registered for the supplied extension,
183 * the interface to the default parser will be returned.
185 ParserInterface *getParser(const char *extension)
187 QCString ext = QCString(extension).lower();
188 if (ext.isEmpty()) ext=".no_extension";
189 ParserInterface *intf = m_extensions.find(ext);
190 if (intf==0 && ext.length()>4)
192 intf = m_extensions.find(ext.left(4));
194 return intf ? intf : m_defaultParser;
198 QDict<ParserInterface> m_parsers;
199 QDict<ParserInterface> m_extensions;
200 ParserInterface *m_defaultParser;