! { dg-do run }
! { dg-require-effective-target fortran_large_int }
!
! Check that we can print large integer values

program test
  implicit none
  ! 128-bit integer kind
  integer, parameter :: k = selected_int_kind(38)

  character(len=39) :: s
  character(len=100) :: buffer
  integer(kind=k) :: n
  integer :: i

  ! Random checks
  do i = 1, 1000
    call random_digits(s)
    read(s,*) n
    write(buffer,'(I0.38)') n
    print *, s
    print *, buffer
    if (adjustl(buffer) /= adjustl(s)) stop 2
  end do

  ! Systematic check
  call check(0_k, "0")
  call check(1_k, "1")
  call check(9_k, "9")
  call check(10_k, "10")
  call check(11_k, "11")
  call check(99_k, "99")
  call check(100_k, "100")
  call check(101_k, "101")
  call check(999_k, "999")
  call check(1000_k, "1000")
  call check(1001_k, "1001")
  call check(9999_k, "9999")
  call check(10000_k, "10000")
  call check(10001_k, "10001")
  call check(99999_k, "99999")
  call check(100000_k, "100000")
  call check(100001_k, "100001")
  call check(999999_k, "999999")
  call check(1000000_k, "1000000")
  call check(1000001_k, "1000001")
  call check(9999999_k, "9999999")
  call check(10000000_k, "10000000")
  call check(10000001_k, "10000001")
  call check(99999999_k, "99999999")
  call check(100000000_k, "100000000")
  call check(100000001_k, "100000001")
  call check(999999999_k, "999999999")
  call check(1000000000_k, "1000000000")
  call check(1000000001_k, "1000000001")
  call check(9999999999_k, "9999999999")
  call check(10000000000_k, "10000000000")
  call check(10000000001_k, "10000000001")
  call check(99999999999_k, "99999999999")
  call check(100000000000_k, "100000000000")
  call check(100000000001_k, "100000000001")
  call check(999999999999_k, "999999999999")
  call check(1000000000000_k, "1000000000000")
  call check(1000000000001_k, "1000000000001")
  call check(9999999999999_k, "9999999999999")
  call check(10000000000000_k, "10000000000000")
  call check(10000000000001_k, "10000000000001")
  call check(99999999999999_k, "99999999999999")
  call check(100000000000000_k, "100000000000000")
  call check(100000000000001_k, "100000000000001")
  call check(999999999999999_k, "999999999999999")
  call check(1000000000000000_k, "1000000000000000")
  call check(1000000000000001_k, "1000000000000001")
  call check(9999999999999999_k, "9999999999999999")
  call check(10000000000000000_k, "10000000000000000")
  call check(10000000000000001_k, "10000000000000001")
  call check(99999999999999999_k, "99999999999999999")
  call check(100000000000000000_k, "100000000000000000")
  call check(100000000000000001_k, "100000000000000001")
  call check(999999999999999999_k, "999999999999999999")
  call check(1000000000000000000_k, "1000000000000000000")
  call check(1000000000000000001_k, "1000000000000000001")
  call check(9999999999999999999_k, "9999999999999999999")
  call check(10000000000000000000_k, "10000000000000000000")
  call check(10000000000000000001_k, "10000000000000000001")
  call check(99999999999999999999_k, "99999999999999999999")
  call check(100000000000000000000_k, "100000000000000000000")
  call check(100000000000000000001_k, "100000000000000000001")
  call check(999999999999999999999_k, "999999999999999999999")
  call check(1000000000000000000000_k, "1000000000000000000000")
  call check(1000000000000000000001_k, "1000000000000000000001")
  call check(9999999999999999999999_k, "9999999999999999999999")
  call check(10000000000000000000000_k, "10000000000000000000000")
  call check(10000000000000000000001_k, "10000000000000000000001")
  call check(99999999999999999999999_k, "99999999999999999999999")
  call check(100000000000000000000000_k, "100000000000000000000000")
  call check(100000000000000000000001_k, "100000000000000000000001")
  call check(999999999999999999999999_k, "999999999999999999999999")
  call check(1000000000000000000000000_k, "1000000000000000000000000")
  call check(1000000000000000000000001_k, "1000000000000000000000001")
  call check(9999999999999999999999999_k, "9999999999999999999999999")
  call check(10000000000000000000000000_k, "10000000000000000000000000")
  call check(10000000000000000000000001_k, "10000000000000000000000001")
  call check(99999999999999999999999999_k, "99999999999999999999999999")
  call check(100000000000000000000000000_k, "100000000000000000000000000")
  call check(100000000000000000000000001_k, "100000000000000000000000001")
  call check(999999999999999999999999999_k, "999999999999999999999999999")
  call check(1000000000000000000000000000_k, "1000000000000000000000000000")
  call check(1000000000000000000000000001_k, "1000000000000000000000000001")
  call check(9999999999999999999999999999_k, "9999999999999999999999999999")
  call check(10000000000000000000000000000_k, "10000000000000000000000000000")
  call check(10000000000000000000000000001_k, "10000000000000000000000000001")
  call check(99999999999999999999999999999_k, "99999999999999999999999999999")
  call check(100000000000000000000000000000_k, "100000000000000000000000000000")
  call check(100000000000000000000000000001_k, "100000000000000000000000000001")
  call check(999999999999999999999999999999_k, "999999999999999999999999999999")
  call check(1000000000000000000000000000000_k, "1000000000000000000000000000000")
  call check(1000000000000000000000000000001_k, "1000000000000000000000000000001")
  call check(9999999999999999999999999999999_k, "9999999999999999999999999999999")
  call check(10000000000000000000000000000000_k, "10000000000000000000000000000000")
  call check(10000000000000000000000000000001_k, "10000000000000000000000000000001")
  call check(99999999999999999999999999999999_k, "99999999999999999999999999999999")
  call check(100000000000000000000000000000000_k, "100000000000000000000000000000000")
  call check(100000000000000000000000000000001_k, "100000000000000000000000000000001")
  call check(999999999999999999999999999999999_k, "999999999999999999999999999999999")
  call check(1000000000000000000000000000000000_k, "1000000000000000000000000000000000")
  call check(1000000000000000000000000000000001_k, "1000000000000000000000000000000001")
  call check(9999999999999999999999999999999999_k, "9999999999999999999999999999999999")
  call check(10000000000000000000000000000000000_k, "10000000000000000000000000000000000")
  call check(10000000000000000000000000000000001_k, "10000000000000000000000000000000001")
  call check(99999999999999999999999999999999999_k, "99999999999999999999999999999999999")
  call check(100000000000000000000000000000000000_k, "100000000000000000000000000000000000")
  call check(100000000000000000000000000000000001_k, "100000000000000000000000000000000001")
  call check(999999999999999999999999999999999999_k, "999999999999999999999999999999999999")
  call check(1000000000000000000000000000000000000_k, "1000000000000000000000000000000000000")
  call check(1000000000000000000000000000000000001_k, "1000000000000000000000000000000000001")
  call check(9999999999999999999999999999999999999_k, "9999999999999999999999999999999999999")
  call check(10000000000000000000000000000000000000_k, "10000000000000000000000000000000000000")
  call check(10000000000000000000000000000000000001_k, "10000000000000000000000000000000000001")
  call check(99999999999999999999999999999999999999_k, "99999999999999999999999999999999999999")
  call check(100000000000000000000000000000000000000_k, "100000000000000000000000000000000000000")
  call check(100000000000000000000000000000000000001_k, "100000000000000000000000000000000000001")
  call check(109999999999999999999999999999999999999_k, "109999999999999999999999999999999999999")

  call check(-1_k, "-1")
  call check(-9_k, "-9")
  call check(-10_k, "-10")
  call check(-11_k, "-11")
  call check(-99_k, "-99")
  call check(-100_k, "-100")
  call check(-101_k, "-101")
  call check(-999_k, "-999")
  call check(-1000_k, "-1000")
  call check(-1001_k, "-1001")
  call check(-9999_k, "-9999")
  call check(-10000_k, "-10000")
  call check(-10001_k, "-10001")
  call check(-99999_k, "-99999")
  call check(-100000_k, "-100000")
  call check(-100001_k, "-100001")
  call check(-999999_k, "-999999")
  call check(-1000000_k, "-1000000")
  call check(-1000001_k, "-1000001")
  call check(-9999999_k, "-9999999")
  call check(-10000000_k, "-10000000")
  call check(-10000001_k, "-10000001")
  call check(-99999999_k, "-99999999")
  call check(-100000000_k, "-100000000")
  call check(-100000001_k, "-100000001")
  call check(-999999999_k, "-999999999")
  call check(-1000000000_k, "-1000000000")
  call check(-1000000001_k, "-1000000001")
  call check(-9999999999_k, "-9999999999")
  call check(-10000000000_k, "-10000000000")
  call check(-10000000001_k, "-10000000001")
  call check(-99999999999_k, "-99999999999")
  call check(-100000000000_k, "-100000000000")
  call check(-100000000001_k, "-100000000001")
  call check(-999999999999_k, "-999999999999")
  call check(-1000000000000_k, "-1000000000000")
  call check(-1000000000001_k, "-1000000000001")
  call check(-9999999999999_k, "-9999999999999")
  call check(-10000000000000_k, "-10000000000000")
  call check(-10000000000001_k, "-10000000000001")
  call check(-99999999999999_k, "-99999999999999")
  call check(-100000000000000_k, "-100000000000000")
  call check(-100000000000001_k, "-100000000000001")
  call check(-999999999999999_k, "-999999999999999")
  call check(-1000000000000000_k, "-1000000000000000")
  call check(-1000000000000001_k, "-1000000000000001")
  call check(-9999999999999999_k, "-9999999999999999")
  call check(-10000000000000000_k, "-10000000000000000")
  call check(-10000000000000001_k, "-10000000000000001")
  call check(-99999999999999999_k, "-99999999999999999")
  call check(-100000000000000000_k, "-100000000000000000")
  call check(-100000000000000001_k, "-100000000000000001")
  call check(-999999999999999999_k, "-999999999999999999")
  call check(-1000000000000000000_k, "-1000000000000000000")
  call check(-1000000000000000001_k, "-1000000000000000001")
  call check(-9999999999999999999_k, "-9999999999999999999")
  call check(-10000000000000000000_k, "-10000000000000000000")
  call check(-10000000000000000001_k, "-10000000000000000001")
  call check(-99999999999999999999_k, "-99999999999999999999")
  call check(-100000000000000000000_k, "-100000000000000000000")
  call check(-100000000000000000001_k, "-100000000000000000001")
  call check(-999999999999999999999_k, "-999999999999999999999")
  call check(-1000000000000000000000_k, "-1000000000000000000000")
  call check(-1000000000000000000001_k, "-1000000000000000000001")
  call check(-9999999999999999999999_k, "-9999999999999999999999")
  call check(-10000000000000000000000_k, "-10000000000000000000000")
  call check(-10000000000000000000001_k, "-10000000000000000000001")
  call check(-99999999999999999999999_k, "-99999999999999999999999")
  call check(-100000000000000000000000_k, "-100000000000000000000000")
  call check(-100000000000000000000001_k, "-100000000000000000000001")
  call check(-999999999999999999999999_k, "-999999999999999999999999")
  call check(-1000000000000000000000000_k, "-1000000000000000000000000")
  call check(-1000000000000000000000001_k, "-1000000000000000000000001")
  call check(-9999999999999999999999999_k, "-9999999999999999999999999")
  call check(-10000000000000000000000000_k, "-10000000000000000000000000")
  call check(-10000000000000000000000001_k, "-10000000000000000000000001")
  call check(-99999999999999999999999999_k, "-99999999999999999999999999")
  call check(-100000000000000000000000000_k, "-100000000000000000000000000")
  call check(-100000000000000000000000001_k, "-100000000000000000000000001")
  call check(-999999999999999999999999999_k, "-999999999999999999999999999")
  call check(-1000000000000000000000000000_k, "-1000000000000000000000000000")
  call check(-1000000000000000000000000001_k, "-1000000000000000000000000001")
  call check(-9999999999999999999999999999_k, "-9999999999999999999999999999")
  call check(-10000000000000000000000000000_k, "-10000000000000000000000000000")
  call check(-10000000000000000000000000001_k, "-10000000000000000000000000001")
  call check(-99999999999999999999999999999_k, "-99999999999999999999999999999")
  call check(-100000000000000000000000000000_k, "-100000000000000000000000000000")
  call check(-100000000000000000000000000001_k, "-100000000000000000000000000001")
  call check(-999999999999999999999999999999_k, "-999999999999999999999999999999")
  call check(-1000000000000000000000000000000_k, "-1000000000000000000000000000000")
  call check(-1000000000000000000000000000001_k, "-1000000000000000000000000000001")
  call check(-9999999999999999999999999999999_k, "-9999999999999999999999999999999")
  call check(-10000000000000000000000000000000_k, "-10000000000000000000000000000000")
  call check(-10000000000000000000000000000001_k, "-10000000000000000000000000000001")
  call check(-99999999999999999999999999999999_k, "-99999999999999999999999999999999")
  call check(-100000000000000000000000000000000_k, "-100000000000000000000000000000000")
  call check(-100000000000000000000000000000001_k, "-100000000000000000000000000000001")
  call check(-999999999999999999999999999999999_k, "-999999999999999999999999999999999")
  call check(-1000000000000000000000000000000000_k, "-1000000000000000000000000000000000")
  call check(-1000000000000000000000000000000001_k, "-1000000000000000000000000000000001")
  call check(-9999999999999999999999999999999999_k, "-9999999999999999999999999999999999")
  call check(-10000000000000000000000000000000000_k, "-10000000000000000000000000000000000")
  call check(-10000000000000000000000000000000001_k, "-10000000000000000000000000000000001")
  call check(-99999999999999999999999999999999999_k, "-99999999999999999999999999999999999")
  call check(-100000000000000000000000000000000000_k, "-100000000000000000000000000000000000")
  call check(-100000000000000000000000000000000001_k, "-100000000000000000000000000000000001")
  call check(-999999999999999999999999999999999999_k, "-999999999999999999999999999999999999")
  call check(-1000000000000000000000000000000000000_k, "-1000000000000000000000000000000000000")
  call check(-1000000000000000000000000000000000001_k, "-1000000000000000000000000000000000001")
  call check(-9999999999999999999999999999999999999_k, "-9999999999999999999999999999999999999")
  call check(-10000000000000000000000000000000000000_k, "-10000000000000000000000000000000000000")
  call check(-10000000000000000000000000000000000001_k, "-10000000000000000000000000000000000001")
  call check(-99999999999999999999999999999999999999_k, "-99999999999999999999999999999999999999")
  call check(-100000000000000000000000000000000000000_k, "-100000000000000000000000000000000000000")
  call check(-100000000000000000000000000000000000001_k, "-100000000000000000000000000000000000001")
  call check(-109999999999999999999999999999999999999_k, "-109999999999999999999999999999999999999")

contains

  subroutine check (i, str)
    implicit none
    integer(kind=k), intent(in), value :: i
    character(len=*), intent(in) :: str

    character(len=100) :: buffer
    write(buffer,*) i
    if (adjustl(buffer) /= adjustl(str)) stop 1
  end subroutine

  subroutine random_digits (str)
    implicit none
    integer, parameter :: l = 38
    character(len=l+1) :: str
    real :: r
    integer :: i, d

    str = ""
    do i = 2, l+1
      call random_number(r)
      d = floor(r * 10)
      str(i:i) = achar(48 + d)
    end do

    call random_number(r)
    if (r > 0.5) then
      str(1:1) = '-'
    end if
  end subroutine
end
