tuxji commented on a change in pull request #466:
URL: https://github.com/apache/incubator-daffodil/pull/466#discussion_r543635266
##########
File path:
daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/Runtime2DataProcessor.scala
##########
@@ -108,6 +108,8 @@ class Runtime2DataProcessor(executableFile: os.Path)
extends DFDL.DataProcessorB
val parseResult = new ParseResult(outfile, Failure(parseError))
parseResult.addDiagnostic(parseError)
parseResult
+ } finally {
+ os.remove.all(tempDir)
Review comment:
Nope, these two are the only new dependencies. I've added their
copyrights to daffodil-cli/bin.LICENSE and in directories-jvm's case, I looked
for a prominent label to add to daffodil-cli/bin.NOTICE but I couldn't find any
such label in directories-jvm's github repo
(<https://github.com/dirs-dev/directories-jvm>).
Both new deps are used by the C code generator in runtime2. OS-Lib has some
other alternatives, but its advantage is that it has very concise and Scala-ish
APIs for operating on files and running processes. We probably could benefit
from using OS-Lib throughout Daffodil, not just in runtime2, to simplify code
that operates on files or runs processes. We probably could expand Daffodil
Utils instead to cover the use cases I've been using OS-Lib for if we needed to
as well.
I found no alternatives except writing our own Daffodil specific
implementation to allow Daffodil to create its own cache directory in the
"right" place on Linux, Mac, and Windows when I looked for and found dev-dirs /
directories-jvm to do exactly that. The C code generator (as far as I know) is
the only place (so far) which needs to use a cache directory, although maybe
there are other places in Daffodil that might find a use for directories-jvm
(besides finding the right place for a Daffodil cache directory, it also can
find the right place for a Daffodil config file inside a user's home directory).
##########
File path:
daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/generators/BinaryIntegerKnownLengthCodeGenerator.scala
##########
@@ -36,50 +38,47 @@ trait BinaryIntegerKnownLengthCodeGenerator {
val bo = e.byteOrderEv.constValue
bo
}
- // For the time being this is a very limited back end.
- // So there are numerous restrictions to enforce.
- e.schemaDefinitionUnless(lengthInBits <= 64, "Length must be 64 bits or
less, but was: %s", lengthInBits)
- if (lengthInBits == 64 && !g.signed)
- e.SDE("Integers of 64 bits length must be signed.")
// This insures we can use regular java.io library calls.
if (e.alignmentValueInBits.intValue() % 8 != 0)
e.SDE("Only alignment to 8-bit (1 byte) boundaries is supported.")
// The restrictions below are ones we want to eventually lift.
- if (lengthInBits != 32)
- e.SDE("Lengths other than 32 bits are not supported.")
-
if (byteOrder ne ByteOrder.BigEndian)
e.SDE("Only dfdl:byteOrder 'bigEndian' is supported.")
if (e.bitOrder ne BitOrder.MostSignificantBitFirst)
e.SDE("Only dfdl:bitOrder 'mostSignificantBitFirst' is supported.")
- if (!g.signed)
- e.SDE("Only signed integers are supported.")
-
- val initStatement = s" instance->$fieldName = 0xCDCDCDCD;"
+ // Start generating code snippets
+ val initialValue = lengthInBits match {
+ case 8 => "0xCD"
+ case 16 => "0xCDCD"
+ case 32 => "0xCDCDCDCD"
+ case 64 => "0xCDCDCDCDCDCDCDCD"
+ case _ => e.SDE("Lengths other than 8, 16, 32, or 64 bits are not
supported.")
Review comment:
Yes, what Mike said. I've added a comment that those are magic debug
values (unusual memory bit patterns) to mark fields that do not have integer
values written to their locations for any reason.
##########
File path: daffodil-runtime2/src/main/resources/examples/ex_int32.c
##########
@@ -99,42 +99,45 @@ static const ERD c2_ERD = {
(ERDUnparseSelf)&c2_unparseSelf, // unparseSelf
};
-static const c1 c1_compute_ERD_offsets;
+static const ex_int32 ex_int32_compute_ERD_offsets;
-static const ptrdiff_t c1_offsets[2] = {
- (char *)&c1_compute_ERD_offsets.e1 - (char *)&c1_compute_ERD_offsets,
- (char *)&c1_compute_ERD_offsets.c2 - (char *)&c1_compute_ERD_offsets};
+static const ptrdiff_t ex_int32_offsets[2] = {
+ (char *)&ex_int32_compute_ERD_offsets.e1 - (char
*)&ex_int32_compute_ERD_offsets,
+ (char *)&ex_int32_compute_ERD_offsets.c2 - (char
*)&ex_int32_compute_ERD_offsets};
-static const ERD *c1_childrenERDs[2] = {&e1_ERD, &c2_ERD};
+static const ERD *ex_int32_childrenERDs[2] = {&e1_ERD, &c2_ERD};
-static const ERD c1_ERD = {
+static const ERD ex_int32_ERD = {
{
- "ex", // namedQName.prefix
- "c1", // namedQName.local
+ NULL, // namedQName.prefix
+ "ex_int32", // namedQName.local
"http://example.com", // namedQName.ns
},
COMPLEX, // typeCode
2, // numChildren
- c1_offsets, // offsets
- c1_childrenERDs, // childrenERDs
- (ERDInitSelf)&c1_initSelf, // initSelf
- (ERDParseSelf)&c1_parseSelf, // parseSelf
- (ERDUnparseSelf)&c1_unparseSelf, // unparseSelf
+ ex_int32_offsets, // offsets
+ ex_int32_childrenERDs, // childrenERDs
+ (ERDInitSelf)&ex_int32_initSelf, // initSelf
+ (ERDParseSelf)&ex_int32_parseSelf, // parseSelf
+ (ERDUnparseSelf)&ex_int32_unparseSelf, // unparseSelf
};
// Return a root element to be used for parsing or unparsing
InfosetBase *
rootElement()
{
- static c1 instance;
+ static ex_int32 instance;
InfosetBase *root = &instance._base;
- c1_ERD.initSelf(root);
+ ex_int32_ERD.initSelf(root);
return root;
}
// Methods to initialize, parse, and unparse infoset nodes
+static inline uint8_t be8toh(uint8_t be8b) { return be8b; }
Review comment:
Yes, as you realized and commented below, these functions are degenerate
1-byte cases of endian-sensitive integer transformation functions defined in
the GNU C library (https://linux.die.net/man/3/be16toh). This ex_int32 example
doesn't use them but the orion_command example does have some 8-bit integers.
The "h" stands for host order which could be little-endian on a little-endian
architecture or big-endian on a big-endian architecture (the functions know
which architecture they're compiled on). Added comment and also added
little-endian versions "htole8" and "le8toh".
##########
File path: daffodil-runtime2/src/main/resources/examples/ex_int32.c
##########
@@ -149,7 +152,7 @@ c2_parseSelf(c2 *instance, const PState *pstate)
const char *error_msg = NULL;
if (!error_msg)
{
- char buffer[4];
+ char buffer[sizeof(uint32_t)];
Review comment:
The endian-sensitive conversion functions take and return only unsigned
integers, so I used unsigned types as temporary variables and in the "sizeof()"
as well for consistency.
##########
File path: project/Rat.scala
##########
@@ -114,7 +114,8 @@ object Rat {
file("daffodil-sapi/src/test/resources/test/sapi/myData16.dat"),
file("daffodil-sapi/src/test/resources/test/sapi/myData19.dat"),
file("daffodil-sapi/src/test/resources/test/sapi/myDataBroken.dat"),
-
file("daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/parse_int32"),
+
file("daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/ex_int32_parse"),
+
file("daffodil-runtime2/src/test/resources/org/apache/daffodil/runtime2/orion_command_parse"),
Review comment:
Yes, renamed binary test files to .dat and sorted runtime2 excludes
before sapi excludes.
##########
File path:
daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/generators/CodeGeneratorState.scala
##########
@@ -260,6 +272,9 @@ class CodeGeneratorState {
|
|// Methods to initialize, parse, and unparse infoset nodes
|
+ |static inline uint8_t be8toh(uint8_t be8b) { return be8b; }
Review comment:
Correct, "be8toh" and company aren't in the standard library and we
still want to generate calls to them even for the degenerate 8-bit (1-byte)
cases.
##########
File path: daffodil-runtime2/src/main/resources/c/libcli/xml_reader.c
##########
@@ -184,10 +184,50 @@ xmlInt32Elem(XMLReader *reader, const ERD *erd, int32_t
*location)
{
if (strcmp(name_from_xml, name_from_erd) == 0)
{
- // Check for any errors getting the 32-bit integer
+ // Check for any errors getting the integer number
const char *errstr = NULL;
- *location = (int32_t)strtonum(number_from_xml, INT32_MIN,
INT32_MAX,
- &errstr);
+
+ // Need to handle varying bit lengths and signedness
Review comment:
Changed to "Handle varying bit lengths of both signed & unsigned
numbers".
##########
File path: daffodil-runtime2/src/main/resources/c/libcli/xml_writer.c
##########
@@ -90,29 +90,64 @@ xmlEndComplex(XMLWriter *writer, const InfosetBase *base)
return complex ? NULL : "Underflowed the XML stack";
}
-// Write 32-bit integer value as element
+// Write 8, 16, 32, or 64-bit signed/unsigned integer as element
static const char *
-xmlInt32Elem(XMLWriter *writer, const ERD *erd, const int32_t *location)
+xmlIntegerElem(XMLWriter *writer, const ERD *erd, const void *intLocation)
{
mxml_node_t *parent = stack_top(&writer->stack);
const char * name = get_erd_name(erd);
- const char * xmlns = get_erd_xmlns(erd);
mxml_node_t *simple = mxmlNewElement(parent, name);
- int32_t value = *location;
- mxml_node_t *text = mxmlNewOpaquef(simple, "%i", value);
+
+ // Set namespace declaration if necessary
+ const char *xmlns = get_erd_xmlns(erd);
if (xmlns)
{
const char *ns = get_erd_ns(erd);
mxmlElementSetAttr(simple, xmlns, ns);
}
- return (simple && text) ? NULL : "Error making new int32 simple element";
+
+ // Need to handle varying bit lengths and signedness
Review comment:
Changed to "Handle varying bit lengths of both signed & unsigned numbers"
##########
File path: daffodil-runtime2/src/main/resources/examples/ex_int32.c
##########
@@ -25,15 +25,15 @@
static void c2_initSelf(c2 *instance);
static const char *c2_parseSelf(c2 *instance, const PState *pstate);
static const char *c2_unparseSelf(const c2 *instance, const UState *ustate);
-static void c1_initSelf(c1 *instance);
-static const char *c1_parseSelf(c1 *instance, const PState *pstate);
-static const char *c1_unparseSelf(const c1 *instance, const UState *ustate);
+static void ex_int32_initSelf(ex_int32 *instance);
Review comment:
This particular example has only signed int32 numbers. Mixing below is
really due to type signatures of functions being called.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]