You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ji...@apache.org on 2021/03/30 15:15:18 UTC

[daffodil] 02/09: Reorganize C source files

This is an automated email from the ASF dual-hosted git repository.

jinterrante pushed a commit to branch runtime2-2202
in repository https://gitbox.apache.org/repos/asf/daffodil.git

commit daa4f46475bbf112b68dbb2d2c0bb4aecb64d088
Author: John Interrante <in...@research.ge.com>
AuthorDate: Sun Dec 6 20:39:38 2020 -0500

    Reorganize C source files
    
    As requested on the dev list, reoganize C source files into two
    distinct groups.  Separate these groups from each other by moving them
    into two subdirectories, "c/libcli" and "c/libruntime".
    
    In build.sbt, ensure C compiler test-builds these subdirectories by
    doing a recursive glob on "c" and "examples".
    
    In TestCLIGenerateC.scala, update tests to keep them passing (some
    tests were checking the location and existence of the
    "generated_code.c" file).
    
    In resources/c, move the C source files into libcli and libruntime.
    
    In CodeGenerator.scala, make CodeGenerator write generated_code.[ch]
    into libruntime, find C source files in any subdirectory, and compile
    them with two include flags (one for each subdirectory).
    
    In TestCodeGenerator.scala, make all tests remove temporary output dir
    after using it, and update tests to keep them passing (some tests were
    checking the location and existence of the "generated_code.c" file).
---
 build.sbt                                          |  7 ++--
 .../daffodil/generating/TestCLIGenerateC.scala     | 24 +++++++-----
 .../main/resources/c/{ => libcli}/daffodil_argp.c  |  0
 .../main/resources/c/{ => libcli}/daffodil_argp.h  |  0
 .../main/resources/c/{ => libcli}/daffodil_main.c  |  0
 .../src/main/resources/c/{ => libcli}/stack.c      |  0
 .../src/main/resources/c/{ => libcli}/stack.h      |  0
 .../src/main/resources/c/{ => libcli}/xml_reader.c |  0
 .../src/main/resources/c/{ => libcli}/xml_reader.h |  0
 .../src/main/resources/c/{ => libcli}/xml_writer.c |  0
 .../src/main/resources/c/{ => libcli}/xml_writer.h |  0
 .../main/resources/c/{ => libruntime}/infoset.c    |  0
 .../main/resources/c/{ => libruntime}/infoset.h    |  0
 .../apache/daffodil/runtime2/CodeGenerator.scala   |  9 +++--
 .../daffodil/runtime2/TestCodeGenerator.scala      | 44 +++++++++++-----------
 15 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/build.sbt b/build.sbt
index ed2beb0..489682b 100644
--- a/build.sbt
+++ b/build.sbt
@@ -71,13 +71,14 @@ lazy val runtime2         = Project("daffodil-runtime2", file("daffodil-runtime2
                                 Compile / ccTargets := ListSet(runtime2CFiles),
                                 Compile / cSources  := Map(
                                   runtime2CFiles -> (
-                                    ((Compile / resourceDirectory).value / "c" * GlobFilter("*.c")).get() ++
-                                    ((Compile / resourceDirectory).value / "examples" * GlobFilter("*.c")).get()
+                                    ((Compile / resourceDirectory).value / "c" ** GlobFilter("*.c")).get() ++
+                                    ((Compile / resourceDirectory).value / "examples" ** GlobFilter("*.c")).get()
                                   )
                                 ),
                                 Compile / cIncludeDirectories := Map(
                                   runtime2CFiles -> Seq(
-                                    (Compile / resourceDirectory).value / "c",
+                                    (Compile / resourceDirectory).value / "c" / "libcli",
+                                    (Compile / resourceDirectory).value / "c" / "libruntime",
                                     (Compile / resourceDirectory).value / "examples"
                                   )
                                 ),
diff --git a/daffodil-cli/src/it/scala/org/apache/daffodil/generating/TestCLIGenerateC.scala b/daffodil-cli/src/it/scala/org/apache/daffodil/generating/TestCLIGenerateC.scala
index 9b5c9b3..f4e5cdc 100644
--- a/daffodil-cli/src/it/scala/org/apache/daffodil/generating/TestCLIGenerateC.scala
+++ b/daffodil-cli/src/it/scala/org/apache/daffodil/generating/TestCLIGenerateC.scala
@@ -17,22 +17,26 @@
 
 package org.apache.daffodil.generating
 
-import org.junit.Test
-import org.junit.Before
-import org.junit.After
-import org.apache.daffodil.CLI.Util
 import net.sf.expectit.matcher.Matchers.contains
 import net.sf.expectit.matcher.Matchers.eof
+import org.apache.daffodil.CLI.Util
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
 
+/**
+ * Checks that we can run the "daffodil generate c" subcommand with
+ * various options and get expected outputs.
+ */
 class TestCLIGenerateC {
 
   val daffodil: String = Util.binPath
-  val outputDir: os.Path = os.pwd/"generate_tmp"
+  var outputDir: os.Path = _
   lazy val schemaFile: String = if (Util.isWindows) Util.cmdConvert(sf) else sf
   val sf: String = Util.daffodilPath("daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/TestRuntime2.dfdl.xsd")
 
   @Before def before(): Unit = {
-    os.remove.all(outputDir)
+    outputDir = os.temp.dir()
   }
 
   @After def after(): Unit = {
@@ -52,7 +56,7 @@ class TestCLIGenerateC {
       shell.close()
     }
 
-    assert(os.exists(outputDir/"c"/"generated_code.c"))
+    assert(os.exists(outputDir/"c"/"libruntime"/"generated_code.c"))
   }
 
   @Test def test_CLI_Generate_noC_error(): Unit = {
@@ -130,7 +134,7 @@ class TestCLIGenerateC {
       shell.close()
     }
 
-    assert(os.exists(outputDir/"c"/"generated_code.c"))
+    assert(os.exists(outputDir/"c"/"libruntime"/"generated_code.c"))
   }
 
   @Test def test_CLI_Generate_root(): Unit = {
@@ -146,7 +150,7 @@ class TestCLIGenerateC {
       shell.close()
     }
 
-    assert(os.exists(outputDir/"c"/"generated_code.c"))
+    assert(os.exists(outputDir/"c"/"libruntime"/"generated_code.c"))
   }
 
   @Test def test_CLI_Generate_root_error(): Unit = {
@@ -193,6 +197,6 @@ class TestCLIGenerateC {
       shell.close()
     }
 
-    assert(os.exists(outputDir/"c"/"generated_code.c"))
+    assert(os.exists(outputDir/"c"/"libruntime"/"generated_code.c"))
   }
 }
diff --git a/daffodil-runtime2/src/main/resources/c/daffodil_argp.c b/daffodil-runtime2/src/main/resources/c/libcli/daffodil_argp.c
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/daffodil_argp.c
rename to daffodil-runtime2/src/main/resources/c/libcli/daffodil_argp.c
diff --git a/daffodil-runtime2/src/main/resources/c/daffodil_argp.h b/daffodil-runtime2/src/main/resources/c/libcli/daffodil_argp.h
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/daffodil_argp.h
rename to daffodil-runtime2/src/main/resources/c/libcli/daffodil_argp.h
diff --git a/daffodil-runtime2/src/main/resources/c/daffodil_main.c b/daffodil-runtime2/src/main/resources/c/libcli/daffodil_main.c
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/daffodil_main.c
rename to daffodil-runtime2/src/main/resources/c/libcli/daffodil_main.c
diff --git a/daffodil-runtime2/src/main/resources/c/stack.c b/daffodil-runtime2/src/main/resources/c/libcli/stack.c
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/stack.c
rename to daffodil-runtime2/src/main/resources/c/libcli/stack.c
diff --git a/daffodil-runtime2/src/main/resources/c/stack.h b/daffodil-runtime2/src/main/resources/c/libcli/stack.h
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/stack.h
rename to daffodil-runtime2/src/main/resources/c/libcli/stack.h
diff --git a/daffodil-runtime2/src/main/resources/c/xml_reader.c b/daffodil-runtime2/src/main/resources/c/libcli/xml_reader.c
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/xml_reader.c
rename to daffodil-runtime2/src/main/resources/c/libcli/xml_reader.c
diff --git a/daffodil-runtime2/src/main/resources/c/xml_reader.h b/daffodil-runtime2/src/main/resources/c/libcli/xml_reader.h
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/xml_reader.h
rename to daffodil-runtime2/src/main/resources/c/libcli/xml_reader.h
diff --git a/daffodil-runtime2/src/main/resources/c/xml_writer.c b/daffodil-runtime2/src/main/resources/c/libcli/xml_writer.c
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/xml_writer.c
rename to daffodil-runtime2/src/main/resources/c/libcli/xml_writer.c
diff --git a/daffodil-runtime2/src/main/resources/c/xml_writer.h b/daffodil-runtime2/src/main/resources/c/libcli/xml_writer.h
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/xml_writer.h
rename to daffodil-runtime2/src/main/resources/c/libcli/xml_writer.h
diff --git a/daffodil-runtime2/src/main/resources/c/infoset.c b/daffodil-runtime2/src/main/resources/c/libruntime/infoset.c
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/infoset.c
rename to daffodil-runtime2/src/main/resources/c/libruntime/infoset.c
diff --git a/daffodil-runtime2/src/main/resources/c/infoset.h b/daffodil-runtime2/src/main/resources/c/libruntime/infoset.h
similarity index 100%
rename from daffodil-runtime2/src/main/resources/c/infoset.h
rename to daffodil-runtime2/src/main/resources/c/libruntime/infoset.h
diff --git a/daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/CodeGenerator.scala b/daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/CodeGenerator.scala
index 6dcc19d..4f2a776 100644
--- a/daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/CodeGenerator.scala
+++ b/daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/CodeGenerator.scala
@@ -77,8 +77,8 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator {
     val codeFileText = codeGeneratorState.generateCodeFile(rootElementName)
 
     // Write the generated C code into our code subdirectory
-    val generatedCodeHeader = codeDir/"generated_code.h"
-    val generatedCodeFile = codeDir/"generated_code.c"
+    val generatedCodeHeader = codeDir/"libruntime"/"generated_code.h"
+    val generatedCodeFile = codeDir/"libruntime"/"generated_code.c"
     os.write(generatedCodeHeader, codeHeaderText)
     os.write(generatedCodeFile, codeFileText)
 
@@ -96,7 +96,7 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator {
     try {
       // Assemble the compiler's command line arguments
       val compiler = pickCompiler
-      val files = os.list(codeDir).filter(_.ext == "c")
+      val files = os.walk(codeDir).filter(_.ext == "c")
       val libs = Seq("-lmxml", if (isWindows) "-largp" else "-lpthread")
 
       // Call the compiler if it was found.  We run the compiler in the output directory,
@@ -105,7 +105,8 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator {
       // We can't let "zig_cache" be put into "c" because we always remove and re-generate
       // everything in "c" from scratch.
       if (compiler.nonEmpty) {
-        val result = os.proc(compiler, "-I", codeDir, files, libs, "-o", exe).call(cwd = outputDir, stderr = os.Pipe)
+        val result = os.proc(compiler, "-I", codeDir/"libcli", "-I", codeDir/"libruntime",
+          files, libs, "-o", exe).call(cwd = outputDir, stderr = os.Pipe)
 
         // Report any compiler output as a warning
         if (result.out.text.nonEmpty || result.err.text.nonEmpty) {
diff --git a/daffodil-runtime2/src/test/scala/org/apache/daffodil/runtime2/TestCodeGenerator.scala b/daffodil-runtime2/src/test/scala/org/apache/daffodil/runtime2/TestCodeGenerator.scala
index 19d5682..f64d6b9 100644
--- a/daffodil-runtime2/src/test/scala/org/apache/daffodil/runtime2/TestCodeGenerator.scala
+++ b/daffodil-runtime2/src/test/scala/org/apache/daffodil/runtime2/TestCodeGenerator.scala
@@ -20,24 +20,36 @@ package org.apache.daffodil.runtime2
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.nio.channels.Channels
-
 import org.apache.daffodil.Implicits.intercept
 import org.apache.daffodil.compiler.Compiler
 import org.apache.daffodil.util.Misc
 import org.apache.daffodil.util.SchemaUtils
 import org.apache.daffodil.util.TestUtils
+import org.junit.After
 import org.junit.Assert.assertArrayEquals
+import org.junit.Before
 import org.junit.Test
 
 /**
  * Checks that we can create a [[CodeGenerator]] and call its methods.
  * The value of this test is to debug the call path from [[Compiler]]
- * to [[CodeGenerator]] for one very simple DFDL schema.  Running TDML
- * tests with daffodil-runtime2 is a more effective way to test the
- * functionality of CodeGenerator's generated code for as many DFDL
- * schemas as you could want.
+ * to [[CodeGenerator]] for a single test DFDL schema.  Running TDML
+ * tests with daffodil-runtime2 is a more effective way to check that
+ * CodeGenerator can generate appropriate code for as many DFDL schemas
+ * as you could want.
  */
 class TestCodeGenerator {
+  // Ensure all tests remove outputDir after using it
+  var outputDir: os.Path = _
+
+  @Before def before(): Unit = {
+    outputDir = os.temp.dir()
+  }
+
+  @After def after(): Unit = {
+    os.remove.all(outputDir)
+  }
+
   // Define a simple DFDL test schema for debugging our code path
   private val testSchema = SchemaUtils.dfdlTestSchema(
       <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
@@ -78,35 +90,29 @@ class TestCodeGenerator {
     val cg = pf.forLanguage("c")
 
     // Generate code from the test schema successfully
-    val outputDir = cg.generateCode(None, "./generateCode_tmp")
+    val outputDir = cg.generateCode(None, s"${this.outputDir}")
     assert(!cg.isError, cg.getDiagnostics.map(_.getMessage()).mkString("\n"))
     assert(os.exists(outputDir))
-    assert(os.exists(outputDir/"c"/"generated_code.c"))
-
-    // Remove the generated code
-    os.remove.all(outputDir)
+    assert(os.exists(outputDir/"c"/"libruntime"/"generated_code.c"))
   }
 
   @Test def test_compileCode_success(): Unit = {
     // Create a CodeGenerator and generate code from the test schema
     val pf = Compiler().compileNode(testSchema)
     val cg = pf.forLanguage("c")
-    val outputDir = cg.generateCode(None, "./compileCode_tmp")
+    val outputDir = cg.generateCode(None, s"${this.outputDir}")
 
     // Compile the generated code into an executable successfully
     val executable = cg.compileCode(outputDir)
     assert(!cg.isError, cg.getDiagnostics.map(_.getMessage()).mkString("\n"))
     assert(os.exists(executable))
-
-    // Remove the generated code
-    os.remove.all(outputDir)
   }
 
   @Test def test_parse_success(): Unit = {
     // Compile the test schema into a C executable
     val pf = Compiler().compileNode(testSchema)
     val cg = pf.forLanguage("c")
-    val outputDir = cg.generateCode(None, "./parse_tmp")
+    val outputDir = cg.generateCode(None, s"${this.outputDir}")
     val executable = cg.compileCode(outputDir)
 
     // Create a Runtime2DataProcessor and parse a binary int32 number successfully
@@ -117,16 +123,13 @@ class TestCodeGenerator {
     assert(!pr.isError && pf.getDiagnostics.isEmpty, pr.getDiagnostics.map(_.getMessage()).mkString("\n"))
     val expected = <e1><x>5</x></e1>
     TestUtils.assertEqualsXMLElements(expected, pr.infosetAsXML)
-
-    // Remove the generated code
-    os.remove.all(outputDir)
   }
 
   @Test def test_unparse_success(): Unit = {
     // Compile the test schema into a C executable
     val pf = Compiler().compileNode(testSchema)
     val cg = pf.forLanguage("c")
-    val outputDir = cg.generateCode(None, "./unparse_tmp")
+    val outputDir = cg.generateCode(None, s"${this.outputDir}")
     val executable = cg.compileCode(outputDir)
 
     // Create a Runtime2DataProcessor and unparse a binary int32 number successfully
@@ -137,8 +140,5 @@ class TestCodeGenerator {
     assert(!pr.isError && pf.getDiagnostics.isEmpty, pr.getDiagnostics.map(_.getMessage()).mkString("\n"))
     val expected = Misc.hex2Bytes("00000005")
     assertArrayEquals(expected, output.toByteArray)
-
-    // Remove the generated code
-    os.remove.all(outputDir)
   }
 }