Skip to content

Commit bee64c5

Browse files
authored
Merge pull request #23 from certik/loadtxt
Implement loadtxt and savetxt
2 parents 9dfeec2 + 65301b9 commit bee64c5

16 files changed

+326
-18
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR)
2+
3+
enable_language(Fortran)
4+
5+
project(stdlib)
6+
7+
enable_testing()
8+
9+
add_subdirectory(src)

Makefile

Lines changed: 0 additions & 18 deletions
This file was deleted.

Makefile.manual

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Fortran stdlib Makefile
2+
3+
FC = gfortran
4+
FCFLAGS=-O0
5+
6+
.PHONY: all clean
7+
8+
all: stdlib tests
9+
10+
stdlib:
11+
$(MAKE) -f Makefile.manual FC=${FC} FCFLAGS=${FCFLAGS} --directory=src/lib
12+
13+
tests: stdlib
14+
$(MAKE) -f Makefile.manual FC=${FC} FCFLAGS=${FCFLAGS} --directory=src/tests
15+
16+
clean:
17+
$(MAKE) -f Makefile.manual clean --directory=src/lib
18+
$(MAKE) -f Makefile.manual clean --directory=src/tests

src/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
set(SRC
2+
stdlib_experimental_io.f90
3+
stdlib_experimental_error.f90
4+
)
5+
6+
add_library(fortran_stdlib ${SRC})
7+
8+
add_subdirectory(tests)
9+
10+
install(TARGETS fortran_stdlib
11+
RUNTIME DESTINATION bin
12+
ARCHIVE DESTINATION lib
13+
LIBRARY DESTINATION lib
14+
)
File renamed without changes.

src/stdlib_experimental_error.f90

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module stdlib_experimental_error
2+
implicit none
3+
private
4+
public :: assert, error_stop
5+
6+
contains
7+
8+
subroutine assert(condition)
9+
! If condition == .false., it aborts the program.
10+
!
11+
! Arguments
12+
! ---------
13+
!
14+
logical, intent(in) :: condition
15+
!
16+
! Example
17+
! -------
18+
!
19+
! call assert(a == 5)
20+
21+
if (.not. condition) call error_stop("Assert failed.")
22+
end subroutine
23+
24+
subroutine error_stop(msg)
25+
! Aborts the program with nonzero exit code
26+
!
27+
! The statement "stop msg" will return 0 exit code when compiled using
28+
! gfortran. error_stop() uses the statement "stop 1" which returns an exit code
29+
! 1 and a print statement to print the message.
30+
!
31+
! Example
32+
! -------
33+
!
34+
! call error_stop("Invalid argument")
35+
36+
character(len=*) :: msg ! Message to print on stdout
37+
print *, msg
38+
stop 1
39+
end subroutine
40+
41+
end module

src/stdlib_experimental_io.f90

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
module stdlib_experimental_io
2+
use iso_fortran_env, only: sp=>real32, dp=>real64
3+
implicit none
4+
private
5+
public :: loadtxt, savetxt
6+
7+
interface loadtxt
8+
module procedure sloadtxt
9+
module procedure dloadtxt
10+
end interface
11+
12+
interface savetxt
13+
module procedure ssavetxt
14+
module procedure dsavetxt
15+
end interface
16+
17+
contains
18+
19+
subroutine sloadtxt(filename, d)
20+
character(len=*), intent(in) :: filename
21+
real(sp), allocatable, intent(out) :: d(:,:)
22+
real(dp), allocatable :: tmp(:,:)
23+
call dloadtxt(filename, tmp)
24+
allocate(d(size(tmp,1),size(tmp,2)))
25+
d = real(tmp,sp)
26+
end subroutine
27+
28+
subroutine dloadtxt(filename, d)
29+
! Loads a 2D array from a text file.
30+
!
31+
! Arguments
32+
! ---------
33+
!
34+
! Filename to load the array from
35+
character(len=*), intent(in) :: filename
36+
! The array 'd' will be automatically allocated with the correct dimensions
37+
real(dp), allocatable, intent(out) :: d(:,:)
38+
!
39+
! Example
40+
! -------
41+
!
42+
! real(dp), allocatable :: data(:, :)
43+
! call loadtxt("log.txt", data) ! 'data' will be automatically allocated
44+
!
45+
! Where 'log.txt' contains for example::
46+
!
47+
! 1 2 3
48+
! 2 4 6
49+
! 8 9 10
50+
! 11 12 13
51+
! ...
52+
!
53+
character :: c
54+
integer :: s, ncol, nrow, ios, i
55+
logical :: lastwhite
56+
real(dp) :: r
57+
58+
open(newunit=s, file=filename, status="old")
59+
60+
! determine number of columns
61+
ncol = 0
62+
lastwhite = .true.
63+
do
64+
read(s, '(a)', advance='no', iostat=ios) c
65+
if (ios /= 0) exit
66+
if (lastwhite .and. .not. whitechar(c)) ncol = ncol + 1
67+
lastwhite = whitechar(c)
68+
end do
69+
70+
rewind(s)
71+
72+
! determine number or rows
73+
nrow = 0
74+
do
75+
read(s, *, iostat=ios) r
76+
if (ios /= 0) exit
77+
nrow = nrow + 1
78+
end do
79+
80+
rewind(s)
81+
82+
allocate(d(nrow, ncol))
83+
do i = 1, nrow
84+
read(s, *) d(i, :)
85+
end do
86+
close(s)
87+
end subroutine
88+
89+
subroutine ssavetxt(filename, d)
90+
character(len=*), intent(in) :: filename
91+
real(sp), intent(in) :: d(:,:)
92+
call dsavetxt(filename, real(d,dp))
93+
end subroutine
94+
95+
subroutine dsavetxt(filename, d)
96+
! Saves a 2D array into a textfile.
97+
!
98+
! Arguments
99+
! ---------
100+
!
101+
character(len=*), intent(in) :: filename ! File to save the array to
102+
real(dp), intent(in) :: d(:,:) ! The 2D array to save
103+
!
104+
! Example
105+
! -------
106+
!
107+
! real(dp) :: data(3, 2)
108+
! call savetxt("log.txt", data)
109+
110+
integer :: s, i
111+
open(newunit=s, file=filename, status="replace")
112+
do i = 1, size(d, 1)
113+
write(s, *) d(i, :)
114+
end do
115+
close(s)
116+
end subroutine
117+
118+
119+
logical function whitechar(char) ! white character
120+
! returns .true. if char is space (32) or tab (9), .false. otherwise
121+
character, intent(in) :: char
122+
if (iachar(char) == 32 .or. iachar(char) == 9) then
123+
whitechar = .true.
124+
else
125+
whitechar = .false.
126+
end if
127+
end function
128+
129+
end module

src/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(loadtxt)
File renamed without changes.

src/tests/loadtxt/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
include_directories(${PROJECT_BINARY_DIR}/src)
2+
3+
project(loadtxt)
4+
5+
add_executable(test_loadtxt test_loadtxt.f90)
6+
target_link_libraries(test_loadtxt fortran_stdlib)
7+
8+
add_executable(test_savetxt test_savetxt.f90)
9+
target_link_libraries(test_savetxt fortran_stdlib)
10+
11+
add_test(test_loadtxt ${PROJECT_BINARY_DIR}/test_loadtxt)
12+
add_test(test_savetxt ${PROJECT_BINARY_DIR}/test_savetxt)

0 commit comments

Comments
 (0)