So, following the suggestion in #201, let's start to discuss file system access API. In order to keep it focused, I'd suggest to start with the directory related operations first. My proposal:
open_directory(dirname, dirdesc, status): Opens a directory and returns a descriptor
type(dirdesc_t): Type containing the data of an opened directory
dirdesc_t%get_next(): Returns the next entry in the open directory or "" if
there are no more entries.
make_directory(dirname, parents, status): Makes a directory. If parents is .true.
also parent directories are created in case they do not exist yet.
remove_directory(dirname, content, status): Removes a directory. If content is
.true. also the directory content is removed (recursive delete).
change_directory(dirname, status): Changes to the given directory
get_working_dir() -> char(:), allocatable: Returns the current working directory.
is_dir(fname) -> logical: GIve .true. if fname is a directory.
A few notes:
The functionality above can be easily realized with a libc-interface (should work on all POSIX systems) and a bit of C-code. The big question is Windows, as I have no clue how to implement this functionality on WIndows.
As for error handling we could have a status argument. I'd argue for having a derived type type(status_t) containg the result of the operation (OK/Error) and a string with the error message in case of error. Whether the status argument should be optional or not is open for discussions.
We should survey Python, Rust, Julia, Matlab, etc. to see what API they use for this.
That looks like a good start :). I would like to add though:
dirdesc_t%get_first() - to get the first entry or to restart the search.
Should it be possible to specify a filter?
As for Windows, as that is the main OS I work with, I might give that a
try. While the function names differ, the functionality is largely the same.
Wrt the type of the various arguments such as dirname, these would be
simple strings? Then I suggest we use the forward slash as the directory
separator - it is accepted by all the major OSs and anything else can be
solved inside the implementation (notably the C bit).
Regards,
Arjen
Op do 16 jul. 2020 om 23:01 schreef Bálint Aradi notifications@github.com:
So, following the suggestion in #201
https://github.com/fortran-lang/stdlib/issues/201, let's start to
discuss file system access API. In order to keep it focused, I'd suggest to
start with the directory related operations first. My proposal:open_directory(dirname, dirdesc, status): Opens a directory and returns a
descriptortype(dirdesc_t): Type containing the data of an opened directory
dirdesc_t%get_next(): Returns the next entry in the open directory or ""
if
there are no more entries.make_directory(dirname, parents, status): Makes a directory. If parents
is .true.
also parent directories are created in case they do not exist yet.remove_directory(dirname, content, status): Removes a directory. If
content is
.true. also the directory content is removed (recursive delete).change_directory(dirname, status): Changes to the given directory
get_working_dir() -> char(:), allocatable: Returns the current working
directory.is_dir(fname) -> logical: GIve .true. if fname is a directory.
A few notes:
-
The functionality above can be easily realized with a libc-interface
(should work on all POSIX systems) and a bit of C-code. The big question is
Windows, as I have no clue how to implement this functionality on WIndows.
-As for error handling we could have a status argument. I'd argue for
having a derived type type(status_t) containg the result of the
operation (OK/Error) and a string with the error message in case of error.
Whether the status argument should be optional or not is open for
discussions.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220, or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR3UW3EBFNYXV2PRHWTR35TDHANCNFSM4O45YWQA
.
I think we should start with just the file path bit. See the Rust library, or the Haskell library.
Also, I don't particularly like the manual iterator design for open_directory. I'd much rather have a function get_contents(directory) -> type(file_path), allocatable :: paths(:). To me, open_directory and dirdesc%get_next() smacks of object-oriented assembly, in an attempt to satisfy primitive obsession.
I'd much rather have a function get_contents(directory) -> type(file_path), allocatable :: paths(:)
:+1: +1
Also, I see inconsistent naming, e.g. is_dir() and dirdesc_t, but change_directory and remove_directory. I like shorter names if they're common enough. In this case, I think they are. What do you think about:
change_directory -> chdirmake_directory -> mkdirremove_directory -> rmdirget_working_dir -> get_cwd or getcwdPython API reference: https://docs.python.org/3/library/os.html
I think we should start with just the file path bit. See the Rust library, or the Haskell library.
Should this be a separate thread? I think in this one we discuss only directory stuff, plus I think most directory operations here are independent of file path.
@everythingfunctional The interface here is basically a 1-1 mapping of the libc API, which also uses an iterator. (Works in Rust also similarly) But sure, if we have a decent file path type, we could have a convenience funtion on top of it which returns an allocatable array instead.
@milancurcic Although I'd be very happy to go with Pythons naming convention, it would not be consistent with Fortrans recent naming strategy (e.g. execute_command_line instead of exec or even command_argument_count). For sake of adoption, I'd probably prefer the style which is more Fortran like, even if I am not big fan of it. We could use _dir everywhere to make it more consistent and somehwat shorter, though: create_dir (or make_dir), remove_dir, change_dir, etc...
I see. In that case the question becomes one of philosophy for stdlib. Does stdlib provide lots of low level stuff for people to build abstractions on top of, or does it aim to provide useful abstractions and ergonomic APIs?
@everythingfunctional I agree, it is a philosophical question. And given the traditional reluctance of Fortran to delve into the depths of the underlying operating system, a higher level solution would indeed be probably more appropriate.
If we return an array, we have to decide on the element type. I see 3 different options:
I am working on Option 3 at the moment, but as discussed in #224, we should decide, whether and if yes how many derived types we want to impose on the users of stdlib...
@everythingfunctional regarding the goal of stdlib, I consider it both:
That way everybody gets what they want, both people who prefer more OO, as well as people who prefer more direct low level API.
In that case, I think the original proposal is perfectly suitable as low-level building blocks. It wouldn't be difficult to build a more ergonomic API using them.
Since this is related to #201, I want to explain the rational why I prefer to rely on standard types and no type bound procedures for low level operations:
In Fortran, one cannot chain function calls (and array access), so an object oriented approach will result in something like:
type(t_path) :: filename
filename = getcwd()
call filename%join('my_file.ext)
print*, filename%islink()
while the functional/procedural way gives:
print*, islink(join(getcwd(),'my_file.ext'))
I acknowledge that this is not the most elaborate example, but in generally I think that a procedural approach is often more natural for Fortran.
@MarDiehl I am a big fan of simple functions / subroutines also over object oriented approach. In general, we can have both to satisfy everybody.
@MarDiehl Yes, your reasoning is very convincing and indeed, that approach fits definitely better to Fortran.
But giving the suggested directory API above, which part would you propose to be change? The only type bound procedure we have so far is get_next(this) so far. As this changes the internal state of the directory, it must be implemented as a subroutine, so we have the choice between
call get_next(mydir, nextentry)
and
call mydir%get_next(nextentry)
I don't know, whether there is any esthetic difference between the two....
If you refer to the type(path) suggestion, I am with you, that we should rather use intrinsic types (e.g. allocatable chars here) whenever possible.
@milancurcic , @MarDiehl As for being "fortranic": Then getcwd() should be rather get_working_dir() or similar, as especially recently introduced Fortran functions handling the environment (e.g. execute_command_line, command_argument_count tend to be rather verbose than abbreviated. I am not saying, that we should be that verbose, but I'd propose to introduce names which are more consistent with the naming philosophy of the already existing language.
Actually, if you have a type-bound procedure, then you can use both forms
:). o it will be down to taste then.
Op do 30 jul. 2020 om 16:44 schreef Bálint Aradi notifications@github.com:
@MarDiehl https://github.com/MarDiehl Yes, your reasoning is very
convincing and indeed, that approach fits definitely better to Fortran.But giving the suggested directory API above, which part would you propose
to be change? The only type bound procedure we have so far is
get_next(this) so far. As this changes the internal state of the
directory, it must be implemented as a subroutine, so we have the choice
betweencall get_next(mydir, nextentry)
and
call mydir%get_next(nextentry)
I don't know, whether there is any esthetic difference between the two....
If you refer to the type(path) suggestion, I am with you, that we should
rather use intrinsic types (e.g. allocatable chars here) whenever possible.@milancurcic https://github.com/milancurcic , @MarDiehl
https://github.com/MarDiehl As for being "fortranic": Then getcwd()
should be rather get_working_dir() or similar, as especially recently
introduced Fortran functions handling the environment (e.g.
execute_command_line, command_argument_count tend to be rather verbose
than abbreviated. I am not saying, that we should be that verbose, but
I'd propose to introduce names which are more consistent with the naming
philosophy of the already existing language.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-666414532,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YRZ5RMFWDCVYSOZPLGDR6GBMRANCNFSM4O45YWQA
.
@aradi
what about an interface like the following:
function list_directory(path)
character(len=*), intent(in) :: path
character(len=:), allocatable, dimension(:) :: list_directory
...
end function list_directory
this would simply return a array of strings containing the file names, an optional argument could specify the search order (creation time, name). This is similar go https://docs.python.org/2/library/os.html#os.listdir, again with the drawback that Fortran has no list type and we need to use an array.
I don't think that works in Fortran, I think you have to use a derived type to have an array of strings, like I did here:
I don't think that works in Fortran, I think you have to use a derived type to have an array of strings, like I did here:
It works. You just need to figure out the maximum length among all strings and the number of strings:
allocate(character(len=max_len)::list_directory(N_files))
Implementing such a function is of course a little bit cumbersome, but the advantage of stdlib is that it has to be done only once.
Ah I see. Ok, that can be a possibility. A bit wasteful, but simpler, and perhaps even more performing than the allocatable in allocatable approach.
I use an interface similar to what is being described, and looking over the list, three more that I find I use extensively are
one for getting the current scratch directory by assuming it is set by $TEMPDIR, $TMP, $TEMP or /tmp; but it would be nice to get what opening a Fortran SCRATCH file is using; something to set what that directory is; and when getting a directory listing as a standard array if you also want to return the length, which can increase processing speed versus trim() and also lets you handle outliers like trailing spaces in the name (an alternative is adding a null character to the name like C). I happen to use the prefix system_ for just about anything that requires an ISO_C_BINDING and is calling a "standard" library; but have no problem with the names above, except that some of the simpler ones like chdir, mkdir, ... are often common extensions so you have the potential problem of referring to the extensions if you forget the USE statement, and/or confusion over which one is being called for those familiar with the extention.
For reference my names are:
833 get_tmp (3m_io) - [M_io] Return the name of the scratch directory(LICENSE:PD)
835 system_dir (3m_io) - [M_io] return filenames in a directory matching specified wildcard string(LICENSE:PD)
1018 system_getcwd (3m_system) - [M_system] call getcwd(3c) to get the pathname of the current working directory(LICENSE:PD)
1016 system_chdir (3m_system) - [M_system] call chdir(3c) from Fortran to change working directory(LICENSE:PD)
1019 system_mkdir (3m_system) - [M_system] call mkdir(3c) to create a new directory(LICENSE:PD)
1024 system_rewinddir (3m_system) - [M_system] call rewinddir(3c) to rewind directory stream(LICENSE:PD)
1031 system_isdir (3m_system) - [M_system] checks if argument is a directory path(LICENSE:PD)
1036 system_closedir (3m_system) - [M_system] close a directory stream by calling closedir(3c)(LICENSE:PD)
1043 system_opendir (3m_system) - [M_system] open directory stream by calling opendir(3c)(LICENSE:PD)
1047 system_readdir (3m_system) - [M_system] read a directory using readdir(3c)(LICENSE:PD)
PS: setting and querying where the scratch files go is not an issue for most programs, but can be a big issue due to performance and space issues when huge scratch files are requred in HPC appiications. I but some notes about that and some of the major portability problems concering scratch files on Blevin's Fortran WIKI page a long time ago.
@MarDiehl Yes, the allocated character array is as "fortranic" as only possible. :smile: Three remarks:
It is not that cumbersome to implement. The algorithm would have first to loop over all entries of a directory anyway (to find out how many there are) and then once more to put their names in the allocated array. In he first loop one can then also easily determine the max file name length.
Consumers would have to trim() the entries to find out the true file names. As long as the file names are just passed to intrinsic statements, like open, this is OK, as open automatically trims the passed character variable, but it may be still error prone and annoying if the user tries to manipulate the file name (e.g. checking whether it ends with a given suffix, or when an additional suffix should be added to the file name).
Should other file manipulation commands automatically trim character variables containing file names? It would be quite convenient (one would spare a lot of trim()s and 100% compatible with current Fortran. However it also would inherit consequence, that it is impossible to treat file names ending on whitespaces, or to be more precise, impossible to distinguish between file names differing only in the nr. of whitespaces at the end of their file names. (But, since we can not fix that problem in the existing open statement anyway, probably the best thing is to have a "consistently broken" implementation of the other features in stdlib anyway...)
@aradi:
1) True, it is actually not that bad. I do the same in the split function.
2) Yes, further manipulation would always require a trim. At least for all the os/os_path functions I would do that for all intent(in) strings
3) This is a important point I totally missed. The hack used for URL encoding (replace by + or %20) is quite ugly. I agree with you that we should simply document this behavior since we cannot change the behavior of trim/open anyways. Better we have a simple and easy to user function that works for 99% of the users than something complicated that handles corner cases but is hard to use for the vast majority. Spaces on the shell are anyways a nightmare and trailing spaces are even difficult for graphical file explorers.
I have picked up work on the Windows version again. While I made good
progress over the weekend, I am not there yet. The most important issue I
am currently facing is this:
The implementation stops via ERROR STOP when a function or routine
encounters an error. This prevents the user from taking corrective action.
It also prevents the program from ignoring the problem of course. Is this
what we want? I can imagine a sort of dual API, much like the OPEN
statement. If you do not provide an argument to store any error condition
in, then the ERROR STOP action is taken. Otherwise it is left to the
programmer to properly deal with the error. Something along these lines:
subroutine chdir(path, error)
character(len=*), intent(in) :: path
logical, intent(out), optional :: error
if ( present(error) ) then
error = .false.
endif
if(chdir_c(f_c_string(path)) /= 0_C_INT) then
if ( present(error) ) then
error = .true.
else
error stop 'chdir: cannot change directory'
endif
endif
The test program is currently also using the routine symlink. As on Windows
links have a very different purpose, the current implementation returns an
error and therefore fails. I have introduced a mechanism to check the
operating system and so we can avoid a call to symlink we know is going to
fail. But that only avoids the above issue.
Some other things worth mentioning:
Regards,
Arjen
Op vr 31 jul. 2020 om 13:17 schreef Martin Diehl notifications@github.com:
@aradi https://github.com/aradi:
- True, it is actually not that bad. I do the same in the split
function.- Yes, further manipulation would always require a trim. At least for
all the os/os_path functions I would do that for all intent(in) strings- This is a important point I totally missed. The hack used for URL
encoding (replace by + or %20) is quite ugly. I agree with you that we
should simply document this behavior since we cannot change the behavior of
trim/open anyways. Better we have a simple and easy to user function
that works for 99% of the users than something complicated that handles
corner cases but is hard to use for the vast majority. Spaces on the shell
are anyways a nightmare and trailing spaces are even difficult for
graphical file explorers.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-667070268,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR4W7F5UDOVL4EEJO7TR6KR6FANCNFSM4O45YWQA
.
Oh, and one thing I forgot: on Windows the usual character used to separate
directory names in a path is the backslash, not the forward slash. While a
forward slash is perfectly acceptable (in most cases anyway and certainly
in Fortran programs), I can imagine people will expect a "\" to work when
splitting up a path name.
Regards,
Arjen
Op ma 7 sep. 2020 om 11:10 schreef Arjen Markus arjen.markus895@gmail.com:
I have picked up work on the Windows version again. While I made good
progress over the weekend, I am not there yet. The most important issue I
am currently facing is this:
The implementation stops via ERROR STOP when a function or routine
encounters an error. This prevents the user from taking corrective action.
It also prevents the program from ignoring the problem of course. Is this
what we want? I can imagine a sort of dual API, much like the OPEN
statement. If you do not provide an argument to store any error condition
in, then the ERROR STOP action is taken. Otherwise it is left to the
programmer to properly deal with the error. Something along these lines:subroutine chdir(path, error)
character(len=*), intent(in) :: path logical, intent(out), optional :: error if ( present(error) ) then error = .false. endif if(chdir_c(f_c_string(path)) /= 0_C_INT) then if ( present(error) ) then error = .true. else error stop 'chdir: cannot change directory' endifendif
The test program is currently also using the routine symlink. As on
Windows links have a very different purpose, the current implementation
returns an error and therefore fails. I have introduced a mechanism to
check the operating system and so we can avoid a call to symlink we know is
going to fail. But that only avoids the above issue.Some other things worth mentioning:
- I found out why CMake was not creating the appropriate makefiles on
Windows (spaces in the path to the compiler, yes, those abominable spaces).
In fact the CMakeLists.txt file at the highest level can be made much
simpler. The result: it works on all three Windows platforms (plain
Windows, Cygwin and MinGW)- I do not think the test program should rely on the present of a Python
installation :). The use it currently makes of it is very limited and
easily done in Fortran.- It may be useful to know the type of OS, so that is now (in my copy of
the repository) caught via a bit of CMake manipulation.Regards,
Arjen
Op vr 31 jul. 2020 om 13:17 schreef Martin Diehl <[email protected]
:
@aradi https://github.com/aradi:
- True, it is actually not that bad. I do the same in the split
function.- Yes, further manipulation would always require a trim. At least
for all the os/os_path functions I would do that for all intent(in)
strings- This is a important point I totally missed. The hack used for URL
encoding (replace by + or %20) is quite ugly. I agree with you that
we should simply document this behavior since we cannot change the behavior
of trim/open anyways. Better we have a simple and easy to user
function that works for 99% of the users than something complicated that
handles corner cases but is hard to use for the vast majority. Spaces on
the shell are anyways a nightmare and trailing spaces are even difficult
for graphical file explorers.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-667070268,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR4W7F5UDOVL4EEJO7TR6KR6FANCNFSM4O45YWQA
.
@arjenmarkus sorry for the late response, I've been busy with other things.
1) error handling: I have a branch with an optional stat argument. If that is given, it's return value can be used for checking the success of a function. Otherwise, error stop is called if something goes wrong. This behavior is similar to the behavior of standard language featurs.
2) windows path handling: We can make set the parameter defining the path separator depending on the OS. That would leave the question if there should be a standardize function (i.e. all user input with / would be translated to \ on Windows). In python, there are actually two implementation to handle these subtle differences (posixpath/ntpath)
3) Is there a difference between "real windows" and MingGW regarding the expected behavior on Windows?
4) I will continue to work on the library on the weekend. Should we exchange ideas via skype or zoom then? I think that would be easier.
No problem, I have been busy too.
The question of distinguishing "real/plain Windows" from MinGW is not very
simple to answer. If you use the console it is rather unixy in behaviour,
but MinGW tries to be windowish. I guess we can refine this later, should
differences become relevant in the context of a Fortran program trying to
cooperate with the operating system.
As for exchanging ideas via Zoom or Skype, that would normally be quite
convenient, but I cannot plan ahead right now (unforeseen and unforeseeable
events in my family).
Regards,
Arjen
Op ma 7 sep. 2020 om 16:18 schreef Martin Diehl notifications@github.com:
@arjenmarkus https://github.com/arjenmarkus sorry for the late
response, I've been busy with other things.
- error handling: I have a branch with an optional stat argument. If
that is given, it's return value can be used for checking the success of a
function. Otherwise, error stop is called if something goes wrong.
This behavior is similar to the behavior of standard language featurs.- windows path handling: We can make set the parameter defining the
path separator depending on the OS. That would leave the question if there
should be a standardize function (i.e. all user input with / would be
translated to \ on Windows). In python, there are actually two
implementation to handle these subtle differences (posixpath/ntpath)- Is there a difference between "real windows" and MingGW regarding
the expected behavior on Windows?- I will continue to work on the library on the weekend. Should we
exchange ideas via skype or zoom then? I think that would be easier.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-688355276,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YRYJM7BHBK4SB6NVJVDSETTSZANCNFSM4O45YWQA
.
ok, then it's best if you contact me via email: m.[email protected] if you have time.
WIll do, asap - I should be able to find time, if nothing else as a
distraction.
Regards,
Arjen
Op di 8 sep. 2020 om 08:17 schreef Martin Diehl notifications@github.com:
ok, then it's best if you contact me via email: m.[email protected] if you
have time.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-688642510,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR32SPX7BXSVA63VBQ3SEXD6HANCNFSM4O45YWQA
.
I am really happy about the implementations by @MarDiehl ! You should come up with a Draft PR to discuss details there!
The status at this moment:
But I agree: it is definitely in a useable state.
@MarDiehl, what do you think? (Note: I need to consolidate and submit the
latest stuff :))
Op wo 7 okt. 2020 om 14:07 schreef Sebastian Müller <
[email protected]>:
I am really happy about the implementations by @MarDiehl
https://github.com/MarDiehl ! You should come up with a Draft PR to
discuss details there!—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-704890386,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR5XMWY7PBXNKARW4RDSJRKW3ANCNFSM4O45YWQA
.
@arjenmarkus Sorry for the late reply, I started a new appointment and simply ignored all emails that were not directly related to my old and new work. I'm now back at this
Ah, good to see you're back :). i have been busy getting the test program
to work on all platforms I have access to (and as it turns out, I have
access to five different platforms, not four, as MinGW and MSYS are related
but in some ways entirely different platforms).
Op wo 7 okt. 2020 om 14:45 schreef Martin Diehl notifications@github.com:
@arjenmarkus https://github.com/arjenmarkus Sorry for the late reply, I
started a new appointment and simply ignored all emails that were not
directly related to my old and new work. I'm now back at this—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-704910095,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR2YXIVA4C5ALFLFDSDSJRPE5ANCNFSM4O45YWQA
.
Hm, a slight but rather nasty problem occurred: the Intel Fortran version
on Windows now stops suddenly in the getsize function. It works fine in a
reduced program.
Op wo 7 okt. 2020 om 15:00 schreef Arjen Markus arjen.markus895@gmail.com:
Ah, good to see you're back :). i have been busy getting the test program
to work on all platforms I have access to (and as it turns out, I have
access to five different platforms, not four, as MinGW and MSYS are related
but in some ways entirely different platforms).Op wo 7 okt. 2020 om 14:45 schreef Martin Diehl <[email protected]
:
@arjenmarkus https://github.com/arjenmarkus Sorry for the late reply,
I started a new appointment and simply ignored all emails that were not
directly related to my old and new work. I'm now back at this—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-704910095,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR2YXIVA4C5ALFLFDSDSJRPE5ANCNFSM4O45YWQA
.
I have isolated the problem in a small test program - see the attachment.
It occurs with Intel Fortran 18 on both Windows and Linux. Since this
hinders the further development of this library, I am going to resort to
using a C function instead (like for the creation/modification/access times
for files).
Regards,
Arjen
Op wo 7 okt. 2020 om 21:16 schreef Arjen Markus arjen.markus895@gmail.com:
Hm, a slight but rather nasty problem occurred: the Intel Fortran version
on Windows now stops suddenly in the getsize function. It works fine in a
reduced program.Op wo 7 okt. 2020 om 15:00 schreef Arjen Markus [email protected]
:
Ah, good to see you're back :). i have been busy getting the test program
to work on all platforms I have access to (and as it turns out, I have
access to five different platforms, not four, as MinGW and MSYS are related
but in some ways entirely different platforms).Op wo 7 okt. 2020 om 14:45 schreef Martin Diehl <[email protected]
:
@arjenmarkus https://github.com/arjenmarkus Sorry for the late reply,
I started a new appointment and simply ignored all emails that were not
directly related to my old and new work. I'm now back at this—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-704910095,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR2YXIVA4C5ALFLFDSDSJRPE5ANCNFSM4O45YWQA
.
program stdlib_test
!use os_path
implicit none
integer :: unit
logical :: error
integer :: ierr
integer :: sz
character(len=:), allocatable, dimension(:) :: split_str
character(len=:), allocatable :: startdir
print*, "Start"
inquire( file = 'testtxt', size = sz, iostat = ierr )
print*, "Size: ", sz
print, "local_getsize('test.txt'): ", local_getsize('test.txt')
!print, "getsize('test.txt'): ", getsize('test.txt')
print*, "Done"
contains
function local_getsize(path)
!integer(int64) :: getsize
integer :: local_getsize
integer :: sz
character(len=*), intent(in) :: path
integer :: ierr
!write(*,*) '>>', path
call local_getsize_routine( path, sz, ierr )
!inquire( file = path, size = sz, iostat = ierr )
local_getsize = sz
if ( ierr /= 0 ) then
local_getsize = -1
endif
!write(*,*) '>>', getsize
end function local_getsize
subroutine local_getsize_routine( path, sz, ierr )
character(len=*), intent(in) :: path
integer, intent(out) :: sz
integer, intent(out) :: ierr
inquire( file = path, size = sz, iostat = ierr )
end subroutine local_getsize_routine
end program stdlib_test
Hi @arjenmarkus , I think the above code will work if you use inquire after opening the file:
subroutine local_getsize_routine( path, sz, ierr )
character(len=*), intent(in) :: path
integer, intent(out) :: sz
integer, intent(out) :: ierr
integer :: fh
open(newunit=fh, file = path, iostat = ierr )
if (ierr /=0 ) return
inquire( unit=fh, size = sz, iostat = ierr )
close(fh)
end subroutine local_getsize_routine
You're right - that does seem to do the trick. I have tested it on both
Windows and Linux.
The only drawback is that the program should have read access to the file
in that case, but the implementation is straightforward.
Op zo 11 okt. 2020 om 13:25 schreef Laurence Kedward <
[email protected]>:
Hi @arjenmarkus https://github.com/arjenmarkus , I think the above code
will work if you use inquire after opening the file:subroutine local_getsize_routine( path, sz, ierr )
character(len=*), intent(in) :: path
integer, intent(out) :: sz
integer, intent(out) :: ierr
integer :: fhopen(newunit=fh, file = path, iostat = ierr ) if (ierr /=0 ) return inquire( unit=fh, size = sz, iostat = ierr ) close(fh)end subroutine local_getsize_routine
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-706690003,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YR67MYLDQ5K5EJFU763SKGIZXANCNFSM4O45YWQA
.
could be also related to https://community.intel.com/t5/Intel-Fortran-Compiler/Reading-file-of-length-zero/m-p/1185659
Well, I will implement the workaround with comments to indicate the reason
for this. There is definitely something fishy wrt inquire(size).
Op zo 11 okt. 2020 om 17:20 schreef Martin Diehl notifications@github.com:
could be also related to
https://community.intel.com/t5/Intel-Fortran-Compiler/Reading-file-of-length-zero/m-p/1185659—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/fortran-lang/stdlib/issues/220#issuecomment-706720676,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAN6YRYSPV2VOPTUCLG5QOLSKHEMTANCNFSM4O45YWQA
.
Have an old file talking about six methods to do this depending on the vintage of the compiler. Was going to send it but I think most methods were mentioned (INQUIRE, ISO_C_BINDING, output of external command, open in append mode as a stream and get position-1, .... I have notes in there about a lot of compilers or systems not supporting multiple simultaneous opens on the file so I think your test should already have the file open to test for that; although the notes look like most of the notes are from 2008.
Most helpful comment
Since this is related to #201, I want to explain the rational why I prefer to rely on standard types and no type bound procedures for low level operations:
In Fortran, one cannot chain function calls (and array access), so an object oriented approach will result in something like:
while the functional/procedural way gives:
I acknowledge that this is not the most elaborate example, but in generally I think that a procedural approach is often more natural for Fortran.