Skip to content

Commit 06afebe

Browse files
committed
loadtxt format update
Update read loop structure. Added optval formatting. Additional messages added to test cases to better understand which read type failed.
1 parent abba1f1 commit 06afebe

File tree

2 files changed

+86
-57
lines changed

2 files changed

+86
-57
lines changed

src/stdlib_io.fypp

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ contains
100100
!! A value of zero results in no lines to be read.
101101
!! The default value is -1.
102102
integer, intent(in), optional :: max_rows
103-
character(len=*), optional :: fmt
103+
character(len=*), intent(in), optional :: fmt
104+
character(len=:), allocatable :: fmt_
104105
!!
105106
!! Example
106107
!! -------
@@ -144,39 +145,52 @@ contains
144145
read(s, *)
145146
end do
146147

147-
do i = 1, max_rows_
148-
#:if 'real' in t1
149-
if ( present( fmt ) ) then
150-
if ( fmt == '*' ) then
151-
read (s,*) d(i, :)
152-
else
153-
read (s,fmt) d(i, :)
154-
endif
155-
else
156-
read (s,"(*"//FMT_REAL_${k1}$(1:len(FMT_REAL_${k1}$)-1)//",1x))") d(i, :)
157-
end if
158-
#:elif 'complex' in t1
159-
if ( present( fmt ) ) then
160-
if ( fmt == '*' ) then
161-
read (s,*) d(i, :)
162-
else
163-
read (s,fmt) d(i, :)
164-
endif
165-
else
166-
read(s, "(*"//FMT_COMPLEX_${k1}$(1:len(FMT_COMPLEX_${k1}$)-1)//",1x))") d(i, :)
167-
end if
168-
#:else
169-
if ( present( fmt ) ) then
170-
if ( fmt == '*' ) then
171-
read (s,*) d(i, :)
172-
else
173-
read (s,fmt) d(i, :)
174-
endif
175-
else
176-
read(s, *) d(i, :)
177-
end if
178-
#:endif
179-
end do
148+
#:if 'real' in t1
149+
! Default to format used for savetxt if fmt not specified.
150+
fmt_ = optval(fmt, "(*"//FMT_REAL_${k1}$(1:len(FMT_REAL_${k1}$)-1)//",1x))")
151+
152+
if ( fmt_ == '*' ) then
153+
! Use list directed read if user has specified fmt='*'
154+
do i = 1, max_rows_
155+
read (s,*) d(i, :)
156+
enddo
157+
else
158+
! Otherwise pass default or user specified fmt string.
159+
do i = 1, max_rows_
160+
read (s,fmt_) d(i, :)
161+
enddo
162+
endif
163+
#:elif 'complex' in t1
164+
! Default to format used for savetxt if fmt not specified.
165+
fmt_ = optval(fmt, "(*"//FMT_COMPLEX_${k1}$(1:len(FMT_COMPLEX_${k1}$)-1)//",1x))")
166+
if ( fmt_ == '*' ) then
167+
! Use list directed read if user has specified fmt='*'
168+
do i = 1, max_rows_
169+
read (s,*) d(i, :)
170+
enddo
171+
else
172+
! Otherwise pass default or user specified fmt string.
173+
do i = 1, max_rows_
174+
read (s,fmt_) d(i, :)
175+
enddo
176+
endif
177+
#:else
178+
! Default to list directed for integer
179+
fmt_ = optval(fmt, "*")
180+
! Use list directed read if user has specified fmt='*'
181+
if ( fmt_ == '*' ) then
182+
do i = 1, max_rows_
183+
read (s,*) d(i, :)
184+
enddo
185+
else
186+
! Otherwise pass default user specified fmt string.
187+
do i = 1, max_rows_
188+
read (s,fmt_) d(i, :)
189+
enddo
190+
endif
191+
192+
#:endif
193+
180194
close(s)
181195

182196
end subroutine loadtxt_${t1[0]}$${k1}$

test/io/test_loadtxt.f90

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ subroutine test_loadtxt_int32(error)
4343
input = int(harvest * 100)
4444
call savetxt('test_int32.txt', input)
4545
call loadtxt('test_int32.txt', expected)
46-
call check(error, all(input == expected))
46+
call check(error, all(input == expected),'Default list directed read failed')
47+
if (allocated(error)) return
4748
call loadtxt('test_int32.txt', expected, fmt='*')
48-
call check(error, all(input == expected))
49+
call check(error, all(input == expected),'User specified list directed read faile')
4950
if (allocated(error)) return
5051
end do
5152

@@ -67,11 +68,13 @@ subroutine test_loadtxt_sp(error)
6768
input = input - 0.5
6869
call savetxt('test_sp.txt', input)
6970
call loadtxt('test_sp.txt', expected)
70-
call check(error, all(input == expected))
71+
call check(error, all(input == expected),'Default format read failed')
72+
if (allocated(error)) return
7173
call loadtxt('test_sp.txt', expected, fmt='*')
72-
call check(error, all(input == expected))
74+
call check(error, all(input == expected),'List directed read failed')
75+
if (allocated(error)) return
7376
call loadtxt('test_sp.txt', expected, fmt="(*"//FMT_REAL_sp(1:len(FMT_REAL_sp)-1)//",1x))")
74-
call check(error, all(input == expected))
77+
call check(error, all(input == expected),'User specified format failed')
7578
if (allocated(error)) return
7679
end do
7780

@@ -93,11 +96,13 @@ subroutine test_loadtxt_sp_huge(error)
9396
input = (input - 0.5) * huge(input)
9497
call savetxt('test_sp_huge.txt', input)
9598
call loadtxt('test_sp_huge.txt', expected)
96-
call check(error, all(input == expected))
99+
call check(error, all(input == expected),'Default format read failed')
100+
if (allocated(error)) return
97101
call loadtxt('test_sp_huge.txt', expected, fmt='*')
98-
call check(error, all(input == expected))
102+
call check(error, all(input == expected),'List directed read failed')
103+
if (allocated(error)) return
99104
call loadtxt('test_sp_huge.txt', expected, fmt="(*"//FMT_REAL_sp(1:len(FMT_REAL_sp)-1)//",1x))")
100-
call check(error, all(input == expected))
105+
call check(error, all(input == expected),'User specified format failed')
101106
if (allocated(error)) return
102107
end do
103108

@@ -119,11 +124,13 @@ subroutine test_loadtxt_sp_tiny(error)
119124
input = (input - 0.5) * tiny(input)
120125
call savetxt('test_sp_tiny.txt', input)
121126
call loadtxt('test_sp_tiny.txt', expected)
122-
call check(error, all(input == expected))
127+
call check(error, all(input == expected),'Default format read failed')
128+
if (allocated(error)) return
123129
call loadtxt('test_sp_tiny.txt', expected, fmt='*')
124-
call check(error, all(input == expected))
130+
call check(error, all(input == expected),'List directed read failed')
131+
if (allocated(error)) return
125132
call loadtxt('test_sp_tiny.txt', expected, fmt="(*"//FMT_REAL_sp(1:len(FMT_REAL_sp)-1)//",1x))")
126-
call check(error, all(input == expected))
133+
call check(error, all(input == expected),'User specified format failed')
127134
if (allocated(error)) return
128135
end do
129136

@@ -145,11 +152,13 @@ subroutine test_loadtxt_dp(error)
145152
input = input - 0.5
146153
call savetxt('test_dp.txt', input)
147154
call loadtxt('test_dp.txt', expected)
148-
call check(error, all(input == expected))
155+
call check(error, all(input == expected),'Default format read failed')
156+
if (allocated(error)) return
149157
call loadtxt('test_dp.txt', expected, fmt='*')
150-
call check(error, all(input == expected))
158+
call check(error, all(input == expected),'List directed read failed')
159+
if (allocated(error)) return
151160
call loadtxt('test_dp.txt', expected, fmt="(*"//FMT_REAL_dp(1:len(FMT_REAL_dp)-1)//",1x))")
152-
call check(error, all(input == expected))
161+
call check(error, all(input == expected),'User specified format failed')
153162
if (allocated(error)) return
154163
end do
155164

@@ -171,11 +180,13 @@ subroutine test_loadtxt_dp_max_skip(error)
171180
input = input - 0.5
172181
call savetxt('test_dp_max_skip.txt', input)
173182
call loadtxt('test_dp_max_skip.txt', expected, skiprows=m, max_rows=n)
174-
call check(error, all(input(m+1:min(n+m,10),:) == expected))
183+
call check(error, all(input(m+1:min(n+m,10),:) == expected),'Default format read failed')
184+
if (allocated(error)) return
175185
call loadtxt('test_dp_max_skip.txt', expected, skiprows=m, max_rows=n, fmt='*')
176-
call check(error, all(input(m+1:min(n+m,10),:) == expected))
186+
call check(error, all(input(m+1:min(n+m,10),:) == expected),'List directed read failed')
187+
if (allocated(error)) return
177188
call loadtxt('test_dp_max_skip.txt', expected, fmt="(*"//FMT_REAL_dp(1:len(FMT_REAL_dp)-1)//",1x))")
178-
call check(error, all(input == expected))
189+
call check(error, all(input == expected),'User specified format failed')
179190
deallocate(expected)
180191
if (allocated(error)) return
181192
end do
@@ -199,11 +210,13 @@ subroutine test_loadtxt_dp_huge(error)
199210
input = (input - 0.5) * huge(input)
200211
call savetxt('test_dp_huge.txt', input)
201212
call loadtxt('test_dp_huge.txt', expected)
202-
call check(error, all(input == expected))
213+
call check(error, all(input == expected),'Default format read failed')
214+
if (allocated(error)) return
203215
call loadtxt('test_dp_huge.txt', expected, fmt='*')
204-
call check(error, all(input == expected))
216+
call check(error, all(input == expected),'List directed read failed')
217+
if (allocated(error)) return
205218
call loadtxt('test_dp_huge.txt', expected, fmt="(*"//FMT_REAL_dp(1:len(FMT_REAL_dp)-1)//",1x))")
206-
call check(error, all(input == expected))
219+
call check(error, all(input == expected),'User specified format failed')
207220
if (allocated(error)) return
208221
end do
209222

@@ -225,11 +238,13 @@ subroutine test_loadtxt_dp_tiny(error)
225238
input = (input - 0.5) * tiny(input)
226239
call savetxt('test_dp_tiny.txt', input)
227240
call loadtxt('test_dp_tiny.txt', expected)
228-
call check(error, all(input == expected))
241+
call check(error, all(input == expected),'Default format read failed')
242+
if (allocated(error)) return
229243
call loadtxt('test_dp_tiny.txt', expected, fmt='*')
230-
call check(error, all(input == expected))
244+
call check(error, all(input == expected),'List directed read failed')
245+
if (allocated(error)) return
231246
call loadtxt('test_dp_tiny.txt', expected, fmt="(*"//FMT_REAL_dp(1:len(FMT_REAL_dp)-1)//",1x))")
232-
call check(error, all(input == expected))
247+
call check(error, all(input == expected),'User specified format failed')
233248
if (allocated(error)) return
234249
end do
235250

0 commit comments

Comments
 (0)