sconsDoxy: Run converters on chapel and doxygen tools
Signed-off-by: Mats Wichmann <mats@linux.com>
This commit is contained in:
parent
35e74d755d
commit
cce3dad4fe
4 changed files with 93 additions and 46 deletions
|
|
@ -1,4 +1,2 @@
|
||||||
|
env = Environment(tools=["default", "doxygen"], toolpath=".")
|
||||||
env =Environment(tools=['default', 'doxygen'], toolpath='.')
|
env.Doxygen("doxy.cfg")
|
||||||
env.Doxygen('doxy.cfg')
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,5 @@
|
||||||
# License along with this library; if not, write to the Free Software
|
# License along with this library; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
from doxygen import generate
|
from .doxygen import generate
|
||||||
from doxygen import exists
|
from .doxygen import exists
|
||||||
|
|
|
||||||
118
doxygen.py
118
doxygen.py
|
|
@ -28,6 +28,7 @@ import os
|
||||||
import os.path
|
import os.path
|
||||||
import glob
|
import glob
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
# Currently supported output formats and their default
|
# Currently supported output formats and their default
|
||||||
# values and output locations.
|
# values and output locations.
|
||||||
|
|
@ -55,6 +56,7 @@ def DoxyfileParse(file_contents, conf_dir, data=None):
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
lex = shlex.shlex(instream=file_contents, posix=True)
|
lex = shlex.shlex(instream=file_contents, posix=True)
|
||||||
lex.wordchars += "*+./-:@"
|
lex.wordchars += "*+./-:@"
|
||||||
lex.whitespace = lex.whitespace.replace("\n", "")
|
lex.whitespace = lex.whitespace.replace("\n", "")
|
||||||
|
|
@ -75,10 +77,10 @@ def DoxyfileParse(file_contents, conf_dir, data=None):
|
||||||
data[key][-1] += token
|
data[key][-1] += token
|
||||||
|
|
||||||
while token:
|
while token:
|
||||||
if token in ['\n']:
|
if token in ["\n"]:
|
||||||
if last_token not in ['\\']:
|
if last_token not in ["\\"]:
|
||||||
key_token = True
|
key_token = True
|
||||||
elif token in ['\\']:
|
elif token in ["\\"]:
|
||||||
pass
|
pass
|
||||||
elif key_token:
|
elif key_token:
|
||||||
key = token
|
key = token
|
||||||
|
|
@ -105,7 +107,7 @@ def DoxyfileParse(file_contents, conf_dir, data=None):
|
||||||
if nextfile in data[key]:
|
if nextfile in data[key]:
|
||||||
raise Exception("recursive @INCLUDE in Doxygen config: " + nextfile)
|
raise Exception("recursive @INCLUDE in Doxygen config: " + nextfile)
|
||||||
data[key].append(nextfile)
|
data[key].append(nextfile)
|
||||||
fh = open(nextfile, 'r')
|
fh = open(nextfile, "r")
|
||||||
DoxyfileParse(fh.read(), conf_dir, data)
|
DoxyfileParse(fh.read(), conf_dir, data)
|
||||||
fh.close()
|
fh.close()
|
||||||
else:
|
else:
|
||||||
|
|
@ -115,12 +117,12 @@ def DoxyfileParse(file_contents, conf_dir, data=None):
|
||||||
last_token = token
|
last_token = token
|
||||||
token = lex.get_token()
|
token = lex.get_token()
|
||||||
|
|
||||||
if last_token == '\\' and token != '\n':
|
if last_token == "\\" and token != "\n":
|
||||||
new_data = False
|
new_data = False
|
||||||
append_data(data, key, new_data, '\\')
|
append_data(data, key, new_data, "\\")
|
||||||
|
|
||||||
# compress lists of len 1 into single strings
|
# compress lists of len 1 into single strings
|
||||||
for (k, v) in data.items():
|
for (k, v) in list(data.items()):
|
||||||
if len(v) == 0:
|
if len(v) == 0:
|
||||||
data.pop(k)
|
data.pop(k)
|
||||||
|
|
||||||
|
|
@ -140,14 +142,35 @@ def DoxySourceFiles(node, env):
|
||||||
any files used to generate docs to the list of source files.
|
any files used to generate docs to the list of source files.
|
||||||
"""
|
"""
|
||||||
default_file_patterns = [
|
default_file_patterns = [
|
||||||
'*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
|
"*.c",
|
||||||
'*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
|
"*.cc",
|
||||||
'*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
|
"*.cxx",
|
||||||
'*.py',
|
"*.cpp",
|
||||||
|
"*.c++",
|
||||||
|
"*.java",
|
||||||
|
"*.ii",
|
||||||
|
"*.ixx",
|
||||||
|
"*.ipp",
|
||||||
|
"*.i++",
|
||||||
|
"*.inl",
|
||||||
|
"*.h",
|
||||||
|
"*.hh ",
|
||||||
|
"*.hxx",
|
||||||
|
"*.hpp",
|
||||||
|
"*.h++",
|
||||||
|
"*.idl",
|
||||||
|
"*.odl",
|
||||||
|
"*.cs",
|
||||||
|
"*.php",
|
||||||
|
"*.php3",
|
||||||
|
"*.inc",
|
||||||
|
"*.m",
|
||||||
|
"*.mm",
|
||||||
|
"*.py",
|
||||||
]
|
]
|
||||||
|
|
||||||
default_exclude_patterns = [
|
default_exclude_patterns = [
|
||||||
'*~',
|
"*~",
|
||||||
]
|
]
|
||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
|
|
@ -181,8 +204,16 @@ def DoxySourceFiles(node, env):
|
||||||
for f in files:
|
for f in files:
|
||||||
filename = os.path.join(root, f)
|
filename = os.path.join(root, f)
|
||||||
|
|
||||||
pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
|
pattern_check = reduce(
|
||||||
exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
|
lambda x, y: x or bool(fnmatch(filename, y)),
|
||||||
|
file_patterns,
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
exclude_check = reduce(
|
||||||
|
lambda x, y: x and fnmatch(filename, y),
|
||||||
|
exclude_patterns,
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
|
||||||
if pattern_check and not exclude_check:
|
if pattern_check and not exclude_check:
|
||||||
sources.append(filename)
|
sources.append(filename)
|
||||||
|
|
@ -192,12 +223,18 @@ def DoxySourceFiles(node, env):
|
||||||
else:
|
else:
|
||||||
# No INPUT specified, so apply plain patterns only
|
# No INPUT specified, so apply plain patterns only
|
||||||
if recursive:
|
if recursive:
|
||||||
for root, dirs, files in os.walk('.'):
|
for root, dirs, files in os.walk("."):
|
||||||
for f in files:
|
for f in files:
|
||||||
filename = os.path.join(root, f)
|
filename = os.path.join(root, f)
|
||||||
|
|
||||||
pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
|
pattern_check = reduce(
|
||||||
exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
|
lambda x, y: x or bool(fnmatch(filename, y)),
|
||||||
|
file_patterns,
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
exclude_check = reduce(
|
||||||
|
lambda x, y: x and fnmatch(filename, y), exclude_patterns, True
|
||||||
|
)
|
||||||
|
|
||||||
if pattern_check and not exclude_check:
|
if pattern_check and not exclude_check:
|
||||||
sources.append(filename)
|
sources.append(filename)
|
||||||
|
|
@ -219,7 +256,7 @@ def DoxySourceFiles(node, env):
|
||||||
# Add additional files to the list of source files:
|
# Add additional files to the list of source files:
|
||||||
def append_additional_source(option, formats):
|
def append_additional_source(option, formats):
|
||||||
for f in formats:
|
for f in formats:
|
||||||
if data.get('GENERATE_' + f, output_formats[f][0]) == "YES":
|
if data.get("GENERATE_" + f, output_formats[f][0]) == "YES":
|
||||||
file = data.get(option, "")
|
file = data.get(option, "")
|
||||||
if file != "":
|
if file != "":
|
||||||
if not os.path.isabs(file):
|
if not os.path.isabs(file):
|
||||||
|
|
@ -228,9 +265,9 @@ def DoxySourceFiles(node, env):
|
||||||
sources.append(file)
|
sources.append(file)
|
||||||
break
|
break
|
||||||
|
|
||||||
append_additional_source("HTML_STYLESHEET", ['HTML'])
|
append_additional_source("HTML_STYLESHEET", ["HTML"])
|
||||||
append_additional_source("HTML_HEADER", ['HTML'])
|
append_additional_source("HTML_HEADER", ["HTML"])
|
||||||
append_additional_source("HTML_FOOTER", ['HTML'])
|
append_additional_source("HTML_FOOTER", ["HTML"])
|
||||||
|
|
||||||
return sources
|
return sources
|
||||||
|
|
||||||
|
|
@ -241,7 +278,7 @@ def DoxySourceScan(node, env, path):
|
||||||
any files used to generate docs to the list of source files.
|
any files used to generate docs to the list of source files.
|
||||||
"""
|
"""
|
||||||
filepaths = DoxySourceFiles(node, env)
|
filepaths = DoxySourceFiles(node, env)
|
||||||
sources = map(lambda path: env.File(path), filepaths)
|
sources = [env.File(path) for path in filepaths]
|
||||||
return sources
|
return sources
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -262,16 +299,16 @@ def DoxyEmitter(target, source, env):
|
||||||
out_dir = os.path.join(conf_dir, out_dir)
|
out_dir = os.path.join(conf_dir, out_dir)
|
||||||
|
|
||||||
# add our output locations
|
# add our output locations
|
||||||
for (k, v) in output_formats.items():
|
for (k, v) in list(output_formats.items()):
|
||||||
if data.get("GENERATE_" + k, v[0]) == "YES":
|
if data.get("GENERATE_" + k, v[0]) == "YES":
|
||||||
# Initialize output file extension for MAN pages
|
# Initialize output file extension for MAN pages
|
||||||
if k == 'MAN':
|
if k == "MAN":
|
||||||
# Is the given extension valid?
|
# Is the given extension valid?
|
||||||
manext = v[3]
|
manext = v[3]
|
||||||
if v[4] and v[4] in data:
|
if v[4] and v[4] in data:
|
||||||
manext = data.get(v[4])
|
manext = data.get(v[4])
|
||||||
# Try to strip off dots
|
# Try to strip off dots
|
||||||
manext = manext.replace('.', '')
|
manext = manext.replace(".", "")
|
||||||
# Can we convert it to an int?
|
# Can we convert it to an int?
|
||||||
try:
|
try:
|
||||||
e = int(manext)
|
e = int(manext)
|
||||||
|
|
@ -279,7 +316,9 @@ def DoxyEmitter(target, source, env):
|
||||||
# No, so set back to default
|
# No, so set back to default
|
||||||
manext = "3"
|
manext = "3"
|
||||||
|
|
||||||
od = env.Dir(os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]), "man" + manext))
|
od = env.Dir(
|
||||||
|
os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]), "man" + manext)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
od = env.Dir(os.path.join(out_dir, data.get(k + "_OUTPUT", v[1])))
|
od = env.Dir(os.path.join(out_dir, data.get(k + "_OUTPUT", v[1])))
|
||||||
# don't clobber target folders
|
# don't clobber target folders
|
||||||
|
|
@ -294,7 +333,9 @@ def DoxyEmitter(target, source, env):
|
||||||
fname = v[2] + data.get(v[4])
|
fname = v[2] + data.get(v[4])
|
||||||
else:
|
else:
|
||||||
fname = v[2] + v[3]
|
fname = v[2] + v[3]
|
||||||
of = env.File(os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]), fname))
|
of = env.File(
|
||||||
|
os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]), fname)
|
||||||
|
)
|
||||||
targets.append(of)
|
targets.append(of)
|
||||||
# don't clean single files, we remove the complete output folders (see above)
|
# don't clean single files, we remove the complete output folders (see above)
|
||||||
env.NoClean(of)
|
env.NoClean(of)
|
||||||
|
|
@ -306,10 +347,14 @@ def DoxyEmitter(target, source, env):
|
||||||
filepaths = DoxySourceFiles(source[0], env)
|
filepaths = DoxySourceFiles(source[0], env)
|
||||||
for f in filepaths:
|
for f in filepaths:
|
||||||
if os.path.isfile(f) and f != doxy_fpath:
|
if os.path.isfile(f) and f != doxy_fpath:
|
||||||
of = env.File(os.path.join(out_dir,
|
of = env.File(
|
||||||
data.get(k + "_OUTPUT", v[1]),
|
os.path.join(
|
||||||
"man" + manext,
|
out_dir,
|
||||||
f + "." + manext))
|
data.get(k + "_OUTPUT", v[1]),
|
||||||
|
"man" + manext,
|
||||||
|
f + "." + manext,
|
||||||
|
)
|
||||||
|
)
|
||||||
targets.append(of)
|
targets.append(of)
|
||||||
# don't clean single files, we remove the complete output folders (see above)
|
# don't clean single files, we remove the complete output folders (see above)
|
||||||
env.NoClean(of)
|
env.NoClean(of)
|
||||||
|
|
@ -336,6 +381,7 @@ def generate(env):
|
||||||
)
|
)
|
||||||
|
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
|
|
||||||
doxyfile_builder = SCons.Builder.Builder(
|
doxyfile_builder = SCons.Builder.Builder(
|
||||||
action="cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}",
|
action="cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}",
|
||||||
emitter=DoxyEmitter,
|
emitter=DoxyEmitter,
|
||||||
|
|
@ -344,12 +390,14 @@ def generate(env):
|
||||||
source_scanner=doxyfile_scanner,
|
source_scanner=doxyfile_scanner,
|
||||||
)
|
)
|
||||||
|
|
||||||
env.Append(BUILDERS={
|
env.Append(
|
||||||
'Doxygen': doxyfile_builder,
|
BUILDERS={
|
||||||
})
|
"Doxygen": doxyfile_builder,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
env.AppendUnique(
|
env.AppendUnique(
|
||||||
DOXYGEN='doxygen',
|
DOXYGEN="doxygen",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
11
test.py
11
test.py
|
|
@ -22,11 +22,11 @@
|
||||||
import unittest
|
import unittest
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from doxygen import DoxyfileParse
|
from .doxygen import DoxyfileParse
|
||||||
|
|
||||||
|
|
||||||
class TestParser(unittest.TestCase):
|
class TestParser(unittest.TestCase):
|
||||||
test_config_dir = os.path.join(os.path.dirname(__file__), 'test_config')
|
test_config_dir = os.path.join(os.path.dirname(__file__), "test_config")
|
||||||
|
|
||||||
def test_simple_parse(self):
|
def test_simple_parse(self):
|
||||||
text = """
|
text = """
|
||||||
|
|
@ -45,13 +45,14 @@ INPUT = test.h
|
||||||
text = """@INCLUDE=include_test.cfg"""
|
text = """@INCLUDE=include_test.cfg"""
|
||||||
result = DoxyfileParse(text, self.test_config_dir)
|
result = DoxyfileParse(text, self.test_config_dir)
|
||||||
self.assertEqual(["abc"], result["INPUT"])
|
self.assertEqual(["abc"], result["INPUT"])
|
||||||
self.assertEqual([os.path.join(self.test_config_dir, "include_test.cfg")],
|
self.assertEqual(
|
||||||
result["@INCLUDE"])
|
[os.path.join(self.test_config_dir, "include_test.cfg")], result["@INCLUDE"]
|
||||||
|
)
|
||||||
|
|
||||||
def test_recursive_include_tag(self):
|
def test_recursive_include_tag(self):
|
||||||
text = """@INCLUDE=recursive_include_test.cfg"""
|
text = """@INCLUDE=recursive_include_test.cfg"""
|
||||||
self.assertRaises(Exception, DoxyfileParse, text, self.test_config_dir)
|
self.assertRaises(Exception, DoxyfileParse, text, self.test_config_dir)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue