Add support for @INCLUDE tags in doxyfiles
Doxygen configs can include other doxygen configs. Add support for @INCLUDE tag.
This commit is contained in:
parent
22dfdfb824
commit
c876fe0044
4 changed files with 52 additions and 16 deletions
48
doxygen.py
48
doxygen.py
|
|
@ -43,16 +43,17 @@ output_formats = {
|
|||
"XML": ("NO", "xml", "index", ".xml", ""),
|
||||
}
|
||||
|
||||
def DoxyfileParse(file_contents):
|
||||
def DoxyfileParse(file_contents, conf_dir, data=None):
|
||||
"""
|
||||
Parse a Doxygen source file and return a dictionary of all the values.
|
||||
Values will be strings and lists of strings.
|
||||
"""
|
||||
data = {}
|
||||
if data is None:
|
||||
data = {}
|
||||
|
||||
import shlex
|
||||
lex = shlex.shlex(instream = file_contents, posix = True)
|
||||
lex.wordchars += "*+./-:"
|
||||
lex.wordchars += "*+./-:@"
|
||||
lex.whitespace = lex.whitespace.replace("\n", "")
|
||||
lex.escape = ""
|
||||
|
||||
|
|
@ -87,12 +88,28 @@ def DoxyfileParse(file_contents):
|
|||
if key == "TAGFILES" and data.has_key(key):
|
||||
append_data( data, key, False, "=" )
|
||||
new_data=False
|
||||
elif key == "@INCLUDE" and data.has_key(key):
|
||||
# don't reset the @INCLUDE list when we see a new @INCLUDE line.
|
||||
pass
|
||||
else:
|
||||
data[key] = list()
|
||||
elif key == "@INCLUDE":
|
||||
# special case for @INCLUDE key: read the referenced
|
||||
# file as a doxyfile too.
|
||||
nextfile = token
|
||||
if not os.path.isabs(nextfile):
|
||||
nextfile = os.path.join(conf_dir, nextfile)
|
||||
if nextfile in data[key]:
|
||||
raise Exception("recursive @INCLUDE in Doxygen config: "+nextfile)
|
||||
data[key].append(nextfile)
|
||||
fh = open(nextfile,'r')
|
||||
DoxyfileParse(fh.read(), conf_dir, data)
|
||||
fh.close()
|
||||
else:
|
||||
append_data( data, key, new_data, token )
|
||||
new_data = True
|
||||
|
||||
|
||||
last_token = token
|
||||
token = lex.get_token()
|
||||
|
||||
|
|
@ -106,7 +123,7 @@ def DoxyfileParse(file_contents):
|
|||
data.pop(k)
|
||||
|
||||
# items in the following list will be kept as lists and not converted to strings
|
||||
if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS", "TAGFILES"]:
|
||||
if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS", "TAGFILES", "@INCLUDE"]:
|
||||
continue
|
||||
|
||||
if len(v) == 1:
|
||||
|
|
@ -132,7 +149,13 @@ def DoxySourceFiles(node, env):
|
|||
|
||||
sources = []
|
||||
|
||||
data = DoxyfileParse(node.get_contents())
|
||||
# We're running in the top-level directory, but the doxygen
|
||||
# configuration file is in the same directory as node; this means
|
||||
# that relative pathnames in node must be adjusted before they can
|
||||
# go onto the sources list
|
||||
conf_dir = os.path.dirname(str(node))
|
||||
|
||||
data = DoxyfileParse(node.get_contents(), conf_dir)
|
||||
|
||||
if data.get("RECURSIVE", "NO") == "YES":
|
||||
recursive = True
|
||||
|
|
@ -142,12 +165,6 @@ def DoxySourceFiles(node, env):
|
|||
file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
|
||||
exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
|
||||
|
||||
# We're running in the top-level directory, but the doxygen
|
||||
# configuration file is in the same directory as node; this means
|
||||
# that relative pathnames in node must be adjusted before they can
|
||||
# go onto the sources list
|
||||
conf_dir = os.path.dirname(str(node))
|
||||
|
||||
input = data.get("INPUT")
|
||||
if input:
|
||||
for node in data.get("INPUT", []):
|
||||
|
|
@ -185,6 +202,10 @@ def DoxySourceFiles(node, env):
|
|||
for pattern in file_patterns:
|
||||
sources.extend(glob.glob(pattern))
|
||||
|
||||
# Add @INCLUDEd files to the list of source files:
|
||||
for node in data.get("@INCLUDE", []):
|
||||
sources.append(node)
|
||||
|
||||
# Add tagfiles to the list of source files:
|
||||
for node in data.get("TAGFILES", []):
|
||||
file = node.split("=")[0]
|
||||
|
|
@ -226,12 +247,12 @@ def DoxySourceScanCheck(node, env):
|
|||
def DoxyEmitter(target, source, env):
|
||||
"""Doxygen Doxyfile emitter"""
|
||||
doxy_fpath = str(source[0])
|
||||
data = DoxyfileParse(source[0].get_contents())
|
||||
conf_dir = os.path.dirname(doxy_fpath)
|
||||
data = DoxyfileParse(source[0].get_contents(), conf_dir)
|
||||
|
||||
targets = []
|
||||
out_dir = data.get("OUTPUT_DIRECTORY", ".")
|
||||
if not os.path.isabs(out_dir):
|
||||
conf_dir = os.path.dirname(doxy_fpath)
|
||||
out_dir = os.path.join(conf_dir, out_dir)
|
||||
|
||||
# add our output locations
|
||||
|
|
@ -291,7 +312,6 @@ def DoxyEmitter(target, source, env):
|
|||
tagfile = data.get("GENERATE_TAGFILE", "")
|
||||
if tagfile != "":
|
||||
if not os.path.isabs(tagfile):
|
||||
conf_dir = os.path.dirname(str(source[0]))
|
||||
tagfile = os.path.join(conf_dir, tagfile)
|
||||
targets.append(env.File(tagfile))
|
||||
|
||||
|
|
|
|||
18
test.py
18
test.py
|
|
@ -9,19 +9,33 @@ import sys
|
|||
from doxygen import DoxyfileParse
|
||||
|
||||
class TestParser(unittest.TestCase):
|
||||
test_config_dir = os.path.join(os.path.dirname(__file__),'test_config')
|
||||
|
||||
def test_simple_parse(self):
|
||||
text="""
|
||||
# comment
|
||||
INPUT = test.h
|
||||
"""
|
||||
result = DoxyfileParse(text)
|
||||
result = DoxyfileParse(text, self.test_config_dir)
|
||||
self.assertEqual(["test.h"], result["INPUT"])
|
||||
|
||||
def test_parse_tag_on_first_line(self):
|
||||
text="""INPUT=."""
|
||||
result = DoxyfileParse(text)
|
||||
result = DoxyfileParse(text, self.test_config_dir)
|
||||
self.assertEqual(["."], result["INPUT"])
|
||||
|
||||
def test_include_tag(self):
|
||||
text="""@INCLUDE=include_test.cfg"""
|
||||
result = DoxyfileParse(text, self.test_config_dir)
|
||||
self.assertEqual(["abc"], result["INPUT"])
|
||||
self.assertEqual([os.path.join(self.test_config_dir,
|
||||
"include_test.cfg")],
|
||||
result["@INCLUDE"])
|
||||
|
||||
def test_recursive_include_tag(self):
|
||||
text="""@INCLUDE=recursive_include_test.cfg"""
|
||||
self.assertRaises(Exception, DoxyfileParse, text, self.test_config_dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
|||
1
test_config/include_test.cfg
Normal file
1
test_config/include_test.cfg
Normal file
|
|
@ -0,0 +1 @@
|
|||
INPUT="abc"
|
||||
1
test_config/recursive_include_test.cfg
Normal file
1
test_config/recursive_include_test.cfg
Normal file
|
|
@ -0,0 +1 @@
|
|||
@INCLUDE=recursive_include_test.cfg
|
||||
Loading…
Reference in a new issue