[or-cvs] r17728: {} Add a script to post-process doxygen output into a sensible (tor/trunk/contrib)

nickm at seul.org nickm at seul.org
Mon Dec 22 14:56:20 UTC 2008


Author: nickm
Date: 2008-12-22 09:56:19 -0500 (Mon, 22 Dec 2008)
New Revision: 17728

Added:
   tor/trunk/contrib/redox.py
Log:
Add a script to post-process doxygen output into a sensible form and add DOCDOC comments to our source files.

Added: tor/trunk/contrib/redox.py
===================================================================
--- tor/trunk/contrib/redox.py	                        (rev 0)
+++ tor/trunk/contrib/redox.py	2008-12-22 14:56:19 UTC (rev 17728)
@@ -0,0 +1,168 @@
+#!/usr/bin/python
+#
+#  Copyright (c) 2008 The Tor Project, Inc.
+#  See LICENSE for licensing information.
+#
+# Hi!
+# I'm redox.py, the Tor redocumentation tool!
+# I am a horrible hack!
+# I read the output of doxygen from stderr, and add missing DOCDOC comments
+#   to tell you where documentation should go!
+# To use me, edit the stuff below...
+#  ...and run 'make doxygen 2>doxygen.stderr' ...
+#  ...and run ./contrib/redox.py < doxygen.stderr !
+# I'll make a bunch of new files by adding missing DOCDOC comments to your
+#    source.  Those files will have names like ./src/common/util.c.newdoc.
+# You will want to look over the changes by hand before checking them in.
+
+SKIP_FILES = [ "OpenBSD_malloc_Linux.c",
+               "eventdns.c",
+               "eventdns.h",
+               "strlcat.c",
+               "strlcpy.c",
+               "aes.c",
+               "aes.h" ]
+
+SKIP_NAME_PATTERNS = [ r'^.*_c_id$' ]
+
+ADD_DOCDOCS_TO_TYPES = [ 'function', 'type', 'typedef' ]
+# ADD_DOCDOCS_TO_TYPES += [ 'variable', 'define' ]
+
+# ====================
+# The rest of this should not need hacking.
+
+import re
+import sys
+
+KINDS = [ "type", "field", "typedef", "define", "function", "variable" ]
+
+NODOC_LINE_RE = re.compile(r'^([^:]+):(\d+): (\w+): (.*) is not documented\.$')
+
+THING_RE = re.compile(r'^Member ([a-zA-Z0-9_]+).*\((typedef|define|function|variable)\) of (file|class) ')
+
+SKIP_NAMES = [re.compile(s) for s in SKIP_NAME_PATTERNS]
+
+def parsething(thing):
+    if thing.startswith("Compound "):
+        tp, name = "type", thing.split()[1]
+    else:
+        m = THING_RE.match(thing)
+        if not m:
+            print thing
+            return None, None
+        else:
+            name, tp, parent = m.groups()
+            if parent == 'class':
+                if tp == 'variable' or tp == 'function':
+                    tp = 'field'
+
+    return name, tp
+
+def read():
+    errs = {}
+    for line in sys.stdin:
+        m = NODOC_LINE_RE.match(line)
+        if m:
+            file, line, tp, thing = m.groups()
+            assert tp == 'Warning'
+            name, kind = parsething(thing)
+            errs.setdefault(file, []).append((int(line), name, kind))
+
+    return errs
+
+def findline(lines, lineno, ident):
+    for lineno in xrange(lineno, 0, -1):
+        if ident in lines[lineno]:
+            return lineno
+
+    return None
+
+FUNC_PAT = re.compile(r"^[A-Za-z0-9_]+\(")
+
+def hascomment(lines, lineno, kind):
+    if "*/" in lines[lineno-1]:
+        return True
+    if kind == 'function' and FUNC_PAT.match(lines[lineno]):
+        if "*/" in lines[lineno-2]:
+            return True
+    return False
+
+def hasdocdoc(lines, lineno, kind):
+    if "DOCDOC" in lines[lineno] or "DOCDOC" in lines[lineno-1]:
+        return True
+    if kind == 'function' and FUNC_PAT.match(lines[lineno]):
+        if "DOCDOC" in lines[lineno-2]:
+            return True
+    return False
+
+def checkf(fn, errs, comments):
+
+    for skip in SKIP_FILES:
+        if fn.endswith(skip):
+            print "Skipping",fn
+            return
+
+    lines = [ None ]
+    try:
+        lines.extend( open(fn, 'r').readlines() )
+    except IOError:
+        return
+
+    for line, name, kind in errs:
+        if any(pat.match(name) for pat in SKIP_NAMES):
+            continue
+
+        if kind not in ADD_DOCDOCS_TO_TYPES:
+            continue
+
+        ln = findline(lines, line, name)
+        if ln == None:
+            print "Couldn't find the definition of %s allegedly on %s of %s"%(
+                name, line, fn)
+        else:
+            if hasdocdoc(lines, line, kind):
+#                print "Has a DOCDOC"
+#                print fn, line, name, kind
+#                print "\t",lines[line-2],
+#                print "\t",lines[line-1],
+#                print "\t",lines[line],
+#                print "-------"
+                pass
+            else:
+                if kind == 'function' and FUNC_PAT.match(lines[ln]):
+                    ln = ln - 1
+
+                comments.setdefault(fn, []).append((ln, kind, name))
+
+def applyComments(fn, entries):
+    N = 0
+
+    lines = [ None ]
+    try:
+        lines.extend( open(fn, 'r').readlines() )
+    except IOError:
+        return
+
+    entries.sort()
+    entries.reverse()
+
+    for ln, kind, name in entries:
+
+        lines.insert(ln, "/* DOCDOC %s */\n"%name)
+        N += 1
+
+    outf = open(fn+".newdoc", 'w')
+    for line in lines[1:]:
+        outf.write(line)
+    outf.close()
+
+    print "Added %s DOCDOCs to %s" %(N, fn)
+
+e = read()
+comments = {}
+
+for fn, errs in e.iteritems():
+    checkf(fn, errs, comments)
+
+for fn, entries in comments.iteritems():
+    applyComments(fn, entries)



More information about the tor-commits mailing list