summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/Command.py8
-rw-r--r--bin/SConsDoc.py18
-rw-r--r--bin/calibrate.py3
-rw-r--r--bin/caller-tree.py2
-rw-r--r--bin/import-test.py23
-rw-r--r--bin/install_python.py25
-rw-r--r--bin/install_scons.py9
-rw-r--r--bin/linecount.py29
-rw-r--r--bin/memoicmp.py25
-rw-r--r--bin/objcounts.py14
-rw-r--r--bin/restore.sh22
-rw-r--r--bin/scons-diff.py12
-rw-r--r--bin/scons-doc.py115
-rw-r--r--bin/scons-proc.py61
-rw-r--r--bin/scons-test.py25
-rw-r--r--bin/scons-unzip.py4
-rw-r--r--bin/sconsexamples.py63
-rw-r--r--bin/sfsum9
-rwxr-xr-xbin/svn-bisect.py3
-rw-r--r--bin/time-scons.py14
-rw-r--r--bin/update-release-info.py354
-rwxr-xr-xbin/xmlagenda.py79
22 files changed, 617 insertions, 300 deletions
diff --git a/bin/Command.py b/bin/Command.py
index efaa356..8702f51 100644
--- a/bin/Command.py
+++ b/bin/Command.py
@@ -14,7 +14,7 @@ class Usage(Exception):
def __init__(self, msg):
self.msg = msg
-class CommandRunner:
+class CommandRunner(object):
"""
Representation of a command to be executed.
"""
@@ -44,7 +44,7 @@ class CommandRunner:
return string
def do_display(self, string):
- if type(string) == type(()):
+ if isinstance(string, tuple):
func = string[0]
args = string[1:]
s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
@@ -59,14 +59,14 @@ class CommandRunner:
pass
def do_execute(self, command):
- if type(command) == type(''):
+ if isinstance(command, str):
command = self.subst(command)
cmdargs = shlex.split(command)
if cmdargs[0] == 'cd':
command = (os.chdir,) + tuple(cmdargs[1:])
elif cmdargs[0] == 'mkdir':
command = (os.mkdir,) + tuple(cmdargs[1:])
- if type(command) == type(()):
+ if isinstance(command, tuple):
func = command[0]
args = command[1:]
return func(*args)
diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py
index 3f64a25..4927dc0 100644
--- a/bin/SConsDoc.py
+++ b/bin/SConsDoc.py
@@ -146,7 +146,7 @@ class Tool(Item):
class ConstructionVariable(Item):
pass
-class Chunk:
+class Chunk(object):
def __init__(self, tag, body=None):
self.tag = tag
if not body:
@@ -158,7 +158,7 @@ class Chunk:
def append(self, data):
self.body.append(data)
-class Arguments:
+class Arguments(object):
def __init__(self, signature, body=None):
if not body:
body = []
@@ -175,7 +175,7 @@ class Arguments:
def append(self, data):
self.body.append(data)
-class Summary:
+class Summary(object):
def __init__(self):
self.body = []
self.collect = []
@@ -217,9 +217,9 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
def __init__(self):
self._start_dispatch = {}
self._end_dispatch = {}
- keys = self.__class__.__dict__.keys()
- start_tag_method_names = filter(lambda k: k[:6] == 'start_', keys)
- end_tag_method_names = filter(lambda k: k[:4] == 'end_', keys)
+ keys = list(self.__class__.__dict__.keys())
+ start_tag_method_names = [k for k in keys if k[:6] == 'start_']
+ end_tag_method_names = [k for k in keys if k[:4] == 'end_']
for method_name in start_tag_method_names:
tag = method_name[6:]
self._start_dispatch[tag] = getattr(self, method_name)
@@ -353,15 +353,13 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
def start_uses(self, attrs):
self.begin_collecting([])
def end_uses(self):
- self.current_object.uses = ''.join(self.collect).split()
- self.current_object.uses.sort()
+ self.current_object.uses = sorted(''.join(self.collect).split())
self.end_collecting()
def start_sets(self, attrs):
self.begin_collecting([])
def end_sets(self):
- self.current_object.sets = ''.join(self.collect).split()
- self.current_object.sets.sort()
+ self.current_object.sets = sorted(''.join(self.collect).split())
self.end_collecting()
# Stuff for the ErrorHandler portion.
diff --git a/bin/calibrate.py b/bin/calibrate.py
index c5d45ce..f377869 100644
--- a/bin/calibrate.py
+++ b/bin/calibrate.py
@@ -20,6 +20,7 @@
# 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.
+from __future__ import division
import optparse
import os
@@ -71,7 +72,7 @@ def main(argv=None):
good = 0
for v in vm.groups():
var, value = v.split('=', 1)
- value = int((int(value) * opts.max) / elapsed)
+ value = int((int(value) * opts.max) // elapsed)
os.environ[var] = str(value)
run += 1
diff --git a/bin/caller-tree.py b/bin/caller-tree.py
index 85bb599..03c1616 100644
--- a/bin/caller-tree.py
+++ b/bin/caller-tree.py
@@ -42,7 +42,7 @@
import sys
-class Entry:
+class Entry(object):
def __init__(self, file_line_func):
self.file_line_func = file_line_func
self.called_by = []
diff --git a/bin/import-test.py b/bin/import-test.py
index 18f7428..906bab0 100644
--- a/bin/import-test.py
+++ b/bin/import-test.py
@@ -25,7 +25,7 @@
# """ triple-quotes will need to have their contents edited by hand.
#
-__revision__ = "bin/import-test.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "bin/import-test.py 5023 2010/06/14 22:05:46 scons"
import os.path
import sys
@@ -35,16 +35,13 @@ directory = sys.argv[1]
Top = None
TopPath = None
-class Dir:
+class Dir(object):
def __init__(self, path):
self.path = path
self.entries = {}
def call_for_each_entry(self, func):
- entries = self.entries
- names = entries.keys()
- names.sort()
- for name in names:
- func(name, entries[name])
+ for name in sorted(self.entries.keys()):
+ func(name, self.entries[name])
def lookup(dirname):
global Top, TopPath
@@ -60,11 +57,6 @@ def lookup(dirname):
node = t.entries[dirs[-1]] = Dir(dirs)
return node
-def make_nodes(arg, dirname, fnames):
- dir = lookup(dirname)
- for f in fnames:
- dir.entries[f] = None
-
def collect_dirs(l, dir):
if dir.path:
l.append(dir.path)
@@ -78,7 +70,7 @@ def print_files(dir):
if not d:
l = dir.path + [n]
sys.stdout.write('\ntest.write(%s, """\\\n' % l)
- p = os.path.join(*([directory] + l))
+ p = os.path.join(directory, *l)
sys.stdout.write(open(p, 'r').read())
sys.stdout.write('""")\n')
dir.call_for_each_entry(print_a_file)
@@ -88,7 +80,10 @@ def print_files(dir):
print_files(d)
dir.call_for_each_entry(recurse)
-os.path.walk(directory, make_nodes, None)
+for dirpath, dirnames, filenames in os.walk(directory):
+ dir = lookup(dirpath)
+ for f in fnames:
+ dir.entries[f] = None
subdir_list = []
collect_dirs(subdir_list, Top)
diff --git a/bin/install_python.py b/bin/install_python.py
index ca1c8b7..86807af 100644
--- a/bin/install_python.py
+++ b/bin/install_python.py
@@ -15,10 +15,6 @@ import sys
from Command import CommandRunner, Usage
all_versions = [
- #'1.5.2', # no longer available at python.org
- '2.0.1',
- '2.1.3',
- '2.2',
'2.3.7',
'2.4.5',
#'2.5.2',
@@ -89,16 +85,6 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...]
tar_gz = os.path.join(downloads_dir, python + '.tgz')
tar_gz_url = os.path.join(downloads_url, version, python + '.tgz')
- if (version.startswith('1.5') or
- version.startswith('1.6') or
- version.startswith('2.0')):
-
- configureflags = '--with-threads'
-
- else:
-
- configureflags = ''
-
cmd.subst_dictionary(locals())
if not os.path.exists(tar_gz):
@@ -110,17 +96,6 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...]
cmd.run('cd %(python)s')
- if (version.startswith('1.6') or
- version.startswith('2.0')):
-
- def edit_modules_setup_in():
- content = open('Modules/Setup.in', 'r').read()
- content = content.replace('\n#zlib', '\nzlib')
- open('Modules/Setup.in', 'w').write(content)
-
- display = 'ed Modules/Setup.in <<EOF\ns/^#zlib/zlib/\nw\nq\nEOF\n'
- cmd.run((edit_modules_setup_in,), display)
-
cmd.run('./configure --prefix=%(prefix)s %(configureflags)s 2>&1 | tee configure.out')
cmd.run('make 2>&1 | tee make.out')
cmd.run('%(sudo)s make install')
diff --git a/bin/install_scons.py b/bin/install_scons.py
index e4e6aff..b5e0af8 100644
--- a/bin/install_scons.py
+++ b/bin/install_scons.py
@@ -79,6 +79,15 @@ all_versions = [
'1.2.0',
'1.2.0.d20090113',
'1.2.0.d20090223',
+ '1.2.0.d20090905',
+ '1.2.0.d20090919',
+ '1.2.0.d20091224',
+ '1.2.0.d20100117',
+ '1.2.0.d20100306',
+ '1.3.0',
+ '1.3.0.d20100404',
+ '1.3.0.d20100501',
+ '2.0.0.alpha.20100508',
]
def main(argv=None):
diff --git a/bin/linecount.py b/bin/linecount.py
index 23ac7c9..7d6e457 100644
--- a/bin/linecount.py
+++ b/bin/linecount.py
@@ -21,12 +21,11 @@
# in each category, the number of non-blank lines, and the number of
# non-comment lines. The last figure (non-comment) lines is the most
# interesting one for most purposes.
-#
+from __future__ import division
-__revision__ = "bin/linecount.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "bin/linecount.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
fmt = "%-16s %5s %7s %9s %11s %11s"
@@ -43,8 +42,12 @@ class Collection(object):
return self.pred(fname)
def __len__(self):
return len(self.files)
- def extend(self, files):
- self.files.extend(files)
+ def collect(self, directory):
+ for dirpath, dirnames, filenames in os.walk(directory):
+ try: dirnames.remove('.svn')
+ except ValueError: pass
+ self.files.extend([ os.path.join(dirpath, f)
+ for f in filenames if self.pred(f) ])
def lines(self):
try:
return self._lines
@@ -82,17 +85,11 @@ src_test_tests = Collection('src/ test_*.py', pred=is_test_)
test_tests = Collection('test/ tests', pred=is_python)
sources = Collection('sources', pred=is_source)
-def t(arg, dirname, names):
- try: names.remove('.svn')
- except ValueError: pass
- names = filter(arg, names)
- arg.extend(map(lambda n, d=dirname: os.path.join(d, n), names))
-
-os.path.walk('src', t, src_Tests_py_tests)
-os.path.walk('src', t, src_test_tests)
-os.path.walk('test', t, test_tests)
-os.path.walk('src/engine', t, sources)
-os.path.walk('src/script', t, sources)
+src_Tests_py_tests.collect('src')
+src_test_tests.collect('src')
+test_tests.collect('test')
+sources.collect('src/engine')
+sources.collect('src/script')
src_tests = Collection('src/ tests', src_Tests_py_tests.files
+ src_test_tests.files)
diff --git a/bin/memoicmp.py b/bin/memoicmp.py
index f45ecb0..812af66 100644
--- a/bin/memoicmp.py
+++ b/bin/memoicmp.py
@@ -1,21 +1,24 @@
#!/usr/bin/env python
#
-# A script to compare the --debug=memoizer output found int
+# A script to compare the --debug=memoizer output found in
# two different files.
-import sys,string
+import sys
def memoize_output(fname):
- mout = {}
- lines=filter(lambda words:
- len(words) == 5 and
- words[1] == 'hits' and words[3] == 'misses',
- map(string.split, open(fname,'r').readlines()))
- for line in lines:
- mout[line[-1]] = ( int(line[0]), int(line[2]) )
- return mout
+ mout = {}
+ #lines=filter(lambda words:
+ # len(words) == 5 and
+ # words[1] == 'hits' and words[3] == 'misses',
+ # map(string.split, open(fname,'r').readlines()))
+ #for line in lines:
+ # mout[line[-1]] = ( int(line[0]), int(line[2]) )
+ for line in open(fname,'r').readlines():
+ words = line.split()
+ if len(words) == 5 and words[1] == 'hits' and words[3] == 'misses':
+ mout[words[-1]] = ( int(words[0]), int(words[2]) )
+ return mout
-
def memoize_cmp(filea, fileb):
ma = memoize_output(filea)
mb = memoize_output(fileb)
diff --git a/bin/objcounts.py b/bin/objcounts.py
index ca814b4..0662012 100644
--- a/bin/objcounts.py
+++ b/bin/objcounts.py
@@ -40,7 +40,7 @@ def fetch_counts(fname):
list = [l.split() for l in lines if re.match('\s+\d', l)]
d = {}
for l in list:
- d[l[-1]] = map(int, l[:-1])
+ d[l[-1]] = list(map(int, l[:-1]))
return d
c1 = fetch_counts(sys.argv[1])
@@ -86,20 +86,14 @@ def printline(c1, c2, classname):
diffstr(c1[3], c2[3]) + \
' ' + classname
-keys = common.keys()
-keys.sort()
-for k in keys:
+for k in sorted(common.keys()):
c = common[k]
printline(c[0], c[1], k)
-keys = c1.keys()
-keys.sort()
-for k in keys:
+for k in sorted(list(c1.keys())):
printline(c1[k], ['--']*4, k)
-keys = c2.keys()
-keys.sort()
-for k in keys:
+for k in sorted(list(c2.keys())):
printline(['--']*4, c2[k], k)
# Local Variables:
diff --git a/bin/restore.sh b/bin/restore.sh
index 8dce2d3..3fd8d72 100644
--- a/bin/restore.sh
+++ b/bin/restore.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env sh
#
-# Simple hack script to restore __revision__, __COPYRIGHT_, 1.3.0
+# Simple hack script to restore __revision__, __COPYRIGHT_, 2.0.0.final.0
# and other similar variables to what gets checked in to source. This
# comes in handy when people send in diffs based on the released source.
#
@@ -24,7 +24,7 @@ for i in `find $DIRS -name '*.py'`; do
ed $i <<EOF
g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation/p
w
-/^__revision__ = /s/= .*/= "bin/restore.sh 4720 2010/03/24 03:14:11 jars"/p
+/^__revision__ = /s/= .*/= "bin/restore.sh 5023 2010/06/14 22:05:46 scons"/p
w
q
EOF
@@ -35,7 +35,7 @@ for i in `find $DIRS -name 'scons.bat'`; do
ed $i <<EOF
g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation/p
w
-/^@REM src\/script\/scons.bat/s/@REM .* knight/@REM bin/restore.sh 4720 2010/03/24 03:14:11 jars/p
+/^@REM src\/script\/scons.bat/s/@REM .* knight/@REM bin/restore.sh 5023 2010/06/14 22:05:46 scons/p
w
q
EOF
@@ -44,15 +44,15 @@ done
for i in `find $DIRS -name '__init__.py' -o -name 'scons.py' -o -name 'sconsign.py'`; do
header $i
ed $i <<EOF
-/^__version__ = /s/= .*/= "1.3.0"/p
+/^__version__ = /s/= .*/= "2.0.0.final.0"/p
w
-/^__build__ = /s/= .*/= "r4720"/p
+/^__build__ = /s/= .*/= "r5023"/p
w
-/^__buildsys__ = /s/= .*/= "jars-desktop"/p
+/^__buildsys__ = /s/= .*/= "scons-dev"/p
w
-/^__date__ = /s/= .*/= "2010/03/24 03:14:11"/p
+/^__date__ = /s/= .*/= "2010/06/14 22:05:46"/p
w
-/^__developer__ = /s/= .*/= "jars"/p
+/^__developer__ = /s/= .*/= "scons"/p
w
q
EOF
@@ -61,7 +61,7 @@ done
for i in `find $DIRS -name 'setup.py'`; do
header $i
ed $i <<EOF
-/^ *version = /s/= .*/= "1.3.0",/p
+/^ *version = /s/= .*/= "2.0.0.final.0",/p
w
q
EOF
@@ -72,9 +72,9 @@ for i in `find $DIRS -name '*.txt'`; do
ed $i <<EOF
g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation/p
w
-/# [^ ]* 0.96.[CD][0-9]* [0-9\/]* [0-9:]* knight$/s/.*/# bin/restore.sh 4720 2010/03/24 03:14:11 jars/p
+/# [^ ]* 0.96.[CD][0-9]* [0-9\/]* [0-9:]* knight$/s/.*/# bin/restore.sh 5023 2010/06/14 22:05:46 scons/p
w
-/Version [0-9][0-9]*\.[0-9][0-9]*/s//Version 1.3.0/p
+/Version [0-9][0-9]*\.[0-9][0-9]*/s//Version 2.0.0.final.0/p
w
q
EOF
diff --git a/bin/scons-diff.py b/bin/scons-diff.py
index 11d1bda..1e4bca0 100644
--- a/bin/scons-diff.py
+++ b/bin/scons-diff.py
@@ -97,15 +97,15 @@ def simple_diff(a, b, fromfile='', tofile='',
for op, a1, a2, b1, b2 in sm.get_opcodes():
if op == 'delete':
result.append("%sd%d\n" % (comma(a1, a2), b1))
- result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ result.extend(['< ' + l for l in a[a1:a2]])
elif op == 'insert':
result.append("%da%s\n" % (a1, comma(b1, b2)))
- result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ result.extend(['> ' + l for l in b[b1:b2]])
elif op == 'replace':
result.append("%sc%s\n" % (comma(a1, a2), comma(b1, b2)))
- result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ result.extend(['< ' + l for l in a[a1:a2]])
result.append('---\n')
- result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ result.extend(['> ' + l for l in b[b1:b2]])
return result
diff_map = {
@@ -173,9 +173,7 @@ def diff_dir(left, right):
u[l] = 1
for r in rlist:
u[r] = 1
- clist = [ x for x in u.keys() if x[-4:] != '.pyc' ]
- clist.sort()
- for x in clist:
+ for x in sorted([ x for x in u.keys() if x[-4:] != '.pyc' ]):
if x in llist:
if x in rlist:
do_diff(os.path.join(left, x),
diff --git a/bin/scons-doc.py b/bin/scons-doc.py
index e385b08..14e862c 100644
--- a/bin/scons-doc.py
+++ b/bin/scons-doc.py
@@ -93,7 +93,6 @@ import optparse
import os
import re
import sgmllib
-import string
import sys
import time
@@ -118,7 +117,7 @@ import TestCmd
sgmllib.entityref = re.compile('&([a-zA-Z][-_.a-zA-Z0-9]*)[^-_a-zA-Z0-9]')
# Classes for collecting different types of data we're interested in.
-class DataCollector:
+class DataCollector(object):
"""Generic class for collecting data between a start tag and end
tag. We subclass for various types of tags we care about."""
def __init__(self):
@@ -185,7 +184,6 @@ Prompt = {
Stdin = """\
import os
import re
-import string
import SCons.Action
import SCons.Defaults
import SCons.Node.FS
@@ -205,7 +203,7 @@ Sep = {
orig = SCons.Node.FS.EntryProxy
class MyEntryProxy(orig):
def __str__(self):
- return string.replace(str(self._Proxy__subject), os.sep, Sep)
+ return str(self._subject).replace(os.sep, Sep)
SCons.Node.FS.EntryProxy = MyEntryProxy
# Slip our own RDirs() method into the Node.FS.File class so that the
@@ -214,11 +212,10 @@ SCons.Node.FS.EntryProxy = MyEntryProxy
# running on to what's appropriate for the example system.
orig_RDirs = SCons.Node.FS.File.RDirs
def my_RDirs(self, pathlist, orig_RDirs=orig_RDirs):
- return map(lambda x: string.replace(str(x), os.sep, Sep),
- orig_RDirs(self, pathlist))
+ return [str(x).replace(os.sep, Sep) for x in orig_RDirs(self, pathlist)]
SCons.Node.FS.File.RDirs = my_RDirs
-class Curry:
+class Curry(object):
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
@@ -231,18 +228,18 @@ class Curry:
else:
kw = kwargs or self.kwargs
- return apply(self.fun, self.pending + args, kw)
+ return self.fun(*self.pending + args, **kw)
def Str(target, source, env, cmd=""):
result = []
for cmd in env.subst_list(cmd, target=target, source=source):
- result.append(string.join(map(str, cmd)))
- return string.join(result, '\\n')
+ result.append(' '.join(map(str, cmd)))
+ return '\\n'.join(result)
-class ToolSurrogate:
+class ToolSurrogate(object):
def __init__(self, tool, variable, func, varlist):
self.tool = tool
- if not type(variable) is type([]):
+ if not isinstance(variable, list):
variable = [variable]
self.variable = variable
self.func = func
@@ -304,7 +301,7 @@ def JavaCCom(target, source, env):
# public class FooBar
# lines in the source file(s) and spits those out
# to .class files named after the class.
- tlist = map(str, target)
+ tlist = list(map(str, target))
not_copied = {}
for t in tlist:
not_copied[t] = 1
@@ -312,7 +309,7 @@ def JavaCCom(target, source, env):
contents = open(src, "rb").read()
classes = public_class_re.findall(contents)
for c in classes:
- for t in filter(lambda x: string.find(x, c) != -1, tlist):
+ for t in [x for x in tlist if x.find(c) != -1]:
open(t, "wb").write(contents)
del not_copied[t]
for t in not_copied.keys():
@@ -324,16 +321,13 @@ def JavaHCom(target, source, env):
for t, s in zip(tlist, slist):
open(t, "wb").write(open(s, "rb").read())
-def find_class_files(arg, dirname, names):
- class_files = filter(lambda n: n[-6:] == '.class', names)
- paths = map(lambda n, d=dirname: os.path.join(d, n), class_files)
- arg.extend(paths)
-
def JarCom(target, source, env):
target = str(target[0])
class_files = []
for src in map(str, source):
- os.path.walk(src, find_class_files, class_files)
+ for dirpath, dirnames, filenames in os.walk(src):
+ class_files.extend([ os.path.join(dirpath, f)
+ for f in filenames if f.endswith('.class') ])
f = open(target, "wb")
for cf in class_files:
f.write(open(cf, "rb").read())
@@ -380,11 +374,11 @@ ToolList = {
}
toollist = ToolList[platform]
-filter_tools = string.split('%(tools)s')
+filter_tools = '%(tools)s'.split()
if filter_tools:
- toollist = filter(lambda x, ft=filter_tools: x[0] in ft, toollist)
+ toollist = [x for x in toollist if x[0] in filter_tools]
-toollist = map(lambda t: apply(ToolSurrogate, t), toollist)
+toollist = [ToolSurrogate(*t) for t in toollist]
toollist.append('install')
@@ -413,8 +407,8 @@ def command_scons(args, c, test, dict):
except AttributeError:
pass
else:
- for arg in string.split(c.environment):
- key, val = string.split(arg, '=')
+ for arg in c.environment.split():
+ key, val = arg.split('=')
try:
save_vals[key] = os.environ[key]
except KeyError:
@@ -427,17 +421,17 @@ def command_scons(args, c, test, dict):
# warnings that come from the new revamped VS support so
# we can build doc on (Linux) systems that don't have
# Visual C installed.
- arguments = '--warn=no-visual-c-missing -f - ' + string.join(args),
+ arguments = '--warn=no-visual-c-missing -f - ' + ' '.join(args),
chdir = test.workpath('WORK'),
stdin = Stdin % dict)
os.environ.update(save_vals)
for key in delete_keys:
del(os.environ[key])
out = test.stdout()
- out = string.replace(out, test.workpath('ROOT'), '')
- out = string.replace(out, test.workpath('WORK/SConstruct'),
+ out = out.replace(test.workpath('ROOT'), '')
+ out = out.replace(test.workpath('WORK/SConstruct'),
'/home/my/project/SConstruct')
- lines = string.split(out, '\n')
+ lines = out.split('\n')
if lines:
while lines[-1] == '':
lines = lines[:-1]
@@ -478,10 +472,7 @@ def command_edit(args, c, test, dict):
def command_ls(args, c, test, dict):
def ls(a):
- files = os.listdir(a)
- files = filter(lambda x: x[0] != '.', files)
- files.sort()
- return [string.join(files, ' ')]
+ return [' '.join(sorted([x for x in os.listdir(a) if x[0] != '.']))]
if args:
l = []
for a in args:
@@ -509,14 +500,11 @@ def ExecuteCommand(args, c, t, dict):
return func(args[1:], c, t, dict)
class MySGML(sgmllib.SGMLParser):
- """A subclass of the standard Python 2.2 sgmllib SGML parser.
+ """A subclass of the standard Python sgmllib SGML parser.
This extends the standard sgmllib parser to recognize, and do cool
stuff with, the added tags that describe our SCons examples,
commands, and other stuff.
-
- Note that this doesn't work with the 1.5.2 sgmllib module, because
- that didn't have the ability to work with ENTITY declarations.
"""
def __init__(self, outfp):
sgmllib.SGMLParser.__init__(self)
@@ -568,8 +556,14 @@ class MySGML(sgmllib.SGMLParser):
# Here is where the heavy lifting begins. The following methods
# handle the begin-end tags of our SCons examples.
+ def for_display(self, contents):
+ contents = contents.replace('__ROOT__', '')
+ contents = contents.replace('<', '&lt;')
+ contents = contents.replace('>', '&gt;')
+ return contents
+
def start_scons_example(self, attrs):
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if t:
name = t[0][1]
try:
@@ -585,7 +579,7 @@ class MySGML(sgmllib.SGMLParser):
def end_scons_example(self):
e = self.e
- files = filter(lambda f: f.printme, e.files)
+ files = [f for f in e.files if f.printme]
if files:
self.outfp.write('<programlisting>')
for f in files:
@@ -593,9 +587,7 @@ class MySGML(sgmllib.SGMLParser):
i = len(f.data) - 1
while f.data[i] == ' ':
i = i - 1
- output = string.replace(f.data[:i+1], '__ROOT__', '')
- output = string.replace(output, '<', '&lt;')
- output = string.replace(output, '>', '&gt;')
+ output = self.for_display(f.data[:i+1])
self.outfp.write(output)
if e.data and e.data[0] == '\n':
e.data = e.data[1:]
@@ -608,7 +600,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<file> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <file> name attribute found")
try:
@@ -632,7 +624,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<directory> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <directory> name attribute found")
try:
@@ -651,7 +643,7 @@ class MySGML(sgmllib.SGMLParser):
self.afunclist = self.afunclist[:-1]
def start_scons_example_file(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_example_file> example attribute found")
exname = t[0][1]
@@ -659,11 +651,11 @@ class MySGML(sgmllib.SGMLParser):
e = self.examples[exname]
except KeyError:
self.error("unknown example name '%s'" % exname)
- fattrs = filter(lambda t: t[0] == 'name', attrs)
+ fattrs = [t for t in attrs if t[0] == 'name']
if not fattrs:
self.error("no <scons_example_file> name attribute found")
fname = fattrs[0][1]
- f = filter(lambda f, fname=fname: f.name == fname, e.files)
+ f = [f for f in e.files if f.name == fname]
if not f:
self.error("example '%s' does not have a file named '%s'" % (exname, fname))
self.f = f[0]
@@ -675,7 +667,7 @@ class MySGML(sgmllib.SGMLParser):
delattr(self, 'f')
def start_scons_output(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_output> example attribute found")
exname = t[0][1]
@@ -704,7 +696,7 @@ class MySGML(sgmllib.SGMLParser):
if o.preserve:
t.preserve()
t.subdir('ROOT', 'WORK')
- t.rootpath = string.replace(t.workpath('ROOT'), '\\', '\\\\')
+ t.rootpath = t.workpath('ROOT').replace('\\', '\\\\')
for d in e.dirs:
dir = t.workpath('WORK', d.name)
@@ -715,19 +707,19 @@ class MySGML(sgmllib.SGMLParser):
i = 0
while f.data[i] == '\n':
i = i + 1
- lines = string.split(f.data[i:], '\n')
+ lines = f.data[i:].split('\n')
i = 0
while lines[0][i] == ' ':
i = i + 1
- lines = map(lambda l, i=i: l[i:], lines)
- path = string.replace(f.name, '__ROOT__', t.rootpath)
+ lines = [l[i:] for l in lines]
+ path = f.name.replace('__ROOT__', t.rootpath)
if not os.path.isabs(path):
path = t.workpath('WORK', path)
dir, name = os.path.split(path)
if dir and not os.path.exists(dir):
os.makedirs(dir)
- content = string.join(lines, '\n')
- content = string.replace(content, '__ROOT__', t.rootpath)
+ content = '\n'.join(lines)
+ content = content.replace('__ROOT__', t.rootpath)
path = t.workpath('WORK', path)
t.write(path, content)
if hasattr(f, 'chmod'):
@@ -761,24 +753,23 @@ class MySGML(sgmllib.SGMLParser):
for c in o.commandlist:
self.outfp.write(p + Prompt[o.os])
- d = string.replace(c.data, '__ROOT__', '')
+ d = c.data.replace('__ROOT__', '')
self.outfp.write('<userinput>' + d + '</userinput>\n')
- e = string.replace(c.data, '__ROOT__', t.workpath('ROOT'))
- args = string.split(e)
+ e = c.data.replace('__ROOT__', t.workpath('ROOT'))
+ args = e.split()
lines = ExecuteCommand(args, c, t, {'osname':o.os, 'tools':o.tools})
content = None
if c.output:
content = c.output
elif lines:
- content = string.join(lines, '\n' + p)
+ content = ( '\n' + p).join(lines)
if content:
content = address_re.sub(r' at 0x700000&gt;', content)
content = engine_re.sub(r' File "bootstrap/src/engine/SCons/', content)
content = file_re.sub(r'\1 <module>', content)
content = nodelist_re.sub(r"\1 'NodeList' object \2", content)
- content = string.replace(content, '<', '&lt;')
- content = string.replace(content, '>', '&gt;')
+ content = self.for_display(content)
self.outfp.write(p + content + '\n')
if o.data[0] == '\n':
@@ -815,7 +806,7 @@ class MySGML(sgmllib.SGMLParser):
def end_sconstruct(self):
f = self.f
self.outfp.write('<programlisting>')
- output = string.replace(f.data, '__ROOT__', '')
+ output = self.for_display(f.data)
self.outfp.write(output + '</programlisting>')
delattr(self, 'f')
self.afunclist = self.afunclist[:-1]
@@ -827,7 +818,7 @@ def process(filename):
try:
f = open(filename, 'r')
except EnvironmentError, e:
- sys.stderr.write('%s: %s\n' % (filename, msg))
+ sys.stderr.write('%s: %s\n' % (filename, e))
return 1
data = f.read()
diff --git a/bin/scons-proc.py b/bin/scons-proc.py
index 15f22b7..7cdb618 100644
--- a/bin/scons-proc.py
+++ b/bin/scons-proc.py
@@ -10,13 +10,16 @@
# and/or .mod files contining the ENTITY definitions for each item,
# or in man-page-formatted output.
#
+import os
+import sys
import getopt
-import os.path
import re
-import string
-import StringIO
-import sys
import xml.sax
+try:
+ from io import StringIO
+except ImportError:
+ # No 'io' module or no StringIO in io
+ exec('from cStringIO import StringIO')
import SConsDoc
@@ -101,7 +104,7 @@ for f in args:
content = content.replace('-->\n', '-->')
input = xml_preamble + content + xml_postamble
try:
- saxparser.parse(StringIO.StringIO(input))
+ saxparser.parse(StringIO(input))
except:
sys.stderr.write("error in %s\n" % f)
raise
@@ -128,7 +131,7 @@ Link_Entities_Header = """\
-->
"""
-class SCons_XML:
+class SCons_XML(object):
def __init__(self, entries, **kw):
self.values = entries
for k, v in kw.items():
@@ -140,7 +143,7 @@ class SCons_XML:
class SCons_XML_to_XML(SCons_XML):
def write(self, files):
- gen, mod = string.split(files, ',')
+ gen, mod = files.split(',')
g.write_gen(gen)
g.write_mod(mod)
def write_gen(self, filename):
@@ -157,12 +160,12 @@ class SCons_XML_to_XML(SCons_XML):
for chunk in v.summary.body:
f.write(str(chunk))
if v.sets:
- s = map(lambda x: '&cv-link-%s;' % x, v.sets)
+ s = ['&cv-link-%s;' % x for x in v.sets]
f.write('<para>\n')
f.write('Sets: ' + ', '.join(s) + '.\n')
f.write('</para>\n')
if v.uses:
- u = map(lambda x: '&cv-link-%s;' % x, v.uses)
+ u = ['&cv-link-%s;' % x for x in v.uses]
f.write('<para>\n')
f.write('Uses: ' + ', '.join(u) + '.\n')
f.write('</para>\n')
@@ -216,34 +219,34 @@ class SCons_XML_to_man(SCons_XML):
for v in self.values:
chunks.extend(v.mansep())
chunks.extend(v.initial_chunks())
- chunks.extend(map(str, v.summary.body))
+ chunks.extend(list(map(str, v.summary.body)))
body = ''.join(chunks)
- body = string.replace(body, '<programlisting>', '.ES')
- body = string.replace(body, '</programlisting>', '.EE')
- body = string.replace(body, '\n</para>\n<para>\n', '\n\n')
- body = string.replace(body, '<para>\n', '')
- body = string.replace(body, '<para>', '\n')
- body = string.replace(body, '</para>\n', '')
-
- body = string.replace(body, '<variablelist>\n', '.RS 10\n')
+ body = body.replace('<programlisting>', '.ES')
+ body = body.replace('</programlisting>', '.EE')
+ body = body.replace('\n</para>\n<para>\n', '\n\n')
+ body = body.replace('<para>\n', '')
+ body = body.replace('<para>', '\n')
+ body = body.replace('</para>\n', '')
+
+ body = body.replace('<variablelist>\n', '.RS 10\n')
# Handling <varlistentry> needs to be rationalized and made
# consistent. Right now, the <term> values map to arbitrary,
# ad-hoc idioms in the current man page.
body = re.compile(r'<varlistentry>\n<term><literal>([^<]*)</literal></term>\n<listitem>\n').sub(r'.TP 6\n.B \1\n', body)
body = re.compile(r'<varlistentry>\n<term><parameter>([^<]*)</parameter></term>\n<listitem>\n').sub(r'.IP \1\n', body)
body = re.compile(r'<varlistentry>\n<term>([^<]*)</term>\n<listitem>\n').sub(r'.HP 6\n.B \1\n', body)
- body = string.replace(body, '</listitem>\n', '')
- body = string.replace(body, '</varlistentry>\n', '')
- body = string.replace(body, '</variablelist>\n', '.RE\n')
+ body = body.replace('</listitem>\n', '')
+ body = body.replace('</varlistentry>\n', '')
+ body = body.replace('</variablelist>\n', '.RE\n')
body = re.sub(r'\.EE\n\n+(?!\.IP)', '.EE\n.IP\n', body)
- body = string.replace(body, '\n.IP\n\'\\"', '\n\n\'\\"')
+ body = body.replace('\n.IP\n\'\\"', '\n\n\'\\"')
body = re.sub('&(scons|SConstruct|SConscript|jar|Make|lambda);', r'\\fB\1\\fP', body)
body = re.sub('&(TARGET|TARGETS|SOURCE|SOURCES);', r'\\fB$\1\\fP', body)
- body = string.replace(body, '&Dir;', r'\fBDir\fP')
- body = string.replace(body, '&target;', r'\fItarget\fP')
- body = string.replace(body, '&source;', r'\fIsource\fP')
+ body = body.replace('&Dir;', r'\fBDir\fP')
+ body = body.replace('&target;', r'\fItarget\fP')
+ body = body.replace('&source;', r'\fIsource\fP')
body = re.sub('&b(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
body = re.sub('&cv(-link)?-([^;]*);', r'$\2', body)
body = re.sub('&f(-link)?-env-([^;]*);', r'\\fBenv.\2\\fP()', body)
@@ -258,8 +261,8 @@ class SCons_XML_to_man(SCons_XML):
body = re.compile(r'^(\S+)\\f([BI])(.*)\\fP$', re.M).sub(r'.R\2 \1 \3', body)
body = re.compile(r'^(\S+)\\f([BI])(.*)\\fP([^\s\\]+)$', re.M).sub(r'.R\2 \1 \3 \4', body)
body = re.compile(r'^(\.R[BI].*[\S])\s+$;', re.M).sub(r'\1', body)
- body = string.replace(body, '&lt;', '<')
- body = string.replace(body, '&gt;', '>')
+ body = body.replace('&lt;', '<')
+ body = body.replace('&gt;', '>')
body = re.sub(r'\\([^f])', r'\\\\\1', body)
body = re.compile("^'\\\\\\\\", re.M).sub("'\\\\", body)
body = re.compile(r'^\.([BI]R?) --', re.M).sub(r'.\1 \-\-', body)
@@ -268,7 +271,7 @@ class SCons_XML_to_man(SCons_XML):
body = re.compile(r'\\f([BI])-', re.M).sub(r'\\f\1\-', body)
f.write(body)
-class Proxy:
+class Proxy(object):
def __init__(self, subject):
"""Wrap an object as a Proxy object"""
self.__subject = subject
@@ -336,7 +339,7 @@ class Tool(Proxy):
prefix = 't-'
tag = 'literal'
def idfunc(self):
- return string.replace(self.name, '+', 'X')
+ return self.name.replace('+', 'X')
def termfunc(self):
return [self.name]
def entityfunc(self):
diff --git a/bin/scons-test.py b/bin/scons-test.py
index aa03d72..2191532 100644
--- a/bin/scons-test.py
+++ b/bin/scons-test.py
@@ -19,13 +19,21 @@ import getopt
import imp
import os
import os.path
-import string
import sys
import tempfile
import time
-import urllib
import zipfile
+try:
+ # try Python 3.x style
+ from urllib.request import urlretrieve
+except ImportError:
+ # nope, must be 2.x; this hack is equivalent
+ import imp
+ # protect import from fixer
+ urlretrieve = imp.load_module('urllib',
+ *imp.find_module('urllib')).urlretrieve
+
helpstr = """\
Usage: scons-test.py [-f zipfile] [-o outdir] [-v] [--xml] [runtest arguments]
Options:
@@ -70,7 +78,7 @@ if not os.path.exists(tempdir):
# Fetch the input file if it happens to be across a network somewhere.
# Ohmigod, does Python make this simple...
-inputfile, headers = urllib.urlretrieve(inputfile)
+inputfile, headers = urlretrieve(inputfile)
# Unzip the header file in the output directory. We use our own code
# (lifted from scons-unzip.py) to make the output subdirectory name
@@ -83,14 +91,14 @@ if outdir is None:
def outname(n, outdir=outdir):
l = []
- while 1:
+ while True:
n, tail = os.path.split(n)
if not n:
break
l.append(tail)
l.append(outdir)
l.reverse()
- return apply(os.path.join, l)
+ return os.path.join(*l)
for name in zf.namelist():
dest = outname(name)
@@ -135,7 +143,7 @@ fp.close()
if not args:
runtest_args = '-a'
else:
- runtest_args = string.join(args)
+ runtest_args = ' '.join(args)
if format == '--xml':
@@ -205,10 +213,7 @@ if format == '--xml':
]
print " <environment>"
- #keys = os.environ.keys()
- keys = environ_keys
- keys.sort()
- for key in keys:
+ for key in sorted(environ_keys):
value = os.environ.get(key)
if value:
print " <variable>"
diff --git a/bin/scons-unzip.py b/bin/scons-unzip.py
index 28c73f8..d4ec4bf 100644
--- a/bin/scons-unzip.py
+++ b/bin/scons-unzip.py
@@ -45,14 +45,14 @@ if outdir is None:
def outname(n, outdir=outdir):
l = []
- while 1:
+ while True:
n, tail = os.path.split(n)
if not n:
break
l.append(tail)
l.append(outdir)
l.reverse()
- return apply(os.path.join, l)
+ return os.path.join(*l)
for name in zf.namelist():
dest = outname(name)
diff --git a/bin/sconsexamples.py b/bin/sconsexamples.py
index 0a409bc..6d3b2de 100644
--- a/bin/sconsexamples.py
+++ b/bin/sconsexamples.py
@@ -66,13 +66,11 @@
# output from SCons, and insert it into the text as appropriate.
# Error output gets passed through to your error output so you
# can see if there are any problems executing the command.
-#
import os
import os.path
import re
import sgmllib
-import string
import sys
sys.path.append(os.path.join(os.getcwd(), 'etc'))
@@ -93,7 +91,7 @@ import TestCmd
# Override it with our own regular expression that adds underscore.
sgmllib.entityref = re.compile('&([a-zA-Z][-_.a-zA-Z0-9]*)[^-_a-zA-Z0-9]')
-class DataCollector:
+class DataCollector(object):
"""Generic class for collecting data between a start tag and end
tag. We subclass for various types of tags we care about."""
def __init__(self):
@@ -156,12 +154,11 @@ Prompt = {
# command output.
Stdin = """\
-import string
import SCons.Defaults
platform = '%s'
-class Curry:
+class Curry(object):
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
@@ -174,15 +171,15 @@ class Curry:
else:
kw = kwargs or self.kwargs
- return apply(self.fun, self.pending + args, kw)
+ return self.fun(*self.pending + args, **kw)
def Str(target, source, env, cmd=""):
result = []
for cmd in env.subst_list(cmd, target=target, source=source):
- result.append(string.join(map(str, cmd)))
- return string.join(result, '\\n')
+ result.append(" ".join(map(str, cmd)))
+ return '\\n'.join(result)
-class ToolSurrogate:
+class ToolSurrogate(object):
def __init__(self, tool, variable, func):
self.tool = tool
self.variable = variable
@@ -212,7 +209,7 @@ ToolList = {
('mslink', 'LINKCOM', Cat)]
}
-tools = map(lambda t: apply(ToolSurrogate, t), ToolList[platform])
+tools = map(lambda t: ToolSurrogate(*t), ToolList[platform])
SCons.Defaults.ConstructionEnvironment.update({
'PLATFORM' : platform,
@@ -223,10 +220,7 @@ SConscript('SConstruct')
"""
class MySGML(sgmllib.SGMLParser):
- """A subclass of the standard Python 2.2 sgmllib SGML parser.
-
- Note that this doesn't work with the 1.5.2 sgmllib module, because
- that didn't have the ability to work with ENTITY declarations.
+ """A subclass of the standard Python sgmllib SGML parser.
"""
def __init__(self):
sgmllib.SGMLParser.__init__(self)
@@ -270,7 +264,7 @@ class MySGML(sgmllib.SGMLParser):
sys.stdout.write('&#' + ref + ';')
def start_scons_example(self, attrs):
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if t:
name = t[0][1]
try:
@@ -286,7 +280,7 @@ class MySGML(sgmllib.SGMLParser):
def end_scons_example(self):
e = self.e
- files = filter(lambda f: f.printme, e.files)
+ files = [f for f in e.files if f.printme]
if files:
sys.stdout.write('<programlisting>')
for f in files:
@@ -294,7 +288,7 @@ class MySGML(sgmllib.SGMLParser):
i = len(f.data) - 1
while f.data[i] == ' ':
i = i - 1
- output = string.replace(f.data[:i+1], '__ROOT__', '')
+ output = f.data[:i+1].replace('__ROOT__', '')
sys.stdout.write(output)
if e.data and e.data[0] == '\n':
e.data = e.data[1:]
@@ -307,7 +301,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<file> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <file> name attribute found")
try:
@@ -331,7 +325,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<directory> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <directory> name attribute found")
try:
@@ -350,7 +344,7 @@ class MySGML(sgmllib.SGMLParser):
self.afunclist = self.afunclist[:-1]
def start_scons_example_file(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_example_file> example attribute found")
exname = t[0][1]
@@ -358,11 +352,11 @@ class MySGML(sgmllib.SGMLParser):
e = self.examples[exname]
except KeyError:
self.error("unknown example name '%s'" % exname)
- fattrs = filter(lambda t: t[0] == 'name', attrs)
+ fattrs = [t for t in attrs if t[0] == 'name']
if not fattrs:
self.error("no <scons_example_file> name attribute found")
fname = fattrs[0][1]
- f = filter(lambda f, fname=fname: f.name == fname, e.files)
+ f = [f for f in e.files if f.name == fname]
if not f:
self.error("example '%s' does not have a file named '%s'" % (exname, fname))
self.f = f[0]
@@ -377,7 +371,7 @@ class MySGML(sgmllib.SGMLParser):
delattr(self, 'f')
def start_scons_output(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_output> example attribute found")
exname = t[0][1]
@@ -408,20 +402,19 @@ class MySGML(sgmllib.SGMLParser):
i = 0
while f.data[i] == '\n':
i = i + 1
- lines = string.split(f.data[i:], '\n')
+ lines = f.data[i:].split('\n')
i = 0
while lines[0][i] == ' ':
i = i + 1
- lines = map(lambda l, i=i: l[i:], lines)
- path = string.replace(f.name, '__ROOT__', t.workpath('ROOT'))
+ lines = [l[i:] for l in lines]
+ path = f.name.replace('__ROOT__', t.workpath('ROOT'))
dir, name = os.path.split(f.name)
if dir:
dir = t.workpath('WORK', dir)
if not os.path.exists(dir):
os.makedirs(dir)
- content = string.join(lines, '\n')
- content = string.replace(content,
- '__ROOT__',
+ content = '\n'.join(lines)
+ content = content.replace('__ROOT__',
t.workpath('ROOT'))
t.write(t.workpath('WORK', f.name), content)
i = len(o.prefix)
@@ -431,19 +424,19 @@ class MySGML(sgmllib.SGMLParser):
p = o.prefix[i:]
for c in o.commandlist:
sys.stdout.write(p + Prompt[o.os])
- d = string.replace(c.data, '__ROOT__', '')
+ d = c.data.replace('__ROOT__', '')
sys.stdout.write('<userinput>' + d + '</userinput>\n')
- e = string.replace(c.data, '__ROOT__', t.workpath('ROOT'))
- args = string.split(e)[1:]
+ e = c.data.replace('__ROOT__', t.workpath('ROOT'))
+ args = e.split()[1:]
os.environ['SCONS_LIB_DIR'] = scons_lib_dir
t.run(interpreter = sys.executable,
program = scons_py,
- arguments = '-f - ' + string.join(args),
+ arguments = '-f - ' + ' '.join(args),
chdir = t.workpath('WORK'),
stdin = Stdin % o.os)
- out = string.replace(t.stdout(), t.workpath('ROOT'), '')
+ out = t.stdout().replace(t.workpath('ROOT'), '')
if out:
- lines = string.split(out, '\n')
+ lines = out.split('\n')
if lines:
while lines[-1] == '':
lines = lines[:-1]
diff --git a/bin/sfsum b/bin/sfsum
index a560b7d..2dfa422 100644
--- a/bin/sfsum
+++ b/bin/sfsum
@@ -25,7 +25,6 @@
import xml.sax
import xml.sax.saxutils
-import string
import sys
SFName = {
@@ -42,7 +41,7 @@ SFName = {
'Christoph Wiedemann' : 'wiedeman',
}
-class Artifact:
+class Artifact(object):
"""Just a place to hold attributes that we find in the XML."""
pass
@@ -51,7 +50,7 @@ Artifacts = {}
def nws(text):
"""Normalize white space. This will become important if/when
we enhance this to search for arbitrary fields."""
- return string.join(string.split(text), ' ')
+ return ' '.join(text.split())
class ClassifyArtifacts(xml.sax.saxutils.DefaultHandler):
"""
@@ -120,9 +119,9 @@ if __name__ == '__main__':
# Hard-coded search for 'Open' bugs. This should be easily
# generalized once we figure out other things for this script to do.
- bugs = filter(lambda x: x.status == 'Open', Artifacts['Bugs'])
+ bugs = [x for x in Artifacts['Bugs'] if x.status == 'Open']
- print Artifacts.keys()
+ print list(Artifacts.keys())
print "%d open bugs" % len(bugs)
diff --git a/bin/svn-bisect.py b/bin/svn-bisect.py
index e9ebcf8..77bda58 100755
--- a/bin/svn-bisect.py
+++ b/bin/svn-bisect.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
# -*- Python -*-
+from __future__ import division
import sys
from math import log, ceil
@@ -52,7 +53,7 @@ msg = "****** max %d revisions to test (bug bracketed by [%d,%d])"
while upper-lower > 1:
print msg % (ceil(log(upper-lower,2)), lower, upper)
- mid = int((lower + upper)/2)
+ mid = (lower + upper)//2
midfails = testfail(mid)
if midfails == lowerfails:
lower = mid
diff --git a/bin/time-scons.py b/bin/time-scons.py
index 78d26e5..b7d8ef1 100644
--- a/bin/time-scons.py
+++ b/bin/time-scons.py
@@ -46,7 +46,7 @@ TimeSCons_revision = 4569
TimeSCons_pieces = ['QMTest', 'timings', 'runtest.py']
-class CommandRunner:
+class CommandRunner(object):
"""
Executor class for commands, including "commands" implemented by
Python functions.
@@ -81,11 +81,11 @@ class CommandRunner:
def display(self, command, stdout=None, stderr=None):
if not self.verbose:
return
- if type(command) == type(()):
+ if isinstance(command, tuple):
func = command[0]
args = command[1:]
s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
- if type(command) == type([]):
+ if isinstance(command, list):
# TODO: quote arguments containing spaces
# TODO: handle meta characters?
s = ' '.join(command)
@@ -102,12 +102,12 @@ class CommandRunner:
"""
if not self.active:
return 0
- if type(command) == type(''):
+ if isinstance(command, str):
command = self.subst(command)
cmdargs = shlex.split(command)
if cmdargs[0] == 'cd':
command = (os.chdir,) + tuple(cmdargs[1:])
- if type(command) == type(()):
+ if isinstance(command, tuple):
func = command[0]
args = command[1:]
return func(*args)
@@ -260,13 +260,15 @@ def do_revisions(cr, opts, branch, revisions, scripts):
lf = os.path.join(opts.origin, opts.logsdir, subdir, log_name)
out = open(lf, 'w')
err = None
+ close_out = True
else:
out = stdout
err = stderr
+ close_out = False
s = cr.run(script_command(script), stdout=out, stderr=err)
if s and status == 0:
status = s
- if out not in (sys.stdout, None):
+ if close_out:
out.close()
out = None
diff --git a/bin/update-release-info.py b/bin/update-release-info.py
new file mode 100644
index 0000000..5c438db
--- /dev/null
+++ b/bin/update-release-info.py
@@ -0,0 +1,354 @@
+#!/usr/bin/env python
+"""
+This program takes information about a release in the ReleaseConfig file
+and inserts the information in various files. It helps to keep the files
+in sync because it never forgets which files need to be updated, nor what
+information should be inserted in each file.
+
+It takes one parameter that says what the mode of update should be, which
+may be one of 'develop', 'release', or 'post'.
+
+In 'develop' mode, which is what someone would use as part of their own
+development practices, the release type is forced to be 'alpha' and the
+patch level is the string 'yyyymmdd'. Otherwise, it's the same as the
+'release' mode.
+
+In 'release' mode, the release type is taken from ReleaseConfig and the
+patch level is calculated from the release date for non-final runs and
+taken from the version tuple for final runs. It then inserts information
+in various files:
+ - The RELEASE header line in src/CHANGES.txt and src/Announce.txt.
+ - The version string at the top of src/RELEASE.txt.
+ - The version string in the 'default_version' variable in SConstruct
+ and QMTest/TestSCons.py.
+ - The copyright years in SConstruct and QMTest/TestSCons.py.
+ - The month and year (used for documentation) in SConstruct.
+ - The unsupported and deprecated Python floors in QMTest/TestSCons.py
+ and src/engine/SCons/Script/Main.py
+ - The version string in the filenames in README.
+
+In 'post' mode, files are prepared for the next release cycle:
+ - In ReleaseConfig, the version tuple is updated for the next release
+ by incrementing the release number (either minor or micro, depending
+ on the branch) and resetting release type to 'alpha'.
+ - A blank template replaces src/RELEASE.txt.
+ - A new section to accumulate changes is added to src/CHANGES.txt and
+ src/Announce.txt.
+"""
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+#
+# 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.
+
+__revision__ = "bin/update-release-info.py 5023 2010/06/14 22:05:46 scons"
+
+import os
+import sys
+import time
+import re
+
+DEBUG = os.environ.get('DEBUG', 0)
+
+# Evaluate parameter
+
+if len(sys.argv) < 2:
+ mode = 'develop'
+else:
+ mode = sys.argv[1]
+ if mode not in ['develop', 'release', 'post']:
+ print("""ERROR: `%s' as a parameter is invalid; it must be one of
+\tdevelop, release, or post. The default is develop.""" % mode)
+ sys.exit(1)
+
+# Get configuration information
+
+config = dict()
+exec open('ReleaseConfig').read() in globals(), config
+
+try:
+ version_tuple = config['version_tuple']
+ unsupported_version = config['unsupported_python_version']
+ deprecated_version = config['deprecated_python_version']
+except KeyError:
+ print('''ERROR: Config file must contain at least version_tuple,
+\tunsupported_python_version, and deprecated_python_version.''')
+ sys.exit(1)
+if DEBUG: print 'version tuple', version_tuple
+if DEBUG: print 'unsupported Python version', unsupported_version
+if DEBUG: print 'deprecated Python version', deprecated_version
+
+try:
+ release_date = config['release_date']
+except KeyError:
+ release_date = time.localtime()[:6]
+else:
+ if len(release_date) == 3:
+ release_date = release_date + time.localtime()[3:6]
+ if len(release_date) != 6:
+ print '''ERROR: Invalid release date''', release_date
+ sys.exit(1)
+if DEBUG: print 'release date', release_date
+
+if mode == 'develop' and version_tuple[3] != 'alpha':
+ version_tuple == version_tuple[:3] + ('alpha', 0)
+if version_tuple[3] != 'final':
+ if mode == 'develop':
+ version_tuple = version_tuple[:4] + ('yyyymmdd',)
+ else:
+ yyyy,mm,dd,_,_,_ = release_date
+ version_tuple = version_tuple[:4] + ((yyyy*100 + mm)*100 + dd,)
+version_string = '.'.join(map(str, version_tuple))
+version_type = version_tuple[3]
+if DEBUG: print 'version string', version_string
+
+if version_type not in ['alpha', 'beta', 'candidate', 'final']:
+ print("""ERROR: `%s' is not a valid release type in version tuple;
+\tit must be one of alpha, beta, candidate, or final""" % version_type)
+ sys.exit(1)
+
+try:
+ month_year = config['month_year']
+except KeyError:
+ if version_type == 'alpha':
+ month_year = 'MONTH YEAR'
+ else:
+ month_year = time.strftime('%B %Y', release_date + (0,0,0))
+if DEBUG: print 'month year', month_year
+
+try:
+ copyright_years = config['copyright_years']
+except KeyError:
+ copyright_years = ', '.join(map(str, list(range(2001, release_date[0] + 1))))
+if DEBUG: print 'copyright years', copyright_years
+
+class UpdateFile(object):
+ """
+ XXX
+ """
+
+ def __init__(self, file, orig = None):
+ '''
+ '''
+ if orig is None: orig = file
+ try:
+ self.content = open(orig, 'rU').read()
+ except IOError:
+ # Couldn't open file; don't try to write anything in __del__
+ self.file = None
+ raise
+ else:
+ self.file = file
+ if file == orig:
+ # so we can see if it changed
+ self.orig = self.content
+ else:
+ # pretend file changed
+ self.orig = ''
+
+ def sub(self, pattern, replacement, count = 1):
+ '''
+ XXX
+ '''
+ self.content = re.sub(pattern, replacement, self.content, count)
+
+ def replace_assign(self, name, replacement, count = 1):
+ '''
+ XXX
+ '''
+ self.sub('\n' + name + ' = .*', '\n' + name + ' = ' + replacement)
+
+ # Determine the pattern to match a version
+
+ _rel_types = '(alpha|beta|candidate|final)'
+ match_pat = '\d+\.\d+\.\d+\.' + _rel_types + '\.(\d+|yyyymmdd)'
+ match_rel = re.compile(match_pat)
+
+ def replace_version(self, replacement = version_string, count = 1):
+ '''
+ XXX
+ '''
+ self.content = self.match_rel.sub(replacement, self.content, count)
+
+ # Determine the release date and the pattern to match a date
+ # Mon, 05 Jun 2010 21:17:15 -0700
+ # NEW DATE WILL BE INSERTED HERE
+
+ if mode == 'develop':
+ new_date = 'NEW DATE WILL BE INSERTED HERE'
+ else:
+ min = (time.daylight and time.altzone or time.timezone)//60
+ hr = min//60
+ min = -(min%60 + hr*100)
+ new_date = (time.strftime('%a, %d %b %Y %X', release_date + (0,0,0))
+ + ' %+.4d' % min)
+
+ _days = '(Sun|Mon|Tue|Wed|Thu|Fri|Sat)'
+ _months = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oce|Nov|Dec)'
+ match_date = _days+', \d\d '+_months+' \d\d\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d'
+ match_date = re.compile(match_date)
+
+ def replace_date(self, replacement = new_date, count = 1):
+ '''
+ XXX
+ '''
+ self.content = self.match_date.sub(replacement, self.content, count)
+
+ def __del__(self):
+ '''
+ XXX
+ '''
+ if self.file is not None and self.content != self.orig:
+ print 'Updating ' + self.file + '...'
+ open(self.file, 'w').write(self.content)
+
+if mode == 'post':
+ # Set up for the next release series.
+
+ if version_tuple[2]:
+ # micro release, increment micro value
+ minor = version_tuple[1]
+ micro = version_tuple[2] + 1
+ else:
+ # minor release, increment minor value
+ minor = version_tuple[1] + 1
+ micro = 0
+ new_tuple = (version_tuple[0], minor, micro, 'alpha', 0)
+ new_version = '.'.join(map(str, new_tuple[:4])) + '.yyyymmdd'
+
+ # Update ReleaseConfig
+
+ t = UpdateFile('ReleaseConfig')
+ if DEBUG: t.file = '/tmp/ReleaseConfig'
+ t.replace_assign('version_tuple', str(new_tuple))
+
+ # Update src/CHANGES.txt
+
+ t = UpdateFile(os.path.join('src', 'CHANGES.txt'))
+ if DEBUG: t.file = '/tmp/CHANGES.txt'
+ t.sub('(\nRELEASE .*)', r"""\nRELEASE VERSION/DATE TO BE FILLED IN LATER\n
+ From John Doe:\n
+ - Whatever John Doe did.\n
+\1""")
+
+ # Update src/RELEASE.txt
+
+ t = UpdateFile(os.path.join('src', 'RELEASE.txt'),
+ os.path.join('template', 'RELEASE.txt'))
+ if DEBUG: t.file = '/tmp/RELEASE.txt'
+ t.replace_version(new_version)
+
+ # Update src/Announce.txt
+
+ t = UpdateFile(os.path.join('src', 'Announce.txt'))
+ if DEBUG: t.file = '/tmp/Announce.txt'
+ t.sub('\nRELEASE .*', '\nRELEASE VERSION/DATE TO BE FILLED IN LATER')
+ announce_pattern = """(
+ Please note the following important changes scheduled for the next
+ release:
+)"""
+ announce_replace = (r"""\1
+ -- FEATURE THAT WILL CHANGE\n
+ Please note the following important changes since release """
+ + '.'.join(map(str, version_tuple[:3])) + ':\n')
+ t.sub(announce_pattern, announce_replace)
+
+ # Write out the last update and exit
+
+ t = None
+ sys.exit()
+
+# Update src/CHANGES.txt
+
+t = UpdateFile(os.path.join('src', 'CHANGES.txt'))
+if DEBUG: t.file = '/tmp/CHANGES.txt'
+t.sub('\nRELEASE .*', '\nRELEASE ' + version_string + ' - ' + t.new_date)
+
+# Update src/RELEASE.txt
+
+t = UpdateFile(os.path.join('src', 'RELEASE.txt'))
+if DEBUG: t.file = '/tmp/RELEASE.txt'
+t.replace_version()
+
+# Update src/Announce.txt
+
+t = UpdateFile(os.path.join('src', 'Announce.txt'))
+if DEBUG: t.file = '/tmp/Announce.txt'
+t.sub('\nRELEASE .*', '\nRELEASE ' + version_string + ' - ' + t.new_date)
+
+# Update SConstruct
+
+t = UpdateFile('SConstruct')
+if DEBUG: t.file = '/tmp/SConstruct'
+t.replace_assign('month_year', repr(month_year))
+t.replace_assign('copyright_years', repr(copyright_years))
+t.replace_assign('default_version', repr(version_string))
+
+# Update README
+
+t = UpdateFile('README')
+if DEBUG: t.file = '/tmp/README'
+t.sub('-' + t.match_pat + '\.', '-' + version_string + '.', count = 0)
+# the loop below can be removed after all 1.x.y releases are dead
+for suf in ['tar', 'win32', 'zip']:
+ t.sub('-(\d+\.\d+\.\d+)\.%s' % suf,
+ '-%s.%s' % (version_string, suf),
+ count = 0)
+
+# Update QMTest/TestSCons.py
+
+t = UpdateFile(os.path.join('QMTest', 'TestSCons.py'))
+if DEBUG: t.file = '/tmp/TestSCons.py'
+t.replace_assign('copyright_years', repr(copyright_years))
+t.replace_assign('default_version', repr(version_string))
+#??? t.replace_assign('SConsVersion', repr(version_string))
+t.replace_assign('python_version_unsupported', str(unsupported_version))
+t.replace_assign('python_version_deprecated', str(deprecated_version))
+
+# Update Script/Main.py
+
+t = UpdateFile(os.path.join('src', 'engine', 'SCons', 'Script', 'Main.py'))
+if DEBUG: t.file = '/tmp/Main.py'
+t.replace_assign('unsupported_python_version', str(unsupported_version))
+t.replace_assign('deprecated_python_version', str(deprecated_version))
+
+# Update doc/user/main.{in,xml}
+
+docyears = ', '.join(map(str, iter(range(2004, release_date[0] + 1))))
+t = UpdateFile(os.path.join('doc', 'user', 'main.in'))
+if DEBUG: t.file = '/tmp/main.in'
+## TODO debug these
+#t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
+#t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
+
+t = UpdateFile(os.path.join('doc', 'user', 'main.xml'))
+if DEBUG: t.file = '/tmp/main.xml'
+## TODO debug these
+#t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
+#t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
+
+# Write out the last update
+
+t = None
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/bin/xmlagenda.py b/bin/xmlagenda.py
index 3009e4c..7937331 100755
--- a/bin/xmlagenda.py
+++ b/bin/xmlagenda.py
@@ -17,24 +17,23 @@
# The team members
# FIXME: These names really should be external to this script
-team = 'Bill Greg Steven Gary Ken Brandon Sohail Jim David'.split()
-team.sort()
+team = sorted('Steven Gary Greg Ken Jim David Bill Sergey Jason'.split())
# The elements to be picked out of the issue
PickList = [
- # sort key -- these are used to sort the entry
- 'target_milestone', 'priority', 'votes_desc', 'creation_ts',
- # payload -- these are displayed
- 'issue_id', 'votes', 'issue_type', 'target_milestone',
- 'priority', 'assigned_to', 'short_desc',
- ]
+ # sort key -- these are used to sort the entry
+ 'target_milestone', 'priority', 'votes_desc', 'creation_ts',
+ # payload -- these are displayed
+ 'issue_id', 'votes', 'issue_type', 'target_milestone',
+ 'priority', 'assigned_to', 'short_desc',
+ ]
# Conbert a leaf element into its value as a text string
# We assume it's "short enough" that there's only one substring
def Value(element):
- v = element.firstChild
- if v is None: return ''
- return v.nodeValue
+ v = element.firstChild
+ if v is None: return ''
+ return v.nodeValue
# Parse the XML issues file and produce a DOM for it
import sys
@@ -47,26 +46,26 @@ xml = parse(xml)
# and put them in our list of issues.
issues = []
for issuezilla in xml.childNodes:
- # The Issuezilla element contains the issues
- if issuezilla.nodeType != issuezilla.ELEMENT_NODE: continue
- for issue in issuezilla.childNodes:
- # The issue elements contain the info for an issue
- if issue.nodeType != issue.ELEMENT_NODE: continue
- # Accumulate the pieces we want to include
- d = {}
- for element in issue.childNodes:
- if element.nodeName in PickList:
- d[element.nodeName] = Value(element)
- # convert 'votes' to numeric, ascending and descending
- try:
- v = int('0' + d['votes'])
- except KeyError:
- pass
- else:
- d['votes_desc'] = -v
- d['votes'] = v
- # Marshal the elements and add them to the list
- issues.append([ d[ix] for ix in PickList ])
+ # The Issuezilla element contains the issues
+ if issuezilla.nodeType != issuezilla.ELEMENT_NODE: continue
+ for issue in issuezilla.childNodes:
+ # The issue elements contain the info for an issue
+ if issue.nodeType != issue.ELEMENT_NODE: continue
+ # Accumulate the pieces we want to include
+ d = {}
+ for element in issue.childNodes:
+ if element.nodeName in PickList:
+ d[element.nodeName] = Value(element)
+ # convert 'votes' to numeric, ascending and descending
+ try:
+ v = int('0' + d['votes'])
+ except KeyError:
+ pass
+ else:
+ d['votes_desc'] = -v
+ d['votes'] = v
+ # Marshal the elements and add them to the list
+ issues.append([ d[ix] for ix in PickList ])
issues.sort()
# Transcribe the issues into comma-separated values.
@@ -75,16 +74,16 @@ import csv
writer = csv.writer(open('editlist.csv', 'w'))
# header
writer.writerow(['ID', 'Votes', 'Type/Member', 'Milestone',
- 'Pri', 'Owner', 'Summary/Comments'])
+ 'Pri', 'Owner', 'Summary/Comments'])
for issue in issues:
- row = issue[4:] # strip off sort key
- #row[0] = """=hyperlink("http://scons.tigris.org/issues/show_bug.cgi?id=%s","%s")""" % (row[0],row[0])
- if row[3] == '-unspecified-': row[3] = 'triage'
- writer.writerow(['','','','','','',''])
- writer.writerow(row)
- writer.writerow(['','','consensus','','','',''])
- writer.writerow(['','','','','','',''])
- for member in team: writer.writerow(['','',member,'','','',''])
+ row = issue[4:] # strip off sort key
+ #row[0] = """=hyperlink("http://scons.tigris.org/issues/show_bug.cgi?id=%s","%s")""" % (row[0],row[0])
+ if row[3] == '-unspecified-': row[3] = 'triage'
+ writer.writerow(['','','','','','',''])
+ writer.writerow(row)
+ writer.writerow(['','','consensus','','','',''])
+ writer.writerow(['','','','','','',''])
+ for member in team: writer.writerow(['','',member,'','','',''])
# Local Variables:
# tab-width:4