Testing the TextIO MODULE

When you created a library MODULE you need to verify it through tests. Especially when you ported the library from another operating system or compiler. This is done by small test programs. Each time you find some new bugs and you just fix them one by one. We start out with a very simple program called 'test1':

MODULE	test1;

IMPORT	InOut, TextIO;

VAR	card1, card2		: CARDINAL;
	int1, int2		: INTEGER;
	str1, str2		: ARRAY [0..41] OF CHAR;
	inF, outF		: TextIO.File;
	ch			: CHAR;

BEGIN
  TextIO.OpenInput (inF, "bestand.001");
  IF  NOT TextIO.Done ()  THEN
    InOut.WriteString ("Cannot open file 'bestand.001'; aborting");
    InOut.WriteLn;
    HALT
  END;
  REPEAT
    TextIO.GetChar (inF, ch);
    InOut.Write (ch);
  UNTIL  TextIO.EOF (inF);
  TextIO.Close (inF)
END test1.
   
This source works. It compiles to a running executable that does not stop. The EOF condition is not recognized. So I changed the condition to
  UNTIL  ch = 0C;
   
and then it works just fine. So TextIO.GetChar, TextIO.OpenInput and TextIO.CLose seem to work, at least.

Of course things can be a lot fishier. Here is the listing of one of the first compiler runs. I created the test1.mod file and then tried to have it compiled into java source code. The first thing the MHC coimpiler does, is, of course, compile all the required other libraries. In this case: the TextIO library:
jan@Beryllium:~/modula/mhc/M$ mhc test1
Modula-2 2.5.67 (c) 1998-2006 J.Neuhoff (www.mhccorp.com)
Licenced to Jan Verhoeven
Compiling: /home/com.mhccorp/mhc/runtime/mod/SYSTEM.mod
Compiling: /home/com.mhccorp/mhc/runtime/mod/FileSystem.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/Strings.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/Strings.mod
Compiling: /home/com.mhccorp/mhc/runtime/mod/FileSystem.mod
Compiling: /home/com.mhccorp/mhc/runtime/mod/InOut.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/Conversions.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/Conversions.mod
Compiling: /home/com.mhccorp/mhc/runtime/mod/InOut.mod
Compiling: /home/jan/modula/mhc/M/TextIO.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/RealConversions.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/RealConversions.mod
Compiling: /home/jan/modula/mhc/M/TextIO.mod
TextIO.mod (36:3) : FileSystem is undefined, using an integer variable
TextIO.mod (36:25) : Procedure variable expected, using HALT
TextIO.mod (36:36) : Too many actual parameters
TextIO.mod (44:3) : FileSystem is undefined, using an integer variable
TextIO.mod (44:27) : Procedure variable expected, using HALT
TextIO.mod (44:38) : Too many actual parameters
TextIO.mod (52:3) : FileSystem is undefined, using an integer variable
TextIO.mod (52:20) : Procedure variable expected, using HALT
TextIO.mod (52:25) : Too many actual parameters
TextIO.mod (60:3) : FileSystem is undefined, using an integer variable
TextIO.mod (60:22) : Procedure variable expected, using HALT
TextIO.mod (60:30) : Too many actual parameters
TextIO.mod (68:3) : FileSystem is undefined, using an integer variable
TextIO.mod (68:20) : Procedure variable expected, using HALT
TextIO.mod (68:25) : Too many actual parameters
TextIO.mod (109:7) : Syntax error
TextIO.mod (109:7) : Compilation not continued
jan@Beryllium:~/modula/mhc/M$ jed TextIO.def
   
In this case
  1. open TextIO.mod in a text editor (for example 'jed')
  2. go to line 36 and see what's wrong there. FileSystem was not imported in the IMP MOD
  3. save and exit
  4. rerun 'mhc test1'
thereby producing this result:
jan@Beryllium:~/modula/mhc/M$ jed TextIO.mod
jan@Beryllium:~/modula/mhc/M$ mhc test1
Modula-2 2.5.67 (c) 1998-2006 J.Neuhoff (www.mhccorp.com)
Licenced to Jan Verhoeven
Compiling: /home/com.mhccorp/mhc/runtime/mod/FileSystem.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/Strings.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/InOut.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/Conversions.def
Compiling: /home/jan/modula/mhc/M/TextIO.def
Compiling: /home/com.mhccorp/mhc/runtime/mod/RealConversions.def
Compiling: /home/jan/modula/mhc/M/TextIO.mod
TextIO.mod (117:1) : Warning: ch has been declared but never used
TextIO.mod (137:1) : Warning: i has been declared but never used
TextIO.mod (137:1) : Warning: n has been declared but never used
TextIO.mod (224:3) : Types are not assignment compatible
TextIO.mod (299:3) : Types are not assignment compatible
TextIO.mod (345:3) : ConvertToString is undefined, using an integer variable
TextIO.mod (345:19) : Procedure variable expected, using HALT
TextIO.mod (345:41) : Too many actual parameters
TextIO.mod (352:3) : ConvertToString is undefined, using an integer variable
TextIO.mod (352:19) : Procedure variable expected, using HALT
TextIO.mod (352:40) : Too many actual parameters
TextIO.mod (359:3) : ConvertToString is undefined, using an integer variable
TextIO.mod (359:19) : Procedure variable expected, using HALT
TextIO.mod (359:41) : Too many actual parameters
TextIO.mod (368:7) : ConvertToString is undefined, using an integer variable
TextIO.mod (368:23) : Procedure variable expected, using HALT
TextIO.mod (368:60) : Too many actual parameters
TextIO.mod (370:23) : Procedure variable expected, using HALT
TextIO.mod (370:45) : Too many actual parameters
TextIO.mod (370:45) : Error limit exceeded
TextIO.mod (370:45) : Compilation not continued
jan@Beryllium:~/modula/mhc/M$ jed TextIO.mod
   
So, at this point, you: erase the unused variables, add SHORT in front of the LONG variables, move ConvertToString to the top of the file, change some functions, etc until there are no errors anymore. Easy. NOT.


Fixing the EOF error

I'm not sure why the EOF is not recognized. So I am going to use a dirty trick and change the TextIO.EOF function into

PROCEDURE EOF (file : File) : BOOLEAN;

BEGIN
  InOut.WriteString ("EOF = ");
  IF  file.eof  THEN  InOut.WriteString ("TRUE")  ELSE  InOut.WriteString ("FALSE")  END;
  InOut.WriteLn;
  RETURN file.eof 
END EOF;
   
Each time, the function is called, a full report is printed. So after a few seconds, the screen fills with
EOF = FALSE
and I have shown that EOF is a problem. See how I'm going fix this. It looks like 'file.eof' is not recognized for some silly reason. I looked around and found the 'dum2' program that I made while trying to read from ASCII files. That program recognized the eof condition well. So I changed the test1.mod program such that the character reader changed into
FileSystem.ReadChar (inF, ch);
instead of
TextIO.GetChar (inF, ch);
and now it works just fine! So this means that the GetChar function is to blame!

And this seems to do the trick:
PROCEDURE GetChar (file : File; VAR x : CHAR);
   
BEGIN
  FileSystem.ReadChar (file, x);
  IF  file.res = 0  THEN  done := TRUE  ELSE  done := FALSE  END;
  Eof := file.eof
END GetChar;
   
Apparently, the EOF status need to be assessed immediately after a read operation. In itself thgis is good enough for me, but it does mean that EOF is now disconnected from a file. This makes sense for InOut.Read after Input Redirection, but not for a module that can have multiple files open. Perhaps MHC is not so mature as they claim. Or Java is to blaim.
I changed things back to the structured approach and the error is back again. This is weird. Perhaps this is why the FileSystem module uses so many SYSTEM.INLINE functions. It looks like variables get out of scope way too soon.

Page created on 29 July 2010 and

Page equipped with FroogleBuster technology