diff --git a/universalmutator/analyze.py b/universalmutator/analyze.py index d48450b..4c30eaa 100644 --- a/universalmutator/analyze.py +++ b/universalmutator/analyze.py @@ -11,138 +11,84 @@ import random import os import py_compile +import argparse def main(): isWindows = platform.system() - args = sys.argv - - if ("--help" in args) or (len(sys.argv) < 3): - if len(sys.argv) < 3: - print("ERROR: analyze_mutants requires at least two arguments\n") - print("USAGE: analyze_mutants [--mutantDir ] [--fromFile ]") - print(" is command to execute to run tests; non-zero return indicates mutant killed") - print(" --mutantDir: directory with all mutants; defaults to current directory") - print(" --fromFile: file containing list of mutants to process; others ignored") - print(" --timeout : change the timeout setting") - print(" --show: show mutants") - print(" --verbose: show mutants and output of analysis") - print(" --seed: random seed for shuffling of mutants") - print(" --noShuffle: do not randomize order of mutants") - print(" --resume: use existing killed.txt and notkilled.txt, resume mutation analysis") - print(" --prefix: add a prefix to killed.txt and notkilled.txt") - print(" --numMutants: run with specific number of mutants") - print(" --compileCommand: compile command to run in selecting mutants") - sys.exit(0) - - verbose = "--verbose" in sys.argv - if verbose: - args.remove("--verbose") - - showM = "--show" in sys.argv - if showM: - args.remove("--show") - - resume = "--resume" in sys.argv - if resume: - args.remove("--resume") - noShuffle = "--noShuffle" in sys.argv - if noShuffle: - args.remove("--noShuffle") + parser = argparse.ArgumentParser() - prefix = None - try: - prefixpos = args.index("--prefix") - except ValueError: - prefixpos = -1 + parser.add_argument("sourcefile", help="a file to mutate", metavar="") - if prefixpos != -1: - prefix = args[prefixpos + 1] - args.remove("--prefix") - args.remove(prefix) + parser.add_argument("cmd", help=" is command to execute to run tests; non-zero return indicates mutant killed", metavar="") - fromFile = None - try: - filepos = args.index("--fromFile") - except ValueError: - filepos = -1 + parser.add_argument("--mutantDir", help ="directory with all mutants; defaults to current directory", nargs = 1, metavar="") - if filepos != -1: - fromFile = args[filepos + 1] - args.remove("--fromFile") - args.remove(fromFile) + parser.add_argument("--fromFile", help="file containing list of mutants to process; others ignored", nargs=1, metavar="") - seed = None - try: - seedpos = args.index("--seed") - except ValueError: - seedpos = -1 + parser.add_argument("--timeout",nargs=1, help = "change the timeout setting", metavar="val",type=int) - if seedpos != -1: - seed = args[seedpos + 1] - args.remove("--seed") - args.remove(seed) - seed = int(seed) + parser.add_argument("--show", action="store_true", help="show mutants") - timeout = 30 - try: - topos = args.index("--timeout") - except ValueError: - topos = -1 + parser.add_argument("--verbose", help="show mutants and output of analysis", action="store_true") - if topos != -1: - timeout = args[topos + 1] - args.remove("--timeout") - args.remove(timeout) - timeout = float(timeout) + parser.add_argument("--seed", help="random seed for shuffling of mutants", nargs=1, type=int, metavar="") - numMutants = -1 - try: - nmpos = args.index("--numMutants") - except ValueError: - nmpos = -1 + parser.add_argument("--noShuffle", help="do not randomize order of mutants", action="store_true") - if nmpos != -1: - numMutants = args[nmpos + 1] - args.remove("--numMutants") - args.remove(numMutants) - numMutants = int(numMutants) + parser.add_argument("--resume", help="use existing killed.txt and notkilled.txt, resume mutation analysis", action="store_true") - compileCommand = None - try: - ccmdpos = args.index("--compileCommand") - except ValueError: - ccmdpos = -1 + parser.add_argument("--prefix", help="add a prefix to killed.txt and notkilled.txt", nargs=1, metavar="") + + parser.add_argument("--numMutants", help="run with specific number of mutants", nargs=1, metavar="", type=int) + + parser.add_argument("--compileCommand", help="compile command to run in selecting mutants", action="store_true") + + args = parser.parse_args() - if ccmdpos != -1: - compileCommand = args[ccmdpos + 1] - args.remove("--compileCommand") - args.remove(compileCommand) + verbose = args.verbose + + showM = args.show + + resume = args.resume + + noShuffle = args.noShuffle + + prefix = args.prefix + + + fromFile = args.fromFile + + seed = args.seed + + timeout = args.timeout + if timeout == None: + timeout=30 + + numMutants = args.numMutants + if(numMutants == None): + numMutants = -1 + + compileCommand = args.compileCommand onlyMutants = None + if fromFile is not None: with open(fromFile, 'r') as file: onlyMutants = file.read().split() - mdir = "." - try: - mdirpos = args.index("--mutantDir") - except ValueError: - mdirpos = -1 - - if mdirpos != -1: - mdir = args[mdirpos + 1] - args.remove("--mutantDir") - args.remove(mdir) + mdir= args.mutantDir + if mdir == None: + mdir = "." if mdir[-1] != "/": mdir += "/" - src = args[1] - tstCmd = [args[2]] + src = args.sourcefile + tstCmd = args.cmd ignore = [] - if len(args) > 3: - with open(sys.argv[3]) as file: + if args.fromfile != None: + with open(args.fromfile) as file: for l in file: ignore.append(l.split()[0]) diff --git a/universalmutator/checkcov.py b/universalmutator/checkcov.py index adbf48e..f0e9abb 100644 --- a/universalmutator/checkcov.py +++ b/universalmutator/checkcov.py @@ -2,38 +2,37 @@ import sys import glob - +import argparse def main(): - args = sys.argv - - if ("--help" in args) or (len(sys.argv) < 4): - if len(sys.argv) < 4: - print("ERROR: check_covered requires at least three arguments\n") - print("USAGE: check_covered [--tstl] [--mutantDir directory]") - print(" --mutantDir: directory to put generated mutants in; defaults to current directory") - print(" --tstl: process that is output from TSTL internal report") - sys.exit(0) - - mdir = "." - try: - mdirpos = args.index("--mutantDir") - except ValueError: - mdirpos = -1 - - if mdirpos != -1: - mdir = args[mdirpos + 1] - args.remove("--mutantDir") - args.remove(mdir) + parser = argparse.ArgumentParser() + + parser.add_argument("sourcefile",nargs = 1, metavar="") + + parser.add_argument("coverfile",nargs = 1, metavar="") + + parser.add_argument("outfile",nargs = 1, metavar="") + + parser.add_argument("--tstl", action="store_true", help = "process that is output from TSTL internal report") + + parser.add_argument("--mutantDir", nargs=1, metavar="directory", help = "directory to put generated mutants in; defaults to current directory") + + args = parser.parse_args() + + mdir= args.mutantDir + if mdir == None: + mdir = "." if mdir[-1] != "/": mdir += "/" - src = args[1] - coverFile = args[2] - outFile = args[3] + src = args.sourcefile + coverFile = args.coverfile + outFile = args.outfile - tstl = "--tstl" in sys.argv + tstl = args.tstl + if tstl == None: + tstl = False srcBase = src.split("/")[-1] srcEnd = src.split(".")[-1] diff --git a/universalmutator/genmutants.py b/universalmutator/genmutants.py index e7352a0..d8a44b6 100644 --- a/universalmutator/genmutants.py +++ b/universalmutator/genmutants.py @@ -3,10 +3,10 @@ import os import random -from re import T import sys import shutil import subprocess +import argparse from universalmutator import mutator @@ -65,7 +65,6 @@ def cmdHandler(tmpMutantName, mutant, sourceFile, uniqueMutants): if "MUTANT" not in cmd: shutil.copy(backupName, sourceFile) - def toGarbage(code): newCode = "" for c in code: @@ -87,7 +86,60 @@ def main(): except BaseException: pass - args = sys.argv + + + print("*** UNIVERSALMUTATOR ***") + + parser = argparse.ArgumentParser() + + parser.add_argument("sourcefile", help="a file to mutate", metavar="") + + parser.add_argument("rules", nargs="*", metavar=" ", help="any amount of rules") + + parser.add_argument("--language", nargs=1, metavar="") + + parser.add_argument("--noCheck", action="store_true", help="skips compilation/comparison and just generates mutant files") + + parser.add_argument("--cmd",nargs=1, help="executes command string, replacing MUTANT with the mutant name, " + "and uses return code to determine mutant validity", metavar="") + + parser.add_argument("--mutantDir", nargs=1, help="directory to put generated mutants in; defaults to current directory", metavar="") + + parser.add_argument("--lines", nargs=1, help="only generate mutants for lines contained in ", metavar="") + + parser.add_argument("--tstl", action="store_true", help=" is TSTL output") + + parser.add_argument("--mutateInStrings",action="store_true", help="mutate inside strings (not just turn to empty string)") + + parser.add_argument("--mutateTestCode",action="store_true", help="mutate only test code") + + parser.add_argument("--mutateBoth", action="store_true", help="mutate both test and normal code") + + parser.add_argument("--ignore", nargs=1, help="ignore lines matching patterns in ", metavar="") + + parser.add_argument("--compile",nargs=1, help="compile instead of source (solidity handler only)", metavar="") + + parser.add_argument("--comby", action="store_true",help="use comby as the method of mutating code") + + parser.add_argument("--noFastCheck", action="store_true", help="do not use fast dead code/comment detection heuristic") + + parser.add_argument("--swap", action="store_true", help="also try adjacent-code swaps") + + parser.add_argument("--redundantOK", action="store_true", help="keep redundant mutants (for compiler output issues)") + + parser.add_argument("--showRules", action="store_true", help="show rule source used to generate each mutant") + + parser.add_argument("--only", nargs=1, help="only use rule file [] [ ...]", - "[--noCheck] [--cmd ] [--mutantDir ]", - "[--lines [--tstl]] [--mutateTestCode] [--mutateBoth]", - "[--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") - print(" to determine mutant validity") - print(" --mutantDir: directory to put generated mutants in; defaults to current directory") - print(" --lines: only generate mutants for lines contained in ") - print(" --tstl: is TSTL output") - 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(" --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") - print(" --noFastCheck: do not use fast dead code/comment detection heuristic") - print(" --swap: also try adjacent-code swaps") - print(" --redundantOK: keep redundant mutants (for compiler output issues)") - print(" --showRules: show rule source used to generate each mutant") - print(" --only : only use rule file ") - print(" --printStat: print stats for the rules and generated mutants into files") - print() - print("Currently supported languages: ", ", ".join(list(set(languages.values())))) - print("If not supplying a command to compile/build, you should use --noCheck for C, C++,") - print("javascript, and other languages with only a default handler.") - sys.exit(0) - - noCheck = False - if "--noCheck" in args: - noCheck = True - args.remove("--noCheck") - - comby = False - if "--comby" in args: - comby = True - args.remove("--comby") - - redundantOK = False - if "--redundantOK" in args: - redundantOK = True - args.remove("--redundantOK") - - showRules = False - if "--showRules" in args: - showRules = True - args.remove("--showRules") - - mutateInStrings = False - if "--mutateInStrings" in args: - mutateInStrings = True - args.remove("--mutateInStrings") - - mutateTestCode = False - if "--mutateTestCode" in args: - mutateTestCode = True - args.remove("--mutateTestCode") - - mutateBoth = False - if "--mutateBoth" in args: - mutateBoth = True - args.remove("--mutateBoth") - - noFastCheck = False - if "--noFastCheck" in args: - noFastCheck = True - args.remove("--noFastCheck") + comby = args.comby - doSwaps = False - if "--swap" in args: - doSwaps = True - args.remove("--swap") + redundantOK = args.redundantOK - tstl = False - if "--tstl" in args: - tstl = True - args.remove("--tstl") + showRules = args.showRules - fuzz = False - if "--fuzz" in args: - fuzz = True - args.remove("--fuzz") + mutateInStrings = args.mutateInStrings - printStat = False - if "--printStat" in args: - printStat = True - args.remove("--printStat") + mutateTestCode = args.mutateTestCode - cmd = None - try: - cmdpos = args.index("--cmd") - except ValueError: - cmdpos = -1 + mutateBoth = args.mutateBoth - if cmdpos != -1: - cmd = args[cmdpos + 1] - args.remove("--cmd") - args.remove(cmd) + noFastCheck = args.noFastCheck - sourceFile = args[1] - ending = "." + sourceFile.split(".")[-1] + doSwaps = args.swap - lineFile = None - try: - linepos = args.index("--lines") - except ValueError: - linepos = -1 + tstl = args.tstl + + # What is this? + fuzz = args.fuzz + + printStat = args.printStat - if linepos != -1: - lineFile = args[linepos + 1] - args.remove("--lines") - args.remove(lineFile) + cmd = args.cmd + + sourceFile = args.sourcefile + ending = "." + sourceFile.split(".")[-1] + lineFile = args.lines if lineFile is not None: with open(lineFile) as file: if not tstl: @@ -248,39 +211,15 @@ def main(): lines.append(int(line)) mdir = "." - try: - mdirpos = args.index("--mutantDir") - except ValueError: - mdirpos = -1 - - if mdirpos != -1: - mdir = args[mdirpos + 1] - args.remove("--mutantDir") - args.remove(mdir) + if args.mutantDir != None: + mdir = args.mutantDir if mdir[-1] != "/": mdir += "/" - ignoreFile = None - try: - ignorepos = args.index("--ignore") - except ValueError: - ignorepos = -1 - - if ignorepos != -1: - ignoreFile = args[ignorepos + 1] - args.remove("--ignore") - args.remove(ignoreFile) + ignoreFile = args.ignore - compileFile = None - try: - compilepos = args.index("--compile") - except ValueError: - compilepos = -1 + compileFile = args.compile - if compilepos != -1: - compileFile = args[compilepos + 1] - args.remove("--compile") - args.remove(compileFile) ignorePatterns = [] if ignoreFile is not None: @@ -321,24 +260,20 @@ def main(): except BaseException: pass - sourceFile = args[1] + sourceFile = args.sourcefile base = (".".join((sourceFile.split(".")[:-1]))).split("/")[-1] ending = "." + sourceFile.split(".")[-1] - if "--only" not in args: - if len(args) < 3: + if args.only == None: + if args.language == None or args.rules == None: try: language = languages[ending] except KeyError: language = "none" otherRules = [] else: - if ".rules" in args[2]: - language = languages[ending] - otherRules = args[2:] - else: - language = args[2] - otherRules = args[3:] + language = args.language + otherRules = args.rules if language not in handlers: if language.lower() in handlers: @@ -361,15 +296,12 @@ def main(): fuzzRules = ["universal.rules", "c_like.rules", "python.rules", "vyper.rules", "solidity.rules"] rules = list(set(fuzzRules + rules)) else: - onlyPos = args.index("--only") - rules = [args[onlyPos + 1]] - if args[2] != "--only": - language = args[2] - else: - try: - language = languages[ending] - except KeyError: - language = "none" + rules = args.only + try: + language = languages[ending] + except KeyError: + language = "none" + if language not in handlers: if language.lower() in handlers: language = language.lower() diff --git a/universalmutator/intersect.py b/universalmutator/intersect.py index e960dd2..be1cfd9 100644 --- a/universalmutator/intersect.py +++ b/universalmutator/intersect.py @@ -1,20 +1,23 @@ from __future__ import print_function import sys +import argparse def main(): - args = sys.argv + parser = argparse.ArgumentParser() - if ("--help" in args) or (len(sys.argv) < 2): - if len(sys.argv) < 2: - print("ERROR: intersect_mutants requires at least three arguments\n") - print("USAGE: intersect_mutants ") - sys.exit(0) + parser.add_argument("infile1",nargs = 1, metavar="") - infile1 = sys.argv[1] - infile2 = sys.argv[2] - outfile = sys.argv[3] + parser.add_argument("infile2",nargs = 1, metavar="") + + parser.add_argument("outfile",nargs = 1, metavar="") + + args = parser.parse_args() + + infile1 = args.infile1 + infile2 = args.infile2 + outfile = args.outfile infile1_mutants = [] with open(infile1, 'r') as if1: diff --git a/universalmutator/prioritize.py b/universalmutator/prioritize.py index 003efa4..8614233 100644 --- a/universalmutator/prioritize.py +++ b/universalmutator/prioritize.py @@ -1,82 +1,69 @@ from __future__ import print_function import glob import sys +import argparse from universalmutator import utils def main(): - args = sys.argv + parser = argparse.ArgumentParser() - if ("--help" in args) or (len(sys.argv) < 3): - if len(sys.argv) < 3: - print("ERROR: prioritize_mutants requires at least two arguments\n") - print("USAGE: prioritize_mutants [N] [--cutoff ]", end="") - print("[--mutantDir ] [--sourceDir ]") - print(" --verbose: produce verbose output") - print(" --noSDPriority: do not prioritize statement deletions over other mutants") - print(" --mutantDir: directory with all mutants; defaults to current directory") - print(" --sourceDir: directory of source files; defaults to current directory") - print(" --cutoff: if minimum distance is less than , stop") - sys.exit(0) + parser.add_argument("infile",nargs = 1, metavar="") - infile = sys.argv[1] - outfile = sys.argv[2] + parser.add_argument("outfile",nargs = 1, metavar="") + + parser.add_argument("N", nargs = "?", type=int, metavar="[N]") + + parser.add_argument("--addinfile", nargs="+", metavar=", ") + + parser.add_argument("--cutoff", nargs=1, metavar="",type=float, help="if minimum distance is less than , stop") + + parser.add_argument("--verbose", help="produce verbose output", action="store_true") + + parser.add_argument("--noSDPriority", action="store_true", help= "do not prioritize statement deletions over other mutants") + + parser.add_argument("--mutantDir", nargs=1, metavar="", help = "directory with all mutants; defaults to current directory") + + parser.add_argument("--sourceDir", nargs=1, metavar="", help = "directory of source files; defaults to current directory") + + args = parser.parse_args() + + infile = args.infile + + outfile = args.outfile infiles = glob.glob(infile) - verbose = False - if "--verbose" in args: - args.remove("--verbose") - verbose = True - - noSDPriority = False - if "--noSDPriority" in args: - args.remove("--noSDPriority") - noSDPriority = True - - mdir = "." - try: - mdirpos = args.index("--mutantDir") - except ValueError: - mdirpos = -1 - - if mdirpos != -1: - mdir = args[mdirpos + 1] - args.remove("--mutantDir") - args.remove(mdir) + verbose = args.verbose + if verbose == None: + verbose = False + + noSDPriority = args.noSDPriority + if noSDPriority == None: + noSDPriority = False + + mdir= args.mutantDir + if mdir == None: + mdir = "." if mdir[-1] != "/": mdir += "/" - sdir = "." - try: - sdirpos = args.index("--sourceDir") - except ValueError: - sdirpos = -1 - - if sdirpos != -1: - sdir = args[sdirpos + 1] - args.remove("--sourceDir") - args.remove(sdir) + sdir= args.sourceDir + if sdir == None: + sdir = "." if sdir[-1] != "/": sdir += "/" - cutoff = 0.0 - try: - cutoffpos = args.index("--cutoff") - except ValueError: - cutoffpos = -1 - - if cutoffpos != -1: - cutoff = args[cutoffpos + 1] - args.remove("--cutoff") - args.remove(cutoff) - cutoff = float(cutoff) - - N = -1 - if len(args) >= 4: - N = int(args[3]) + + cutoff = args.cutoff + if cutoff == None: + cutoff = 0.0 + + N = args.N + if N == None: + N = -1 mutants = [] for f in infiles: diff --git a/universalmutator/prune.py b/universalmutator/prune.py index 9a81009..729197a 100644 --- a/universalmutator/prune.py +++ b/universalmutator/prune.py @@ -1,51 +1,45 @@ from __future__ import print_function import re import sys +import argparse + from universalmutator import utils def main(): - args = sys.argv - - if ("--help" in args) or (len(sys.argv) < 2): - if len(sys.argv) < 2: - print("ERROR: show_mutants requires at least one argument\n") - print("USAGE: prune_mutants [--mutantDir ] [--sourceDir ]") - print(" --mutantDir: directory with all mutants; defaults to current directory") - print(" --sourceDir: directory of source files; defaults to current directory") - sys.exit(0) - - infile = sys.argv[1] - outfile = sys.argv[2] - config = sys.argv[3] - - mdir = "." - try: - mdirpos = args.index("--mutantDir") - except ValueError: - mdirpos = -1 - - if mdirpos != -1: - mdir = args[mdirpos + 1] - args.remove("--mutantDir") - args.remove(mdir) + parser = argparse.ArgumentParser() + + parser.add_argument("infile",nargs = 1, metavar="") + + parser.add_argument("outfile",nargs = 1, metavar="") + + parser.add_argument("pruningconf", nargs =1, metavar="") + + parser.add_argument("--mutantDir", nargs=1, metavar="", help = "directory with all mutants; defaults to current directory") + + parser.add_argument("--sourceDir", nargs=1, metavar="", help = "directory of source files; defaults to current directory") + + args = parser.parse_args() + + + infile = args.infile + outfile = args.outfile + config = args.pruningconf + + mdir= args.mutantDir + if mdir == None: + mdir = "." if mdir[-1] != "/": mdir += "/" - sdir = "." - try: - sdirpos = args.index("--sourceDir") - except ValueError: - sdirpos = -1 - - if sdirpos != -1: - sdir = args[sdirpos + 1] - args.remove("--sourceDir") - args.remove(sdir) + sdir= args.sourceDir + if sdir == None: + sdir = "." if sdir[-1] != "/": sdir += "/" + mutants = [] with open(infile, 'r') as mfile: diff --git a/universalmutator/show.py b/universalmutator/show.py index b63bd68..7342021 100644 --- a/universalmutator/show.py +++ b/universalmutator/show.py @@ -1,51 +1,37 @@ from __future__ import print_function import sys +import argparse from universalmutator import utils def main(): - args = sys.argv - - if ("--help" in args) or (len(sys.argv) < 2): - if len(sys.argv) < 2: - print("ERROR: show_mutants requires at least one argument\n") - print("USAGE: show_mutants [--mutantDir ] [--sourceDir ]") - print(" --mutantDir: directory with all mutants; defaults to current directory") - print(" --sourceDir: directory of source files; defaults to current directory") - print(" --concise: display in concise mutant format") - sys.exit(0) - - infile = sys.argv[1] - - concise = "--concise" in sys.argv - if concise: - args.remove("--concise") - - mdir = "." - try: - mdirpos = args.index("--mutantDir") - except ValueError: - mdirpos = -1 - - if mdirpos != -1: - mdir = args[mdirpos + 1] - args.remove("--mutantDir") - args.remove(mdir) + parser = argparse.ArgumentParser() + + parser.add_argument("infile",nargs = 1, metavar="") + + parser.add_argument("--mutantDir", nargs=1, metavar="", help = "directory with all mutants; defaults to current directory") + + parser.add_argument("--sourceDir", nargs=1, metavar="", help = "directory of source files; defaults to current directory") + + parser.add_argument("--concise", action="store_true", help="display in concise mutant format") + + args = parser.parse_args() + + infile = args.infile + + concise = args.concise + + mdir= args.mutantDir + if mdir == None: + mdir = "." if mdir[-1] != "/": mdir += "/" - sdir = "." - try: - sdirpos = args.index("--sourceDir") - except ValueError: - sdirpos = -1 - - if sdirpos != -1: - sdir = args[sdirpos + 1] - args.remove("--sourceDir") - args.remove(sdir) + sdir= args.sourceDir + if sdir == None: + sdir = "." if sdir[-1] != "/": sdir += "/"