TEXTDRV.ob07 4.5 KB

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