!       PROGRAM TEST
!       CHARACTER CHAIN*80,NAME*80,DEF*40,EXT*20,ANAME*80
!       LOGICAL FOUND, SIC_FINDFILE
!
!       DEF = ' ' ! 'GAG_DEMO:'
!       write(6,*) "Path ?",def
!       read(5,'(a)') def
!       EXT = '.PRO'
! 1     WRITE(6,*) 'name?'
!       READ(5,'(a)',END=100) ANAME
!       NAME = ANAME
!       CALL SIC_PARSEF(NAME,CHAIN,DEF,EXT)
!       Print *,'File '//TRIM(CHAIN)
!       Print *,'Short name '//TRIM(NAME)
!       NAME = ANAME
!       FOUND = SIC_FINDFILE (NAME,CHAIN,DEF,EXT)
!       Print *,'Found ',found
!       Print *,'File '//TRIM(CHAIN)
!       Print *,'Short name '//TRIM(NAME)
!       GOTO 1
! 100   CONTINUE
!       END
!
subroutine sic_resolve_log(chain)
  use gsys_interfaces, except_this=>sic_resolve_log
  use gildas_def
  !---------------------------------------------------------------------
  ! @ public
  ! Resolve logical variables recursively
  !---------------------------------------------------------------------
  character(len=*), intent(inout) :: chain  !
  ! Local
  character(len=path_length) :: file
  character(len=filename_length) :: direct
  logical :: ok
  integer(kind=4) :: i1,ier
  !
  ok = .true.
  do while(ok)
    ier = sic_getlog(chain)
    !
    ! Translate logical names
    i1 = index(chain,':')
    !
    ! Now we have only "logical names" and slashes.
    if (i1.ne.0) then
      direct = chain(1:i1)
      i1 = i1+1
      file = direct
      ier = sic_getlog(direct)
      if (direct.eq.file) exit
      file = trim(direct)//chain(i1:)
    else
      file = chain
      ok = .false.
    endif
    chain=file
  enddo
end subroutine sic_resolve_log
!
subroutine sic_parse_file(name,dir,ext,file)
  use gsys_interfaces, except_this=>sic_parse_file
  use gildas_def
  !---------------------------------------------------------------------
  ! @ public
  ! Adds the directory DIR and extension EXT if necessary to the file
  ! name NAME to form FILE. In addition, logical name are translated to
  ! obtain the intrinsic "physical" names.
  !
  ! For UNIX purposes: (a logical name is somestring finished with ":")
  !      a) converts "\" to "/"
  !      b) converts ~ to $HOME
  !
  ! if first character is "!" or "/"
  !     1) TRANSLATES LOGICAL NAMES
  !     2) Does not add extension
  !     3) is respectful of upper/lowercases
  ! if not :
  !     1) converts to lowercase
  !     2) TRANSLATES LOGICAL NAMES
  !     3) Does add extension, in lowercase
  !---------------------------------------------------------------------
  character(len=*), intent(in)  :: name  ! File name
  character(len=*), intent(in)  :: dir   ! Default directory
  character(len=*), intent(in)  :: ext   ! Default extension
  character(len=*), intent(out) :: file  ! Fully extended file name
  ! Local
  integer(kind=4) :: lon,i,i1,i2,l
  character(len=filename_length) :: chain, direct
  character(len=1) :: ousep, insep, disep
  character(len=1), parameter :: notrans='!'
  logical :: ok
  data direct/' '/
  !
  call gag_separ(insep,ousep,disep)
  !
  if (name(1:1).eq.notrans) then
    chain = name(2:)
  else
    chain = name
  endif
  !
  call sic_resolve_log(chain)
  !
  ! get full directory part
  ok = .true.
  i1 = len_trim(chain)
  do while (ok .and. i1.gt.0)
    if (chain(i1:i1).eq.ousep .or. chain(i1:i1).eq.insep) then
      ok = .false.
    else
      i1 = i1-1
    endif
  enddo
  if (i1.eq.0) then
    direct = dir
    call sic_resolve_log(direct)
    l = len_trim(direct)
    file = trim(direct)//chain
  else
    file = chain
    l = i1
  endif
  !
  ! Convert directory separators
  lon = len_trim(file)
  do i=1,lon
    if (file(i:i).eq.insep) file(i:i)=ousep
  enddo
  !
  ! Extension?
  lon = len_trim(file(l+1:))+l
  i2 = index(file(l+1:lon),'.')
  if (i2.eq.0) then
    ! Insert default extension
    file(lon+1:) = ext
    i2 = lon+1
    lon = len_trim(file)
    call sic_lower(file(i2:lon))   ! To debug tasks...
  endif
  !
end subroutine sic_parse_file
!
subroutine sic_parsef(name,file,dir,ext)
  use gbl_message
  use gsys_interfaces, except_this=>sic_parsef
  !---------------------------------------------------------------------
  ! @ public
  !  Same as SIC_PARSE_FILE +
  !  at return, NAME is the file named stripped from directory and
  !  extension
  ! ---
  !  Obsolete: use SIC_PARSE_FILE and/or SIC_PARSE_NAME instead
  !---------------------------------------------------------------------
  character(len=*), intent(inout) :: name  ! File name
  character(len=*), intent(out)   :: file  ! Fully extended file name
  character(len=*), intent(in)    :: dir   ! Default directory
  character(len=*), intent(in)    :: ext   ! Default extension
  ! Local
  character(len=filename_length) :: tmp
  !
  ! Compute DIR+NAME+EXT into FILE
  call sic_parse_file(name,dir,ext,file)
  !
  ! Strip NAME from its directory and extension
  tmp = name
  call sic_parse_name(tmp,name)
  !
end subroutine sic_parsef
!
function sic_query_file (name,path,ext,file)
  use gildas_def
  use gsys_interfaces, except_this=>sic_query_file
  !---------------------------------------------------------------------
  ! @ public
  ! Same as sic_findfile but avoid modifying input 'name'
  !---------------------------------------------------------------------
  logical :: sic_query_file              ! Function value on return
  character(len=*), intent(in)  :: name  ! File name
  character(len=*), intent(in)  :: path  ! Search path
  character(len=*), intent(in)  :: ext   ! Default extension
  character(len=*), intent(out) :: file  ! Fully extended file name
  ! Local
  character(len=filename_length) :: temp
  !
  temp = name
  sic_query_file = sic_findfile(temp,file,path,ext)
end function sic_query_file
!
function sic_findfile(name,file,path,ext)
  use gsys_interfaces, except_this=>sic_findfile
  !---------------------------------------------------------------------
  ! @ public
  !  Search on the path PATH and with extension EXT if necessary the
  ! file name NAME to find FILE. At return, NAME is the file named
  ! stripped from these extensions. In addition, logical name are
  ! translated to obtain the intrinsic "physical" names.
  !---------------------------------------------------------------------
  logical :: sic_findfile                  ! Function value on return
  character(len=*), intent(inout) :: name  ! File name
  character(len=*), intent(out)   :: file  ! Fully extended file name
  character(len=*), intent(in)    :: path  ! Search Path
  character(len=*), intent(in)    :: ext   ! Default extension
  ! Local
  integer(kind=4) :: lon,i,lpath,iext,ipath,isep1,isep2,ier
  character(len=path_length) :: apath
  character(len=512) :: chain, direct
  character(len=512) :: etype
  character(len=1) :: ousep, insep, disep
  character(len=1), parameter :: notrans='!'
  logical :: ok
  data direct/' '/
  !
  call gag_separ(insep,ousep,disep)
  sic_findfile = .false.
  !
  ! Convert directory separators
  if (name(1:1).eq.notrans) then
    chain = name(2:)
  else
    chain = name
  endif
  !
  lon = len_trim(chain)
  !
  if (lon.le.0) then
    ! Stupid protection, but seems to happen
    file = ''
    return
  endif
  !
  do i=1,lon
    if (chain(i:i).eq.insep) chain(i:i)=ousep
  enddo
  ier = sic_getlog(chain)
  lon = len_trim(chain)
  !
  ! Get extension
  iext = lon
  ipath = 0
  ok = .true.
  do while(ok)
    if (chain(iext:iext).eq.'.') then
      etype = chain(iext:lon)
      iext = iext-1
      ok = .false.
    elseif  (chain(iext:iext).eq.ousep) then
      etype = ext
      call sic_lower(etype)    ! To debug tasks
      iext = lon
      ok = .false.
    else
      if (chain(iext:iext).eq.':') ipath = iext
      iext = iext-1
      if (iext.eq.0) then
        iext = lon
        etype = ext
        call sic_lower(etype)  ! To debug tasks
        ok = .false.
      endif
    endif
  enddo
  !
  ! Insert default path if needed, or used built-in directory
  if (ipath.eq.0) ipath = index(chain,':')
  if (ipath.eq.0) then
    apath = path
  else
    apath = chain(1:ipath)
  endif
  name = chain(ipath+1:iext)
  call sic_resolve_log(apath)
  lpath = len_trim(apath)
  !
  ! Translate path name
  isep1 = 1
  do while (isep1.lt.lpath)
    isep2 = index(apath(isep1:lpath),';')
    if (isep2.eq.0) isep2 = lpath-isep1+2
    direct = apath(isep1:isep2-2+isep1)
    call sic_resolve_log(direct)
    file = trim(direct)//chain(ipath+1:iext)//etype
    if (gag_inquire(file,len_trim(file)).ne.0) then
      sic_findfile = .false.
    else
      sic_findfile = .true.
      return
    endif
    isep1 = isep1+isep2
  enddo
  !
  ! If no search path or directory was specified, search
  ! for current directory, OR if an absolute path was
  ! specified, use it "as is"
  if (lpath.ne.0.and.chain(1:1).ne.ousep) return
  file = chain(ipath+1:iext)//etype
  sic_findfile = (gag_inquire(file,len_trim(file)).eq.0)
end function sic_findfile
!
subroutine sic_parse_name(iname,ofile,oext,odir)
  use gildas_def
  use gsys_interfaces, except_this=>sic_parse_name
  !---------------------------------------------------------------------
  ! @ public
  !  Split an input file name as:
  !  - its basename (no extension),
  !  - its extension,
  !  - its dirname.
  ! Sic logicals are resolved in the the input file name before parsing
  !---------------------------------------------------------------------
  character(len=*), intent(in)            :: iname
  character(len=*), intent(out)           :: ofile
  character(len=*), intent(out), optional :: oext
  character(len=*), intent(out), optional :: odir
  ! Local
  character(len=1) :: insep,ousep,disep
  character(len=1), parameter :: notrans='!'
  logical :: ok
  character(len=filename_length) :: oname
  integer(kind=4) :: lf,i,isep,idot
  !
  call gag_separ(insep,ousep,disep)
  !
  if (iname(1:1).eq.notrans) then
    oname = iname(2:)
  else
    oname = iname
  endif
  call sic_resolve_log(oname)
  lf = len_trim(oname)
  !
  ! Search for last directory separator
  ok = .true.
  isep = lf
  do while (ok .and. isep.gt.0)
    if (oname(isep:isep).eq.ousep .or. oname(isep:isep).eq.insep) then
      ok = .false.
    else
      isep = isep-1
    endif
  enddo
  ! NB: isep can be 0 on return
  !
  ! Set output directory name
  if (present(odir)) then
    odir = oname(1:isep)
    ! Convert directory separators
    do i=1,isep
      if (odir(i:i).eq.insep)  odir(i:i) = ousep
    enddo
  endif
  !
  ! Set output name and extension
  idot = index(oname(isep+1:lf),'.')
  if (idot.eq.0) then
    ofile = oname(isep+1:lf)
    if (present(oext))  oext = ''
  else
    ofile = oname(isep+1:isep+idot-1)
    if (present(oext))  oext = oname(isep+idot+1:lf)
  endif
  !
end subroutine sic_parse_name
