Skip to content

Commit 458d45e

Browse files
committed
vendor pathlib, add status=scratch
1 parent b00180f commit 458d45e

File tree

5 files changed

+109
-3
lines changed

5 files changed

+109
-3
lines changed

src/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
2+
if(WIN32)
3+
set(is_windows .true.)
4+
else()
5+
set(is_windows .false.)
6+
endif()
7+
configure_file(pathlib.in.f90 pathlib.f90)
8+
19
target_sources(nc4fortran PRIVATE
210
interface.f90
311
read.f90 reader.f90
412
write.f90 writer.f90
5-
string_utils.f90)
13+
string_utils.f90 ${CMAKE_CURRENT_BINARY_DIR}/pathlib.f90)

src/interface.f90

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module nc4fortran
1010
nf90_def_dim, nf90_put_att, nf90_def_var, nf90_get_var, nf90_put_var, nf90_float, nf90_double, nf90_int, nf90_int64, &
1111
nf90_inq_libvers
1212

13+
use pathlib, only : unlink, get_tempdir, is_absolute_path
1314
use string_utils, only : toLower, strip_trailing_null, truncate_string_null
1415

1516
implicit none (type, external)
@@ -28,6 +29,8 @@ module nc4fortran
2829
integer :: comp_lvl = 0 !< compression level (1-9) 0: disable compression
2930
logical :: verbose = .false.
3031
logical :: debug = .false.
32+
logical :: is_scratch = .false.
33+
!! will be auto-deleted on close
3134
character(80) :: libversion
3235

3336
contains
@@ -251,6 +254,10 @@ subroutine nc_initialize(self,filename,ierr, status,action,comp_lvl,verbose,debu
251254
end select
252255
case('new','replace')
253256
ier = nf90_create(self%filename, ior(NF90_CLOBBER, NF90_NETCDF4), self%ncid)
257+
case('scratch')
258+
ier = nf90_create(self%filename, ior(NF90_CLOBBER, NF90_NETCDF4), self%ncid)
259+
self%is_scratch = .true.
260+
if(.not.is_absolute_path(filename)) self%filename = get_tempdir() // '/' // filename
254261
case default
255262
write(stderr,*) 'Unsupported status -> '// lstatus
256263
error stop 128
@@ -279,6 +286,11 @@ subroutine nc_finalize(self, ierr)
279286
if (present(ierr)) return
280287
error stop
281288
endif
289+
290+
if(self%is_scratch) then
291+
if (unlink(self%filename)) write(stderr,*) 'WARNING: could not delete scratch file: ' // self%filename
292+
endif
293+
282294
end subroutine nc_finalize
283295

284296

src/meson.build

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
nc4_src = files('interface.f90',
1+
conf_data = configuration_data()
2+
3+
is_windows = os == 'windows' ? '.true.' : '.false.'
4+
5+
conf_data.set('is_windows', is_windows)
6+
pathlib_src = configure_file(
7+
input : 'pathlib.in.f90',
8+
output : 'pathlib.f90',
9+
configuration : conf_data)
10+
11+
nc4_src = files('interface.f90',
212
'read.f90', 'reader.f90',
313
'write.f90', 'writer.f90',
4-
'string_utils.f90')
14+
'string_utils.f90', meson.current_build_dir() / 'pathlib.f90')

src/pathlib.in.f90

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
module pathlib
2+
!! vendored from Michael Hirsch's Fortran pathlib
3+
4+
implicit none (type, external)
5+
6+
contains
7+
8+
function get_tempdir()
9+
10+
character(1024) :: argv
11+
integer :: L, i
12+
character(:), allocatable :: get_tempdir
13+
14+
call get_environment_variable("TMP", argv, L, i)
15+
if (L==0 .or. i/=0) call get_environment_variable("TEMP", argv, L, i)
16+
if (L==0 .or. i/=0) call get_environment_variable("TMPDIR", argv, L, i)
17+
if (L==0 .or. i/=0) argv = "/tmp"
18+
19+
get_tempdir = trim(argv)
20+
21+
end function get_tempdir
22+
23+
24+
pure logical function is_absolute_path(path)
25+
!! heuristic to determine absolute path
26+
27+
character(*), intent(in) :: path
28+
29+
is_absolute_path = .false.
30+
31+
if(@is_windows@) then
32+
if (lge(path(1:1), 'A') .and. lle(path(1:1), 'z') .and. path(2:2) == ':') is_absolute_path = .true.
33+
else
34+
if(path(1:1) == '/') is_absolute_path=.true.
35+
endif
36+
37+
end function
38+
39+
40+
logical function unlink(filename)
41+
!! deletes file in Fortran standard manner.
42+
character(*), intent(in) :: filename
43+
integer :: i, u
44+
45+
open(newunit=u, file=filename, iostat=i)
46+
close(u, status='delete', iostat=i)
47+
48+
inquire(file=filename, exist=unlink)
49+
50+
end function unlink
51+
52+
end module pathlib

src/tests/test_io.f90

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ program test_netcdf
2323
call test_exist(path)
2424
print *, 'OK: exist check'
2525

26+
call test_scratch(path)
27+
print *, 'OK: scratch'
28+
2629
call test_scalar(path)
2730
print *, 'OK: scalar'
2831

@@ -47,6 +50,27 @@ subroutine test_exist(path)
4750
end subroutine test_exist
4851

4952

53+
subroutine test_scratch(path)
54+
55+
character(*), intent(in) :: path
56+
type(netcdf_file) :: hf
57+
logical :: e
58+
59+
call hf%initialize('scratch.nc', status='scratch')
60+
print *, 'scratch: ', hf%filename
61+
call hf%finalize()
62+
63+
call hf%initialize(path // '/scalar.nc', status='scratch')
64+
print *, 'scratch: ', hf%filename
65+
call hf%write('here', 12)
66+
call hf%finalize()
67+
68+
inquire(file=path//'/scalar.nc', exist=e)
69+
if(e) error stop 'scratch file was not auto-deletect'
70+
71+
end subroutine test_scratch
72+
73+
5074
subroutine test_scalar(path)
5175

5276
character(*), intent(in) :: path

0 commit comments

Comments
 (0)