-- StdioImpl.mesa
-- last edited by Suzuki:  August 24, 1981  12:25 PM
 
DIRECTORY
	AltoFileDefs USING [FP],
	DirectoryDefs USING [DirectoryLookup],
	ImageDefs,
	IODefs,
	stdio,
	StreamDefs,
	StringDefs,
	Real;

StdioImpl: PROGRAM 
	IMPORTS DirectoryDefs, ImageDefs, IODefs, Real, StreamDefs, StringDefs
	EXPORTS stdio = { OPEN stdio, StreamDefs;

stderr: PUBLIC FILE ← IODefs.GetOutputStream[];
stdin: PUBLIC FILE ← IODefs.GetInputStream[];
stdout: PUBLIC FILE ← IODefs.GetOutputStream[];

atof: PUBLIC PROC[s: STRING] RETURNS[REAL] = {
	RETURN[Real.StringToReal[s]]};
atoi: PUBLIC PROC[s: STRING] RETURNS[INTEGER] = {
	RETURN[StringDefs.StringToDecimal[s]]};

putc: PUBLIC PROC[c: CHARACTER, out: FILE] = {
	out.put[out, c]};
getch: PUBLIC PROC[in: FILE] RETURNS [CHARACTER] = {
	RETURN[in.get[in]]};
extRead: PUBLIC PROC[FILE] = {};
extWrite: PUBLIC PROC[FILE] = {};

fopen: PUBLIC PROC[name: STRING, access: STRING] RETURNS [FILE] = {
  fp: AltoFileDefs.FP;
  IF access[0]='r THEN
    IF DirectoryDefs.DirectoryLookup[@fp, name, FALSE] THEN 
      RETURN[StreamDefs.NewByteStream[name, Read]]
    ELSE RETURN[NIL]
  ELSE RETURN[StreamDefs.NewByteStream[name, ReadWriteAppend]]};
fclose: PUBLIC PROC[file: FILE] = {
	file.destroy[file]};
fflush: PUBLIC PROC[FILE] = {};
fgets: PUBLIC PROC[s: STRING, n: CARDINAL, iop: FILE] RETURNS [STRING] = { 
	c: CHARACTER;
	i: CARDINAL ← 177777B;
	get: PROCEDURE [StreamHandle] RETURNS [UNSPECIFIED] ← iop.get;
	ReadN: PROC[char: CHARACTER] RETURNS [BOOLEAN] = {
	  IF n=0 THEN RETURN[TRUE];
	  n ← n-1;
	  IF char=15C THEN RETURN[TRUE] ELSE RETURN[FALSE]};
	WITH iop SELECT FROM
	  Keyboard => {c ← IODefs.ReadEditedString[s, ReadN, TRUE];
		StringDefs.AppendChar[s, c];
		stdout.put[stdout, c];
		RETURN[s]};
	  Disk => IF iop.endof[iop] THEN RETURN[NIL];
	ENDCASE => ERROR;
	WHILE (n←n-1)>0 DO
		IF (c ← get[iop
		  !StreamDefs.StreamError => EXIT])=15C THEN GOTO CarriageReturn;
		s[i ← i+1] ← c;
	REPEAT
	  CarriageReturn => s[i ← i+1] ← c;
	ENDLOOP;
	s.length ← i;
	RETURN[s]};

exit: PUBLIC PROC[INTEGER] = {
	ImageDefs.StopMesa[]};

}.