tuxji opened a new pull request #488:
URL: https://github.com/apache/incubator-daffodil/pull/488
Extend the C code generator in daffodil-runtime2 to support choices in
DFDL schemas with restrictions (no backtracking or discrimination
needed). An xs:choice complex type must have a dfdl:choiceDispatchKey
expression pointing to a preceding infoset element which must contain
an integral value. Each alternative in the choice must be labeled
with a dfdl:choiceBranchKey attribute having only integer literals.
The C code generator makes some assumptions to simplify converting the
choiceDispatchKey expression to C code accessing the preceding infoset
element:
- the expression starts with '{xs:string( and ends with )}'
- the expression returns the value of a previous element without
changing the value in any way (except converting it to xs:string)
- both the expression and the C code use only local names (for now...)
- we can map the context node's path to a Unix-like slash path
- all dpath operations look like Unix-like relative paths (../tag)
- we can normalize the new path and convert it to C struct dot notation
- we can store the accessed value in an int64_t local variable safely
Also add some DFDL schemas with choice elements to make sure C code
generator keeps working for these schemas.
Changelog:
In build.sbt, trim unnecessary C compile flags (note we don't use the
.o files built by sbt-cc, we only want C compilation error/warning
messages).
In c/Makefile, put *.h files in HEADERS (not SOURCES) and trim
-Wno-missing-field-initializers from CFLAGS since we've fixed all
these warnings in the C code now.
In daffodil_argp.c, fix warnings about missing field initializers.
In daffodil_main.c, fix warnings about missing field initializers.
In infoset.c, store offsets as size_t instead of ptrdiff_t since
they're always nonnegative numbers. Handle CHOICE typeCode
appropriately (i.e., call ERD member function initChoice) when walking
infoset with visitor methods.
In infoset.h, add initChoice to ERD member functions and CHOICE to
TypeCode enumerations. Store offsets as size_t instead of ptrdiff_t
since they're always nonnegative numbers. Define static constant
NO_CHOICE as value to determine when _choice fields are uninitialized.
In parsers.c/unparsers.c, reorder macro definitions slightly.
Add NestedUnion.[ch] to show how C code can support choice complex
types. C code was generated from nested.dfdl.xsd schema using
NestedUnion as the root element.
In ex_nums.[ch], replace old generated code with new generated code.
In CodeGenerator.scala, add scaladoc comments and remove -lpthread
since we don't need to link C executable with it.
In Runtime2CodeGenerator.scala, add braces to generateCode method.
Note that I tried to detect choice complex types when walking grammar
objects in generateCode method but found out it was very difficult to
detect them in that place while it was easier to detect them in
ElementParseAndUnspecifiedLengthCodeGenerator.scala instead.
In CodeGeneratorState.scala, rename qualifiedName function to erdName
and improve it to qualify erdName with global complex type's name and
append _ERD before returning erdName. Update calls in rest of file
accordingly. Make addImplementation method generate new ERD member
function initChoice. Add choiceDispatchField function to convert a
choiceDispatchKey expression into C struct dot notation for accessing
the choiceDispatchKey expression's runtime value. We'll probably
revise the choiceDispatchField function a few times to handle more
cases as they come up. Add new methods addBeforeSwitchStatements and
addAfterSwitchStatements to generate declarations, ERD definitions,
offset computations, ERD computations, init statements, initChoice
statements, parse statements, and unparse statements needed to handle
choices with several alternative branches. Make addComplexTypeERD
method include correct count and initChoice member function in ERDs
containing alternative branches. Make addComplexTypeStatements method
generate C code (switch statement cases) for initChoice, parse, and
unparse functions of complex types with alternative branches. Make
minor changes to addFieldDeclaration, generateCodeFile and
generateCodeHeader methods to improve the generated C code.
In ElementParseAndUnspecifiedLengthCodeGenerator.scala, call
cgState.addBeforeSwitchStatements and cgState.addAfterSwitchStatements
in right places to generate C code for complex types having choices.
In TestRuntime2.tdml, change defaultRoundTrip to "none" since every
parse test is accompanied by an unparse test, making the extra work
done by "onePass" redundant. Or maybe we should keep
defaultRoundTrip="onePass" and delete all the unparse tests, but it's
nice to have debuggable entry points for both parse and unparse tests.
Add egress_xdcc_bw.dfdl.xsd and ingress_xdcc_bw.dfdl.xsd from a
collaborator who already gave permission for Apache license. Add
egress_xdcc_bw.tdml and ingress_xdcc_bw.tdml with corresponding parse
binary data files and unparse XML files to test all choice
alternatives in both schemas.
Add nested.dfdl.xsd to provide a much smaller schema also using
dfdl:choiceDispatchKey and dfdl:choiceBranchKey for development and
testing. Add nested.tdml with corresponding binary data files and
unparse XML files to test NestedUnion in nested schema.
In orion-command.dfdl.xsd, incorporate latest changes from
collaborator to define global elements using global complex type
declarations instead of nested complex type declarations.
In orion-command.tdml, change defaultRoundTrip to "none" to avoid
redundancy and speed up tests.
Add TestEgressXdccBw.scala, TestIngressXdccBw.scala, and
TestNested.scala to provide entry points for calling all of the new
test cases.
In Rat.scala, tell ratCheck to ignore newly added binary data files.
----------------------------------------------------------------
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]