mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-04-06 18:02:25 +00:00
181 lines
5.8 KiB
Modula-2
181 lines
5.8 KiB
Modula-2
(* $Id: OakStrings.Mod,v 1.3 1999/10/03 11:44:53 ooc-devel Exp $ *)
|
|
MODULE oocOakStrings;
|
|
(* Oakwood compliant string manipulation facilities.
|
|
Copyright (C) 1998, 1999 Michael van Acken
|
|
|
|
This module is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public License
|
|
as published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This module 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
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with OOC. If not, write to the Free Software Foundation,
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*)
|
|
(* see also [Oakwood Guidelines, revision 1A]
|
|
Module Strings provides a set of operations on strings (i.e., on string
|
|
constants and character arrays, both of wich contain the character 0X as a
|
|
terminator). All positions in strings start at 0.
|
|
|
|
Remarks
|
|
String assignments and string comparisons are already supported by the language
|
|
Oberon-2.
|
|
*)
|
|
|
|
PROCEDURE Length* (s: ARRAY OF CHAR): INTEGER;
|
|
(* Returns the number of characters in s up to and excluding the first 0X. *)
|
|
VAR
|
|
i: INTEGER;
|
|
BEGIN
|
|
i := 0;
|
|
WHILE (s[i] # 0X) DO
|
|
INC (i)
|
|
END;
|
|
RETURN i
|
|
END Length;
|
|
|
|
PROCEDURE Insert* (src: ARRAY OF CHAR; pos: INTEGER; VAR dst: ARRAY OF CHAR);
|
|
(* Inserts the string src into the string dst at position pos (0<=pos<=
|
|
Length(dst)). If pos=Length(dst), src is appended to dst. If the size of
|
|
dst is not large enough to hold the result of the operation, the result is
|
|
truncated so that dst is always terminated with a 0X. *)
|
|
VAR
|
|
lenSrc, lenDst, maxDst, i: INTEGER;
|
|
BEGIN
|
|
lenDst := Length (dst);
|
|
lenSrc := Length (src);
|
|
maxDst := SHORT (LEN (dst))-1;
|
|
IF (pos+lenSrc < maxDst) THEN
|
|
IF (lenDst+lenSrc > maxDst) THEN
|
|
(* 'dst' too long, truncate it *)
|
|
lenDst := maxDst-lenSrc;
|
|
dst[lenDst] := 0X
|
|
END;
|
|
(* 'src' is inserted inside of 'dst', move tail section *)
|
|
FOR i := lenDst TO pos BY -1 DO
|
|
dst[i+lenSrc] := dst[i]
|
|
END
|
|
ELSE
|
|
dst[maxDst] := 0X;
|
|
lenSrc := maxDst-pos
|
|
END;
|
|
(* copy characters from 'src' to 'dst' *)
|
|
FOR i := 0 TO lenSrc-1 DO
|
|
dst[pos+i] := src[i]
|
|
END
|
|
END Insert;
|
|
|
|
PROCEDURE Append* (s: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR);
|
|
(* Has the same effect as Insert(s, Length(dst), dst). *)
|
|
VAR
|
|
sp, dp, m: INTEGER;
|
|
BEGIN
|
|
m := SHORT (LEN(dst))-1; (* max length of dst *)
|
|
dp := Length (dst); (* append s at position dp *)
|
|
sp := 0;
|
|
WHILE (dp < m) & (s[sp] # 0X) DO (* copy chars from s to dst *)
|
|
dst[dp] := s[sp];
|
|
INC (dp);
|
|
INC (sp)
|
|
END;
|
|
dst[dp] := 0X (* terminate dst *)
|
|
END Append;
|
|
|
|
PROCEDURE Delete* (VAR s: ARRAY OF CHAR; pos, n: INTEGER);
|
|
(* Deletes n characters from s starting at position pos (0<=pos<=Length(s)).
|
|
If n>Length(s)-pos, the new length of s is pos. *)
|
|
VAR
|
|
lenStr, i: INTEGER;
|
|
BEGIN
|
|
lenStr := Length (s);
|
|
IF (pos+n < lenStr) THEN
|
|
FOR i := pos TO lenStr-n DO
|
|
s[i] := s[i+n]
|
|
END
|
|
ELSE
|
|
s[pos] := 0X
|
|
END
|
|
END Delete;
|
|
|
|
PROCEDURE Replace* (src: ARRAY OF CHAR; pos: INTEGER; VAR dst: ARRAY OF CHAR);
|
|
(* Has the same effect as Delete(dst, pos, Length(src)) followed by an
|
|
Insert(src, pos, dst). *)
|
|
VAR
|
|
sp, maxDst: INTEGER;
|
|
addNull: BOOLEAN;
|
|
BEGIN
|
|
maxDst := SHORT (LEN (dst))-1; (* max length of dst *)
|
|
addNull := FALSE;
|
|
sp := 0;
|
|
WHILE (src[sp] # 0X) & (pos < maxDst) DO (* copy chars from src to dst *)
|
|
(* set addNull=TRUE if we write over the end of dst *)
|
|
addNull := addNull OR (dst[pos] = 0X);
|
|
dst[pos] := src[sp];
|
|
INC (pos);
|
|
INC (sp)
|
|
END;
|
|
IF addNull THEN
|
|
dst[pos] := 0X (* terminate dst *)
|
|
END
|
|
END Replace;
|
|
|
|
PROCEDURE Extract* (src: ARRAY OF CHAR; pos, n: INTEGER; VAR dst: ARRAY OF CHAR);
|
|
(* Extracts a substring dst with n characters from position pos (0<=pos<=
|
|
Length(src)) in src. If n>Length(src)-pos, dst is only the part of src from
|
|
pos to the end of src, i.e. Length(src)-1. If the size of dst is not large
|
|
enough to hold the result of the operation, the result is truncated so that
|
|
dst is always terminated with a 0X. *)
|
|
VAR
|
|
i: INTEGER;
|
|
BEGIN
|
|
(* set n to Max(n, LEN(dst)-1) *)
|
|
IF (n > LEN(dst)) THEN
|
|
n := SHORT (LEN(dst))-1
|
|
END;
|
|
(* copy upto n characters into dst *)
|
|
i := 0;
|
|
WHILE (i < n) & (src[pos+i] # 0X) DO
|
|
dst[i] := src[pos+i];
|
|
INC (i)
|
|
END;
|
|
dst[i] := 0X
|
|
END Extract;
|
|
|
|
PROCEDURE Pos* (pat, s: ARRAY OF CHAR; pos: INTEGER): INTEGER;
|
|
(* Returns the position of the first occurrence of pat in s. Searching starts
|
|
at position pos. If pat is not found, -1 is returned. *)
|
|
VAR
|
|
posPat: INTEGER;
|
|
BEGIN
|
|
posPat := 0;
|
|
LOOP
|
|
IF (pat[posPat] = 0X) THEN (* reached end of pattern *)
|
|
RETURN pos-posPat
|
|
ELSIF (s[pos] = 0X) THEN (* end of string (but not of pattern) *)
|
|
RETURN -1
|
|
ELSIF (s[pos] = pat[posPat]) THEN (* characters identic, compare next one *)
|
|
INC (pos); INC (posPat)
|
|
ELSE (* difference found: reset indices and restart *)
|
|
pos := pos-posPat+1; posPat := 0
|
|
END
|
|
END
|
|
END Pos;
|
|
|
|
PROCEDURE Cap* (VAR s: ARRAY OF CHAR);
|
|
(* Replaces each lower case letter with s by its upper case equivalent. *)
|
|
VAR
|
|
i: INTEGER;
|
|
BEGIN
|
|
i := 0;
|
|
WHILE (s[i] # 0X) DO
|
|
s[i] := CAP (s[i]);
|
|
INC (i)
|
|
END
|
|
END Cap;
|
|
|
|
END oocOakStrings.
|