pcb-rnd knowledge pool
KiCad s-epxression file format tree
kicad_pcb_fmt by Tibor 'Igor2' Palinkas on 2019-04-05 | Tags: howto, kicad, reverse, engineering, file, format |
Abstract: Reverse engineered "complete" list of KiCad's s-expression file format tree.
KiCad doesn't seem to have a real, complete file format specification on pcbnew's board format. There is a pdf with some explanation and a lot of examples, but no definitive, "these are all nodes we ever emit or read" kind of description.
While working on io_kicad, this proved to be a problem: with most reverse engineered formats, we can support only what we find examples of. But how do we know when we have finished, when we have complete support for the format? There are three answers:
- with proprietary software and undocumented file formats, we never know, the struggle never ends: new users will always bring new corner cases we need to isolate and fix up
- with a properly specified file format, such as tEDAx, we just need to match up the code with the specification and can be sure everything is supported
- KiCad and other open source tools with no proper file format specification falls in between: we can't match our implementation to a specification, but we have the source code to see what their implementation does.
Before reading the details of KiCad's C++ parser, it is worth making a map. A map of the tree that the s-expression represents: all possible nodes. I decided to create this by a hackish script that reads the C++ code to extract method names and tokens. It's not a generic solution, not a proper C++ parser, it's just a quick hack so that I didn't need to do this manually.
The script has multiple stages with different digested output (tables). At the end it prints the indented complete tree of all nodes and indirect hints on the node types (the method names parsing the data for the give node) and line numbers pointing into the C++ code. Below is a table with the results.
KiCad major ver | patch | tree | diff | annot-diff |
---|---|---|---|---|
4 | v4 patch | v4 tree | ||
5 | v5 patch | v5 tree | 4->5 | 4->5 |
The intention is to use this map to find where io_kicad is not prepared for a feature, then create test cases for that feature and go the usual reverse engineering way of comparing KiCad's output to ours.