diff options
| author | Greg Noel <GregNoel@tigris.org> | 2009-04-22 20:17:29 (GMT) |
|---|---|---|
| committer | Greg Noel <GregNoel@tigris.org> | 2009-04-22 20:17:29 (GMT) |
| commit | c87d08dc59a35cf77f69e07ca491c39999d0c0b1 (patch) | |
| tree | a8b6310321febc631edf9d79c0ea92ba4fb42af5 /src/engine | |
| parent | 565fa2e2e6ccf707cd9ccf20c3504af771548f63 (diff) | |
| download | SCons-c87d08dc59a35cf77f69e07ca491c39999d0c0b1.zip SCons-c87d08dc59a35cf77f69e07ca491c39999d0c0b1.tar.gz SCons-c87d08dc59a35cf77f69e07ca491c39999d0c0b1.tar.bz2 | |
Add Textfile and Substfile builders
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/MANIFEST-xml.in | 33 | ||||
| -rw-r--r-- | src/engine/MANIFEST.in | 1 | ||||
| -rw-r--r-- | src/engine/SCons/Tool/textfile.py | 166 |
3 files changed, 184 insertions, 16 deletions
diff --git a/src/engine/MANIFEST-xml.in b/src/engine/MANIFEST-xml.in index 5a5c9b6..9cc9923 100644 --- a/src/engine/MANIFEST-xml.in +++ b/src/engine/MANIFEST-xml.in @@ -6,19 +6,24 @@ SCons/Platform/posix.xml SCons/Platform/sunos.xml SCons/Platform/win32.xml SCons/Tool/386asm.xml -SCons/Tool/aixcc.xml +SCons/Tool/BitKeeper.xml +SCons/Tool/CVS.xml +SCons/Tool/Perforce.xml +SCons/Tool/RCS.xml +SCons/Tool/SCCS.xml +SCons/Tool/Subversion.xml +SCons/Tool/__init__.xml SCons/Tool/aixc++.xml +SCons/Tool/aixcc.xml SCons/Tool/aixf77.xml SCons/Tool/aixlink.xml SCons/Tool/applelink.xml SCons/Tool/ar.xml SCons/Tool/as.xml SCons/Tool/bcc32.xml -SCons/Tool/BitKeeper.xml +SCons/Tool/c++.xml SCons/Tool/cc.xml SCons/Tool/cvf.xml -SCons/Tool/CVS.xml -SCons/Tool/c++.xml SCons/Tool/default.xml SCons/Tool/dmd.xml SCons/Tool/dvi.xml @@ -28,31 +33,30 @@ SCons/Tool/f77.xml SCons/Tool/f90.xml SCons/Tool/f95.xml SCons/Tool/fortran.xml +SCons/Tool/g++.xml SCons/Tool/g77.xml SCons/Tool/gas.xml SCons/Tool/gcc.xml SCons/Tool/gnulink.xml SCons/Tool/gs.xml -SCons/Tool/g++.xml -SCons/Tool/hpcc.xml SCons/Tool/hpc++.xml +SCons/Tool/hpcc.xml SCons/Tool/hplink.xml SCons/Tool/icc.xml SCons/Tool/icl.xml SCons/Tool/ifl.xml SCons/Tool/ifort.xml -SCons/Tool/ilink32.xml SCons/Tool/ilink.xml -SCons/Tool/__init__.xml -SCons/Tool/intelc.xml +SCons/Tool/ilink32.xml SCons/Tool/install.xml +SCons/Tool/intelc.xml SCons/Tool/jar.xml SCons/Tool/javac.xml SCons/Tool/javah.xml SCons/Tool/latex.xml SCons/Tool/lex.xml -SCons/Tool/linkloc.xml SCons/Tool/link.xml +SCons/Tool/linkloc.xml SCons/Tool/m4.xml SCons/Tool/masm.xml SCons/Tool/midl.xml @@ -70,24 +74,21 @@ SCons/Tool/packaging/__init__.xml SCons/Tool/pdf.xml SCons/Tool/pdflatex.xml SCons/Tool/pdftex.xml -SCons/Tool/Perforce.xml SCons/Tool/qt.xml -SCons/Tool/RCS.xml SCons/Tool/rmic.xml SCons/Tool/rpcgen.xml -SCons/Tool/SCCS.xml SCons/Tool/sgiar.xml -SCons/Tool/sgicc.xml SCons/Tool/sgic++.xml +SCons/Tool/sgicc.xml SCons/Tool/sgilink.xml -SCons/Tool/Subversion.xml SCons/Tool/sunar.xml -SCons/Tool/suncc.xml SCons/Tool/sunc++.xml +SCons/Tool/suncc.xml SCons/Tool/sunlink.xml SCons/Tool/swig.xml SCons/Tool/tar.xml SCons/Tool/tex.xml +SCons/Tool/textfile.xml SCons/Tool/tlib.xml SCons/Tool/yacc.xml SCons/Tool/zip.xml diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index ede9888..e7c9bd8 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -169,6 +169,7 @@ SCons/Tool/sunlink.py SCons/Tool/swig.py SCons/Tool/tar.py SCons/Tool/tex.py +SCons/Tool/textfile.py SCons/Tool/tlib.py SCons/Tool/wix.py SCons/Tool/yacc.py diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py new file mode 100644 index 0000000..8fa2180 --- /dev/null +++ b/src/engine/SCons/Tool/textfile.py @@ -0,0 +1,166 @@ +# -*- python -*- +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +""" +Textfile/Substfile builder for SCons. + + Create file 'target' which typically is a textfile. The 'source' + may be any combination of strings, Nodes, or lists of same. A + 'linesep' will be put between any part written and defaults to + os.linesep. + + The only difference between the Textfile builder and the Substfile + builder is that strings are converted to Value() nodes for the + former and File() nodes for the latter. To insert files in the + former or strings in the latter, wrap them in a File() or Value(), + respectively. + + 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. Values are substituted in a "random" order; if any + substitution could be further expanded by another subsitition, it + is unpredictible whether the expansion will occur. +""" + +import SCons + +import os +import re + +from SCons.Node import Node +from SCons.Node.Python import Value +from SCons.Util import is_List, is_String + +def _do_subst(node, subs): + """ + Fetch the node contents and replace all instances of the keys with + their values. For example, if subs is + {'%VERSION%': '1.2345', '%BASE%': 'MyProg', '%prefix%': '/bin'}, + then all instances of %VERSION% in the file will be replaced with + 1.2345 and so forth. + """ + contents = node.get_text_contents() + if not subs: return contents + for (k,v) in subs: + contents = re.sub(k, v, contents) + return contents + +def _action(target, source, env): + # prepare the line separator + linesep = env['LINESEPARATOR'] + if linesep is None: + linesep = os.linesep + elif is_String(linesep): + pass + elif isinstance(linesep, Value): + linesep = linesep.get_text_contents() + else: + raise SCons.Errors.UserError( + 'unexpected type/class for LINESEPARATOR: %s' + % repr(linesep), None) + + # create a dictionary to use for the substitutions + if not env.has_key('SUBST_DICT'): + subs = None # no substitutions + else: + d = env['SUBST_DICT'] + if SCons.Util.is_Dict(d): + d = d.items() + elif SCons.Util.is_Sequence(d): + pass + else: + raise SCons.Errors.UserError('SUBST_DICT must be dict or sequence') + subs = [] + for (k,v) in d: + if callable(v): + v = v() + if SCons.Util.is_String(v): + v = env.subst(v) + else: + v = str(v) + subs.append((k,v)) + + # write the file + try: + fd = open(target[0].get_path(), "w") + except (OSError,IOError), e: + raise SCons.Errors.UserError("Can't write target file %s" % target[0]) + # separate lines by 'linesep' only if linesep is not empty + lsep = None + for s in source: + if lsep: fd.write(lsep) + fd.write(_do_subst(s, subs)) + lsep = linesep + fd.close() + +def _strfunc(target, source, env): + return "Creating '%s'" % target[0] + +def _convert_list(target, source, env): + if len(target) != 1: + raise SCons.Errors.UserError("Only one target file allowed") + def _convert_list_R(newlist, sources): + for elem in sources: + if is_List(elem): + _convert_list_R(newlist, elem) + elif isinstance(elem, Node): + newlist.append(elem) + else: + newlist.append(Value(elem)) + newlist = [] + _convert_list_R(newlist, source) + return target, newlist + +_common_varlist = ['SUBST_DICT', 'LINESEPARATOR'] + +_text_varlist = _common_varlist + ['TEXTFILEPREFIX', 'TEXTFILESUFFIX'] +_text_builder = SCons.Builder.Builder( + action = SCons.Action.Action(_action, _strfunc, varlist = _text_varlist), + source_factory = Value, + emitter = _convert_list, + prefix = '$TEXTFILEPREFIX', + suffix = '$TEXTFILESUFFIX', + ) + +_subst_varlist = _common_varlist + ['SUBSTFILEPREFIX', 'TEXTFILESUFFIX'] +_subst_builder = SCons.Builder.Builder( + action = SCons.Action.Action(_action, _strfunc, varlist = _subst_varlist), + source_factory = SCons.Node.FS.File, + emitter = _convert_list, + prefix = '$SUBSTFILEPREFIX', + suffix = '$SUBSTFILESUFFIX', + src_suffix = ['.in'], + ) + +def generate(env): + env['LINESEPARATOR'] = os.linesep + env['BUILDERS']['Textfile'] = _text_builder + env['TEXTFILEPREFIX'] = '' + env['TEXTFILESUFFIX'] = '.txt' + env['BUILDERS']['Substfile'] = _subst_builder + env['SUBSTFILEPREFIX'] = '' + env['SUBSTFILESUFFIX'] = '' + +def exists(env): + return 1 |
