Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2002-07

Source files involved in (text) file handling (Q & A)

4 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Tom Verhoeff

I am looking into the handling of text files within FreePascal programs. I have found that the text file type is defined in

fpc/rtl/inc/textrec.inc and text.inc via TextRec,
and system.inc (for def. of type FileFunc),
systemh.inc (for routine headers)

However, text.inc refers to routines named

Do_Open, Do_Read, Do_Write, DoClose, Do_IsDevice, Do_FilePos, Do_Seek

which work on file handles, and I cannot find their definitions.

It is also not clear to me which higher level file includes system.inc and text.inc (textrec.inc is included in system.inc).

Apologies! I did some more tracking and found that rtl/linux/ has syslinux.pp, which includes system.pp, which includes sysunixh.inc and sysunix.inc (located in rtl/unix/). Then sysunixh.inc includes systemh.inc, and and sysunix.inc includes system.inc and text.inc. Furthermore sysunix.inc has the definitions for Do_xxx under Low Level File Routines in terms of routines named sys_xxx define in rtl/linux/syscalls.inc. A rather contorted maze, if I may say so, :-). In summary:

    fpc/
      rtl/
        inc/
          textrec.inc  defines type TextRec
          text.inc     implements routines Assign, Reset, Rewrite, Close, etc.
                       on TextRec, using FileFunc, in terms of routines
                       Do_Open, Do_Read, Do_Write, Do_Close on handles
                       (Do_Open is exceptional and works on var f that
                       must have handle and mode as first two fields)
          systemh.inc  declares routines Assign, Reset, Rewrite, Close, etc.
                       on Text
          system.inc   defines type FileFunc = Procedure(var t: TextRec);
        linux/
          syscalls.inc implements Sys_Open, Sys_Read, Sys_Write, Sys_Close, etc.
          syslinux.pp  includes system.pp
          system.pp    includes rtl/unix/{sysunixh,sysunix}.inc
        unix/
          sysunixh.inc includes rtl/inc/systemh.inc
          sysunix.inc  includes rtl/{inc/{sytem,text},linux/syscalls}.inc,
                       implements Do_Open, Do_Read, Do_Write, Do_Close, etc.
                       in terms of Sys_xxxx
  (I had no interest in tracing the Windows branch.)

By the way, in the implementation for SeekEof (in text.inc), I read that the file position is NOT actually advanced, UNLESS the file is associated with a device. The implementation for SeekEoln always advances the file position. The documentation (ref.pdf) states that both SeekEof and SeekEoln advance the file position. An experiment shows that the implementation is right (small wonder :-).

Reason for my interest is that I wanted to know why FilePos and Seek are not implemented for text files. The answer seems to be that there is a problem if they are associated with devices, which are not seekable. I would like to have FilePos and Seek when the text files are not associated with a device, and that seems doable somehow. They could just return an error if the text file is not seekable. I would probably also be happy if SeekEoln would NOT advance the file position whenever possible (just like SeekEof).

I hope this message may still be useful in some archive.

Thanks for your attention,

Tom Verhoeff

Reply by email

Jonas Maebe
to Tom Verhoeff
Tom Verhoeff wrote
routines named sys_xxx define in rtl/linux/syscalls.inc. A rather contorted maze, if I may say so, :-).

It's mostly there to allow easy porting.

Show quoted text 5 lines
By the way, in the implementation for SeekEof (in text.inc), I read that the file position is NOT actually advanced, UNLESS the file is associated with a device. The implementation for SeekEoln always advances the file position. The documentation (ref.pdf) states that both SeekEof and SeekEoln advance the file position.

In the past this was true, but we got a bug report stating that the seekeof() behaviour was incompatible with TP, so I changed it. I didn't think of the fact that seekeoln() probably had the same problem. I'll have a look at it.

An experiment shows that the implementation is right (small wonder :-).

Michael, that's a job for you :)

Reason for my interest is that I wanted to know why FilePos and Seek are not implemented for text files. The answer seems to be that there is a problem if they are associated with devices, which are not seekable.

That's possible. We just copied the behaviour of TP in this regard, I don't know why Borland chose it that way.

Jonas

Reply by email

Pavel V. Ozerski
to Jonas Maebe

Hello all,
May be, my snapshot is slightly outdated but these problems may be not fixed yet. Therefore I would report about them. May be, some of these problems are already known.

1) variables absolute to procedural variables are not supported sometimes. Compiler finds an error only if this procedural variable uses no parameters (but can be a procedure or a function) or if Delphi- or TP-compatible compilation mode is used: "Error: absolute can only be associated with a var or const" and in second case additionally "Error: Wrong number of parameters specified" if variable has a parameter list, otherwise all is OK. That breaks BP/Delphi compatibility and creates some real problems for programming. Examples:

var
 x:function:longint;
 y:pointer absolute x;
begin
end.
{$mode Delphi}
var
 x:function(x:longint):longint;
 y:pointer absolute x;
begin
end.

2) How to access of address of procedural variable in TP- or Delphi-compatible mode? This sample works correctly after compilation by Delphi 6 but cannot be compiled by FPC compiler:

{$ifdef FPC}
{$mode Delphi}
{$endif}
{$APPTYPE CONSOLE}
var
 x:function(x:longint):longint;
 y:pointer absolute x;
 z,w,v:pointer;
begin
 z:=@@x;
 w:=addr(@x);
 v:=@(addr(x));
 writeln(longint(y),' ',longint(z),' ',longint(w),' ',longint(v));
end.

I explored compiler sources a little and found that a new token DOUBLEADDR @@ is introduced although it doesn't work now. But this sample demonstrates also that this way seems to be wrong, IMHO, because all combinations of @ and addr() are supported in Delphi here.

Sincerely, Pavel

Reply by email

Peter Vreman
to Pavel V. Ozerski
you wrote
Hello all, May be, my snapshot is slightly outdated but these problems may be not fixed yet. Therefore I would report about them. May be, some of these problems are already known.

Thanks, the problems were not known yet. I've added all 3 problems to the testsuite.

Peter

Reply by email