def runcheckers(): # If there are no checkers then don't run if len(__checkers__) == 0: return global __addon_name__ global __errorid__ addon = sys.argv[0] parser = cppcheckdata.ArgumentParser() args = parser.parse_args() __addon_name__ = os.path.splitext(os.path.basename(addon))[0] for dumpfile in args.dumpfile: if not args.quiet: print('Checking %s...' % dumpfile) data = cppcheckdata.CppcheckData(dumpfile) for cfg in data.iterconfigurations(): if not args.quiet: print('Checking %s, config %s...' % (dumpfile, cfg.name)) for c in __checkers__: __errorid__ = c.__name__ c(cfg, data)
#!/usr/bin/env python3 # # Locate casts in the code # import cppcheckdata import sys for arg in sys.argv[1:]: if arg.startswith('-'): continue print('Checking %s...' % arg) data = cppcheckdata.CppcheckData(arg) for cfg in data.iterconfigurations(): print('Checking %s, config %s...' % (arg, cfg.name)) for token in cfg.tokenlist: if token.str != '(' or not token.astOperand1 or token.astOperand2: continue # Is it a lambda? if token.astOperand1.str == '{': continue # we probably have a cast.. if there is something inside the parentheses # there is a cast. Otherwise this is a function call. typetok = token.next if not typetok.isName: continue
parser = get_args_parser() args = parser.parse_args() if args.verify: VERIFY = True if not args.dumpfile: if not args.quiet: print("no input files.") sys.exit(0) for dumpfile in args.dumpfile: if not args.quiet: print('Checking %s...' % dumpfile) data = cppcheckdata.CppcheckData(dumpfile) if VERIFY: VERIFY_ACTUAL = [] VERIFY_EXPECTED = [] for tok in data.rawTokens: if tok.str.startswith('//') and 'TODO' not in tok.str: for word in tok.str[2:].split(' '): if re.match(r'cert-[A-Z][A-Z][A-Z][0-9][0-9].*',word): VERIFY_EXPECTED.append(str(tok.linenr) + ':' + word) for cfg in data.iterconfigurations(): if not args.quiet: print('Checking %s, config %s...' % (dumpfile, cfg.name)) exp05(cfg) exp42(cfg)
def process(dumpfiles, configfile, debugprint=False): errors = [] conf = loadConfig(configfile) for afile in dumpfiles: if not afile[-5:] == '.dump': continue print('Checking ' + afile + '...') data = cppcheckdata.CppcheckData(afile) # Check File naming if "RE_FILE" in conf and conf["RE_FILE"]: mockToken = DataStruct(afile[:-5], "0", afile[afile.rfind('/') + 1:-5]) msgType = 'File name' for exp in conf["RE_FILE"]: evalExpr(conf["RE_FILE"], exp, mockToken, msgType, errors) # Check Namespace naming if "RE_NAMESPACE" in conf and conf["RE_NAMESPACE"]: for tk in data.rawTokens: if tk.str == 'namespace': mockToken = DataStruct(tk.next.file, tk.next.linenr, tk.next.str) msgType = 'Namespace' for exp in conf["RE_NAMESPACE"]: evalExpr(conf["RE_NAMESPACE"], exp, mockToken, msgType, errors) for cfg in data.configurations: print('Checking %s, config %s...' % (afile, cfg.name)) if "RE_VARNAME" in conf and conf["RE_VARNAME"]: for var in cfg.variables: if var.nameToken and var.access != 'Global' and var.access != 'Public' and var.access != 'Private': prev = var.nameToken.previous varType = prev.str while "*" in varType and len(varType.replace("*", "")) == 0: prev = prev.previous varType = prev.str + varType if debugprint: print("Variable Name: " + str(var.nameToken.str)) print("original Type Name: " + str(var.nameToken.valueType.originalTypeName)) print("Type Name: " + var.nameToken.valueType.type) print("Sign: " + str(var.nameToken.valueType.sign)) print("variable type: " + varType) print("\n") print("\t-- {} {}".format(varType, str(var.nameToken.str))) if conf["skip_one_char_variables"] and len(var.nameToken.str) == 1: continue if varType in conf["var_prefixes"]: if not var.nameToken.str.startswith(conf["var_prefixes"][varType]): errors.append(reportError( var.typeStartToken.file, var.typeStartToken.linenr, 'style', 'Variable ' + var.nameToken.str + ' violates naming convention')) mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) msgType = 'Variable' for exp in conf["RE_VARNAME"]: evalExpr(conf["RE_VARNAME"], exp, mockToken, msgType, errors) # Check Private Variable naming if "RE_PRIVATE_MEMBER_VARIABLE" in conf and conf["RE_PRIVATE_MEMBER_VARIABLE"]: # TODO: Not converted yet for var in cfg.variables: if (var.access is None) or var.access != 'Private': continue mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) msgType = 'Private member variable' for exp in conf["RE_PRIVATE_MEMBER_VARIABLE"]: evalExpr(conf["RE_PRIVATE_MEMBER_VARIABLE"], exp, mockToken, msgType, errors) # Check Public Member Variable naming if "RE_PUBLIC_MEMBER_VARIABLE" in conf and conf["RE_PUBLIC_MEMBER_VARIABLE"]: for var in cfg.variables: if (var.access is None) or var.access != 'Public': continue mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) msgType = 'Public member variable' for exp in conf["RE_PUBLIC_MEMBER_VARIABLE"]: evalExpr(conf["RE_PUBLIC_MEMBER_VARIABLE"], exp, mockToken, msgType, errors) # Check Global Variable naming if "RE_GLOBAL_VARNAME" in conf and conf["RE_GLOBAL_VARNAME"]: for var in cfg.variables: if (var.access is None) or var.access != 'Global': continue mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) msgType = 'Public member variable' for exp in conf["RE_GLOBAL_VARNAME"]: evalExpr(conf["RE_GLOBAL_VARNAME"], exp, mockToken, msgType, errors) # Check Functions naming if "RE_FUNCTIONNAME" in conf and conf["RE_FUNCTIONNAME"]: for token in cfg.tokenlist: if token.function: if token.function.type == 'Constructor' or token.function.type == 'Destructor': continue retval = token.previous.str prev = token.previous while "*" in retval and len(retval.replace("*", "")) == 0: prev = prev.previous retval = prev.str + retval if debugprint: print("\t:: {} {}".format(retval, token.function.name)) if retval and retval in conf["function_prefixes"]: if not token.function.name.startswith(conf["function_prefixes"][retval]): errors.append(reportError( token.file, token.linenr, 'style', 'Function ' + token.function.name + ' violates naming convention')) mockToken = DataStruct(token.file, token.linenr, token.function.name) msgType = 'Function' for exp in conf["RE_FUNCTIONNAME"]: evalExpr(conf["RE_FUNCTIONNAME"], exp, mockToken, msgType, errors) # Check Class naming if "RE_CLASS_NAME" in conf and conf["RE_CLASS_NAME"]: for fnc in cfg.functions: # Check if it is Constructor/Destructor if fnc.type == 'Constructor' or fnc.type == 'Destructor': mockToken = DataStruct(fnc.tokenDef.file, fnc.tokenDef.linenr, fnc.name) msgType = 'Class ' + fnc.type for exp in conf["RE_CLASS_NAME"]: evalExpr(conf["RE_CLASS_NAME"], exp, mockToken, msgType, errors) return errors
def check_y2038_safe(dumpfile, quiet=False): # Assume that the code is Y2038 safe until proven otherwise y2038safe = True # load XML from .dump file data = cppcheckdata.CppcheckData(dumpfile) # Convert dump file path to source file in format generated by cppcheck. # For example after the following call: # cppcheck ./src/my-src.c --dump # We got 'src/my-src.c' value for 'file' field in cppcheckdata. srcfile = dumpfile.rstrip('.dump') srcfile = os.path.expanduser(srcfile) srcfile = os.path.normpath(srcfile) # go through each configuration for cfg in data.iterconfigurations(): if not quiet: print('Checking %s, config %s...' % (srcfile, cfg.name)) safe_ranges = [] safe = -1 time_bits_defined = False srclinenr = '0' for directive in cfg.directives: # track source line number if directive.file == srcfile: srclinenr = directive.linenr # check for correct _TIME_BITS if present if re_define_time_bits_64.match(directive.str): time_bits_defined = True elif re_define_time_bits.match(directive.str): cppcheckdata.reportError(directive, 'error', '_TIME_BITS must be defined equal to 64', 'y2038', 'type-bits-not-64') time_bits_defined = False y2038safe = False elif re_undef_time_bits.match(directive.str): time_bits_defined = False # check for _USE_TIME_BITS64 (un)definition if re_define_use_time_bits64.match(directive.str): safe = int(srclinenr) # warn about _TIME_BITS not being defined if not time_bits_defined: cppcheckdata.reportError(directive, 'warning', '_USE_TIME_BITS64 is defined but _TIME_BITS was not', 'y2038', 'type-bits-undef') elif re_undef_use_time_bits64.match(directive.str): unsafe = int(srclinenr) # do we have a safe..unsafe area? if unsafe > safe > 0: safe_ranges.append((safe, unsafe)) safe = -1 # check end of source beyond last directive if len(cfg.tokenlist) > 0: unsafe = int(cfg.tokenlist[-1].linenr) if unsafe > safe > 0: safe_ranges.append((safe, unsafe)) # go through all tokens for token in cfg.tokenlist: if token.str in id_Y2038: if not any(lower <= int(token.linenr) <= upper for (lower, upper) in safe_ranges): cppcheckdata.reportError(token, 'warning', token.str + ' is Y2038-unsafe', 'y2038', 'unsafe-call') y2038safe = False token = token.next return y2038safe