From 9643f46cc8bab8ab4bea353088a60823bd94fbbc Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 28 Aug 2008 02:57:12 +0200 Subject: [PATCH 1/3] Scons-Wiki: Improvements until 2008 This code was taken from the Wiki and incorporated into the Lumiera.org build system in August 2008 --- __init__.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/__init__.py b/__init__.py index fd51393e7..630fb9f92 100644 --- a/__init__.py +++ b/__init__.py @@ -116,8 +116,17 @@ def DoxySourceScan(node, env, path): 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)) for node in data.get("INPUT", []): + if not os.path.isabs(node): + node = os.path.join(conf_dir, node) if os.path.isfile(node): sources.append(node) elif os.path.isdir(node): @@ -150,7 +159,7 @@ def DoxyEmitter(source, target, env): "HTML": ("YES", "html"), "LATEX": ("YES", "latex"), "RTF": ("NO", "rtf"), - "MAN": ("YES", "man"), + "MAN": ("NO", "man"), "XML": ("NO", "xml"), } @@ -185,13 +194,12 @@ def generate(env): scan_check = DoxySourceScanCheck, ) - doxyfile_builder = env.Builder( - action = env.Action("cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}"), + import SCons.Builder + doxyfile_builder = SCons.Builder.Builder( + action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}", emitter = DoxyEmitter, target_factory = env.fs.Entry, single_source = True, - - source_scanner = doxyfile_scanner, ) From 153dcfb5b22a90c3d9a64081374ad4709bc7cb73 Mon Sep 17 00:00:00 2001 From: Dirk Reiners Date: Mon, 26 Feb 2007 00:00:00 +0100 Subject: [PATCH 2/3] Scons-Wiki: variable substituion and hierarchical doxygen (Reiners) Improvements added by Dirk Reiners: I added two (at least for me ;)) important features of doxygen: variable substituion and hierarchical doxygen files. Variable substituion allows doxygen to reference variables from the scons environment using $(VARNAME). This is very useful for things like version numbers or for only having certain parts (as defined by scons) included in the documentation without having to mess with doxygen files. Hierarchical doxygen files just interpret the @INCLUDE key as an include. I also had trouble with files that started with a key, I fixed that. Note that I'm a python newbie, so there are probably more elegant ways to do some of the things I did. Feel free to change them. Hope it helps. --- __init__.py | 67 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/__init__.py b/__init__.py index fd51393e7..d3938da6f 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,8 @@ -# vim: set et sw=3 tw=0 fo=awqorc ft=python: +# SCons Doxygen Bilder +# +# Copyright (C) 2007 Dirk Reiners +# +# based on the version from http://www.scons.org/wiki/DoxygenBuilder?highlight=%28doxygen%29 # # Astxx, the Asterisk C++ API and Utility Library. # Copyright (C) 2005, 2006 Matthew A. Nicholson @@ -21,8 +25,9 @@ import os import os.path import glob from fnmatch import fnmatch +import subprocess -def DoxyfileParse(file_contents): +def DoxyfileParse(file_contents, file_dir, env): """ Parse a Doxygen source file and return a dictionary of all the values. Values will be strings and lists of strings. @@ -30,20 +35,34 @@ def DoxyfileParse(file_contents): data = {} import shlex + lex = shlex.shlex(instream = file_contents, posix = True) - lex.wordchars += "*+./-:" + lex.wordchars += "*+./-:@$()" lex.whitespace = lex.whitespace.replace("\n", "") - lex.escape = "" - + lex.escape = "" + lineno = lex.lineno token = lex.get_token() key = token # the first token should be a key last_token = "" - key_token = False - next_key = False + key_token = True new_data = True - + def append_data(data, key, new_data, token): + if token[:2] == "$(": + try: + token = env[token[2:-1]] + except KeyError: + print "ERROR: Variable %s used in Doxygen file is not in environment!" % token + token = "" + # Convert space-separated list to actual list + token = token.split() + if len(token): + append_data(data, key, new_data, token[0]) + for i in token[1:]: + append_data(data, key, True, i) + return + if new_data or len(data[key]) == 0: data[key].append(token) else: @@ -64,6 +83,13 @@ def DoxyfileParse(file_contents): data[key] = list() elif token == "=": data[key] = list() + elif key == "@INCLUDE": + + filename = token + if not os.path.isabs(filename): + filename = os.path.join(file_dir, filename) + + lex.push_source(open(filename), filename) else: append_data( data, key, new_data, token ) new_data = True @@ -74,6 +100,7 @@ def DoxyfileParse(file_contents): if last_token == '\\' and token != '\n': new_data = False append_data( data, key, new_data, '\\' ) + # compress lists of len 1 into single strings for (k, v) in data.items(): @@ -107,7 +134,9 @@ def DoxySourceScan(node, env, path): sources = [] - data = DoxyfileParse(node.get_contents()) + conf_dir = os.path.dirname(str(node)) + + data = DoxyfileParse(node.get_contents(), conf_dir, env) if data.get("RECURSIVE", "NO") == "YES": recursive = True @@ -118,6 +147,8 @@ def DoxySourceScan(node, env, path): exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) for node in data.get("INPUT", []): + if not os.path.isabs(node): + node = os.path.join(conf_dir, node) if os.path.isfile(node): sources.append(node) elif os.path.isdir(node): @@ -154,7 +185,7 @@ def DoxyEmitter(source, target, env): "XML": ("NO", "xml"), } - data = DoxyfileParse(source[0].get_contents()) + data = DoxyfileParse(source[0].get_contents(), os.path.dirname(str(source[0])), env) targets = [] out_dir = data.get("OUTPUT_DIRECTORY", ".") @@ -162,6 +193,7 @@ def DoxyEmitter(source, target, env): # add our output locations for (k, v) in output_formats.items(): if data.get("GENERATE_" + k, v[0]) == "YES": + print os.path.join(out_dir, data.get(k + "_OUTPUT", v[1])) targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) # don't clobber targets @@ -174,6 +206,17 @@ def DoxyEmitter(source, target, env): return (targets, source) + +def DoxyAction(source, target, env): + """Doxygen action""" + e={} + for k,v in env.Dictionary().iteritems(): + e[k] = str(v) + p = subprocess.Popen("cd %s && %s %s" % + (os.path.dirname(str(source[0])), env["DOXYGEN"], os.path.basename(str(source[0]))), + shell=True, env=e) + sts = os.waitpid(p.pid, 0) + def generate(env): """ Add builders and construction variables for the @@ -186,12 +229,10 @@ def generate(env): ) doxyfile_builder = env.Builder( - action = env.Action("cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}"), + action = DoxyAction, emitter = DoxyEmitter, target_factory = env.fs.Entry, single_source = True, - - source_scanner = doxyfile_scanner, ) From 30ef78ac307cd2cdf54cba5c0f00a790d5e95066 Mon Sep 17 00:00:00 2001 From: Norton Date: Thu, 20 Dec 2007 00:00:00 +0100 Subject: [PATCH 3/3] Scons-Wiki: generate fake target file in output directory (Norton) --- __init__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/__init__.py b/__init__.py index fd51393e7..9a3f1a134 100644 --- a/__init__.py +++ b/__init__.py @@ -138,7 +138,6 @@ def DoxySourceScan(node, env, path): sources = map( lambda path: env.File(path), sources ) return sources - def DoxySourceScanCheck(node, env): """Check if we should scan this file""" return os.path.isfile(node.path) @@ -159,6 +158,9 @@ def DoxyEmitter(source, target, env): targets = [] out_dir = data.get("OUTPUT_DIRECTORY", ".") + # generate a fake target file in the output directory + targets.append(env.File( os.path.join(out_dir, 'foobar'))) + # add our output locations for (k, v) in output_formats.items(): if data.get("GENERATE_" + k, v[0]) == "YES": @@ -185,13 +187,12 @@ def generate(env): scan_check = DoxySourceScanCheck, ) - doxyfile_builder = env.Builder( - action = env.Action("cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}"), + import SCons.Builder + doxyfile_builder = SCons.Builder.Builder( + action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file} && touch ${TARGET}", emitter = DoxyEmitter, target_factory = env.fs.Entry, single_source = True, - - source_scanner = doxyfile_scanner, )