Skip to content

Commit 13b78ef

Browse files
authored
Merge pull request #37 from zoziha/add_readline
Add readline
2 parents 84e4d5f + 54b5452 commit 13b78ef

File tree

5 files changed

+118
-0
lines changed

5 files changed

+118
-0
lines changed

fpm.toml

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ main = "test_io_file.f90"
4141
name = "io_color"
4242
source-dir = "test/io"
4343
main = "test_io_color.f90"
44+
[[test]]
45+
name = "io_read_line"
46+
source-dir = "test/io"
47+
main = "test_io_read_line.f90"
4448

4549
## [linalg] tests
4650
[[test]]

meta-src/forlab_io.fypp

+16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module forlab_io
1818
public :: disp
1919

2020
public :: progress_bar, progress_perc
21+
22+
public :: read_line, read_file
2123

2224
!> Version: experimental
2325
!>
@@ -187,6 +189,20 @@ module forlab_io
187189
end subroutine progress_perc_${k1}$
188190
#:endfor
189191
end interface progress_perc
192+
193+
interface
194+
module subroutine read_line(line, unit, iostat)
195+
character(:), allocatable, intent(out) :: line
196+
integer, intent(in), optional :: unit
197+
integer, intent(out), optional :: iostat
198+
end subroutine read_line
199+
module subroutine read_file(string, file, iostat, keep_newline)
200+
character(:), allocatable, intent(out) :: string
201+
character(*), intent(in) :: file
202+
integer, intent(out), optional :: iostat
203+
logical, intent(in), optional :: keep_newline
204+
end subroutine read_file
205+
end interface
190206

191207
contains
192208

src/forlab_io.f90

+16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module forlab_io
1818

1919
public :: progress_bar, progress_perc
2020

21+
public :: read_line, read_file
22+
2123
!> Version: experimental
2224
!>
2325
!> forlab file derived type.
@@ -637,6 +639,20 @@ module subroutine progress_perc_int64(iter, itermax, prefix)
637639
end subroutine progress_perc_int64
638640
end interface progress_perc
639641

642+
interface
643+
module subroutine read_line(line, unit, iostat)
644+
character(:), allocatable, intent(out) :: line
645+
integer, intent(in), optional :: unit
646+
integer, intent(out), optional :: iostat
647+
end subroutine read_line
648+
module subroutine read_file(string, file, iostat, keep_newline)
649+
character(:), allocatable, intent(out) :: string
650+
character(*), intent(in) :: file
651+
integer, intent(out), optional :: iostat
652+
logical, intent(in), optional :: keep_newline
653+
end subroutine read_file
654+
end interface
655+
640656
contains
641657

642658
!> Version: experimental

src/forlab_io_read_line.f90

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
submodule (forlab_io) forlab_io_read_line
2+
3+
use, intrinsic :: iso_fortran_env, only: stdin => input_unit
4+
implicit none
5+
character(*), parameter :: nl = new_line("\n")
6+
7+
contains
8+
9+
!> Read a line from the input unit.
10+
subroutine read_line(line, unit, iostat)
11+
12+
character(:), allocatable, intent(out) :: line
13+
integer, intent(in), optional :: unit
14+
integer, intent(out), optional :: iostat
15+
16+
integer :: unit_, iostat_
17+
character(len=512) :: line_
18+
character(len=512) :: msg
19+
20+
unit_ = optval(unit, stdin)
21+
22+
line = ""
23+
read(unit_, "(A512)", iostat=iostat_, iomsg=msg) line_
24+
if (present(iostat)) then
25+
iostat = iostat_
26+
if (iostat_ == 0) line = trim(line_)
27+
else
28+
if (iostat_ == 0) then
29+
line = trim(line_)
30+
else
31+
error stop msg
32+
end if
33+
end if
34+
35+
end subroutine read_line
36+
37+
!> Read ASCII file as a string.
38+
subroutine read_file(string, file, iostat, keep_newline)
39+
40+
character(:), allocatable, intent(out) :: string
41+
character(*), intent(in) :: file
42+
integer, intent(out), optional :: iostat
43+
logical, intent(in), optional :: keep_newline
44+
45+
integer :: iostat_, unit, count, i
46+
character(:), allocatable :: string_
47+
character(len=512) :: msg
48+
logical :: keep_newline_
49+
50+
keep_newline_ = optval(keep_newline, .true.)
51+
open(newunit=unit, file=file)
52+
53+
string = ""
54+
count = countlines(file)
55+
do i = 1, count
56+
call read_line(string_, unit, iostat_)
57+
if (keep_newline_) string_ = string_ // nl
58+
string = string//string_
59+
end do
60+
close(unit)
61+
62+
end subroutine read_file
63+
64+
end submodule forlab_io_read_line

test/io/test_io_read_line.f90

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
program main
2+
3+
use forlab_io, only: read_line, read_file
4+
implicit none
5+
integer :: unit
6+
character(:), allocatable :: line
7+
8+
open(newunit=unit, file="test/io/test_io_read_line.f90")
9+
call read_line(line, unit)
10+
print *, line, len(line)
11+
12+
call read_file(line, "test/io/test_io_read_line.f90")
13+
print *, line, len(line)
14+
15+
call read_file(line, "test/io/test_io_read_line.f90", keep_newline=.false.)
16+
print *, line, len(line)
17+
18+
end program main

0 commit comments

Comments
 (0)