Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 7596 → Rev 7597

/programs/develop/oberon07/Source/TEXTDRV.ob07
0,0 → 1,209
(*
BSD 2-Clause License
 
Copyright (c) 2018, Anton Krotov
All rights reserved.
*)
 
MODULE TEXTDRV;
 
IMPORT FILES, C := COLLECTIONS;
 
 
CONST
 
CR = 0DX; LF = 0AX;
 
CHUNK = 1024 * 256;
 
 
TYPE
 
TEXT* = POINTER TO RECORD (C.ITEM)
 
chunk: ARRAY CHUNK OF BYTE;
pos, size: INTEGER;
file: FILES.FILE;
utf8: BOOLEAN;
CR: BOOLEAN;
 
line*, col*: INTEGER;
eof*: BOOLEAN;
eol*: BOOLEAN;
 
open*: PROCEDURE (text: TEXT; name: ARRAY OF CHAR): BOOLEAN;
peak*: PROCEDURE (text: TEXT): CHAR;
nextc*: PROCEDURE (text: TEXT)
 
END;
 
 
VAR
 
texts: C.COLLECTION;
 
 
PROCEDURE reset (text: TEXT);
BEGIN
text.chunk[0] := 0;
text.pos := 0;
text.size := 0;
text.file := NIL;
text.utf8 := FALSE;
text.CR := FALSE;
text.line := 1;
text.col := 1;
text.eof := FALSE;
text.eol := FALSE
END reset;
 
 
PROCEDURE peak (text: TEXT): CHAR;
RETURN CHR(text.chunk[text.pos])
END peak;
 
 
PROCEDURE load (text: TEXT);
BEGIN
IF ~text.eof THEN
text.size := FILES.read(text.file, text.chunk, LEN(text.chunk));
text.pos := 0;
IF text.size = 0 THEN
text.eof := TRUE;
text.chunk[0] := 0
END
END
END load;
 
 
PROCEDURE next (text: TEXT);
VAR
c: CHAR;
BEGIN
IF text.pos < text.size - 1 THEN
INC(text.pos)
ELSE
load(text)
END;
 
IF ~text.eof THEN
 
c := peak(text);
 
IF c = CR THEN
INC(text.line);
text.col := 0;
text.eol := TRUE;
text.CR := TRUE
ELSIF c = LF THEN
IF ~text.CR THEN
INC(text.line);
text.col := 0;
text.eol := TRUE
ELSE
text.eol := FALSE
END;
text.CR := FALSE
ELSE
text.eol := FALSE;
IF text.utf8 THEN
IF (c < 80X) OR (c > 0BFX) THEN
INC(text.col)
END
ELSE
INC(text.col)
END;
text.CR := FALSE
END
 
END
 
END next;
 
 
PROCEDURE init (text: TEXT);
BEGIN
 
IF (text.pos = 0) & (text.size >= 3) THEN
IF (text.chunk[0] = 0EFH) &
(text.chunk[1] = 0BBH) &
(text.chunk[2] = 0BFH) THEN
text.pos := 3;
text.utf8 := TRUE
END
END;
 
IF text.size = 0 THEN
text.chunk[0] := 0;
text.size := 1;
text.eof := FALSE
END;
 
text.line := 1;
text.col := 1
 
END init;
 
 
PROCEDURE open (text: TEXT; name: ARRAY OF CHAR): BOOLEAN;
BEGIN
ASSERT(text # NIL);
 
reset(text);
text.file := FILES.open(name);
IF text.file # NIL THEN
load(text);
init(text)
END
 
RETURN text.file # NIL
END open;
 
 
PROCEDURE NewText (): TEXT;
VAR
text: TEXT;
citem: C.ITEM;
 
BEGIN
citem := C.pop(texts);
IF citem = NIL THEN
NEW(text)
ELSE
text := citem(TEXT)
END
 
RETURN text
END NewText;
 
 
PROCEDURE create* (): TEXT;
VAR
text: TEXT;
BEGIN
text := NewText();
reset(text);
text.open := open;
text.peak := peak;
text.nextc := next
 
RETURN text
END create;
 
 
PROCEDURE destroy* (VAR text: TEXT);
BEGIN
IF text # NIL THEN
IF text.file # NIL THEN
FILES.close(text.file)
END;
 
C.push(texts, text);
text := NIL
END
END destroy;
 
 
BEGIN
texts := C.create()
END TEXTDRV.