def FunctionHeaderFormat(self): """ Verify the function header format and content keywords: <TheFunctionName> matches the current functions name <TheParameters> names of parameters must match, void matches empty string <TheReturnType> names the return type, void matches empty string """ # Function Header Specific keywords eFunctionName = '<TheFunctionName>' eParams = '<TheParameters>' eParamsIn = '<TheParametersIn>' eParamsOut = '<TheParametersOut>' eParamsInOut = '<TheParametersInOut>' eReturnType = '<TheReturnType>' self.SetStatusMsg(msg='Check Function Header Format') # in the function header we look for important items fhDesc = self.projFile.formats[PF.eFmtFunction] fhRawDesc = self.projFile.rawFormats[PF.eFmtFunction] fc = FormatChecker(eDbDetectId, self.updateTime, fhDesc, fhRawDesc) pctCtr = 0 totalFiles = len(self.srcFiles) for i in self.srcFiles: if self.abortRequest: break pctCtr += 1 self.SetStatusMsg((pctCtr / float(totalFiles) * 100)) # compute the relative path from a srcRoot rpfn, fn = self.projFile.RelativePathName(i) # Get file/function information funcInfo = self.udb.GetFileFunctionInfo(fn) for func in funcInfo: if func == 'ConvertToDegC': pass # get function info fi = funcInfo[func] hdr = fi[udb.eFiHeader] params = fi[udb.eFiParams] lineNum = fi[udb.eFiStart] # header split by line if hdr: hdrLines = hdr.split('\n') fc.Check(hdr) fc.ReportErrors(self.vDb, rpfn, lineNum, 'Function Header', func, 'FuncHdr') else: # No function header severity = 'Error' violationId = 'FuncHdr.NoHeader' desc = 'Function Header %s is missing' % (func) details = 'N/A' self.vDb.Insert(rpfn, func, severity, violationId, desc, details, lineNum, eDbDetectId, self.updateTime) continue # is the function name supposed to be in the header? keyItems = fc.GetKeywordItems(eFunctionName) if keyItems: for item in keyItems: keyInfo = item.keywords[eFunctionName] searchIn = '\n'.join(keyInfo.lines) if searchIn.find(func) == -1: severity = 'Error' violationId = 'FuncHdr.FuncName' desc = 'Function Name %s Missing in header' % func details = 'Expected at offset %d of %d lines' % ( keyInfo.line0, len(hdrLines)) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, lineNum, eDbDetectId, self.updateTime) # check parameters - if requested and collect associated lines # TODO: detect actual out param types *, & report misplaced comments expectParams = False paramLines = [] for p in (eParams, eParamsIn, eParamsOut, eParamsInOut): keyItems = fc.GetKeywordItems(p) for item in keyItems: expectParams = True paramLines.extend(item.keywords[p].lines) # collect any lines associated with parameters and see if all the params are defined if expectParams: searchIn = '\n'.join(paramLines) for px, p in enumerate(params): if searchIn.find(p) == -1: severity = 'Error' violationId = 'FuncHdr.Param' desc = 'Function Header %s Missing Param %s' % ( func, p) details = 'Parameter <%s> not in description' % p self.vDb.Insert(rpfn, func, severity, violationId, desc, details, lineNum, eDbDetectId, self.updateTime) # check return type - if requested keyItems = fc.GetKeywordItems(eReturnType) for item in keyItems: searchIn = '\n'.join(item.keywords[eReturnType].lines) rawText = item.JoinRaw() rtnLineDesc = rawText.replace(eReturnType, '') searchIn = searchIn.replace(rtnLineDesc, '').strip() if not searchIn and fi[udb.eFiReturnType] != 'void': severity = 'Error' violationId = 'FuncHdr.Return' desc = 'Function Header %s Missing return info' % ( func) details = 'Function header consists of %d lines' % len( hdrLines) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, lineNum, eDbDetectId, self.updateTime) self.vDb.Commit()
def CheckLine(self, rpfn, funcInfo, lines): """ Analyze for: 1. Lines exceed the max line length 2. Lines with the word TODO, TBD 3. No tabs in the file report the line number(s) for the above """ # File Specific keywords eFileName = '<TheFileName>' eTheDescription = '<TheDescription>' # leave these - PCLint should report these may need to do some work on it eLocalFuncProto = '<TheLocalFunctionPrototypes>' eLocalFunctions = '<TheLocalFunctions>' eGlobalFunctions = '<TheGlobalFunctions>' # check all line lengths fileSize = len(lines) fn = os.path.split(rpfn)[1] lineLimit = self.projFile.metrics[PF.eMetricLine] # get the filename and start/end line numbers data = {} for func in funcInfo: start = funcInfo[func]['start'] end = funcInfo[func]['end'] data[(start, end)] = func #--------------------------------- init the file format check # determine file type c/h ext = os.path.splitext(rpfn)[1] # build format name fmtName = 'File_%s' % ext.replace('.', '').upper() fileDescLines = self.projFile.formats.get(fmtName, '') rawDescLines = self.projFile.rawFormats.get(fmtName, '') fc = FormatChecker(eDbDetectId, self.updateTime, fileDescLines, rawDescLines) for lx, line in enumerate(lines): txt = line.rstrip() lineLen = len(txt) u4cLine = lx + 1 # U4C refs start at line 1 func = None # feed the file format checker fc.CheckLine(lx, line) if lineLen > lineLimit: func = 'N/A' for ds, de in data: if u4cLine >= ds and u4cLine <= de: func = data[(ds, de)] severity = 'Warning' violationId = 'Metric.Line' desc = 'Line Length in %s line %d' % (fn, lx) details = '%3d: %s' % (lineLen, txt.strip()) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, u4cLine, eDbDetectId, self.updateTime) # check for TO-DO or T.B.D. txtl = txt.lower() todoRe = re.compile(r' ?todo[: ]+') tbdRe = re.compile(r' ?tbd[: ]+') if todoRe.search(txtl) or tbdRe.search(txtl): if func is None: func = 'N/A' for ds, de in data: if ds <= u4cLine <= de: func = data[(ds, de)] severity = 'Info' violationId = 'Misc.TODO' desc = 'Line contains TODO/TBD %s line %d' % (fn, lx) details = '%s' % (txt.strip()) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, u4cLine, eDbDetectId, self.updateTime) # check for tabs if txt.find('\t') != -1: if txt.lower().find('todo') != -1 or txt.lower().find( 'tbd') != -1: if func is None: func = 'N/A' for ds, de in data: if u4cLine >= ds and u4cLine <= de: func = data[(ds, de)] severity = 'Error' violationId = 'Misc.TAB' desc = 'Line contains TAB(s) %s line %d' % (fn, lx) details = '%s' % (txt.strip()) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, u4cLine, eDbDetectId, self.updateTime) # check any lines remaining in the line buffer fc.FinishBuffer() #------------------------------------------------- report and file format errors # save this info incase we need to do some work for the three eLocal/Global above self.fileKeywordData[rpfn] = copy.deepcopy(fc.items) fc.ReportErrors(self.vDb, rpfn, -1, 'File Format', rpfn, 'FileFmt') # check for the filename being were it is supposed to be keyItems = fc.GetKeywordItems(eFileName) if keyItems: for item in keyItems: keyInfo = item.keywords[eFileName] text = '\n'.join(keyInfo.lines) if text.lower().find(fn.lower()) == -1: # no mention of file name severity = 'Error' violationId = 'FileFmt.FileName' func = 'N/A' desc = 'Missing Filename near line %d' % keyInfo.line0 details = 'Expected filename at line %d [Item %d]' % ( keyInfo.line0, item.itemId) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, keyInfo.line0, eDbDetectId, self.updateTime) # check for a file description keyItems = fc.GetKeywordItems(eTheDescription) if keyItems: for item in keyItems: keyInfo = item.keywords[eTheDescription] text = '\n'.join(keyInfo.lines) rawText = item.JoinRaw() replaceTxt = rawText.replace(eTheDescription, '').strip() text = text.replace(replaceTxt, '').strip() if not text: # no mention of file name severity = 'Error' violationId = 'FileFmt.NoDesc' func = 'N/A' desc = 'Missing File Desc near line %d' % keyInfo.line0 details = 'Expected file description at line %d [Item %d]' % ( keyInfo.line0, item.itemId) self.vDb.Insert(rpfn, func, severity, violationId, desc, details, keyInfo.line0, eDbDetectId, self.updateTime) self.vDb.Commit()