cannam@140: import os cannam@140: import os.path cannam@140: import string cannam@140: cannam@140: paRootDirectory = '../../' cannam@140: paHtmlDocDirectory = os.path.join( paRootDirectory, "doc", "html" ) cannam@140: cannam@140: ## Script to check documentation status cannam@140: ## this script assumes that html doxygen documentation has been generated cannam@140: ## cannam@140: ## it then walks the entire portaudio source tree and check that cannam@140: ## - every source file (.c,.h,.cpp) has a doxygen comment block containing cannam@140: ## - a @file directive cannam@140: ## - a @brief directive cannam@140: ## - a @ingroup directive cannam@140: ## - it also checks that a corresponding html documentation file has been generated. cannam@140: ## cannam@140: ## This can be used as a first-level check to make sure the documentation is in order. cannam@140: ## cannam@140: ## The idea is to get a list of which files are missing doxygen documentation. cannam@140: ## cannam@140: ## How to run: cannam@140: ## $ cd doc/utils cannam@140: ## $ python checkfiledocs.py cannam@140: cannam@140: def oneOf_a_in_b(a, b): cannam@140: for x in a: cannam@140: if x in b: cannam@140: return True cannam@140: return False cannam@140: cannam@140: # recurse from top and return a list of all with the given cannam@140: # extensions. ignore .svn directories. return absolute paths cannam@140: def recursiveFindFiles( top, extensions, dirBlacklist, includePaths ): cannam@140: result = [] cannam@140: for (dirpath, dirnames, filenames) in os.walk(top): cannam@140: if not oneOf_a_in_b(dirBlacklist, dirpath): cannam@140: for f in filenames: cannam@140: if os.path.splitext(f)[1] in extensions: cannam@140: if includePaths: cannam@140: result.append( os.path.abspath( os.path.join( dirpath, f ) ) ) cannam@140: else: cannam@140: result.append( f ) cannam@140: return result cannam@140: cannam@140: # generate the html file name that doxygen would use for cannam@140: # a particular source file. this is a brittle conversion cannam@140: # which i worked out by trial and error cannam@140: def doxygenHtmlDocFileName( sourceFile ): cannam@140: return sourceFile.replace( '_', '__' ).replace( '.', '_8' ) + '.html' cannam@140: cannam@140: cannam@140: sourceFiles = recursiveFindFiles( os.path.join(paRootDirectory,'src'), [ '.c', '.h', '.cpp' ], ['.svn', 'mingw-include'], True ); cannam@140: sourceFiles += recursiveFindFiles( os.path.join(paRootDirectory,'include'), [ '.c', '.h', '.cpp' ], ['.svn'], True ); cannam@140: docFiles = recursiveFindFiles( paHtmlDocDirectory, [ '.html' ], ['.svn'], False ); cannam@140: cannam@140: cannam@140: cannam@140: currentFile = "" cannam@140: cannam@140: def printError( f, message ): cannam@140: global currentFile cannam@140: if f != currentFile: cannam@140: currentFile = f cannam@140: print f, ":" cannam@140: print "\t!", message cannam@140: cannam@140: cannam@140: for f in sourceFiles: cannam@140: if not doxygenHtmlDocFileName( os.path.basename(f) ) in docFiles: cannam@140: printError( f, "no doxygen generated doc page" ) cannam@140: cannam@140: s = file( f, 'rt' ).read() cannam@140: cannam@140: if not '/**' in s: cannam@140: printError( f, "no doxygen /** block" ) cannam@140: cannam@140: if not '@file' in s: cannam@140: printError( f, "no doxygen @file tag" ) cannam@140: cannam@140: if not '@brief' in s: cannam@140: printError( f, "no doxygen @brief tag" ) cannam@140: cannam@140: if not '@ingroup' in s: cannam@140: printError( f, "no doxygen @ingroup tag" ) cannam@140: cannam@140: