diff options
Diffstat (limited to 'bin')
-rw-r--r-- | bin/calibrate.py | 6 | ||||
-rw-r--r-- | bin/docdiff | 16 | ||||
-rw-r--r-- | bin/docrun | 16 | ||||
-rw-r--r-- | bin/docupdate | 16 | ||||
-rw-r--r-- | bin/import-test.py | 4 | ||||
-rw-r--r-- | bin/linecount.py | 4 | ||||
-rw-r--r-- | bin/restore.sh | 28 | ||||
-rw-r--r-- | bin/scons-doc.py | 95 | ||||
-rw-r--r-- | bin/scons-proc.py | 174 | ||||
-rw-r--r-- | bin/sconsexamples.py | 505 | ||||
-rwxr-xr-x | bin/scp-sourceforge | 38 | ||||
-rw-r--r-- | bin/update-release-info.py | 18 | ||||
-rwxr-xr-x | bin/xmlagenda.py | 18 |
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('⌖', 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 < and > entities to literal < and > characters. body = body.replace('<', '<') body = body.replace('>', '>') - 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 |