dtsformat is a small C formatter for Device Tree source files.
It formats .dts and .dtsi files with a DTS-aware token/layout engine, reads project style from .dtsformat, and is intended to work well with both Linux-style DTS sources and Zephyr-style preprocessed DTS files.
The formatter supports:
- project-local configuration discovery through
.dtsformat - spaces or tabs for indentation
- configurable indentation width
- a configurable column limit used for line wrapping
- DTS includes via
/include/ "file.dtsi" - preprocessor lines such as
#include,#ifdef, and#endif - comments inside properties, including array/list values
- preservation of at most one empty line from the input
- Formatter in C: A single native executable built with Meson.
- Project Config Discovery: Searches upward for
.dtsformatnext to the formatted file, similar to how.clang-formatis typically used. - Linux + Zephyr Coverage: Handles common Linux DTS style as well as Zephyr files that use C preprocessor directives.
- Configurable Indentation: Supports tabs or spaces with configurable width.
- Column-Aware Wrapping: Tries to wrap long property values and collections around a configured limit.
- Comment Preservation: Keeps line comments and block comments as explicit formatted lines, including comments embedded in array-style property values.
- Fixture Tests: Includes regression fixtures for includes, preprocessor directives, blank lines, and array comments.
meson setup build
meson compile -C buildIf ccache is configured in your environment and causes sandbox or temp-directory issues, this also works:
env CCACHE_DISABLE=1 meson compile -C build./build/dtsformat board.dts./build/dtsformat --in-place board.dtscat board.dts | ./build/dtsformatThe formatter looks for a .dtsformat file starting from the input file directory and walking upward.
You can also provide a config explicitly with --config.
Example:
UseTab: Never
IndentWidth: 4
ColumnLimit: 88Supported keys:
UseTab:AlwaysorNeverIndentWidth: positive integerColumnLimit: positive integer
Formats one or more DTS/DTSI files.
./build/dtsformat [--in-place] [--config PATH] [FILE ...]Examples:
./build/dtsformat app.overlay
./build/dtsformat --in-place boards/my_board.dts
./build/dtsformat --config ./style/.dtsformat soc.dtsiIf no file is provided, dtsformat reads from stdin and writes formatted output to stdout.
The formatter currently aims to normalize:
- spacing around
=,:,,, and| - indentation for nested nodes and property continuations
- wrapping of long
<...>and[...]property values - placement of standalone comments
- separation of preprocessor lines and
/include/directives - preservation of one empty line between logical sections
Example:
#include "pinctrl.dtsi"
/ {
zephyr,user {
map =
// Left
<0>, <1>, <2>, <3>,
// Right
<4>, <5>, <6>, <7>;
};
};
Project documentation lives in the repository:
- Formatter Guide: docs/FORMATTER.md
Run the full suite with:
meson test -C build --print-errorlogsThe current tests cover:
- Linux-style DTS formatting
- Zephyr-style tab-indented formatting
/include/directives- preprocessor directives such as
#includeand#ifdef - blank-line preservation
- comments embedded in array/list property values
Requirements:
- Meson
- Ninja
- a C11 compiler
- Python 3 for the test runner
Typical build flow:
meson setup build
env CCACHE_DISABLE=1 meson compile -C build
env CCACHE_DISABLE=1 meson test -C build --print-errorlogsUseful reports and patches include:
- DTS formatting regressions
- Zephyr preprocessing edge cases
- Linux DTS style edge cases
- better wrapping heuristics for long property values
- additional regression fixtures
- documentation fixes
If you report an issue, include:
- the DTS/DTSI input
- the
.dtsformatfile, if any - the command you ran
- the actual output
- the expected output