A host-only, schema-driven namelist parser and validator. Validates a
namelist file against a registered schema of groups and keys,
collecting ALL errors (with path:line: prefixes, did-you-mean
suggestions, range/enum/length checks) and rejecting unsupported
syntax (repeat-counts, indexed assignment, derived-type refs).
Defaults contract (load-bearing): every key constructor captures its default from the CURRENT target value at registration; the schema NEVER takes a default argument. Register AFTER config defaults exist, BEFORE parsing.
Required-key semantics: a required=.true. key must appear whenever
its GROUP appears; an absent group is fine (defaults rule).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private, | parameter | :: | MAX_SUGGEST_LEN | = | 64 |
Cap on names fed to the Levenshtein suggester. |
| integer, | private, | parameter | :: | rk | = | wp |
Working real kind — tracks the solver |
Cross-key validation callback. Empty string = OK; a non-empty string is appended to the collected errors.
Captured default value, formatted for namelist output.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_key_t), | intent(in) | :: | this |
True if the current target value equals the captured default.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_key_t), | intent(in) | :: | this |
Validate values and assign through the target pointer.
On success err_msg is left unallocated.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
Current target value, formatted for namelist output.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_key_t), | intent(in) | :: | this |
Enum key: a string restricted to an allowed list, validated case-insensitively and assigned its canonical spelling.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | allowed(:) | |||
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| character(len=:), | public, | allocatable | :: | default | |||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| character(len=:), | public, | allocatable | :: | retired(:) |
Spellings that USED to be legal and no longer are (renamed or
withdrawn). A namelist still carrying one must not fall
through to the bare “not in allowed set {…}” message — that
tells the reader the value is wrong but not what replaced it.
Matching one of these fails loud with |
||
| character(len=:), | public, | allocatable | :: | retired_hint |
What to say when a retired spelling is used. Name the replacement; this string IS the migration instruction. |
||
| character(len=:), | public, | pointer | :: | tgt | => | null() | |
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
| procedure, public :: default_string => string_default_string | |
| procedure, public :: is_default => string_is_default | |
| procedure, public :: parse_tokens => enum_parse | |
| procedure, public :: value_string => string_value_string |
A namelist group: a name, doc, growable key list, parse-state, and an optional cross-key validation callback.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| procedure(group_check_iface), | public, | pointer, nopass | :: | cross_check | => | null() |
Optional cross-key validator (empty string = OK). |
| character(len=:), | public, | allocatable | :: | doc |
Group description. |
||
| logical, | public | :: | found | = | .false. |
Parse-state: true when the group appears in the file. |
|
| type(nml_key_box_t), | public, | allocatable | :: | keys(:) |
Registered keys. |
||
| character(len=:), | public, | allocatable | :: | name |
Group name (matched case-insensitively). |
| procedure, public :: add => group_add | |
| procedure, public :: find_key => group_find_key |
Integer-valued key with optional [min,max] range validation.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| integer, | public | :: | default | = | 0 | ||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| logical, | public | :: | has_max | = | .false. | ||
| logical, | public | :: | has_min | = | .false. | ||
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| integer, | public, | pointer | :: | tgt | => | null() | |
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
||
| integer, | public | :: | vmax | = | 0 | ||
| integer, | public | :: | vmin | = | 0 |
| procedure, public :: default_string => int_default_string | |
| procedure, public :: is_default => int_is_default | |
| procedure, public :: parse_tokens => int_parse | |
| procedure, public :: value_string => int_value_string |
Boxes a polymorphic key so groups can hold a growable array.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| class(nml_key_t), | public, | allocatable | :: | key |
Abstract base for a single namelist key descriptor.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
| procedure(default_string_iface), public, deferred :: default_string | |
| procedure(is_default_iface), public, deferred :: is_default | |
| procedure(parse_tokens_iface), public, deferred :: parse_tokens | |
| procedure(value_string_iface), public, deferred :: value_string |
Logical-valued key.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| logical, | public | :: | default | = | .false. | ||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| logical, | public, | pointer | :: | tgt | => | null() | |
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
| procedure, public :: default_string => logical_default_string | |
| procedure, public :: is_default => logical_is_default | |
| procedure, public :: parse_tokens => logical_parse | |
| procedure, public :: value_string => logical_value_string |
Real-array key: accepts 1..size(tgt) values, fills from element 1, errors if more than size(tgt) values are given.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| real(kind=rk), | public, | allocatable | :: | default(:) | |||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| real(kind=rk), | public, | pointer | :: | tgt(:) | => | null() | |
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
| procedure, public :: default_string => real_array_default_string | |
| procedure, public :: is_default => real_array_is_default | |
| procedure, public :: parse_tokens => real_array_parse | |
| procedure, public :: value_string => real_array_value_string |
Real-valued key with optional [min,max] range validation.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| real(kind=rk), | public | :: | default | = | 0.0_rk | ||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| logical, | public | :: | has_max | = | .false. | ||
| logical, | public | :: | has_min | = | .false. | ||
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| real(kind=rk), | public, | pointer | :: | tgt | => | null() | |
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
||
| real(kind=rk), | public | :: | vmax | = | 0.0_rk | ||
| real(kind=rk), | public | :: | vmin | = | 0.0_rk |
| procedure, public :: default_string => real_default_string | |
| procedure, public :: is_default => real_is_default | |
| procedure, public :: parse_tokens => real_parse | |
| procedure, public :: value_string => real_value_string |
The top-level schema: validated groups plus external (skipped) group names.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | external_names(:) |
Names of groups whose bodies are skipped without validation. |
||
| type(nml_group_t), | public, | allocatable | :: | groups(:) |
Registered, validated groups. |
| procedure, public :: add_external_group => schema_add_external_group | |
| procedure, public :: add_group => schema_add_group | |
| procedure, public :: find_group => schema_find_group | |
| procedure, public :: is_external => schema_is_external | |
| procedure, public :: parse => schema_parse | |
| procedure, public :: parse_lines => schema_parse_lines | |
| procedure, public :: render_json => schema_render_json | |
| procedure, public :: render_markdown => schema_render_markdown | |
| procedure, public :: write_doc_all => schema_write_doc_all | |
| procedure, public :: write_doc_short => schema_write_doc_short |
String key. Deferred-len char pointer associates with a fixed-len target and assumes its length; parsing errors if the parsed value is LONGER than len(tgt) (no silent truncation).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=:), | public, | allocatable | :: | dead_reason |
Unallocated/empty = live. Non-empty = this knob is registered
(accepted, type/range-validated) but does NOT reach any
ocean-path behaviour – e.g. |
||
| character(len=:), | public, | allocatable | :: | default | |||
| character(len=:), | public, | allocatable | :: | doc |
Human-readable description (FORD-style synthesis doc). |
||
| logical, | public | :: | found | = | .false. |
Parse-state: set true when the key is seen in the file. |
|
| character(len=:), | public, | allocatable | :: | name |
Key name (matched case-insensitively). |
||
| logical, | public | :: | required | = | .false. |
If true, the key must appear whenever its group appears. |
|
| character(len=:), | public, | pointer | :: | tgt | => | null() | |
| character(len=:), | public, | allocatable | :: | units |
Optional units string, default ‘’. |
| procedure, public :: default_string => string_default_string | |
| procedure, public :: is_default => string_is_default | |
| procedure, public :: parse_tokens => string_parse | |
| procedure, public :: value_string => string_value_string |
Construct an enum key restricted to allowed, capturing the
current target as default.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| character(len=:), | intent(in), | pointer | :: | tgt | ||
| character(len=*), | intent(in) | :: | doc | |||
| character(len=*), | intent(in) | :: | allowed(:) | |||
| character(len=*), | intent(in), | optional | :: | units | ||
| logical, | intent(in), | optional | :: | required | ||
| character(len=*), | intent(in), | optional | :: | dead_on_ocean_path | ||
| character(len=*), | intent(in), | optional | :: | retired(:) | ||
| character(len=*), | intent(in), | optional | :: | retired_hint |
Construct an integer key, capturing the current target as default.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| integer, | intent(in), | pointer | :: | tgt | ||
| character(len=*), | intent(in) | :: | doc | |||
| character(len=*), | intent(in), | optional | :: | units | ||
| logical, | intent(in), | optional | :: | required | ||
| integer, | intent(in), | optional | :: | min | ||
| integer, | intent(in), | optional | :: | max | ||
| character(len=*), | intent(in), | optional | :: | dead_on_ocean_path |
Construct a logical key, capturing the current target as default.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| logical, | intent(in), | pointer | :: | tgt | ||
| character(len=*), | intent(in) | :: | doc | |||
| character(len=*), | intent(in), | optional | :: | units | ||
| logical, | intent(in), | optional | :: | required | ||
| character(len=*), | intent(in), | optional | :: | dead_on_ocean_path |
Construct a real key, capturing the current target as default.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| real(kind=rk), | intent(in), | pointer | :: | tgt | ||
| character(len=*), | intent(in) | :: | doc | |||
| character(len=*), | intent(in), | optional | :: | units | ||
| logical, | intent(in), | optional | :: | required | ||
| real(kind=rk), | intent(in), | optional | :: | min | ||
| real(kind=rk), | intent(in), | optional | :: | max | ||
| character(len=*), | intent(in), | optional | :: | dead_on_ocean_path |
Construct a real-array key, capturing the current target as default (whole-array compare for is_default).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| real(kind=rk), | intent(in), | pointer | :: | tgt(:) | ||
| character(len=*), | intent(in) | :: | doc | |||
| character(len=*), | intent(in), | optional | :: | units | ||
| logical, | intent(in), | optional | :: | required | ||
| character(len=*), | intent(in), | optional | :: | dead_on_ocean_path |
Construct a string key, capturing the current target as default.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| character(len=:), | intent(in), | pointer | :: | tgt | ||
| character(len=*), | intent(in) | :: | doc | |||
| character(len=*), | intent(in), | optional | :: | units | ||
| logical, | intent(in), | optional | :: | required | ||
| character(len=*), | intent(in), | optional | :: | dead_on_ocean_path |
Format an integer.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | v |
Format a logical as a JSON true/false literal (as opposed to
fmt_logical’s Fortran .true./.false.).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| logical, | intent(in) | :: | v |
Format a logical as namelist .true./.false..
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| logical, | intent(in) | :: | v |
Format a real in a stable, namelist-valid exponential form.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=rk), | intent(in) | :: | v |
Index of name in the group’s key list, 0 if absent.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_group_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | name |
All key names of a group as a char array.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_group_t), | intent(in) | :: | g |
All registered + external group names as a char array.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_schema_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_int_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_int_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_int_key_t), | intent(in) | :: | this |
True for identifier characters (alnum + underscore).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=1), | intent(in) | :: | c |
True if word looks like N*value (integer, then ‘*’).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | word |
Minimal JSON string escaping: backslash, double-quote, and the common control characters. Doc/name/units strings in this codebase are plain single-line ASCII, so this is deliberately not a general-purpose escaper.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | s |
Real -> JSON number, robust to extreme magnitude (e.g. huge(wp)
floor/ceiling sentinels like kv_max’s default): fmt_real’s
E18.10 is too narrow for a 3-digit exponent and gfortran drops
the E literal to fit (“0.1797693135+309”), which is not valid
JSON. ES.E3 explicitly requests a 3-digit exponent field, which
forces the E to stay, at a width sized for the worst case. 16
fraction digits (17 significant figures) is real64’s round-trip
guarantee – one digit short (as an earlier version of this
function used) rounds huge(wp)’s text UP past the true maximum
finite double, so re-parsing it (e.g. Python’s json.load)
overflows to infinity, which is not valid JSON and breaks the
generator (tools/gen_python_config.py) that reads this file.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=rk), | intent(in) | :: | v |
Render arr(:) as a comma-separated list of JSON numbers (no
enclosing brackets).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=rk), | intent(in) | :: | arr(:) |
Render arr(:) as a comma-separated list of JSON-quoted strings
(no enclosing brackets – the caller supplies those).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | arr(:) |
Levenshtein edit distance between two (capped) strings.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | a | |||
| character(len=*), | intent(in) | :: | b |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_logical_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_logical_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_logical_key_t), | intent(in) | :: | this |
Lowercase an ASCII string.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | s |
Build a path:line: error prefix.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | path | |||
| integer, | intent(in) | :: | line |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_array_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_array_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_array_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_key_t), | intent(in) | :: | this |
Index of name in the schema’s groups, 0 if absent.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | name |
True if name is a registered external group.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | name |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_string_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_string_key_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_string_key_t), | intent(in) | :: | this |
Remove a trailing ! comment, respecting single/double quotes.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | line |
Drop a trailing _nml suffix (namelist files spell groups
&<name>_nml; the schema stores the bare <name>).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
Build a ” (did you mean ‘x’?)” fragment if a close candidate exists (distance <= max(2, len/3)); else empty.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name | |||
| character(len=*), | intent(in) | :: | candidates(:) |
Append a message to a growable error list.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err | |||
| character(len=*), | intent(in) | :: | msg |
Append one value token to the values buffer.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=256), | intent(inout), | allocatable | :: | vals(:) | ||
| integer, | intent(inout) | :: | vcount | |||
| character(len=*), | intent(in) | :: | tok |
Consume one key = value [value...] starting at token ti;
advance ti past the consumed tokens. Validates structure,
unknown keys, duplicate keys, and applies via parse_tokens.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_group_t), | intent(inout) | :: | g | |||
| character(len=256), | intent(in) | :: | tokens(:) | |||
| integer, | intent(in) | :: | tok_line(:) | |||
| integer, | intent(in) | :: | n_tok | |||
| integer, | intent(inout) | :: | ti | |||
| character(len=*), | intent(in) | :: | path | |||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err |
Flag unsupported namelist syntax embedded in a bare token.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | word | |||
| character(len=*), | intent(in) | :: | path | |||
| integer, | intent(in) | :: | line | |||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err |
Tokenize a group body up to and including the terminating ‘/’. Token kinds are encoded by their text: “=” , “,” , a quoted or bare value, an identifier, or special markers for unsupported syntax which are flagged here. The ‘/’ ends collection.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(inout) | :: | li | |||
| integer, | intent(inout) | :: | col | |||
| character(len=*), | intent(in) | :: | path | |||
| character(len=256), | intent(out), | allocatable | :: | tokens(:) | ||
| integer, | intent(out), | allocatable | :: | tok_line(:) | ||
| integer, | intent(out) | :: | n_tok | |||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err |
Resolve a group name to known / external / unknown and parse (or skip) its body up to the terminating ‘/’.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(inout) | :: | li | |||
| integer, | intent(inout) | :: | col | |||
| character(len=*), | intent(in) | :: | gname | |||
| character(len=*), | intent(in) | :: | prefix | |||
| logical, | intent(inout), | allocatable | :: | group_seen(:) | ||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err | |||
| character(len=*), | intent(in) | :: | path |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_enum_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
Add a key to the group (sourced-allocate into a box). Error stop on duplicate key name (programming error).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_group_t), | intent(inout) | :: | this | |||
| class(nml_key_t), | intent(in) | :: | key |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_int_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_logical_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
Transfer a group’s contents without copying any polymorphic key box (descriptor moves only — see schema_add_group).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_group_t), | intent(inout) | :: | src | |||
| type(nml_group_t), | intent(inout) | :: | dst |
Advance (li,col) to the character AFTER the next ‘&’. On EOF sets li = n_lines + 1. Bare non-blank tokens before ‘&’ are tolerated as inter-group whitespace.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(inout) | :: | li | |||
| integer, | intent(inout) | :: | col |
Read the namelist file at path, then drive the parse. The file
is the only on-disk touch; the walk runs on the in-memory lines
(shared with the from-buffer path, parse_from_lines).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | path | |||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err |
Walk an in-memory namelist (already split into lines): strip
comments, scan for &group headers, dispatch keys. label
names the source in error messages — a file path for parse_file,
a sentinel (e.g. “
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| character(len=*), | intent(in) | :: | label | |||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err |
Tokenize and apply key = value... pairs until ‘/’.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_group_t), | intent(inout) | :: | g | |||
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(inout) | :: | li | |||
| integer, | intent(inout) | :: | col | |||
| character(len=*), | intent(in) | :: | path | |||
| character(len=:), | intent(inout), | allocatable | :: | errors(:) | ||
| integer, | intent(inout) | :: | n_err |
Required-key + cross-check pass shared by the file and buffer parsers, then the error-return / error-stop finalization.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | label | |||
| character(len=:), | intent(inout), | allocatable | :: | err_buf(:) | ||
| integer, | intent(inout) | :: | n_err | |||
| integer, | intent(out), | optional | :: | status | ||
| character(len=:), | intent(out), | optional, | allocatable | :: | errors(:) |
Append a token, growing the buffer as needed.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=256), | intent(inout), | allocatable | :: | tokens(:) | ||
| integer, | intent(inout), | allocatable | :: | tok_line(:) | ||
| integer, | intent(inout) | :: | n_tok | |||
| character(len=*), | intent(in) | :: | val | |||
| integer, | intent(in) | :: | line |
Read an identifier starting at (li,col); advance past it.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(inout) | :: | li | |||
| integer, | intent(inout) | :: | col | |||
| character(len=:), | intent(out), | allocatable | :: | gname |
Read the whole file into a deferred-len line array.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | path | |||
| character(len=:), | intent(out), | allocatable | :: | lines(:) | ||
| integer, | intent(out) | :: | n_lines | |||
| logical, | intent(out) | :: | ok |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_array_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_real_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
Reset parse-state (found flags) before a parse.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(nml_schema_t), | intent(inout) | :: | this |
Register a group name the schema knows exists but does NOT validate (its body is skipped silently).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | name |
MOVE a locally-built group into the schema — g is consumed
(allocatables transferred). Move semantics on purpose: intrinsic
assignment deep-copies the polymorphic key boxes, which NVHPC
miscompiles (heap corruption); move_alloc transfers descriptors
only. Error stop on duplicate name.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(inout) | :: | this | |||
| type(nml_group_t), | intent(inout) | :: | g |
Parse and validate the namelist file at path.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | path | |||
| integer, | intent(out), | optional | :: | status | ||
| character(len=:), | intent(out), | optional, | allocatable | :: | errors(:) |
In-memory sibling of schema_parse: validate + apply a namelist
already held as a lines(:) character array (no file touch).
Same error-return convention as schema_parse.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(out), | optional | :: | status | ||
| character(len=:), | intent(out), | optional, | allocatable | :: | errors(:) |
Emit the schema as JSON: one object per group, nesting one object
per key. This is the ONLY thing tools/gen_python_config.py
reads – it parses no Fortran source, mirroring the precedent
schema_render_markdown already set for docs/generated_nml_knobs.md.
&ocean_bc_nml is NOT here – it is registered via
add_external_group (see rdb_config.F90), so it carries no keys
on this schema; python/rdb/_config_bc.py is a hand-written
stub with its own drift test (see docs D5.7).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | path |
Render the schema as Markdown: per group a heading, doc line, and a knob table.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | path |
Write every group and key as valid namelist with aligned docs.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | path |
Write only non-default keys (MOM6 parameter_doc.short). Groups with no non-default keys are omitted entirely.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_schema_t), | intent(in) | :: | this | |||
| character(len=*), | intent(in) | :: | path |
Advance past the next ‘/’ (group terminator); recovery aid.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | lines(:) | |||
| integer, | intent(in) | :: | n_lines | |||
| integer, | intent(inout) | :: | li | |||
| integer, | intent(inout) | :: | col |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nml_string_key_t), | intent(inout) | :: | this | |||
| character(len=*), | intent(in) | :: | values(:) | |||
| character(len=:), | intent(out), | allocatable | :: | err_msg |
Write one key as a JSON object. A select type over the
concrete key recovers the kind-specific fields (vmin/vmax,
allowed(:), array size) that nml_key_t’s abstract interface
does not carry – the one place this walk needs the concrete
type (schema_render_markdown does not, since default_string()
is polymorphic).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | u | |||
| type(nml_key_box_t), | intent(in) | :: | box | |||
| logical, | intent(in) | :: | is_last |
Write one aligned key = value ! [units] doc line. When
short_only, skip default-valued keys (and leave wrote_any).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | unit | |||
| type(nml_key_box_t), | intent(in) | :: | box | |||
| logical, | intent(in) | :: | short_only | |||
| logical, | intent(inout) | :: | wrote_any |