forked from KolibriOS/kolibrios
ce8fecbc6b
git-svn-id: svn://kolibrios.org@9177 a494cfbc-eb01-0410-851d-a64ba20cac60
210 lines
4.1 KiB
Plaintext
210 lines
4.1 KiB
Plaintext
(*
|
|
BSD 2-Clause License
|
|
|
|
Copyright (c) 2018-2021, Anton Krotov
|
|
All rights reserved.
|
|
*)
|
|
|
|
MODULE TEXTDRV;
|
|
|
|
IMPORT FILES, C := COLLECTIONS;
|
|
|
|
|
|
CONST
|
|
|
|
CR = 0DX; LF = 0AX; HT = 9X;
|
|
|
|
CHUNK = 1024 * 256;
|
|
|
|
defTabSize* = 4;
|
|
|
|
|
|
TYPE
|
|
|
|
TEXT* = POINTER TO RECORD (C.ITEM)
|
|
|
|
chunk: ARRAY CHUNK OF CHAR;
|
|
pos, size: INTEGER;
|
|
file: FILES.FILE;
|
|
utf8: BOOLEAN;
|
|
CR: BOOLEAN;
|
|
|
|
line*, col*: INTEGER;
|
|
ifc*: INTEGER;
|
|
elsec*: INTEGER;
|
|
eof*: BOOLEAN;
|
|
eol*: BOOLEAN;
|
|
skip*: BOOLEAN;
|
|
peak*: CHAR;
|
|
_skip*,
|
|
_elsif*,
|
|
_else*: ARRAY 100 OF BOOLEAN;
|
|
fname*: ARRAY 2048 OF CHAR
|
|
|
|
END;
|
|
|
|
|
|
VAR
|
|
|
|
texts: C.COLLECTION;
|
|
TabSize: INTEGER;
|
|
|
|
|
|
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] := 0X
|
|
END;
|
|
text.peak := text.chunk[0]
|
|
END
|
|
END load;
|
|
|
|
|
|
PROCEDURE next* (text: TEXT);
|
|
VAR
|
|
c: CHAR;
|
|
|
|
BEGIN
|
|
IF text.pos < text.size - 1 THEN
|
|
INC(text.pos);
|
|
text.peak := text.chunk[text.pos]
|
|
ELSE
|
|
load(text)
|
|
END;
|
|
|
|
IF ~text.eof THEN
|
|
|
|
c := text.peak;
|
|
|
|
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
|
|
ELSIF c = HT THEN
|
|
text.col := text.col + TabSize - text.col MOD TabSize;
|
|
text.eol := FALSE;
|
|
text.CR := FALSE
|
|
ELSE
|
|
IF text.utf8 THEN
|
|
IF ORD(c) DIV 64 # 2 THEN
|
|
INC(text.col)
|
|
END
|
|
ELSE
|
|
INC(text.col)
|
|
END;
|
|
text.eol := FALSE;
|
|
text.CR := FALSE
|
|
END
|
|
|
|
END
|
|
|
|
END next;
|
|
|
|
|
|
PROCEDURE init (text: TEXT);
|
|
BEGIN
|
|
IF (text.pos = 0) & (text.size >= 3) THEN
|
|
IF (text.chunk[0] = 0EFX) &
|
|
(text.chunk[1] = 0BBX) &
|
|
(text.chunk[2] = 0BFX) THEN
|
|
text.pos := 3;
|
|
text.utf8 := TRUE
|
|
END
|
|
END;
|
|
|
|
IF text.size = 0 THEN
|
|
text.chunk[0] := 0X;
|
|
text.size := 1;
|
|
text.eof := FALSE
|
|
END;
|
|
|
|
text.line := 1;
|
|
text.col := 1;
|
|
|
|
text.peak := text.chunk[text.pos]
|
|
END init;
|
|
|
|
|
|
PROCEDURE close* (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 close;
|
|
|
|
|
|
PROCEDURE open* (name: ARRAY OF CHAR): TEXT;
|
|
VAR
|
|
text: TEXT;
|
|
citem: C.ITEM;
|
|
|
|
BEGIN
|
|
citem := C.pop(texts);
|
|
IF citem = NIL THEN
|
|
NEW(text)
|
|
ELSE
|
|
text := citem(TEXT)
|
|
END;
|
|
|
|
IF text # NIL THEN
|
|
text.chunk[0] := 0X;
|
|
text.pos := 0;
|
|
text.size := 0;
|
|
text.utf8 := FALSE;
|
|
text.CR := FALSE;
|
|
text.line := 1;
|
|
text.col := 1;
|
|
text.eof := FALSE;
|
|
text.eol := FALSE;
|
|
text.skip := FALSE;
|
|
text.ifc := 0;
|
|
text.elsec := 0;
|
|
text._skip[0] := FALSE;
|
|
text.peak := 0X;
|
|
text.file := FILES.open(name);
|
|
COPY(name, text.fname);
|
|
IF text.file # NIL THEN
|
|
load(text);
|
|
init(text)
|
|
ELSE
|
|
close(text)
|
|
END
|
|
END
|
|
|
|
RETURN text
|
|
END open;
|
|
|
|
|
|
PROCEDURE setTabSize* (n: INTEGER);
|
|
BEGIN
|
|
IF (0 < n) & (n <= 64) THEN
|
|
TabSize := n
|
|
ELSE
|
|
TabSize := defTabSize
|
|
END
|
|
END setTabSize;
|
|
|
|
|
|
BEGIN
|
|
TabSize := defTabSize;
|
|
texts := C.create()
|
|
END TEXTDRV. |