subroutine get_i4list_fromsic(rname,line,opt,nf,list,error)
  use iso_c_binding
  use gkernel_interfaces
  use gkernel_types
  use gbl_message
  use gbl_format
  use imager_interfaces, only : map_message
  !
  ! @ public-mandatory
  !*
  !   SIC -- Utility routine
  !
  ! Return in the allocatable array the content of the 1-D
  ! SIC variable given as (first and only) argument of Option # opt.
  ! Return the size of the array in NF.
  ! If NF is non zero on entry, the size must match and the
  ! array is pre-allocated.
  !!
  character(len=*), intent(in) :: rname  !! Caller name
  character(len=*), intent(in) :: line   !! Command line
  integer, intent(in) :: opt             !! Option number
  integer, intent(inout) :: nf           !! Size of array. 
  !! If Zero on entry, automatic. If non zero, must match variable size.
  integer, allocatable, intent(inout) :: list(:)  !! List 
  logical, intent(out) :: error          !! Logical error flag
  !
  ! Local ---
  character(len=64) :: listname
  logical :: found
  type(sic_descriptor_t) :: desc
  integer :: na, ier
  type(c_ptr) :: cptr
  integer(4), pointer :: i1ptr(:)
  !
  ! Code ----
  call sic_ch(line,opt,1,listname,na,.true.,error)
  if (error) return
  call sic_descriptor(listname,desc,found)
  if (.not.found) then
    call sic_i4(line,opt,1,na,.true.,error)
    if (error) then
      call map_message(seve%e,rname,'Variable '//trim(listname)//' does not exists.')
      return 
    endif
    if (nf.eq.0) then
      nf = 1
      allocate(list(nf),stat=ier)
    else if (.not.allocated(list)) then
      call map_message(seve%e,rname,'List is not allocated')
      error = .true.
    endif
    if (error) return
    list(1:nf) = na
    return
  else if (desc%type.ne.fmt_i4) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must be Integer ')
    error = .true.
    return
  endif
  if (desc%ndim.ne.1) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must have rank 1')
    error = .true.
    return
  endif
  !
  if (nf.eq.0) then
    nf = desc%dims(1)
    allocate(list(nf),stat=ier)
  else if (nf.ne.desc%dims(1)) then
    call map_message(seve%e,rname,'Number of elements mismatch in List')
    error = .true.
  else if (.not.allocated(list)) then
    call map_message(seve%e,rname,'List is not allocated')
    error = .true.
  endif
  if (error) return
  !
  call adtoad(desc%addr,cptr,1)
  call c_f_pointer(cptr,i1ptr,[nf])
  list(1:nf) = i1ptr
end subroutine get_i4list_fromsic
!
subroutine get_r4list_fromsic(rname,line,opt,nf,list,error)
  use iso_c_binding
  use gkernel_interfaces
  use gkernel_types
  use gbl_message
  use gbl_format
  use imager_interfaces, only : map_message
  !
  ! @ public-mandatory
  !*
  !   SIC -- Utility routine
  !
  ! Return in the allocatable array the content of the 1-D
  ! SIC variable given as (first and only) argument of Option # opt.
  ! Return the size of the array in NF.
  ! If NF is non zero on entry, the size must match and the
  ! array is pre-allocated.
  !!
  character(len=*), intent(in) :: rname  !! Caller name
  character(len=*), intent(in) :: line   !! Command line
  integer, intent(in) :: opt             !! Option number
  integer, intent(inout) :: nf           !! Size of array. 
  !! If Zero on entry, automatic. If non zero, must match variable size.
  real(kind=4), allocatable, intent(inout) :: list(:)  !! List 
  logical, intent(out) :: error  !! Logical error flag
  !
  ! Local ---
  character(len=64) :: listname
  logical :: found
  type(sic_descriptor_t) :: desc
  integer :: na, ier
  real(4) :: re
  type(c_ptr) :: cptr
  real(4), pointer :: r1ptr(:)
  !
  ! Code ----
  call sic_ch(line,opt,1,listname,na,.true.,error)
  if (error) return
  call sic_descriptor(listname,desc,found)
  if (.not.found) then
    call sic_r4(line,opt,1,re,.true.,error)
    if (error) then
      call map_message(seve%e,rname,'Variable '//trim(listname)//' does not exists.')
      return 
    endif
    if (nf.eq.0) then
      nf = 1
      allocate(list(nf),stat=ier)
    else if (.not.allocated(list)) then
      call map_message(seve%e,rname,'List is not allocated')
      error = .true.
    endif
    if (error) return
    list(1:nf) = re
    return
  else if (desc%type.ne.fmt_r4) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must be Real ')
    error = .true.
    return
  endif
  if (desc%ndim.ne.1) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must have rank 1')
    error = .true.
    return
  endif
  if (nf.eq.0) then
    nf = desc%dims(1)
    allocate(list(nf),stat=ier)
  else if (nf.ne.desc%dims(1)) then
    call map_message(seve%e,rname,'Number of elements mismatch in List')
    error = .true.
  else if (.not.allocated(list)) then
    call map_message(seve%e,rname,'List is not allocated')
    error = .true.
  endif
  if (error) return
  !
  call adtoad(desc%addr,cptr,1)
  call c_f_pointer(cptr,r1ptr,[nf])
  list(1:nf) = r1ptr
end subroutine get_r4list_fromsic
!
subroutine compress_list_i4(ilist,ival,istart,iend,n)
  !
  ! @ public-mandatory
  !
  integer, intent(in) :: ilist(:)                 !! List of values
  integer, intent(in) :: ival                     !! Test value
  integer, allocatable, intent(out) :: istart(:)  !! Start of block
  integer, allocatable, intent(out) :: iend(:)    !! End of block
  integer, intent(out) :: n                       !! Number of blocks
  !
  ! Local --
  integer :: i, k, ilast, m
  !
  ! Code ---
  m = size(ilist)
  allocate(istart(m),iend(m))  ! Could use (m/2+1)
  if (ilist(1).eq.ival) then
    k = 1
    istart(k) = 1
    iend(1:2) = 0
  else
    k = 0
  endif
  ilast = ilist(1)
  !
  do i=2,m
    if (ilist(i).ne.ilast) then
      if (ilist(i).ne.ival) then
        if (k.ne.0) iend(k) = i-1
      else
        k = k+1
        istart(k) = i
        iend(k:k+1) = 0
      endif
      ilast = ilist(i)
    endif
  enddo
  !
  if (iend(k).eq.0) iend(k) = m
  n = k
end subroutine compress_list_i4

        
