CLI reference¶
Run pinfit from the project directory or any of its descendants. To run the plain release jar on
your own Java 17+ instead of the installed bundle, substitute java -jar path/to/pinfit-<version>.jar for pinfit everywhere below.
Pinfit - YAML-driven C interface and module generator
Usage: pinfit <command> [options]
Commands:
init Create a new pinfit.yaml project
create Scaffold a new interface, module, or other spec
gen, generate Generate C source from YAML specs
rename Rename a module and update every reference to it
fix-prototypes Add missing prototypes for hand-written functions
detach Remove Pinfit tags and generated-file tracking (destructive)
Run 'pinfit help <command>' or 'pinfit <command> --help' for details on a command,
and 'pinfit --version' for the installed version.
pinfit, pinfit help and pinfit --help/-h all print the command list above, with no flag detail.
For a given command, either pinfit <command> --help/-h or pinfit help <command> prints that
command's full usage and flags — the sections below. pinfit --version (or -V) prints the
installed version, e.g. Pinfit 0.1.0. Errors print a red Pinfit error block, usually
followed by a cyan hint explaining how to fix the spec.
The same reference is also shipped as a Unix man page, man/man1/pinfit.1
in the repository. On a system with man, view it directly or install it:
man ./man/man1/pinfit.1
# or, to make `man pinfit` work from anywhere:
mkdir -p ~/.local/share/man/man1 && cp man/man1/pinfit.1 ~/.local/share/man/man1/ && mandb
pinfit init¶
Creates pinfit.yaml — and nothing else. Pinfit never chooses a source layout for you.
Without a directory it writes in the current one. It refuses to overwrite an existing pinfit.yaml
unless you pass -f.
See Project configuration for what the file contains.
pinfit create¶
Writes a spec file into directory, creating that directory when needed. Without a directory it
writes in the current one. The scaffold arrives pre-filled with commented examples of every field.
| Kind | Command |
|---|---|
| Interface | pinfit create interface common_iic drivers/Interface |
| Module | pinfit create module ra_iic drivers/RA --implements common_iic |
| State machine | pinfit create state-machine door [--engine builtin\|statesmith] |
| Observer | pinfit create observer button_events --interface button_listener --capacity 8 |
| Command table | pinfit create command-table uart_cmd |
| Status codes | pinfit create status-codes pinfit_status |
| Adapter | pinfit create adapter bus_adapter --from bus --to bus_hal |
Options¶
| Option | Applies to | Meaning |
|---|---|---|
--implements <name>[,<name>...] |
module | Interfaces the module implements. Comma-separated, no spaces. |
--interface <name> |
observer | The listener interface. Required. |
--capacity <n> |
observer | Maximum subscribers. |
--from <interface> |
adapter | The interface the adapter exposes. Required. |
--to <interface> |
adapter | The interface it calls into. Required. |
--dir <directory> |
all | The target directory, as an explicit flag instead of a positional argument. |
Creating does not generate
create writes YAML only. Run pinfit generate to produce the C.
Not into a nested project
pinfit create ... Lib/importedlib is refused when that directory has its own pinfit.yaml — you
would be writing a spec into another project, to be generated under the wrong rules. See
Nested projects.
pinfit generate¶
pinfit generate [directory] [-f|--force] [-v|--verbose] [--also-nested] [--strict]
pinfit gen [directory] ...
Scans the given directory tree (the current one by default), resolves every spec, and writes the
headers and sources. Interface references are resolved across the whole project, so specs can be
laid out however you like. gen is an alias.
Generation is idempotent: running it twice produces identical files the second time. User regions are carried across every run — see User regions.
-f, --force¶
Overwrite files on disk that are not Pinfit-generated, or that were edited outside their user regions, instead of refusing.
This destroys hand-written content
Pinfit normally refuses to write over a file lacking its generated-file marker, which is what
protects a hand-written ra_iic.c that predates the spec. --force removes that protection.
Commit first.
-v, --verbose¶
Replaces the progress bar with a per-file report of the project root, the scope, which spec produced each output, whether it is new or regenerated, and how many user regions were carried over:
Project root: D:\firmware
Scope: D:\firmware
[1/3] drivers\Interface\common_iic.interface.yaml -> drivers\Interface\common_iic_I.h (new file)
[2/3] drivers\RA\ra_iic.module.yaml -> drivers\RA\ra_iic.h (regenerated, no user regions found)
[3/3] drivers\RA\ra_iic.module.yaml -> drivers\RA\ra_iic.c (regenerated, 2 user region(s) carried over)
Use it when you want to confirm that your code was picked up, or to find which spec owns a file.
--also-nested¶
Also generate every nested project found under the scanned directory, each with its own
pinfit.yaml. Asks for confirmation first, after a fast directory count.
Full explanation.
--strict¶
Fails instead of warning when a non-void function falls back to a zero-initializer default -
same as strict: true in pinfit.yaml, for one run.
pinfit rename module¶
Renames a module: its spec file and its generated header and source are moved, the references are updated, and the project is regenerated in the same run.
Moved drivers\RA\ra_iic.module.yaml -> drivers\RA\ra_iic_master.module.yaml
Moved drivers\RA\ra_iic.h -> drivers\RA\ra_iic_master.h
Moved drivers\RA\ra_iic.c -> drivers\RA\ra_iic_master.c
Renamed module 'ra_iic' to 'ra_iic_master'
3 file(s) generated
Use this rather than renaming files by hand: edited region content moves with the files, and generated identifiers built from the module name are rebuilt consistently.
Your own call sites are not rewritten
Code inside user regions, and code elsewhere in your project that calls the old
ra_iic_* functions, is yours to update. The compiler will find them.
pinfit fix-prototypes¶
Scans every Pinfit-generated module source (.c) file in scope for functions you wrote directly
inside a usercode region that have no prototype anywhere in the file. This only catches plain
hand-written functions — a helper you added yourself, not part of any .module.yaml — since
YAML-spec'd module functions already get a prototype from Pinfit.
For each file with findings, it prints the function names and a unified diff (3 lines of context)
of the prototype(s) it would add to the module.source.prototypes usercode region at the top of
the file, then asks before writing anything:
drivers\RA\ra_iic.c - 1 function(s) without a prototype:
checksum
--- a/drivers\RA\ra_iic.c
+++ b/drivers\RA\ra_iic.c
@@ -14,6 +14,7 @@
/*@Pinfit usercode-*/
/*@Pinfit usercode+ module.source.prototypes*/
+static uint8_t checksum(const uint8_t *data, size_t length);
/*@Pinfit usercode-*/
/*@Pinfit(variable-definition:transfer_count)*/
Add these prototypes to the module.source.prototypes usercode region? [y/N]:
Answering anything but y/yes leaves that file untouched and moves on to the next one; the
command itself always exits 0 and reports how many prototypes were added, across how many files.
Single-line signatures only
This is a line-based scan, not a C parser. A function signature split across multiple lines won't be recognized — keep the return type, name and parameter list on one line, brace on the next (or the same) line, as Pinfit's own generated functions do.
pinfit detach¶
Permanently removes Pinfit from the project. It keeps all generated C code and unrelated YAML,
removes the Pinfit marker lines, then deletes pinfit.yaml and every Pinfit spec YAML
(*.interface.yaml, *.module.yaml, *.state-machine.yaml, *.status-codes.yaml,
*.observer.yaml, *.command-table.yaml, *.adapter.yaml), and the custom documentation YAML the
project referenced.
For an engine: statesmith state machine,
the generated .plantuml is kept - only its Pinfit marker is stripped, as documentation - it is not
deleted like the YAML specs above.
DESTRUCTIVE: detach Pinfit from this project
This removes all Pinfit tags and Pinfit-owned YAML configuration.
Generated C code and unrelated YAML files are kept.
Type the project name 'firmware' to continue:
You must type the exact project name from pinfit.yaml. Anything else cancels with nothing
changed.
There is no undo
A detached project cannot be regenerated unless it is configured again from scratch with
pinfit init. Commit before running it.
Like generate, detach stops at nested projects: a vendored library with its own pinfit.yaml is
left fully intact.
Exit codes¶
| Code | Meaning |
|---|---|
0 |
Success. |
1 |
A Pinfit error was printed — an invalid spec, a missing reference, a refused overwrite, an unreadable file — or a confirmation prompt was declined (detach, --also-nested). |
2 |
A Pinfit internal error was printed: a bug in Pinfit itself, not in your specs. Set PINFIT_DEBUG=1 and re-run to see the stack trace, and please report it. |
A declined confirmation is a non-zero exit deliberately, so a script that pipes n into
pinfit generate --also-nested does not report success for a run that generated nothing.