//----------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All Rights Reserved. // //----------------------------------------------------------------------------- package chalice; import java.io.BufferedReader import java.io.InputStreamReader import java.io.File import java.io.FileWriter import scala.util.parsing.input.Position import scala.util.parsing.input.NoPosition import collection.mutable.ListBuffer object Chalice { /** * Reporting options */ private[chalice] var vsMode = false; /** * Translation options */ // level 0 or below: no defaults // level 1: unfold predicates with receiver this in pre and postconditions // level 2: unfold predicates and functions with receiver this in pre and postconditions // level 3 or above: level 2 + autoMagic\ private[chalice] var defaults = 0: Int; private[chalice] var autoFold = false: Boolean; private[chalice] var checkLeaks = false: Boolean; private[chalice] var autoMagic = false: Boolean; private[chalice] var skipDeadlockChecks = false: Boolean; private[chalice] var skipTermination = false: Boolean; private[chalice] var noFreeAssume = false: Boolean; // percentageSupport 0: use multiplication directly // percentageSupport 1: fix Permission$denominator as constant (possibly unsound for small values of the constant?) // percentageSupport 2: use function and provide some (redundant) axioms // percentageSupport 3: use an uninterpreted function and axiomatize the properties of multiplication private[chalice] var percentageSupport = 2; private[chalice] var smoke = false; private[chalice] var smokeAll = false; def main(args: Array[String]): Unit = { var boogiePath = "C:\\boogie\\Binaries\\Boogie.exe" val inputs = new ListBuffer[String]() var printProgram = false var doTypecheck = true var doTranslate = true var boogieArgs = " "; var gen = false; var showFullStackTrace = false // help texts and closures for boolean command line options // closures should be idempotent import scala.collection.immutable.ListMap val options = ListMap[String,(() => Unit, String)]( "help" -> ( {() => }, "print this message"), "print" -> ( {() => printProgram = true}, "print intermediate versions of the Chalice program"), "noTranslate" -> ( {() => doTranslate = false}, "do not translate the program to Boogie (only parse and typecheck)"), "noTypecheck"-> ( {() => doTypecheck = false}, "do not typecheck the program (only parse). Implies /noTranslate."), "vs" -> ( {() => vsMode = true}, "Microsoft Visual Studio mode (special error reporting for Visual Studio; requires an existing, writable directory at C:\\tmp)"), "checkLeaks" -> ( {() => checkLeaks = true}, "(no description available)"), "noDeadlockChecks" -> ( {() => skipDeadlockChecks = true}, "skip all lock ordering checks"), "noTermination" -> ( {() => skipTermination = true}, "skip the termination checks for functions"), "defaults" -> ( {() => defaults = 3}, null), "gen" -> ( {() => gen = true}, "generate C# code from the Chalice program"), "autoFold" -> ( {() => autoFold = true}, "automatically fold predicates whenever necessary"), "autoMagic" -> ( {() => autoMagic = true}, "automatically try to infer accessibility predicates and non-nullness checks in specifications"), "noFreeAssume" -> ( {() => noFreeAssume = true}, "(no description available)"), "showFullStackTrace" -> ( {() => showFullStackTrace = true}, "show the full stack trace if an exception is encountered"), "smoke" -> ( {() => smoke = true}, "smoke testing; try to find unreachable code, preconditions/invariants/predicates that are equivalent to false and assumptions that introduce contradictions, by trying to prove 'false' at various positions."), "smokeAll" -> ( {() => smokeAll = true; smoke = true}, "aggressive smoke testing; try to prove false after every statement.") ) // help text for options with arguments val nonBooleanOptions = ListMap( "boogie:" -> "use the executable of Boogie at ", "defaults:" -> ("defaults to reduce specification overhead\n"+ "level 0 or below: no defaults\n"+ "level 1: unfold predicates with receiver this in pre and postconditions\n"+ "level 2: unfold predicates and functions with receiver this in pre and postconditions\n"+ "level 3 or above: level 2 + autoMagic"), "percentageSupport:" -> ("determin how percentage permissions are translated to Boogie\n"+ "0: use multiplication directly (can cause performance problems)\n"+ "1: fix Permission$denominator as constant (possibly unsound)\n"+ "2: use a function and provide some (redundant) axioms\n"+ "3: use an uninterpreted function and axiomatize the properties of multiplication"), "boogieOpt:, /bo:" -> "specify additional Boogie options" ) lazy val help = { val maxLength = math.min((nonBooleanOptions.keys++options.keys).map(s => s.length+1).max,14) val printOptionHelp = (param: String, help: String) => "\n /" + param + (" "*(maxLength-param.length-1)) + ": " + help.split("\n").map(h => " "*(maxLength+2+2)+wordWrap(h, 80-2-2-math.max(maxLength,param.length+1)," "*(maxLength+2+2))).mkString("\n").substring(maxLength+2+2) "Chalice concurrent program verifier.\nUsage: chalice [option] +\n"+ " where