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/11/04 13:03:04 UTC

[daffodil] branch main updated: Raise minimum C level to ISO C11 with GNU extensions

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 4fd08c6  Raise minimum C level to ISO C11 with GNU extensions
4fd08c6 is described below

commit 4fd08c65ccbc88334b4be010b4258bec61e1435f
Author: John Interrante <in...@research.ge.com>
AuthorDate: Wed Nov 3 11:42:45 2021 -0400

    Raise minimum C level to ISO C11 with GNU extensions
    
    Fix pedantic warning "ISO C99 doesn't support unnamed structs/unions"
    found when compiling nested.dfdl.xsd's NestedUnion example with
    current Makefile's CFLAGS.  Installed centos7 vagrant box and verified
    that both gcc and clang support "-Wall Wextra -Wpedantic -std=gnu11"
    all the way back to gcc-4 and clang-3 on CentOS 7.  Therefore, will
    raise runtime2's minimum C language support level to ISO C11 with GNU
    extensions and make all the places where Daffodil calls the C compiler
    pass -std=gnu11 to the C compiler to compile code with the same
    minimum C level.  ISO C11 also allows "for (" loops to define loop
    variables in place so we can make that change too.
    
    build.sbt - Change cFlags to use "-Wpendantic -std=gnu11" instead of
    "-pedantic -std=gnu99".
    
    Makefile - Change CFLAGS to use "-Wpedantic -std=gnu11" instead of
    "-pedantic -std=gnu99".  Slightly improve Makefile comments' step by
    step instructions as well.
    
    daffodil_getopt.c, xml_reader.c, xml_writer.c, errors.c, infoset.c -
    Define loop variables in place within "for (" loops.
    
    CodeGenerator.scala - Pass "-std=gnu11" to C compiler.  Now all places
    that call the C compiler will compile with the same minimum C level.
    
    NestedUnion/generated_code.[ch] - Replace with re-generated code.
    These files are manually updated and their only purpose is to display
    how the generated code changes as changes are made to runtime2 over
    time.
    
    DAFFODIL-2578
---
 build.sbt                                          |  2 +-
 .../org/apache/daffodil/runtime2/c/Makefile        | 46 +++++++++++-----------
 .../daffodil/runtime2/c/libcli/daffodil_getopt.c   |  3 +-
 .../apache/daffodil/runtime2/c/libcli/xml_reader.c |  3 +-
 .../apache/daffodil/runtime2/c/libcli/xml_writer.c |  3 +-
 .../apache/daffodil/runtime2/c/libruntime/errors.c |  3 +-
 .../daffodil/runtime2/c/libruntime/infoset.c       |  3 +-
 .../apache/daffodil/runtime2/CodeGenerator.scala   |  4 +-
 .../runtime2/examples/NestedUnion/generated_code.c | 25 ++++++------
 .../runtime2/examples/NestedUnion/generated_code.h |  6 ++-
 10 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/build.sbt b/build.sbt
index 0558960..3191d4e 100644
--- a/build.sbt
+++ b/build.sbt
@@ -86,7 +86,7 @@ lazy val runtime2         = Project("daffodil-runtime2", file("daffodil-runtime2
                                     (Compile / resourceDirectory).value / "org" / "apache" / "daffodil" / "runtime2" / "examples"
                                   )
                                 ),
-                                Compile / cFlags := (Compile / cFlags).value.withDefaultValue(Seq("-Wall", "-Wextra", "-pedantic", "-std=gnu99"))
+                                Compile / cFlags := (Compile / cFlags).value.withDefaultValue(Seq("-Wall", "-Wextra", "-Wpedantic", "-std=gnu11"))
                               )
 
 lazy val core             = Project("daffodil-core", file("daffodil-core")).configs(IntegrationTest)
diff --git a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/Makefile b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/Makefile
index 0f9f24d..14c442d 100644
--- a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/Makefile
+++ b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/Makefile
@@ -14,23 +14,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Step 0: You will need to install the Mini-XML library and xmldiff.
-# Here's how to install both packages on Ubuntu 20.04 (first-time
-# setup only):
+# Step 0: Install the Mini-XML library and xmldiff (first time setup
+# only).  Here's the command to install both packages on Ubuntu.
 
 # $ sudo apt install libmxml-dev xmldiff
 
-# Step 1: Copy your test data files here and either rename them to
-# parse.dat and unparse.xml or set PARSE_DAT and UNPARSE_XML.
-
-# $ cp ../ex_nums_parse.dat parse.dat
-# $ cp ../ex_nums_unparse_runtime2.xml unparse.xml
-
-PARSE_DAT = parse.dat
-UNPARSE_XML = unparse.xml
-
-# Step 2: Compile the C source files into an executable program which
-# can run the parse and unparse checks (e.g., .dat <-> .xml).
+# Step 1: Compile the C source files into an executable program which
+# can run the parse and unparse checks (e.g., .dat <-> .xml).  Just
+# run make with no arguments unless you want to override CC or CFLAGS.
 
 # $ make
 
@@ -38,32 +29,41 @@ PROGRAM = ./daffodil
 HEADERS = libcli/*.h libruntime/*.h
 SOURCES = libcli/*.c libruntime/*.c
 INCLUDES = -Ilibcli -Ilibruntime
-CFLAGS = -g -Wall -Wextra -pedantic -std=gnu99
+CFLAGS = -g -Wall -Wextra -Wpedantic -std=gnu11
 LIBS = -lmxml
 
 $(PROGRAM): $(HEADERS) $(SOURCES)
 	$(CC) $(CFLAGS) $(INCLUDES) $(SOURCES) $(LIBS) -o $(PROGRAM)
 
-# Step 3: Run the executable on the test data files and check that the
-# new temp data files match the original test data files.
+# Step 2: Copy your test files here and rename them to parse.dat and
+# unparse.xml or else edit PARSE_DAT and UNPARSE_XML below.
+
+# $ cp ../ex_nums_parse.dat parse.dat
+# $ cp ../ex_nums_unparse_runtime2.xml unparse.xml
+
+PARSE_DAT = parse.dat
+UNPARSE_XML = unparse.xml
+
+# Step 3: Run the executable on the test files and check that the new
+# scratch files match the original test files.
 
 # $ make check
 
 check: parse-check unparse-check
 
 parse-check: $(PROGRAM)
-	$(PROGRAM) -o temp_$(UNPARSE_XML) parse $(PARSE_DAT)
-	xmldiff $(UNPARSE_XML) temp_$(UNPARSE_XML)
+	$(PROGRAM) -o tmp_$(UNPARSE_XML) parse $(PARSE_DAT)
+	xmldiff $(UNPARSE_XML) tmp_$(UNPARSE_XML)
 
 unparse-check: $(PROGRAM)
-	$(PROGRAM) -o temp_$(PARSE_DAT) unparse $(UNPARSE_XML)
-	diff $(PARSE_DAT) temp_$(PARSE_DAT)
+	$(PROGRAM) -o tmp_$(PARSE_DAT) unparse $(UNPARSE_XML)
+	diff $(PARSE_DAT) tmp_$(PARSE_DAT)
 
-# Step 4 (optional): Remove the executable and temp data files.
+# Step 4: Remove the executable and scratch files (optional).
 
 # $ make clean
 
 clean:
-	rm -f $(PROGRAM) temp_$(PARSE_DAT) temp_$(UNPARSE_XML)
+	rm -f $(PROGRAM) tmp_$(PARSE_DAT) tmp_$(UNPARSE_XML)
 
 .PHONY: check parse-check unparse-check clean
diff --git a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/daffodil_getopt.c b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/daffodil_getopt.c
index 8a4b8a0..ad979d2 100644
--- a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/daffodil_getopt.c
+++ b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/daffodil_getopt.c
@@ -104,8 +104,7 @@ parse_daffodil_cli(int argc, char *argv[])
     }
 
     // Get the command and the infile arg
-    int i;
-    for (i = optind; i < argc; i++)
+    for (int i = optind; i < argc; i++)
     {
         const char *arg = argv[i];
 
diff --git a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_reader.c b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_reader.c
index a309552..5dc6e9a 100644
--- a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_reader.c
+++ b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_reader.c
@@ -268,8 +268,7 @@ strtohexbinary(const char *text, HexBinary *hexBinary)
 
     // Store hexadecimal characters into byte array
     if (hexBinary->array) memset(hexBinary->array, 0, hexBinary->lengthInBytes);
-    size_t i;
-    for (i = 0; i < numNibbles; i++)
+    for (size_t i = 0; i < numNibbles; i++)
     {
         char    c = text[i];
         uint8_t value = 0;
diff --git a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_writer.c b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_writer.c
index 9c4dd2a..a146a31 100644
--- a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_writer.c
+++ b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libcli/xml_writer.c
@@ -86,8 +86,7 @@ binaryToHex(HexBinary hexBinary, bool freeMemory)
 
     // Convert each binary byte to two hexadecimal characters
     char *nibble = text;
-    size_t i;
-    for (i = 0; i < hexBinary.lengthInBytes; i++)
+    for (size_t i = 0; i < hexBinary.lengthInBytes; i++)
     {
         static char hexDigit[] = "0123456789ABCDEF";
         *(nibble++) = hexDigit[hexBinary.array[i] / 16]; // high nibble
diff --git a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/errors.c b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/errors.c
index 94febe4..83bc508 100644
--- a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/errors.c
+++ b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/errors.c
@@ -148,8 +148,7 @@ print_diagnostics(const Diagnostics *diagnostics)
 {
     if (diagnostics)
     {
-        size_t i;
-        for (i = 0; i < diagnostics->length; i++)
+        for (size_t i = 0; i < diagnostics->length; i++)
         {
             const Error *error = &diagnostics->array[i];
             print_maybe_stop(error, 0);
diff --git a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/infoset.c b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/infoset.c
index 85b407d..35ab348 100644
--- a/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/infoset.c
+++ b/daffodil-runtime2/src/main/resources/org/apache/daffodil/runtime2/c/libruntime/infoset.c
@@ -132,8 +132,7 @@ walkInfosetNode(const VisitEventHandler *handler, const InfosetBase *infoNode)
     const ERD **const childrenERDs = infoNode->erd->childrenERDs;
     const size_t *    offsets = infoNode->erd->offsets;
 
-    size_t i;
-    for (i = 0; i < count && !error; i++)
+    for (size_t i = 0; i < count && !error; i++)
     {
         const size_t offset = offsets[i];
         const ERD *  childERD = childrenERDs[i];
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 5c68924..2f25133 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
@@ -112,6 +112,8 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator {
     try {
       // Assemble the compiler's command line arguments
       val compiler = pickCompiler
+      val cFlags = Seq("-std=gnu11")
+      val includes = Seq("-Ilibcli", "-Ilibruntime")
       val absFiles = os.walk(codeDir).filter(_.ext == "c")
       val relFiles = Seq("libcli/*.c", "libruntime/*.c")
       val libs = Seq("-lmxml")
@@ -121,7 +123,7 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator {
       // global cache directory, not a local zig_cache directory)
       if (compiler.nonEmpty) {
         val result = os
-          .proc(compiler, "-Ilibcli", "-Ilibruntime", if (isWin) relFiles else absFiles, libs, "-o", exe)
+          .proc(compiler, cFlags, includes, if (isWin) relFiles else absFiles, libs, "-o", exe)
           .call(cwd = codeDir, stderr = os.Pipe)
 
         // Report any compiler output as a warning
diff --git a/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.c b/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.c
index 833f045..8f1b538 100644
--- a/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.c
+++ b/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.c
@@ -1,14 +1,17 @@
+// clang-format off
 #include "generated_code.h"
 #include <math.h>       // for NAN
-#include <stdbool.h>    // for bool, true, false
+#include <stdbool.h>    // for true, false, bool
 #include <stddef.h>     // for NULL, size_t
+#include <string.h>     // for memset, memcmp
 #include "errors.h"     // for Error, PState, UState, ERR_CHOICE_KEY, UNUSED
-#include "parsers.h"    // for parse_be_float, parse_be_int16, parse_be_bool32, parse_validate_fixed, parse_be_bool16, parse_be_int32, parse_be_uint32, parse_le_bool32, parse_le_int64, parse_le_uint8, parse_be_bool8, parse_be_double, parse_be_int64, parse_be_int8, parse_be_uint16, parse_be_uint64, parse_be_uint8, parse_le_bool16, parse_le_bool8, parse_le_double, parse_le_float, parse_le_int16, parse_le_int32, parse_le_int8, parse_le_uint16, parse_le_uint32, parse_le_uint64
-#include "unparsers.h"  // for unparse_be_float, unparse_be_int16, unparse_be_bool32, unparse_validate_fixed, unparse_be_bool16, unparse_be_int32, unparse_be_uint32, unparse_le_bool32, unparse_le_int64, unparse_le_uint8, unparse_be_bool8, unparse_be_double, unparse_be_int64, unparse_be_int8, unparse_be_uint16, unparse_be_uint64, unparse_be_uint8, unparse_le_bool16, unparse_le_bool8, unparse_le_double, unparse_le_float, unparse_le_int16, unparse_le_int32, unparse_le_int8, unparse_le_uint1 [...]
+#include "parsers.h"    // for alloc_hexBinary, parse_hexBinary, parse_be_float, parse_be_int16, parse_validate_fixed, parse_be_bool32, parse_be_bool16, parse_be_int32, parse_be_uint16, parse_be_uint32, parse_le_bool32, parse_le_int64, parse_le_uint16, parse_le_uint8, parse_be_bool8, parse_be_double, parse_be_int64, parse_be_int8, parse_be_uint64, parse_be_uint8, parse_le_bool16, parse_le_bool8, parse_le_double, parse_le_float, parse_le_int16, parse_le_int32, parse_le_int8, parse_le_uint [...]
+#include "unparsers.h"  // for unparse_hexBinary, unparse_be_float, unparse_be_int16, unparse_validate_fixed, unparse_be_bool32, unparse_be_bool16, unparse_be_int32, unparse_be_uint16, unparse_be_uint32, unparse_le_bool32, unparse_le_int64, unparse_le_uint16, unparse_le_uint8, unparse_be_bool8, unparse_be_double, unparse_be_int64, unparse_be_int8, unparse_be_uint64, unparse_be_uint8, unparse_le_bool16, unparse_le_bool8, unparse_le_double, unparse_le_float, unparse_le_int16, unparse_le_in [...]
+// clang-format on
 
 // Initialize our program's name and version
 
-const char *daffodil_program_version = "daffodil-runtime2 3.1.0";
+const char *daffodil_program_version = "daffodil-runtime2 3.2.0-SNAPSHOT";
 
 // Declare prototypes for easier compilation
 
@@ -247,9 +250,9 @@ static void
 foo_initSelf(foo *instance)
 {
     instance->_base.erd = &foo_data_NestedUnionType_ERD;
-    instance->a = 0xCCCCCCCC;
-    instance->b = 0xCCCCCCCC;
-    instance->c = 0xCCCCCCCC;
+    instance->a = 0x77777777;
+    instance->b = 0x77777777;
+    instance->c = 0x77777777;
 }
 
 static void
@@ -331,7 +334,7 @@ data_initChoice(data *instance, const NestedUnion *rootElement)
         instance->_choice = 1;
         break;
     default:
-        error.d64 = key;
+        error.arg.d64 = key;
         return &error;
     }
 
@@ -365,7 +368,7 @@ data_parseSelf(data *instance, PState *pstate)
         break;
     default:
         // Should never happen because initChoice would return an error first
-        error.d64 = (int64_t)instance->_choice;
+        error.arg.d64 = (int64_t)instance->_choice;
         pstate->error = &error;
         return;
     }
@@ -391,7 +394,7 @@ data_unparseSelf(const data *instance, UState *ustate)
         break;
     default:
         // Should never happen because initChoice would return an error first
-        error.d64 = (int64_t)instance->_choice;
+        error.arg.d64 = (int64_t)instance->_choice;
         ustate->error = &error;
         return;
     }
@@ -401,7 +404,7 @@ static void
 NestedUnion_initSelf(NestedUnion *instance)
 {
     instance->_base.erd = &NestedUnion_ERD;
-    instance->tag = 0xCCCCCCCC;
+    instance->tag = 0x77777777;
     data_initSelf(&instance->data);
 }
 
diff --git a/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.h b/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.h
index 16fdf8b..0ee034b 100644
--- a/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.h
+++ b/daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/examples/NestedUnion/generated_code.h
@@ -1,10 +1,12 @@
 #ifndef GENERATED_CODE_H
 #define GENERATED_CODE_H
 
+// clang-format off
+#include "infoset.h"  // for HexBinary, InfosetBase
 #include <stdbool.h>  // for bool
 #include <stddef.h>   // for size_t
-#include <stdint.h>   // for int16_t, int32_t, int64_t, uint32_t, uint8_t, int8_t, uint16_t, uint64_t
-#include "infoset.h"  // for InfosetBase
+#include <stdint.h>   // for uint8_t, int16_t, int32_t, int64_t, uint32_t, int8_t, uint16_t, uint64_t
+// clang-format on
 
 // Define infoset structures