module subroutine parse_molecules_section(unit, config, error)
!! Parse %molecules section containing multiple %molecule blocks
integer, intent(in) :: unit
type(mqc_config_t), intent(inout) :: config
type(error_t), intent(out) :: error
character(len=MAX_LINE_LEN) :: line, key, value
character(len=256) :: msg
integer :: io_stat, eq_pos, nmol, imol
nmol = 0
! First pass: read nmol
do
read (unit, '(A)', iostat=io_stat) line
if (io_stat /= 0) then
call error%set(ERROR_IO, "Unexpected end of file in %molecules section")
return
end if
line = adjustl(line)
if (len_trim(line) == 0) cycle
if (line(1:1) == '#' .or. line(1:1) == '!') cycle
if (trim(strip_comment(line)) == 'end') exit
eq_pos = index(line, '=')
if (eq_pos > 0) then
key = adjustl(line(1:eq_pos - 1))
value = adjustl(line(eq_pos + 1:))
if (trim(key) == 'nmol') then
read (value, *, iostat=io_stat) nmol
if (io_stat /= 0) then
call error%set(ERROR_PARSE, "Invalid nmol value")
return
end if
exit
end if
end if
end do
if (nmol == 0) then
! No molecules, just skip to end
call skip_to_end(unit, error)
return
end if
config%nmol = nmol
allocate (config%molecules(nmol))
! Parse individual molecules
imol = 0
do
read (unit, '(A)', iostat=io_stat) line
if (io_stat /= 0) exit
line = adjustl(line)
if (len_trim(line) == 0) cycle
if (line(1:1) == '#' .or. line(1:1) == '!') cycle
if (trim(strip_comment(line)) == 'end') exit
if (trim(line) == '%molecule') then
imol = imol + 1
if (imol > nmol) then
call error%set(ERROR_PARSE, "More molecules than declared nmol")
return
end if
call parse_single_molecule(unit, config%molecules(imol), error)
if (error%has_error()) then
call error%add_context("mqc_config_parser:parse_molecules_section")
return
end if
end if
end do
if (imol /= nmol) then
write (msg, '(A,I0,A,I0)') "Expected ", nmol, " molecules, found ", imol
call error%set(ERROR_PARSE, trim(msg))
return
end if
end subroutine parse_molecules_section