(*---------------------------------------------------------------------------
    :Program.    Strings.mod
    :Author.     ??? backtranslated Bernd Preusing
    :Address.    Gerhardstr. 16  D-2200 Elmshorn
    :Phone.      04121/22486
    :Shortcut.   [bep]
    :Version.    
    :Date.       Oct-88
    :Copyright.  M2Amiga
    :Language.   Modula-II
    :Translator. M2Amiga
    :Imports.    
    :UpDate.     
    :Contents.   
    :Remark.     no bugs
---------------------------------------------------------------------------*)
IMPLEMENTATION MODULE Strings;

PROCEDURE Length(VAR str: ARRAY OF CHAR): INTEGER;
VAR cnt: INTEGER;
BEGIN
  FOR cnt:=0 TO HIGH(str) DO
    IF str[cnt]=0C THEN
      RETURN cnt
    END;
  END;
  RETURN HIGH(str)+1
END Length;

PROCEDURE Occurs(VAR str: ARRAY OF CHAR; from: INTEGER;
		 token: ARRAY OF CHAR;
		 caseSens: BOOLEAN): INTEGER;
VAR
  len,pos,occ: INTEGER;
  ch:CHAR;
BEGIN (* Ich glaube, lieber nicht, wenn ich das sehe! *)
  IF token[0]=0C THEN
    RETURN from
  END;
  len:=Length(token);
  IF (from>HIGH(str)) OR ((len-1)>HIGH(str)) OR (from<0) THEN
    RETURN last
  END;
  FOR pos:=0 TO from DO
    IF str[pos]=0C THEN
      RETURN last
    END;
  END;
  IF caseSens THEN
    ch:=token[0]
  ELSE
    ch:=CAP(token[0])
  END;
  FOR pos:=from TO HIGH(str)-len+1 DO
    IF str[pos]=0C THEN
      RETURN last
    END;
    IF caseSens THEN
      IF str[pos]=ch THEN
        occ:=1;
	LOOP
	  IF occ>=len THEN RETURN pos END;
	  IF str[pos+occ]#token[occ] THEN EXIT END;
	  INC(occ)
	END; (* loop *)
      END;
    ELSE
      IF CAP(str[pos])=ch THEN
	occ:=1;
	LOOP
	  IF occ>=len THEN RETURN pos END;
	  IF CAP(str[pos+occ])#CAP(token[occ]) THEN EXIT END;
	  INC(occ)
	END;
      END
    END (* if casesens *)
  END; (* for pos *)
  RETURN last 
END Occurs; (* Gott sei Dank! *)

PROCEDURE Insert(VAR str: ARRAY OF CHAR; at: INTEGER; token: ARRAY OF CHAR);
VAR TokenLength,StrLength,MaxStrLength,LastPos,i :INTEGER;
BEGIN
  TokenLength:=Length(token);
  StrLength:=Length(str);
  MaxStrLength:=HIGH(str)+1;

  IF at=last THEN
    at:=StrLength
  ELSIF at<first THEN
    RETURN
  ELSIF at>StrLength THEN
    IF at>HIGH(str) THEN at:=MaxStrLength END;
    FOR i:=StrLength TO at-1 DO
      str[i]:=' '
    END;
    IF at<=HIGH(str) THEN str[at]:=0C END;
    StrLength:=at;
  END;

  IF TokenLength>0 THEN
    LastPos:=StrLength+TokenLength-1;
    IF LastPos>HIGH(str) THEN LastPos:=HIGH(str) END;
    IF at<StrLength THEN
      FOR i:=LastPos TO at+TokenLength BY -1 DO
          str[i]:=str[i-TokenLength]
      END;
    END;
    IF TokenLength>(MaxStrLength-at) THEN
      TokenLength:=MaxStrLength-at
    ELSE
      IF LastPos<HIGH(str) THEN
	str[LastPos+1]:=0C
      END;
    END;
    FOR i:=0 TO TokenLength-1 DO
      str[i+at]:=token[i]
    END;
  END
END Insert;

PROCEDURE Delete(VAR str: ARRAY OF CHAR; start,length: INTEGER);
VAR len,pos:INTEGER;
BEGIN
  IF (start<0) OR (length<=0) THEN
    RETURN
  END;
  len:=Length(str);
  IF (start<len) AND (length>0) THEN
    IF length>=(len-start) THEN
      str[start]:=0C
    ELSE
      FOR pos:=start TO len-length-1 DO
	  str[pos]:=str[pos+length]
      END;
      str[len-length]:=0C
    END
  END;
END Delete;

PROCEDURE Copy(VAR str: ARRAY OF CHAR; source: ARRAY OF CHAR;
		start, length: INTEGER);
VAR i,len: INTEGER;
BEGIN
  IF (start>HIGH(source)) OR (length<=0) OR (start<0) THEN
    str[0]:=0C
  ELSE
    IF start>0 THEN
      FOR i:=0 TO start-1 DO
        IF source[i]=0C THEN
	  str[0]:=0C;
	  RETURN
	END;
      END;
    END;
    len:=HIGH(str)+1;
    IF length>len THEN length:=len END;
    i:=HIGH(source)-start+1;
    IF length>i THEN length:=i END;
    FOR i:=0 TO length-1 DO
      str[i]:=source[start+i];
      IF str[i]=0C THEN RETURN END;
    END;
    IF length<len THEN
      str[length]:=0C
    END
  END
END Copy;

PROCEDURE Compare(VAR str: ARRAY OF CHAR; start,length: INTEGER;
		token:ARRAY OF CHAR; caseSens:BOOLEAN): INTEGER;
VAR a,b,c,d:INTEGER; ch1,ch2:CHAR;
BEGIN
  IF (start<0) OR (length<0) THEN
    RETURN 0
  END;
  a:=0;
  b:=start;
  c:=start+length;
  d:=Length(str);
  IF d<c THEN c:=d END;
  LOOP
    IF b>=c THEN
      IF (a>HIGH(token)) OR (token[a]=0C) THEN
        RETURN 0
      ELSE
        RETURN a+1
      END;
    ELSE
      IF a>HIGH(token) THEN
        RETURN -(a+1)
      END;
    END;
    ch2:=token[a];
    IF caseSens THEN
      ch1:=str[b]
    ELSE
      ch1:=CAP(str[b]);
      ch2:=CAP(ch2)
    END;
    INC(a);
    INC(b);
    IF ch1>ch2 THEN
      RETURN -a
    ELSIF ch1<ch2 THEN
      RETURN a
    ELSIF  ch1=0C THEN
      RETURN 0
    END;
  END; (* LOOP *)
END Compare;

END Strings.mod
