cannam@140
|
1 import os
|
cannam@140
|
2 import os.path
|
cannam@140
|
3 import string
|
cannam@140
|
4
|
cannam@140
|
5 paRootDirectory = '../../'
|
cannam@140
|
6 paHtmlDocDirectory = os.path.join( paRootDirectory, "doc", "html" )
|
cannam@140
|
7
|
cannam@140
|
8 ## Script to check documentation status
|
cannam@140
|
9 ## this script assumes that html doxygen documentation has been generated
|
cannam@140
|
10 ##
|
cannam@140
|
11 ## it then walks the entire portaudio source tree and check that
|
cannam@140
|
12 ## - every source file (.c,.h,.cpp) has a doxygen comment block containing
|
cannam@140
|
13 ## - a @file directive
|
cannam@140
|
14 ## - a @brief directive
|
cannam@140
|
15 ## - a @ingroup directive
|
cannam@140
|
16 ## - it also checks that a corresponding html documentation file has been generated.
|
cannam@140
|
17 ##
|
cannam@140
|
18 ## This can be used as a first-level check to make sure the documentation is in order.
|
cannam@140
|
19 ##
|
cannam@140
|
20 ## The idea is to get a list of which files are missing doxygen documentation.
|
cannam@140
|
21 ##
|
cannam@140
|
22 ## How to run:
|
cannam@140
|
23 ## $ cd doc/utils
|
cannam@140
|
24 ## $ python checkfiledocs.py
|
cannam@140
|
25
|
cannam@140
|
26 def oneOf_a_in_b(a, b):
|
cannam@140
|
27 for x in a:
|
cannam@140
|
28 if x in b:
|
cannam@140
|
29 return True
|
cannam@140
|
30 return False
|
cannam@140
|
31
|
cannam@140
|
32 # recurse from top and return a list of all with the given
|
cannam@140
|
33 # extensions. ignore .svn directories. return absolute paths
|
cannam@140
|
34 def recursiveFindFiles( top, extensions, dirBlacklist, includePaths ):
|
cannam@140
|
35 result = []
|
cannam@140
|
36 for (dirpath, dirnames, filenames) in os.walk(top):
|
cannam@140
|
37 if not oneOf_a_in_b(dirBlacklist, dirpath):
|
cannam@140
|
38 for f in filenames:
|
cannam@140
|
39 if os.path.splitext(f)[1] in extensions:
|
cannam@140
|
40 if includePaths:
|
cannam@140
|
41 result.append( os.path.abspath( os.path.join( dirpath, f ) ) )
|
cannam@140
|
42 else:
|
cannam@140
|
43 result.append( f )
|
cannam@140
|
44 return result
|
cannam@140
|
45
|
cannam@140
|
46 # generate the html file name that doxygen would use for
|
cannam@140
|
47 # a particular source file. this is a brittle conversion
|
cannam@140
|
48 # which i worked out by trial and error
|
cannam@140
|
49 def doxygenHtmlDocFileName( sourceFile ):
|
cannam@140
|
50 return sourceFile.replace( '_', '__' ).replace( '.', '_8' ) + '.html'
|
cannam@140
|
51
|
cannam@140
|
52
|
cannam@140
|
53 sourceFiles = recursiveFindFiles( os.path.join(paRootDirectory,'src'), [ '.c', '.h', '.cpp' ], ['.svn', 'mingw-include'], True );
|
cannam@140
|
54 sourceFiles += recursiveFindFiles( os.path.join(paRootDirectory,'include'), [ '.c', '.h', '.cpp' ], ['.svn'], True );
|
cannam@140
|
55 docFiles = recursiveFindFiles( paHtmlDocDirectory, [ '.html' ], ['.svn'], False );
|
cannam@140
|
56
|
cannam@140
|
57
|
cannam@140
|
58
|
cannam@140
|
59 currentFile = ""
|
cannam@140
|
60
|
cannam@140
|
61 def printError( f, message ):
|
cannam@140
|
62 global currentFile
|
cannam@140
|
63 if f != currentFile:
|
cannam@140
|
64 currentFile = f
|
cannam@140
|
65 print f, ":"
|
cannam@140
|
66 print "\t!", message
|
cannam@140
|
67
|
cannam@140
|
68
|
cannam@140
|
69 for f in sourceFiles:
|
cannam@140
|
70 if not doxygenHtmlDocFileName( os.path.basename(f) ) in docFiles:
|
cannam@140
|
71 printError( f, "no doxygen generated doc page" )
|
cannam@140
|
72
|
cannam@140
|
73 s = file( f, 'rt' ).read()
|
cannam@140
|
74
|
cannam@140
|
75 if not '/**' in s:
|
cannam@140
|
76 printError( f, "no doxygen /** block" )
|
cannam@140
|
77
|
cannam@140
|
78 if not '@file' in s:
|
cannam@140
|
79 printError( f, "no doxygen @file tag" )
|
cannam@140
|
80
|
cannam@140
|
81 if not '@brief' in s:
|
cannam@140
|
82 printError( f, "no doxygen @brief tag" )
|
cannam@140
|
83
|
cannam@140
|
84 if not '@ingroup' in s:
|
cannam@140
|
85 printError( f, "no doxygen @ingroup tag" )
|
cannam@140
|
86
|
cannam@140
|
87
|