program m

character(len=100) :: p, t
logical            :: result

do
   write(unit=*,fmt="(a)",advance="no")  "Target path: "
   read(unit=*,fmt="(a)") t
   write(unit=*,fmt="(a)",advance="no")  "Path: "
   read(unit=*,fmt="(a)") p

   result = match(p,t)
   print *, "Result: ", result

enddo


CONTAINS

recursive function match(p,ptarget) result(res_match)
character(len=*), intent(in)  :: p
character(len=*), intent(in)  :: ptarget
logical                       :: res_match

!
! Checks whether a given XML path matches the target path ptarget
! Only absolute paths are considered.
!
! Examples of target paths:
!
!           /pseudo/vps/radfunc      [1]
!           //radfunc/data
!           //data
!           //*/vps/data                 *//
!           //job//data
!           //*                          *//
!
integer  :: len_target, len_path, pos_target, pos_path
character(len=100)   :: anchor_leaf

res_match = .false.       

 print *, ":testing: "
 print *, "          ", trim(p)
 print *, " against: ", trim(ptarget)
 print *, "-----------------------------------------"

if (trim(p) == trim(ptarget)) then
   res_match = .true.
   print *, "outright equality"
   return

else if (ptarget == "/") then
   ! We  process // in the middle below

   res_match = .true.
   print *, "target begins by //"
   return

else              ! We get the extreme elements

   len_target = len_trim(ptarget)
   len_path = len_trim(p)
   pos_target = index(ptarget,"/",back=.true.)
   pos_path = index(p,"/",back=.true.)

   print *, " Path leaf: ", p(pos_path+1:len_path) 
   print *, " Target leaf: ", ptarget(pos_target+1:len_target)

   if (pos_target == len_target) then   ! // in the middle...
      ! Get leaf further up
      search_anchor : do 
         print *, "looking for anchor in: ", ptarget(1:len_target-1)
         print *, "press enter"
         read *
         pos_target = index(ptarget(1:len_target-1),"/",back=.true.)
         print *, "pos_target in anchor search: ", pos_target
         if (pos_target == 1) then  ! Target begins by /.// 
            res_match = .true.
            print *, "reached initial /.// in target"
            return
         endif
         anchor_leaf = ptarget(pos_target:len_target-1)
         print *, " Anchor leaf: ", trim(anchor_leaf)
         if (anchor_leaf == "/.") then  ! keep searching
            len_target = pos_target 
            cycle search_anchor
         else
            exit search_anchor
         endif
      enddo search_anchor

      ! Note that the anchor includes the leading /
      ! Now we search for that anchor in the candidate path
      !
      print *, " Searching anchor in : ", trim(p(1:len_path))
      pos_path = index(p(1:len_path),trim(anchor_leaf),back=.true.)
      if (pos_path /= 0) then

         ! Found anchor. Continue further up.
         !
         res_match = match(p(1:pos_path-1),ptarget(1:pos_target-1))
      endif

   else if  (ptarget(pos_target+1:len_target) == ".") then

      ! A dot is a dummy. Continue further up.
      !
      res_match = match(p(1:len_path),ptarget(1:pos_target-1))

   else if  (ptarget(pos_target+1:len_target) == "*") then

      if (len_path == pos_path) then
         print *, "empty element. len_path, pos_path: ", len_path, pos_path
         RETURN   ! empty path element
      endif

      ! A star matches any non-empty leaf. Continue further up.
      !
      res_match = match(p(1:pos_path-1),ptarget(1:pos_target-1))

   else  if (p(pos_path+1:len_path) ==  &
             ptarget(pos_target+1:len_target)) then 

      ! Leafs are equal. Continue further up.
      !
      res_match = match(p(1:pos_path-1),ptarget(1:pos_target-1))

   endif

endif

end function match

end program m













