[Oberon] System.Directory options

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Mon Oct 23 05:44:29 CEST 2017


See inline comments.

> If ch is "!" then we want to put it in pat[i+1], if not then
> since PROCEDURE List only compares with that value, any other one
> will do.  So that's why I suggested putting ch in in both cases.

You are of course right, but only for this particular implementation
of PROCEDURE System.List (which checks only that one value).

My original implementation (which clears the rest of the *full*
pattern array of 32 chars to 0X in order to *always* guarantee
that a “clean” pattern array is presented to System.List)

   ...
   WHILE ch > "!" DO pat[i] := ch; INC(i); Texts.Read(R, ch) END;
   pat[i] := 0X; INC(i);
   IF ch = "!" THEN pat[i] := "!"; INC(i) END ; (*directory option*)
   WHILE i < LEN(pat) DO pat[i] := 0X; INC(i) END ;
   ...

would work with ANY implementation of System.List - including one
that accepts other (or even multiple) options. See your next point.


> FWIW, I was also concerned about what would have to change if
> another option was added.


I have always lamented about the fact some Oberon commands use
a “non-standard” way (whatever that means in Oberon) of parsing
arguments - such as in System.Directory, where the “!” option must
come *immediately* after the pattern, i.e. with *no* space allowed.

This choice may have been motivated by the fact that the parameter
“!" is passed on to System.List *as part of the pattern itself*.

But it didn’t have to. Since List already uses a global variable 
for the pattern, it could equally well have used yet another global
variable ‘patOptions' to hold the options (patOptions could be a
SET for example). This would have kept the pattern itself clean
and separate from the options, and also have made the handling of
multiple options a trivial exercise.

But ok, if we accept the current status quo, the only way to have
multiple (single char) options would be to handle them explicitly:

e.g. in System.Directory:

   i := 0;
   WHILE (ch >= "A") & (ch <= "Z") OR (ch >= "a") & (ch <= "z”)  OR (ch = “.”) OR (ch = “*”) DO
     pat[i] := ch; INC(i); Texts.Read(R, ch)
   END;
   pat[i] := 0X; INC(i);
   WHILE ch > “ “ DO pat[i] := ch; INC(i); Texts.Read(R, ch) END ; (*directory options*)
   pat[i] := 0X;

e.g. in System.List:

   INC(j0); ch := pat[j0]
   WHILE ch # 0X DO (*options*)
     IF ch = "!" THEN (*option 1*)
       Kernel.GetSector(adr, hp);
       Texts.Write(W, 9X); Texts.WriteClock(W, hp.date);
       Texts.WriteInt(W, hp.aleng*FileDir.SectorSize + hp.bleng - FileDir.HeaderSize, 8) (*length*)
       (*Texts.WriteHex(W, adr)*)
     ELSIF ch = “+” THEN ... (*option 2*)
     ELSIF ch = “?” THEN ... (*option 3*)
     ELSIF ...
     END ;
     INC(j0)
   END

This is not recommended. It “fills" the pattern with the options
which then need to be handled separately in List.

It is easier and cleaner use a global variable for the options.

e.g. in System.Directory: INCL(patOptions, option)
e.g. in System.List: IF 1 IN patOptions THEN...

My two Groschen..

-AP
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20171023/6695c3ab/attachment.html>


More information about the Oberon mailing list