# fortfmt-fix
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.).
## Quickstart
### Installation
```bash
# 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 .
```
### Command Line Usage
```bash
# 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/
```
### Python API
```python
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
)
```
## Default Widths
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` |
## Examples
### Basic FORMAT Statement
```fortran
! Before
FORMAT(I, F.6, E.12E3)
! After
FORMAT(I12, F25.6, E25.12E3)
```
### Nested Groups with Repeat Counts
```fortran
! Before
WRITE(*,'(1X, 2(F.6, 1X), I)') a, b, c
! After
WRITE(*,'(1X, 2(F25.6, 1X), I12)') a, b, c
```
### READ Statement Listification
```fortran
! Before (with --listify-reads)
read(5, '(I, I, F.6)') i, j, x
! After
read(5, *) i, j, x
```
## Command Line Options
- `--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
## Safety & Idempotence
**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
### Recommended Usage
For best results, use as a **pre-commit hook** to catch format issues early:
```bash
# 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)$
```
## Testing
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:
```bash
pytest -q
```
## See Also
- `docs/OSS-Approval-OnePager.md` - Project overview and approval
- `JOSS/paper.md` - Academic paper describing the tool
- `CHANGELOG.md` - Version history and changes
Raw data
{
"_id": null,
"home_page": null,
"name": "fortfmt-fix",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "fortran, compiler, modernization, portability, gfortran, intel, format",
"author": null,
"author_email": "David Bross <brossdh@anl.gov>",
"download_url": "https://files.pythonhosted.org/packages/f5/f9/0aa50f475defe35a02f5b3ff9de67e87c4abce20681ba2b5aead8e70b192/fortfmt_fix-0.1.0.tar.gz",
"platform": null,
"description": "# fortfmt-fix\n\nA small, deterministic codemod that rewrites Intel/DEC omitted-width Fortran FORMAT\ndescriptors (e.g., `I`, `F.d`, `E.dE#`, `G.d`, `L`) to **standard-conforming**\nforms (e.g., `I12`, `F25.16`), improving portability across compilers (gfortran, ifx, etc.).\n\n## Quickstart\n\n### Installation\n\n```bash\n# From PyPI (when available)\npip install fortfmt-fix\n\n# From source (development mode)\ngit clone https://github.com/anl-cec/fortfmt-fix.git\ncd fortfmt-fix\npip install -e .\n```\n\n### Command Line Usage\n\n```bash\n# Show proposed changes without modifying files\nfortfmt-fix --dry-run path/to/src\n\n# Apply changes in-place\nfortfmt-fix --in-place path/to/src\n\n# Process specific files\nfortfmt-fix --dry-run file1.f90 file2.f90\n\n# Process directories recursively\nfortfmt-fix --in-place src/\n```\n\n### Python API\n\n```python\nfrom fortran_format_codemod import transform_source\n\n# Basic usage\nresult = transform_source(\"WRITE(*,'(I)') i\")\n# Returns: \"WRITE(*,'(I12)') i\"\n\n# With flags\nresult = transform_source(\n \"WRITE(*,'(I)') i\", \n int64=True, # Use I23 instead of I12\n listify_reads=True, # Convert safe READ statements to list-directed\n trace=True # Enable debug output\n)\n```\n\n## Default Widths\n\nThe tool applies the following default widths when omitted:\n\n| Descriptor | Default | With `--int64` |\n|------------|---------|----------------|\n| `I` | `I12` | `I23` |\n| `L` | `L2` | `L2` |\n| `F` | `F25.16`| `F25.16` |\n| `E` | `E25.16E3` | `E25.16E3` |\n| `D` | `D25.16E3` | `D25.16E3` |\n| `G` | `G25.16`| `G25.16` |\n| `ES` | `ES25.16E3` | `ES25.16E3` |\n| `EN` | `EN25.16E3` | `EN25.16E3` |\n\n## Examples\n\n### Basic FORMAT Statement\n```fortran\n! Before\nFORMAT(I, F.6, E.12E3)\n\n! After\nFORMAT(I12, F25.6, E25.12E3)\n```\n\n### Nested Groups with Repeat Counts\n```fortran\n! Before\nWRITE(*,'(1X, 2(F.6, 1X), I)') a, b, c\n\n! After \nWRITE(*,'(1X, 2(F25.6, 1X), I12)') a, b, c\n```\n\n### READ Statement Listification\n```fortran\n! Before (with --listify-reads)\nread(5, '(I, I, F.6)') i, j, x\n\n! After\nread(5, *) i, j, x\n```\n\n## Command Line Options\n\n- `--dry-run` - Show proposed changes without modifying files\n- `--in-place` - Apply changes directly to files\n- `--int64` - Use wider integer defaults (I23 instead of I12) for 64-bit I/O\n- `--listify-reads` - Convert safe READ statements to list-directed form\n- `--trace` - Enable verbose debug output\n\n## Safety & Idempotence\n\n**fortfmt-fix** is designed to be safe and idempotent:\n\n- **Conservative**: Only transforms omitted-width descriptors, never touches explicit widths\n- **Idempotent**: Running the tool multiple times produces identical results\n- **Preserves semantics**: Quoted strings and non-format content are never modified\n- **Deterministic**: No random behavior or network calls\n\n### Recommended Usage\n\nFor best results, use as a **pre-commit hook** to catch format issues early:\n\n```bash\n# Install pre-commit\npip install pre-commit\n\n# Add to .pre-commit-config.yaml\nrepos:\n - repo: local\n hooks:\n - id: fortfmt-fix\n name: fortfmt-fix\n entry: fortfmt-fix --dry-run\n language: system\n files: \\.(f90|F90|f|F)$\n```\n\n## Testing\n\nThe package includes comprehensive tests covering:\n\n- Basic descriptor transformations\n- Nested groups and continuation lines \n- Flag behavior (`--int64`, `--listify-reads`)\n- Idempotence verification\n- Edge cases and malformed input handling\n- CLI smoke tests\n\nRun tests with:\n```bash\npytest -q\n```\n\n## See Also\n\n- `docs/OSS-Approval-OnePager.md` - Project overview and approval\n- `JOSS/paper.md` - Academic paper describing the tool\n- `CHANGELOG.md` - Version history and changes\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "Codemod to replace Intel/DEC omitted-width FORMATs with standard-conforming Fortran I/O",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/dbross/fortfmt-fix",
"Issues": "https://github.com/dbross/fortfmt-fix/issues",
"Repository": "https://github.com/dbross/fortfmt-fix"
},
"split_keywords": [
"fortran",
" compiler",
" modernization",
" portability",
" gfortran",
" intel",
" format"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a125a7212c9f3292243ff1abb1516bfb8c2df01d1d51fee846bf78dd26e5858f",
"md5": "6abf018bc3910754989cd9069ded5b38",
"sha256": "391520e3a67155f602848c7901e6669545bcd535e7ce5d382ae8679728511750"
},
"downloads": -1,
"filename": "fortfmt_fix-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6abf018bc3910754989cd9069ded5b38",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 11623,
"upload_time": "2025-10-08T19:02:59",
"upload_time_iso_8601": "2025-10-08T19:02:59.296427Z",
"url": "https://files.pythonhosted.org/packages/a1/25/a7212c9f3292243ff1abb1516bfb8c2df01d1d51fee846bf78dd26e5858f/fortfmt_fix-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f5f90aa50f475defe35a02f5b3ff9de67e87c4abce20681ba2b5aead8e70b192",
"md5": "86860fd8ec91e649bd637f91e7fc2f02",
"sha256": "1cfd418ee399eb4ac01101f4f63754a189998ead11dedb12182a6bfb98b5c134"
},
"downloads": -1,
"filename": "fortfmt_fix-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "86860fd8ec91e649bd637f91e7fc2f02",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 15308,
"upload_time": "2025-10-08T19:03:00",
"upload_time_iso_8601": "2025-10-08T19:03:00.301840Z",
"url": "https://files.pythonhosted.org/packages/f5/f9/0aa50f475defe35a02f5b3ff9de67e87c4abce20681ba2b5aead8e70b192/fortfmt_fix-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-08 19:03:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dbross",
"github_project": "fortfmt-fix",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "fortfmt-fix"
}