module classic_interfaces_public
  interface
    subroutine classic_message_set_id(id)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      ! Alter library id into input id. Should be called by the library
      ! which wants to share its id with the current one.
      !---------------------------------------------------------------------
      integer(kind=4), intent(in) :: id         !
    end subroutine classic_message_set_id
  end interface
  !
  interface
    subroutine classic_init(error)
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !  Initialize the Classic library. This should be done only once at
      ! startup. The library will refuse opening a Classic file as long
      ! as this has not been done.
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Logical error flag
    end subroutine classic_init
  end interface
  !
  interface
    subroutine classic_entry_init(file,xnum,maxsec,version,full,ed,error)
      use classic_params
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      ! Initialize the Entry for a new observation
      !---------------------------------------------------------------------
      type(classic_file_t),       intent(inout) :: file     !
      integer(kind=entry_length), intent(in)    :: xnum     ! The corresponding Entry number
      integer(kind=4),            intent(in)    :: maxsec   ! Maximum number of sections the ed can describe
      integer(kind=4),            intent(in)    :: version  ! Observation version
      logical,                    intent(out)   :: full     ! File is full?
      type(classic_entrydesc_t),  intent(out)   :: ed       ! The new Entry Descriptor
      logical,                    intent(inout) :: error    ! Logical error flag
    end subroutine classic_entry_init
  end interface
  !
  interface
    subroutine classic_entry_section_read(isec,lsec,sec,ed,buf,error)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Read a section from an entry
      !---------------------------------------------------------------------
      integer(kind=4),           intent(in)    :: isec    ! Section id
      integer(kind=data_length), intent(inout) :: lsec    ! Length of section (updated on return)
      integer(kind=4),           intent(inout) :: sec(*)  ! Section buffer
      type(classic_entrydesc_t), intent(in)    :: ed      ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf     ! Working buffer
      logical,                   intent(inout) :: error   ! Logical error flag
    end subroutine classic_entry_section_read
  end interface
  !
  interface
    subroutine classic_entry_data_read(array,ndata,ed,buf,error)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public-mandatory (because symbol is used elsewhere)
      !  Read the 'data' block from the entry
      !---------------------------------------------------------------------
      integer(kind=data_length), intent(inout) :: ndata         ! Length in 32_bit words (updated)
      real(kind=4),              intent(out)   :: array(ndata)  ! Data itself
      type(classic_entrydesc_t), intent(in)    :: ed            ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf           ! Working buffer
      logical,                   intent(inout) :: error         ! Logical error flag
    end subroutine classic_entry_data_read
  end interface
  !
  interface
    subroutine classic_entry_data_readsub(array,ndata,first,last,ed,buf,error)
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Read a subset of the 'data' block from the entry
      !---------------------------------------------------------------------
      integer(kind=data_length), intent(inout) :: ndata         ! Length in 32_bit words (updated)
      real(kind=4),              intent(out)   :: array(ndata)  ! Data itself
      integer(kind=data_length), intent(in)    :: first         ! First data word to read
      integer(kind=data_length), intent(in)    :: last          ! Last data word to read
      type(classic_entrydesc_t), intent(in)    :: ed            ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf           ! Working buffer
      logical,                   intent(inout) :: error         ! Logical error flag
    end subroutine classic_entry_data_readsub
  end interface
  !
  interface
    subroutine classic_entry_section_add(isec,lsec,sec,ed,buf,error)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Add a new section to an entry. Must not exist before.
      !---------------------------------------------------------------------
      integer(kind=4),           intent(in)    :: isec    ! Section id
      integer(kind=data_length), intent(in)    :: lsec    ! Length of section
      integer(kind=4),           intent(in)    :: sec(*)  ! Section buffer
      type(classic_entrydesc_t), intent(inout) :: ed      ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf     ! Working buffer
      logical,                   intent(inout) :: error   ! Logical error flag
    end subroutine classic_entry_section_add
  end interface
  !
  interface
    subroutine classic_entry_section_update(isec,lsec,sec,ed,buf,error)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Update an old section in an entry. Must exist before.
      !---------------------------------------------------------------------
      integer(kind=4),           intent(in)    :: isec    ! Section id
      integer(kind=data_length), intent(in)    :: lsec    ! Length of section
      integer(kind=4),           intent(in)    :: sec(*)  ! Section buffer
      type(classic_entrydesc_t), intent(in)    :: ed      ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf     ! Working buffer
      logical,                   intent(inout) :: error   ! Logical error flag
    end subroutine classic_entry_section_update
  end interface
  !
  interface
    subroutine classic_entry_data_add(array,ndata,ed,buf,error)
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Write the 'data' block to the entry. Must not exist before.
      !---------------------------------------------------------------------
      integer(kind=data_length), intent(in)    :: ndata         ! Length in 32_bit words
      real(kind=4),              intent(in)    :: array(ndata)  ! Data itself
      type(classic_entrydesc_t), intent(inout) :: ed            ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf           ! Working buffer
      logical,                   intent(inout) :: error         ! Logical error flag
    end subroutine classic_entry_data_add
  end interface
  !
  interface
    subroutine classic_entry_data_update(array,ndata,ed,buf,error)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Update the 'data' block to the entry. Must exist before.
      !---------------------------------------------------------------------
      integer(kind=data_length), intent(in)    :: ndata         ! Length in 32_bit words
      real(kind=4),              intent(in)    :: array(ndata)  ! Data itself
      type(classic_entrydesc_t), intent(inout) :: ed            ! The Entry Descriptor
      type(classic_recordbuf_t), intent(inout) :: buf           ! Working buffer
      logical,                   intent(inout) :: error         ! Logical error flag
    end subroutine classic_entry_data_update
  end interface
  !
  interface
    subroutine classic_entry_close(file,buf,error)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Perform the needed operations when all the entry elements have
      ! been written.
      !---------------------------------------------------------------------
      type(classic_file_t),      intent(inout) :: file   !
      type(classic_recordbuf_t), intent(in)    :: buf    !
      logical,                   intent(inout) :: error  !
    end subroutine classic_entry_close
  end interface
  !
  interface
    subroutine classic_entrydesc_read(file,buf,ed,error)
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !   Read the Entry Descriptor
      !---------------------------------------------------------------------
      type(classic_file_t),      intent(in)    :: file   !
      type(classic_recordbuf_t), intent(inout) :: buf    ! Working buffer
      type(classic_entrydesc_t), intent(inout) :: ed     ! The Entry Descriptor read
      logical,                   intent(inout) :: error  ! Logical error flag
    end subroutine classic_entrydesc_read
  end interface
  !
  interface
    subroutine classic_entrydesc_write(file,buf,ed,error)
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !   Write the input Entry Descriptor
      !---------------------------------------------------------------------
      type(classic_file_t),      intent(inout) :: file   !
      type(classic_recordbuf_t), intent(inout) :: buf    ! Working buffer
      type(classic_entrydesc_t), intent(in)    :: ed     ! The Entry Descriptor to be written
      logical,                   intent(inout) :: error  ! Logical error flag
    end subroutine classic_entrydesc_write
  end interface
  !
  interface
    function classic_entrydesc_seclen(ed,iden)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      ! Return the length of the identified section (or 0 if missing).
      ! Unefficient if you call each section one by one.
      !---------------------------------------------------------------------
      integer(kind=4) :: classic_entrydesc_seclen
      type(classic_entrydesc_t), intent(in)  :: ed    ! The Entry Descriptor
      integer(kind=4),           intent(in)  :: iden  ! The section identifier
    end function classic_entrydesc_seclen
  end interface
  !
  interface
    subroutine classic_entrydesc_secfind_one(ed,iden,found,num)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Find if 1 section is present in the input Entry Descriptor.
      ! Inefficient if you test each section one by one.
      !---------------------------------------------------------------------
      type(classic_entrydesc_t), intent(in)  :: ed     ! The Entry Descriptor
      integer(kind=4),           intent(in)  :: iden   ! The section identifier
      logical,                   intent(out) :: found  ! Section was found or not?
      integer(kind=4),           intent(out) :: num    ! The section number (if found)
    end subroutine classic_entrydesc_secfind_one
  end interface
  !
  interface
    subroutine classic_entrydesc_secfind_all(ed,found,first,error)
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !   Fill a 'found' array for all sections present or not. This assumes
      ! that the section identifiers (seciden(:) values) can be used as
      ! position index (maybe with an offset) in the 'found' array.
      !---------------------------------------------------------------------
      type(classic_entrydesc_t), intent(in)    :: ed        ! The Entry Descriptor
      logical,                   intent(out)   :: found(:)  ! Sections were found or not?
      integer(kind=4),           intent(in)    :: first     ! First index in the array (offset)
      logical,                   intent(inout) :: error     ! Logical error flag
    end subroutine classic_entrydesc_secfind_all
  end interface
  !
  interface
    subroutine classic_entrydesc_dump(ed)
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Dump the input Entry Descriptor
      !---------------------------------------------------------------------
      type(classic_entrydesc_t), intent(in) :: ed  ! The Entry Descriptor
    end subroutine classic_entrydesc_dump
  end interface
  !
  interface
    subroutine classic_filedesc_init(file,fkind,lsingle,lsize,vind,lind,gex,error)
      use gildas_def
      use gbl_format
      use gbl_message
      use classic_params
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !   Initialize a new File Descriptor.
      !   The following elements must have been set before:
      !       file%lun, file%spec, file%nspec
      !   On return, those are set:
      !       file%desc, file%conv
      !---------------------------------------------------------------------
      type(classic_file_t),       intent(inout) :: file     !
      integer(kind=4),            intent(in)    :: fkind    ! File kind
      logical,                    intent(in)    :: lsingle  ! Single or multiple
      integer(kind=entry_length), intent(in)    :: lsize    ! Total number of entries (linear growth)
      integer(kind=4),            intent(in)    :: vind     ! Index version
      integer(kind=4),            intent(in)    :: lind     ! Index length (words)
      real(kind=4),               intent(in)    :: gex      ! Extension growth
      logical,                    intent(inout) :: error    ! Logical error flag
    end subroutine classic_filedesc_init
  end interface
  !
  interface
    subroutine classic_filedesc_open(file,error)
      use gbl_message
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      ! Open and read the File Descriptor, namely:
      ! - Get the File Code and set the File-Data-Type-to-System-Data-Type
      !   conversion code,
      ! - Read the File Descriptor from the file, and take care of the
      !   possible conversion.
      ! Fortran-open the file itself if needed.
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file   !
      logical,              intent(out)   :: error  ! Logical error flag
    end subroutine classic_filedesc_open
  end interface
  !
  interface
    subroutine classic_filedesc_read(file,error)
      use gbl_message
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !   Read the File Descriptor from the file, and take care of the
      ! possible conversion. The file itself must have been opened before.
      ! The conversion code is not reevaluated.
      !   It may be useful to re-read a File Descriptor because another
      ! program might have updated it since last classic_filedesc_open or
      ! classic_filedesc_read.
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file   !
      logical,              intent(inout) :: error  ! Logical error flag
    end subroutine classic_filedesc_read
  end interface
  !
  interface
    subroutine classic_filedesc_write(file,error)
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      ! Write the File Descriptor to the file.
      ! The file itself must have been opened before
      !---------------------------------------------------------------------
      type(classic_file_t), intent(in)    :: file   !
      logical,              intent(inout) :: error  ! Logical error flag
    end subroutine classic_filedesc_write
  end interface
  !
  interface
    subroutine classic_filedesc_dump(fdesc,name)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      ! Dump the content of the File Descriptor
      !---------------------------------------------------------------------
      type(classic_filedesc_t), intent(in) :: fdesc  ! The File Descriptor
      character(len=*),         intent(in) :: name   ! The File Descriptor name (some prefix)
    end subroutine classic_filedesc_dump
  end interface
  !
  interface
    subroutine reallocate_recordbuf(buf,len,error)
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Allocate or reallocate the input working buffer
      !---------------------------------------------------------------------
      type(classic_recordbuf_t), intent(inout) :: buf    !
      integer(kind=4),           intent(in)    :: len    ! New length required
      logical,                   intent(inout) :: error  ! Logical error flag
    end subroutine reallocate_recordbuf
  end interface
  !
  interface
    subroutine deallocate_recordbuf(buf,error)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Deallocate the input working buffer
      !---------------------------------------------------------------------
      type(classic_recordbuf_t), intent(inout) :: buf    !
      logical,                   intent(inout) :: error  ! Logical error flag
    end subroutine deallocate_recordbuf
  end interface
  !
  interface
    subroutine classic_file_loss(file,unused,error)
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      ! Parse the input file and search for unused (lost) bytes
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file    !
      integer(kind=4),      intent(in)    :: unused  ! Number of unused bytes per Index
      logical,              intent(inout) :: error   !
    end subroutine classic_file_loss
  end interface
  !
  interface
    subroutine classic_file_copy(in,ou,error)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Copy the input classic_file_t into the output one, taking care
      ! of some special elements like pointers and allocatables.
      !---------------------------------------------------------------------
      type(classic_file_t), intent(in)    :: in     !
      type(classic_file_t), intent(inout) :: ou     !
      logical,              intent(inout) :: error  ! Logical error flag
    end subroutine classic_file_copy
  end interface
  !
  interface
    function classic_file_size(file)
      use gildas_def
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      ! Return the file size (according to its descriptor) in bytes
      !---------------------------------------------------------------------
      integer(kind=size_length) :: classic_file_size
      type(classic_file_t), intent(in) :: file
    end function classic_file_size
  end interface
  !
  interface
    subroutine classic_file_init(file,version,reclen,error)
      use gbl_message
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !   Initialize a new Classic file. The following elements must have
      ! been set before:
      !   file%lun
      !   file%spec
      !   file%nspec
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file     !
      integer(kind=4),      intent(in)    :: version  ! File version
      integer(kind=4),      intent(in)    :: reclen   ! Record length (words)
      logical,              intent(inout) :: error    ! Logical error flag
    end subroutine classic_file_init
  end interface
  !
  interface
    subroutine classic_file_open(file,readwrite,error)
      use gbl_message
      use classic_types
      use classic_vars
      !---------------------------------------------------------------------
      ! @ public
      !   Open an old Classic file. The following elements must have been
      ! set before:
      !   file%lun
      !   file%spec
      !   file%nspec
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file       !
      logical,              intent(in)    :: readwrite  !
      logical,              intent(inout) :: error      ! Logical error flag
    end subroutine classic_file_open
  end interface
  !
  interface
    subroutine classic_file_close(file,error)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Perform the needed operations to close a classic_file_t structure
      !---------------------------------------------------------------------
      type(classic_file_t), intent(inout) :: file   !
      logical,              intent(inout) :: error  !
    end subroutine classic_file_close
  end interface
  !
  interface
    subroutine classic_file_fopen(file,statu,error)
      use gbl_format
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Fortran-open the given Classic file. The following elements must
      ! have been set before:
      !   file%lun
      !   file%spec
      !   file%nspec
      !   file%readwrite
      !   file%desc%reclen
      !---------------------------------------------------------------------
      type(classic_file_t), intent(in)    :: file   !
      character(len=*),     intent(in)    :: statu  ! 'OLD' or 'NEW'
      logical,              intent(inout) :: error  !
    end subroutine classic_file_fopen
  end interface
  !
  interface
    subroutine classic_file_fclose(file,error)
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Fortran-close the given Classic file. The following elements must
      ! have been set before:
      !   file%lun
      !   file%spec
      !---------------------------------------------------------------------
      type(classic_file_t), intent(in)    :: file   !
      logical,              intent(inout) :: error  !
    end subroutine classic_file_fclose
  end interface
  !
  interface
    subroutine classic_file_fflush(file,error)
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      ! Fortran-flush the given Classic file. According to Fortran:
      !   "Execution of a FLUSH statement causes data written to an
      !    external file to be available to other processes, or causes data
      !    placed in an external file by means other than Fortran to be
      !    available to a READ statement. These actions are processor
      !    dependent."
      ! In other words, it works on both writing and reading files.
      !---------------------------------------------------------------------
      type(classic_file_t), intent(in)    :: file   !
      logical,              intent(inout) :: error  !
    end subroutine classic_file_fflush
  end interface
  !
  interface
    subroutine classic_entryindex_read(file,entry_num,data,buf,error)
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  Read an entry in the given file, and return its Entry Index in the
      ! 'data(*)' buffer
      !---------------------------------------------------------------------
      type(classic_file_t),       intent(in)    :: file       !
      integer(kind=entry_length), intent(in)    :: entry_num  ! Entry number
      integer(kind=4),            intent(out)   :: data(*)    !
      type(classic_recordbuf_t),  intent(inout) :: buf        ! Working buffer
      logical,                    intent(inout) :: error      ! Logical errror flag
    end subroutine classic_entryindex_read
  end interface
  !
  interface
    subroutine classic_entryindex_write(file,entry_num,data,buf,error)
      use gbl_message
      use classic_params
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !   Write the given Entry Index ('data(*)' buffer) for the given entry
      ! in the given file. There must be room already provisioned for the
      ! entry in the Extension Index.
      !---------------------------------------------------------------------
      type(classic_file_t),       intent(in)    :: file       !
      integer(kind=entry_length), intent(in)    :: entry_num  ! Entry number
      integer(kind=4),            intent(in)    :: data(*)    !
      type(classic_recordbuf_t),  intent(inout) :: buf        ! Working buffer
      logical,                    intent(inout) :: error      ! Logical errror flag
    end subroutine classic_entryindex_write
  end interface
  !
  interface
    subroutine classic_recordbuf_open(file,rstart,wstart,buf,error)
      use gbl_message
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      ! Open the buffer for reading a new object
      !---------------------------------------------------------------------
      type(classic_file_t),      intent(in)    :: file    !
      integer(kind=8),           intent(in)    :: rstart  ! First record of the object
      integer(kind=4),           intent(in)    :: wstart  ! First word in this record
      type(classic_recordbuf_t), intent(inout) :: buf     !
      logical,                   intent(inout) :: error   !
    end subroutine classic_recordbuf_open
  end interface
  !
  interface
    subroutine classic_recordbuf_nullify(buf)
      use classic_types
      !---------------------------------------------------------------------
      ! @ public
      !  "Nullify" the input buffer i.e. reset its record positions so that
      ! recordbuf_read/write won't assume something useful is stored in the
      ! data buffer.
      !---------------------------------------------------------------------
      type(classic_recordbuf_t), intent(inout) :: buf  !
    end subroutine classic_recordbuf_nullify
  end interface
  !
  interface
    subroutine toc_init_pointers(toc,error)
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      !  Initialize the pointers arrays
      !---------------------------------------------------------------------
      type(toc_t), intent(inout), target :: toc    ! Table-Of-Content description
      logical,     intent(inout)         :: error  !
    end subroutine toc_init_pointers
  end interface
  !
  interface
    subroutine toc_clean(toc,error)
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      !  Clean all the TOC structure
      !---------------------------------------------------------------------
      type(toc_t), intent(inout) :: toc    ! Table-Of-Content description
      logical,     intent(inout) :: error  !
    end subroutine toc_clean
  end interface
  !
  interface
    subroutine toc_getkeys(line,iopt,toc,keys,error)
      use gbl_message
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      !  Get arguments of option /TOC from command line. 'keys' is unchanged
      ! if no argument is present.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line     ! Command line
      integer(kind=4),  intent(in)    :: iopt     ! Option number
      type(toc_t),      intent(in)    :: toc      ! Table-Of-Content description
      integer(kind=4),  intent(inout) :: keys(:)  ! List of key identifiers retrieved
      logical,          intent(inout) :: error    ! Error flag
    end subroutine toc_getkeys
  end interface
  !
  interface
    subroutine toc_main(rname,toc,nentry,keywords,sname,olun,p_format,error,dobak)
      use gbl_message
      use classic_params
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      !  Main Table-Of-Contents engine
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: rname        ! Calling routine name
      type(toc_t),                intent(inout) :: toc          !
      integer(kind=entry_length), intent(in)    :: nentry       ! Size of index (can be 0)
      integer(kind=4),            intent(in)    :: keywords(:)  ! Selection
      character(len=*),           intent(in)    :: sname        ! Sic structure name (none if empty)
      integer(kind=4),            intent(in)    :: olun         ! Output logical unit
      interface
        subroutine p_format(key,ival,output)  ! Formatting subroutine
        use classic_params
        use toc_types
        type(toc_descriptor_t),     intent(in)  :: key
        integer(kind=entry_length), intent(in)  :: ival
        character(len=*),           intent(out) :: output
        end subroutine p_format
      end interface
      logical,                    intent(inout) :: error        ! Logical error flag
      logical, optional,          intent(in)    :: dobak        ! Also generate the back pointers?
    end subroutine toc_main
  end interface
  !
  interface
    subroutine toc_select_all(rname,toc,nentry,keywords,dobak,p_format,error)
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      !  Compute the equivalence classes for all (combined) keywords
      !---------------------------------------------------------------------
      character(len=*),           intent(in)    :: rname
      type(toc_t),                intent(inout) :: toc
      integer(kind=entry_length), intent(in)    :: nentry       ! Size of index
      integer(kind=4),            intent(in)    :: keywords(:)  ! Selection (key identifiers)
      logical,                    intent(in)    :: dobak        ! Also generate the back pointers (key%select%bak)?
      interface
        subroutine p_format(key,ival,output)  ! Formatting subroutine
        use classic_params
        use toc_types
        type(toc_descriptor_t),     intent(in)  :: key
        integer(kind=entry_length), intent(in)  :: ival
        character(len=*),           intent(out) :: output
        end subroutine p_format
      end interface
      logical,                    intent(inout) :: error
    end subroutine toc_select_all
  end interface
  !
  interface
    function toc_generic_eq(ptrs,m,l)
      use classic_params
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      ! TOC support routine
      !---------------------------------------------------------------------
      logical :: toc_generic_eq  ! Function value on return
      type(toc_pointers_t),       intent(in) :: ptrs  ! Pointers to data arrays
      integer(kind=entry_length), intent(in) :: m     ! Observation number
      integer(kind=entry_length), intent(in) :: l     ! Observation number
    end function toc_generic_eq
  end interface
  !
  interface
    subroutine toc_format(key,ival,output)
      use toc_types
      !---------------------------------------------------------------------
      ! @ public
      ! TOC support routine: generic formatting routine
      !---------------------------------------------------------------------
      type(toc_descriptor_t),     intent(in)  :: key     !
      integer(kind=entry_length), intent(in)  :: ival    !
      character(len=*),           intent(out) :: output  !
    end subroutine toc_format
  end interface
  !
end module classic_interfaces_public
