Studying more of the eXpat XML parser as vendored into Papyrix...
The primary parser state might transition to a CData state. It invokes a helper propagating any errors before deciding whether to switch to the external-entity state or that primary state. Normalizes its input, iterates over the lexed XML tokens possibly invoking another helper to help clean up, & branches over results to clean up. Primarily its looks for cdata-sect-close tokens, converting others to text.
1/?
If the DTD build flag's set it there's a whole suite of states for parsing that DTD prologue. I won't discuss further, since I've got enough already!
There's a wrapper around callbacks for handling text encodings. There's a wrapper around one of 2 XML declaration lexers which additionally copies data into memory that's not about to be freed, while handling those text encodings.
There's another wrapper around the callbacks for unknown encodings.
These are used in the starting parser state.
2/?