import os
import os.path
+import errno
import shutil
import stat
import time
-import types
import sys
import SCons.Action
global _default_env
if not _default_env:
import SCons.Util
- _default_env = apply(SCons.Environment.Environment, args, kw)
+ _default_env = SCons.Environment.Environment(*args, **kw)
if SCons.Util.md5:
_default_env.Decider('MD5')
else:
# ways by creating ActionFactory instances.
ActionFactory = SCons.Action.ActionFactory
-def chmod_func(path, mode):
- return os.chmod(str(path), mode)
+def get_paths_str(dest):
+ # If dest is a list, we need to manually call str() on each element
+ if SCons.Util.is_List(dest):
+ elem_strs = []
+ for element in dest:
+ elem_strs.append('"' + str(element) + '"')
+ return '[' + ', '.join(elem_strs) + ']'
+ else:
+ return '"' + str(dest) + '"'
+
+def chmod_func(dest, mode):
+ SCons.Node.FS.invalidate_node_memos(dest)
+ if not SCons.Util.is_List(dest):
+ dest = [dest]
+ for element in dest:
+ os.chmod(str(element), mode)
-Chmod = ActionFactory(chmod_func,
- lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
+def chmod_strfunc(dest, mode):
+ return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode)
+
+Chmod = ActionFactory(chmod_func, chmod_strfunc)
def copy_func(dest, src):
+ SCons.Node.FS.invalidate_node_memos(dest)
if SCons.Util.is_List(src) and os.path.isdir(dest):
for file in src:
- shutil.copy(file, dest)
+ shutil.copy2(file, dest)
return 0
elif os.path.isfile(src):
- return shutil.copy(src, dest)
+ return shutil.copy2(src, dest)
else:
return shutil.copytree(src, dest, 1)
lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
convert=str)
-def delete_func(entry, must_exist=0):
- entry = str(entry)
- if not must_exist and not os.path.exists(entry):
- return None
- if not os.path.exists(entry) or os.path.isfile(entry):
- return os.unlink(entry)
- else:
- return shutil.rmtree(entry, 1)
+def delete_func(dest, must_exist=0):
+ SCons.Node.FS.invalidate_node_memos(dest)
+ if not SCons.Util.is_List(dest):
+ dest = [dest]
+ for entry in dest:
+ entry = str(entry)
+ if not must_exist and not os.path.exists(entry):
+ continue
+ if not os.path.exists(entry) or os.path.isfile(entry):
+ os.unlink(entry)
+ continue
+ else:
+ shutil.rmtree(entry, 1)
+ continue
-def delete_strfunc(entry, must_exist=0):
- return 'Delete("%s")' % entry
+def delete_strfunc(dest, must_exist=0):
+ return 'Delete(%s)' % get_paths_str(dest)
Delete = ActionFactory(delete_func, delete_strfunc)
-Mkdir = ActionFactory(os.makedirs,
- lambda dir: 'Mkdir("%s")' % dir,
- convert=str)
+def mkdir_func(dest):
+ SCons.Node.FS.invalidate_node_memos(dest)
+ if not SCons.Util.is_List(dest):
+ dest = [dest]
+ for entry in dest:
+ try:
+ os.makedirs(str(entry))
+ except os.error, e:
+ p = str(entry)
+ if (e[0] == errno.EEXIST or (sys.platform=='win32' and e[0]==183)) \
+ and os.path.isdir(str(entry)):
+ pass # not an error if already exists
+ else:
+ raise
+
+Mkdir = ActionFactory(mkdir_func,
+ lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
+
+def move_func(dest, src):
+ SCons.Node.FS.invalidate_node_memos(dest)
+ SCons.Node.FS.invalidate_node_memos(src)
+ shutil.move(src, dest)
-Move = ActionFactory(lambda dest, src: os.rename(src, dest),
+Move = ActionFactory(move_func,
lambda dest, src: 'Move("%s", "%s")' % (dest, src),
convert=str)
-def touch_func(file):
- file = str(file)
- mtime = int(time.time())
- if os.path.exists(file):
- atime = os.path.getatime(file)
- else:
- open(file, 'w')
- atime = mtime
- return os.utime(file, (atime, mtime))
+def touch_func(dest):
+ SCons.Node.FS.invalidate_node_memos(dest)
+ if not SCons.Util.is_List(dest):
+ dest = [dest]
+ for file in dest:
+ file = str(file)
+ mtime = int(time.time())
+ if os.path.exists(file):
+ atime = os.path.getatime(file)
+ else:
+ open(file, 'w')
+ atime = mtime
+ os.utime(file, (atime, mtime))
Touch = ActionFactory(touch_func,
- lambda file: 'Touch("%s")' % file)
+ lambda file: 'Touch(%s)' % get_paths_str(file))
# Internal utility functions
if not list:
return list
- if SCons.Util.is_List(list):
- list = SCons.Util.flatten(list)
-
l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
- if not l is None:
+ if l is not None:
list = l
return _concat_ixes(prefix, list, suffix, env)
return result
-def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
+def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None):
"""
- This is a wrapper around _concat()/_concat_ixes() that checks for the
- existence of prefixes or suffixes on list elements and strips them
+ This is a wrapper around _concat()/_concat_ixes() that checks for
+ the existence of prefixes or suffixes on list items and strips them
where it finds them. This is used by tools (like the GNU linker)
that need to turn something like 'libfoo.a' into '-lfoo'.
"""
- if not list:
- return list
+ if not itms:
+ return itms
if not callable(c):
env_c = env['_concat']
else:
c = _concat_ixes
- if SCons.Util.is_List(list):
- list = SCons.Util.flatten(list)
-
- if SCons.Util.is_List(stripprefixes):
- stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes))
- else:
- stripprefixes = [env.subst(stripprefixes)]
-
- if SCons.Util.is_List(stripsuffixes):
- stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes))
- else:
- stripsuffixes = [stripsuffixes]
+ stripprefixes = list(map(env.subst, SCons.Util.flatten(stripprefixes)))
+ stripsuffixes = list(map(env.subst, SCons.Util.flatten(stripsuffixes)))
stripped = []
- for l in SCons.PathList.PathList(list).subst_path(env, None, None):
+ for l in SCons.PathList.PathList(itms).subst_path(env, None, None):
if isinstance(l, SCons.Node.FS.File):
stripped.append(l)
continue
return c(prefix, stripped, suffix, env)
-def _defines(prefix, defs, suffix, env, c=_concat_ixes):
- """A wrapper around _concat_ixes that turns a list or string
- into a list of C preprocessor command-line definitions.
+def processDefines(defs):
+ """process defines, resolving strings, lists, dictionaries, into a list of
+ strings
"""
if SCons.Util.is_List(defs):
l = []
for d in defs:
- if SCons.Util.is_List(d) or type(d) is types.TupleType:
+ if SCons.Util.is_List(d) or isinstance(d, tuple):
l.append(str(d[0]) + '=' + str(d[1]))
else:
l.append(str(d))
# Consequently, we have to sort the keys to ensure a
# consistent order...
l = []
- keys = defs.keys()
- keys.sort()
- for k in keys:
- v = defs[k]
+ for k,v in sorted(defs.items()):
if v is None:
l.append(str(k))
else:
l.append(str(k) + '=' + str(v))
else:
l = [str(defs)]
- return c(prefix, env.subst_path(l), suffix, env)
+ return l
+
+def _defines(prefix, defs, suffix, env, c=_concat_ixes):
+ """A wrapper around _concat_ixes that turns a list or string
+ into a list of C preprocessor command-line definitions.
+ """
+
+ return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
class NullCmdGenerator:
"""This is a callable class that can be used in place of other
self.method = method
def __call__(self, *args, **kw):
try: 1/0
- except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
+ except ZeroDivisionError:
+ # Don't start iterating with the current stack-frame to
+ # prevent creating reference cycles (f_back is safe).
+ frame = sys.exc_info()[2].tb_frame.f_back
variable = self.variable
while frame:
- if frame.f_locals.has_key(variable):
+ if variable in frame.f_locals:
v = frame.f_locals[variable]
if v:
method = getattr(v, self.method)
- return apply(method, args, kw)
+ return method(*args, **kw)
frame = frame.f_back
return None
'DSUFFIXES' : SCons.Tool.DSuffixes,
'ENV' : {},
'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
- 'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
+# 'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes, # moved to the TeX tools generate functions
'_concat' : _concat,
'_defines' : _defines,
'_stripixes' : _stripixes,
'File' : Variable_Method_Caller('TARGET', 'File'),
'RDirs' : Variable_Method_Caller('TARGET', 'RDirs'),
}
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: