Loading contrib/redox.py 100644 → 100755 +50 −9 Original line number Diff line number Diff line Loading @@ -14,7 +14,24 @@ # 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. # # So, here's your workflow: # # 0. Make sure you're running a bourne shell for the redirects below. # 1. make doxygen 1>doxygen.stdout 2>doxygen.stderr. # 2. grep Warning doxygen.stderr | grep -v 'is not documented' | less # [This will tell you about all the bogus doxygen output you have] # 3. python ./contrib/redox.py <doxygen.stderr # [This will make lots of .newdoc files with DOCDOC comments for # whatever was missing documentation.] # 4. Look over those .newdoc files, and see which docdoc comments you # want to merge into the main file. If it's all good, just run # "mv fname.c.newdoc fname.c". Otherwise, you'll need to merge # the parts you like by hand. # Which files should we ignore warning from? Mostly, these are external # files that we've snarfed in from somebody else, whose C we do no intend # to document for them. SKIP_FILES = [ "OpenBSD_malloc_Linux.c", "eventdns.c", "eventdns.h", Loading @@ -23,8 +40,11 @@ SKIP_FILES = [ "OpenBSD_malloc_Linux.c", "aes.c", "aes.h" ] # What names of things never need javadoc SKIP_NAME_PATTERNS = [ r'^.*_c_id$' ] # Which types of things should get DOCDOC comments added if they are # missing documentation? Recognized types are in KINDS below. ADD_DOCDOCS_TO_TYPES = [ 'function', 'type', 'typedef' ] # ADD_DOCDOCS_TO_TYPES += [ 'variable', 'define' ] Loading @@ -43,6 +63,9 @@ THING_RE = re.compile(r'^Member ([a-zA-Z0-9_]+).*\((typedef|define|function|vari SKIP_NAMES = [re.compile(s) for s in SKIP_NAME_PATTERNS] def parsething(thing): """I figure out what 'foobar baz in quux quum is not documented' means, and return: the name of the foobar, and the kind of the foobar. """ if thing.startswith("Compound "): tp, name = "type", thing.split()[1] else: Loading @@ -59,6 +82,10 @@ def parsething(thing): return name, tp def read(): """I snarf doxygen stderr from stdin, and parse all the "foo has no documentation messages. I return a map from filename to lists of tuples of (alleged line number, name of thing, kind of thing) """ errs = {} for line in sys.stdin: m = NODOC_LINE_RE.match(line) Loading @@ -71,6 +98,9 @@ def read(): return errs def findline(lines, lineno, ident): """Given a list of all the lines in the file (adjusted so 1-indexing works), a line number that ident is alledgedly on, and ident, I figure out the line where ident was really declared.""" for lineno in xrange(lineno, 0, -1): if ident in lines[lineno]: return lineno Loading @@ -80,6 +110,8 @@ def findline(lines, lineno, ident): FUNC_PAT = re.compile(r"^[A-Za-z0-9_]+\(") def hascomment(lines, lineno, kind): """I return true if it looks like there's already a good comment about the thing on lineno of lines of type kind. """ if "*/" in lines[lineno-1]: return True if kind == 'function' and FUNC_PAT.match(lines[lineno]): Loading @@ -88,6 +120,8 @@ def hascomment(lines, lineno, kind): return False def hasdocdoc(lines, lineno, kind): """I return true if it looks like there's already a docdoc comment about the thing on lineno of lines of type kind.""" if "DOCDOC" in lines[lineno] or "DOCDOC" in lines[lineno-1]: return True if kind == 'function' and FUNC_PAT.match(lines[lineno]): Loading @@ -95,13 +129,17 @@ def hasdocdoc(lines, lineno, kind): return True return False def checkf(fn, errs, comments): def checkf(fn, errs): """I go through the output of read() for a single file, and build a list of tuples of things that want DOCDOC comments. Each tuple has: the line number where the comment goes; the kind of thing; its name. """ for skip in SKIP_FILES: if fn.endswith(skip): print "Skipping",fn return comments = [] lines = [ None ] try: lines.extend( open(fn, 'r').readlines() ) Loading Loading @@ -132,9 +170,11 @@ def checkf(fn, errs, comments): if kind == 'function' and FUNC_PAT.match(lines[ln]): ln = ln - 1 comments.setdefault(fn, []).append((ln, kind, name)) comments.append((ln, kind, name)) def applyComments(fn, entries): """I apply lots of comments to the file in fn, making a new .newdoc file. """ N = 0 lines = [ None ] Loading @@ -143,6 +183,9 @@ def applyComments(fn, entries): except IOError: return # Process the comments in reverse order by line number, so that # the line numbers for the ones we haven't added yet remain valid # until we add them. Standard trick. entries.sort() entries.reverse() Loading @@ -159,10 +202,8 @@ def applyComments(fn, entries): 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) comments = checkf(fn, errs) if comments: applyComments(fn, comments) Loading
contrib/redox.py 100644 → 100755 +50 −9 Original line number Diff line number Diff line Loading @@ -14,7 +14,24 @@ # 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. # # So, here's your workflow: # # 0. Make sure you're running a bourne shell for the redirects below. # 1. make doxygen 1>doxygen.stdout 2>doxygen.stderr. # 2. grep Warning doxygen.stderr | grep -v 'is not documented' | less # [This will tell you about all the bogus doxygen output you have] # 3. python ./contrib/redox.py <doxygen.stderr # [This will make lots of .newdoc files with DOCDOC comments for # whatever was missing documentation.] # 4. Look over those .newdoc files, and see which docdoc comments you # want to merge into the main file. If it's all good, just run # "mv fname.c.newdoc fname.c". Otherwise, you'll need to merge # the parts you like by hand. # Which files should we ignore warning from? Mostly, these are external # files that we've snarfed in from somebody else, whose C we do no intend # to document for them. SKIP_FILES = [ "OpenBSD_malloc_Linux.c", "eventdns.c", "eventdns.h", Loading @@ -23,8 +40,11 @@ SKIP_FILES = [ "OpenBSD_malloc_Linux.c", "aes.c", "aes.h" ] # What names of things never need javadoc SKIP_NAME_PATTERNS = [ r'^.*_c_id$' ] # Which types of things should get DOCDOC comments added if they are # missing documentation? Recognized types are in KINDS below. ADD_DOCDOCS_TO_TYPES = [ 'function', 'type', 'typedef' ] # ADD_DOCDOCS_TO_TYPES += [ 'variable', 'define' ] Loading @@ -43,6 +63,9 @@ THING_RE = re.compile(r'^Member ([a-zA-Z0-9_]+).*\((typedef|define|function|vari SKIP_NAMES = [re.compile(s) for s in SKIP_NAME_PATTERNS] def parsething(thing): """I figure out what 'foobar baz in quux quum is not documented' means, and return: the name of the foobar, and the kind of the foobar. """ if thing.startswith("Compound "): tp, name = "type", thing.split()[1] else: Loading @@ -59,6 +82,10 @@ def parsething(thing): return name, tp def read(): """I snarf doxygen stderr from stdin, and parse all the "foo has no documentation messages. I return a map from filename to lists of tuples of (alleged line number, name of thing, kind of thing) """ errs = {} for line in sys.stdin: m = NODOC_LINE_RE.match(line) Loading @@ -71,6 +98,9 @@ def read(): return errs def findline(lines, lineno, ident): """Given a list of all the lines in the file (adjusted so 1-indexing works), a line number that ident is alledgedly on, and ident, I figure out the line where ident was really declared.""" for lineno in xrange(lineno, 0, -1): if ident in lines[lineno]: return lineno Loading @@ -80,6 +110,8 @@ def findline(lines, lineno, ident): FUNC_PAT = re.compile(r"^[A-Za-z0-9_]+\(") def hascomment(lines, lineno, kind): """I return true if it looks like there's already a good comment about the thing on lineno of lines of type kind. """ if "*/" in lines[lineno-1]: return True if kind == 'function' and FUNC_PAT.match(lines[lineno]): Loading @@ -88,6 +120,8 @@ def hascomment(lines, lineno, kind): return False def hasdocdoc(lines, lineno, kind): """I return true if it looks like there's already a docdoc comment about the thing on lineno of lines of type kind.""" if "DOCDOC" in lines[lineno] or "DOCDOC" in lines[lineno-1]: return True if kind == 'function' and FUNC_PAT.match(lines[lineno]): Loading @@ -95,13 +129,17 @@ def hasdocdoc(lines, lineno, kind): return True return False def checkf(fn, errs, comments): def checkf(fn, errs): """I go through the output of read() for a single file, and build a list of tuples of things that want DOCDOC comments. Each tuple has: the line number where the comment goes; the kind of thing; its name. """ for skip in SKIP_FILES: if fn.endswith(skip): print "Skipping",fn return comments = [] lines = [ None ] try: lines.extend( open(fn, 'r').readlines() ) Loading Loading @@ -132,9 +170,11 @@ def checkf(fn, errs, comments): if kind == 'function' and FUNC_PAT.match(lines[ln]): ln = ln - 1 comments.setdefault(fn, []).append((ln, kind, name)) comments.append((ln, kind, name)) def applyComments(fn, entries): """I apply lots of comments to the file in fn, making a new .newdoc file. """ N = 0 lines = [ None ] Loading @@ -143,6 +183,9 @@ def applyComments(fn, entries): except IOError: return # Process the comments in reverse order by line number, so that # the line numbers for the ones we haven't added yet remain valid # until we add them. Standard trick. entries.sort() entries.reverse() Loading @@ -159,10 +202,8 @@ def applyComments(fn, entries): 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) comments = checkf(fn, errs) if comments: applyComments(fn, comments)