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
......@@ -54,6 +54,7 @@ USE ISO_FORTRAN_ENV
USE IntrType
USE ExceptionHandler
USE Times
USE Strings
USE IO_Strings
USE FileType_Fortran
IMPLICIT NONE
......
......@@ -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
ELSE
WRITE(hh_mm_ss,'(a,":",a,":",f4.1)') str(hrs,3),str(mins,2),secs
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
ELSE
WRITE(hh_mm_ss,'(a,":",a,":",f5.2)') str(hrs,2),str(mins,2),secs
ENDIF
!Write seconds
WRITE(componentTimeString,'(f8.2)') secs; componentTimeString=ADJUSTL(componentTimeString)
IF(LEN_TRIM(componentTimeString) == 4) THEN
hh_mm_ss='0'//TRIM(componentTimeString)
ELSE
hh_mm_ss=TRIM(componentTimeString)
ENDIF
!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
IF(secs < 9.995_SRK) THEN
WRITE(hh_mm_ss,'(a,":0",f4.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
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)
......
......@@ -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()')
......@@ -107,41 +106,41 @@ SUBROUTINE testTimers()
ASSERT_EQ(TRIM(testTimer%getTimerName()),'myName','%setTimerName()')
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(testTimer%getTimeChar(),'100.000 microsec','%getTimeChar() (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(testTimer%getTimeChar(),'999.000 ms','%getTimeChar() (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(testTimer%getTimeChar(),'100.637 s','%getTimeChar() (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')
ASSERT_EQ(testTimer%getTimeChar(),' 0.000 microsec','time char')
ASSERT_EQ(testTimer%getTimeChar(),'0.000 microsec','time char')
CALL testTimer%tic()
CALL sleep(1)
CALL testTimer%toc()
......@@ -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')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment