A small, deterministic codemod that rewrites Intel/DEC omitted-width Fortran FORMAT
descriptors (e.g., I, F.d, E.dE#, G.d, L) to standard-conforming
forms (e.g., I12, F25.16), improving portability across compilers (gfortran, ifx, etc.).
# From PyPI (when available)
pip install fortfmt-fix
# From source (development mode)
git clone https://github.com/anl-cec/fortfmt-fix.git
cd fortfmt-fix
pip install -e .# Show proposed changes without modifying files
fortfmt-fix --dry-run path/to/src
# Apply changes in-place
fortfmt-fix --in-place path/to/src
# Process specific files
fortfmt-fix --dry-run file1.f90 file2.f90
# Process directories recursively
fortfmt-fix --in-place src/from fortran_format_codemod import transform_source
# Basic usage
result = transform_source("WRITE(*,'(I)') i")
# Returns: "WRITE(*,'(I12)') i"
# With flags
result = transform_source(
"WRITE(*,'(I)') i",
int64=True, # Use I23 instead of I12
listify_reads=True, # Convert safe READ statements to list-directed
trace=True # Enable debug output
)The tool applies the following default widths when omitted:
| Descriptor | Default | With --int64 |
|---|---|---|
I |
I12 |
I23 |
L |
L2 |
L2 |
F |
F25.16 |
F25.16 |
E |
E25.16E3 |
E25.16E3 |
D |
D25.16E3 |
D25.16E3 |
G |
G25.16 |
G25.16 |
ES |
ES25.16E3 |
ES25.16E3 |
EN |
EN25.16E3 |
EN25.16E3 |
! Before
FORMAT(I, F.6, E.12E3)
! After
FORMAT(I12, F25.6, E25.12E3)! Before
WRITE(*,'(1X, 2(F.6, 1X), I)') a, b, c
! After
WRITE(*,'(1X, 2(F25.6, 1X), I12)') a, b, c! Before (with --listify-reads)
read(5, '(I, I, F.6)') i, j, x
! After
read(5, *) i, j, x--dry-run- Show proposed changes without modifying files--in-place- Apply changes directly to files--int64- Use wider integer defaults (I23 instead of I12) for 64-bit I/O--listify-reads- Convert safe READ statements to list-directed form--trace- Enable verbose debug output
fortfmt-fix is designed to be safe and idempotent:
- Conservative: Only transforms omitted-width descriptors, never touches explicit widths
- Idempotent: Running the tool multiple times produces identical results
- Preserves semantics: Quoted strings and non-format content are never modified
- Deterministic: No random behavior or network calls
For best results, use as a pre-commit hook to catch format issues early:
# Install pre-commit
pip install pre-commit
# Add to .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: fortfmt-fix
name: fortfmt-fix
entry: fortfmt-fix --dry-run
language: system
files: \.(f90|F90|f|F)$The package includes comprehensive tests covering:
- Basic descriptor transformations
- Nested groups and continuation lines
- Flag behavior (
--int64,--listify-reads) - Idempotence verification
- Edge cases and malformed input handling
- CLI smoke tests
Run tests with:
pytest -qdocs/OSS-Approval-OnePager.md- Project overview and approvalJOSS/paper.md- Academic paper describing the toolCHANGELOG.md- Version history and changes