According to Kevin A. Foss:
While I'm on the topic of exploring the file functions, does anyone want to explain the function of the various Seek* functions in extended Pascal? The descriptions in the standard contain a lot of intelligible text and little in the way of examples.
I have the same problem.
I assumed that Seekread(file, n) would simply take me to the nth record in 'file,' -- which it does, but then it actually seems to stall the file pointer at n until you read two items. [...] I would have expected D D E F G H for output? Why does the file pointer stay at 3 for two consecutive reads? Is this a bug or am I misusing seekread()?
I consider this a bug in GPC, but in fact I am not sure either what the EP standard really means. Prospero's Extended Pascal compiler (PEP) rejects your code but it accepts the following:
Program Test ( Output );
Var Data: File [ 0..25 ] of Char; C: Char;
begin rewrite ( Data ); for C:= 'A' to 'Z' do write ( Data, C ); reset ( Data ); SeekRead ( Data, ord ( 'O' ) - ord ( 'A' ) ); read ( Data, C ); write ( C ); SeekRead ( Data, ord ( 'K' ) - ord ( 'A' ) ); read ( Data, C ); writeln ( C ); end.
(seekrd.pas)
To fix GPC so it produces 'OK' from this source, edit the file `rts/rts-random.c' and comment out the `if' statement after "Seek back to the place ..." in `_p_seekread()' and in `_p_seekupdate()'.
(* BTW, EP experts, if I write `Program Test ( Output, Data );', the program does *not* ask me for a file name for `Data' when compiled with PEP. It works anyway, but I do not detect the data file on my hard disk afterwards. What is the legal way to produce an external file in EP? *)
(* sqr ( BTW ), UCSD/BP's `Seek' is now in GPC, too. *)
(* BTW pow 3, I see it's time for the next beta ... *)
Also isn't the typechecking of seekread a little harsh to not allow: [...] reset(inputfile, 'data'); [...] when it does allow: [...] index : integer = 3; [...] seekread(inputfile, index);
The problem was that, in order to avoid arithmetical overflow, GPC assigned the largest possible type to integer constants (either `LongestInt' or `LongestCard') and converted it to something smaller when the constant is used together with something of known type.
This is fixed now, too: Integer constants in GPC are now `Integer'. Only if this does not fit, `Cardinal', `LongestInt', and `LongestCard' are used (in this order).
Various Miscellany: When I was playing around with all of this I wrote an ugly bit of code that could be reduced to:
program test(output); var i : 3..3; begin i := i + 1; writeln(i); end.
Why isn't there a warning about i being undefined? This code outputs 1, btw :)
A good question. Maybe the GCC backend initializes global variables to zero, so it has a defined value (out of range)? I will have to investigate it (kevin2.pas) ...
Lastly according to iso7185:6.4.2.4, "The first constant of a subrange-type shall specify the smallest value, and this shall be less than or equal to the largest value..." yet gpc happily compiles code like:
program test(output); var i: 4..1;begin writeln(i) end.
Fixed. :-)
Thanks for the bug reports,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [971005] maintainer GNU Pascal [971001] - http://home.pages.de/~gnu-pascal/ [971005]