Skip to content

Latest commit

 

History

History
199 lines (135 loc) · 4.73 KB

File metadata and controls

199 lines (135 loc) · 4.73 KB

Formatter Guide

This document describes the current behavior of dtsformat, how configuration works, and what parts of DTS syntax the formatter currently handles well.

Scope

dtsformat is a formatter for .dts and .dtsi files.

It is designed for:

  • Linux-style DTS sources
  • Zephyr overlays and DTS files
  • Zephyr files that contain C preprocessor directives such as #include and #ifdef

It is not a full semantic parser. The current implementation is a DTS-aware token formatter with layout rules for common DTS structures.

Build

meson setup build
env CCACHE_DISABLE=1 meson compile -C build

CLI

Basic usage:

./build/dtsformat [--in-place] [--config PATH] [FILE ...]

Options:

  • --in-place, -i Write the formatted output back to the input file.
  • --config PATH Use an explicit config file instead of searching for .dtsformat.
  • --help, -h Show usage.

If no file is passed, input is read from stdin and output is written to stdout.

Configuration

The formatter searches for .dtsformat starting from the directory of the input file and walking upward toward the filesystem root.

When formatting stdin, it searches upward starting from the current working directory.

Example .dtsformat:

UseTab: Never
IndentWidth: 4
ColumnLimit: 88

Supported keys are:

UseTab

Controls whether indentation is emitted with tabs or spaces.

Allowed values:

  • Always
  • Never

Notes:

  • When UseTab: Always is used, indentation levels are written as tabs.
  • IndentWidth still exists in config for consistency, but tab indentation is emitted as tabs rather than being expanded into spaces.

IndentWidth

Positive integer.

Used when UseTab: Never.

Example:

IndentWidth: 2

ColumnLimit

Positive integer.

Used as a wrapping target for long property values and collections. The formatter tries to keep output under this limit, but exact wrapping is heuristic rather than guaranteed for every token sequence.

Current Formatting Behavior

The formatter currently normalizes:

  • node indentation
  • spaces around =
  • spaces around bitwise |
  • spaces after list commas when they are separators rather than part of a DTS property name
  • property continuation indentation
  • wrapping of long <...> and [...] values
  • standalone line comments and block comments
  • /include/ "file.dtsi" directives
  • preprocessor lines such as #include, #ifdef, #endif, #define, and related directives
  • preservation of at most one empty line from the input

Comments

Comments are emitted as standalone formatted lines.

This is important for DTS properties like:

map =
    // Left
    <0>, <1>, <2>, <3>,
    // Right
    <4>, <5>, <6>, <7>;

Without explicit handling, comments in the middle of a property value tend to collapse onto the same line as = or a list item. The formatter keeps them on their own continuation line.

Includes and Preprocessor Directives

The formatter supports both of these styles:

/include/ "soc.dtsi"
#include "board.dtsi"

Preprocessor directives are preserved as directive lines. This includes common forms such as:

  • #include
  • #if
  • #ifdef
  • #ifndef
  • #elif
  • #else
  • #endif
  • #define
  • #undef
  • #error
  • #pragma
  • #line

The formatter distinguishes these from DTS properties such as #address-cells and #size-cells.

Empty Lines

The formatter preserves vertical separation from the input, but normalizes runs of multiple blank lines down to one empty line.

That means:

  • one empty line stays one empty line
  • two or more consecutive empty lines become one empty line
  • no blank line is inserted unless it already exists in the source or is required by normal formatting rules

Testing

The repository uses fixture-based tests driven by Python and Meson.

Current fixture coverage includes:

  • Linux-style formatting
  • Zephyr tab-based formatting
  • /include/ handling
  • preprocessor directive handling
  • blank-line preservation
  • comments inside array/list property values

Run tests with:

env CCACHE_DISABLE=1 meson test -C build --print-errorlogs

Known Limits

Current limitations include:

  • formatting is token/layout based rather than AST-based
  • line wrapping is heuristic and not guaranteed to be globally optimal
  • very complex macro-heavy preprocessed DTS input may still need additional rules
  • the config format intentionally supports only a small subset of .clang-format-style key/value behavior

Project Layout

  • src/main.c: CLI, file IO, config resolution, in-place formatting
  • src/config.c: .dtsformat parsing and config discovery
  • src/formatter.c: tokenization and formatting rules
  • tests/test_formatter.py: fixture runner
  • tests/fixtures/: regression cases