Files.dir.This never fails

User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Files.dir.This never fails

Post by DGDanforth »

The follow code never fails. The ASSERT is always true
no matter what the path is passed to This.

Code: Select all

loc := Files.dir.This("any string you try");
ASSERT(loc.res = 0);
To me that is a bug.
The documentation says
PROCEDURE (d: Directory) This (IN path: ARRAY OF CHAR): Locator
NEW, ABSTRACT
Returns a locator, given a path name in the host platform's syntax.
This may perform some validity checks, e.g., whether the syntax of the name is correct. Passing the empty string yields a default location (typically the BlackBox directory itself).

Post
result # NIL
result.res = 0
legal locator
result.res # 0
illegal locator
But notice it has result.res # 0 when the 'locator' is illegal and not when the 'path' is illegal.
Whenever is the locator illegal?

Motivation:
I had hoped to use Files.dir.This to determine if the folder associated with the path exists.
Because of the above behavior that does not work.

Goal: How do I determine if a folder exists?
-Doug
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Files.dir.This never fails

Post by Josef Templ »

as far as I know, a locator can also be used for creating new directories
in a later call of Register.
So it cannot be a requirement that a directory already exists
and a locator does not give any information about the existence of a directory.
A locator is basically an abstraction for a directory path.

I think it has been discussed before if it would give sense
to add a function that can be used for checking if a directory already exists.
The existence of a file can be checked with Old but a directory cannot.
Currently the only way to check the existence of a directory is to use LocList
on the parent directory.

- Josef
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Files.dir.This never fails

Post by Robert »

Josef Templ wrote:I think it has been discussed before if it would give sense
to add a function that can be used for checking if a directory already exists.
Yes - it has!
The existence of a file can be checked with Old but a directory cannot.
Currently the only way to check the existence of a directory is to use LocList
on the parent directory.
I have some interfaces to, and wrappers around, the Windows DLL "shlwapi" which solves these problems for me. I'll post them this evening if anyone is interested.

I believe some BlackBox code includes things like "IF loc = NIL ..." so as well as missing / wanted functionality I suspect there are also bugs in this area.
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Files.dir.This never fails

Post by DGDanforth »

Josef Templ wrote:as far as I know, a locator can also be used for creating new directories
in a later call of Register.
So it cannot be a requirement that a directory already exists
and a locator does not give any information about the existence of a directory.
A locator is basically an abstraction for a directory path.

I think it has been discussed before if it would give sense
to add a function that can be used for checking if a directory already exists.
The existence of a file can be checked with Old but a directory cannot.
Currently the only way to check the existence of a directory is to use LocList
on the parent directory.

- Josef
Using LocList should work (I'll try it) but is inefficient when there are "holes" in the directory tree.
What I mean by that is when a device, say C:, has created a deep directory tree and one wishes to
back up that tree to say, F:, then scanning F: for the existence of the sub directories can consume
some time.
-Doug
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Files.dir.This never fails

Post by DGDanforth »

Robert wrote:I have some interfaces to, and wrappers around, the Windows DLL "shlwapi" which solves these problems for me. I'll post them this evening if anyone is interested.
I'm interested!
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Files.dir.This never fails

Post by Robert »

Robert wrote:I believe some BlackBox code includes things like "IF loc = NIL ..." so ... I suspect there are also bugs in this area.
Look at StdMenuTool.IncludeSub (for example).
This relies on Files.dir.This failing. Must be a bug ?
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Files.dir.This never fails

Post by Josef Templ »

Robert wrote:
Robert wrote:I believe some BlackBox code includes things like "IF loc = NIL ..." so ... I suspect there are also bugs in this area.
Look at StdMenuTool.IncludeSub (for example).
This relies on Files.dir.This failing. Must be a bug ?
Agree.
The check after Files.dir.This should be: IF loc.res # 0 THEN RETURN END
However, it will be hard to find a test case where it matters.

- Josef
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Files.dir.This never fails

Post by Robert »

Josef Templ wrote:Agree.
The check after Files.dir.This should be: IF loc.res # 0 THEN RETURN END
However, it will be hard to find a test case where it matters.
Do you mean it will be hard to find a test case here (StdMenuTool), or anywhere? This design pattern (IF loc.res # 0) is quite common, I only quoted StdMenuTool as an example.

And I think it matters because people (myself anyway) use the BlackBox code as an example of what to do in their own code.
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Files.dir.This never fails

Post by DGDanforth »

Dev/Mod/Markers.odc
loc := Files.dir.This("Dev"); IF loc = NIL THEN RETURN END;

Dev/Mod/Packer.odc
loc := Files.dir.This(l.path);
IF loc # NIL THEN
fi := Files.dir.FileList(loc);
WHILE (fi # NIL) & (Diff(l.name, fi.name, FALSE) # 0) DO fi := fi.next END
END;
IF (loc = NIL) OR (fi = NIL) THEN
IF l.path # "" THEN StdLog.String(l.path + "/") END;
...
Std/Mod/Api.odc
loc := Files.dir.This(sub);
IF loc # NIL THEN
...
loc := Files.dir.This("System"); ASSERT(loc # NIL, 100);
Std/Mod/Coder.odc
i := 0; ch := path[0]; loc := Files.dir.This("");
WHILE (ch # 0X) & (loc # NIL) DO
Std/Mod/Dialog.odc
loc := Files.dir.This(sub); file := NIL;
IF loc # NIL THEN
loc := Files.dir.This("System");
IF loc # NIL THEN loc := loc.This(cat) END
Std/Mod/MenuTool.odc
loc := Files.dir.This(sub); IF loc = NIL THEN RETURN END;
Xhtml/Mod/StdFileWriters.odc
loc := Files.dir.This(""); IF loc = NIL THEN RETURN END;

So, there are 7 modules out of 25 that use Files.dir.This that have questionable usage and
incorrect assumptions about what that procedure returns.
Has the return value changed from OberonF to BlackBox 1.7?
-Doug
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Files.dir.This never fails

Post by Josef Templ »

Robert wrote: Do you mean it will be hard to find a test case here (StdMenuTool), or anywhere? This design pattern (IF loc.res # 0) is quite common, I only quoted StdMenuTool as an example.
I mean that particular case in StdMenuTool.
It uses only existing and thereby valid subsystem names, as far as I see from the code.
The check is redundant.

But I agree that it is not a good template to copy from.

- Josef
Post Reply