Oberon/A2/Oberon.Strings.Mod

(* ETH Oberon, Copyright 2001 ETH Zuerich Institut fuer Computersysteme, ETH Zentrum, CH-8092 Zuerich. Refer to the "General ETH Oberon System Source License" contract available at : http : //www.oberon.ethz.ch/ *) MODULE Strings IN Oberon;	(** portable *) (* ejz, *) (** Strings is a utility module that provides procedures to manipulate strings. &#9;&#9;Note : All strings MUST be 0X terminated. *) &#9;IMPORT Oberon, Texts, Dates, Reals IN A2; &#9;CONST &#9;&#9;CR* &#61; 0DX; (** the Oberon end of line character *) &#9;&#9;Tab* &#61; 09X; (** the horizontal tab character *) &#9;&#9;LF* &#61; 0AX; (** the UNIX end of line character *) &#9;VAR &#9;&#9;isAlpha* : ARRAY 256 OF BOOLEAN; (** all letters in the oberon charset *) &#9;&#9;ISOToOberon*, OberonToISO* : ARRAY 256 OF CHAR; (** Translation tables for iso-8859-1 to oberon ascii code. *) &#9;&#9;CRLF* : ARRAY 4 OF CHAR; (** end of line "string" used by MS-DOS and most TCP protocols *) &#9;&#9;sDayName : ARRAY 7, 4 OF CHAR; &#9;&#9;lDayName : ARRAY 7, 12 OF CHAR; &#9;&#9;sMonthName : ARRAY 12, 4 OF CHAR; &#9;&#9;lMonthName : ARRAY 12, 12 OF CHAR; &#9;&#9;dateform, timeform : ARRAY 32 OF CHAR; (** Length of str. *) &#9;PROCEDURE Length*(CONST str(** in *) : ARRAY OF CHAR) : LONGINT; &#9;&#9;VAR i, l : LONGINT; &#9;BEGIN &#9;&#9;l : &#61; LEN(str); i : &#61; 0; &#9;&#9;WHILE (i &#60; l) &#38; (str&#91;i&#93; # 0X) DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;RETURN i &#9;END Length; (** Append this to to. *) &#9;PROCEDURE Append*(VAR to(** in/out *) : ARRAY OF CHAR; CONST this : ARRAY OF CHAR); &#9;&#9;VAR i, j, l : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE to&#91;i&#93; # 0X DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;l : &#61; LEN(to)-1; j : &#61; 0; &#9;&#9;WHILE (i &#60; l) &#38; (this&#91;j&#93; # 0X) DO &#9;&#9;&#9;to&#91;i&#93; : &#61; this&#91;j&#93;; INC(i); INC(j) &#9;&#9;END; &#9;&#9;to&#91;i&#93; : &#61; 0X &#9;END Append; (** Append this to to. *) &#9;PROCEDURE AppendCh*(VAR to(** in/out *) : ARRAY OF CHAR; this : CHAR); &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE to&#91;i&#93; # 0X DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;IF i &#60; (LEN(to)-1) THEN &#9;&#9;&#9;to&#91;i&#93; : &#61; this; to&#91;i+1&#93; : &#61; 0X &#9;&#9;END &#9;END AppendCh; (** TRUE if ch is a hexadecimal digit. *) &#9;PROCEDURE IsHexDigit*(ch : CHAR) : BOOLEAN; &#9;BEGIN &#9;&#9;RETURN ((ch &#62;&#61; "0") &#38; (ch &#60;&#61; "9")) OR ((CAP(ch) &#62;&#61; "A") &#38; (CAP(ch) &#60;&#61; "F")) &#9;END IsHexDigit; (** TRUE if ch is a decimal digit. *) &#9;PROCEDURE IsDigit*(ch : CHAR) : BOOLEAN; &#9;BEGIN &#9;&#9;RETURN (ch &#62;&#61; "0") &#38; (ch &#60;&#61; "9") &#9;END IsDigit; (** TRUE if ch is a letter. *) &#9;PROCEDURE IsAlpha*(ch : CHAR) : BOOLEAN; &#9;BEGIN &#9;&#9;RETURN isAlpha&#91;ORD(ch)&#93; &#9;END IsAlpha; (** If ch is an upper-case letter return the corresponding lower-case letter. *) &#9;PROCEDURE LowerCh*(ch : CHAR) : CHAR; &#9;BEGIN &#9;&#9;CASE ch OF &#9;&#9;&#9;"A" .. "Z" : ch : &#61; CHR(ORD(ch)-ORD("A")+ORD("a")) &#9;(*		&#124;"" : ch : &#61; "" &#9;&#9;&#9;&#124;"" : ch : &#61; "" &#9;&#9;&#9;&#124;"" : ch : &#61; "" *) &#9;&#9;ELSE &#9;&#9;END; &#9;&#9;RETURN ch &#9;END LowerCh; (** If ch is an lower-case letter return the corresponding upper-case letter. *) &#9;PROCEDURE UpperCh*(ch : CHAR) : CHAR; &#9;BEGIN &#9;&#9;CASE ch OF &#9;&#9;&#9;"a" .. "z" : ch : &#61; CAP(ch) (*			&#124;"" : ch : &#61; "" &#9;&#9;&#9;&#124;"" : ch : &#61; "" &#9;&#9;&#9;&#124;"" : ch : &#61; "" &#9;&#9;&#9;&#124;"" : ch : &#61; "A" &#9;&#9;&#9;&#124;"" : ch : &#61; "E" &#9;&#9;&#9;&#124;"" : ch : &#61; "I" &#9;&#9;&#9;&#124;"" : ch : &#61; "O" &#9;&#9;&#9;&#124;"" : ch : &#61; "U" &#9;&#9;&#9;&#124;"" : ch : &#61; "A" &#9;&#9;&#9;&#124;"" : ch : &#61; "E" &#9;&#9;&#9;&#124;"" : ch : &#61; "I" &#9;&#9;&#9;&#124;"" : ch : &#61; "O" &#9;&#9;&#9;&#124;"" : ch : &#61; "U" &#9;&#9;&#9;&#124;"" : ch : &#61; "E" &#9;&#9;&#9;&#124;"" : ch : &#61; "E" &#9;&#9;&#9;&#124;"" : ch : &#61; "I" &#9;&#9;&#9;&#124;"" : ch : &#61; "C" &#9;&#9;&#9;&#124;"" : ch : &#61; "A" &#9;&#9;&#9;&#124;"" : ch : &#61; "N" &#9;&#9;&#9;&#124;"" : ch : &#61; "S" *) &#9;&#9;ELSE &#9;&#9;END; &#9;&#9;RETURN ch &#9;END UpperCh; (** Convert str to all lower-case letters. *) &#9;PROCEDURE Lower*(CONST str(** in *) : ARRAY OF CHAR; VAR lstr(** out *) : ARRAY OF CHAR); &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE str&#91;i&#93; # 0X DO &#9;&#9;&#9;lstr&#91;i&#93; : &#61; LowerCh(str&#91;i&#93;); INC(i) &#9;&#9;END; &#9;&#9;lstr&#91;i&#93; : &#61; 0X &#9;END Lower; (** Convert str to all upper-case letters. *) &#9;PROCEDURE Upper*(CONST str(** in *) : ARRAY OF CHAR; VAR ustr(** out *) : ARRAY OF CHAR); &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE str&#91;i&#93; # 0X DO &#9;&#9;&#9;ustr&#91;i&#93; : &#61; UpperCh(str&#91;i&#93;); INC(i) &#9;&#9;END; &#9;&#9;ustr&#91;i&#93; : &#61; 0X &#9;END Upper; (** Is str prefixed by pre? *) &#9;PROCEDURE Prefix*(CONST pre, str(** in *) : ARRAY OF CHAR) : BOOLEAN; &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (pre&#91;i&#93; # 0X) &#38; (pre&#91;i&#93; &#61; str&#91;i&#93;) DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;RETURN pre&#91;i&#93; &#61; 0X &#9;END Prefix; (** Checks if str is prefixed by pre. The case is ignored. *) &#9;PROCEDURE CAPPrefix*(CONST pre, str(** in *) : ARRAY OF CHAR) : BOOLEAN; &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (pre&#91;i&#93; # 0X) &#38; (CAP(pre&#91;i&#93;) &#61; CAP(str&#91;i&#93;)) DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;RETURN pre&#91;i&#93; &#61; 0X &#9;END CAPPrefix; (** Compare str1 to str2. The case is ignored. *) &#9;PROCEDURE CAPCompare*(CONST str1(** in *), str2(** in *) : ARRAY OF CHAR) : BOOLEAN; &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (str1&#91;i&#93; # 0X) &#38; (str2&#91;i&#93; # 0X) &#38; (CAP(str1&#91;i&#93;) &#61; CAP(str2&#91;i&#93;)) DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;RETURN str1&#91;i&#93; &#61; str2&#91;i&#93; &#9;END CAPCompare; (** Get the parameter-value on line. The parameter value is started behind the first colon character. *) &#9;PROCEDURE GetPar*(CONST line(** in *) : ARRAY OF CHAR; VAR par(** out *) : ARRAY OF CHAR); &#9;&#9;VAR i, j, l : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (line&#91;i&#93; # 0X) &#38; (line&#91;i&#93; # " : ") DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;IF line&#91;i&#93; &#61; " : " THEN &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;WHILE (line&#91;i&#93; # 0X) &#38; (line&#91;i&#93; &#60;&#61; " ") DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;l : &#61; LEN(par)-1; j : &#61; 0; &#9;&#9;WHILE (j &#60; l) &#38; (line&#91;i&#93; # 0X) DO &#9;&#9;&#9;par&#91;j&#93; : &#61; line&#91;i&#93;; INC(j); INC(i) &#9;&#9;END; &#9;&#9;par&#91;j&#93; : &#61; 0X &#9;END GetPar; (** Get the suffix of str. The suffix is started by the last dot in str. *) &#9;PROCEDURE GetSuffix*(CONST str(** in *) : ARRAY OF CHAR; VAR suf(** out *) : ARRAY OF CHAR); &#9;&#9;VAR i, j, l, dot : LONGINT; &#9;BEGIN &#9;&#9;dot : &#61; -1; i : &#61; 0; &#9;&#9;WHILE str&#91;i&#93; # 0X DO &#9;&#9;&#9;IF str&#91;i&#93; &#61; "." THEN &#9;&#9;&#9;&#9;dot : &#61; i &#9;&#9;&#9;ELSIF str&#91;i&#93; &#61; "/" THEN &#9;&#9;&#9;&#9;dot : &#61; -1 &#9;&#9;&#9;END; &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;j : &#61; 0; &#9;&#9;IF dot &#62; 0 THEN &#9;&#9;&#9;l : &#61; LEN(suf)-1; i : &#61; dot+1; &#9;&#9;&#9;WHILE (j &#60; l) &#38; (str&#91;i&#93; # 0X) DO &#9;&#9;&#9;&#9;suf&#91;j&#93; : &#61; str&#91;i&#93;; INC(j); INC(i) &#9;&#9;&#9;END &#9;&#9;END; &#9;&#9;suf&#91;j&#93; : &#61; 0X &#9;END GetSuffix; (** Change the suffix of str to suf. *) &#9;PROCEDURE ChangeSuffix*(VAR str(** in/out *) : ARRAY OF CHAR; CONST suf : ARRAY OF CHAR); &#9;&#9;VAR i, j, l, dot : LONGINT; &#9;BEGIN &#9;&#9;dot : &#61; -1; i : &#61; 0; &#9;&#9;WHILE str&#91;i&#93; # 0X DO &#9;&#9;&#9;IF str&#91;i&#93; &#61; "." THEN &#9;&#9;&#9;&#9;dot : &#61; i &#9;&#9;&#9;ELSIF str&#91;i&#93; &#61; "/" THEN &#9;&#9;&#9;&#9;dot : &#61; -1 &#9;&#9;&#9;END; &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;IF dot &#62; 0 THEN &#9;&#9;&#9;l : &#61; LEN(str)-1; i : &#61; dot+1; j : &#61; 0; &#9;&#9;&#9;WHILE (i &#60; l) &#38; (suf&#91;j&#93; # 0X) DO &#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; suf&#91;j&#93;; INC(i); INC(j) &#9;&#9;&#9;END; &#9;&#9;&#9;str&#91;i&#93; : &#61; 0X &#9;&#9;END &#9;END ChangeSuffix; (** Search in src starting at pos for the next occurrence of pat. Returns pos&#61;-1 if not found. *) &#9;PROCEDURE Search*(CONST pat, src(** in *) : ARRAY OF CHAR; VAR pos(** in/out *) : LONGINT); &#9;&#9;CONST MaxPat &#61; 128; &#9;&#9;VAR &#9;&#9;&#9;buf : ARRAY MaxPat OF CHAR; &#9;&#9;&#9;len, i, srclen : LONGINT; &#9;&#9;PROCEDURE Find(beg : LONGINT); &#9;&#9;&#9;VAR &#9;&#9;&#9;&#9;i, j, b, e : LONGINT; &#9;&#9;&#9;&#9;ch : CHAR; &#9;&#9;&#9;&#9;ref : ARRAY MaxPat OF CHAR; &#9;&#9;BEGIN &#9;&#9;&#9;ch : &#61; src&#91;pos&#93;; INC(pos); &#9;&#9;&#9;ref&#91;0&#93; : &#61; ch; &#9;&#9;&#9;i : &#61; 0; j : &#61; 0; b : &#61; 0; e : &#61; 1; &#9;&#9;&#9;WHILE (pos &#60;&#61; srclen) &#38; (i &#60; len) DO &#9;&#9;&#9;&#9;IF buf&#91;i&#93; &#61; ch THEN &#9;&#9;&#9;&#9;&#9;INC(i); j : &#61; (j + 1) MOD MaxPat &#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;i : &#61; 0; b : &#61; (b + 1) MOD MaxPat; j : &#61; b &#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;IF j # e THEN &#9;&#9;&#9;&#9;&#9;ch : &#61; ref&#91;j&#93; &#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;IF pos &#62;&#61; srclen THEN &#9;&#9;&#9;&#9;&#9;&#9;ch : &#61; 0X &#9;&#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;&#9;ch : &#61; src&#91;pos&#93; &#9;&#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;&#9;INC(pos); ref&#91;j&#93; : &#61; ch; e : &#61; (e + 1) MOD MaxPat; INC(beg); &#9;&#9;&#9;&#9;END &#9;&#9;&#9;END; &#9;&#9;&#9;IF i &#61; len THEN &#9;&#9;&#9;&#9;pos : &#61; beg-len &#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;pos : &#61; -1 &#9;&#9;&#9;END &#9;&#9;END Find; &#9;BEGIN &#9;&#9;len : &#61; Length(pat); &#9;&#9;IF MaxPat &#60; len THEN &#9;&#9;&#9;len : &#61; MaxPat &#9;&#9;END; &#9;&#9;IF len &#60;&#61; 0 THEN &#9;&#9;&#9;pos : &#61; -1; &#9;&#9;&#9;RETURN &#9;&#9;END; &#9;&#9;i : &#61; 0; &#9;&#9;REPEAT &#9;&#9;&#9;buf&#91;i&#93; : &#61; pat&#91;i&#93;; INC(i) &#9;&#9;UNTIL i &#62;&#61; len; &#9;&#9;srclen : &#61; Length(src); &#9;&#9;IF pos &#60; 0 THEN &#9;&#9;&#9;pos : &#61; 0 &#9;&#9;ELSIF pos &#62;&#61; srclen THEN &#9;&#9;&#9;pos : &#61; -1; &#9;&#9;&#9;RETURN &#9;&#9;END; &#9;&#9;Find(pos) &#9;END Search; (** Search in src starting at pos for the next occurrence of pat. *) &#9;PROCEDURE CAPSearch*(CONST pat, src(** in *) : ARRAY OF CHAR; VAR pos(** in/out *) : LONGINT); &#9;&#9;CONST MaxPat &#61; 128; &#9;&#9;VAR &#9;&#9;&#9;buf : ARRAY MaxPat OF CHAR; &#9;&#9;&#9;len, i, srclen : LONGINT; &#9;&#9;PROCEDURE Find(beg : LONGINT); &#9;&#9;&#9;VAR &#9;&#9;&#9;&#9;i, j, b, e : LONGINT; &#9;&#9;&#9;&#9;ch : CHAR; &#9;&#9;&#9;&#9;ref : ARRAY MaxPat OF CHAR; &#9;&#9;BEGIN &#9;&#9;&#9;ch : &#61; UpperCh(src&#91;pos&#93;); INC(pos); &#9;&#9;&#9;ref&#91;0&#93; : &#61; ch; &#9;&#9;&#9;i : &#61; 0; j : &#61; 0; b : &#61; 0; e : &#61; 1; &#9;&#9;&#9;WHILE (pos &#60;&#61; srclen) &#38; (i &#60; len) DO &#9;&#9;&#9;&#9;IF buf&#91;i&#93; &#61; ch THEN &#9;&#9;&#9;&#9;&#9;INC(i); j : &#61; (j + 1) MOD MaxPat &#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;i : &#61; 0; b : &#61; (b + 1) MOD MaxPat; j : &#61; b &#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;IF j # e THEN &#9;&#9;&#9;&#9;&#9;ch : &#61; ref&#91;j&#93; &#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;IF pos &#62;&#61; srclen THEN &#9;&#9;&#9;&#9;&#9;&#9;ch : &#61; 0X &#9;&#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;&#9;ch : &#61; UpperCh(src&#91;pos&#93;) &#9;&#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;&#9;INC(pos); ref&#91;j&#93; : &#61; ch; e : &#61; (e + 1) MOD MaxPat; INC(beg); &#9;&#9;&#9;&#9;END &#9;&#9;&#9;END; &#9;&#9;&#9;IF i &#61; len THEN &#9;&#9;&#9;&#9;pos : &#61; beg-len &#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;pos : &#61; -1 &#9;&#9;&#9;END &#9;&#9;END Find; &#9;BEGIN &#9;&#9;len : &#61; Length(pat); &#9;&#9;IF MaxPat &#60; len THEN &#9;&#9;&#9;len : &#61; MaxPat &#9;&#9;END; &#9;&#9;IF len &#60;&#61; 0 THEN &#9;&#9;&#9;pos : &#61; -1; &#9;&#9;&#9;RETURN &#9;&#9;END; &#9;&#9;i : &#61; 0; &#9;&#9;REPEAT &#9;&#9;&#9;buf&#91;i&#93; : &#61; UpperCh(pat&#91;i&#93;); INC(i) &#9;&#9;UNTIL i &#62;&#61; len; &#9;&#9;srclen : &#61; Length(src); &#9;&#9;IF pos &#60; 0 THEN &#9;&#9;&#9;pos : &#61; 0 &#9;&#9;ELSIF pos &#62;&#61; srclen THEN &#9;&#9;&#9;pos : &#61; -1; &#9;&#9;&#9;RETURN &#9;&#9;END; &#9;&#9;Find(pos) &#9;END CAPSearch; (** Convert a string into an integer. Leading white space characters are ignored. *) &#9;PROCEDURE StrToInt*(CONST str : ARRAY OF CHAR; VAR val : LONGINT); &#9;&#9;VAR i, d : LONGINT; ch : CHAR; neg : BOOLEAN; &#9;BEGIN &#9;&#9;i : &#61; 0; ch : &#61; str&#91;0&#93;; &#9;&#9;WHILE (ch # 0X) &#38; (ch &#60;&#61; " ") DO &#9;&#9;&#9;INC(i); ch : &#61; str&#91;i&#93; &#9;&#9;END; &#9;&#9;neg : &#61; FALSE; IF ch &#61; "+" THEN INC(i); ch : &#61; str&#91;i&#93; END; &#9;&#9;IF ch &#61; "-" THEN neg : &#61; TRUE; INC(i); ch : &#61; str&#91;i&#93; END; &#9;&#9;WHILE (ch # 0X) &#38; (ch &#60;&#61; " ") DO &#9;&#9;&#9;INC(i); ch : &#61; str&#91;i&#93; &#9;&#9;END; &#9;&#9;val : &#61; 0; &#9;&#9;WHILE (ch &#62;&#61; "0") &#38; (ch &#60;&#61; "9") DO &#9;&#9;&#9;d : &#61; ORD(ch)-ORD("0"); &#9;&#9;&#9;INC(i); ch : &#61; str&#91;i&#93;; &#9;&#9;&#9;IF val &#60;&#61; ((MAX(LONGINT)-d) DIV 10) THEN &#9;&#9;&#9;&#9;val : &#61; 10*val+d &#9;&#9;&#9;ELSIF neg &#38; (val &#61; 214748364) &#38; (d &#61; 8) &#38; ((ch &#60; "0") OR (ch &#62; "9")) THEN &#9;&#9;&#9;&#9;val : &#61; MIN(LONGINT); neg : &#61; FALSE &#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;HALT(99) &#9;&#9;&#9;END &#9;&#9;END; &#9;&#9;IF neg THEN val : &#61; -val END &#9;END StrToInt; (** Convert the substring beginning at position i in str into an integer. Any leading whitespace characters are ignored. &#9;After the conversion i pointes to the first character after the integer. *) &#9;PROCEDURE StrToIntPos*(CONST str : ARRAY OF CHAR; VAR val : LONGINT; VAR i : INTEGER); &#9;&#9;VAR noStr : ARRAY 16 OF CHAR; &#9;BEGIN &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; (str&#91;i&#93; &#60;&#61; " ") DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;val : &#61; 0; &#9;&#9;IF str&#91;i&#93; &#61; "-" THEN &#9;&#9;&#9;noStr&#91;val&#93; : &#61; str&#91;i&#93;; INC(val); INC(i); &#9;&#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; (str&#91;i&#93; &#60;&#61; " ") DO &#9;&#9;&#9;&#9;INC(i) &#9;&#9;&#9;END &#9;&#9;END; &#9;&#9;WHILE (str&#91;i&#93; &#62;&#61; "0") &#38; (str&#91;i&#93; &#60;&#61; "9") DO &#9;&#9;&#9;noStr&#91;val&#93; : &#61; str&#91;i&#93;; INC(val); INC(i) &#9;&#9;END; &#9;&#9;noStr&#91;val&#93; : &#61; 0X; &#9;&#9;StrToInt(noStr, val) &#9;END StrToIntPos; (** Convert an integer into a string. *) &#9;PROCEDURE IntToStr*(val : LONGINT; VAR str : ARRAY OF CHAR); &#9;&#9;VAR &#9;&#9;&#9;i, j : LONGINT; &#9;&#9;&#9;digits : ARRAY 16 OF LONGINT; &#9;BEGIN &#9;&#9;IF val &#61; MIN(LONGINT) THEN &#9;&#9;&#9;COPY("-2147483648", str); &#9;&#9;&#9;RETURN &#9;&#9;END; &#9;&#9;IF val &#60; 0 THEN &#9;&#9;&#9;val : &#61; -val; str&#91;0&#93; : &#61; "-"; j : &#61; 1 &#9;&#9;ELSE &#9;&#9;&#9;j : &#61; 0 &#9;&#9;END; &#9;&#9;i : &#61; 0; &#9;&#9;REPEAT &#9;&#9;&#9;digits&#91;i&#93; : &#61; val MOD 10; INC(i); val : &#61; val DIV 10 &#9;&#9;UNTIL val &#61; 0; &#9;&#9;DEC(i); &#9;&#9;WHILE i &#62;&#61; 0 DO &#9;&#9;&#9;str&#91;j&#93; : &#61; CHR(digits&#91;i&#93;+ORD("0")); INC(j); DEC(i) &#9;&#9;END; &#9;&#9;str&#91;j&#93; : &#61; 0X &#9;END IntToStr; (** Converts a real to a string. *) PROCEDURE RealToStr*(x : LONGREAL; VAR s : ARRAY OF CHAR); VAR e, h, l, n, len : LONGINT; i, j, pos : INTEGER; z : LONGREAL; d : ARRAY 16 OF CHAR; &#9;PROCEDURE Wr(ch : CHAR); &#9;BEGIN &#9;&#9;IF ch &#61; 0X THEN HALT(42) END; &#9;&#9;IF pos &#60; len THEN s&#91;pos&#93; : &#61; ch; INC(pos) END; &#9;END Wr; BEGIN &#9;len : &#61; LEN(s)-1; pos : &#61; 0; &#9;e : &#61; Reals.ExpoL(x); &#9;IF e &#61; 2047 THEN &#9;&#9;Wr("N"); Wr("a"); Wr("N") &#9;ELSE &#9;&#9;n : &#61; 14; &#9;&#9;IF (x &#60; 0) &#38; (e # 0) THEN Wr("-"); x : &#61; - x END; &#9;&#9;IF e &#61; 0 THEN h : &#61; 0; l : &#61; 0 (* no denormals *) &#160;&#160;&#160;&#160;ELSE e : &#61; (e - 1023) * 301029 DIV 1000000; (* ln(2)/ln(10) &#61; 0.301029996 *) &#160;&#160;&#160;&#160;&#160;&#160;z : &#61; Reals.Ten(e+1); &#160;&#160;&#160;&#160;&#160;&#160;IF x &#62;&#61; z THEN x : &#61; x/z; INC(e) ELSE x : &#61; x * Reals.Ten(-e) END; &#160;&#160;&#160;&#160;&#160;&#160;IF x &#62;&#61; 10 THEN x : &#61; x * Reals.Ten(-1) + 0.5D0 / Reals.Ten(n); INC(e) &#160;&#160;&#160;&#160;&#160;&#160;ELSE x : &#61; x + 0.5D0 / Reals.Ten(n); &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IF x &#62;&#61; 10 THEN x : &#61; x * Reals.Ten(-1); INC(e) END &#160;&#160;&#160;&#160;&#160;&#160;END; &#160;&#160;&#160;&#160;&#160;&#160;x : &#61; x * Reals.Ten(7); h : &#61; ENTIER(x); x : &#61; (x-h) * Reals.Ten(8); l : &#61; ENTIER(x) &#160;&#160;&#160;&#160;END; &#9;&#9;i : &#61; 15; WHILE i &#62; 7 DO d&#91;i&#93; : &#61; CHR(l MOD 10 + ORD("0")); l : &#61; l DIV 10; DEC(i) END; &#9;&#9;WHILE i &#62;&#61; 0 DO d&#91;i&#93; : &#61; CHR(h MOD 10 + ORD("0")); h : &#61; h DIV 10; DEC(i) END; &#9;&#9;IF ABS(e) &#62; 8 THEN (* scientific notation *) &#9;&#9;&#9;j : &#61; 15; WHILE (j &#62; 0) &#38; (d&#91;j&#93; &#61; "0") DO DEC(j) END; &#9;&#9;&#9;Wr(d&#91;0&#93;); IF j # 0 THEN Wr(".") END; i : &#61; 1; WHILE i &#60;&#61; j DO Wr(d&#91;i&#93;); INC(i) END; &#9;&#9;&#9;IF e &#60; 0 THEN Wr("D"); Wr("-"); e : &#61; - e ELSE Wr("D"); Wr("+") END; &#9;&#9;&#9;Wr(CHR(e DIV 100 + ORD("0"))); e : &#61; e MOD 100; &#9;&#9;&#9;Wr(CHR(e DIV 10 + ORD("0"))); Wr(CHR(e MOD 10 + ORD("0"))) &#9;&#9;ELSE &#9;&#9;&#9;IF e &#60; 0 THEN (* leading zeros *) &#9;&#9;&#9;&#9;j : &#61; (* !15*) 14; WHILE (j &#62; 0) &#38; (d&#91;j&#93; &#61; "0") DO DEC(j) END; &#9;&#9;&#9;&#9;Wr("0"); Wr("."); INC(e); &#9;&#9;&#9;&#9;WHILE e &#60; 0 DO Wr("0"); INC(e) END; &#9;&#9;&#9;&#9;i : &#61; 0; WHILE i &#60;&#61; j DO Wr(d&#91;i&#93;); INC(i) END &#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;i : &#61; 0; WHILE (e &#62;&#61; 0) &#38; (i &#60; 16 ) DO Wr(d&#91;i&#93;); INC(i); DEC(e) END; &#9;&#9;&#9;&#9;IF i &#60; 16 THEN &#9;&#9;&#9;&#9;&#9;Wr("."); &#9;&#9;&#9;&#9;&#9;WHILE i &#60; (*16*) 15 DO Wr(d&#91;i&#93;); INC(i); END; &#9;&#9;&#9;&#9;&#9;WHILE s&#91;pos - 1&#93; &#61; "0" DO DEC(pos) END; &#9;&#9;&#9;&#9;&#9;IF s&#91;pos - 1&#93; &#61; "." THEN DEC(pos) END; &#9;&#9;&#9;&#9;END &#9;&#9;&#9;END &#9;&#9;END &#9;END; &#9;s&#91;pos&#93; : &#61; 0X END RealToStr; PROCEDURE RealToFixStr*(x : LONGREAL; VAR str : ARRAY OF CHAR; n, f, D : LONGINT); &#9;VAR pos, len, e, i, h, l : LONGINT; r, z : LONGREAL; d : ARRAY 16 OF CHAR; s : CHAR; &#9;PROCEDURE Wr(ch : CHAR); &#9;BEGIN &#9;&#9;IF ch &#61; 0X THEN HALT(42) END; &#9;&#9;IF pos &#60; len THEN str&#91;pos&#93; : &#61; ch; INC(pos) END; &#9;END Wr; BEGIN &#9;len : &#61; LEN(str)-1; pos : &#61; 0; &#9;e : &#61; Reals.ExpoL(x); &#9;IF (e &#61; 2047) OR (ABS(D) &#62; 308) THEN &#9;&#9;Wr("N"); Wr("a"); Wr("N") &#9;ELSE &#9;&#9;IF D &#61; 0 THEN DEC(n, 2) ELSE DEC(n, 7) END; &#9;&#9;IF n &#60; 2 THEN n : &#61; 2 END; &#9;&#9;IF f &#60; 0 THEN f : &#61; 0 END; &#9;&#9;IF n &#60; f + 2 THEN n : &#61; f + 2 END; &#9;&#9;DEC(n, f); &#9;&#9;IF (e # 0) &#38; (x &#60; 0) THEN s : &#61; "-"; x : &#61; - x ELSE s : &#61; " " END; &#9;&#9;IF e &#61; 0 THEN &#9;&#9;&#9;h : &#61; 0; l : &#61; 0; DEC(e, D-1) (* no denormals *) &#9;&#9;ELSE &#9;&#9;&#9;e : &#61; (e - 1023) * 301029 DIV 1000000; (* ln(2)/ln(10) &#61; 0.301029996 *) &#9;&#9;&#9;z : &#61; Reals.Ten(e+1); &#9;&#9;&#9;IF x &#62;&#61; z THEN x : &#61; x/z; INC(e) ELSE x : &#61; x * Reals.Ten(-e) END; &#9;&#9;&#9;DEC(e, D-1); i : &#61; -(e+f); &#9;&#9;&#9;IF i &#60;&#61; 0 THEN r : &#61; 5 * Reals.Ten(i) ELSE r : &#61; 0 END; &#9;&#9;&#9;IF x &#62;&#61; 10 THEN &#9;&#9;&#9;&#9;x : &#61; x * Reals.Ten(-1) + r; INC(e) &#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;x : &#61; x + r; &#9;&#9;&#9;&#9;IF x &#62;&#61; 10 THEN x : &#61; x * Reals.Ten(-1); INC(e) END &#9;&#9;&#9;END; &#9;&#9;&#9;x : &#61; x * Reals.Ten(7); h : &#61; ENTIER(x); x : &#61; (x-h) * Reals.Ten(8); l : &#61; ENTIER(x) &#9;&#9;END; &#9;&#9;i : &#61; 15; &#9;&#9;WHILE i &#62; 7 DO d&#91;i&#93; : &#61; CHR(l MOD 10 + ORD("0")); l : &#61; l DIV 10; DEC(i) END; &#9;&#9;WHILE i &#62;&#61; 0 DO d&#91;i&#93; : &#61; CHR(h MOD 10 + ORD("0")); h : &#61; h DIV 10; DEC(i) END; &#9;&#9;IF n &#60;&#61; e THEN n : &#61; e + 1 END; &#9;&#9;IF e &#62; 0 THEN &#9;&#9;&#9;WHILE n &#62; e DO Wr(" "); DEC(n) END; &#9;&#9;&#9;Wr(s); e : &#61; 0; &#9;&#9;&#9;WHILE n &#62; 0 DO &#9;&#9;&#9;&#9;DEC(n); &#9;&#9;&#9;&#9;IF e &#60; 16 THEN Wr(d&#91;e&#93;); INC(e) ELSE Wr("0") END &#9;&#9;&#9;END; &#9;&#9;&#9;Wr(".") &#9;&#9;ELSE &#9;&#9;&#9;WHILE n &#62; 1 DO Wr(" "); DEC(n) END; &#9;&#9;&#9;Wr(s); Wr("0"); Wr("."); &#9;&#9;&#9;WHILE (0 &#60; f) &#38; (e &#60; 0) DO Wr("0"); DEC(f); INC(e) END &#9;&#9;END; &#9;&#9;WHILE f &#62; 0 DO &#9;&#9;&#9;DEC(f); &#9;&#9;&#9;IF e &#60; 16 THEN Wr(d&#91;e&#93;); INC(e) ELSE Wr("0") END &#9;&#9;END; &#9;&#9;IF D # 0 THEN &#9;&#9;&#9;IF D &#60; 0 THEN Wr("D"); Wr("-"); D : &#61; - D &#9;&#9;&#9;ELSE Wr("D"); Wr("+") &#9;&#9;&#9;END; &#9;&#9;&#9;Wr(CHR(D DIV 100 + ORD("0"))); D : &#61; D MOD 100; &#9;&#9;&#9;Wr(CHR(D DIV 10 + ORD("0"))); Wr(CHR(D MOD 10 + ORD("0"))) &#9;&#9;END &#9;END; &#9;str&#91;pos&#93; : &#61; 0X END RealToFixStr; (** Convert a string into a real. Precondition : s has a well defined real syntax. Scientific notation with D and E to indicate exponents is allowed. *) PROCEDURE StrToReal*(CONST s : ARRAY OF CHAR; VAR r : LONGREAL); VAR p, e : INTEGER; y, g : LONGREAL; neg, negE : BOOLEAN; BEGIN &#9;p : &#61; 0; &#9;WHILE (s&#91;p&#93; &#61; " ") OR (s&#91;p&#93; &#61; "0") DO INC(p) END; &#9;IF s&#91;p&#93; &#61; "-" THEN neg : &#61; TRUE; INC(p) ELSE neg : &#61; FALSE END; &#9;WHILE (s&#91;p&#93; &#61; " ") OR (s&#91;p&#93; &#61; "0") DO INC(p) END; &#9;y : &#61; 0; &#9;WHILE ("0" &#60;&#61; s&#91;p&#93;) &#38; (s&#91;p&#93; &#60;&#61; "9") DO &#9;&#9;y : &#61; y * 10 + (ORD(s&#91;p&#93;) - 30H); &#9;&#9;INC(p); &#9;END; &#9;IF s&#91;p&#93; &#61; "." THEN &#9;&#9;INC(p); g : &#61; 1; &#9;&#9;WHILE ("0" &#60;&#61; s&#91;p&#93;) &#38; (s&#91;p&#93; &#60;&#61; "9") DO &#9;&#9;&#9;g : &#61; g / 10; y : &#61; y + g * (ORD(s&#91;p&#93;) - 30H); &#9;&#9;&#9;INC(p); &#9;&#9;END; &#9;END; &#9;IF (s&#91;p&#93; &#61; "D") OR (s&#91;p&#93; &#61; "E") THEN &#9;&#9;INC(p); e : &#61; 0; &#9;&#9;IF s&#91;p&#93; &#61; "-" THEN negE : &#61; TRUE; INC(p) ELSE negE : &#61; FALSE END; &#9;&#9;WHILE (s&#91;p&#93; &#61; "0") DO INC(p) END; &#9;&#9;WHILE ("0" &#60;&#61; s&#91;p&#93;) &#38; (s&#91;p&#93; &#60;&#61; "9") DO &#9;&#9;&#9;e : &#61; e * 10 + (ORD(s&#91;p&#93;) - 30H); &#9;&#9;&#9;INC(p); &#9;&#9;END; &#9;&#9;IF negE THEN y : &#61; y / Reals.Ten(e) &#9;&#9;ELSE y : &#61; y * Reals.Ten(e) END; &#9;END; &#9;IF neg THEN y : &#61; -y END; &#9;r : &#61; y; END StrToReal; (** Convert a string into a boolean. "Yes", "True" and "On" are TRUE all other strings are FALSE. &#9;Leading white space characters are ignored. *) &#9;PROCEDURE StrToBool*(CONST str : ARRAY OF CHAR; VAR b : BOOLEAN); &#9;&#9;VAR i : LONGINT; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; (str&#91;i&#93; &#60;&#61; " ") DO &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;CASE CAP(str&#91;i&#93;) OF &#9;&#9;&#9;"Y", "T" : b : &#61; TRUE &#9;&#9;&#9;&#124;"O" : b : &#61; CAP(str&#91;i+1&#93;) &#61; "N" &#9;&#9;ELSE &#9;&#9;&#9;b : &#61; FALSE &#9;&#9;END &#9;END StrToBool; (** Convert a boolean into "Yes" or "No". *) &#9;PROCEDURE BoolToStr*(b : BOOLEAN; VAR str : ARRAY OF CHAR); &#9;BEGIN &#9;&#9;IF b THEN &#9;&#9;&#9;COPY("Yes", str) &#9;&#9;ELSE &#9;&#9;&#9;COPY("No", str) &#9;&#9;END &#9;END BoolToStr; (** Convert a string to a set *) &#160;&#160;&#160;&#160;PROCEDURE StrToSet*(CONST str : ARRAY OF CHAR; VAR set : SET); &#160;&#160;&#160;&#160;&#160;&#160;VAR i, d, d1 : LONGINT; ch : CHAR; dot : BOOLEAN; &#160;&#160;&#160;&#160;BEGIN &#160;&#160;&#160;&#160;&#160;&#160;set : &#61; &#123;&#125;; dot : &#61; FALSE; &#160;&#160;&#160;&#160;&#160;&#160;i : &#61; 0; ch : &#61; str&#91;i&#93;; &#160;&#160;&#160;&#160;&#160;&#160;WHILE (ch # 0X) &#38; (ch # "&#125;") DO &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WHILE (ch # 0X) &#38; ((ch &#60; "0") OR (ch &#62; "9")) DO INC(i); ch : &#61; str&#91;i&#93; END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IF ch &#61; 0X THEN RETURN END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;d : &#61; 0; WHILE (ch &#62;&#61; "0") &#38; (ch &#60;&#61; "9") DO d : &#61; d*10 + ORD(ch) - 30H; INC(i); ch : &#61; str&#91;i&#93; END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IF d &#60;&#61; MAX(SET) THEN INCL(set, d) END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IF dot THEN &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;d1 : &#61; 0; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WHILE (d1 &#60;&#61; MAX(SET)) &#38; (d1 &#60; d) DO INCL(set, d1); INC(d1) END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;dot : &#61; FALSE &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WHILE ch &#61; " " DO INC(i); ch : &#61; str&#91;i&#93; END; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;IF ch &#61; "." THEN d1 : &#61; d + 1; dot : &#61; TRUE END &#160;&#160;&#160;&#160;&#160;&#160;END &#160;&#160;&#160;&#160;END StrToSet; (** Convert a set to a string *) &#9;PROCEDURE SetToStr* (set : SET; VAR str : ARRAY OF CHAR); &#9;VAR i, j, k : INTEGER; noFirst : BOOLEAN; &#9;BEGIN &#9;&#9;str&#91;0&#93; : &#61; "&#123;"; i : &#61; 0; k : &#61; 1; noFirst : &#61; FALSE; &#9;&#9;WHILE i &#60;&#61; MAX(SET) DO &#9;&#9;&#9;IF i IN set THEN &#9;&#9;&#9;&#9;IF noFirst THEN str&#91;k&#93; : &#61; ","; INC(k) ELSE noFirst : &#61; TRUE END; &#9;&#9;&#9;&#9;IF i &#62;&#61; 10 THEN str&#91;k&#93; : &#61; CHR(i DIV 10 + 30H); INC(k) END; &#9;&#9;&#9;&#9;str&#91;k&#93; : &#61; CHR(i MOD 10 + 30H); INC(k); &#9;&#9;&#9;&#9;j : &#61; i; INC(i); &#9;&#9;&#9;&#9;WHILE (i &#60;&#61; MAX(SET)) &#38; (i IN set) DO INC(i) END; &#9;&#9;&#9;&#9;IF i-2 &#62; j THEN &#9;&#9;&#9;&#9;&#9;str&#91;k&#93; : &#61; "."; str&#91;k+1&#93; : &#61; "."; INC(k, 2); j : &#61; i - 1; &#9;&#9;&#9;&#9;&#9;IF j &#62;&#61; 10 THEN str&#91;k&#93; : &#61; CHR(j DIV 10 + 30H); INC(k) END; &#9;&#9;&#9;&#9;&#9;str&#91;k&#93; : &#61; CHR(j MOD 10 + 30H); INC(k) &#9;&#9;&#9;&#9;ELSE i : &#61; j &#9;&#9;&#9;&#9;END &#9;&#9;&#9;END; &#9;&#9;&#9;INC(i) &#9;&#9;END; &#9;&#9;str&#91;k&#93; : &#61; "&#125;"; str&#91;k+1&#93; : &#61; 0X &#9;END SetToStr; (** Convert date (Oberon.GetClock) into specified format. *) &#9;PROCEDURE DateToStr*(date : LONGINT; VAR str : ARRAY OF CHAR); &#9;&#9;VAR i, j, k, x : LONGINT; form, name : ARRAY 32 OF CHAR; &#9;BEGIN &#9;&#9;COPY(dateform, form); &#9;&#9;IF form &#61; "" THEN form : &#61; "DD.MM.YY" END; &#9;&#9;i : &#61; 0; j : &#61; 0; &#9;&#9;WHILE form&#91;j&#93; # 0X DO &#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "D" THEN	(* Day *) &#9;&#9;&#9;&#9;INC(j); x : &#61; date MOD 32; &#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "D" THEN &#9;&#9;&#9;&#9;&#9;INC(j); &#9;&#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "D" THEN &#9;&#9;&#9;&#9;&#9;&#9;INC(j); x : &#61; Dates.DayOfWeek(date); &#9;&#9;&#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "D" THEN INC(j); COPY(lDayName&#91;x&#93;, name) &#9;&#9;&#9;&#9;&#9;&#9;ELSE COPY(sDayName&#91;x&#93;, name) &#9;&#9;&#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;&#9;&#9;k : &#61; 0; WHILE name&#91;k&#93; # 0X DO str&#91;i&#93; : &#61; name&#91;k&#93;; INC(i); INC(k) END &#9;&#9;&#9;&#9;&#9;ELSE (* day with leading zero *) &#9;&#9;&#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;&#9;str&#91;i + 1&#93; : &#61; CHR(x MOD 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;&#9;INC(i, 2) &#9;&#9;&#9;&#9;&#9;END &#9;&#9;&#9;&#9;ELSE	(* no leading zero *) &#9;&#9;&#9;&#9;&#9;IF x &#62; 9 THEN str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); INC(i) END; &#9;&#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x MOD 10 + ORD("0")); INC(i) &#9;&#9;&#9;&#9;END &#9;&#9;&#9;ELSIF CAP(form&#91;j&#93;) &#61; "M" THEN	(* Month *) &#9;&#9;&#9;&#9;INC(j); x : &#61; date DIV 32 MOD 16; &#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "M" THEN &#9;&#9;&#9;&#9;&#9;INC(j); &#9;&#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "M" THEN &#9;&#9;&#9;&#9;&#9;&#9;INC(j); &#9;&#9;&#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "M" THEN INC(j); COPY(lMonthName&#91;x-1&#93;, name) &#9;&#9;&#9;&#9;&#9;&#9;ELSE COPY(sMonthName&#91;x-1&#93;, name) &#9;&#9;&#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;&#9;&#9;k : &#61; 0; WHILE name&#91;k&#93; # 0X DO str&#91;i&#93; : &#61; name&#91;k&#93;; INC(i); INC(k) END &#9;&#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;&#9;str&#91;i + 1&#93; : &#61; CHR(x MOD 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;&#9;INC(i, 2) &#9;&#9;&#9;&#9;&#9;END &#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;IF x &#62; 9 THEN str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); INC(i) END; &#9;&#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x MOD 10 + ORD("0")); INC(i) &#9;&#9;&#9;&#9;END &#9;&#9;&#9;ELSIF CAP(form&#91;j&#93;) &#61; "Y" THEN	(* Year *) &#9;&#9;&#9;&#9;INC(j,2); x : &#61; date DIV 512; &#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; "Y" THEN &#9;&#9;&#9;&#9;&#9;INC(j, 2); INC(x, 1900); &#9;&#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x DIV 1000 + ORD("0")); str&#91;i + 1&#93; : &#61; CHR(x DIV 100 MOD 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;str&#91;i + 2&#93; : &#61; CHR(x DIV 10 MOD 10 + ORD("0")); str&#91;i + 3&#93; : &#61; CHR(x MOD 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;INC(i, 4) &#9;&#9;&#9;&#9;ELSE &#9;&#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x DIV 10 MOD 10 + ORD("0")); str&#91;i + 1&#93; : &#61; CHR(x MOD 10 + ORD("0")); &#9;&#9;&#9;&#9;&#9;INC(i, 2) &#9;&#9;&#9;&#9;END &#9;&#9;&#9;ELSE str&#91;i&#93; : &#61; form&#91;j&#93;; INC(i); INC(j) &#9;&#9;&#9;END &#9;&#9;END; &#9;&#9;str&#91;i&#93; : &#61; 0X &#9;END DateToStr; (** Returns a month&#39;s name (set short to get the abbreviation) *) &#9;PROCEDURE MonthToStr* (month : INTEGER; VAR str : ARRAY OF CHAR; short : BOOLEAN); &#9;BEGIN &#9;&#9;month : &#61; (month - 1) MOD 12; &#9;&#9;IF short THEN COPY(sMonthName&#91;month&#93;, str) ELSE COPY(lMonthName&#91;month&#93;, str) END &#9;END MonthToStr; (** Returns a day&#39;s name (set short to get the abbreviation) *) &#9;PROCEDURE DayToStr* (day : INTEGER; VAR str : ARRAY OF CHAR; short : BOOLEAN); &#9;BEGIN &#9;&#9;IF short THEN COPY(sDayName&#91;day MOD 7&#93;, str) ELSE COPY(lDayName&#91;day MOD 7&#93;, str) END &#9;END DayToStr; (** Convert time (Oberon.GetClock) into specified format. *) &#9;PROCEDURE TimeToStr*(time : LONGINT; VAR str : ARRAY OF CHAR); &#9;&#9;VAR i, j, x, h, hPos : LONGINT; form : ARRAY 32 OF CHAR; shortH, leadingH : BOOLEAN; &#9;BEGIN &#9;&#9;COPY(timeform, form); &#9;&#9;IF form &#61; "" THEN form : &#61; "HH : MM : SS" END; &#9;&#9;i : &#61; 0; j : &#61; 0; h : &#61; time DIV 4096 MOD 32; shortH : &#61; FALSE; &#9;&#9;WHILE form&#91;j&#93; # 0X DO &#9;&#9;&#9;IF ((CAP(form&#91;j&#93;) &#61; "A") OR (CAP(form&#91;j&#93;) &#61; "P")) &#38; (CAP(form&#91;j+1&#93;) &#61; "M") THEN &#9;&#9;&#9;&#9;shortH : &#61; TRUE; &#9;&#9;&#9;&#9;IF CAP(form&#91;j&#93;) &#61; form&#91;j&#93; THEN x : &#61; 0 ELSE x : &#61; 32 END; &#9;&#9;&#9;&#9;IF (h &#60; 1) OR (h &#62; 12) THEN str&#91;i&#93; : &#61; CHR(ORD("P") + x) ELSE str&#91;i&#93; : &#61; CHR(ORD("A") + x) END; &#9;&#9;&#9;&#9;h : &#61; h MOD 12; IF h &#61; 0 THEN h : &#61; 12 END; &#9;&#9;&#9;&#9;str&#91;i + 1&#93; : &#61; CHR(ORD("M") + x); &#9;&#9;&#9;&#9;INC(i, 2); &#9;&#9;&#9;&#9;WHILE (CAP(form&#91;j&#93;) &#61; "A") OR (CAP(form&#91;j&#93;) &#61; "P") OR (CAP(form&#91;j&#93;) &#61; "M") DO INC(j) END &#9;&#9;&#9;ELSIF form&#91;j&#93; &#61; "H" THEN &#9;&#9;&#9;&#9;hPos : &#61; i; INC(i, 2); INC(j); leadingH : &#61; (form&#91;j&#93; &#61; "H"); &#9;&#9;&#9;&#9;IF leadingH THEN INC(j) END &#9;&#9;&#9;ELSIF form&#91;j&#93; &#61; "M" THEN &#9;&#9;&#9;&#9;INC(j); x : &#61; time DIV 64 MOD 64; &#9;&#9;&#9;&#9;IF form&#91;j&#93; &#61; "M" THEN str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); INC(i); INC(j) &#9;&#9;&#9;&#9;ELSIF x &#62; 9 THEN str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); INC(i) &#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x MOD 10 + ORD("0")); INC(i) &#9;&#9;&#9;ELSIF form&#91;j&#93; &#61; "S" THEN &#9;&#9;&#9;&#9;INC(j); x : &#61; time MOD 64; &#9;&#9;&#9;&#9;IF form&#91;j&#93; &#61; "S" THEN str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); INC(i); INC(j) &#9;&#9;&#9;&#9;ELSIF x &#62; 9 THEN str&#91;i&#93; : &#61; CHR(x DIV 10 + ORD("0")); INC(i) &#9;&#9;&#9;&#9;END; &#9;&#9;&#9;&#9;str&#91;i&#93; : &#61; CHR(x MOD 10 + ORD("0")); INC(i) &#9;&#9;&#9;ELSE str&#91;i&#93; : &#61; form&#91;j&#93;; INC(i); INC(j) &#9;&#9;&#9;END &#9;&#9;END; &#9;&#9;str&#91;i&#93; : &#61; 0X; &#9;&#9;IF &#126;leadingH THEN &#9;&#9;&#9;IF h &#62; 9 THEN str&#91;hPos&#93; : &#61; CHR(h DIV 10 + ORD("0")); INC(hPos) &#9;&#9;&#9;ELSE i : &#61; hPos + 1; WHILE str&#91;i&#93; # 0X DO str&#91;i&#93; : &#61; str&#91;i + 1&#93;; INC(i) END &#9;&#9;&#9;END; &#9;&#9;&#9;str&#91;hPos&#93; : &#61; CHR(h MOD 10 + ORD("0")) &#9;&#9;ELSE &#9;&#9;&#9;str&#91;hPos&#93; : &#61; CHR(h DIV 10 + ORD("0")); &#9;&#9;&#9;str&#91;hPos + 1&#93; : &#61; CHR(h MOD 10 + ORD("0")) &#9;&#9;END &#9;END TimeToStr; (** Convert a string into an time value. Leading white space characters are ignored. *) &#9;PROCEDURE StrToTime*(CONST str : ARRAY OF CHAR; VAR time : LONGINT); &#9;&#9;VAR &#9;&#9;&#9;h, m, s : LONGINT; &#9;&#9;&#9;i : INTEGER; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; ((str&#91;i&#93; &#60; "0") OR (str&#91;i&#93; &#62; "9")) DO INC(i) END; &#9;&#9;StrToIntPos(str, h, i); &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; ((str&#91;i&#93; &#60; "0") OR (str&#91;i&#93; &#62; "9")) DO INC(i) END; &#9;&#9;StrToIntPos(str, m, i); &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; ((str&#91;i&#93; &#60; "0") OR (str&#91;i&#93; &#62; "9")) DO INC(i) END; &#9;&#9;StrToIntPos(str, s, i); &#9;&#9;time : &#61; (h*64 + m)*64 + s &#9;END StrToTime; (** Convert a string into an date value. Leading white space characters are ignored. *) &#9;PROCEDURE StrToDate*(CONST str : ARRAY OF CHAR; VAR date : LONGINT); &#9;&#9;VAR &#9;&#9;&#9;d, m, y : LONGINT; &#9;&#9;&#9;i : INTEGER; &#9;BEGIN &#9;&#9;i : &#61; 0; &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; ((str&#91;i&#93; &#60; "0") OR (str&#91;i&#93; &#62; "9")) DO INC(i) END; &#9;&#9;StrToIntPos(str, d, i); &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; ((str&#91;i&#93; &#60; "0") OR (str&#91;i&#93; &#62; "9")) DO INC(i) END; &#9;&#9;StrToIntPos(str, m, i); &#9;&#9;WHILE (str&#91;i&#93; # 0X) &#38; ((str&#91;i&#93; &#60; "0") OR (str&#91;i&#93; &#62; "9")) DO INC(i) END; &#9;&#9;StrToIntPos(str, y, i); y : &#61; y-1900; &#9;&#9;date : &#61; (y*16 + m)*32 + d &#9;END StrToDate; &#9;PROCEDURE Init; &#9;&#9;VAR i : LONGINT; s : Texts.Scanner; &#9;BEGIN &#9;&#9;Oberon.OpenScanner(s, "System.DateFormat"); &#9;&#9;IF s.class &#61; Texts.String THEN COPY(s.s, dateform) ELSE dateform : &#61; "" END; &#9;&#9;Oberon.OpenScanner(s, "System.TimeFormat"); &#9;&#9;IF s.class &#61; Texts.String THEN COPY(s.s, timeform) ELSE timeform : &#61; "" END; &#9;&#9;sDayName&#91;0&#93; : &#61; "Mon";	sDayName&#91;1&#93; : &#61; "Tue";	sDayName&#91;2&#93; : &#61; "Wed";	sDayName&#91;3&#93; : &#61; "Thu"; &#9;&#9;sDayName&#91;4&#93; : &#61; "Fri";	sDayName&#91;5&#93; : &#61; "Sat";	sDayName&#91;6&#93; : &#61; "Sun"; &#9;&#9;lDayName&#91;0&#93; : &#61; "Monday";	lDayName&#91;1&#93; : &#61; "Tuesday";	lDayName&#91;2&#93; : &#61; "Wednesday";	lDayName&#91;3&#93; : &#61; "Thursday"; &#9;&#9;lDayName&#91;4&#93; : &#61; "Friday";	lDayName&#91;5&#93; : &#61; "Saturday";	lDayName&#91;6&#93; : &#61; "Sunday"; &#9;&#9;sMonthName&#91;0&#93; : &#61; "Jan"; sMonthName&#91;1&#93; : &#61; "Feb"; sMonthName&#91;2&#93; : &#61; "Mar"; sMonthName&#91;3&#93; : &#61; "Apr"; &#9;&#9;sMonthName&#91;4&#93; : &#61; "May"; sMonthName&#91;5&#93; : &#61; "Jun"; sMonthName&#91;6&#93; : &#61; "Jul"; sMonthName&#91;7&#93; : &#61; "Aug"; &#9;&#9;sMonthName&#91;8&#93; : &#61; "Sep"; sMonthName&#91;9&#93; : &#61; "Oct"; sMonthName&#91;10&#93; : &#61; "Nov"; sMonthName&#91;11&#93; : &#61; "Dec"; &#9;&#9;lMonthName&#91;0&#93; : &#61; "January"; lMonthName&#91;1&#93; : &#61; "February"; lMonthName&#91;2&#93; : &#61; "March"; lMonthName&#91;3&#93; : &#61; "April"; &#9;&#9;lMonthName&#91;4&#93; : &#61; "May"; lMonthName&#91;5&#93; : &#61; "June"; lMonthName&#91;6&#93; : &#61; "July"; lMonthName&#91;7&#93; : &#61; "August"; &#9;&#9;lMonthName&#91;8&#93; : &#61; "September"; lMonthName&#91;9&#93; : &#61; "October"; lMonthName&#91;10&#93; : &#61; "November"; &#9;&#9;lMonthName&#91;11&#93; : &#61; "December"; &#9;&#9;FOR i : &#61; 0 TO 255 DO &#9;&#9;&#9;isAlpha&#91;i&#93; : &#61; ((i &#62;&#61; ORD("A")) &#38; (i &#60;&#61; ORD("Z"))) OR ((i &#62;&#61; ORD("a")) &#38; (i &#60;&#61; ORD("z"))) &#9;&#9;END; (*		isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; &#9;&#9;isAlpha&#91;ORD("")&#93; : &#61; TRUE; isAlpha&#91;ORD("")&#93; : &#61; TRUE; *) &#9;&#9;FOR i : &#61; 0 TO 255 DO &#9;&#9;&#9;ISOToOberon&#91;i&#93; : &#61; CHR(i); OberonToISO&#91;i&#93; : &#61; CHR(i) &#9;&#9;END; &#9;&#9;ISOToOberon&#91;8&#93; : &#61; CHR(127); &#9;&#9;ISOToOberon&#91;146&#93; : &#61; CHR(39); &#9;&#9;ISOToOberon&#91;160&#93; : &#61; CHR(32); &#9;&#9;ISOToOberon&#91;162&#93; : &#61; CHR(99); &#9;&#9;ISOToOberon&#91;166&#93; : &#61; CHR(124); &#9;&#9;ISOToOberon&#91;168&#93; : &#61; CHR(34); &#9;&#9;ISOToOberon&#91;169&#93; : &#61; CHR(99); &#9;&#9;ISOToOberon&#91;170&#93; : &#61; CHR(97); &#9;&#9;ISOToOberon&#91;171&#93; : &#61; CHR(60); &#9;&#9;ISOToOberon&#91;173&#93; : &#61; CHR(45); &#9;&#9;ISOToOberon&#91;174&#93; : &#61; CHR(114); &#9;&#9;ISOToOberon&#91;175&#93; : &#61; CHR(45); &#9;&#9;ISOToOberon&#91;176&#93; : &#61; CHR(111); &#9;&#9;ISOToOberon&#91;178&#93; : &#61; CHR(50); &#9;&#9;ISOToOberon&#91;179&#93; : &#61; CHR(51); &#9;&#9;ISOToOberon&#91;180&#93; : &#61; CHR(39); &#9;&#9;ISOToOberon&#91;183&#93; : &#61; CHR(46); &#9;&#9;ISOToOberon&#91;185&#93; : &#61; CHR(49); &#9;&#9;ISOToOberon&#91;186&#93; : &#61; CHR(48); &#9;&#9;ISOToOberon&#91;187&#93; : &#61; CHR(62); &#9;&#9;ISOToOberon&#91;192&#93; : &#61; CHR(65); &#9;&#9;ISOToOberon&#91;193&#93; : &#61; CHR(65); &#9;&#9;ISOToOberon&#91;194&#93; : &#61; CHR(65); &#9;&#9;ISOToOberon&#91;195&#93; : &#61; CHR(65); &#9;&#9;ISOToOberon&#91;196&#93; : &#61; CHR(128); OberonToISO&#91;128&#93; : &#61; CHR(196); &#9;&#9;ISOToOberon&#91;197&#93; : &#61; CHR(65); &#9;&#9;ISOToOberon&#91;198&#93; : &#61; CHR(65); &#9;&#9;ISOToOberon&#91;199&#93; : &#61; CHR(67); &#9;&#9;ISOToOberon&#91;200&#93; : &#61; CHR(69); &#9;&#9;ISOToOberon&#91;201&#93; : &#61; CHR(69); &#9;&#9;ISOToOberon&#91;202&#93; : &#61; CHR(69); &#9;&#9;ISOToOberon&#91;203&#93; : &#61; CHR(69); &#9;&#9;ISOToOberon&#91;204&#93; : &#61; CHR(73); &#9;&#9;ISOToOberon&#91;205&#93; : &#61; CHR(73); &#9;&#9;ISOToOberon&#91;206&#93; : &#61; CHR(73); &#9;&#9;ISOToOberon&#91;207&#93; : &#61; CHR(73); &#9;&#9;ISOToOberon&#91;208&#93; : &#61; CHR(68); &#9;&#9;ISOToOberon&#91;209&#93; : &#61; CHR(78); &#9;&#9;ISOToOberon&#91;210&#93; : &#61; CHR(79); &#9;&#9;ISOToOberon&#91;211&#93; : &#61; CHR(79); &#9;&#9;ISOToOberon&#91;212&#93; : &#61; CHR(79); &#9;&#9;ISOToOberon&#91;213&#93; : &#61; CHR(79); &#9;&#9;ISOToOberon&#91;214&#93; : &#61; CHR(129); OberonToISO&#91;129&#93; : &#61; CHR(214); &#9;&#9;ISOToOberon&#91;215&#93; : &#61; CHR(42); &#9;&#9;ISOToOberon&#91;216&#93; : &#61; CHR(79); &#9;&#9;ISOToOberon&#91;217&#93; : &#61; CHR(85); &#9;&#9;ISOToOberon&#91;218&#93; : &#61; CHR(85); &#9;&#9;ISOToOberon&#91;219&#93; : &#61; CHR(85); &#9;&#9;ISOToOberon&#91;220&#93; : &#61; CHR(130); OberonToISO&#91;130&#93; : &#61; CHR(220); &#9;&#9;ISOToOberon&#91;221&#93; : &#61; CHR(89); &#9;&#9;ISOToOberon&#91;222&#93; : &#61; CHR(80); &#9;&#9;ISOToOberon&#91;223&#93; : &#61; CHR(150); OberonToISO&#91;150&#93; : &#61; CHR(223); &#9;&#9;ISOToOberon&#91;224&#93; : &#61; CHR(139); OberonToISO&#91;139&#93; : &#61; CHR(224); &#9;&#9;ISOToOberon&#91;225&#93; : &#61; CHR(148); OberonToISO&#91;148&#93; : &#61; CHR(225); &#9;&#9;ISOToOberon&#91;226&#93; : &#61; CHR(134); OberonToISO&#91;134&#93; : &#61; CHR(226); &#9;&#9;ISOToOberon&#91;227&#93; : &#61; CHR(97); &#9;&#9;ISOToOberon&#91;228&#93; : &#61; CHR(131); OberonToISO&#91;131&#93; : &#61; CHR(228); &#9;&#9;ISOToOberon&#91;229&#93; : &#61; CHR(97); &#9;&#9;ISOToOberon&#91;230&#93; : &#61; CHR(97); &#9;&#9;ISOToOberon&#91;231&#93; : &#61; CHR(147); OberonToISO&#91;147&#93; : &#61; CHR(231); &#9;&#9;ISOToOberon&#91;232&#93; : &#61; CHR(140); OberonToISO&#91;140&#93; : &#61; CHR(232); &#9;&#9;ISOToOberon&#91;233&#93; : &#61; CHR(144); OberonToISO&#91;144&#93; : &#61; CHR(233); &#9;&#9;ISOToOberon&#91;234&#93; : &#61; CHR(135); OberonToISO&#91;135&#93; : &#61; CHR(234); &#9;&#9;ISOToOberon&#91;235&#93; : &#61; CHR(145); OberonToISO&#91;145&#93; : &#61; CHR(235); &#9;&#9;ISOToOberon&#91;236&#93; : &#61; CHR(141); OberonToISO&#91;141&#93; : &#61; CHR(236); &#9;&#9;ISOToOberon&#91;237&#93; : &#61; CHR(105); &#9;&#9;ISOToOberon&#91;238&#93; : &#61; CHR(136); OberonToISO&#91;136&#93; : &#61; CHR(238); &#9;&#9;ISOToOberon&#91;239&#93; : &#61; CHR(146); OberonToISO&#91;146&#93; : &#61; CHR(239); &#9;&#9;ISOToOberon&#91;240&#93; : &#61; CHR(100); &#9;&#9;ISOToOberon&#91;241&#93; : &#61; CHR(149); OberonToISO&#91;149&#93; : &#61; CHR(241); &#9;&#9;ISOToOberon&#91;242&#93; : &#61; CHR(142); OberonToISO&#91;142&#93; : &#61; CHR(242); &#9;&#9;ISOToOberon&#91;243&#93; : &#61; CHR(111); &#9;&#9;ISOToOberon&#91;244&#93; : &#61; CHR(137); OberonToISO&#91;137&#93; : &#61; CHR(244); &#9;&#9;ISOToOberon&#91;245&#93; : &#61; CHR(111); &#9;&#9;ISOToOberon&#91;246&#93; : &#61; CHR(132); OberonToISO&#91;132&#93; : &#61; CHR(246); &#9;&#9;ISOToOberon&#91;248&#93; : &#61; CHR(111); &#9;&#9;ISOToOberon&#91;249&#93; : &#61; CHR(143); OberonToISO&#91;143&#93; : &#61; CHR(249); &#9;&#9;ISOToOberon&#91;250&#93; : &#61; CHR(117); &#9;&#9;ISOToOberon&#91;251&#93; : &#61; CHR(138); OberonToISO&#91;138&#93; : &#61; CHR(251); &#9;&#9;ISOToOberon&#91;252&#93; : &#61; CHR(133); OberonToISO&#91;133&#93; : &#61; CHR(252); &#9;&#9;ISOToOberon&#91;253&#93; : &#61; CHR(121); &#9;&#9;ISOToOberon&#91;254&#93; : &#61; CHR(112); &#9;&#9;ISOToOberon&#91;255&#93; : &#61; CHR(121); &#9;&#9;CRLF&#91;0&#93; : &#61; CR; CRLF&#91;1&#93; : &#61; LF; CRLF&#91;2&#93; : &#61; 0X; CRLF&#91;3&#93; : &#61; 0X &#9;END Init; BEGIN &#9;Init END Strings.