summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/calibrate.py6
-rw-r--r--bin/docdiff16
-rw-r--r--bin/docrun16
-rw-r--r--bin/docupdate16
-rw-r--r--bin/import-test.py4
-rw-r--r--bin/linecount.py4
-rw-r--r--bin/restore.sh28
-rw-r--r--bin/scons-doc.py95
-rw-r--r--bin/scons-proc.py174
-rw-r--r--bin/sconsexamples.py505
-rwxr-xr-xbin/scp-sourceforge38
-rw-r--r--bin/update-release-info.py18
-rwxr-xr-xbin/xmlagenda.py18
13 files changed, 305 insertions, 633 deletions
diff --git a/bin/calibrate.py b/bin/calibrate.py
index f377869..72a6ac7 100644
--- a/bin/calibrate.py
+++ b/bin/calibrate.py
@@ -64,7 +64,11 @@ def main(argv=None):
output = p.communicate()[0]
vm = variable_re.search(output)
em = elapsed_re.search(output)
- elapsed = float(em.group(1))
+ try:
+ elapsed = float(em.group(1))
+ except AttributeError:
+ print output
+ raise
print "run %3d: %7.3f: %s" % (run, elapsed, ' '.join(vm.groups()))
if opts.min < elapsed and elapsed < opts.max:
good += 1
diff --git a/bin/docdiff b/bin/docdiff
deleted file mode 100644
index c7adb05..0000000
--- a/bin/docdiff
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if test $# -eq 0; then
- for f in doc/user/*.in; do
- xml=doc/user/`basename $f .in`.xml
- echo $f:
- python bin/scons-doc.py $f | diff $DIFFFLAGS $xml -
- done
-else
- for a in $*; do
- f=doc/user/$a.in
- xml=doc/user/$a.xml
- echo $f:
- python bin/scons-doc.py $f | diff $DIFFFLAGS $xml -
- done
-fi
diff --git a/bin/docrun b/bin/docrun
deleted file mode 100644
index ad8ea9f..0000000
--- a/bin/docrun
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if test $# -eq 0; then
- for f in doc/user/*.in; do
- xml=doc/user/`basename $f .in`.xml
- echo $f:
- python bin/scons-doc.py $f
- done
-else
- for a in $*; do
- f=doc/user/$a.in
- xml=doc/user/$a.xml
- echo $f:
- python bin/scons-doc.py $f
- done
-fi
diff --git a/bin/docupdate b/bin/docupdate
deleted file mode 100644
index cd9b532..0000000
--- a/bin/docupdate
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if test $# -eq 0; then
- for f in doc/user/*.in; do
- xml=doc/user/`basename $f .in`.xml
- echo $f:
- python bin/scons-doc.py $f > $xml
- done
-else
- for a in $*; do
- f=doc/user/$a.in
- xml=doc/user/$a.xml
- echo $f:
- python bin/scons-doc.py $f > $xml
- done
-fi
diff --git a/bin/import-test.py b/bin/import-test.py
index 4991aee..cb95ff2 100644
--- a/bin/import-test.py
+++ b/bin/import-test.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
#
# tree2test.py - turn a directory tree into TestSCons code
#
@@ -25,7 +25,7 @@
# """ triple-quotes will need to have their contents edited by hand.
#
-__revision__ = "bin/import-test.py 5134 2010/08/16 23:02:40 bdeegan"
+__revision__ = "bin/import-test.py 5357 2011/09/09 21:31:03 bdeegan"
import os.path
import sys
diff --git a/bin/linecount.py b/bin/linecount.py
index 9d0be94..7121ebd 100644
--- a/bin/linecount.py
+++ b/bin/linecount.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
#
# Count statistics about SCons test and source files. This must be run
# against a fully-populated tree (for example, one that's been freshly
@@ -23,7 +23,7 @@
# interesting one for most purposes.
from __future__ import division
-__revision__ = "bin/linecount.py 5134 2010/08/16 23:02:40 bdeegan"
+__revision__ = "bin/linecount.py 5357 2011/09/09 21:31:03 bdeegan"
import os.path
diff --git a/bin/restore.sh b/bin/restore.sh
index 6db56f1..3aab7ae 100644
--- a/bin/restore.sh
+++ b/bin/restore.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env sh
#
-# Simple hack script to restore __revision__, __COPYRIGHT_, 2.0.1
+# Simple hack script to restore __revision__, __COPYRIGHT_, 2.1.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.
#
@@ -22,9 +22,9 @@ header() {
for i in `find $DIRS -name '*.py'`; do
header $i
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
+g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation/p
w
-/^__revision__ = /s/= .*/= "bin/restore.sh 5134 2010/08/16 23:02:40 bdeegan"/p
+/^__revision__ = /s/= .*/= "bin/restore.sh 5357 2011/09/09 21:31:03 bdeegan"/p
w
q
EOF
@@ -33,9 +33,9 @@ done
for i in `find $DIRS -name 'scons.bat'`; do
header $i
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
+g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation/p
w
-/^@REM src\/script\/scons.bat/s/@REM .* knight/@REM bin/restore.sh 5134 2010/08/16 23:02:40 bdeegan/p
+/^@REM src\/script\/scons.bat/s/@REM .* knight/@REM bin/restore.sh 5357 2011/09/09 21:31:03 bdeegan/p
w
q
EOF
@@ -44,13 +44,13 @@ 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/= .*/= "2.0.1"/p
+/^__version__ = /s/= .*/= "2.1.0"/p
w
-/^__build__ = /s/= .*/= "r5134"/p
+/^__build__ = /s/= .*/= "r5357[MODIFIED]"/p
w
-/^__buildsys__ = /s/= .*/= "cooldog"/p
+/^__buildsys__ = /s/= .*/= "ubuntu"/p
w
-/^__date__ = /s/= .*/= "2010/08/16 23:02:40"/p
+/^__date__ = /s/= .*/= "2011/09/09 21:31:03"/p
w
/^__developer__ = /s/= .*/= "bdeegan"/p
w
@@ -61,7 +61,7 @@ done
for i in `find $DIRS -name 'setup.py'`; do
header $i
ed $i <<EOF
-/^ *version = /s/= .*/= "2.0.1",/p
+/^ *version = /s/= .*/= "2.1.0",/p
w
q
EOF
@@ -70,11 +70,11 @@ done
for i in `find $DIRS -name '*.txt'`; do
header $i
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
+g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation/p
w
-/# [^ ]* 0.96.[CD][0-9]* [0-9\/]* [0-9:]* knight$/s/.*/# bin/restore.sh 5134 2010/08/16 23:02:40 bdeegan/p
+/# [^ ]* 0.96.[CD][0-9]* [0-9\/]* [0-9:]* knight$/s/.*/# bin/restore.sh 5357 2011/09/09 21:31:03 bdeegan/p
w
-/Version [0-9][0-9]*\.[0-9][0-9]*/s//Version 2.0.1/p
+/Version [0-9][0-9]*\.[0-9][0-9]*/s//Version 2.1.0/p
w
q
EOF
@@ -83,7 +83,7 @@ done
for i in `find $DIRS -name '*.xml'`; do
header $i
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
+g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation/p
w
q
EOF
diff --git a/bin/scons-doc.py b/bin/scons-doc.py
index 14e862c..f99dfa7 100644
--- a/bin/scons-doc.py
+++ b/bin/scons-doc.py
@@ -26,6 +26,23 @@
# and inserting it into examples in our DocBook
# documentation
#
+# Synopsis:
+#
+# scons-doc [OPTIONS] [.in files]
+#
+# When no input files are given, the folder doc/user/* is searched for .in files.
+#
+# Available options:
+#
+# -d, --diff create examples for the .in file and output a unified
+# diff against the related .xml file
+# -r, --run create examples for the .in file, but do not change
+# any files
+# -s, --simple_diff use a simpler output for the diff mode (no unified
+# diff!)
+# -u, --update create examples for the .in file and update the
+# related .xml file
+#
# This script looks for some SGML tags that describe SCons example
# configurations and commands to execute in those configurations, and
# uses TestCmd.py to execute the commands and insert the output from
@@ -95,6 +112,7 @@ import re
import sgmllib
import sys
import time
+import glob
sys.path.append(os.path.join(os.getcwd(), 'QMTest'))
sys.path.append(os.path.join(os.getcwd(), 'build', 'QMTest'))
@@ -811,7 +829,7 @@ class MySGML(sgmllib.SGMLParser):
delattr(self, 'f')
self.afunclist = self.afunclist[:-1]
-def process(filename):
+def process(filename, fout=sys.stdout):
if filename == '-':
f = sys.stdin
else:
@@ -829,7 +847,7 @@ def process(filename):
first_line, data = data.split('\n', 1)
sys.stdout.write(first_line + '\n')
- x = MySGML(sys.stdout)
+ x = MySGML(fout)
for c in data:
x.feed(c)
x.close()
@@ -841,13 +859,76 @@ def main(argv=None):
argv = sys.argv
parser = optparse.OptionParser()
- opts, args = parser.parse_args(argv[1:])
+ parser.add_option('-d', '--diff',
+ action='store_true', dest='diff', default=False,
+ help='create examples for the .in file and output a unified diff against the related .xml file')
+ parser.add_option('-r', '--run',
+ action='store_true', dest='run', default=False,
+ help='create examples for the .in file, but do not change any files')
+ parser.add_option('-s', '--simple_diff',
+ action='store_true', dest='simple', default=False,
+ help='use a simpler output for the diff mode (no unified diff!)')
+ parser.add_option('-u', '--update',
+ action='store_true', dest='update', default=False,
+ help='create examples for the .in file and update the related .xml file')
- if not args:
- args = ['-']
+ opts, args = parser.parse_args(argv[1:])
- for arg in args:
- process(arg)
+ if opts.diff:
+ import StringIO
+ import difflib
+
+ if not args:
+ args = glob.glob('doc/user/*.in')
+ for arg in sorted(args):
+ diff = None
+ s = StringIO.StringIO()
+ process(arg,s)
+ filename = arg[:-2]+'xml'
+ try:
+ fxml = open(filename, 'r')
+ xmlcontent = fxml.read()
+ fxml.close()
+ if opts.simple:
+ diff = list(difflib.context_diff(xmlcontent.splitlines(),
+ s.getvalue().splitlines(),
+ fromfile=arg, tofile=filename))
+ else:
+ diff = list(difflib.unified_diff(xmlcontent.splitlines(),
+ s.getvalue().splitlines(),
+ fromfile=arg, tofile=filename,
+ lineterm=''))
+ except EnvironmentError, e:
+ sys.stderr.write('%s: %s\n' % (filename, e))
+
+ s.close()
+ if diff:
+ print "%s:" % arg
+ print '\n'.join(diff)
+ elif opts.run:
+ if not args:
+ args = glob.glob('doc/user/*.in')
+ for arg in sorted(args):
+ print "%s:" % arg
+ process(arg)
+ elif opts.update:
+ if not args:
+ args = glob.glob('doc/user/*.in')
+ for arg in sorted(args):
+ print "%s:" % arg
+ filename = arg[:-2]+'xml'
+ try:
+ fxml = open(filename, 'w')
+ process(arg, fxml)
+ fxml.close()
+ except EnvironmentError, e:
+ sys.stderr.write('%s: %s\n' % (filename, e))
+ else:
+ if not args:
+ args = ['-']
+
+ for arg in args:
+ process(arg)
if __name__ == "__main__":
sys.exit(main())
diff --git a/bin/scons-proc.py b/bin/scons-proc.py
index 7cdb618..6d15816 100644
--- a/bin/scons-proc.py
+++ b/bin/scons-proc.py
@@ -10,10 +10,11 @@
# 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
import re
+import string
+import sys
import xml.sax
try:
from io import StringIO
@@ -153,9 +154,7 @@ class SCons_XML_to_XML(SCons_XML):
for v in self.values:
f.write('\n<varlistentry id="%s%s">\n' %
(v.prefix, v.idfunc()))
- for term in v.termfunc():
- f.write('<term><%s>%s</%s></term>\n' %
- (v.tag, term, v.tag))
+ f.write('%s\n' % v.xml_term())
f.write('<listitem>\n')
for chunk in v.summary.body:
f.write(str(chunk))
@@ -212,23 +211,41 @@ class SCons_XML_to_XML(SCons_XML):
class SCons_XML_to_man(SCons_XML):
def write(self, filename):
+ """
+ Converts the contents of the specified filename from DocBook XML
+ to man page macros.
+
+ This does not do an intelligent job. In particular, it doesn't
+ actually use the structured nature of XML to handle arbitrary
+ input. Instead, we're using text replacement and regular
+ expression substitutions to convert observed patterns into the
+ macros we want. To the extent that we're relatively consistent
+ with our input .xml, this works, but could easily break if handed
+ input that doesn't match these specific expectations.
+ """
if not filename:
return
f = self.fopen(filename)
chunks = []
for v in self.values:
- chunks.extend(v.mansep())
- chunks.extend(v.initial_chunks())
+ chunks.extend(v.man_separator())
+ chunks.extend(v.initial_man_chunks())
chunks.extend(list(map(str, v.summary.body)))
body = ''.join(chunks)
+
+ # Simple transformation of examples into our defined macros for those.
body = body.replace('<programlisting>', '.ES')
body = body.replace('</programlisting>', '.EE')
+
+ # Replace groupings of <para> tags and surrounding newlines
+ # with single blank lines.
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', '')
+ # Convert <variablelist> and its child tags.
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,
@@ -240,35 +257,54 @@ class SCons_XML_to_man(SCons_XML):
body = body.replace('</varlistentry>\n', '')
body = body.replace('</variablelist>\n', '.RE\n')
+ # Get rid of unnecessary .IP macros, and unnecessary blank lines
+ # in front of .IP macros.
body = re.sub(r'\.EE\n\n+(?!\.IP)', '.EE\n.IP\n', body)
+ body = body.replace('\n.EE\n.IP\n.ES\n', '\n.EE\n\n.ES\n')
body = body.replace('\n.IP\n\'\\"', '\n\n\'\\"')
- body = re.sub('&(scons|SConstruct|SConscript|jar|Make|lambda);', r'\\fB\1\\fP', body)
+
+ # Convert various named entities and tagged names to nroff
+ # in-line font conversions (\fB, \fI, \fP).
+ body = re.sub('&(scons|SConstruct|SConscript|Dir|jar|Make|lambda);',
+ r'\\fB\1\\fP', body)
body = re.sub('&(TARGET|TARGETS|SOURCE|SOURCES);', r'\\fB$\1\\fP', body)
- body = body.replace('&Dir;', r'\fBDir\fP')
- body = body.replace('&target;', r'\fItarget\fP')
- body = body.replace('&source;', r'\fIsource\fP')
+ body = re.sub('&(target|source);', r'\\fI\1\\fP', body)
body = re.sub('&b(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
- body = re.sub('&cv(-link)?-([^;]*);', r'$\2', body)
+ body = re.sub('&cv(-link)?-([^;]*);', r'\\fB$\2\\fP', body)
body = re.sub('&f(-link)?-env-([^;]*);', r'\\fBenv.\2\\fP()', body)
body = re.sub('&f(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
body = re.sub(r'<(application|command|envar|filename|function|literal|option)>([^<]*)</\1>',
r'\\fB\2\\fP', body)
body = re.sub(r'<(classname|emphasis|varname)>([^<]*)</\1>',
r'\\fI\2\\fP', body)
+
+ # Convert groupings of font conversions (\fB, \fI, \fP) to
+ # man page .B, .BR, .I, .IR, .R, .RB and .RI macros.
body = re.compile(r'^\\f([BI])([^\\]* [^\\]*)\\fP\s*$', re.M).sub(r'.\1 "\2"', body)
body = re.compile(r'^\\f([BI])(.*)\\fP\s*$', re.M).sub(r'.\1 \2', body)
body = re.compile(r'^\\f([BI])(.*)\\fP(\S+)$', re.M).sub(r'.\1R \2 \3', body)
+ body = re.compile(r'^(\.B)( .*)\\fP(.*)\\fB(.*)$', re.M).sub(r'\1R\2 \3 \4', body)
+ body = re.compile(r'^(\.B)R?( .*)\\fP(.*)\\fI(.*)$', re.M).sub(r'\1I\2\3 \4', body)
+ body = re.compile(r'^(\.I)( .*)\\fP\\fB(.*)\\fP\\fI(.*)$', re.M).sub(r'\1R\2 \3 \4', body)
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)
+
+ # Convert &lt; and &gt; entities to literal < and > characters.
body = body.replace('&lt;', '<')
body = body.replace('&gt;', '>')
- body = re.sub(r'\\([^f])', r'\\\\\1', body)
+
+ # Backslashes. Oh joy.
+ body = re.sub(r'\\(?=[^f])', r'\\\\', body)
body = re.compile("^'\\\\\\\\", re.M).sub("'\\\\", body)
+ body = re.compile(r'^\.([BI]R?) ([^"]\S*\\\\\S+[^"])$', re.M).sub(r'.\1 "\2"', body)
+
+ # Put backslashes in front of various hyphens that need
+ # to be long em-dashes.
body = re.compile(r'^\.([BI]R?) --', re.M).sub(r'.\1 \-\-', body)
body = re.compile(r'^\.([BI]R?) -', re.M).sub(r'.\1 \-', body)
- body = re.compile(r'^\.([BI]R?) (\S+)\\\\(\S+)$', re.M).sub(r'.\1 "\2\\\\\\\\\2"', body)
body = re.compile(r'\\f([BI])-', re.M).sub(r'\\f\1\-', body)
+
f.write(body)
class Proxy(object):
@@ -290,34 +326,91 @@ class Proxy(object):
return cmp(self.__subject, other)
return cmp(self.__dict__, other.__dict__)
-class Builder(Proxy):
+class SConsThing(Proxy):
+ def idfunc(self):
+ return self.name
+ def xml_term(self):
+ return '<term>%s</term>' % self.name
+
+class Builder(SConsThing):
description = 'builder'
prefix = 'b-'
tag = 'function'
- def idfunc(self):
- return self.name
- def termfunc(self):
- return ['%s()' % self.name, 'env.%s()' % self.name]
+ def xml_term(self):
+ return ('<term><synopsis><%s>%s()</%s></synopsis>\n<synopsis><%s>env.%s()</%s></synopsis></term>' %
+ (self.tag, self.name, self.tag, self.tag, self.name, self.tag))
def entityfunc(self):
return self.name
- def mansep(self):
+ def man_separator(self):
return ['\n', "'\\" + '"'*69 + '\n']
- def initial_chunks(self):
- return [ '.IP %s\n' % t for t in self.termfunc() ]
+ def initial_man_chunks(self):
+ return [ '.IP %s()\n.IP env.%s()\n' % (self.name, self.name) ]
-class Function(Proxy):
+class Function(SConsThing):
description = 'function'
prefix = 'f-'
tag = 'function'
- def idfunc(self):
- return self.name
- def termfunc(self):
- return ['%s()' % self.name, 'env.%s()' % self.name]
+ def args_to_xml(self, arg):
+ s = ''.join(arg.body).strip()
+ result = []
+ for m in re.findall('([a-zA-Z/_]+=?|[^a-zA-Z/_]+)', s):
+ if m[0] in string.letters:
+ if m[-1] == '=':
+ result.append('<literal>%s</literal>=' % m[:-1])
+ else:
+ result.append('<varname>%s</varname>' % m)
+ else:
+ result.append(m)
+ return ''.join(result)
+ def xml_term(self):
+ try:
+ arguments = self.arguments
+ except AttributeError:
+ arguments = ['()']
+ result = ['<term>']
+ for arg in arguments:
+ try:
+ signature = arg.signature
+ except AttributeError:
+ signature = "both"
+ s = self.args_to_xml(arg)
+ if signature in ('both', 'global'):
+ result.append('<synopsis>%s%s</synopsis>\n' % (self.name, s)) #<br>
+ if signature in ('both', 'env'):
+ result.append('<synopsis><varname>env</varname>.%s%s</synopsis>' % (self.name, s))
+ result.append('</term>')
+ return ''.join(result)
def entityfunc(self):
return self.name
- def mansep(self):
+ def man_separator(self):
return ['\n', "'\\" + '"'*69 + '\n']
- def initial_chunks(self):
+ def args_to_man(self, arg):
+ """Converts the contents of an <arguments> tag, which
+ specifies a function's calling signature, into a series
+ of tokens that alternate between literal tokens
+ (to be displayed in roman or bold face) and variable
+ names (to be displayed in italics).
+
+ This is complicated by the presence of Python "keyword=var"
+ arguments, where "keyword=" should be displayed literally,
+ and "var" should be displayed in italics. We do this by
+ detecting the keyword= var portion and appending it to the
+ previous string, if any.
+ """
+ s = ''.join(arg.body).strip()
+ result = []
+ for m in re.findall('([a-zA-Z/_]+=?|[^a-zA-Z/_]+)', s):
+ if m[-1] == '=' and result:
+ if result[-1][-1] == '"':
+ result[-1] = result[-1][:-1] + m + '"'
+ else:
+ result[-1] += m
+ else:
+ if ' ' in m:
+ m = '"%s"' % m
+ result.append(m)
+ return ' '.join(result)
+ def initial_man_chunks(self):
try:
arguments = self.arguments
except AttributeError:
@@ -328,40 +421,35 @@ class Function(Proxy):
signature = arg.signature
except AttributeError:
signature = "both"
+ s = self.args_to_man(arg)
if signature in ('both', 'global'):
- result.append('.TP\n.RI %s%s\n' % (self.name, arg))
+ result.append('.TP\n.RI %s%s\n' % (self.name, s))
if signature in ('both', 'env'):
- result.append('.TP\n.IR env .%s%s\n' % (self.name, arg))
+ result.append('.TP\n.IR env .%s%s\n' % (self.name, s))
return result
-class Tool(Proxy):
+class Tool(SConsThing):
description = 'tool'
prefix = 't-'
tag = 'literal'
def idfunc(self):
return self.name.replace('+', 'X')
- def termfunc(self):
- return [self.name]
def entityfunc(self):
return self.name
- def mansep(self):
+ def man_separator(self):
return ['\n']
- def initial_chunks(self):
+ def initial_man_chunks(self):
return ['.IP %s\n' % self.name]
-class Variable(Proxy):
+class Variable(SConsThing):
description = 'construction variable'
prefix = 'cv-'
tag = 'envar'
- def idfunc(self):
- return self.name
- def termfunc(self):
- return [self.name]
def entityfunc(self):
return '$' + self.name
- def mansep(self):
+ def man_separator(self):
return ['\n']
- def initial_chunks(self):
+ def initial_man_chunks(self):
return ['.IP %s\n' % self.name]
if output_type == '--man':
diff --git a/bin/sconsexamples.py b/bin/sconsexamples.py
deleted file mode 100644
index 6d3b2de..0000000
--- a/bin/sconsexamples.py
+++ /dev/null
@@ -1,505 +0,0 @@
-#!/usr/bin/env python2
-#
-# scons_examples.py - an SGML preprocessor for capturing SCons output
-# and inserting into examples in our DocBook
-# documentation
-#
-
-# This script looks for some SGML tags that describe SCons example
-# configurations and commands to execute in those configurations, and
-# uses TestCmd.py to execute the commands and insert the output into
-# the output SGML. This way, we can run a script and update all of
-# our example output without having to do a lot of laborious by-hand
-# checking.
-#
-# An "SCons example" looks like this, and essentially describes a set of
-# input files (program source files as well as SConscript files):
-#
-# <scons_example name="ex1">
-# <file name="SConstruct" printme="1">
-# env = Environment()
-# env.Program('foo')
-# </file>
-# <file name="foo.c">
-# int main() { printf("foo.c\n"); }
-# </file>
-# </scons_example>
-#
-# The <file> contents within the <scons_example> tag will get written
-# into a temporary directory whenever example output needs to be
-# generated. By default, the <file> contents are not inserted into text
-# directly, unless you set the "printme" attribute on one or more files,
-# in which case they will get inserted within a <programlisting> tag.
-# This makes it easy to define the example at the appropriate
-# point in the text where you intend to show the SConstruct file.
-#
-# Note that you should usually give the <scons_example> a "name"
-# attribute so that you can refer to the example configuration later to
-# run SCons and generate output.
-#
-# If you just want to show a file's contents without worry about running
-# SCons, there's a shorter <sconstruct> tag:
-#
-# <sconstruct>
-# env = Environment()
-# env.Program('foo')
-# </sconstruct>
-#
-# This is essentially equivalent to <scons_example><file printme="1">,
-# but it's more straightforward.
-#
-# SCons output is generated from the following sort of tag:
-#
-# <scons_output example="ex1" os="posix">
-# <command>scons -Q foo</command>
-# <command>scons -Q foo</command>
-# </scons_output>
-#
-# You tell it which example to use with the "example" attribute, and
-# then give it a list of <command> tags to execute. You can also supply
-# an "os" tag, which specifies the type of operating system this example
-# is intended to show; if you omit this, default value is "posix".
-#
-# The generated SGML will show the command line (with the appropriate
-# command-line prompt for the operating system), execute the command in
-# a temporary directory with the example files, capture the standard
-# 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 sys
-
-sys.path.append(os.path.join(os.getcwd(), 'etc'))
-sys.path.append(os.path.join(os.getcwd(), 'build', 'etc'))
-
-scons_py = os.path.join('bootstrap', 'src', 'script', 'scons.py')
-if not os.path.exists(scons_py):
- scons_py = os.path.join('src', 'script', 'scons.py')
-
-scons_lib_dir = os.path.join(os.getcwd(), 'bootstrap', 'src', 'engine')
-if not os.path.exists(scons_lib_dir):
- scons_lib_dir = os.path.join(os.getcwd(), 'src', 'engine')
-
-import TestCmd
-
-# The regular expression that identifies entity references in the
-# standard sgmllib omits the underscore from the legal characters.
-# 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(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):
- self.data = ""
- def afunc(self, data):
- self.data = self.data + data
-
-class Example(DataCollector):
- """An SCons example. This is essentially a list of files that
- will get written to a temporary directory to collect output
- from one or more SCons runs."""
- def __init__(self):
- DataCollector.__init__(self)
- self.files = []
- self.dirs = []
-
-class File(DataCollector):
- """A file, that will get written out to a temporary directory
- for one or more SCons runs."""
- def __init__(self, name):
- DataCollector.__init__(self)
- self.name = name
-
-class Directory(DataCollector):
- """A directory, that will get created in a temporary directory
- for one or more SCons runs."""
- def __init__(self, name):
- DataCollector.__init__(self)
- self.name = name
-
-class Output(DataCollector):
- """Where the command output goes. This is essentially
- a list of commands that will get executed."""
- def __init__(self):
- DataCollector.__init__(self)
- self.commandlist = []
-
-class Command(DataCollector):
- """A tag for where the command output goes. This is essentially
- a list of commands that will get executed."""
- pass
-
-Prompt = {
- 'posix' : '% ',
- 'win32' : 'C:\\>'
-}
-
-# Magick SCons hackery.
-#
-# So that our examples can still use the default SConstruct file, we
-# actually feed the following into SCons via stdin and then have it
-# SConscript() the SConstruct file. This stdin wrapper creates a set
-# of ToolSurrogates for the tools for the appropriate platform. These
-# Surrogates print output like the real tools and behave like them
-# without actually having to be on the right platform or have the right
-# tool installed.
-#
-# The upshot: We transparently change the world out from under the
-# top-level SConstruct file in an example just so we can get the
-# command output.
-
-Stdin = """\
-import SCons.Defaults
-
-platform = '%s'
-
-class Curry(object):
- def __init__(self, fun, *args, **kwargs):
- self.fun = fun
- self.pending = args[:]
- self.kwargs = kwargs.copy()
-
- def __call__(self, *args, **kwargs):
- if kwargs and self.kwargs:
- kw = self.kwargs.copy()
- kw.update(kwargs)
- else:
- kw = kwargs or self.kwargs
-
- 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(" ".join(map(str, cmd)))
- return '\\n'.join(result)
-
-class ToolSurrogate(object):
- def __init__(self, tool, variable, func):
- self.tool = tool
- self.variable = variable
- self.func = func
- def __call__(self, env):
- t = Tool(self.tool)
- t.generate(env)
- orig = env[self.variable]
- env[self.variable] = Action(self.func, strfunction=Curry(Str, cmd=orig))
-
-def Null(target, source, env):
- pass
-
-def Cat(target, source, env):
- target = str(target[0])
- f = open(target, "wb")
- for src in map(str, source):
- f.write(open(src, "rb").read())
- f.close()
-
-ToolList = {
- 'posix' : [('cc', 'CCCOM', Cat),
- ('link', 'LINKCOM', Cat),
- ('tar', 'TARCOM', Null),
- ('zip', 'ZIPCOM', Null)],
- 'win32' : [('msvc', 'CCCOM', Cat),
- ('mslink', 'LINKCOM', Cat)]
-}
-
-tools = map(lambda t: ToolSurrogate(*t), ToolList[platform])
-
-SCons.Defaults.ConstructionEnvironment.update({
- 'PLATFORM' : platform,
- 'TOOLS' : tools,
-})
-
-SConscript('SConstruct')
-"""
-
-class MySGML(sgmllib.SGMLParser):
- """A subclass of the standard Python sgmllib SGML parser.
- """
- def __init__(self):
- sgmllib.SGMLParser.__init__(self)
- self.examples = {}
- self.afunclist = []
-
- def handle_data(self, data):
- try:
- f = self.afunclist[-1]
- except IndexError:
- sys.stdout.write(data)
- else:
- f(data)
-
- def handle_comment(self, data):
- sys.stdout.write('<!--' + data + '-->')
-
- def handle_decl(self, data):
- sys.stdout.write('<!' + data + '>')
-
- def unknown_starttag(self, tag, attrs):
- try:
- f = self.example.afunc
- except AttributeError:
- f = sys.stdout.write
- if not attrs:
- f('<' + tag + '>')
- else:
- f('<' + tag)
- for name, value in attrs:
- f(' ' + name + '=' + '"' + value + '"')
- f('>')
-
- def unknown_endtag(self, tag):
- sys.stdout.write('</' + tag + '>')
-
- def unknown_entityref(self, ref):
- sys.stdout.write('&' + ref + ';')
-
- def unknown_charref(self, ref):
- sys.stdout.write('&#' + ref + ';')
-
- def start_scons_example(self, attrs):
- t = [t for t in attrs if t[0] == 'name']
- if t:
- name = t[0][1]
- try:
- e = self.examples[name]
- except KeyError:
- e = self.examples[name] = Example()
- else:
- e = Example()
- for name, value in attrs:
- setattr(e, name, value)
- self.e = e
- self.afunclist.append(e.afunc)
-
- def end_scons_example(self):
- e = self.e
- files = [f for f in e.files if f.printme]
- if files:
- sys.stdout.write('<programlisting>')
- for f in files:
- if f.printme:
- i = len(f.data) - 1
- while f.data[i] == ' ':
- i = i - 1
- output = f.data[:i+1].replace('__ROOT__', '')
- sys.stdout.write(output)
- if e.data and e.data[0] == '\n':
- e.data = e.data[1:]
- sys.stdout.write(e.data + '</programlisting>')
- delattr(self, 'e')
- self.afunclist = self.afunclist[:-1]
-
- def start_file(self, attrs):
- try:
- e = self.e
- except AttributeError:
- self.error("<file> tag outside of <scons_example>")
- t = [t for t in attrs if t[0] == 'name']
- if not t:
- self.error("no <file> name attribute found")
- try:
- e.prefix
- except AttributeError:
- e.prefix = e.data
- e.data = ""
- f = File(t[0][1])
- f.printme = None
- for name, value in attrs:
- setattr(f, name, value)
- e.files.append(f)
- self.afunclist.append(f.afunc)
-
- def end_file(self):
- self.e.data = ""
- self.afunclist = self.afunclist[:-1]
-
- def start_directory(self, attrs):
- try:
- e = self.e
- except AttributeError:
- self.error("<directory> tag outside of <scons_example>")
- t = [t for t in attrs if t[0] == 'name']
- if not t:
- self.error("no <directory> name attribute found")
- try:
- e.prefix
- except AttributeError:
- e.prefix = e.data
- e.data = ""
- d = Directory(t[0][1])
- for name, value in attrs:
- setattr(d, name, value)
- e.dirs.append(d)
- self.afunclist.append(d.afunc)
-
- def end_directory(self):
- self.e.data = ""
- self.afunclist = self.afunclist[:-1]
-
- def start_scons_example_file(self, 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]
- try:
- e = self.examples[exname]
- except KeyError:
- self.error("unknown example name '%s'" % exname)
- 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 = [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]
-
- def end_scons_example_file(self):
- f = self.f
- sys.stdout.write('<programlisting>')
- i = len(f.data) - 1
- while f.data[i] == ' ':
- i = i - 1
- sys.stdout.write(f.data[:i+1] + '</programlisting>')
- delattr(self, 'f')
-
- def start_scons_output(self, 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]
- try:
- e = self.examples[exname]
- except KeyError:
- self.error("unknown example name '%s'" % exname)
- # Default values for an example.
- o = Output()
- o.os = 'posix'
- o.e = e
- # Locally-set.
- for name, value in attrs:
- setattr(o, name, value)
- self.o = o
- self.afunclist.append(o.afunc)
-
- def end_scons_output(self):
- o = self.o
- e = o.e
- t = TestCmd.TestCmd(workdir='', combine=1)
- t.subdir('ROOT', 'WORK')
- for d in e.dirs:
- dir = t.workpath('WORK', d.name)
- if not os.path.exists(dir):
- os.makedirs(dir)
- for f in e.files:
- i = 0
- while f.data[i] == '\n':
- i = i + 1
- lines = f.data[i:].split('\n')
- i = 0
- while lines[0][i] == ' ':
- i = i + 1
- 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 = '\n'.join(lines)
- content = content.replace('__ROOT__',
- t.workpath('ROOT'))
- t.write(t.workpath('WORK', f.name), content)
- i = len(o.prefix)
- while o.prefix[i-1] != '\n':
- i = i - 1
- sys.stdout.write('<literallayout>' + o.prefix[:i])
- p = o.prefix[i:]
- for c in o.commandlist:
- sys.stdout.write(p + Prompt[o.os])
- d = c.data.replace('__ROOT__', '')
- sys.stdout.write('<userinput>' + d + '</userinput>\n')
- 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 - ' + ' '.join(args),
- chdir = t.workpath('WORK'),
- stdin = Stdin % o.os)
- out = t.stdout().replace(t.workpath('ROOT'), '')
- if out:
- lines = out.split('\n')
- if lines:
- while lines[-1] == '':
- lines = lines[:-1]
- for l in lines:
- sys.stdout.write(p + l + '\n')
- #err = t.stderr()
- #if err:
- # sys.stderr.write(err)
- if o.data[0] == '\n':
- o.data = o.data[1:]
- sys.stdout.write(o.data + '</literallayout>')
- delattr(self, 'o')
- self.afunclist = self.afunclist[:-1]
-
- def start_command(self, attrs):
- try:
- o = self.o
- except AttributeError:
- self.error("<command> tag outside of <scons_output>")
- try:
- o.prefix
- except AttributeError:
- o.prefix = o.data
- o.data = ""
- c = Command()
- o.commandlist.append(c)
- self.afunclist.append(c.afunc)
-
- def end_command(self):
- self.o.data = ""
- self.afunclist = self.afunclist[:-1]
-
- def start_sconstruct(self, attrs):
- sys.stdout.write('<programlisting>')
-
- def end_sconstruct(self):
- sys.stdout.write('</programlisting>')
-
-try:
- file = sys.argv[1]
-except IndexError:
- file = '-'
-
-if file == '-':
- f = sys.stdin
-else:
- try:
- f = open(file, 'r')
- except IOError, msg:
- print file, ":", msg
- sys.exit(1)
-
-data = f.read()
-if f is not sys.stdin:
- f.close()
-
-x = MySGML()
-for c in data:
- x.feed(c)
-x.close()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/bin/scp-sourceforge b/bin/scp-sourceforge
new file mode 100755
index 0000000..ad761d1
--- /dev/null
+++ b/bin/scp-sourceforge
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -x
+set -e
+
+if [ -z "$1" ]; then
+ echo usage: $0 SourceForgeUserName
+ exit
+fi
+
+SF_USER=$1
+
+rm -rf sf
+for p in scons scons-src scons-local
+do
+ mkdir -p sf/$p/$VERSION
+ cp -p src/Announce.txt \
+ build/scons/CHANGES.txt \
+ build/scons/RELEASE.txt \
+ sf/$p/$VERSION
+done
+
+cp -p build/dist/scons-$VERSION-1.noarch.rpm \
+ build/dist/scons-$VERSION-1.src.rpm \
+ build/dist/scons-$VERSION.tar.gz \
+ build/dist/scons-$VERSION.win32.exe \
+ build/dist/scons-$VERSION.zip \
+ sf/scons/$VERSION
+cp -p build/dist/scons-local-$VERSION.tar.gz \
+ build/dist/scons-local-$VERSION.zip \
+ sf/scons-src/$VERSION
+cp -p build/dist/scons-src-$VERSION.tar.gz \
+ build/dist/scons-src-$VERSION.zip \
+ sf/scons-local/$VERSION
+
+# Transmit them in this order, since the most-recent is displayed at the top
+scp -r sf/scons-local/ sf/scons-src/ sf/scons/ \
+ $SF_USER,scons@frs.sourceforge.net:/home/pfs/project/s/sc/scons
+rm -rf sf
diff --git a/bin/update-release-info.py b/bin/update-release-info.py
index 7e11c4b..1c84466 100644
--- a/bin/update-release-info.py
+++ b/bin/update-release-info.py
@@ -36,7 +36,7 @@ In 'post' mode, files are prepared for the next release cycle:
src/Announce.txt.
"""
#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -57,7 +57,7 @@ In 'post' mode, files are prepared for the next release cycle:
# 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 5134 2010/08/16 23:02:40 bdeegan"
+__revision__ = "bin/update-release-info.py 5357 2011/09/09 21:31:03 bdeegan"
import os
import sys
@@ -114,12 +114,18 @@ if version_tuple[3] != 'final':
else:
yyyy,mm,dd,_,_,_ = release_date
version_tuple = version_tuple[:4] + ((yyyy*100 + mm)*100 + dd,)
- version_string = '.'.join(map(str, version_tuple))
+
+import pdb
+pdb.set_trace()
+
+if mode == 'final' or mode == 'release':
+ version_string = '.'.join(map(str, version_tuple[0:3]))
else:
- # Final release doesn't have type or builddate in version string
- version_string = '.'.join(map(str, version_tuple[:3]))
+ 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']:
@@ -188,7 +194,9 @@ class UpdateFile(object):
'''
XXX
'''
+ if DEBUG: print "content before:%s"%self.content
self.content = self.match_rel.sub(replacement, self.content, count)
+ if DEBUG: print "content after :%s"%self.content
# Determine the release date and the pattern to match a date
# Mon, 05 Jun 2010 21:17:15 -0700
diff --git a/bin/xmlagenda.py b/bin/xmlagenda.py
index 7937331..b3cd520 100755
--- a/bin/xmlagenda.py
+++ b/bin/xmlagenda.py
@@ -1,11 +1,15 @@
#!/usr/bin/env python
-# Download the issues from Issuzilla as XML; this creates a file named
-# 'issues.xml'. Run this script to translate 'issues.xml' into a CSV
-# file named 'editlist.csv'. Upload the CSV into a Google spreadsheet.
+# Query the scons.tigris.org database for the issues of interest.
+# The typical triage query is found on http://www.scons.org/wiki/BugParty
-# In the spreadsheet, select the last column and pick "delete-->column" (it
-# was added by the upload to allow for expansion and we don't need it).
+# Download the issues from Issuezilla as XML; this creates a file
+# named 'issues.xml'. Run this script in the dir containing
+# issues.xml (or pass full path as arg to this script) to translate
+# 'issues.xml' into a CSV file named 'editlist.csv'. Upload the CSV
+# into a Google spreadsheet.
+
+# In the spreadsheet:
# Select all the columns and pick "align-->top"
# Select the ID and votes columns and pick "align-->right"
# Select the priority column and pick "align-->center"
@@ -17,7 +21,7 @@
# The team members
# FIXME: These names really should be external to this script
-team = sorted('Steven Gary Greg Ken Jim David Bill Sergey Jason'.split())
+team = sorted('Steven Gary Greg Ken Jim Bill Jason Dirk Anatoly'.split())
# The elements to be picked out of the issue
PickList = [
@@ -85,6 +89,8 @@ for issue in issues:
writer.writerow(['','','','','','',''])
for member in team: writer.writerow(['','',member,'','','',''])
+print "Exported %d issues to editlist.csv. Ready to upload to Google."%len(issues)
+
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil