 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Dec 15, 2009 1:14 pm Post subject: Query about FEXISTS@ |
|
|
I'm working on some code I haven't looked at for a while, which uses the Salford function FEXISTS@. It seems (to me) to be behaving somewhat differently to the way it is documented. The problem rang a bell so I searched the forum, and the one reference I can find to this function is here:
http://forums.silverfrost.com/viewtopic.php?t=864
although the focus in this topic is split between apparent problems with both FEXISTS@ and OPEN, and the questions never got resolved.
So, according to the documentation:
"FEXISTS@ returns a logical value which is .TRUE. if the name supplied in PATH is that of a file which does exist, or is a wildcard which matches one file only. It returns .FALSE. if such a file does not exist, or if an error occurs in which case ERROR_CODE returns a non-zero system error code."
My concern is with the case where a file does not exist, when FEXISTS@ returns FALSE (as it should) and an error code of 2 (as I believe it should not). I believe that if a file does not exist, the returns should be FALSE and 0. FALSE and non-zero should be returned only if something goes wrong.
Does something here need to be rectified?
Andy |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Tue Dec 15, 2009 1:24 pm Post subject: |
|
|
I understand your logic but users may already depend on this implementation where the error code provides information about the reason for the failure.
The best I could do would be to provide another function that is implemented in the way you prefer. |
|
Back to top |
|
 |
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Dec 15, 2009 3:18 pm Post subject: |
|
|
I'm not sure you do understand my logic, then . There is nothing wrong with using the error code to provide information about the reason for the failure, if there is a failure. My concern is that if the file simply does not exist, there is no failure - so the error code should reflect that, with a value of zero. Currently, when a file does not exist, the function is behaving as if an abnormal condition occurred, with the error code of 2 conveying more information about what that abnormal condition was.
It may be that a file not existing is defined as an abnormal condition, flagged by an error code of 2 - in which case it is only the documentation that needs to be changed, because there is no way to get a return value of FALSE and an error code of 0. The documentation doesn't actually state that FALSE/0 is returned if a file does not exist, but I think it is implied by a misleading comma:
"It returns .FALSE. if such a file does not exist, or if an error occurs in which case ERROR_CODE returns a non-zero system error code."
Implication: it returns FALSE in two circumstances, in the latter of which a non-zero error code is returned (implying that a zero error code is returned in the former circumstance). As opposed to:
"It returns .FALSE. if such a file does not exist or if an error occurs, in which case ERROR_CODE returns a non-zero system error code."
Implication: a return value of FALSE is always coupled with a non-zero error code. Which is what seems to happen.
It may be my inferencing that is faulty rather than the documentation's implication
Andy |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Tue Dec 15, 2009 4:56 pm Post subject: |
|
|
I still reckon that I understand your logic. The fact that a file does not exist is not an error condition - the function has succeeded in its purpose.
Never-the-less the function has been written in this way and all I can do is change the documentation if it is misleading. I do not want to change the way the function behaves unless it is absolutely necessary. Someone, somewhere may have used this odd behaviour to advantage. |
|
Back to top |
|
 |
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Dec 15, 2009 5:28 pm Post subject: Re: |
|
|
PaulLaidler wrote: | I still reckon that I understand your logic. The fact that a file does not exist is not an error condition - the function has succeeded in its purpose. |
Well, we agree on this! But I think we always did.
PaulLaidler wrote: | Never-the-less the function has been written in this way and all I can do is change the documentation if it is misleading. I do not want to change the way the function behaves unless it is absolutely necessary. Someone, somewhere may have used this odd behaviour to advantage. |
I agree again; I guess I must not have originally expressed myself too clearly. I understand that modifying the interface of a runtime routine is a last resort. I think the smallest of changes in the documentation is all that is required, as per my previous post. |
|
Back to top |
|
 |
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Thu May 12, 2011 11:27 am Post subject: |
|
|
Busy day on the forums today! Nothing like resurrecting old code to open up new cans of old worms. Now I'm tripping up again over another old issue.
This function FEXISTS@ appears to have changed its behaviour notwithstanding Paul's stating he was not going to. And unfortunately it has not changed in a way to bring it into line with its documented behaviour.
I am, as I was before, using it to check the existence of a path. According to the documentation, it should return TRUE if the path exists, FALSE and an error code of 0 if the path does not exist, and FALSE and an error code not 0 if "an error occurs".
Last time I posted about this, it was returning FALSE and a non-zero error code (2) if the path did not exist. I coded around this.
Now I am running the same old code and it is failing because my code-around is broken. The function now returns FALSE and an error code of 3 instead of 2 if the path does not exist.
So it seems the function got changed anyway, and broke my code. Quite ironic, since the stated reason for not changing it was lest it should break someone else's. Maybe now would be a good time to change it again so it finally behaves in line with the documentation (sigh). |
|
Back to top |
|
 |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: D�sseldorf, Germany
|
Posted: Thu May 12, 2011 1:29 pm Post subject: |
|
|
sparge, just a question because it is interesting for me: Why do you use FEXISTS@ and not the standard Fortran function inquire? What are the differences between both functions?
Regards - Wilfried |
|
Back to top |
|
 |
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Thu May 12, 2011 1:38 pm Post subject: Re: |
|
|
Wilfried Linder wrote: | sparge, just a question because it is interesting for me: Why do you use FEXISTS@ and not the standard Fortran function inquire? What are the differences between both functions? |
Hi Wilfried,
Good question! I have never made much use of INQUIRE, for some reason. I just refreshed my memory. It has an encyclopedia of key words, some of which are mutually exclusive, and I would be surprised if correct syntax was checked for at compile time. Maybe that's one reason why? (This particular use of mine dates back many years). Also, if I understand correctly, INQUIRE can be used for files but not paths. Maybe Salford wrote functions like FEXISTS@ for reasons like this?
Andy |
|
Back to top |
|
 |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: D�sseldorf, Germany
|
Posted: Thu May 12, 2011 1:58 pm Post subject: |
|
|
Hi Andy, you're right. I just have tested inquire and it really only works for files (like I'm using it) but not for paths.
Thanks and regards - Wilfried |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Thu May 12, 2011 6:20 pm Post subject: |
|
|
I think that INQUIRE has to work for files in systems that don't conform to the drive:\directory\subdirectory etc organisation, so the definition does not include that aspect. Moreover, INQUIRE looks at the Fortran qualities of a file as well as whether it exists or not.
I dug out my FTN77 manuals, and they don't have FEXISTS@ detailed, so it is a more recent innovation than 1994! They do have MKDIR@ (which is a useful thing to remember), but not RMDIR@ (I made that up in FTN style from the DOS command). There are a bunch of other rather useful subroutines such as SET_FILE_DATE_TIME_STAMP@, RENAME@, ERASE@, SET_FILE_ATTRIBUTE@, ATTACH@, CURDIR@. I wondered if you would find DIRENT@ or FILES@ of some use? Their error codes are DOS error codes. In my experience, many of the Salford FTN77 functions still work, and with the FTN77 library manual online, can be relatively easily followed up.
In this search I was rather amused by the routines READFA@ and WRITEFA@, which I suspect are the file equivalents of the "invisible box".
Isn't it wise to take Paul up on his 18-month old offer to produce the appropriate directory-testing routine? May I suggest DirEXISTS@ or PathEXISTS@ might be good names? One of its tasks could be to check that the path would be acceptable to GET_FILTERED_FILE@ and routines of that ilk.
Eddie |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri May 13, 2011 2:27 am Post subject: |
|
|
Would it be worth writing a routine, using FILES@, to return the number of files in a directory path ?
It would be interesting to see the error return for a path that does not exist, as I think a path that would exist would return at least 2 files; '..' and '.'
Say Integer*4 Function Count_Files_in_Path (path)
returning num-2 if exists and -1 if does not exist.
FILES@ does require a bit of temporary memory to run, especially if there are a lot of files (20,000 is not uncommon, eg in temporary internet files)
John |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Fri May 13, 2011 6:42 am Post subject: |
|
|
I have added this to my list of things to do.
I plan to have something for you before the next release. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri May 13, 2011 7:29 am Post subject: |
|
|
Andy,
I'd recomend that you consider the options available and write a routine to detect if a path exists. The options considered include to use:
1) Fortran INQUIRE
2) Get a list of files in path using $FILES@ ( there should be 2 entries in an empty directory)
3) FEXISTS@ may require a review of error states (does it return a 1,2 or 4-byte logical?)
4) DIRENT@, which I have never used
I'd expect that $FILES@ could produce a fairly robust solution.
There may be other issues with network path access and also new directory structures in Windows 7, both of which I have little experience with.
John |
|
Back to top |
|
 |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: D�sseldorf, Germany
|
Posted: Fri May 13, 2011 8:37 am Post subject: |
|
|
Just an idea, using John's advise:
Code: | WINAPP
OPTIONS(INTL)
PROGRAM TEST
IMPLICIT NONE
integer*2 max,nof,n(10)
integer*4 m(10)
character*120 path,afile(10)
path = 'c:\temp\*.*'
nof = 2
max = 10
afile = ' '
call files@(path,nof,max,afile,n,n,n,m)
print*,nof,' ',afile(1)
print*,nof,' ',afile(2)
path = 'c:\blablabla\*.*'
nof = 2
max = 10
afile = ' '
call files@(path,nof,max,afile,n,n,n,m)
print*,nof,' ',afile(1)
print*,nof,' ',afile(2)
end |
In the first case, the path exists, so the number of files (nof) is greater than zero. In the second case, the path didn't exists and nof = 0.
Another way to check whether a path exists may be to use the attach@ routine.
Regards - Wilfried |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri May 13, 2011 8:52 am Post subject: |
|
|
I cut up my directory sizing program and produced the following attempt.
It gives 2 entries for an empty directory and no entries for a non-existent directory.
It worked for a hidden directory, but would probably give 0 for a directory you do not have the rights to.
You need to check other unusual options.
I look for all files "*.*", but you could modify it for special files if the test is more relevant.
(I hope it is not too big - was too big !) Code: | ! Last change: JDC 20 Jul 2010 4:35 pm
integer n, path_exists
character cmnam@*256, this_path*256
external cmnam@, path_exists
intrinsic trim
!
!--- read the command line for the directory
!
this_path = cmnam@()
write (*,*) 'path : ', trim (this_path)
!
n = path_exists (this_path, 5000)
write (*,*) n,' file entries found in ',trim (this_path)
end
function combine_path_name (this_path, suffix)
!
character combine_path_name*320, this_path*(*), suffix*(*)
!
character full*320
integer*4 n1
intrinsic len_trim, trim
!
n1 = len_trim (this_path)
if (this_path(n1:n1) /= '\') then
full = trim (this_path) // '\' // trim (suffix)
else
full = trim (this_path) // trim (suffix)
end if
combine_path_name = full
return
!
end
subroutine get_file_type (file_name, attr, type_flag)
!
character file_name*(*)
integer*2 attr, type_flag(8)
integer*4 n, mask, nf
intrinsic iand, ishft
!
! Parse the attribute flag
!
! label(15 16384 Encrypted
! label(14 8192 Not Content Indexed
! label(13 4096 Off line
! label(12 'C' 2048 compression flag
! label(11 1024 Reparse Point
! label(10 512 Sparse_File
! label(9 ) = 'T' 256 Temporary or Normal flag ?
! label(8:8) = 'N' 128 Network flag Normal
! label(7:7) = 'Z' 64 unknown flag Device
! label(6:6) = 'a' 32 archive flag
! label(5:5) = 'd' 16 sub directory
! label(4:4) = 'V' 8 volume label
! label(3:3) = 's' 4 system file
! label(2:2) = 'h' 2 hidden file
! label(1:1) = 'r' 1 read only file
!
mask = attr
type_flag = 0
if (attr == 0) return
!
do n = 1,7
if (iand (mask,1) /= 0) then
type_flag(n) = 1
end if
mask = ishft (mask,-1)
end do
type_flag(8) = mask
!
! Set dummy entries to be omitted
if (type_flag(5)>0) then
n = len_trim (file_name)
nf = index (file_name, '\', .true.)
if (file_name(nf:n) .eq.'\.' ) type_flag(4) = 2
if (file_name(nf:n) .eq.'\..') type_flag(4) = 2
end if
!
return
end
|
|
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|