Shared machinery for the per-dimension config modules (spec
2026-07-06-multidim-machinery-refactor-design.md, section 4). A dimension
supplies DATA — a field_desc_t(:) table binding key/group/kind/bounds/
choices to pointers into its config derived type — and this engine supplies
the behavior. Cross-field and conditional rules stay in the per-dimension
validate routines; only unconditional per-field constraints (flagged
check_in_validate) are enforced here.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | cfg_kind_int | = | 1 |
Value-kind tags. Owned here; re-exported by config_schema / config_schema_2d so their ABI-facing constants keep working unchanged. |
| integer, | public, | parameter | :: | cfg_kind_real | = | 2 | |
| integer, | public, | parameter | :: | cfg_kind_logical | = | 3 | |
| integer, | public, | parameter | :: | cfg_kind_choice | = | 4 | |
| integer, | public, | parameter | :: | cfg_kind_string | = | 5 | |
| integer, | public, | parameter | :: | cfg_kind_real3 | = | 6 | |
| integer, | public, | parameter | :: | choice_msg_valid_list | = | 1 |
Generated choice-violation message styles (match the historical texts). |
| integer, | public, | parameter | :: | choice_msg_one_of | = | 2 | |
| integer, | public, | parameter | :: | choice_msg_bare | = | 3 |
One configuration field: schema metadata + validation constraint + a typed pointer into a live config instance. Exactly one of the pointer components is associated, per value_kind.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=32), | public | :: | key | = | '' | ||
| character(len=32), | public | :: | group | = | '' | ||
| integer, | public | :: | value_kind | = | 0 | ||
| character(len=256), | public | :: | help | = | '' | ||
| logical, | public | :: | has_min | = | .false. | ||
| logical, | public | :: | min_exclusive | = | .false. | ||
| real(kind=wp), | public | :: | min_value | = | 0.0_wp | ||
| logical, | public | :: | has_max | = | .false. | ||
| real(kind=wp), | public | :: | max_value | = | 0.0_wp | ||
| character(len=64), | public, | allocatable | :: | choices(:) | |||
| integer, | public | :: | choice_msg_style | = | choice_msg_valid_list | ||
| character(len=160), | public | :: | msg_choice | = | '' | ||
| logical, | public | :: | casefold | = | .false. | ||
| logical, | public | :: | check_in_validate | = | .true. |
.false. => published in the schema but NOT checked by validate_fields (conditional/cross-field rules stay in the per-dim validate routine). |
|
| character(len=160), | public | :: | msg_min | = | '' | ||
| character(len=160), | public | :: | msg_max | = | '' | ||
| integer, | public, | pointer | :: | iptr | => | null() | |
| real(kind=wp), | public, | pointer | :: | rptr | => | null() | |
| logical, | public, | pointer | :: | lptr | => | null() | |
| character(len=:), | public, | pointer | :: | sptr | => | null() | |
| real(kind=wp), | public, | pointer | :: | r3ptr(:) | => | null() |
Metadata-only constructor. Callers associate the matching pointer component afterwards (build_field_table binds them to a target config).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | key | |||
| character(len=*), | intent(in) | :: | group | |||
| integer, | intent(in) | :: | value_kind | |||
| character(len=*), | intent(in) | :: | help | |||
| logical, | intent(in), | optional | :: | has_min | ||
| logical, | intent(in), | optional | :: | min_exclusive | ||
| real(kind=wp), | intent(in), | optional | :: | min_value | ||
| character(len=*), | intent(in), | optional | :: | msg_min | ||
| logical, | intent(in), | optional | :: | has_max | ||
| real(kind=wp), | intent(in), | optional | :: | max_value | ||
| character(len=*), | intent(in), | optional | :: | msg_max | ||
| character(len=*), | intent(in), | optional | :: | choices(:) | ||
| integer, | intent(in), | optional | :: | choice_msg_style | ||
| character(len=*), | intent(in), | optional | :: | msg_choice | ||
| logical, | intent(in), | optional | :: | casefold | ||
| logical, | intent(in), | optional | :: | check_in_validate |
1-based index of key in the table (normalized compare); 0 when absent.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key |
Compose the historical choice-violation text for one field.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | prefix | |||
| type(field_desc_t), | intent(in) | :: | f |
Typed by-name read. .false. on unknown key OR kind mismatch; the caller composes its historical error text (they differ between 1D and 2D).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| integer, | intent(out) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| real(kind=wp), | intent(out) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| logical, | intent(out) | :: | value |
Strings and choices are both readable as strings (historical behavior).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| character(len=*), | intent(out) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| real(kind=wp), | intent(out) | :: | value(3) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(inout) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| integer, | intent(in) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(inout) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| real(kind=wp), | intent(in) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(inout) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| logical, | intent(in) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(inout) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| character(len=*), | intent(in) | :: | value |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(inout) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | key | |||
| real(kind=wp), | intent(in) | :: | value(3) |
Lowercase every casefold-flagged string field in place (the table-driven replacement for the 1D normalize_config).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(inout) | :: | fields(:) |
Enforce every unconditional per-field constraint, in table order; first
violation wins. prefix is the historical message prefix ('config' or
'config_2d'). Choice comparison casefolds the candidate via to_lower
(length/blank-preserving), NOT lowercase_token (which adjustl's first):
a leading-whitespace value like ' hllc' must be REJECTED here, matching
the 2D to_lower-on-compare behavior; the 1D path already normalizes
(adjustl+lowercase) via normalize_fields before this runs, so its
stored values never carry leading blanks by the time they reach here.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(field_desc_t), | intent(in) | :: | fields(:) | |||
| character(len=*), | intent(in) | :: | prefix | |||
| logical, | intent(out) | :: | ok | |||
| character(len=*), | intent(out) | :: | message |