[fpc-devel] Publish some of FPC's internal cross-platform functionality

Anton Shepelev anton.txt at gmail.com
Mon Mar 11 22:09:05 CET 2019


Sven Barth to Anton Shepelev:

> > Writers of drivers for this Pascal-style I/O interface
> > should have the ability to convert OS-specific error
> > codes into InOurRes values, which are not even
> > documented at:
> >
> >    https://www.freepascal.org/docs-html/rtl/system/inoutres.html
>
> You're not supposed to use InOutRes directly to read it
> (that should probably be added to its documentation) , but
> instead IOResult needs to be used.

But I am talking about writing to InOutRes in order to
indicate an error condition from one of the TextRec
operations, because FreePascal ignores the return value of
those functions.

> > Notice also that FreePascal's TextRec handling is
> > incompatible with that of Delphi.  The TextRec
> > operations OpenFunc, InOutFunc, FlushFunc, and CloseFunc
> > return a longint, which Delphi interprets as the result
> > code but FreePascal ignores.  Therefore, I must set
> > InOutRes in FreePascal and return the error in Delphi.
>
> Now *that* is something that can and probably also should
> be talked about.

OK.  system.inc defines FileFunc as a procedure without a
return value:

   FileFunc = Procedure(var t : TextRec);

whereas streamio.pp defines the same operations as functions
returning longint, e.g.:

   Function StreamRead(var F: TTextRec) : longint;

and reports errors through the return value, which is
ignored in text.inc .  Not so in Delphi, where the internal
mechanism forwards the return value to IOResult, relieving
the driver writer of setting it manually.

In addition to system.inc and text.inc, a patch will modify
all platform-specfic files that implement the TextRec
operations and set InOutRes.  Many of them already use the
return value for the size of data read or written, but one
could use negative values to encode errors.  text.inc would
then:

   procedure FileReadFunc( var t:TextRec ): LongInt;
   var fres: LongInt;
   begin
      fres := do_read( f.Handle, f.Bufptr, f.BufSize );
      if fres < 0 then { fres has a negative IOResult value. }
      begin
         result := -fres; exit;
      end;
      result   := 0; { Success }
      t.BufEnd := fres;
      t.BufPos := 0;
   end;

and will check the return value of every TextRec operation.

-- 
Please, do not forward replies to my e-mail.




More information about the fpc-devel mailing list