(* Copyright 2021-2023 Anton Krotov This file is part of CEdit. CEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. CEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CEdit. If not, see . *) MODULE Utils; IMPORT SYSTEM; CONST SPACE* = 20X; SLASH* = "/"; OS* = "KOS"; PROCEDURE streq* (s1, s2: INTEGER; n: INTEGER): BOOLEAN; VAR c1, c2: WCHAR; res: BOOLEAN; BEGIN res := TRUE; WHILE (n > 0) & res DO SYSTEM.GET(s1, c1); SYSTEM.GET(s2, c2); res := c1 = c2; INC(s1, SYSTEM.SIZE(WCHAR)); INC(s2, SYSTEM.SIZE(WCHAR)); DEC(n) END RETURN res END streq; PROCEDURE append* (VAR s1: ARRAY OF WCHAR; s2: ARRAY OF WCHAR); VAR n, i, j: INTEGER; BEGIN j := LENGTH(s1); n := LENGTH(s2); ASSERT(j + n < LEN(s1)); i := 0; WHILE i < n DO s1[j] := s2[i]; INC(i); INC(j) END; s1[j] := 0X END append; PROCEDURE append8* (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); VAR n, i, j: INTEGER; BEGIN j := LENGTH(s1); n := LENGTH(s2); ASSERT(j + n < LEN(s1)); i := 0; WHILE i < n DO s1[j] := s2[i]; INC(i); INC(j) END; s1[j] := 0X END append8; PROCEDURE reverse* (VAR s: ARRAY OF WCHAR); VAR ch: WCHAR; i, j: INTEGER; BEGIN i := 0; j := LENGTH(s) - 1; WHILE i < j DO ch := s[i]; s[i] := s[j]; s[j] := ch; INC(i); DEC(j) END END reverse; PROCEDURE reverse8* (VAR s: ARRAY OF CHAR); VAR ch: CHAR; i, j: INTEGER; BEGIN i := 0; j := LENGTH(s) - 1; WHILE i < j DO ch := s[i]; s[i] := s[j]; s[j] := ch; INC(i); DEC(j) END END reverse8; PROCEDURE int2str* (val: INTEGER; VAR s: ARRAY OF WCHAR); VAR i: INTEGER; BEGIN i := 0; REPEAT s[i] := WCHR(ORD("0") + val MOD 10); INC(i); val := val DIV 10 UNTIL val = 0; s[i] := 0X; reverse(s) END int2str; PROCEDURE isDigit* (ch: WCHAR): BOOLEAN; RETURN ("0" <= ch) & (ch <= "9") END isDigit; PROCEDURE isOct* (ch: WCHAR): BOOLEAN; RETURN ("0" <= ch) & (ch <= "7") END isOct; PROCEDURE isHex* (ch: WCHAR): BOOLEAN; RETURN ("0" <= ch) & (ch <= "9") OR ("A" <= ch) & (ch <= "F") END isHex; PROCEDURE isLetter* (ch: WCHAR): BOOLEAN; RETURN ("a" <= ch) & (ch <= "z") OR ("A" <= ch) & (ch <= "Z") OR (* cyrillic *) (430X <= ch) & (ch <= 44FX) OR (410X <= ch) & (ch <= 42FX) OR (ch = 491X) OR (ch = 490X) OR (450X <= ch) & (ch <= 45FX) OR (400X <= ch) & (ch <= 40FX) END isLetter; PROCEDURE upper* (VAR ch: WCHAR): BOOLEAN; VAR res: BOOLEAN; BEGIN IF ("a" <= ch) & (ch <= "z") OR (430X <= ch) & (ch <= 44FX) THEN ch := WCHR(ORD(ch) - 20H); res := TRUE ELSIF (450X <= ch) & (ch <= 45FX) THEN ch := WCHR(ORD(ch) - 50H); res := TRUE ELSIF ch = 491X THEN ch := 490X; res := TRUE ELSE res := FALSE END RETURN res END upper; PROCEDURE lower* (VAR ch: WCHAR): BOOLEAN; VAR res: BOOLEAN; BEGIN IF ("A" <= ch) & (ch <= "Z") OR (410X <= ch) & (ch <= 42FX) THEN ch := WCHR(ORD(ch) + 20H); res := TRUE ELSIF (400X <= ch) & (ch <= 40FX) THEN ch := WCHR(ORD(ch) + 50H); res := TRUE ELSIF ch = 490X THEN ch := 491X; res := TRUE ELSE res := FALSE END RETURN res END lower; PROCEDURE lcase* (ch: WCHAR): WCHAR; BEGIN IF lower(ch) THEN END RETURN ch END lcase; PROCEDURE lowcase* (VAR s: ARRAY OF WCHAR); VAR i: INTEGER; BEGIN i := LENGTH(s) - 1; WHILE i >= 0 DO IF lower(s[i]) THEN END; DEC(i) END END lowcase; PROCEDURE lowcase8* (VAR s: ARRAY OF CHAR); VAR i: INTEGER; BEGIN i := LENGTH(s) - 1; WHILE i >= 0 DO IF ("A" <= s[i]) & (s[i] <= "Z") THEN s[i] := CHR(ORD(s[i]) + 20H) END; DEC(i) END END lowcase8; PROCEDURE str2int* (s: ARRAY OF WCHAR; VAR val: INTEGER): BOOLEAN; VAR i, temp: INTEGER; res, neg: BOOLEAN; BEGIN temp := 0; res := TRUE; neg := FALSE; i := 0; WHILE (s[i] # 0X) & (s[i] = SPACE) DO INC(i) END; IF s[i] = "-" THEN INC(i); neg := TRUE ELSIF s[i] = "+" THEN INC(i) END; IF isDigit(s[i]) THEN REPEAT temp := temp*10 + ORD(s[i]) - ORD("0"); INC(i) UNTIL ~isDigit(s[i]); IF neg THEN temp := -temp END; val := temp ELSE res := FALSE END RETURN res END str2int; PROCEDURE getFileName* (path: ARRAY OF CHAR; VAR name: ARRAY OF CHAR; ch: CHAR); VAR i, j: INTEGER; BEGIN j := 0; i := LENGTH(path) - 1; WHILE (i >= 0) & (path[i] # ch) DO name[j] := path[i]; DEC(i); INC(j) END; name[j] := 0X; reverse8(name) END getFileName; PROCEDURE getPath* (fname: ARRAY OF CHAR; VAR path: ARRAY OF CHAR); VAR i, j: INTEGER; BEGIN j := 0; i := LENGTH(fname) - 1; WHILE (i >= 0) & (fname[i] # SLASH) DO DEC(i) END; path := fname; path[i] := 0X END getPath; PROCEDURE lg10* (n: INTEGER): INTEGER; VAR res: INTEGER; BEGIN res := 0; WHILE n >= 10 DO n := n DIV 10; INC(res) END RETURN res END lg10; PROCEDURE between* (a, b, c: INTEGER): BOOLEAN; RETURN (a <= b) & (b <= c) END between; PROCEDURE inString* (c: WCHAR; s: ARRAY OF WCHAR): BOOLEAN; VAR i, L: INTEGER; BEGIN L := LENGTH(s); i := 0; WHILE (i < L) & (c # s[i]) DO INC(i) END RETURN i < L END inString; PROCEDURE isWordChar* (c: WCHAR): BOOLEAN; RETURN isLetter(c) OR isDigit(c) OR (c = "_") END isWordChar; END Utils.