[Cppunit-cvs] cppunit2/scons-tools doxygen.py, NONE, 1.1 srcdist.py, NONE, 1.1 substinfile.py, NONE
Brought to you by:
blep
From: Baptiste L. <bl...@us...> - 2006-06-06 03:05:54
|
Update of /cvsroot/cppunit/cppunit2/scons-tools In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv26100/scons-tools Added Files: doxygen.py srcdist.py substinfile.py targz.py Log Message: - synchronized with lastest jsoncpp. --- NEW FILE: doxygen.py --- import os import os.path import glob from fnmatch import fnmatch def DoxyfileParse(file_contents): """ Parse a Doxygen source file and return a dictionary of all the values. Values will be strings and lists of strings. """ data = {} import shlex lex = shlex.shlex(instream = file_contents, posix = True) lex.wordchars += "*+./-:" lex.whitespace = lex.whitespace.replace("\n", "") lex.escape = "" lineno = lex.lineno last_backslash_lineno = lineno token = lex.get_token() key = token # the first token should be a key last_token = "" key_token = False next_key = False new_data = True def append_data(data, key, new_data, token): if new_data or len(data[key]) == 0: data[key].append(token) else: data[key][-1] += token while token: if token in ['\n']: if last_token not in ['\\']: key_token = True elif token in ['\\']: pass elif key_token: key = token key_token = False else: if token == "+=": if not data.has_key(key): data[key] = list() elif token == "=": data[key] = list() else: append_data( data, key, new_data, token ) new_data = True last_token = token token = lex.get_token() 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(): if len(v) == 0: 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"]: continue if len(v) == 1: data[k] = v[0] return data def DoxySourceScan(node, env, path): """ Doxygen Doxyfile source scanner. This should scan the Doxygen file and add any files used to generate docs to the list of source files. """ default_file_patterns = [ '*.c', '*.cc', '*.cxx', '*.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 = [ '*~', ] sources = [] data = DoxyfileParse(node.get_contents()) if data.get("RECURSIVE", "NO") == "YES": recursive = True else: recursive = False file_patterns = data.get("FILE_PATTERNS", default_file_patterns) exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) for node in data.get("INPUT", []): if os.path.isfile(node): sources.add(node) elif os.path.isdir(node): if recursive: for root, dirs, files in os.walk(node): for f in files: filename = os.path.join(root, f) pattern_check = reduce(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: sources.append(filename) else: for pattern in file_patterns: sources.extend(glob.glob("/".join([node, pattern]))) 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) def DoxyEmitter(source, target, env): """Doxygen Doxyfile emitter""" # possible output formats and their default values and output locations output_formats = { "HTML": ("YES", "html"), "LATEX": ("YES", "latex"), "RTF": ("NO", "rtf"), "MAN": ("YES", "man"), "XML": ("NO", "xml"), } data = DoxyfileParse(source[0].get_contents()) targets = [] out_dir = data.get("OUTPUT_DIRECTORY", ".") # add our output locations for (k, v) in output_formats.items(): if data.get("GENERATE_" + k, v[0]) == "YES": targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) # don't clobber targets for node in targets: env.Precious(node) # set up cleaning stuff for node in targets: env.Clean(node, node) return (targets, source) def generate(env): """ Add builders and construction variables for the Doxygen tool. This is currently for Doxygen 1.4.6. """ doxyfile_scanner = env.Scanner( DoxySourceScan, "DoxySourceScan", scan_check = DoxySourceScanCheck, ) doxyfile_builder = env.Builder( action = env.Action("cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}"), emitter = DoxyEmitter, target_factory = env.fs.Entry, single_source = True, source_scanner = doxyfile_scanner, ) env.Append(BUILDERS = { 'Doxygen': doxyfile_builder, }) env.AppendUnique( DOXYGEN = 'doxygen', ) def exists(env): """ Make sure doxygen exists. """ return env.Detect("doxygen") --- NEW FILE: targz.py --- """tarball Tool-specific initialization for tarball. """ ## Commands to tackle a command based implementation: ##to unpack on the fly... ##gunzip < FILE.tar.gz | tar xvf - ##to pack on the fly... ##tar cvf - FILE-LIST | gzip -c > FILE.tar.gz import os.path import SCons.Builder import SCons.Node.FS import SCons.Util try: import gzip import tarfile internal_targz = 1 except ImportError: internal_targz = 0 TARGZ_DEFAULT_COMPRESSION_LEVEL = 9 if internal_targz: def targz(target, source, env): def archive_name( path ): path = os.path.normpath( os.path.abspath( path ) ) common_path = os.path.commonprefix( (base_dir, path) ) archive_name = path[len(common_path):] return archive_name def visit(tar, dirname, names): for name in names: path = os.path.join(dirname, name) if os.path.isfile(path): tar.add(path, archive_name(path) ) compression = env.get('TARGZ_COMPRESSION_LEVEL',TARGZ_DEFAULT_COMPRESSION_LEVEL) base_dir = os.path.normpath( env.get('TARGZ_BASEDIR', env.Dir('.')).abspath ) target_path = str(target[0]) fileobj = gzip.GzipFile( target_path, 'wb', compression ) tar = tarfile.TarFile(os.path.splitext(target_path)[0], 'w', fileobj) for source in source: source_path = str(source) if source.isdir(): os.path.walk(source_path, visit, tar) else: tar.add(source_path, archive_name(source_path) ) # filename, arcname tar.close() targzAction = SCons.Action.Action(targz, varlist=['TARGZ_COMPRESSION_LEVEL','TARGZ_BASEDIR']) def makeBuilder( emitter = None ): return SCons.Builder.Builder(action = SCons.Action.Action('$TARGZ_COM', '$TARGZ_COMSTR'), source_factory = SCons.Node.FS.Entry, source_scanner = SCons.Defaults.DirScanner, suffix = '$TARGZ_SUFFIX', multi = 1) TarGzBuilder = makeBuilder() def generate(env): """Add Builders and construction variables for zip to an Environment. The following environnement variables may be set: TARGZ_COMPRESSION_LEVEL: integer, [0-9]. 0: no compression, 9: best compression (same as gzip compression level). TARGZ_BASEDIR: base-directory used to determine archive name (this allow archive name to be relative to something other than top-dir). """ env['BUILDERS']['TarGz'] = TarGzBuilder env['TARGZ_COM'] = targzAction env['TARGZ_COMPRESSION_LEVEL'] = TARGZ_DEFAULT_COMPRESSION_LEVEL # range 0-9 env['TARGZ_SUFFIX'] = '.tar.gz' env['TARGZ_BASEDIR'] = env.Dir('.') # Sources archive name are made relative to that directory. def exists(env): return internal_targz --- NEW FILE: srcdist.py --- import os import os.path import glob from fnmatch import fnmatch import targz ##def DoxyfileParse(file_contents): ## """ ## Parse a Doxygen source file and return a dictionary of all the values. ## Values will be strings and lists of strings. ## """ ## data = {} ## ## import shlex ## lex = shlex.shlex(instream = file_contents, posix = True) ## lex.wordchars += "*+./-:" ## lex.whitespace = lex.whitespace.replace("\n", "") ## lex.escape = "" ## ## lineno = lex.lineno ## last_backslash_lineno = lineno ## token = lex.get_token() ## key = token # the first token should be a key ## last_token = "" ## key_token = False ## next_key = False ## new_data = True ## ## def append_data(data, key, new_data, token): ## if new_data or len(data[key]) == 0: ## data[key].append(token) ## else: ## data[key][-1] += token ## ## while token: ## if token in ['\n']: ## if last_token not in ['\\']: ## key_token = True ## elif token in ['\\']: ## pass ## elif key_token: ## key = token ## key_token = False ## else: ## if token == "+=": ## if not data.has_key(key): ## data[key] = list() ## elif token == "=": ## data[key] = list() ## else: ## append_data( data, key, new_data, token ) ## new_data = True ## ## last_token = token ## token = lex.get_token() ## ## 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(): ## if len(v) == 0: ## 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"]: ## continue ## ## if len(v) == 1: ## data[k] = v[0] ## ## return data ## ##def DoxySourceScan(node, env, path): ## """ ## Doxygen Doxyfile source scanner. This should scan the Doxygen file and add ## any files used to generate docs to the list of source files. ## """ ## default_file_patterns = [ ## '*.c', '*.cc', '*.cxx', '*.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 = [ ## '*~', ## ] ## ## sources = [] ## ## data = DoxyfileParse(node.get_contents()) ## ## if data.get("RECURSIVE", "NO") == "YES": ## recursive = True ## else: ## recursive = False ## ## file_patterns = data.get("FILE_PATTERNS", default_file_patterns) ## exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) ## ## for node in data.get("INPUT", []): ## if os.path.isfile(node): ## sources.add(node) ## elif os.path.isdir(node): ## if recursive: ## for root, dirs, files in os.walk(node): ## for f in files: ## filename = os.path.join(root, f) ## ## pattern_check = reduce(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: ## sources.append(filename) ## else: ## for pattern in file_patterns: ## sources.extend(glob.glob("/".join([node, pattern]))) ## 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) def srcDistEmitter(source, target, env): ## """Doxygen Doxyfile emitter""" ## # possible output formats and their default values and output locations ## output_formats = { ## "HTML": ("YES", "html"), ## "LATEX": ("YES", "latex"), ## "RTF": ("NO", "rtf"), ## "MAN": ("YES", "man"), ## "XML": ("NO", "xml"), ## } ## ## data = DoxyfileParse(source[0].get_contents()) ## ## targets = [] ## out_dir = data.get("OUTPUT_DIRECTORY", ".") ## ## # add our output locations ## for (k, v) in output_formats.items(): ## if data.get("GENERATE_" + k, v[0]) == "YES": ## targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) ## ## # don't clobber targets ## for node in targets: ## env.Precious(node) ## ## # set up cleaning stuff ## for node in targets: ## env.Clean(node, node) ## ## return (targets, source) return (target,source) def generate(env): """ Add builders and construction variables for the SrcDist tool. """ ## doxyfile_scanner = env.Scanner( ## DoxySourceScan, ## "DoxySourceScan", ## scan_check = DoxySourceScanCheck, ## ) srcdist_builder = targz.makeBuilder( srcDistEmitter ) env['BUILDERS']['SrcDist'] = srcdist_builder def exists(env): """ Make sure srcdist exists. """ return True --- NEW FILE: substinfile.py --- import re from SCons.Script import * # the usual scons stuff you get in a SConscript def generate(env): """ Add builders and construction variables for the SubstInFile tool. Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT from the source to the target. The values of SUBST_DICT first have any construction variables expanded (its keys are not expanded). If a value of SUBST_DICT is a python callable function, it is called and the result is expanded as the value. If there's more than one source and more than one target, each target gets substituted from the corresponding source. """ def do_subst_in_file(targetfile, sourcefile, dict): """Replace all instances of the keys of dict with their values. For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'}, then all instances of %VERSION% in the file will be replaced with 1.2345 etc. """ try: f = open(sourcefile, 'rb') contents = f.read() f.close() except: raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile for (k,v) in dict.items(): contents = re.sub(k, v, contents) try: f = open(targetfile, 'wb') f.write(contents) f.close() except: raise SCons.Errors.UserError, "Can't write target file %s"%targetfile return 0 # success def subst_in_file(target, source, env): if not env.has_key('SUBST_DICT'): raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set." d = dict(env['SUBST_DICT']) # copy it for (k,v) in d.items(): if callable(v): d[k] = env.subst(v()).replace('\\','\\\\') elif SCons.Util.is_String(v): d[k] = env.subst(v).replace('\\','\\\\') else: raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v)) for (t,s) in zip(target, source): return do_subst_in_file(str(t), str(s), d) def subst_in_file_string(target, source, env): """This is what gets printed on the console.""" return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t)) for (t,s) in zip(target, source)]) def subst_emitter(target, source, env): """Add dependency from substituted SUBST_DICT to target. Returns original target, source tuple unchanged. """ d = env['SUBST_DICT'].copy() # copy it for (k,v) in d.items(): if callable(v): d[k] = env.subst(v()) elif SCons.Util.is_String(v): d[k]=env.subst(v) Depends(target, SCons.Node.Python.Value(d)) return target, source ## env.Append(TOOLS = 'substinfile') # this should be automaticaly done by Scons ?!? subst_action = SCons.Action.Action( subst_in_file, subst_in_file_string ) env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter) def exists(env): """ Make sure tool exists. """ return True |