module n3io1
  implicit none

  logical, save:: omit_iostat = .false.
  integer, save:: iostat = 0

contains

  subroutine iounit_new(iunit)
    integer, intent(out):: iunit
    logical:: opened, exist
    do, iunit = 100, 0, -1
      inquire(unit=iunit, opened=opened, exist=exist)
      if (exist .and. .not. opened) return
    enddo
    iunit = -1
  end subroutine

  subroutine delete(file, iostat)
    character(*), intent(in):: file
    integer, intent(out):: iostat
    integer:: u
    call iounit_new(u)
    open(unit=u, file=file, iostat=iostat)
    if (iostat /= 0) return
    close(unit=u, status="DELETE", iostat=iostat)
  end subroutine

  integer function open(file, form, access, status, recl, action)
    use n3bits, only: upcase
    character(*), intent(in):: file
    character(*), intent(in), optional:: form, access, status, action
    integer, intent(in), optional:: recl
    character(20):: qform, qaccess, qstatus, qaction
    call iounit_new(open)
    if (open == -1) return
    if (present(form)) then
      qform = form
    else
      qform = 'FORMATTED'
    endif
    call upcase(qform)
    if (present(access)) then
      qaccess = access
    else
      if (qform == 'FORMATTED') then
        qaccess = 'SEQUENTIAL'
      else
        qaccess = 'DIRECT'
      endif
    endif
    call upcase(qaccess)
    if (present(status)) then
      qstatus = status
    else
      qstatus = "UNKNOWN"
    endif
    if (present(action)) then
      qaction = action
    else
      qaction = "READWRITE"
    endif
    ! --- JUST DO IT ---
    if (qaccess == 'DIRECT') then
      if (.not. present(recl)) then
        open = -2
        return
      endif
      if (omit_iostat) then
        open(unit=open, file=file, form=qform, access=qaccess, &
        & status=qstatus, recl=recl, action=qaction)
        iostat = 0
      else
        open(unit=open, file=file, form=qform, access=qaccess, &
        & status=qstatus, recl=recl, action=qaction, iostat=iostat)
        if (iostat /= 0) open = -3
      endif
    else
      if (omit_iostat) then
        open(unit=open, file=file, form=qform, access=qaccess, &
        & status=qstatus, action=qaction)
        iostat = 0
      else
        open(unit=open, file=file, form=qform, access=qaccess, &
        & status=qstatus, action=qaction, iostat=iostat)
        if (iostat /= 0) open = -3
      endif
    endif
  end function

  subroutine writeln(line, unit)
    character(*), intent(in):: line
    integer, intent(in), optional:: unit
    if (present(unit)) then
      write(unit, '(A)', iostat=iostat) line
    else
      write(*, '(A)', iostat=iostat) line
    endif
  end subroutine

end module
