Subversion Repositories Kolibri OS

Rev

Rev 8097 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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