Subversion Repositories Kolibri OS

Rev

Rev 7597 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2018, 2019, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE TEXTDRV;
  9.  
  10. IMPORT FILES, C := COLLECTIONS;
  11.  
  12.  
  13. CONST
  14.  
  15.     CR = 0DX; LF = 0AX;
  16.  
  17.     CHUNK = 1024 * 256;
  18.  
  19.  
  20. TYPE
  21.  
  22.     TEXT* = POINTER TO RECORD (C.ITEM)
  23.  
  24.         chunk:        ARRAY CHUNK OF BYTE;
  25.         pos, size:    INTEGER;
  26.         file:         FILES.FILE;
  27.         utf8:         BOOLEAN;
  28.         CR:           BOOLEAN;
  29.  
  30.         line*, col*:  INTEGER;
  31.         eof*:         BOOLEAN;
  32.         eol*:         BOOLEAN;
  33.         peak*:        CHAR
  34.  
  35.     END;
  36.  
  37.  
  38. VAR
  39.  
  40.     texts: C.COLLECTION;
  41.  
  42.  
  43. PROCEDURE load (text: TEXT);
  44. BEGIN
  45.     IF ~text.eof THEN
  46.         text.size := FILES.read(text.file, text.chunk, LEN(text.chunk));
  47.         text.pos := 0;
  48.         IF text.size = 0 THEN
  49.             text.eof := TRUE;
  50.             text.chunk[0] := 0
  51.         END;
  52.         text.peak := CHR(text.chunk[0])
  53.     END
  54. END load;
  55.  
  56.  
  57. PROCEDURE next* (text: TEXT);
  58. VAR
  59.     c: CHAR;
  60.  
  61. BEGIN
  62.     IF text.pos < text.size - 1 THEN
  63.         INC(text.pos);
  64.         text.peak := CHR(text.chunk[text.pos])
  65.     ELSE
  66.         load(text)
  67.     END;
  68.  
  69.     IF ~text.eof THEN
  70.  
  71.         c := text.peak;
  72.  
  73.         IF c = CR THEN
  74.             INC(text.line);
  75.             text.col := 0;
  76.             text.eol := TRUE;
  77.             text.CR  := TRUE
  78.         ELSIF c = LF THEN
  79.             IF ~text.CR THEN
  80.                 INC(text.line);
  81.                 text.col := 0;
  82.                 text.eol := TRUE
  83.             ELSE
  84.                 text.eol := FALSE
  85.             END;
  86.             text.CR := FALSE
  87.         ELSE
  88.             text.eol  := FALSE;
  89.             IF text.utf8 THEN
  90.                 IF (c < 80X) OR (c > 0BFX) THEN
  91.                     INC(text.col)
  92.                 END
  93.             ELSE
  94.                 INC(text.col)
  95.             END;
  96.             text.CR := FALSE
  97.         END
  98.  
  99.     END
  100.  
  101. END next;
  102.  
  103.  
  104. PROCEDURE init (text: TEXT);
  105. BEGIN
  106.     IF (text.pos = 0) & (text.size >= 3) THEN
  107.         IF (text.chunk[0] = 0EFH) &
  108.            (text.chunk[1] = 0BBH) &
  109.            (text.chunk[2] = 0BFH) THEN
  110.             text.pos := 3;
  111.             text.utf8 := TRUE
  112.         END
  113.     END;
  114.  
  115.     IF text.size = 0 THEN
  116.         text.chunk[0] := 0;
  117.         text.size := 1;
  118.         text.eof := FALSE
  119.     END;
  120.  
  121.     text.line := 1;
  122.     text.col  := 1;
  123.  
  124.     text.peak := CHR(text.chunk[text.pos])
  125. END init;
  126.  
  127.  
  128. PROCEDURE close* (VAR text: TEXT);
  129. BEGIN
  130.     IF text # NIL THEN
  131.         IF text.file # NIL THEN
  132.             FILES.close(text.file)
  133.         END;
  134.  
  135.         C.push(texts, text);
  136.         text := NIL
  137.     END
  138. END close;
  139.  
  140.  
  141. PROCEDURE open* (name: ARRAY OF CHAR): TEXT;
  142. VAR
  143.     text: TEXT;
  144.     citem: C.ITEM;
  145.  
  146. BEGIN
  147.     citem := C.pop(texts);
  148.     IF citem = NIL THEN
  149.         NEW(text)
  150.     ELSE
  151.         text := citem(TEXT)
  152.     END;
  153.  
  154.     IF text # NIL THEN
  155.         text.chunk[0] := 0;
  156.         text.pos  := 0;
  157.         text.size := 0;
  158.         text.utf8 := FALSE;
  159.         text.CR   := FALSE;
  160.         text.line := 1;
  161.         text.col  := 1;
  162.         text.eof  := FALSE;
  163.         text.eol  := FALSE;
  164.         text.peak := 0X;
  165.         text.file := FILES.open(name);
  166.         IF text.file # NIL THEN
  167.             load(text);
  168.             init(text)
  169.         ELSE
  170.             close(text)
  171.         END
  172.     END
  173.  
  174.     RETURN text
  175. END open;
  176.  
  177.  
  178. BEGIN
  179.     texts := C.create()
  180. END TEXTDRV.