aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchuyler Eldridge2018-10-24 14:36:05 -0400
committerSchuyler Eldridge2018-10-24 18:58:02 -0400
commit3d3bc2fb9cf602f289852267db1f2193893bf1e7 (patch)
treebf9efdcd7e1c8fb50175686810531be07747e8a9 /src
parent69f9060f1439dae88146e850208148caf12bb059 (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.scala26
-rw-r--r--src/test/scala/firrtlTests/transforms/BlacklBoxSourceHelperSpec.scala21
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?")
+ }
+
+}