STRINGS.ob07 7.4 KB

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