Metadata-Version: 2.4
Name: rdlfmt
Version: 0.1.1
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
Classifier: Topic :: Software Development :: Quality Assurance
License-File: LICENSE-MIT
License-File: LICENSE-APACHE
Summary: A formatter for SystemRDL
Keywords: systemrdl,formatter,eda,registers,csr
License-Expression: MIT OR Apache-2.0
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/fischeti/rdlfmt
Project-URL: Issues, https://github.com/fischeti/rdlfmt/issues
Project-URL: Repository, https://github.com/fischeti/rdlfmt

# rdlfmt

A formatter for [SystemRDL](https://www.accellera.org/downloads/standards/systemrdl) 2.0,
following the [PeakRDL style guide](https://peakrdl.readthedocs.io/en/latest/style-guide.html).

Before:

```systemrdl
addrmap top{
  reg {
      field{sw=rw;
    hw=r;} data[31:0];   // payload
  }ctrl @0x0;


  reg{field{sw=r;hw=w;}status[7:0];}stat@0x4;
};
```

After:

```systemrdl
addrmap top {
    reg {
        field {
            sw = rw;
            hw = r;
        } data[31:0]; // payload
    } ctrl @ 0x0;

    reg {
        field {
            sw = r; hw = w;
        } status[7:0];
    } stat @ 0x4;
};
```

## Install

A prebuilt binary, needing no toolchain of any kind:

```bash
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/fischeti/rdlfmt/releases/latest/download/rdlfmt-installer.sh | sh
```

On Windows:

```powershell
powershell -c "irm https://github.com/fischeti/rdlfmt/releases/latest/download/rdlfmt-installer.ps1 | iex"
```

From PyPI, which is convenient if you already manage `peakrdl` this way. The
package is the Rust binary in a wheel, not a Python program, so it pulls in
nothing else:

```bash
uv tool install rdlfmt
```

Or without installing at all:

```bash
uvx rdlfmt --check .
```

From crates.io, if you have a Rust toolchain:

```bash
cargo install rdlfmt
```

Or build from source (Rust 1.88+):

```bash
cargo build --release
```

## As a PeakRDL plugin

Installed into the same environment as [PeakRDL](https://peakrdl.readthedocs.io),
the wheel also registers a `peakrdl fmt` subcommand:

```bash
uv tool install peakrdl-cli --with rdlfmt
```

```bash
peakrdl fmt --check .
```

## Usage

Format a file, rewriting it in place — this is the default, and what you want
most of the time:

```bash
rdlfmt regs.rdl
```

Format every `.rdl` file in a directory tree:

```bash
rdlfmt .
```

Check without writing anything. Exits 1 if any file is not formatted, which is
the one for CI:

```bash
rdlfmt --check .
```

Same, but show what would change:

```bash
rdlfmt --diff regs.rdl
```

Write to stdout and leave the file alone:

```bash
rdlfmt --stdout regs.rdl
```

With no path at all, it reads stdin and writes stdout:

```bash
cat regs.rdl | rdlfmt
```

## What it does

The style guide's rules, applied mechanically: four spaces per level and never
tabs, opening brace on the same line as the statement it belongs to, closing
brace on its own line followed by the instance name, spaces around assignment
and expression operators, no space before the `;` that follows a `}`.

Line breaks *between* statements are yours. `rdlfmt` neither forces one
statement per line nor joins them, so grouping you put there on purpose
survives — which is also how the style guide's `sw`/`hw` exception is
accommodated without a special case. Note the two registers in the example
above: the first one's properties stay split, the second's stay joined. Runs of
blank lines collapse to one.

There is nothing to configure, deliberately. A formatter earns its value by
ending arguments, not by relocating them into a config file.

Comments and preprocessor directives survive. The parser builds a lossless
concrete syntax tree, so every byte of the input is present in the tree —
a `` `ifdef `` or a trailing `//` comment is data to be placed, not noise to be
dropped.

## What it will not do

**Format a file it did not fully understand.** If the input has syntax errors,
`rdlfmt` reports them and refuses, rather than reformatting a structure it had
to guess at.

**Change your code.** Every result is verified before it is returned: the output
is re-lexed and compared token by token against the input, and if anything but
whitespace moved, the output is withheld and you get a bug report instead of a
damaged file. That check is what makes rewriting files in place the default.

## Library

The formatter is also a library:

```rust
let formatted = rdlfmt::format(source)?;
```

`rdlfmt::syntax` exposes the lexer and the CST underneath, if you want the tree
rather than the text. Turn off default features to drop the CLI dependencies.

## License

Dual-licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
- MIT license ([LICENSE-MIT](LICENSE-MIT))

at your option.

