Commits

dirkbaechle  committed 2c5627b

- moved the functionality of the bin/doc* shell scripts to scons-doc.py
- bin/doc* and sconsexample.py are not used anymore and get deleted

  • Participants
  • Parent commits a856f1b

Comments (0)

Files changed (5)

File bin/docdiff

-#!/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

File bin/docrun

-#!/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

File bin/docupdate

-#!/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

File bin/scons-doc.py

 #                   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
 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'))
         delattr(self, 'f')
         self.afunclist = self.afunclist[:-1]
 
-def process(filename):
+def process(filename, fout=sys.stdout):
     if filename == '-':
         f = sys.stdin
     else:
         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()
         argv = sys.argv
 
     parser = optparse.OptionParser()
+    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')
+
     opts, args = parser.parse_args(argv[1:])
 
-    if not args:
-        args = ['-']
-
-    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())

File bin/sconsexamples.py

-#!/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: