IMPLEMENTATION MODULE M2makeOS; (* GNU Modula-2 implementation: binds the NUL-string (_s) half of m2make_os.c plus the shared m2osBye/m2osClose via M2makeC. Arguments come from the host FileIO (which already skips argv[0]) and are cached in a static table. Compiled only by gm2 (staged as M2makeOS.mod). *) FROM SYSTEM IMPORT ADDRESS; IMPORT M2makeC, FileIO, IOChan, StdChans; TYPE AStr = ARRAY [0..255] OF CHAR; VAR argTab: ARRAY [0..63] OF AStr; argN: CARDINAL; argDrained: BOOLEAN; PROCEDURE CopyArg(src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR); VAR i: CARDINAL; BEGIN i := 0; WHILE (i <= HIGH(src)) AND (i <= HIGH(dst)) DO dst[i] := src[i]; IF src[i] = CHR(0) THEN RETURN END; INC(i) END; dst[HIGH(dst)] := CHR(0) END CopyArg; PROCEDURE Drain; VAR s: AStr; i: CARDINAL; BEGIN IF argDrained THEN RETURN END; argDrained := TRUE; argN := 0; i := 0; WHILE i <= HIGH(s) DO s[i] := CHR(0); INC(i) END; LOOP FileIO.NextParameter(s); IF s[0] = CHR(0) THEN EXIT END; IF argN > HIGH(argTab) THEN EXIT END; CopyArg(s, argTab[argN]); INC(argN) END END Drain; PROCEDURE FileExists(VAR name: ARRAY OF CHAR): BOOLEAN; BEGIN RETURN M2makeC.m2osExistS(name) END FileExists; PROCEDURE FileMTime(VAR name: ARRAY OF CHAR; VAR t: LONGINT): BOOLEAN; BEGIN RETURN M2makeC.m2osMtimeS(name, t) END FileMTime; PROCEDURE ExecCmd(VAR cmd: ARRAY OF CHAR): INTEGER; BEGIN RETURN M2makeC.m2osSystemS(cmd) END ExecCmd; PROCEDURE ExitNow(code: INTEGER); BEGIN (* Flush gm2's channel buffers: raw exit() would drop the tail. *) IOChan.Flush(StdChans.StdOutChan()); M2makeC.m2osBye(code) END ExitNow; PROCEDURE OpenRead(VAR name: ARRAY OF CHAR): RdFile; BEGIN RETURN M2makeC.m2osOpenreadS(name) END OpenRead; PROCEDURE ArgCount(): CARDINAL; BEGIN Drain; RETURN argN END ArgCount; PROCEDURE ZeroArg(VAR s: ARRAY OF CHAR); VAR k: CARDINAL; BEGIN k := 0; WHILE k <= HIGH(s) DO s[k] := CHR(0); INC(k) END END ZeroArg; PROCEDURE GetArg(i: CARDINAL; VAR s: ARRAY OF CHAR; cap: CARDINAL): BOOLEAN; VAR k: CARDINAL; done: BOOLEAN; BEGIN Drain; IF cap = 0 THEN RETURN FALSE END; IF i >= argN THEN RETURN FALSE END; ZeroArg(s); k := 0; done := FALSE; WHILE (NOT done) AND (k + 1 < cap) AND (k <= HIGH(argTab[i])) AND (k <= HIGH(s)) DO IF argTab[i][k] = CHR(0) THEN done := TRUE ELSE s[k] := argTab[i][k]; INC(k) END END; RETURN TRUE END GetArg; PROCEDURE ReadLine(h: RdFile; VAR buf: ARRAY OF CHAR; cap: CARDINAL): BOOLEAN; BEGIN RETURN M2makeC.m2osReadlineS(h, buf, cap) END ReadLine; PROCEDURE CloseRead(h: RdFile); BEGIN M2makeC.m2osClose(h) END CloseRead; BEGIN argDrained := FALSE; argN := 0 END M2makeOS.