# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-# The Modifications are Copyright (C) 2006,2007
+# The Modifications are Copyright (C) 2006,2007,2008,2009
# Fraunhofer Institute for Open Communication Systems (FOKUS)
# Competence Center NETwork research (NET), St. Augustin, GERMANY
# Stefan Bund <g0dil@berlios.de>
-## \file
-# \brief Doxygen builder
-
-## \package senfscons.Doxygen
-# \brief Doxygen Documentation Builder
-#
-# This builder will invoke \c doxygen to build software
-# documentation. The doxygen builder only takes the name of the
-# doxyfile as it's source file. The builder parses that doxygen
-# configuration file.
-#
-# The builder will automatically find all sources on which the
-# documentation depends. This includes
-# \li the source code files (as selected by the \c RECURSIVE, \c
-# FILE_PATTERNS, \c INPUT and \c EXCLUDE_PATTERNS doxygen
-# directives
-# \li the \c HTML_HEADER and \c HTML_FOOTER
-# \li all referenced \c TAGFILES
-# \li the \c INPUT_FILTER
-# \li all included doxyfiles (via \c @INCLUDE)
-#
-# The builder will emit a list of targets built by doxygen. This
-# depends on the types of documentation built.
-#
-# The builder will also generate additional commands to resolve
-# cross-references to other module documentations. This is based on
-# the \c TAGFILES used. Tagfiles built in the same project in other
-# modules are automatically found and the links will be resolved
-# correctly. To resolve links from external tagfiles, you may specify
-# <i>tagfilename</i><tt>_DOXY_URL</tt> as a construction environment
-# variable to specify the path to resolve references from the given
-# tagfile to. <i>tagfilename</i> is the uppercased basename of the
-# tagfile used.
-#
-# \par Construction Envrionment Variables:
-# <table class="senf">
-# <tr><td>\c DOXYGEN</td><td>doxygen command, defaults to \c doxygen</td></tr>
-# <tr><td><i>tag</i><tt>_DOXY_URL</tt></td><td>external tagfile resolve URL</td></tr>
-# </table>
-#
-# \ingroup builder
-
# I (g0dil@berlios.de) have been fighting 4 problems in this
# implementation:
# - A Directory target will *not* call any source scanners
# - Theres a bug in SCons which will produce an error message for
# directory targets if dir.sources is not set explicitly
# - the first argument to env.Clean() must be the command line target,
-# with which the scons was invoked. This does not help to add
-# aditional files or directories to be cleaned if you don't know
-# that target (it's not possible to say 'if you clean this file,
-# also clean that one' hich is, what I had expected env.Clean to
-# do).
+# with which scons was invoked. This does not help to add aditional
+# files or directories to be cleaned if you don't know that target
+# (it's not possible to say 'if you clean this file, also clean that
+# one' which is, what I had expected env.Clean to do).
#
# Together, these problems have produced several difficulties. I have
# solved them by
# cause source scanners to be invoked
# - Adding the documentation directory as a target (so it will be
# cleaned up which env.Clean doesn't help me to do), but *only* if
-# scons is called to with the -c option
+# scons is called with the -c option
# - Setting dir.sources to the known source-list to silence the error
# message whenever a directory is added as a target
#
ENVVAR_RE = re.compile(r"\$\(([0-9A-Za-z_-]+)\)")
- def __init__(self, path, env, include_path=None, items = None):
+ def __init__(self, node, env, include_path=None, items = None):
+ self._node = node
self._env = env
self._include_path = include_path or []
- self._lexer = DoxyfileLexer(file(path))
- self._dir = os.path.split(path)[0]
+ self._lexer = DoxyfileLexer(file(node.srcnode().get_path()))
+ self._dir = node.dir
self._items = items or {}
def parse(self):
if len(value) != 1:
raise ValueError,"Invalid argument to @INCLUDE"
- for d in [ self._dir ] + self._include_path:
+ for d in [ self._dir.get_path() ] + self._include_path:
p = os.path.join(d,value[0])
if os.path.exists(p):
self._items.setdefault('@INCLUDE',[]).append(p)
- parser = DoxyfileParser(p, self._env, self._include_path, self._items)
+ parser = DoxyfileParser(self._node.File(p), self._env, self._include_path, self._items)
parser.parse()
return
- raise ValueError,"@INCLUDE file not found"
+ raise ValueError,"@INCLUDE file '%s' not found" % value[0]
def _INCLUDE_PATH(self, op, value):
self._include_path.extend(value)
def items(self):
return self._items
-def DoxyfileParse(env,file):
+def DoxyfileParse(env,node):
# We don't parse source files which do not contain the word 'doxyfile'. SCons will
# pass other dependencies to DoxyfileParse which are not doxyfiles ... grmpf ...
- if not 'doxyfile' in file.lower():
- return {}
ENV = {}
ENV.update(env.get("ENV",{}))
ENV.update(env.get("DOXYENV", {}))
- parser = DoxyfileParser(file,ENV)
+ parser = DoxyfileParser(node,ENV)
try:
parser.parse()
except ValueError, v:
sources = []
basedir = node.dir.abspath
- data = DoxyfileParse(env, node.abspath)
+ data = DoxyfileParse(env, node)
recursive = data.get("RECURSIVE", "NO").upper()=="YES"
file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
def DoxySourceScanCheck(node, env):
"""Check if we should scan this file"""
- return os.path.isfile(node.path)
+ return os.path.isfile(node.path) and 'doxyfile' in node.name.lower()
def DoxyEmitter(source, target, env):
"""Doxygen Doxyfile emitter"""
"XML" : ("NO", "xml"),
}
- data = DoxyfileParse(env, source[0].abspath)
+ data = DoxyfileParse(env, source[0])
targets = []
if data.get("OUTPUT_DIRECTORY",""):
def doxyNodeHtmlDir(env,node):
if not node.sources : return None
- data = DoxyfileParse(env, node.sources[0].abspath)
+ data = DoxyfileParse(env, node.sources[0])
if data.get("GENERATE_HTML",'YES').upper() != 'YES' : return None
return os.path.normpath(os.path.join( node.sources[0].dir.abspath,
data.get("OUTPUT_DIRECTORY","."),
return os.path.join(*([".."] * (len(source_elts) - prefix_len) +
target_elts[prefix_len:]))
-def DoxyGenerator(source, target, env, for_signature):
- data = DoxyfileParse(env, source[0].abspath)
- actions = [
- SCons.Action.Action("$DOXYGENCOM"),
- SCons.Action.Action([ "touch $TARGETS" ]),
- ]
-
- return actions
+def doxyAction(target, source, env):
+ e = {}
+ e.update(env['ENV'])
+ for k,v in env.get('DOXYENV',[]).iteritems() : e[k] = env.subst(v)
+ SCons.Action.Action("$DOXYGENCOM")(target, source, env.Clone(ENV = e), show=False)
+
+def doxyActionStr(target, source, env):
+ return env.subst("$DOXYGENCOM",target=target,source=source)
def generate(env):
"""
)
doxyfile_builder = env.Builder(
- generator = DoxyGenerator,
+ action = [ SCons.Action.Action(doxyAction, doxyActionStr),
+ SCons.Action.Action([ "touch $TARGETS" ]) ],
emitter = DoxyEmitter,
target_factory = env.fs.Entry,
single_source = True,