Internals
This page documents internals that are not meant to be used by the users.
Parsing
The conversion from XML to the internal representation of ATDF format heavily relies on the generated function AtmelToolsDeviceFiles.node_to_atdf.
AtmelToolsDeviceFiles.node_to_atdf — Functionnode_to_atdf([dest::Type{T},] node::XML.Node) where {T <: AbstractATDF}Convert an XML node to the destination type. If dest is not given, then node XML.nodetype must me an XML.Document, and the function will attempt to extract the root <avr-tools-device-file> node and convert it to an AVRToolsDeviceFile instance.
The main bit of AtmelToolsDeviceFiles.node_to_atdf is @generated and is intended to use AtmelToolsDeviceFiles.AbstractATDF subtypes as a template for interpreting the XML.Node object it has been fed.
AtmelToolsDeviceFiles.AbstractATDF — TypeAbstract supertype for parsing ATDF.
This approach simplifies the description of the format as it relies mostly on the defined structures in types.jl.
The structures are built from the inferred schema from examples of files I have found so far. Unfortunately I was unable to find a proper schema on the internet yet. If you are in possiession of such a schema from Microship please reach out, for example by opening an issue!
Of course, the structures themselve are not exactly enough to define the XML schema, so we define a set of helper functions. We can define four kind of data we want to fetch from the XML code: attributes, single-valued structures, direct children arrays, wrapped children arrays.
Attribute fetching
AtmelToolsDeviceFiles._build_xml_attribute_name — Function_build_xml_attribute_name(fieldname)Transform a field name into an XML attribute name.
AtmelToolsDeviceFiles._generate_attribute_fetching — Function_generate_attribute_fetching(name, type)Generate the code to fetch an attribute given a field name and a template type. Returns a named tuple with a fetchcode expression to retrieve the attribute, and a checkcode expression to perform verification on the input XML node.
Single-valued child structures
AtmelToolsDeviceFiles._generate_single_child_fetching — Function_generate_single_child_fetching(name, type)Generate the codes to fetch a single struct child name of an XML node using template type.
Direct children arrays
AtmelToolsDeviceFiles._generate_children_name — Function_generate_children_name(fieldname)Generate the expected tag name of children corresponding to a fieldname.
AtmelToolsDeviceFiles._generate_children_fetching — Function_generate_children_fetching(name, Vector{type})Generate the codes to fetch struct children of an XML node. Return a named tuple with the condition to trigger the code fetching, the type of the children, the variable used in the main function to store the children, and the fetchcode to parse a specific child.
Wrapped children arrays
AtmelToolsDeviceFiles._has_wrapper_children — Function_has_wrapper_children(T)Default to false. Types that have wrapped children must return true.
Example of a wrapped children case:
<tag>
<signals>
<signal></signal>
...
<signal></signal>
</signals>
</tag>The equivalent un-wrapped case would be:
<tag>
<signal></signal>
...
<signal></signal>
</tag>AtmelToolsDeviceFiles._generate_wrapper_children_name — Function_generate_wrapper_children_name(fieldname)Generate the expected wrapper tag name of children corresponding to a fieldname.
AtmelToolsDeviceFiles._special_wrapped_children_name — Function_special_wrapped_children_name(_, predicted)
Sometimes the name of the wrapper does not match the name of the children. Defining a method for this function allows overwriting the default child name.
AtmelToolsDeviceFiles._fetch_wrapped_children — Function_fetch_wrapped_children(childtype, node, name)Iterate over a child node to extract the grand-children of type childtype with the given XML tag. Return a vector of childtype. Used by the code generated in _generate_wrapped_children_fetching.
AtmelToolsDeviceFiles._generate_wrapped_children_fetching — Function_generate_wrapped_children_fetching(name, Vector{type})Generate the codes to fetch wrapped struct children of an XML node. Return a named tuple with the condition to trigger the code fetching, the type of the children, the variable used in the main function to store the children, and the fetchcode to parse a specific child using _fetch_wrapped_children.
node_to_atdf generated methods structure
Reading the source code of AtmelToolsDeviceFiles.node_to_atdf is probably the best option. However, we give here a summary of what the structure of generated methods look like.
- Attributes fetching. If the node is expected to have attributes, we fetch them and run the
checkcodeexpressions generated byAtmelToolsDeviceFiles._generate_attribute_fetching. - Declaration of the variables used by single-valued children and array children. Single-valued children variables are initialized as
nothingand arrays as empty arrays. - A
forloop that iterates over the children and checks if it needs to trigger thefetchcodeof the single-valued childrent, array children, or wrapped array children. - Check over all single-valued children that they are not
nothingafter the loop (we do not allow optional structure single-valued children at the time). - Build the internal representation of the node from the extracted variables.