|  | @@ -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",
 | 
	
	
		
			
				|  | @@ -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' ]
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -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:
 | 
	
	
		
			
				|  | @@ -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)
 | 
	
	
		
			
				|  | @@ -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
 | 
	
	
		
			
				|  | @@ -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]):
 | 
	
	
		
			
				|  | @@ -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]):
 | 
	
	
		
			
				|  | @@ -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() )
 | 
	
	
		
			
				|  | @@ -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 ]
 | 
	
	
		
			
				|  | @@ -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()
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -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)
 |