STRINGS.ob07 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2018-2021, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE STRINGS;
  7. IMPORT UTILS;
  8. PROCEDURE copy* (src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR; spos, dpos, count: INTEGER);
  9. BEGIN
  10. WHILE count > 0 DO
  11. dst[dpos] := src[spos];
  12. INC(spos);
  13. INC(dpos);
  14. DEC(count)
  15. END
  16. END copy;
  17. PROCEDURE append* (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR);
  18. VAR
  19. n1, n2: INTEGER;
  20. BEGIN
  21. n1 := LENGTH(s1);
  22. n2 := LENGTH(s2);
  23. ASSERT(n1 + n2 < LEN(s1));
  24. copy(s2, s1, 0, n1, n2);
  25. s1[n1 + n2] := 0X
  26. END append;
  27. PROCEDURE IntToStr* (x: INTEGER; VAR str: ARRAY OF CHAR);
  28. VAR
  29. i, a: INTEGER;
  30. BEGIN
  31. IF x = UTILS.minint THEN
  32. IF UTILS.bit_depth = 32 THEN
  33. COPY("-2147483648", str)
  34. ELSIF UTILS.bit_depth = 64 THEN
  35. COPY("-9223372036854775808", str)
  36. END
  37. ELSE
  38. i := 0;
  39. IF x < 0 THEN
  40. x := -x;
  41. i := 1;
  42. str[0] := "-"
  43. END;
  44. a := x;
  45. REPEAT
  46. INC(i);
  47. a := a DIV 10
  48. UNTIL a = 0;
  49. str[i] := 0X;
  50. REPEAT
  51. DEC(i);
  52. str[i] := CHR(x MOD 10 + ORD("0"));
  53. x := x DIV 10
  54. UNTIL x = 0
  55. END
  56. END IntToStr;
  57. PROCEDURE search* (s: ARRAY OF CHAR; VAR pos: INTEGER; c: CHAR; forward: BOOLEAN);
  58. VAR
  59. length: INTEGER;
  60. BEGIN
  61. length := LENGTH(s);
  62. IF (0 <= pos) & (pos < length) THEN
  63. IF forward THEN
  64. WHILE (pos < length) & (s[pos] # c) DO
  65. INC(pos)
  66. END;
  67. IF pos = length THEN
  68. pos := -1
  69. END
  70. ELSE
  71. WHILE (pos >= 0) & (s[pos] # c) DO
  72. DEC(pos)
  73. END
  74. END
  75. ELSE
  76. pos := -1
  77. END
  78. END search;
  79. PROCEDURE replace* (VAR s: ARRAY OF CHAR; find, repl: CHAR);
  80. VAR
  81. i, strlen: INTEGER;
  82. BEGIN
  83. strlen := LENGTH(s) - 1;
  84. FOR i := 0 TO strlen DO
  85. IF s[i] = find THEN
  86. s[i] := repl
  87. END
  88. END
  89. END replace;
  90. PROCEDURE trim* (source: ARRAY OF CHAR; VAR result: ARRAY OF CHAR);
  91. VAR
  92. LenS, start, _end, i, j: INTEGER;
  93. BEGIN
  94. LenS := LENGTH(source) - 1;
  95. j := 0;
  96. IF LenS >= 0 THEN
  97. start := 0;
  98. WHILE (start <= LenS) & (source[start] <= 20X) DO
  99. INC(start)
  100. END;
  101. _end := LenS;
  102. WHILE (_end >= 0) & (source[_end] <= 20X) DO
  103. DEC(_end)
  104. END;
  105. FOR i := start TO _end DO
  106. result[j] := source[i];
  107. INC(j)
  108. END
  109. END;
  110. result[j] := 0X
  111. END trim;
  112. PROCEDURE letter* (c: CHAR): BOOLEAN;
  113. RETURN ("a" <= c) & (c <= "z") OR ("A" <= c) & (c <= "Z") OR (c = "_")
  114. END letter;
  115. PROCEDURE digit* (c: CHAR): BOOLEAN;
  116. RETURN ("0" <= c) & (c <= "9")
  117. END digit;
  118. PROCEDURE hexdigit* (c: CHAR): BOOLEAN;
  119. RETURN ("0" <= c) & (c <= "9") OR ("A" <= c) & (c <= "F")
  120. END hexdigit;
  121. PROCEDURE space* (c: CHAR): BOOLEAN;
  122. RETURN (0X < c) & (c <= 20X)
  123. END space;
  124. PROCEDURE cap* (VAR c: CHAR);
  125. BEGIN
  126. IF ("a" <= c) & (c <= "z") THEN
  127. c := CHR(ORD(c) - 32)
  128. END
  129. END cap;
  130. PROCEDURE UpCase* (VAR str: ARRAY OF CHAR);
  131. VAR
  132. i: INTEGER;
  133. BEGIN
  134. i := LENGTH(str) - 1;
  135. WHILE i >= 0 DO
  136. cap(str[i]);
  137. DEC(i)
  138. END
  139. END UpCase;
  140. PROCEDURE StrToInt* (str: ARRAY OF CHAR; VAR x: INTEGER): BOOLEAN;
  141. VAR
  142. i, k: INTEGER;
  143. res: BOOLEAN;
  144. BEGIN
  145. res := TRUE;
  146. i := 0;
  147. x := 0;
  148. k := LENGTH(str);
  149. WHILE i < k DO
  150. IF digit(str[i]) THEN
  151. x := x * 10 + ORD(str[i]) - ORD("0")
  152. ELSE
  153. i := k;
  154. res := FALSE
  155. END;
  156. INC(i)
  157. END
  158. RETURN res
  159. END StrToInt;
  160. PROCEDURE CheckVer (str: ARRAY OF CHAR): BOOLEAN;
  161. VAR
  162. i, k: INTEGER;
  163. res: BOOLEAN;
  164. BEGIN
  165. k := LENGTH(str);
  166. res := k < LEN(str);
  167. IF res & digit(str[0]) THEN
  168. i := 0;
  169. WHILE (i < k) & digit(str[i]) DO
  170. INC(i)
  171. END;
  172. IF (i < k) & (str[i] = ".") THEN
  173. INC(i);
  174. IF i < k THEN
  175. WHILE (i < k) & digit(str[i]) DO
  176. INC(i)
  177. END
  178. ELSE
  179. res := FALSE
  180. END
  181. ELSE
  182. res := FALSE
  183. END;
  184. res := res & (i = k)
  185. ELSE
  186. res := FALSE
  187. END
  188. RETURN res
  189. END CheckVer;
  190. PROCEDURE StrToVer* (str: ARRAY OF CHAR; VAR major, minor: INTEGER): BOOLEAN;
  191. VAR
  192. i: INTEGER;
  193. res: BOOLEAN;
  194. BEGIN
  195. res := CheckVer(str);
  196. IF res THEN
  197. i := 0;
  198. minor := 0;
  199. major := 0;
  200. WHILE digit(str[i]) DO
  201. major := major * 10 + ORD(str[i]) - ORD("0");
  202. INC(i)
  203. END;
  204. INC(i);
  205. WHILE digit(str[i]) DO
  206. minor := minor * 10 + ORD(str[i]) - ORD("0");
  207. INC(i)
  208. END
  209. END
  210. RETURN res
  211. END StrToVer;
  212. PROCEDURE Utf8To16* (src: ARRAY OF CHAR; VAR dst: ARRAY OF WCHAR): INTEGER;
  213. VAR
  214. i, j, u, srclen, dstlen: INTEGER;
  215. c: CHAR;
  216. BEGIN
  217. srclen := LEN(src);
  218. dstlen := LEN(dst);
  219. i := 0;
  220. j := 0;
  221. WHILE (i < srclen) & (j < dstlen) & (src[i] # 0X) DO
  222. c := src[i];
  223. CASE c OF
  224. |00X..7FX:
  225. u := ORD(c)
  226. |0C1X..0DFX:
  227. u := (ORD(c) - 0C0H) * 64;
  228. IF i + 1 < srclen THEN
  229. INC(i);
  230. INC(u, ORD(src[i]) MOD 64)
  231. END
  232. |0E1X..0EFX:
  233. u := (ORD(c) - 0E0H) * 4096;
  234. IF i + 1 < srclen THEN
  235. INC(i);
  236. INC(u, (ORD(src[i]) MOD 64) * 64)
  237. END;
  238. IF i + 1 < srclen THEN
  239. INC(i);
  240. INC(u, ORD(src[i]) MOD 64)
  241. END
  242. (*
  243. |0F1X..0F7X:
  244. |0F9X..0FBX:
  245. |0FDX:
  246. *)
  247. ELSE
  248. END;
  249. INC(i);
  250. dst[j] := WCHR(u);
  251. INC(j)
  252. END;
  253. IF j < dstlen THEN
  254. dst[j] := WCHR(0)
  255. END
  256. RETURN j
  257. END Utf8To16;
  258. PROCEDURE HashStr* (name: ARRAY OF CHAR): INTEGER;
  259. VAR
  260. i, h: INTEGER;
  261. g: SET;
  262. BEGIN
  263. h := 0;
  264. i := 0;
  265. WHILE name[i] # 0X DO
  266. h := h * 16 + ORD(name[i]);
  267. g := BITS(h) * {28..31};
  268. h := ORD(BITS(h) / BITS(LSR(ORD(g), 24)) - g);
  269. INC(i)
  270. END
  271. RETURN h
  272. END HashStr;
  273. END STRINGS.