📄 fileio.mod
字号:
BEGIN
IF NotRead(f) THEN Okay := FALSE; RETURN END;
WHILE ~ f^.eol DO Read(f, ch) END;
f^.haveCh := FALSE; f^.eol := FALSE;
END ReadLn;
PROCEDURE ReadString (f: File; VAR str: ARRAY OF CHAR);
VAR
j: CARDINAL;
ch: CHAR;
BEGIN
str[0] := 0C; j := 0;
IF NotRead(f) THEN Okay := FALSE; RETURN END;
REPEAT Read(f, ch) UNTIL (ch # " ") OR ~ Okay;
IF Okay THEN
WHILE ch >= " " DO
IF j <= HIGH(str) THEN str[j] := ch END; INC(j);
Read(f, ch);
WHILE (ch = BS) OR (ch = DEL) DO
IF j > 0 THEN DEC(j) END; Read(f, ch)
END
END;
IF j <= HIGH(str) THEN str[j] := 0C END;
Okay := j > 0; f^.haveCh := TRUE; f^.savedCh := ch;
END
END ReadString;
PROCEDURE ReadLine (f: File; VAR str: ARRAY OF CHAR);
VAR
j: CARDINAL;
ch: CHAR;
BEGIN
str[0] := 0C; j := 0;
IF NotRead(f) THEN Okay := FALSE; RETURN END;
Read(f, ch);
IF Okay THEN
WHILE ch >= " " DO
IF j <= HIGH(str) THEN str[j] := ch END; INC(j);
Read(f, ch);
WHILE (ch = BS) OR (ch = DEL) DO
IF j > 0 THEN DEC(j) END; Read(f, ch)
END
END;
IF j <= HIGH(str) THEN str[j] := 0C END;
Okay := j > 0; f^.haveCh := TRUE; f^.savedCh := ch;
END
END ReadLine;
PROCEDURE ReadToken (f: File; VAR str: ARRAY OF CHAR);
VAR
j: CARDINAL;
ch: CHAR;
BEGIN
str[0] := 0C; j := 0;
IF NotRead(f) THEN Okay := FALSE; RETURN END;
REPEAT Read(f, ch) UNTIL (ch > " ") OR ~ Okay;
IF Okay THEN
WHILE ch > " " DO
IF j <= HIGH(str) THEN str[j] := ch END; INC(j);
Read(f, ch);
WHILE (ch = BS) OR (ch = DEL) DO
IF j > 0 THEN DEC(j) END; Read(f, ch)
END
END;
IF j <= HIGH(str) THEN str[j] := 0C END;
Okay := j > 0; f^.haveCh := TRUE; f^.savedCh := ch;
END
END ReadToken;
PROCEDURE ReadInt (f: File; VAR i: INTEGER);
VAR
Digit: INTEGER;
j: CARDINAL;
Negative: BOOLEAN;
s: ARRAY [0 .. 80] OF CHAR;
BEGIN
i := 0; j := 0;
IF NotRead(f) THEN Okay := FALSE; RETURN END;
ReadToken(f, s);
IF s[0] = "-" (* deal with sign *)
THEN Negative := TRUE; INC(j)
ELSE Negative := FALSE; IF s[0] = "+" THEN INC(j) END
END;
IF (s[j] < "0") OR (s[j] > "9") THEN Okay := FALSE END;
WHILE (j <= 80) & (s[j] >= "0") & (s[j] <= "9") DO
Digit := VAL(INTEGER, ORD(s[j]) - ORD("0"));
IF i <= (MAX(INTEGER) - Digit) DIV 10
THEN i := 10 * i + Digit
ELSE Okay := FALSE
END;
INC(j)
END;
IF Negative THEN i := -i END;
IF (j > 80) OR (s[j] # 0C) THEN Okay := FALSE END;
IF ~ Okay THEN i := 0 END;
END ReadInt;
PROCEDURE ReadCard (f: File; VAR i: CARDINAL);
VAR
Digit: CARDINAL;
j: CARDINAL;
s: ARRAY [0 .. 80] OF CHAR;
BEGIN
i := 0; j := 0;
IF NotRead(f) THEN Okay := FALSE; RETURN END;
ReadToken(f, s);
WHILE (j <= 80) & (s[j] >= "0") & (s[j] <= "9") DO
Digit := ORD(s[j]) - ORD("0");
IF i <= (MAX(CARDINAL) - Digit) DIV 10
THEN i := 10 * i + Digit
ELSE Okay := FALSE
END;
INC(j)
END;
IF (j > 80) OR (s[j] # 0C) THEN Okay := FALSE END;
IF ~ Okay THEN i := 0 END;
END ReadCard;
PROCEDURE ReadBytes (f: File; VAR buf: ARRAY OF SYSTEM.BYTE; VAR len: CARDINAL);
VAR
TooMany: BOOLEAN;
Wanted: CARDINAL;
BEGIN
IF NotRead(f) OR (f = con)
THEN Okay := FALSE; len := 0;
ELSE
IF len = 0 THEN Okay := TRUE; RETURN END;
TooMany := len - 1 > HIGH(buf);
IF TooMany THEN Wanted := HIGH(buf) + 1 ELSE Wanted := len END;
UxFiles.ReadNBytes(f^.ref, SYSTEM.ADR(buf), Wanted, len);
Okay := len # 0;
IF len # Wanted THEN Okay := FALSE END;
len := Wanted;
END;
IF ~ Okay THEN f^.eof := TRUE END;
IF TooMany THEN Okay := FALSE END;
END ReadBytes;
PROCEDURE Write (f: File; ch: CHAR);
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
IF ch = EOL
THEN Write(f, CR); Write(f, LF)
ELSIF (f = con) OR (f = StdOut) & ToScreen
THEN ConWrite(ch); Okay := TRUE;
ELSIF f = err THEN ErrWrite(ch); Okay := TRUE;
ELSE UxFiles.WriteByte(f^.ref, ch);
END;
END Write;
PROCEDURE WriteLn (f: File);
BEGIN
IF NotWrite(f)
THEN Okay := FALSE;
ELSE Write(f, EOL)
END
END WriteLn;
PROCEDURE WriteString (f: File; str: ARRAY OF CHAR);
VAR
pos: CARDINAL;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
pos := 0;
WHILE (pos <= HIGH(str)) & (str[pos] # 0C) DO
Write(f, str[pos]); INC(pos)
END
END WriteString;
PROCEDURE WriteText (f: File; text: ARRAY OF CHAR; len: INTEGER);
VAR
i, slen: INTEGER;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
slen := LENGTH(text);
FOR i := 0 TO len - 1 DO
IF i < slen THEN Write(f, text[i]) ELSE Write(f, " ") END;
END
END WriteText;
PROCEDURE WriteInt (f: File; n: INTEGER; wid: CARDINAL);
VAR
l, d: CARDINAL;
x: INTEGER;
t: ARRAY [1 .. 25] OF CHAR;
sign: CHAR;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
IF n < 0
THEN sign := "-"; x := - n;
ELSE sign := " "; x := n;
END;
l := 0;
REPEAT
d := x MOD 10; x := x DIV 10;
INC(l); t[l] := CHR(ORD("0") + d);
UNTIL x = 0;
IF wid = 0 THEN Write(f, " ") END;
WHILE wid > l + 1 DO Write(f, " "); DEC(wid); END;
IF (sign = "-") OR (wid > l) THEN Write(f, sign); END;
WHILE l > 0 DO Write(f, t[l]); DEC(l); END;
END WriteInt;
PROCEDURE WriteCard (f: File; n, wid: CARDINAL);
VAR
l, d: CARDINAL;
t: ARRAY [1 .. 25] OF CHAR;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
l := 0;
REPEAT
d := n MOD 10; n := n DIV 10;
INC(l); t[l] := CHR(ORD("0") + d);
UNTIL n = 0;
IF wid = 0 THEN Write(f, " ") END;
WHILE wid > l DO Write(f, " "); DEC(wid); END;
WHILE l > 0 DO Write(f, t[l]); DEC(l); END;
END WriteCard;
PROCEDURE WriteBytes (f: File; VAR buf: ARRAY OF SYSTEM.BYTE; len: CARDINAL);
VAR
TooMany: BOOLEAN;
num: CARDINAL;
BEGIN
TooMany := (len > 0) & (len - 1 > HIGH(buf));
IF NotWrite(f) OR (f = con) OR (f = err)
THEN
Okay := FALSE
ELSE
IF TooMany THEN len := HIGH(buf) + 1 END;
UxFiles.WriteNBytes(f^.ref, SYSTEM.ADR(buf), len, num);
Okay := num = len;
END;
IF TooMany THEN Okay := FALSE END;
END WriteBytes;
PROCEDURE GetDate (VAR Year, Month, Day: CARDINAL);
VAR
time: SysClock.DateTime;
BEGIN
SysClock.GetClock(time);
Year := time.year;
Month := time.month;
Day := time.day;
END GetDate;
PROCEDURE GetTime (VAR Hrs, Mins, Secs, Hsecs: CARDINAL);
VAR
time: SysClock.DateTime;
BEGIN
SysClock.GetClock(time);
Hrs := time.hour;
Mins := time.minute;
Secs := time.second;
Hsecs := time.fractions;
END GetTime;
PROCEDURE Write2 (f: File; i: CARDINAL);
BEGIN
Write(f, CHR(i DIV 10 + ORD("0")));
Write(f, CHR(i MOD 10 + ORD("0")));
END Write2;
PROCEDURE WriteDate (f: File);
VAR
Year, Month, Day: CARDINAL;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
GetDate(Year, Month, Day);
Write2(f, Day); Write(f, "/"); Write2(f, Month); Write(f, "/");
WriteCard(f, Year, 1)
END WriteDate;
PROCEDURE WriteTime (f: File);
VAR
Hrs, Mins, Secs, Hsecs: CARDINAL;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
GetTime(Hrs, Mins, Secs, Hsecs);
Write2(f, Hrs); Write(f, ":"); Write2(f, Mins); Write(f, ":");
Write2(f, Secs)
END WriteTime;
VAR
Hrs0, Mins0, Secs0, Hsecs0: CARDINAL;
Hrs1, Mins1, Secs1, Hsecs1: CARDINAL;
PROCEDURE WriteElapsedTime (f: File);
VAR
Hrs, Mins, Secs, Hsecs, s, hs: CARDINAL;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
GetTime(Hrs, Mins, Secs, Hsecs);
WriteString(f, "Elapsed time: ");
IF Hrs >= Hrs1
THEN s := (Hrs - Hrs1) * 3600 + (Mins - Mins1) * 60 + Secs - Secs1
ELSE s := (Hrs + 24 - Hrs1) * 3600 + (Mins - Mins1) * 60 + Secs - Secs1
END;
IF Hsecs >= Hsecs1
THEN hs := Hsecs - Hsecs1
ELSE hs := (Hsecs + 100) - Hsecs1; DEC(s);
END;
WriteCard(f, s, 1); Write(f, ".");
Write2(f, hs); WriteString(f, " s"); WriteLn(f);
Hrs1 := Hrs; Mins1 := Mins; Secs1 := Secs; Hsecs1 := Hsecs;
END WriteElapsedTime;
PROCEDURE WriteExecutionTime (f: File);
VAR
Hrs, Mins, Secs, Hsecs, s, hs: CARDINAL;
BEGIN
IF NotWrite(f) THEN Okay := FALSE; RETURN END;
GetTime(Hrs, Mins, Secs, Hsecs);
WriteString(f, "Execution time: ");
IF Hrs >= Hrs0
THEN s := (Hrs - Hrs0) * 3600 + (Mins - Mins0) * 60 + Secs - Secs0
ELSE s := (Hrs + 24 - Hrs0) * 3600 + (Mins - Mins0) * 60 + Secs - Secs0
END;
IF Hsecs >= Hsecs0
THEN hs := Hsecs - Hsecs0
ELSE hs := (Hsecs + 100) - Hsecs0; DEC(s);
END;
WriteCard(f, s, 1); Write(f, "."); Write2(f, hs);
WriteString(f, " s"); WriteLn(f);
END WriteExecutionTime;
(* The code for the next four procedures below may be commented out if your
compiler supports ISO PROCEDURE constant declarations and these declarations
are made in the DEFINITION MODULE *)
PROCEDURE SLENGTH (stringVal: ARRAY OF CHAR): CARDINAL;
BEGIN
RETURN StdStrings.Length(stringVal)
END SLENGTH;
PROCEDURE Assign (source: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR);
BEGIN
(* Be careful - some libraries have the parameters reversed! *)
StdStrings.Assign(source, destination)
END Assign;
PROCEDURE Extract (source: ARRAY OF CHAR; startIndex: CARDINAL;
numberToExtract: CARDINAL; VAR destination: ARRAY OF CHAR);
BEGIN
StdStrings.Extract(source, startIndex, numberToExtract, destination);
END Extract;
PROCEDURE Concat (source1, source2: ARRAY OF CHAR; VAR destination: ARRAY OF CHAR);
BEGIN
StdStrings.Assign(source1, destination);
StdStrings.Append(source2, destination);
END Concat;
(* The code for the four procedures above may be commented out if your
compiler supports ISO PROCEDURE constant declarations and these declarations
are made in the DEFINITION MODULE *)
PROCEDURE Compare (stringVal1, stringVal2: ARRAY OF CHAR): INTEGER;
BEGIN
RETURN VAL(INTEGER, StdStrings.Compare(stringVal1, stringVal2)) - 1;
END Compare;
PROCEDURE ORDL (n: INT32): CARDINAL;
BEGIN RETURN VAL(CARDINAL, n) END ORDL;
PROCEDURE INTL (n: INT32): INTEGER;
BEGIN RETURN VAL(INTEGER, n) END INTL;
PROCEDURE INT (n: CARDINAL): INT32;
BEGIN RETURN VAL(INT32, n) END INT;
PROCEDURE CloseAll;
(* There seems no way to install this as termination procedure in the
GPM-PC version *)
VAR
handle: CARDINAL;
BEGIN
FOR handle := 0 TO MaxFiles - 1 DO
IF handle IN Handles THEN UxFiles.Close(Opened[handle]^.ref, Okay) END
END;
END CloseAll;
PROCEDURE QuitExecution;
BEGIN
HALT
END QuitExecution;
BEGIN
CheckRedirection; (* Not apparently available on many systems *)
GetTime(Hrs0, Mins0, Secs0, Hsecs0);
Hrs1 := Hrs0; Mins1 := Mins0; Secs1 := Secs0; Hsecs1 := Hsecs0;
Handles := BITSET{};
Okay := FALSE; EOFChar := 32C;
Param := 0;
numPar := ProgArgs.ArgNumber();
ALLOCATE(con, SYSTEM.TSIZE(FileRec));
con^.savedCh := 0C; con^.haveCh := FALSE; con^.self := con;
con^.noOutput := FALSE; con^.noInput := FALSE; con^.textOK := TRUE;
con^.eof := FALSE; con^.eol := FALSE;
ALLOCATE(StdIn, SYSTEM.TSIZE(FileRec));
StdIn^.ref := StdFiles.StreamOfStdIn();
StdIn^.savedCh := 0C; StdIn^.haveCh := FALSE; StdIn^.self := StdIn;
StdIn^.noOutput := TRUE; StdIn^.noInput := FALSE; StdIn^.textOK := TRUE;
StdIn^.eof := FALSE; StdIn^.eol := FALSE;
ALLOCATE(StdOut, SYSTEM.TSIZE(FileRec));
StdOut^.ref := StdFiles.StreamOfStdOut();
StdOut^.savedCh := 0C; StdOut^.haveCh := FALSE; StdOut^.self := StdOut;
StdOut^.noOutput := FALSE; StdOut^.noInput := TRUE; StdOut^.textOK := TRUE;
StdOut^.eof := TRUE; StdOut^.eol := TRUE;
ALLOCATE(err, SYSTEM.TSIZE(FileRec));
err^.ref := StdFiles.StreamOfStdErr();
err^.savedCh := 0C; err^.haveCh := FALSE; err^.self := err;
err^.noOutput := FALSE; err^.noInput := TRUE; err^.textOK := TRUE;
err^.eof := TRUE; err^.eol := TRUE;
(*
FINALLY (* For ISO compilers *)
(* Preferably find some way to install CloseAll as an at-exit procedure *)
CloseAll;
*)
END FileIO.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -