@@ -64,8 +64,6 @@ trait BoogieInterface {
6464 " /proverOpt:O:smt.qi.max_multi_patterns=1000" ,
6565 s " /proverOpt:PROVER_PATH= $z3Path" )
6666
67- val timeoutErrorName = " TIMEOUT"
68-
6967 /** The (resolved) path where Boogie is supposed to be located. */
7068 def boogiePath : String
7169
@@ -79,7 +77,7 @@ trait BoogieInterface {
7977 // Hence, for now we have to trust Boogie to manage its own sub-processes.
8078 // private var _z3ProcessStream: Option[LazyList[ProcessHandle]] = None
8179
82- var errormap : Map [Int , AbstractError ] = Map ()
80+ var errormap : Map [Int , VerificationError ] = Map ()
8381 var models : collection.mutable.ListBuffer [String ] = new collection.mutable.ListBuffer [String ]
8482 def invokeBoogie (program : Program , options : Seq [String ], timeout : Option [Int ]): (String ,VerificationResult ) = {
8583 // find all errors and assign everyone a unique id
@@ -90,33 +88,35 @@ trait BoogieInterface {
9088 }
9189
9290 // invoke Boogie
93- val output = run(program.toString, defaultOptions ++ options, timeout)
94- // parse the output
95- parse(output, timeout) match {
96- case (version,Nil ) =>
97- (version,Success )
98- case (version,errorIds) => {
99- val errors = (0 until errorIds.length).map(i => {
100- val id = errorIds(i)
101- val error = errormap.get(id).get
102- if (models.nonEmpty) {
103- error match {
104- case e : AbstractVerificationError =>
105- e.failureContexts = Seq (FailureContextImpl (Some (SimpleCounterexample (Model (models(i))))))
106- case _ =>
107- }
91+ val optOutput = run(program.toString, defaultOptions ++ options, timeout)
92+ optOutput match {
93+ case None =>
94+ // Timeout
95+ (null , Failure (Seq (TimeoutOccurred (timeout.get, " second(s)" ))))
96+ case Some (output) =>
97+ // parse the output
98+ parse(output) match {
99+ case (version, Nil ) =>
100+ (version, Success )
101+ case (version, errorIds) => {
102+ val errors = (0 until errorIds.length).map(i => {
103+ val id = errorIds(i)
104+ val error = errormap.get(id).get
105+ if (models.nonEmpty) {
106+ error.failureContexts = Seq (FailureContextImpl (Some (SimpleCounterexample (Model (models(i))))))
107+ }
108+ error
109+ })
110+ (version, Failure (errors))
108111 }
109- error
110- })
111- (version,Failure (errors))
112- }
112+ }
113113 }
114114 }
115115
116116 /**
117117 * Parse the output of Boogie. Returns a pair of the detected version number and a sequence of error identifiers.
118118 */
119- private def parse (output : String , timeout : Option [ Int ] ): (String ,Seq [Int ]) = {
119+ private def parse (output : String ): (String ,Seq [Int ]) = {
120120 val LogoPattern = " Boogie program verifier version ([0-9.]+),.*" .r
121121 val SummaryPattern = " Boogie program verifier finished with ([0-9]+) verified, ([0-9]+) error.*" .r
122122 val ErrorPattern = " .+ \\ [([0-9]+)\\ ]" .r
@@ -131,13 +131,6 @@ trait BoogieInterface {
131131 errormap += (otherErrId -> internalError)
132132 }
133133
134- def reportTimeout () = {
135- otherErrId -= 1
136- errors += otherErrId
137- val timeoutError = TimeoutOccurred (timeout.get, " second(s)" )
138- errormap += (otherErrId -> timeoutError)
139- }
140-
141134 var parsingModel : Option [StringBuilder ] = None
142135 var stateInitialBlock = false
143136 for (l <- output.linesIterator) {
@@ -161,7 +154,6 @@ trait BoogieInterface {
161154 case SummaryPattern (v, e) =>
162155 if (e.toInt != errors.size) unexpected(s " Found ${errors.size} errors, but there should be $e. The output was: $output" )
163156 case " " => // ignore empty lines
164- case `timeoutErrorName` if timeout.isDefined => reportTimeout()
165157 case _ =>
166158 unexpected(s " Found an unparsable output from Boogie: $l" )
167159 }
@@ -171,6 +163,7 @@ trait BoogieInterface {
171163
172164 /**
173165 * Invoke Boogie.
166+ * Returns None if there was a timeout, otherwise the Boogie output.
174167 */
175168 private def run (input : String , options : Seq [String ], timeout : Option [Int ]) = {
176169 reporter report BackendSubProcessReport (" carbon" , boogiePath, BeforeInputSent , _boogieProcessPid)
@@ -233,7 +226,10 @@ trait BoogieInterface {
233226 val normalOutput = inputConsumer.result.get
234227 reporter report BackendSubProcessReport (" carbon" , boogiePath, OnExit , _boogieProcessPid)
235228
236- errorOutput + normalOutput + (if (boogieTimeout) timeoutErrorName else " " )
229+ if (boogieTimeout)
230+ None
231+ else
232+ Some (errorOutput + normalOutput)
237233 } catch {
238234 case _ : NoSuchElementException => sys.error(" Could not retrieve output from Boogie" )
239235 }
0 commit comments