[comp.lang.modula2] JPI TopSpeed FIO.WrBin bug affects only re-directed I/O. Apologies.

SLovatt@massey.ac.nz (S.J. Lovatt) (07/12/90)

I received this by E-mail, but the answer bears on my previous posting, so
I'm posting the reply:

> From: Tom Almy <toma%tekgvs.labs.tek.com@RELAY.CS.NET>
>
> Let's figure out what is going on. I received my copy in June, but the
> files are dated April. Several samples:
>
> r_fio.mod 28287   4-17-90
> r_core.a        84096   4-14-90
> library (.lib) files are 4-26-90
> ts.exe is 4/24/90
> ts .dll files are 4/26/90
>
> and there is no "b" on my version number that I could find.
>
> So are your files earlier, later, or (horrors!) the same?
>
> Tom Almy
> toma@tekgvs.labs.tek.com
> Standard Disclaimers Apply

I checked my files, and they have the same dates as yours. Much puzzled, I
re-ran my tests, and a couple more. When I found the bug, I was writing
filter programs, which used re-directed standard input and output.
Therefore, all of my tests used re-directed I/O. Recalling your comment
about having used FIO.WrBin directly, I ran another two tests - this time
using ordinary file I/O. The results are given below (I used a printer
re-direction utility to direct Ctrl/PrtSc into a file, and thus captured
exactly what I did). BTW, the dump program is flawless - I've been using
it for over a year without any problems, and it was written in TS M2
Version 1 Rel 1.15.

My conclusions are as follows:

1) There is a bug, and it only shows up when using re-directed I/O.

2) That bug can be fixed by using CLB._write instead of CLB.write.

3) I mucked up my testing by not testing enough cases, and therefore
assumed that the error was more general than it is. Sorry if I caused
anybody any inconvenience. It is a lesson that I will remember for the
future. Maybe I should read comp.software.eng more carefully.

I also checked R_CORE.A

I found two write routines, one _write, and one __write. The __write
routine has a C prototype included as a comment as follows:

int _write (int handle, void *buffer, int num)

I did not go into R_CORE.A deeply enough to work out the differences
between the two, but apparently the effect on WrLn is one of them. In FIO,
my comment about CLB procedures often having leading underscores holds
true, but it was not as accurate as it ought to have been for the case of
CLB.write. In the original module as supplied, CLB.write is called in
FlsBuf, WrBin and WrChar. CLB._write is called in Truncate only.

Thanks to Tom Almy for helping to clear this up.

Regarding the version no. 1.04b. Since the file dates are the same as
version 1.04, perhaps the 'b' is for 'British' (as in Commonwealth, of
which New Zealand is a part), or perhaps it indicates an export version.
The only other TS M2 user in N.Z. (that I know of) also has version 1.04b,
and a recent posting from South Africa also mentioned that he had version
1.04b.

Summary of test procedure follows:
---------------------------------------------------------------------

Results with modified FIO.WrBin (which uses CLB._write):

For the program as follows:

MODULE TestWrLn;

FROM FIO IMPORT StandardOutput,WrLn;

BEGIN
   WrLn (StandardOutput);
END TestWrLn.

... the result was:

C:\M2\2>testwrln >test.out

C:\M2\2>dump test.out
       0: 0D 0A -- -- -- -- -- -- -- -- -- -- -- -- -- --   ..--------------

C:\M2\2>

... and for the program as follows:

MODULE TestWr2;

FROM FIO IMPORT StandardOutput,WrLn,File,Create,Close;

VAR      outfile : File;

BEGIN
   outfile := Create ('test2.out');
   WrLn (outfile);
   Close (outfile);
END TestWr2.

... the result was:

C:\M2\2>testwr2

C:\M2\2>dump test2.out
       0: 0D 0A -- -- -- -- -- -- -- -- -- -- -- -- -- --   ..--------------

C:\M2\2>

... all the above as expected.

Results with original FIO.WrBin (which uses CLB.write):

C:\M2\2>testwr2

C:\M2\2>dump test2.out
       0: 0D 0A -- -- -- -- -- -- -- -- -- -- -- -- -- --   ..--------------

C:\M2\2>testwrln >test.out

C:\M2\2>dump test.out
       0: 0D 0D 0A -- -- -- -- -- -- -- -- -- -- -- -- --   ...-------------

C:\M2\2>

... so the problem turns up in the test cases which I used but not in
others.

Again, sorry if I caused anybody any inconvenience.

- Simon


-- 
Simon Lovatt            | S.J.Lovatt@massey.ac.nz |
Dept of Biotechnology   |                         |
Massey University, N.Z. |                         |

toma@tekgvs.LABS.TEK.COM (Tom Almy) (07/12/90)

Well I investigated this some more, and came to a different conclusion than
Simon Lovatt.

The IO module does MS-DOS calls directly and thus does not suffer from this
problem. So you can do IO.WrLn where output is redirected to a file and not
get the lf -> crlf conversion.

On the other hand, the FIO module does io through the common language interface
(read *C-like interface*). Files can be opened in text (which translates) or
binary ("raw") mode. All the FIO procedures that open files use binary mode.

Unfortunately, the FIO.StandardInput and FIO.StandardOutput files (as well as
several others) are initially open, and the mode bit is
set to text! In a mixed language program, this would be required for C modules
to successfully write to the display.

Now, there are two solutions.

The first is to change the second entry in __openfd (in file r_mcore.a) from
4002H to 8002H, and recompile the libraries. Don't try to use the new library
if you have TS C.

A second less drastic solution is to import CLB and execute:
CLB._openfd[StandardInput] := CLB._openfd[StandardOutput] + CLB.O_BINARY - CLB.O_TEXT;

These bits are marked "read only", but in this case you gotta break the rules.

Of course, ideally one should be using the IO module, which doesn't have this 
problem. But I recognize that there might be some instances where one would
desire FIO so that routines can arbitrarily output to any device. Also, you 
can buffer file access with FIO (default is unbuffered, but I always specify
a buffer since it can make major differences in performance), while IO is
always unbuffered.

Simon's original fix has the problem that any file open for appending probably
won't work correctly as _write has the code to reposition the file at the end
while __write does not. Also _write has code to prevent a zero length write
(which truncates the file with MS-DOS).

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply

Ernie.Bokkelkamp@p22.f1.n491.z5.fidonet.org (Ernie Bokkelkamp) (07/14/90)

On 12 Jul 1990 20:32, S.J. Lovatt (1:105/42) wrote:

 SL>The only other TS M2 user in N.Z. (that I know of) also has 
 SL>version 1.04b,
 SL>and a recent posting from South Africa also mentioned that he 
 SL>had version
 SL>1.04b.

While re-making the libraries I noticed that the compiler reports the version number 1.04 and I have been unable to find a "b" anywhere except for the label on the disk. All disk labels state "TopSpeed Modula-2 V2" "Release 1.04b".

Regards
Ernie



--  
uucp: uunet!m2xenix!puddle!5!491!1.22!Ernie.Bokkelkamp
Internet: Ernie.Bokkelkamp@p22.f1.n491.z5.fidonet.org