Discussion:
Arithmetic operations on values of type FilePos (ISO I/O Library)
(too old to reply)
trijezdci
2017-07-29 12:38:12 UTC
Permalink
Hi Modulans

I have a portability layer for I/O. It is meant to be portable across dialects, compilers and operating systems. A configuration script lets users choose what underlying library to use (PIM, ISO, POSIX or vendor library). The choices depend on the dialect, the compiler and operating system.

As I am implementing the portability layer for use with the ISO library underneath, in particular a procedure that gets the size of a file, the ISO library type FilePos is giving me some headache.

I need to be able to do arithmetic operations on values of type FilePos in order to determine whether a value returned by RndFile.EndPos() would overflow type FileSize defined by my portability layer which is either CARDINAL or LONGINT depending on environment and configuration. If it does, I set a status SizeOverflow, which may happen when a compiler only supports 32 bit but produces code that runs on a 64 bit platform trying to get the file size of files larger 2 or 4 GB. A small price to pay for portability.

Anyway, I discovered that the p1 compiler does not permit arithmetic on values of type FilePos, nor does it permit conversion to another type. Astonishingly, this does not even appear to violate the ISO standard which defines type FilePos as an array of LOC of an implementation defined size. It does not seem to mandate that one can do arithmetic on values of the type, nor conversion.

Thus, when using the p1 compiler, I cannot convert the file size returned by RndFile.EndPos() nor could I check whether or not it would overflow my FileSize type. I had no choice but to open the file and read it byte by byte to the end while incrementing a counter in order to obtain a file size that is actually of any use. Very inefficient on larger files, but there seems to be no other way with p1's ISO library.

Now, I am wondering how many other ISO compilers (if any) suffer from the same silliness.

The operations I use can be seen in this function which checks whether an overflow would occur:

https://github.com/m2sf/m2pp/blob/master/src/imp/BasicFileSys/BasicFileSys.mw.mod#L192

if the test determines that no overflow would occur the value is simply converted using VAL().

https://github.com/m2sf/m2pp/blob/master/src/imp/BasicFileSys/BasicFileSys.mw.mod#L81


I would appreciate if group readers could check with whatever ISO compiler they have access to whether or not their compilers permit these arithmetic operations on values of type FilePos and conversion to CARDINAL and LONGINT.

thanks a lot in advance.
Chris Burrows
2017-07-30 02:35:04 UTC
Permalink
Just a thought - can you make use of the following?

"... a parameter defined as ARRAY OF LOC will accept any type that can be declared, and inside the procedure you can determine the size of the type passed with the HIGH function."

I've used a similar capability in Oberon recently to map file and directory structures onto SDHC disk sectors.

The info quoted above is in the ADW Modula-2 Help file. You can download a copy of the ADW system from here if you want to investigate further:

https://www.modula2.org/adwm2/

Chris Burrows
CFB Software
http://www.astrobe.com
trijezdci
2017-07-30 12:56:34 UTC
Permalink
Post by Chris Burrows
Just a thought - can you make use of the following?
"... a parameter defined as ARRAY OF LOC will accept any type that can be declared, and inside the procedure you can determine the size of the type passed with the HIGH function."
Thanks. I am aware of that but it is not generally a good idea to second guess implementation defined internal representations of types. There could be endianness issues. This could be fragile and high maintenance.

I'd rather use a portable and safe solution that is inefficient than one that is fragile and fast.

In any event, the ISO library should be considered a last resort when nothing else is available. Last resort fallback options are often not efficient.

Most of the compilers are on POSIX/Unix systems and have foreign function interfacing to C through which I supply a clean POSIX based implementation, bypassing the ISO library.

GPM/CLR doesn't even provide an ISO I/O library, it comes with a vendor specific library, a clean design. John Gough knows how to design APIs, we cannot say the same of ISO WG13.

The compilers for which the ISO library is presently the only option are ADW, Modulaware and XDS/Windows. They all support foreign function interfacing, so eventually I am going to write a clean interface to the native API of the underlying OS, but for now it is the ISO fallback on those.


But still, I would like to know which compilers are affected by this silliness, so that I can warn people about it in the installation notes.

It is always possible that p1 is the only compiler that behaves this way.

Thus again, I'd appreciate if anyone with access to an ISO compiler could check if FilePos permits arithmetic and conversion on their compiler and report back. Thanks a lot.

regards
benjamin
trijezdci
2017-08-01 10:28:22 UTC
Permalink
Further details ...

the p1 compiler doesn't even allow comparisons of two values of type FilePos for equality/inequality as can be seen here:

https://github.com/m2sf/m2pp/commit/9accc347b2cd20ba7e132f4673b2463872e37b68

it reports an operation of incompatible type even though both functions return the same type, FilePos.
Loading...