📄 fileio.mi
字号:
ELSIF Compare(name, "ERR") = 0 THEN
Okay := TRUE; f := err; RETURN
ELSE
ALLOCATE(f, SYSTEM.TSIZE(FileRec));
IF newFile
THEN BuffIO.OpenOutput(f^.ref, fileName);
ELSE BuffIO.OpenInput(f^.ref, fileName);
END;
IF ~ Okay
THEN
DEALLOCATE(f, SYSTEM.TSIZE(FileRec)); f := NIL
ELSE
(* textOK below may have to be altered according to implementation *)
f^.savedCh := 0C; f^.haveCh := FALSE; f^.textOK := TRUE;
f^.eof := newFile; f^.eol := newFile; f^.self := f;
f^.noInput := newFile; f^.noOutput := ~ newFile;
ASCIIZ(f^.name, fileName);
i := 0 (* find next available filehandle *);
WHILE (i IN Handles) & (i < MaxFiles) DO INC(i) END;
IF i < MaxFiles
THEN f^.handle := i; INCL(Handles, i); Opened[i] := f
ELSE WriteString(err, "Too many files"); Okay := FALSE
END;
END
END
END Open;
PROCEDURE Close (VAR f: File);
BEGIN
IF NotFile(f) OR (File(f) = StdIn) OR (File(f) = StdOut)
THEN Okay := FALSE
ELSE
EXCL(Handles, f^.handle);
BuffIO.Close(f^.ref);
IF Okay THEN DEALLOCATE(f, SYSTEM.TSIZE(FileRec)) END;
f := NIL
END
END Close;
PROCEDURE Delete (VAR f: File);
BEGIN
IF NotFile(f)
THEN Okay := FALSE
ELSE WriteString(err, "FileIO.Delete not implemented")
END;
Okay := FALSE; f := NIL
END Delete;
(*
PROCEDURE Delete (VAR f: File);
BEGIN
IF NotFile(f)
THEN Okay := FALSE
ELSE
EXCL(Handles, f^.handle);
FIO.Erase(f^.name);
Okay := FIO.IOresult() = 0;
IF Okay THEN DEALLOCATE(f, SYSTEM.TSIZE(FileRec)) END;
f := NIL
END
END Delete;
*)
PROCEDURE SearchFile (VAR f: File; envVar, fileName: ARRAY OF CHAR;
newFile: BOOLEAN);
VAR
i, j: INTEGER;
k: CARDINAL;
c: CHAR;
fname: ARRAY [0 .. NameLength] OF CHAR;
path: ARRAY [0 .. NameLength] OF CHAR;
BEGIN
FOR k := 0 TO HIGH(envVar) DO envVar[k] := CAP(envVar[k]) END;
GetEnv(envVar, path);
i := 0;
REPEAT
j := 0;
REPEAT
c := path[i]; fname[j] := c; INC(i); INC(j)
UNTIL (c = PathSep) OR (c = 0C);
IF (j > 1) & (fname[j-2] = DirSep) THEN DEC(j) ELSE fname[j-1] := DirSep END;
fname[j] := 0C; Concat(fname, fileName, fname);
Open(f, fname, newFile);
UNTIL (c = 0C) OR Okay
END SearchFile;
PROCEDURE ExtractDirectory (fullName: ARRAY OF CHAR;
VAR directory: ARRAY OF CHAR);
VAR
i, start: CARDINAL;
BEGIN
start := 0; i := 0;
WHILE (i <= HIGH(fullName)) & (fullName[i] # 0C) DO
IF i <= HIGH(directory) THEN
directory[i] := fullName[i];
END;
IF (fullName[i] = ":") OR (fullName[i] = DirSep) THEN start := i + 1 END;
INC(i)
END;
IF start <= HIGH(directory) THEN directory[start] := 0C END
END ExtractDirectory;
PROCEDURE ExtractFileName (fullName: ARRAY OF CHAR;
VAR fileName: ARRAY OF CHAR);
VAR
i, l, start: CARDINAL;
BEGIN
start := 0; l := 0;
WHILE (l <= HIGH(fullName)) & (fullName[l] # 0C) DO
IF (fullName[l] = ":") OR (fullName[l] = DirSep) THEN start := l + 1 END;
INC(l)
END;
i := 0;
WHILE (start < l) & (i <= HIGH(fileName)) DO
fileName[i] := fullName[start]; INC(start); INC(i)
END;
IF i <= HIGH(fileName) THEN fileName[i] := 0C END
END ExtractFileName;
PROCEDURE AppendExtension (oldName, ext: ARRAY OF CHAR;
VAR newName: ARRAY OF CHAR);
VAR
i, j: CARDINAL;
fn: ARRAY [0 .. NameLength] OF CHAR;
BEGIN
ExtractDirectory(oldName, newName);
ExtractFileName(oldName, fn);
i := 0; j := 0;
WHILE (i <= NameLength) & (fn[i] # 0C) DO
IF fn[i] = "." THEN j := i + 1 END;
INC(i)
END;
IF (j # i) (* then name did not end with "." *) OR (i = 0) THEN
IF j # 0 THEN i := j - 1 END;
IF (ext[0] # ".") & (ext[0] # 0C) THEN
IF i <= NameLength THEN fn[i] := "."; INC(i) END
END;
j := 0;
WHILE (j <= HIGH(ext)) & (ext[j] # 0C) & (i <= NameLength) DO
fn[i] := ext[j]; INC(i); INC(j)
END
END;
IF i <= NameLength THEN fn[i] := 0C END;
Concat(newName, fn, newName)
END AppendExtension;
PROCEDURE ChangeExtension (oldName, ext: ARRAY OF CHAR;
VAR newName: ARRAY OF CHAR);
VAR
i, j: CARDINAL;
fn: ARRAY [0 .. NameLength] OF CHAR;
BEGIN
ExtractDirectory(oldName, newName);
ExtractFileName(oldName, fn);
i := 0; j := 0;
WHILE (i <= NameLength) & (fn[i] # 0C) DO
IF fn[i] = "." THEN j := i + 1 END;
INC(i)
END;
IF j # 0 THEN i := j - 1 END;
IF (ext[0] # ".") & (ext[0] # 0C) THEN
IF i <= NameLength THEN fn[i] := "."; INC(i) END
END;
j := 0;
WHILE (j <= HIGH(ext)) & (ext[j] # 0C) & (i <= HIGH(fn)) DO
fn[i] := ext[j]; INC(i); INC(j)
END;
IF i <= NameLength THEN fn[i] := 0C END;
Concat(newName, fn, newName)
END ChangeExtension;
PROCEDURE Length (f: File): INT32;
VAR
pos, len: INTEGER;
BEGIN
IF NotFile(f)
THEN
Okay := FALSE; RETURN Long0
ELSE
pos := LIBC.lseek(f^.ref, 0, 0, LIBC.SEEK_CUR);
len := LIBC.lseek(f^.ref, 0, 0, LIBC.SEEK_END);
pos := LIBC.lseek(f^.ref, pos, 0, LIBC.SEEK_SET);
Okay := pos >= 0;
END;
RETURN len;
END Length;
PROCEDURE GetPos (f: File): INT32;
VAR
pos: CARDINAL;
BEGIN
IF NotFile(f)
THEN Okay := FALSE; RETURN Long0
ELSE pos := BuffIO.GetPos(f^.ref);
END;
RETURN pos;
END GetPos;
PROCEDURE SetPos (f: File; pos: INT32);
BEGIN
IF NotFile(f)
THEN Okay := FALSE
ELSE BuffIO.SetPos(f^.ref, pos); f^.haveCh := FALSE
END
END SetPos;
PROCEDURE Reset (f: File);
BEGIN
IF NotFile(f)
THEN
Okay := FALSE
ELSE
SetPos(f, 0);
IF Okay THEN
f^.haveCh := FALSE; f^.eof := f^.noInput; f^.eol := f^.noInput
END
END
END Reset;
PROCEDURE Rewrite (f: File);
BEGIN
IF NotFile(f)
THEN
Okay := FALSE
ELSE
BuffIO.Close(f^.ref);
BuffIO.OpenOutput(f^.ref, f^.name);
IF ~ Okay
THEN
DEALLOCATE(f, SYSTEM.TSIZE(FileRec)); f := NIL
ELSE
f^.savedCh := 0C; f^.haveCh := FALSE;
f^.eof := TRUE; f^.eol := TRUE;
f^.noInput := TRUE; f^.noOutput := FALSE;
END
END
END Rewrite;
PROCEDURE EndOfLine (f: File): BOOLEAN;
BEGIN
IF NotRead(f)
THEN Okay := FALSE; RETURN TRUE
ELSE Okay := TRUE; RETURN f^.eol OR f^.eof
END
END EndOfLine;
PROCEDURE EndOfFile (f: File): BOOLEAN;
BEGIN
IF NotRead(f)
THEN Okay := FALSE; RETURN TRUE
ELSE Okay := TRUE; RETURN f^.eof
END
END EndOfFile;
PROCEDURE Read (f: File; VAR ch: CHAR);
BEGIN
IF NotRead(f) THEN Okay := FALSE; ch := 0C; RETURN END;
IF f^.haveCh OR f^.eof
THEN
ch := f^.savedCh; Okay := ch # 0C;
ELSE
IF (f = File(con)) OR (f = File(StdIn)) & FromKeyboard
THEN
ConRead(ch); ConWrite(ch); Okay := ch # EOFChar;
IF ch = Erase THEN
IF ch # BS THEN ConWrite(BS) END;
ConWrite(" "); ConWrite(BS)
END
ELSE
BuffIO.GetByte(f^.ref, ch);
IF ch = CR THEN ch := EOL END;
END;
END;
IF ~ Okay THEN ch := 0C END;
f^.savedCh := ch; f^.haveCh := ~ Okay;
f^.eof := ch = 0C; f^.eol := f^.eof OR (ch = EOL);
END Read;
PROCEDURE ReadAgain (f: File);
BEGIN
IF NotRead(f)
THEN Okay := FALSE
ELSE f^.haveCh := TRUE
END
END ReadAgain;
PROCEDURE ReadLn (f: File);
VAR
ch: CHAR;
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 = Erase 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 = Erase 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 = Erase DO
IF j > 0 THEN DEC(j) END; Read(f, ch)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -