Add support for documenting functions (with arbitrary calling signatures)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 23 Feb 2010 22:10:53 +0000 (22:10 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 23 Feb 2010 22:10:53 +0000 (22:10 +0000)
in our home-brew DocBook-based .xml files.

git-svn-id: http://scons.tigris.org/svn/scons/trunk@4686 fdb21ef1-2011-0410-befe-b5e4ea1792b1

bin/SConsDoc.py
bin/scons-proc.py

index d3a043b7ca63a435364a371fd486f41d80ed42b9..72d8c1cfb7f48fd797fa67ded573710662868200 100644 (file)
@@ -5,8 +5,8 @@
 
 __doc__ = """
 This module parses home-brew XML files that document various things
-in SCons.  Right now, it handles Builders, construction variables,
-and Tools, but we expect it to get extended in the future.
+in SCons.  Right now, it handles Builders, functions, construction
+variables, and Tools, but we expect it to get extended in the future.
 
 In general, you can use any DocBook tag in the input, and this module
 just adds processing various home-brew tags to try to make life a
@@ -14,14 +14,14 @@ little easier.
 
 Builder example:
 
-    <builder name="VARIABLE">
+    <builder name="BUILDER">
     <summary>
-    This is the summary description of an SCons Tool.
+    This is the summary description of an SCons Builder.
     It will get placed in the man page,
     and in the appropriate User's Guide appendix.
     The name of any builder may be interpolated
     anywhere in the document by specifying the
-    &b-VARIABLE;
+    &b-BUILDER;
     element.  It need not be on a line by itself.
 
     Unlike normal XML, blank lines are significant in these
@@ -35,6 +35,32 @@ Builder example:
     </summary>
     </builder>
 
+Function example:
+
+    <scons_function name="FUNCTION">
+    <arguments>
+    (arg1, arg2, key=value)
+    </arguments>
+    <summary>
+    This is the summary description of an SCons function.
+    It will get placed in the man page,
+    and in the appropriate User's Guide appendix.
+    The name of any builder may be interpolated
+    anywhere in the document by specifying the
+    &f-FUNCTION;
+    element.  It need not be on a line by itself.
+
+    Unlike normal XML, blank lines are significant in these
+    descriptions and serve to separate paragraphs.
+    They'll get replaced in DocBook output with appropriate tags
+    to indicate a new paragraph.
+
+    <example>
+    print "this is example code, it will be offset and indented"
+    </example>
+    </summary>
+    </scons_function>
+
 Construction variable example:
 
     <cvar name="VARIABLE">
@@ -60,14 +86,14 @@ Construction variable example:
 
 Tool example:
 
-    <tool name="VARIABLE">
+    <tool name="TOOL">
     <summary>
     This is the summary description of an SCons Tool.
     It will get placed in the man page,
     and in the appropriate User's Guide appendix.
     The name of any tool may be interpolated
     anywhere in the document by specifying the
-    &t-VARIABLE;
+    &t-TOOL;
     element.  It need not be on a line by itself.
 
     Unlike normal XML, blank lines are significant in these
@@ -82,8 +108,9 @@ Tool example:
     </tool>
 """
 
-import os.path
 import imp
+import os.path
+import re
 import sys
 import xml.sax.handler
 
@@ -106,6 +133,9 @@ class Item:
 class Builder(Item):
     pass
 
+class Function(Item):
+    pass
+
 class Tool(Item):
     def __init__(self, name):
         Item.__init__(self, name)
@@ -126,6 +156,22 @@ class Chunk:
     def append(self, data):
         self.body.append(data)
 
+class Arguments:
+    def __init__(self, body=None):
+        if not body:
+            body = []
+        self.body = body
+    def __str__(self):
+        s = ''.join(self.body).strip()
+        result = []
+        for m in re.findall('([a-zA-Z_]+|[^a-zA-Z_]+)', s):
+            if ' ' in m:
+                m = '"%s"' % m
+            result.append(m)
+        return ' '.join(result)
+    def append(self, data):
+        self.body.append(data)
+
 class Summary:
     def __init__(self):
         self.body = []
@@ -181,6 +227,7 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
         self.collect = []
         self.current_object = []
         self.builders = {}
+        self.functions = {}
         self.tools = {}
         self.cvars = {}
 
@@ -244,6 +291,17 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
     def end_builder(self):
         self.end_xxx()
 
+    def start_scons_function(self, attrs):
+        name = attrs.get('name')
+        try:
+            function = self.functions[name]
+        except KeyError:
+            function = Function(name)
+            self.functions[name] = function
+        self.begin_xxx(function)
+    def end_scons_function(self):
+        self.end_xxx()
+
     def start_tool(self, attrs):
         name = attrs.get('name')
         try:
@@ -266,6 +324,14 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
     def end_cvar(self):
         self.end_xxx()
 
+    def start_arguments(self, attrs):
+        arguments = Arguments()
+        self.current_object.arguments = arguments
+        self.begin_xxx(arguments)
+        self.begin_collecting(arguments)
+    def end_arguments(self):
+        self.end_xxx()
+
     def start_summary(self, attrs):
         summary = Summary()
         self.current_object.summary = summary
index 9194ffda182559a84a23f26d885e6fe5196065bf..fdbcd653ec29a0a9888fcf131df81b040cb4f306 100644 (file)
@@ -2,8 +2,8 @@
 #
 # Process a list of Python and/or XML files containing SCons documentation.
 #
-# This script creates formatted lists of the Builders, Tools or
-# construction variables documented in the specified XML files.
+# This script creates formatted lists of the Builders, functions, Tools
+# or construction variables documented in the specified XML files.
 #
 # Dependening on the options, the lists are output in either
 # DocBook-formatted generated XML files containing the summary text
@@ -24,9 +24,11 @@ base_sys_path = [os.getcwd() + '/build/test-tar-gz/lib/scons'] + sys.path
 
 helpstr = """\
 Usage: scons-proc.py [--man|--xml]
-                     [-b file(s)] [-t file(s)] [-v file(s)] [infile ...]
+                     [-b file(s)] [-f file(s)] [-t file(s)] [-v file(s)]
+                     [infile ...]
 Options:
   -b file(s)        dump builder information to the specified file(s)
+  -f file(s)        dump function information to the specified file(s)
   -t file(s)        dump tool information to the specified file(s)
   -v file(s)        dump variable information to the specified file(s)
   --man             print info in man page format, each -[btv] argument
@@ -36,11 +38,12 @@ Options:
 """
 
 opts, args = getopt.getopt(sys.argv[1:],
-                           "b:ht:v:",
+                           "b:f:ht:v:",
                            ['builders=', 'help',
                             'man', 'xml', 'tools=', 'variables='])
 
 buildersfiles = None
+functionsfiles = None
 output_type = '--xml'
 toolsfiles = None
 variablesfiles = None
@@ -48,6 +51,8 @@ variablesfiles = None
 for o, a in opts:
     if o in ['-b', '--builders']:
         buildersfiles = a
+    elif o in ['-f', '--functions']:
+        functionsfiles = a
     elif o in ['-h', '--help']:
         sys.stdout.write(helpstr)
         sys.exit(0)
@@ -194,8 +199,7 @@ class SCons_XML_to_man(SCons_XML):
         chunks = []
         for v in self.values:
             chunks.extend(v.mansep())
-            for n in v.initial_chunks():
-                chunks.append('.IP %s\n' % n)
+            chunks.extend(v.initial_chunks())
             chunks.extend(map(str, v.summary.body))
 
         body = ''.join(chunks)
@@ -212,7 +216,8 @@ class SCons_XML_to_man(SCons_XML):
         body = string.replace(body, '&source;', r'\fIsource\fP')
         body = re.sub('&b(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
         body = re.sub('&cv(-link)?-([^;]*);', r'$\2', body)
-        body = re.sub(r'<(command|envar|filename|literal|option)>([^<]*)</\1>',
+        body = re.sub('&f(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
+        body = re.sub(r'<(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)
@@ -259,7 +264,27 @@ class Builder(Proxy):
     def mansep(self):
         return ['\n', "'\\" + '"'*69 + '\n']
     def initial_chunks(self):
-        return self.termfunc()
+        return [ '.IP %s\n' % t for t in self.termfunc() ]
+
+class Function(Proxy):
+    description = 'function'
+    prefix = 'f-'
+    tag = 'function'
+    def idfunc(self):
+        return self.name
+    def termfunc(self):
+        return ['%s()' % self.name, 'env.%s()' % self.name]
+    def entityfunc(self):
+        return self.name
+    def mansep(self):
+        return ['\n', "'\\" + '"'*69 + '\n']
+    def initial_chunks(self):
+        try:
+            x = self.arguments
+        except AttributeError:
+            x = '()'
+        y = ['%s%s' % (self.name, x), 'env.%s%s' % (self.name, x)]
+        return [ '.TP\n.RI %s\n' % t for t in y ]
 
 class Tool(Proxy):
     description = 'tool'
@@ -274,7 +299,7 @@ class Tool(Proxy):
     def mansep(self):
         return ['\n']
     def initial_chunks(self):
-        return [self.name]
+        return ['.IP %s\n' % self.name]
 
 class Variable(Proxy):
     description = 'construction variable'
@@ -289,7 +314,7 @@ class Variable(Proxy):
     def mansep(self):
         return ['\n']
     def initial_chunks(self):
-        return [self.name]
+        return ['.IP %s\n' % self.name]
 
 if output_type == '--man':
     processor_class = SCons_XML_to_man
@@ -303,6 +328,10 @@ if buildersfiles:
     g = processor_class([ Builder(b) for b in sorted(h.builders.values()) ])
     g.write(buildersfiles)
 
+if functionsfiles:
+    g = processor_class([ Function(b) for b in sorted(h.functions.values()) ])
+    g.write(functionsfiles)
+
 if toolsfiles:
     g = processor_class([ Tool(t) for t in sorted(h.tools.values()) ])
     g.write(toolsfiles)