apply_one_pair Subroutine

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

Calls

proc~~apply_one_pair~~CallsGraph proc~apply_one_pair apply_one_pair names names proc~apply_one_pair->names parse_tokens parse_tokens proc~apply_one_pair->parse_tokens proc~add_err add_err proc~apply_one_pair->proc~add_err proc~append_val append_val proc~apply_one_pair->proc~append_val proc~group_find_key nml_group_t%group_find_key proc~apply_one_pair->proc~group_find_key proc~group_key_list group_key_list proc~apply_one_pair->proc~group_key_list proc~make_prefix make_prefix proc~apply_one_pair->proc~make_prefix proc~suggest suggest proc~apply_one_pair->proc~suggest proc~lower lower proc~group_find_key->proc~lower proc~fmt_int fmt_int proc~make_prefix->proc~fmt_int proc~levenshtein levenshtein proc~suggest->proc~levenshtein proc~suggest->proc~lower

Called by

proc~~apply_one_pair~~CalledByGraph proc~apply_one_pair apply_one_pair proc~parse_group_body parse_group_body proc~parse_group_body->proc~apply_one_pair proc~dispatch_group dispatch_group proc~dispatch_group->proc~parse_group_body proc~parse_from_lines parse_from_lines proc~parse_from_lines->proc~dispatch_group proc~parse_file parse_file proc~parse_file->proc~parse_from_lines proc~schema_parse_lines nml_schema_t%schema_parse_lines proc~schema_parse_lines->proc~parse_from_lines proc~read_config_from_string_impl read_config_from_string_impl proc~read_config_from_string_impl->proc~schema_parse_lines proc~schema_parse nml_schema_t%schema_parse proc~schema_parse->proc~parse_file

Variables

Type Visibility Attributes Name Initial
integer, private :: j
character(len=:), private, allocatable :: keyname
integer, private :: kidx
integer, private :: kline
character(len=:), private, allocatable :: prefix
character(len=256), private, allocatable :: vals(:)
integer, private :: vcount
integer, private :: vstart

Source Code

   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.
      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=:), allocatable, intent(inout) :: errors(:)
      integer, intent(inout) :: n_err

      character(len=:), allocatable :: keyname, prefix
      integer :: kidx, kline, vstart, vcount, j
      character(len=256), allocatable :: vals(:)

      ! Skip stray separators.
      do while (ti <= n_tok)
         if (trim(tokens(ti)) == ",") then
            ti = ti + 1
         else
            exit
         end if
      end do
      if (ti > n_tok) return

      keyname = trim(tokens(ti))
      kline = tok_line(ti)
      prefix = make_prefix(path, kline)

      if (keyname == "=") then
         call add_err(errors, n_err, prefix//"stray '=' with no key name")
         ti = ti + 1
         return
      end if

      ! Expect '=' next.
      if (ti + 1 > n_tok) then
         call add_err(errors, n_err, prefix//"key '"//keyname//"' has no '=' assignment")
         ti = ti + 1
         return
      end if
      if (trim(tokens(ti + 1)) /= "=") then
         call add_err(errors, n_err, prefix//"expected '=' after key '"//keyname// &
                      "', got '"//trim(tokens(ti + 1))//"'")
         ti = ti + 1
         return
      end if

      ! Gather value tokens (skip commas) until next `ident =` or end.
      vstart = ti + 2
      vcount = 0
      allocate (vals(0))
      j = vstart
      do while (j <= n_tok)
         if (trim(tokens(j)) == ",") then
            j = j + 1
            cycle
         end if
         ! Lookahead: is this token a key (followed by '=')?
         if (j + 1 <= n_tok) then
            if (trim(tokens(j + 1)) == "=") exit
         end if
         call append_val(vals, vcount, tokens(j))
         j = j + 1
      end do

      ti = j

      ! Resolve and apply.
      kidx = g%find_key(keyname)
      if (kidx == 0) then
         block
            character(len=:), allocatable :: names(:)
            character(len=:), allocatable :: sug
            names = group_key_list(g)
            sug = ""
            if (size(names) > 0) sug = suggest(keyname, names)
            call add_err(errors, n_err, prefix//"unknown key '"//keyname// &
                         "' in group '"//g%name//"'"//sug)
         end block
         return
      end if
      if (g%keys(kidx)%key%found) then
         call add_err(errors, n_err, prefix//"duplicate key '"//keyname// &
                      "' in group '"//g%name//"'")
         return
      end if
      g%keys(kidx)%key%found = .true.
      if (vcount == 0) then
         call add_err(errors, n_err, prefix//"key '"//keyname//"' has no value")
         return
      end if
      block
         character(len=:), allocatable :: emsg
         call g%keys(kidx)%key%parse_tokens(vals(1:vcount), emsg)
         if (allocated(emsg)) then
            call add_err(errors, n_err, prefix//trim(emsg))
         end if
      end block
   end subroutine apply_one_pair