Commit 2527159d authored by Graham, Aaron's avatar Graham, Aaron
Browse files

Try to prevent Timer error once and for all

modifies timer routines to return StringType instead of fixed-length characters
parent 9b2b6136
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ USE ISO_FORTRAN_ENV
USE IntrType
USE ExceptionHandler
USE Times
USE Strings
USE IO_Strings
USE FileType_Fortran
IMPLICIT NONE
+37 −45
Original line number Diff line number Diff line
@@ -70,26 +70,12 @@ PUBLIC :: TimerPtrArray
PUBLIC :: getDate
PUBLIC :: getClockTime
PUBLIC :: getTimeFromDate
PUBLIC :: MAXLEN_TIME_STRING
PUBLIC :: MAXLEN_DATE_STRING
PUBLIC :: MAXLEN_CLOCK_STRING
PUBLIC :: runTestTimes
INTERFACE
  MODULE SUBROUTINE runTestTimes()
  ENDSUBROUTINE runTestTimes
ENDINTERFACE

!> Maximum length of character string for the reported time
INTEGER(SIK),PARAMETER :: MAXLEN_TIME_STRING=20
!> Maximum length of character string for the reported date
INTEGER(SIK),PARAMETER :: MAXLEN_DATE_STRING=13
!> Maximum length of character string for the elapsed time (private)
INTEGER(SIK),PARAMETER :: MAXLEN_ETIME=11
!> Maximum length of character string for the reported clock time
INTEGER(SIK),PARAMETER :: MAXLEN_CLOCK_STRING=8
!> Maximum length of the time unit string
INTEGER(SIK),PARAMETER :: MAXLEN_TIME_UNITS=9

!> @brief Derived Datatype for the Timer data object
!>
!> This is the data object is used to define default timers within the
@@ -105,10 +91,10 @@ TYPE :: TimerType
  !> The elapsed time recorded for this timer in seconds.
  REAL(SDK) :: elapsedtime=0_SDK
  !> The time recorded by this timer given as a string.
  CHARACTER(LEN=MAXLEN_ETIME),PRIVATE :: time=''
  TYPE(StringType),PRIVATE :: time
  !> The units for the time given in @ref Times::TimerType::time
  !> "%time", also a string.
  CHARACTER(LEN=MAXLEN_TIME_UNITS),PRIVATE :: unit=''
  TYPE(StringType),PRIVATE :: unit
  !> indicates if the timer is high resolution
  LOGICAL(SBK),PRIVATE :: HiResTimer=.TRUE.
  !> Convert the processor clock count value to a time in seconds.
@@ -432,9 +418,10 @@ ENDFUNCTION getTimeReal
!> @returns time output argument, the elapsed time as a string
FUNCTION getTimeChar(this) RESULT(time)
  CLASS(TimerType),INTENT(INOUT) :: this
  CHARACTER(LEN=MAXLEN_TIME_STRING) :: time
  CHARACTER(LEN=:),ALLOCATABLE :: time

  CALL SetTimeAndUnits(this)
  ALLOCATE(CHARACTER(LEN=LEN_TRIM(this%time)+LEN_TRIM(this%unit)) :: time)
  time=TRIM(this%time)//TRIM(this%unit)
ENDFUNCTION getTimeChar
!
@@ -452,11 +439,13 @@ ENDFUNCTION getTimeChar
!> than or equal to 100 hours, the time will be formatted HHH:MM:SS.d.  Times of
!> 1000 hours and greater are not supported.
!>
IMPURE ELEMENTAL FUNCTION getTimeHHMMSS(this,tsec,force_hour) RESULT(hh_mm_ss)
FUNCTION getTimeHHMMSS(this,tsec,force_hour) RESULT(hh_mm_ss)
  CLASS(TimerType),INTENT(IN) :: this
  REAL(SRK),INTENT(IN),OPTIONAL :: tsec
  LOGICAL(SBK),INTENT(IN),OPTIONAL :: force_hour
  CHARACTER(LEN=MAXLEN_ETIME) :: hh_mm_ss
  TYPE(StringType) :: hh_mm_ss
  !
  CHARACTER(LEN=8) :: componentTimeString
  LOGICAL(SBK) :: force_hours
  INTEGER(SIK) :: it,hrs,mins
  REAL(SRK) :: t,secs
@@ -482,25 +471,30 @@ IMPURE ELEMENTAL FUNCTION getTimeHHMMSS(this,tsec,force_hour) RESULT(hh_mm_ss)
    mins=0_SIK
  ENDIF

  IF(hrs >= 100_SIK) THEN
    IF(secs < 9.95_SRK) THEN
      WRITE(hh_mm_ss,'(a,":",a,":0",f3.1)') str(hrs,3),str(mins,2),secs
  !Write seconds
  WRITE(componentTimeString,'(f8.2)') secs; componentTimeString=ADJUSTL(componentTimeString)
  IF(LEN_TRIM(componentTimeString) == 4) THEN
    hh_mm_ss='0'//TRIM(componentTimeString)
  ELSE
      WRITE(hh_mm_ss,'(a,":",a,":",f4.1)') str(hrs,3),str(mins,2),secs
    hh_mm_ss=TRIM(componentTimeString)
  ENDIF
  ELSEIF(hrs > 0_SIK .OR. force_hours) THEN
    IF(secs < 9.995_SRK) THEN
      WRITE(hh_mm_ss,'(a,":",a,":0",f4.2)') str(hrs,2),str(mins,2),secs
  !Write minutes
  WRITE(componentTimeString,'(i8)') mins; componentTimeString=ADJUSTL(componentTimeString)
  IF(LEN_TRIM(componentTimeString) == 1) THEN
    hh_mm_ss='0'//TRIM(componentTimeString)//':'//hh_mm_ss
  ELSE
      WRITE(hh_mm_ss,'(a,":",a,":",f5.2)') str(hrs,2),str(mins,2),secs
    hh_mm_ss=''//TRIM(componentTimeString)//':'//hh_mm_ss
  ENDIF
  !Write hours
  IF(hrs > 0) THEN
    WRITE(componentTimeString,'(i8)') hrs; componentTimeString=ADJUSTL(componentTimeString)
    IF(LEN_TRIM(componentTimeString) == 1) THEN
      hh_mm_ss='0'//TRIM(componentTimeString)//':'//hh_mm_ss
    ELSE
    IF(secs < 9.995_SRK) THEN
      WRITE(hh_mm_ss,'(a,":0",f4.2)') str(mins,2),secs
    ELSE
      WRITE(hh_mm_ss,'(a,":",f5.2)') str(mins,2),secs
      hh_mm_ss=TRIM(componentTimeString)//':'//hh_mm_ss
    ENDIF
  ENDIF

ENDFUNCTION getTimeHHMMSS
!
!-------------------------------------------------------------------------------
@@ -591,25 +585,23 @@ SUBROUTINE SetTimeAndUnits(this)
  REAL(SRK),PARAMETER :: sec2msec=1.e-3_SRK
  CLASS(TimerType),INTENT(INOUT) :: this
  REAL(SRK) :: t
  CHARACTER(LEN=MAXLEN_ETIME) :: tstring
  CHARACTER(LEN=MAXLEN_TIME_UNITS) :: tunit
  CHARACTER(LEN=16) :: tstring

  t=this%elapsedtime
  IF(0._SRK <= t .AND. t < sec2msec) THEN
    tunit=' microsec'
    this%unit=' microsec'
    WRITE(tstring,'(f9.3)') t/sec2micsec
  ELSEIF(sec2msec <= t .AND. t < 1._SRK) THEN
    tunit=' ms      '
    this%unit=' ms      '
    WRITE(tstring,'(f9.3)') t/sec2msec
  ELSEIF(1._SRK <= t .AND. t < 100000._SRK) THEN
    tunit=' s       '
    this%unit=' s       '
    WRITE(tstring,'(f9.3)') t
  ELSEIF(100000._SRK <= t) THEN
    tunit=' hh:mm:ss'
    tstring=getTimeHHMMSS(this)
    this%unit=' hh:mm:ss'
    tstring=CHAR(getTimeHHMMSS(this))
  ENDIF
  this%time=tstring
  this%unit=tunit
  this%time=ADJUSTL(TRIM(tstring))
ENDSUBROUTINE SetTimeAndUnits
!
!-------------------------------------------------------------------------------
@@ -945,11 +937,11 @@ ENDFUNCTION getTimeReal_Parent
!> than or equal to 100 hours, the time will be formatted HHH:MM:SS.d.  Times of
!> 1000 hours and greater are not supported.
!>
IMPURE ELEMENTAL FUNCTION getTimeHHMMSS_Parent(this,tsec,force_hour) RESULT(hh_mm_ss)
FUNCTION getTimeHHMMSS_Parent(this,tsec,force_hour) RESULT(hh_mm_ss)
  CLASS(ParentTimerType),INTENT(IN) :: this
  REAL(SRK),INTENT(IN),OPTIONAL :: tsec
  LOGICAL(SBK),INTENT(IN),OPTIONAL :: force_hour
  CHARACTER(LEN=MAXLEN_ETIME) :: hh_mm_ss
  TYPE(StringType) :: hh_mm_ss

  REQUIRE(ALLOCATED(this%timers))
  REQUIRE(SIZE(this%timers) > 0)
+45 −49
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@ INTEGER :: idum1,idum2,idum3,ioerr
CHARACTER(LEN=1) :: adum1,adum2
CHARACTER(LEN=5) :: adum3
CHARACTER(LEN=2) :: adum4
CHARACTER(LEN=MAXLEN_DATE_STRING) :: adate
CHARACTER(LEN=MAXLEN_CLOCK_STRING) :: aclock
TYPE(StringType) :: adate
TYPE(StringType) :: aclock
REAL(SRK) :: totalElapsed
!
!===============================================================================
@@ -41,35 +41,34 @@ ENDSUBROUTINE runTestTimes
!
!-------------------------------------------------------------------------------
SUBROUTINE testTimers()
  TYPE(StringType),ALLOCATABLE :: tokens(:)

  COMPONENT_TEST('getDate()')
  !
  !Test getDate()
  adate=getDate()
  idum1=0
  idum2=0
  idum3=0
  READ(adate,'(i2,a1,i2,a1,i4)',iostat=ioerr) idum1,adum1,idum2,adum2,idum3
  ASSERT_EQ(ioerr,0,'ioerr')
  tokens=adate%split('/')
  idum1=tokens(1)%stoi()
  idum2=tokens(2)%stoi()
  idum3=tokens(3)%stoi()
  ASSERT_GT(idum1,0,'month')
  ASSERT_LT(idum1,13,'month')
  ASSERT_GT(idum2,0,'day')
  ASSERT_LT(idum2,32,'day')
  ASSERT_GT(idum3,0,'year')
  ASSERT_EQ(adum1,adum2,'adum')
  ASSERT_EQ(adum1,'/','adum1')
  INFO(0) 'getDate() = '//getDate()
  ASSERT_EQ(getDate(),getDate(1),'getDate(1)')

  idum1=0
  idum2=0
  adate=getDate(2)
  READ(adate,'(a5,i2,a2,i4)',iostat=ioerr) adum3,idum1,adum4,idum2
  ASSERT_EQ(ioerr,0,'ioerr')
  tokens=adate%split(' ')
  idum1=tokens(2)%stoi(1,2)
  idum2=tokens(3)%stoi()
  ASSERT_GT(idum1,0,'day')
  ASSERT_LT(idum1,32,'day')
  ASSERT_GT(idum2,0,'year')
  ASSERT_EQ(adum4(1:1),',','month')
  ASSERT_EQ(tokens(1)%substr(LEN(tokens(1))),'.','month')

  !Test getTimeFromDate
  COMPONENT_TEST('getTimeFromDate')
@@ -90,16 +89,16 @@ SUBROUTINE testTimers()
  idum2=0
  idum3=0
  aclock=getClockTime()
  READ(aclock,'(i2,a1,i2,a1,i2)',iostat=ioerr) idum1,adum1,idum2,adum2,idum3
  ASSERT_EQ(ioerr,0,'ioerr')
  tokens=aclock%split(':')
  idum1=tokens(1)%stoi()
  idum2=tokens(2)%stoi()
  idum3=tokens(3)%stoi()
  ASSERT_GT(idum1,-1,'hour')
  ASSERT_LT(idum1,24,'hour')
  ASSERT_GT(idum2,-1,'minute')
  ASSERT_LT(idum2,60,'minute')
  ASSERT_GT(idum3,-1,'minute')
  ASSERT_LT(idum3,60,'minute')
  ASSERT_EQ(adum1,':',':')
  ASSERT_EQ(adum1,adum2,':')

  COMPONENT_TEST('HI-RES TIMER')
  ASSERT_EQ(LEN_TRIM(testTimer%getTimerName()),0,'%getTimerName()')
@@ -108,36 +107,36 @@ SUBROUTINE testTimers()
  testTimer%elapsedtime=0.0001_SRK
  ASSERT_EQ(testTimer%getTimeReal(),0.0001_SRK,'%getTimeReal()')
  ASSERT_EQ(testTimer%getTimeChar(),'100.000 microsec','%getTimeChar() (us)')
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'00:00.00   ','%getTimeHHMMSS() (us)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'00:00.00','%getTimeHHMMSS() (us)')
  testTimer%elapsedtime=0.999_SRK
  ASSERT_EQ(testTimer%getTimeChar(),'999.000 ms','%getTimeChar() (ms)')
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'00:01.00   ','%getTimeHHMMSS() (ms)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'00:01.00   ','%getTimeHHMMSS() (ms)')
  testTimer%elapsedtime=100.637_SRK
  ASSERT_EQ(testTimer%getTimeChar(),'100.637 s','%getTimeChar() (s)')
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'01:40.64   ','%getTimeHHMMSS() (s)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'01:40.64','%getTimeHHMMSS() (s)')
  testTimer%elapsedtime=100000.6_SRK
  ASSERT_EQ(testTimer%getTimeChar(),'27:46:40.60 hh:mm:ss','%getTimeChar() (hr)')
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'27:46:40.60','%getTimeHHMMSS() (hr)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'27:46:40.60','%getTimeHHMMSS() (hr)')
  testTimer%elapsedtime=3719.6_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'01:01:59.60','%getTimeHHMMSS() (round)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'01:01:59.60','%getTimeHHMMSS() (round)')
  testTimer%elapsedtime=33179.995099046479
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'09:13:00.00','%getTimeHHMMSS() (round)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'09:13:00.00','%getTimeHHMMSS() (round)')
  testTimer%elapsedtime=360000.0_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:00:00.0','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:00:00.00','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=360000.94_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:00:00.9','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:00:00.94','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=360000.96_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:00:01.0','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:00:00.96','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=360009.4_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:00:09.4','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:00:09.40','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=360009.94_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:00:09.9','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:00:09.94','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=360009.96_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:00:10.0','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:00:09.96','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=360069.96_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'100:01:10.0','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'100:01:09.96','%getTimeHHMMSS() (long)')
  testTimer%elapsedtime=363669.96_SRK
  ASSERT_EQ(testTimer%getTimeHHMMSS(),'101:01:10.0','%getTimeHHMMSS() (long)')
  ASSERT_EQ(CHAR(testTimer%getTimeHHMMSS()),'101:01:09.96','%getTimeHHMMSS() (long)')
  CALL testTimer%ResetTimer()
  ASSERT_EQ(LEN_TRIM(testTimer%getTimername()),0,'name')
  ASSERT_EQ(testTimer%elapsedtime,0._SRK,'elapsedtime')
@@ -164,42 +163,39 @@ SUBROUTINE testTimers()
  CALL testTimer%setTimerHiResMode(.FALSE.)
  ASSERT(.NOT.testTimer%getTimerHiResMode(),'%getTimerHiResMode()')
  adate=testTimer%getDate()
  idum1=0
  idum2=0
  idum3=0
  READ(adate,'(i2,a1,i2,a1,i4)',iostat=ioerr) idum1,adum1,idum2,adum2,idum3
  ASSERT_EQ(ioerr,0,'ioerr')
  tokens=adate%split('/')
  idum1=tokens(1)%stoi()
  idum2=tokens(2)%stoi()
  idum3=tokens(3)%stoi()
  ASSERT_GT(idum1,0,'month')
  ASSERT_LT(idum1,13,'month')
  ASSERT_GT(idum2,0,'day')
  ASSERT_LT(idum2,32,'day')
  ASSERT_GT(idum3,0,'year')
  ASSERT_EQ(adum1,adum2,'adum')
  ASSERT_EQ(adum1,'/','adum1')
  ASSERT_EQ(testTimer%getDate(),testTimer%getDate(1),'%getDate(1)')
  idum1=0
  idum2=0
  adate=testTimer%getDate(2)
  READ(adate,'(a5,i2,a2,i4)',iostat=ioerr) adum3,idum1,adum4,idum2
  ASSERT_EQ(ioerr,0,'ioerr')
  tokens=adate%split('/')
  idum1=tokens(1)%stoi()
  idum2=tokens(2)%stoi()
  idum3=tokens(3)%stoi()
  ASSERT_GT(idum1,0,'day')
  ASSERT_LT(idum1,32,'day')
  ASSERT(idum2 > 0,'year')
  ASSERT_EQ(adum4(1:1),',','month')
  idum1=0
  idum2=0
  idum3=0
  aclock=testTimer%getClockTime()
  READ(aclock,'(i2,a1,i2,a1,i2)',iostat=ioerr) idum1,adum1,idum2,adum2,idum3
  ASSERT_EQ(ioerr,0,'ioerr')
  tokens=aclock%split(':')
  idum1=tokens(1)%stoi()
  idum2=tokens(2)%stoi()
  idum3=tokens(3)%stoi()
  ASSERT_GT(idum1,-1,'hour')
  ASSERT_LT(idum1,24,'hour')
  ASSERT_GT(idum2,-1,'minute')
  ASSERT_LT(idum2,60,'minute')
  ASSERT_GT(idum3,-1,'minute')
  ASSERT_LT(idum3,60,'minute')
  ASSERT_EQ(adum1,':',':')
  ASSERT_EQ(adum1,adum2,':')
  testTimer%elapsedtime=0.0001_SRK

  COMPONENT_TEST('testTimer%getRemainingTime')