mirror of
https://github.com/opencv/opencv.git
synced 2024-11-28 13:10:12 +08:00
185 lines
7.0 KiB
Python
185 lines
7.0 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Usage: check_doc.py > log.txt
|
|
The script parses different opencv modules
|
|
(that are described by instances of class Comp below) and
|
|
checks for typical errors in headers and docs, for consistence and for completeness.
|
|
Due to its simplicity, it falsely reports some bugs, that should be
|
|
just ignored.
|
|
"""
|
|
|
|
import sys, os, re, glob
|
|
|
|
comps = []
|
|
|
|
class Comp:
|
|
def __init__(self,comp_name):
|
|
self.name = comp_name
|
|
|
|
cxcore = Comp('cxcore')
|
|
cxcore.header_path = '../cxcore/include'
|
|
cxcore.headers = ['cxcore.h','cxtypes.h']
|
|
cxcore.ext_macro = 'CVAPI'
|
|
cxcore.inline_macro = 'CV_INLINE'
|
|
cxcore.func_prefix = 'cv'
|
|
cxcore.doc_path = '../docs/ref'
|
|
cxcore.docs = ['opencvref_cxcore.htm']
|
|
comps.append(cxcore)
|
|
|
|
cv = Comp('cv')
|
|
cv.header_path = '../cv/include'
|
|
cv.headers = ['cv.h','cvtypes.h']
|
|
cv.ext_macro = 'CVAPI'
|
|
cv.inline_macro = 'CV_INLINE'
|
|
cv.func_prefix = 'cv'
|
|
cv.doc_path = '../docs/ref'
|
|
cv.docs = ['opencvref_cv.htm']
|
|
comps.append(cv)
|
|
|
|
|
|
highgui = Comp('highgui')
|
|
highgui.header_path = '../otherlibs/highgui'
|
|
highgui.headers = ['highgui.h']
|
|
highgui.ext_macro = 'CVAPI'
|
|
highgui.inline_macro = 'CV_INLINE'
|
|
highgui.func_prefix = 'cv'
|
|
highgui.doc_path = '../docs/ref'
|
|
highgui.docs = ['opencvref_highgui.htm']
|
|
comps.append(highgui)
|
|
|
|
|
|
def normalize_decl(decl):
|
|
decl = re.sub( r'^\((.+?)\)', r'\1', decl)
|
|
decl = re.sub( r' CV_DEFAULT\((.+?)\)(,|( *\);))', r'=\1\2', decl)
|
|
decl = re.sub( r'\);', r' );', decl )
|
|
decl = re.sub( r'\(', r'( ', decl )
|
|
decl = re.sub( r'/\*.+?\*/', r'', decl )
|
|
decl = re.sub( r'\binline\b', r'', decl )
|
|
decl = re.sub( r' +', r' ', decl )
|
|
decl = re.sub( r' ?= ?', r'=', decl )
|
|
return decl.strip()
|
|
|
|
def print_report(filename, line_no, msg):
|
|
print '%s(%d): %s' % (filename,line_no,msg)
|
|
|
|
for comp in comps:
|
|
print "==================================================="
|
|
print 'Checking %s...' % (comp.name,)
|
|
header_path = comp.header_path
|
|
func_list = {}
|
|
|
|
if not header_path.endswith('/') and not header_path.endswith('\\'):
|
|
header_path += '/'
|
|
for header_glob in comp.headers:
|
|
glob_expr = header_path + header_glob
|
|
for header in glob.glob(glob_expr):
|
|
f = open(header,'r')
|
|
func_name = ""
|
|
mode = line_no = 0 # mode - outside func declaration (0) or inside (1)
|
|
for l in f.xreadlines():
|
|
line_no += 1
|
|
ll = ""
|
|
|
|
#if re.findall(r'\b([abd-z]|([c][a-uw-z]))[a-z]*[A-Z]', l):
|
|
# print_report(header,line_no,"Bad-style identifier:\n\t"+l)
|
|
|
|
if mode == 0:
|
|
if l.startswith(comp.ext_macro):
|
|
ll = l[len(comp.ext_macro):]
|
|
decl = ""
|
|
mode = 1
|
|
elif l.startswith(comp.inline_macro):
|
|
temp_func_name = re.findall( r'^.+?\b(' + comp.func_prefix + '\w+)', l )
|
|
if temp_func_name and temp_func_name[0] != func_name:
|
|
ll = l[len(comp.inline_macro):]
|
|
decl = ""
|
|
mode = 1
|
|
else:
|
|
ll = l
|
|
|
|
if ll:
|
|
decl += ll.rstrip('\n') + ' '
|
|
if ll.find(';') >= 0:
|
|
mode = 0
|
|
decl = normalize_decl(decl)
|
|
func_name = re.findall( r'^.+?\b(' + comp.func_prefix + '\w+)', decl )[0]
|
|
if func_list.get(func_name,[]):
|
|
print_report(header,line_no,"Duplicated declaration of " + \
|
|
func_name + "... ignored")
|
|
else:
|
|
func_list[func_name] = [decl,header,line_no,0]
|
|
else:
|
|
mode = 1
|
|
f.close()
|
|
|
|
doc_path = comp.doc_path
|
|
if not doc_path.endswith('/') and not doc_path.endswith('\\'):
|
|
doc_path += '/'
|
|
|
|
blurb_re = re.compile( r'^<p class="Blurb"' )
|
|
|
|
for doc_glob in comp.docs:
|
|
glob_expr = doc_path + doc_glob
|
|
for doc in glob.glob(glob_expr):
|
|
f = open(doc, 'r')
|
|
mode = line_no = 0 # mode - 0 outside function declaration, 2 - inside,
|
|
# 1 transitional state ('cause <pre> is used not only
|
|
# for declaring functions)
|
|
for l in f.xreadlines():
|
|
line_no += 1
|
|
#if re.findall(r'\b([abd-z]|([c][a-uw-z]))[a-z]*[A-Z]', l):
|
|
# print_report(doc,line_no,"Bad-style identifier:\n\t" + l)
|
|
if mode == 0:
|
|
if blurb_re.match(l):
|
|
mode = 1
|
|
elif mode == 1:
|
|
if l.endswith('<pre>\n'):
|
|
mode = 2
|
|
decl = ""
|
|
elif mode == 2:
|
|
if l.startswith('</pre>'):
|
|
mode = 0
|
|
if decl.find('CV_DEFAULT') >= 0:
|
|
print_report(doc,line_no,'CV_DEFAULT is used in documentation')
|
|
decl = normalize_decl(decl)
|
|
decl_list = decl.split(';')
|
|
for decl in decl_list:
|
|
decl = decl.strip()
|
|
if decl:
|
|
decl = decl + ';'
|
|
|
|
#print '***', decl
|
|
func_name = re.findall( r'^.+?\b(' + comp.func_prefix + '\w+)\(', decl )
|
|
if not func_name: continue
|
|
|
|
func_name = func_name[0]
|
|
decl_info = func_list.get(func_name,[])
|
|
if decl_info:
|
|
if decl_info[3] == 0:
|
|
if decl_info[0] != decl:
|
|
print_report(doc,line_no,'Incorrect documentation on ' + func_name + ':')
|
|
print ' hdr: ' + decl_info[0]
|
|
print ' doc: ' + decl
|
|
decl_info[3] = 1
|
|
else:
|
|
print_report(doc,line_no,'Duplicated documentation on ' + func_name)
|
|
else:
|
|
print_report(doc,line_no,'The function '+func_name+' is not declared')
|
|
elif not l.startswith('#define'):
|
|
decl += l.rstrip('\n')
|
|
f.close()
|
|
|
|
print "---------------------------------------------------"
|
|
keys = func_list.keys()
|
|
undocumented_funcs = []
|
|
for k in keys:
|
|
decl_info = func_list[k]
|
|
if decl_info[3] == 0:
|
|
undocumented_funcs.append((decl_info[1],decl_info[2],k))
|
|
|
|
undocumented_funcs.sort()
|
|
|
|
for decl_info in undocumented_funcs:
|
|
print_report(decl_info[0],decl_info[1],'Undocumented function '+decl_info[2])
|
|
|