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

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


The following commit(s) were added to refs/heads/main by this push:
     new 8a3d60731 Make code gen support empty grams
8a3d60731 is described below

commit 8a3d60731a23800b0e401998136c6cee350ea7d7
Author: John Interrante <[email protected]>
AuthorDate: Mon Nov 20 15:40:44 2023 -0500

    Make code gen support empty grams
    
    Fix the Daffodil C code generator to stop crashing when a schema
    contains an empty grammar object.  Make sure the code gen recognizes
    empty grams instead of crashing when seeing them.
    
    c/DaffodilCCodeGenerator.scala: Add clause to support empty grams.
    
    c/TestDaffodilCExamplesGenerator.scala: Add test which fails or passes
    without or with above fix to verify that fix actually works.
    
    DAFFODIL-2863
---
 .../codegen/c/DaffodilCCodeGenerator.scala         |  3 ++
 .../codegen/c/TestDaffodilCExamplesGenerator.scala | 42 +++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git 
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
 
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
index c5308172b..7bedd2fa5 100644
--- 
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
+++ 
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
@@ -259,6 +259,9 @@ object DaffodilCCodeGenerator
    */
   def generateCode(gram: Gram, cgState: CodeGeneratorState): Unit = {
     gram match {
+      // Skip empty grams
+      case g: Gram if g.isEmpty => noop(g)
+      // Handle non-empty grams
       case g: AlignmentFill => alignmentFillGenerateCode(g, cgState)
       case g: AssertBooleanPrim => noop(g)
       case g: BinaryBoolean => binaryBooleanGenerateCode(g.e, cgState)
diff --git 
a/daffodil-codegen-c/src/test/scala/org/apache/daffodil/codegen/c/TestDaffodilCExamplesGenerator.scala
 
b/daffodil-codegen-c/src/test/scala/org/apache/daffodil/codegen/c/TestDaffodilCExamplesGenerator.scala
index d97c836df..daa484ae0 100644
--- 
a/daffodil-codegen-c/src/test/scala/org/apache/daffodil/codegen/c/TestDaffodilCExamplesGenerator.scala
+++ 
b/daffodil-codegen-c/src/test/scala/org/apache/daffodil/codegen/c/TestDaffodilCExamplesGenerator.scala
@@ -17,6 +17,10 @@
 
 package org.apache.daffodil.codegen.c
 
+import org.apache.daffodil.core.compiler.Compiler
+import org.apache.daffodil.lib.api.TDMLImplementation
+import org.apache.daffodil.lib.util.SchemaUtils
+
 import org.junit.Test
 
 /**
@@ -24,7 +28,8 @@ import org.junit.Test
  * capture call of genCExamples
  */
 class TestDaffodilCExamplesGenerator {
-  // Test added for code coverage and debugging
+
+  // Calls DaffodilCExamplesGenerator for code coverage and debugging
   @Test def test_DaffodilCExamplesGenerator_main(): Unit = {
     // Generate the C examples in a safe place (target/examples)
     val rootDir = if (os.exists(os.pwd / "src")) os.pwd / os.up else os.pwd
@@ -36,4 +41,39 @@ class TestDaffodilCExamplesGenerator {
     val generatedCode = examplesDir / "variablelen" / "generated_code.c"
     assert(os.exists(generatedCode))
   }
+
+  // Checks C code can be generated from a schema with an empty grammar object
+  @Test def test_generateCode(): Unit = {
+    // Define a schema containing an empty grammar object
+    val testSchema = SchemaUtils.dfdlTestSchema(
+      <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+      <dfdl:format representation="binary" ref="GeneralFormat"/>,
+      <xs:element name="foo">
+        <xs:complexType>
+          <xs:choice>
+            <xs:element name="bar" type="xs:int"/>
+            <xs:sequence/>
+          </xs:choice>
+        </xs:complexType>
+      </xs:element>,
+    )
+
+    // Compile the schema into a ProcessorFactory
+    val pf = Compiler().compileNode(testSchema)
+    assert(!pf.isError, pf.getDiagnostics.map(_.getMessage()).mkString("\n"))
+
+    // Get a CodeGenerator from the ProcessorFactory
+    val cg = pf.forLanguage("c")
+    assert(!cg.isError, cg.getDiagnostics.map(_.getMessage()).mkString("\n"))
+
+    // Generate C code into a temporary directory
+    val tempDir: os.Path =
+      os.temp.dir(dir = null, prefix = TDMLImplementation.DaffodilC.toString)
+    cg.generateCode(tempDir.toString)
+    os.remove.all(tempDir)
+
+    // Check the C code was generated successfully
+    assert(!cg.isError, cg.getDiagnostics.map(_.getMessage()).mkString("\n"))
+  }
+
 }

Reply via email to