IMPLEMENTATION MODULE FileIO; (* Self-hosted file I/O: SysShim only. *) IMPORT SysShim; VAR argIdx: CARDINAL; PROCEDURE NextParameter (VAR s: ARRAY OF CHAR); BEGIN IF SysShim.arg(argIdx, s, LEN(s)) THEN INC(argIdx) ELSE s[0] := CHR(0) END END NextParameter; PROCEDURE Open (VAR f: File; fileName: ARRAY OF CHAR; newFile: BOOLEAN); BEGIN IF newFile THEN f := SysShim.fopenwrite(fileName) ELSE f := SysShim.fopenread(fileName) END; Okay := f # NIL END Open; PROCEDURE Close (VAR f: File); BEGIN SysShim.fclose(f); f := NIL END Close; PROCEDURE ReadBytes (f: File; VAR buf: ARRAY OF CHAR; VAR len: CARDINAL); BEGIN len := SysShim.fread(f, buf, len) END ReadBytes; PROCEDURE Write (f: File; ch: CHAR); BEGIN IF ch = EOL THEN SysShim.fwriteln(f) ELSE SysShim.fputc(f, ch) END END Write; PROCEDURE WriteLn (f: File); BEGIN SysShim.fwriteln(f) END WriteLn; PROCEDURE WriteString (f: File; str: ARRAY OF CHAR); BEGIN SysShim.fputs(f, str) END WriteString; PROCEDURE WriteInt (f: File; int: INTEGER; wid: CARDINAL); BEGIN SysShim.fwriteintw(f, int, wid) END WriteInt; PROCEDURE WriteCard (f: File; card, wid: CARDINAL); BEGIN SysShim.fwriteintw(f, card, wid) END WriteCard; PROCEDURE SLENGTH (stringVal: ARRAY OF CHAR): CARDINAL; BEGIN RETURN LEN(stringVal) END SLENGTH; PROCEDURE Assign (source: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR); VAR i, n: CARDINAL; BEGIN n := LEN(source); IF n > LEN(destination) THEN n := LEN(destination) END; i := 0; WHILE i < n DO destination[i] := source[i]; INC(i) END END Assign; PROCEDURE Extract (source: ARRAY OF CHAR; startIndex, numberToExtract: CARDINAL; VAR destination: ARRAY OF CHAR); VAR i, n, k: CARDINAL; BEGIN n := LEN(source); k := 0; i := startIndex; WHILE (i < n) AND (k < numberToExtract) AND (k < LEN(destination)) DO destination[k] := source[i]; INC(k); INC(i) END END Extract; PROCEDURE Concat (stringVal1, stringVal2: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR); VAR i, k: CARDINAL; BEGIN k := 0; i := 0; WHILE (i < LEN(stringVal1)) AND (k < LEN(destination)) DO destination[k] := stringVal1[i]; INC(k); INC(i) END; i := 0; WHILE (i < LEN(stringVal2)) AND (k < LEN(destination)) DO destination[k] := stringVal2[i]; INC(k); INC(i) END END Concat; PROCEDURE Compare (stringVal1, stringVal2: ARRAY OF CHAR): INTEGER; VAR i, n, m: CARDINAL; BEGIN n := LEN(stringVal1); m := LEN(stringVal2); i := 0; WHILE (i < n) AND (i < m) DO IF stringVal1[i] < stringVal2[i] THEN RETURN -1 ELSIF stringVal1[i] > stringVal2[i] THEN RETURN 1 END; INC(i) END; IF n < m THEN RETURN -1 ELSIF n > m THEN RETURN 1 END; RETURN 0 END Compare; BEGIN (* Arguments exclude argv[0] (the program name), matching the gm2 host FileIO: user arguments start at cmdline index 1. *) argIdx := 1; Okay := TRUE; StdOut := SysShim.stdout(); con := StdOut; StdIn := NIL; err := SysShim.stderr() END FileIO.