rdb_nml_schema Module

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).


Uses

  • module~~rdb_nml_schema~~UsesGraph module~rdb_nml_schema rdb_nml_schema module~rdb_constants rdb_constants module~rdb_nml_schema->module~rdb_constants module~rdb_error_ring rdb_error_ring module~rdb_nml_schema->module~rdb_error_ring pic_logger pic_logger module~rdb_nml_schema->pic_logger pic_types pic_types module~rdb_constants->pic_types module~rdb_error_ring->pic_logger

Used by

  • module~~rdb_nml_schema~~UsedByGraph module~rdb_nml_schema rdb_nml_schema module~rdb_config rdb_config module~rdb_config->module~rdb_nml_schema module~rdb_config_schema rdb_config_schema module~rdb_config_schema->module~rdb_config module~rdb_decomp rdb_decomp module~rdb_decomp->module~rdb_config module~rdb_driver rdb_driver module~rdb_driver->module~rdb_config module~rdb_ocean_engine rdb_ocean_engine module~rdb_driver->module~rdb_ocean_engine module~rdb_ocean_state rdb_ocean_state module~rdb_driver->module~rdb_ocean_state module~rdb_halo rdb_halo module~rdb_driver->module~rdb_halo module~rdb_ocean_console_stats rdb_ocean_console_stats module~rdb_driver->module~rdb_ocean_console_stats module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_driver->module~rdb_ocean_dyn module~rdb_handle rdb_handle module~rdb_handle->module~rdb_config module~rdb_handle->module~rdb_ocean_engine module~rdb_handle->module~rdb_ocean_state module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_config module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_fold_apply rdb_ocean_fold_apply module~rdb_ocean_api->module~rdb_ocean_fold_apply module~rdb_ocean_data_forcing rdb_ocean_data_forcing module~rdb_ocean_data_forcing->module~rdb_config module~rdb_ocean_data_input rdb_ocean_data_input module~rdb_ocean_data_forcing->module~rdb_ocean_data_input module~rdb_ocean_halo_state rdb_ocean_halo_state module~rdb_ocean_data_forcing->module~rdb_ocean_halo_state module~rdb_ocean_data_input->module~rdb_config module~rdb_ocean_engine->module~rdb_config module~rdb_ocean_engine->module~rdb_decomp module~rdb_ocean_engine->module~rdb_ocean_data_forcing module~rdb_ocean_engine->module~rdb_ocean_data_input module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ocean_stability_audit rdb_ocean_stability_audit module~rdb_ocean_engine->module~rdb_ocean_stability_audit module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_state rdb_state module~rdb_ocean_engine->module~rdb_state module~rdb_ocean_engine->module~rdb_halo module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_fold_exchange rdb_ocean_fold_exchange module~rdb_ocean_engine->module~rdb_ocean_fold_exchange module~rdb_ocean_halo rdb_ocean_halo module~rdb_ocean_engine->module~rdb_ocean_halo module~rdb_ice_evp rdb_ice_evp module~rdb_ocean_engine->module~rdb_ice_evp module~rdb_ice_transport rdb_ice_transport module~rdb_ocean_engine->module~rdb_ice_transport module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_engine->module~rdb_ocean_fold_apply module~rdb_ocean_engine->module~rdb_ocean_halo_state module~rdb_ocean_setup->module~rdb_config module~rdb_ocean_setup->module~rdb_decomp module~rdb_ocean_setup->module~rdb_ocean_state module~rdb_ocean_setup->module~rdb_halo module~rdb_ocean_setup->module~rdb_ocean_fold_exchange module~rdb_ocean_setup->module~rdb_ocean_halo module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_fold_apply module~rdb_ocean_setup->module~rdb_ocean_halo_state module~rdb_ocean_stability_audit->module~rdb_config module~rdb_ocean_state->module~rdb_config module~rdb_ocean_state->module~rdb_decomp module~rdb_ocean_state->module~rdb_ocean_data_forcing module~rdb_ocean_state->module~rdb_ocean_data_input module~rdb_ocean_z_init rdb_ocean_z_init module~rdb_ocean_state->module~rdb_ocean_z_init module~rdb_ocean_restart_io rdb_ocean_restart_io module~rdb_ocean_state->module~rdb_ocean_restart_io module~rdb_continuity rdb_continuity module~rdb_ocean_state->module~rdb_continuity module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_ocean_z_init->module~rdb_config module~rdb_state->module~rdb_config module~rdb_halo->module~rdb_decomp module~rdb_ocean_diag_derived->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_diag_fills module~rdb_ocean_diag_fills->module~rdb_ocean_state module~rdb_ocean_fold_exchange->module~rdb_decomp module~rdb_ocean_halo->module~rdb_decomp module~rdb_ocean_restart_io->module~rdb_decomp module~rdb_barotropic_substep rdb_barotropic_substep module~rdb_barotropic_substep->module~rdb_ocean_fold_exchange module~rdb_barotropic_substep->module~rdb_ocean_halo module~rdb_continuity->module~rdb_ocean_fold_exchange module~rdb_continuity->module~rdb_ocean_halo module~rdb_continuity->module~rdb_ocean_fold_apply module~rdb_ice_evp->module~rdb_ocean_halo module~rdb_ice_transport->module~rdb_halo module~rdb_ice_transport->module~rdb_ocean_halo module~rdb_ice_transport->module~rdb_continuity module~rdb_ice_transport->module~rdb_ocean_halo_state module~rdb_ocean_bt_wide rdb_ocean_bt_wide module~rdb_ocean_bt_wide->module~rdb_ocean_halo module~rdb_ocean_bt_wide->module~rdb_barotropic_substep module~rdb_ocean_chksum rdb_ocean_chksum module~rdb_ocean_chksum->module~rdb_halo module~rdb_ocean_console_stats->module~rdb_halo module~rdb_ocean_dyn->module~rdb_ocean_halo module~rdb_ocean_dyn->module~rdb_barotropic_substep module~rdb_ocean_dyn->module~rdb_continuity module~rdb_ocean_dyn->module~rdb_ocean_bt_wide module~rdb_ocean_dyn->module~rdb_ocean_chksum module~rdb_ocean_dyn->module~rdb_ocean_console_stats module~rdb_ocean_dyn->module~rdb_ocean_fold_apply module~rdb_ocean_dyn->module~rdb_ocean_halo_state module~rdb_ocean_fold_apply->module~rdb_ocean_fold_exchange module~rdb_ocean_halo_state->module~rdb_ocean_halo module~rdb_ocean_halo_state->module~rdb_ocean_fold_apply proc~ocean_cavity_mass_step ocean_cavity_mass_step proc~ocean_cavity_mass_step->module~rdb_halo module~rdb_ice_ocean_coupler rdb_ice_ocean_coupler module~rdb_ice_ocean_coupler->module~rdb_ocean_halo_state

Variables

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 wp so real(wp) config targets associate in either single- or double-precision builds.


Abstract Interfaces

abstract interface

  • public function group_check_iface() result(msg)

    Cross-key validation callback. Empty string = OK; a non-empty string is appended to the collected errors.

    Arguments

    None

    Return Value character(len=:), allocatable

abstract interface

  • private function default_string_iface(this) result(str)

    Captured default value, formatted for namelist output.

    Arguments

    Type IntentOptional Attributes Name
    class(nml_key_t), intent(in) :: this

    Return Value character(len=:), allocatable

abstract interface

  • private function is_default_iface(this) result(yes)

    True if the current target value equals the captured default.

    Arguments

    Type IntentOptional Attributes Name
    class(nml_key_t), intent(in) :: this

    Return Value logical

abstract interface

  • private subroutine parse_tokens_iface(this, values, err_msg)

    Validate values and assign through the target pointer. On success err_msg is left unallocated.

    Arguments

    Type IntentOptional Attributes Name
    class(nml_key_t), intent(inout) :: this
    character(len=*), intent(in) :: values(:)
    character(len=:), intent(out), allocatable :: err_msg

abstract interface

  • private function value_string_iface(this) result(str)

    Current target value, formatted for namelist output.

    Arguments

    Type IntentOptional Attributes Name
    class(nml_key_t), intent(in) :: this

    Return Value character(len=:), allocatable


Derived Types

type, public, extends(nml_string_key_t) ::  nml_enum_key_t

Enum key: a string restricted to an allowed list, validated case-insensitively and assigned its canonical spelling.

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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 retired_hint instead.

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 ‘’.

Type-Bound Procedures

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

type, public ::  nml_group_t

A namelist group: a name, doc, growable key list, parse-state, and an optional cross-key validation callback.

Components

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).

Type-Bound Procedures

procedure, public :: add => group_add
procedure, public :: find_key => group_find_key

type, public, extends(nml_key_t) ::  nml_int_key_t

Integer-valued key with optional [min,max] range validation.

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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

Type-Bound Procedures

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

type, public ::  nml_key_box_t

Boxes a polymorphic key so groups can hold a growable array.

Components

Type Visibility Attributes Name Initial
class(nml_key_t), public, allocatable :: key

type, public, abstract ::  nml_key_t

Abstract base for a single namelist key descriptor.

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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 ‘’.

Type-Bound Procedures

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

type, public, extends(nml_key_t) ::  nml_logical_key_t

Logical-valued key.

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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 ‘’.

Type-Bound Procedures

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

type, public, extends(nml_key_t) ::  nml_real_array_key_t

Real-array key: accepts 1..size(tgt) values, fills from element 1, errors if more than size(tgt) values are given.

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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 ‘’.

Type-Bound Procedures

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

type, public, extends(nml_key_t) ::  nml_real_key_t

Real-valued key with optional [min,max] range validation.

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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

Type-Bound Procedures

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

type, public ::  nml_schema_t

The top-level schema: validated groups plus external (skipped) group names.

Components

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.

Type-Bound Procedures

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

type, public, extends(nml_key_t) ::  nml_string_key_t

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).

Components

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. &vcoord_nml zstar_stretching is captured on cfg but never copied onto ocean_state%vcoord (rdb_ocean_vcoord.F90:179,182). Carried into the JSON emitter (render_json) so a generated caller-side layer can warn on assignment instead of presenting a dead knob as live.

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 ‘’.

Type-Bound Procedures

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

Functions

public function nml_enum(name, tgt, doc, allowed, units, required, dead_on_ocean_path, retired, retired_hint) result(key)

Construct an enum key restricted to allowed, capturing the current target as default.

Read more…

Arguments

Type IntentOptional 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

Return Value type(nml_enum_key_t)

public function nml_int(name, tgt, doc, units, required, min, max, dead_on_ocean_path) result(key)

Construct an integer key, capturing the current target as default.

Arguments

Type IntentOptional 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

Return Value type(nml_int_key_t)

public function nml_logical(name, tgt, doc, units, required, dead_on_ocean_path) result(key)

Construct a logical key, capturing the current target as default.

Arguments

Type IntentOptional 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

Return Value type(nml_logical_key_t)

public function nml_real(name, tgt, doc, units, required, min, max, dead_on_ocean_path) result(key)

Construct a real key, capturing the current target as default.

Arguments

Type IntentOptional 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

Return Value type(nml_real_key_t)

public function nml_real_array(name, tgt, doc, units, required, dead_on_ocean_path) result(key)

Construct a real-array key, capturing the current target as default (whole-array compare for is_default).

Arguments

Type IntentOptional 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

Return Value type(nml_real_array_key_t)

public function nml_string(name, tgt, doc, units, required, dead_on_ocean_path) result(key)

Construct a string key, capturing the current target as default.

Arguments

Type IntentOptional 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

Return Value type(nml_string_key_t)

private pure function fmt_int(v) result(str)

Format an integer.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: v

Return Value character(len=:), allocatable

private pure function fmt_json_bool(v) result(str)

Format a logical as a JSON true/false literal (as opposed to fmt_logical’s Fortran .true./.false.).

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: v

Return Value character(len=:), allocatable

private pure function fmt_logical(v) result(str)

Format a logical as namelist .true./.false..

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: v

Return Value character(len=:), allocatable

private pure function fmt_real(v) result(str)

Format a real in a stable, namelist-valid exponential form.

Arguments

Type IntentOptional Attributes Name
real(kind=rk), intent(in) :: v

Return Value character(len=:), allocatable

private function group_find_key(this, name) result(idx)

Index of name in the group’s key list, 0 if absent.

Arguments

Type IntentOptional Attributes Name
class(nml_group_t), intent(in) :: this
character(len=*), intent(in) :: name

Return Value integer

private function group_key_list(g) result(names)

All key names of a group as a char array.

Arguments

Type IntentOptional Attributes Name
type(nml_group_t), intent(in) :: g

Return Value character(len=:), allocatable, (:)

private function group_name_list(this) result(names)

All registered + external group names as a char array.

Arguments

Type IntentOptional Attributes Name
type(nml_schema_t), intent(in) :: this

Return Value character(len=:), allocatable, (:)

private function int_default_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_int_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function int_is_default(this) result(yes)

Arguments

Type IntentOptional Attributes Name
class(nml_int_key_t), intent(in) :: this

Return Value logical

private function int_value_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_int_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private pure function is_ident_char(c) result(yes)

True for identifier characters (alnum + underscore).

Arguments

Type IntentOptional Attributes Name
character(len=1), intent(in) :: c

Return Value logical

private pure function is_repeat_count(word) result(yes)

True if word looks like N*value (integer, then ‘*’).

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: word

Return Value logical

private pure function json_escape(s) result(out)

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.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: s

Return Value character(len=:), allocatable

private pure function json_fmt_real(v) result(str)

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.

Arguments

Type IntentOptional Attributes Name
real(kind=rk), intent(in) :: v

Return Value character(len=:), allocatable

private pure function json_real_array(arr) result(str)

Render arr(:) as a comma-separated list of JSON numbers (no enclosing brackets).

Arguments

Type IntentOptional Attributes Name
real(kind=rk), intent(in) :: arr(:)

Return Value character(len=:), allocatable

private pure function json_string_array(arr) result(str)

Render arr(:) as a comma-separated list of JSON-quoted strings (no enclosing brackets – the caller supplies those).

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: arr(:)

Return Value character(len=:), allocatable

private pure function levenshtein(a, b) result(dist)

Levenshtein edit distance between two (capped) strings.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: a
character(len=*), intent(in) :: b

Return Value integer

private function logical_default_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_logical_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function logical_is_default(this) result(yes)

Arguments

Type IntentOptional Attributes Name
class(nml_logical_key_t), intent(in) :: this

Return Value logical

private function logical_value_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_logical_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private pure function lower(s) result(out)

Lowercase an ASCII string.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: s

Return Value character(len=len)

private function make_prefix(path, line) result(p)

Build a path:line: error prefix.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: path
integer, intent(in) :: line

Return Value character(len=:), allocatable

private function real_array_default_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_real_array_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function real_array_is_default(this) result(yes)

Arguments

Type IntentOptional Attributes Name
class(nml_real_array_key_t), intent(in) :: this

Return Value logical

private function real_array_value_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_real_array_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function real_default_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_real_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function real_is_default(this) result(yes)

Arguments

Type IntentOptional Attributes Name
class(nml_real_key_t), intent(in) :: this

Return Value logical

private function real_value_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_real_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function schema_find_group(this, name) result(idx)

Index of name in the schema’s groups, 0 if absent.

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(in) :: this
character(len=*), intent(in) :: name

Return Value integer

private function schema_is_external(this, name) result(yes)

True if name is a registered external group.

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(in) :: this
character(len=*), intent(in) :: name

Return Value logical

private function string_default_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_string_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private function string_is_default(this) result(yes)

Arguments

Type IntentOptional Attributes Name
class(nml_string_key_t), intent(in) :: this

Return Value logical

private function string_value_string(this) result(str)

Arguments

Type IntentOptional Attributes Name
class(nml_string_key_t), intent(in) :: this

Return Value character(len=:), allocatable

private pure function strip_comment(line) result(out)

Remove a trailing ! comment, respecting single/double quotes.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: line

Return Value character(len=:), allocatable

private pure function strip_nml(name) result(out)

Drop a trailing _nml suffix (namelist files spell groups &<name>_nml; the schema stores the bare <name>).

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: name

Return Value character(len=:), allocatable

private function suggest(name, candidates) result(msg)

Build a ” (did you mean ‘x’?)” fragment if a close candidate exists (distance <= max(2, len/3)); else empty.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: name
character(len=*), intent(in) :: candidates(:)

Return Value character(len=:), allocatable


Subroutines

private subroutine add_err(errors, n_err, msg)

Append a message to a growable error list.

Arguments

Type IntentOptional Attributes Name
character(len=:), intent(inout), allocatable :: errors(:)
integer, intent(inout) :: n_err
character(len=*), intent(in) :: msg

private subroutine append_val(vals, vcount, tok)

Append one value token to the values buffer.

Arguments

Type IntentOptional Attributes Name
character(len=256), intent(inout), allocatable :: vals(:)
integer, intent(inout) :: vcount
character(len=*), intent(in) :: tok

private subroutine apply_one_pair(g, tokens, tok_line, n_tok, ti, path, errors, n_err)

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.

Arguments

Type IntentOptional 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

private subroutine check_unsupported(word, path, line, errors, n_err)

Flag unsupported namelist syntax embedded in a bare token.

Arguments

Type IntentOptional 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

private subroutine collect_tokens(lines, n_lines, li, col, path, tokens, tok_line, n_tok, errors, 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.

Arguments

Type IntentOptional 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

private subroutine dispatch_group(this, lines, n_lines, li, col, gname, prefix, group_seen, errors, n_err, path)

Resolve a group name to known / external / unknown and parse (or skip) its body up to the terminating ‘/’.

Arguments

Type IntentOptional 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

private subroutine enum_parse(this, values, err_msg)

Arguments

Type IntentOptional Attributes Name
class(nml_enum_key_t), intent(inout) :: this
character(len=*), intent(in) :: values(:)
character(len=:), intent(out), allocatable :: err_msg

private subroutine group_add(this, key)

Add a key to the group (sourced-allocate into a box). Error stop on duplicate key name (programming error).

Arguments

Type IntentOptional Attributes Name
class(nml_group_t), intent(inout) :: this
class(nml_key_t), intent(in) :: key

private subroutine int_parse(this, values, err_msg)

Arguments

Type IntentOptional Attributes Name
class(nml_int_key_t), intent(inout) :: this
character(len=*), intent(in) :: values(:)
character(len=:), intent(out), allocatable :: err_msg

private subroutine logical_parse(this, values, err_msg)

Arguments

Type IntentOptional Attributes Name
class(nml_logical_key_t), intent(inout) :: this
character(len=*), intent(in) :: values(:)
character(len=:), intent(out), allocatable :: err_msg

private subroutine move_group(src, dst)

Transfer a group’s contents without copying any polymorphic key box (descriptor moves only — see schema_add_group).

Arguments

Type IntentOptional Attributes Name
type(nml_group_t), intent(inout) :: src
type(nml_group_t), intent(inout) :: dst

private subroutine next_amp(lines, n_lines, li, col)

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.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: lines(:)
integer, intent(in) :: n_lines
integer, intent(inout) :: li
integer, intent(inout) :: col

private subroutine parse_file(this, path, errors, n_err)

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).

Arguments

Type IntentOptional 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

private subroutine parse_from_lines(this, lines, n_lines, label, errors, 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. ““) for buffer parses.

Arguments

Type IntentOptional 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

private subroutine parse_group_body(g, lines, n_lines, li, col, path, errors, n_err)

Tokenize and apply key = value... pairs until ‘/’.

Arguments

Type IntentOptional 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

private subroutine post_parse_validate(this, label, err_buf, n_err, status, errors)

Required-key + cross-check pass shared by the file and buffer parsers, then the error-return / error-stop finalization.

Arguments

Type IntentOptional 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(:)

private subroutine push_tok(tokens, tok_line, n_tok, val, line)

Append a token, growing the buffer as needed.

Arguments

Type IntentOptional 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

private subroutine read_group_name(lines, n_lines, li, col, gname)

Read an identifier starting at (li,col); advance past it.

Arguments

Type IntentOptional 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

private subroutine read_lines(path, lines, n_lines, ok)

Read the whole file into a deferred-len line array.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: path
character(len=:), intent(out), allocatable :: lines(:)
integer, intent(out) :: n_lines
logical, intent(out) :: ok

private subroutine real_array_parse(this, values, err_msg)

Arguments

Type IntentOptional Attributes Name
class(nml_real_array_key_t), intent(inout) :: this
character(len=*), intent(in) :: values(:)
character(len=:), intent(out), allocatable :: err_msg

private subroutine real_parse(this, values, err_msg)

Arguments

Type IntentOptional Attributes Name
class(nml_real_key_t), intent(inout) :: this
character(len=*), intent(in) :: values(:)
character(len=:), intent(out), allocatable :: err_msg

private subroutine reset_state(this)

Reset parse-state (found flags) before a parse.

Arguments

Type IntentOptional Attributes Name
type(nml_schema_t), intent(inout) :: this

private subroutine schema_add_external_group(this, name)

Register a group name the schema knows exists but does NOT validate (its body is skipped silently).

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(inout) :: this
character(len=*), intent(in) :: name

private subroutine schema_add_group(this, g)

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.

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(inout) :: this
type(nml_group_t), intent(inout) :: g

private subroutine schema_parse(this, path, status, errors)

Parse and validate the namelist file at path.

Read more…

Arguments

Type IntentOptional 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(:)

private subroutine schema_parse_lines(this, lines, n_lines, status, 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.

Arguments

Type IntentOptional 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(:)

private subroutine schema_render_json(this, path)

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).

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(in) :: this
character(len=*), intent(in) :: path

private subroutine schema_render_markdown(this, path)

Render the schema as Markdown: per group a heading, doc line, and a knob table.

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(in) :: this
character(len=*), intent(in) :: path

private subroutine schema_write_doc_all(this, path)

Write every group and key as valid namelist with aligned docs.

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(in) :: this
character(len=*), intent(in) :: path

private subroutine schema_write_doc_short(this, path)

Write only non-default keys (MOM6 parameter_doc.short). Groups with no non-default keys are omitted entirely.

Arguments

Type IntentOptional Attributes Name
class(nml_schema_t), intent(in) :: this
character(len=*), intent(in) :: path

private subroutine skip_to_slash(lines, n_lines, li, col)

Advance past the next ‘/’ (group terminator); recovery aid.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: lines(:)
integer, intent(in) :: n_lines
integer, intent(inout) :: li
integer, intent(inout) :: col

private subroutine string_parse(this, values, err_msg)

Arguments

Type IntentOptional Attributes Name
class(nml_string_key_t), intent(inout) :: this
character(len=*), intent(in) :: values(:)
character(len=:), intent(out), allocatable :: err_msg

private subroutine write_key_json(u, box, is_last)

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).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: u
type(nml_key_box_t), intent(in) :: box
logical, intent(in) :: is_last

private subroutine write_key_line(unit, box, short_only, wrote_any)

Write one aligned key = value ! [units] doc line. When short_only, skip default-valued keys (and leave wrote_any).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: unit
type(nml_key_box_t), intent(in) :: box
logical, intent(in) :: short_only
logical, intent(inout) :: wrote_any