diff options
| author | Schuyler Eldridge | 2018-10-24 14:36:05 -0400 |
|---|---|---|
| committer | Schuyler Eldridge | 2018-10-24 18:58:02 -0400 |
| commit | 3d3bc2fb9cf602f289852267db1f2193893bf1e7 (patch) | |
| tree | bf9efdcd7e1c8fb50175686810531be07747e8a9 /src | |
| parent | 69f9060f1439dae88146e850208148caf12bb059 (diff) | |
Better error message on missing BlackBox resource
This wraps interactions with a BlackBox resource file such that a
FileNotFoundException are wrapped in a BlackBoxNotFoundException and
rethrown. This provides a better, verbose error message to the user and avoids a
FileNotFoundException showing up as an internal FIRRTL error.
This adds tests that the expected exception is thrown for both
BlackBoxResourceAnno and BlackBoxResourceAnno.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/transforms/BlackBoxSourceHelper.scala | 26 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/transforms/BlacklBoxSourceHelperSpec.scala | 21 |
2 files changed, 41 insertions, 6 deletions
diff --git a/src/main/scala/firrtl/transforms/BlackBoxSourceHelper.scala b/src/main/scala/firrtl/transforms/BlackBoxSourceHelper.scala index bf419840..31c2a04b 100644 --- a/src/main/scala/firrtl/transforms/BlackBoxSourceHelper.scala +++ b/src/main/scala/firrtl/transforms/BlackBoxSourceHelper.scala @@ -35,6 +35,13 @@ case class BlackBoxPathAnno(target: ModuleName, path: String) extends BlackBoxHe override def serialize: String = s"path\n$path" } +/** Exception indicating that a blackbox wasn't found + * @param fileName the name of the BlackBox file (only used for error message generation) + * @param e an underlying exception that generated this + */ +class BlackBoxNotFoundException(fileName: String, e: Throwable = null) extends FIRRTLException( + s"BlackBox '$fileName' not found. Did you misspell it? Is it in src/{main,test}/resources?", e) + /** Handle source for Verilog ExtModules (BlackBoxes) * * This transform handles the moving of Verilog source for black boxes into the @@ -70,6 +77,7 @@ class BlackBoxSourceHelper extends firrtl.Transform { * @note the state is not changed by this transform * @param state Input Firrtl AST * @return A transformed Firrtl AST + * @throws BlackBoxNotFoundException if a Verilog source cannot be found */ override def execute(state: CircuitState): CircuitState = { val (annos, targetDir) = collectAnnos(state.annotations) @@ -82,7 +90,7 @@ class BlackBoxSourceHelper extends firrtl.Transform { val fromFile = new File(path) val toFile = new File(targetDir, fileName) - val inputStream = new FileInputStream(fromFile).getChannel + val inputStream = BlackBoxSourceHelper.safeFile(fromFile.toString)(new FileInputStream(fromFile).getChannel) val outputStream = new FileOutputStream(toFile).getChannel outputStream.transferFrom(inputStream, 0, Long.MaxValue) @@ -105,6 +113,16 @@ class BlackBoxSourceHelper extends firrtl.Transform { } object BlackBoxSourceHelper { + /** Safely access a file converting [[FileNotFoundException]]s and [[NullPointerException]]s into + * [[BlackBoxNotFoundException]]s + * @param fileName the name of the file to be accessed (only used for error message generation) + * @param code some code to run + */ + private def safeFile[A](fileName: String)(code: => A) = try { code } catch { + case e@ (_: FileNotFoundException | _: NullPointerException) => throw new BlackBoxNotFoundException(fileName, e) + case t: Throwable => throw t + } + /** * finds the named resource and writes into the directory * @param name the name of the resource @@ -122,14 +140,12 @@ object BlackBoxSourceHelper { * finds the named resource and writes into the directory * @param name the name of the resource * @param file the file to write it into + * @throws BlackBoxNotFoundException if the requested resource does not exist */ def copyResourceToFile(name: String, file: File) { val in = getClass.getResourceAsStream(name) - if (in == null) { - throw new FileNotFoundException(s"Resource '$name'") - } val out = new FileOutputStream(file) - Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write) + safeFile(name)(Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write)) out.close() } diff --git a/src/test/scala/firrtlTests/transforms/BlacklBoxSourceHelperSpec.scala b/src/test/scala/firrtlTests/transforms/BlacklBoxSourceHelperSpec.scala index 7daebf21..c6918624 100644 --- a/src/test/scala/firrtlTests/transforms/BlacklBoxSourceHelperSpec.scala +++ b/src/test/scala/firrtlTests/transforms/BlacklBoxSourceHelperSpec.scala @@ -105,5 +105,24 @@ class BlacklBoxSourceHelperTransformSpec extends LowTransformSpec { val verilogCompiler = new VerilogEmitter verilogCompiler.transforms.map { x => x.getClass } should contain (classOf[BlackBoxSourceHelper]) } -} + behavior of "BlackBox resources that do not exist" + + it should "provide a useful error message for BlackBoxResourceAnno" in { + val annos = Seq( BlackBoxTargetDirAnno("test_run_dir"), + BlackBoxResourceAnno(moduleName, "/blackboxes/IDontExist.v") ) + + (the [BlackBoxNotFoundException] thrownBy { execute(input, "", annos) }) + .getMessage should include ("Did you misspell it?") + } + + it should "provide a useful error message for BlackBoxPathAnno" in { + val absPath = new java.io.File("src/test/resources/blackboxes/IDontExist.v").getCanonicalPath + val annos = Seq( BlackBoxTargetDirAnno("test_run_dir"), + BlackBoxPathAnno(moduleName, absPath) ) + + (the [BlackBoxNotFoundException] thrownBy { execute(input, "", annos) }) + .getMessage should include ("Did you misspell it?") + } + +} |
