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 <[email protected]> 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) } }
