diff --git a/universalmutator/genmutants.py b/universalmutator/genmutants.py index e7352a0..2a1cb99 100644 --- a/universalmutator/genmutants.py +++ b/universalmutator/genmutants.py @@ -120,8 +120,8 @@ def main(): print("USAGE: mutate [] [ ...]", "[--noCheck] [--cmd ] [--mutantDir ]", "[--lines [--tstl]] [--mutateTestCode] [--mutateBoth]", - "[--ignore ] [--compile ] [--noFastCheck] [--swap]", - "[--redundantOK] [--showRules] [--only ]") + "[mutateChange ][--ignore ] [--compile ] [--noFastCheck]", + "[--swap][--redundantOK] [--showRules] [--only ]") print() print(" --noCheck: skips compilation/comparison and just generates mutant files") print(" --cmd executes command string, replacing MUTANT with the mutant name, and uses return code") @@ -132,6 +132,7 @@ def main(): print(" --mutateInStrings: mutate inside strings (not just turn to empty string)") print(" --mutateTestCode: mutate only test code") print(" --mutateBoth: mutate both test and normal code") + print(" --mutateChange: only mutates the lines that have changed from the source file, to other file.") print(" --ignore : ignore lines matching patterns in ") print(" --compile : compile instead of source (solidity handler only)") print(" --comby: use comby as the method of mutating code") @@ -259,6 +260,17 @@ def main(): args.remove(mdir) if mdir[-1] != "/": mdir += "/" + + changeFile = None + try: + changepos = args.index("--mutateChange") + except ValueError: + changepos = -1 + + if changepos != -1: + changeFile = args[changepos + 1] + args.remove("--mutateChange") + args.remove(changeFile) ignoreFile = None try: @@ -381,15 +393,32 @@ def main(): # remove non-ascii characters (comby issue) line_processed = line.encode('ascii', 'ignore').decode() source.append(line_processed) + skippedLines = [] + if changeFile is not None: + print("ONLY MUTATING LINES CHANGED IN", changeFile) + change = [] + + with open(changeFile, 'r') as file: + for line in file: + # remove non-ascii characters (comby issue) + line_processed = line.encode('ascii', 'ignore').decode() + change.append(line_processed) + + with open(changeFile, 'r') as changef, open(sourceFile, 'r') as sourcef: + for i in range (min(len(change),len(source))): + + if change[i] == source[i]: + + skippedLines.append(change[i]) mutants = [] if comby: mutants = mutator.mutants_comby(source, ruleFiles=rules, mutateTestCode=mutateTestCode, mutateBoth=mutateBoth, - ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz, language=ending) + ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz, language=ending,skipLines=skippedLines) else: mutants = mutator.mutants_regexp(source, ruleFiles=rules, mutateTestCode=mutateTestCode, mutateBoth=mutateBoth, - ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz) + ignorePatterns=ignorePatterns, ignoreStringOnly=not mutateInStrings, fuzzing=fuzz, skipLines=skippedLines) if fuzz: if len(mutants) == 0: sys.exit(255) diff --git a/universalmutator/mutator.py b/universalmutator/mutator.py index 1791d61..d82e141 100644 --- a/universalmutator/mutator.py +++ b/universalmutator/mutator.py @@ -81,7 +81,8 @@ def parseRules(ruleFiles, comby=False): def mutants_comby(source, ruleFiles=None, mutateTestCode=False, mutateBoth=False, - ignorePatterns=None, ignoreStringOnly=False, fuzzing=False, language=".generic"): + ignorePatterns=None, ignoreStringOnly=False, fuzzing=False, language=".generic", skipLines=None): + if ruleFiles is None: ruleFiles = ["universal.rules"] comby = Comby() @@ -128,7 +129,7 @@ def mutants_comby(source, ruleFiles=None, mutateTestCode=False, mutateBoth=False return mutants def mutants_regexp(source, ruleFiles=None, mutateTestCode=False, mutateBoth=False, - ignorePatterns=None, ignoreStringOnly=False, fuzzing=False): + ignorePatterns=None, ignoreStringOnly=False, fuzzing=False,skipLines = None): if ruleFiles is None: ruleFiles = ["universal.rules"] print("MUTATING WITH RULES:", ", ".join(ruleFiles)) @@ -172,6 +173,10 @@ def mutants_regexp(source, ruleFiles=None, mutateTestCode=False, mutateBoth=Fals if mutateTestCode and (not mutateBoth): continue skipLine = False + + if skipLines and l in skipLines: + skipLine = True + for lhs in ignoreRules: if lhs.search(l): skipLine = True