module subroutine parse_connectivity_generic(unit, nbonds, nbroken, bonds, error)
!! Generic parser for %connectivity section (works for both config and molecule)
use mqc_physical_fragment, only: bond_t
integer, intent(in) :: unit
integer, intent(inout) :: nbonds, nbroken
type(bond_t), allocatable, intent(inout) :: bonds(:)
type(error_t), intent(out) :: error
character(len=MAX_LINE_LEN) :: line, key, value, status_str
integer :: io_stat, eq_pos, nbonds_local, ibond
integer :: atom_i, atom_j, order
nbonds_local = 0
! First pass: read nbonds
do
read (unit, '(A)', iostat=io_stat) line
if (io_stat /= 0) then
call error%set(ERROR_IO, "Unexpected end of file in %connectivity 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) == 'nbonds') then
read (value, *, iostat=io_stat) nbonds_local
if (io_stat /= 0) then
call error%set(ERROR_PARSE, "Invalid nbonds value")
return
end if
exit
end if
end if
end do
if (nbonds_local == 0) then
! No bonds, just skip to end
call skip_to_end(unit, error)
return
end if
nbonds = nbonds_local
allocate (bonds(nbonds))
! Read bonds
ibond = 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
! Check for key=value pairs (like nbroken=9)
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) == 'nbroken') then
read (value, *, iostat=io_stat) nbroken
end if
cycle
end if
if (trim(strip_comment(line)) == 'end') exit
! Parse bond line: atom_i atom_j order broken/preserved
read (line, *, iostat=io_stat) atom_i, atom_j, order, status_str
if (io_stat /= 0) then
call error%set(ERROR_PARSE, "Invalid bond format in %connectivity section")
return
end if
ibond = ibond + 1
if (ibond > nbonds) then
call error%set(ERROR_PARSE, "More bonds than declared nbonds")
return
end if
bonds(ibond)%atom_i = atom_i
bonds(ibond)%atom_j = atom_j
bonds(ibond)%order = order
bonds(ibond)%is_broken = (trim(status_str) == 'broken')
end do
end subroutine parse_connectivity_generic