DEFINITION MODULE String;
(*
    Title: 	String - Definitions
    LastEdit:   "Fri May 25 13:52:15 1984"
    Author: 	jd/mjj
		Cambridge University Computer Laboratory;
                Hacked by LDS, Acorn Computers.
*)

(*
  This Module manages three kinds of 'string':
    STRINGs, ARRAYs OF CHAR and Literals (enclosed by " ").
  These are denoted in abbreviated form by S, C and L respectively.
   
  STRINGs are represented as pointers to character arrays, in which
  the last significant character of the string is followed by
  EndStringCh. Contortions are gone through when the string is
  actually allocated to ensure that a minimum of space is used.
  It is thus meaningless and dangerous to deference such a pointer 
  and use the object in an array context.
  
  ARRAYs of CHAR passed to String are assumed to be of exact length, or
  to be terminated by an EndStringCh.
  
  Literals are the obvious thing.
  
  In the following, the last one or two capital letters of the procedure
  names denote the type(s) of the most significant parameters. Thus
  CopyCS is copy from ARRAY OF CHAR to STRING.
  
  Most 'to STRING' procedures allocate a new STRING to hold the result.
  For uniformity, all of these are FUNCTIONs returning a type STRING.
  
*)

IMPORT SYSTEMTYPES;

EXPORT QUALIFIED

(* TYPEs *)	STRING, COMPARISON,

(* CONSTs *)    EndStringCh,
                EQ, LT, GT,              (* synonyms *)

(* PROCs *)	New, Dispose,            (* STRING creation and destruction *)

	        LengthS, LengthC,        (* Length functions *)
		
                FindS, FindC,            (* CHAR finding procedures *)
		
		(* concatenation and copying functions *)
	        CopyCS,    CopySC,    CopyLS,    CopyLC,
	        CopyCC,    CopySS,    ConcatSS,
                AppendCS,  AppendCC,  AppendLS,  AppendLC,
                PrependCS, PrependCC, PrependLS, PrependLC,

                (* Comparison functions *)
	        CompareSS, CompareCC, CompareCS, CompareLS, CompareLC,
                EqualSS, EqualCC, EqualCS, EqualLS, EqualLC,

                (* sub-string extraction functions *)
	        ExtractCC, ExtractCS, ExtractSC, ExtractSS;
        
TYPE      STRING = SYSTEMTYPES.STRING;
TYPE  COMPARISON = (equal, less, greater);

CONST EndStringCh = 0C;
               EQ = equal;
               LT = less;
               GT = greater;

(*  All procedures which return results of type STRING
    generate new instances.  Those which take VAR STRING
    arguments update the argument to be the modified string,
    which may or may not be a new instance.
*)

PROCEDURE New(n : CARDINAL) : STRING;
(* create a string which can hold 'n' characters excluding the terminator. *)

PROCEDURE Dispose (VAR s: STRING);
(*  destroys 's', and updates s to NIL. *)

PROCEDURE LengthS(s : STRING) : CARDINAL;
PROCEDURE LengthC(VAR s : ARRAY OF CHAR) : CARDINAL;
		
PROCEDURE FindS(s : STRING;  ch : CHAR;  VAR index : CARDINAL) : BOOLEAN;
PROCEDURE FindC(VAR s: ARRAY OF CHAR; ch: CHAR; VAR index: CARDINAL): BOOLEAN;
(*  searches 's' from the 'index' position, returning TRUE if 'ch'
    is found and setting 'index' to the associated position.
    The first element of the string is at 'index=0'.
*)

PROCEDURE CopyCS(VAR a : ARRAY OF CHAR) : STRING;
(*  turns 'a' into a STRING. Each call generates a unique instance. *)

PROCEDURE CopySC(s : STRING;  VAR chars : ARRAY OF CHAR);
(*  the reverse of 'New', in that 'chars' contains those bytes in 's',
    including EndStringCh.  This function should be used in preference
    to dereferencing 's', when wishing to call a procedure which reqires
    an ARRAY OF CHAR as argument. It's too bad it can't be a function.
*)

PROCEDURE CopyLS(literal : ARRAY OF CHAR) : STRING;
(*  turns 'literal' into a STRING. Each call generates a unique instance. *)

PROCEDURE CopyLC(literal : ARRAY OF CHAR;  VAR chars : ARRAY OF CHAR);
(* copy literal to chars and add EndStringCh if space permits *)

PROCEDURE CopyCC(VAR chars1, chars2 : ARRAY OF CHAR);

PROCEDURE CopySS(s : STRING) : STRING;
(* create a new instance of s *)

(* The following procedures provide a complete set of concatenation *)
(* primitives for {S,L,C} + S -> S and {S,L,C} + C -> C             *)

PROCEDURE ConcatSS(s1, s2 : STRING) : STRING;
(* Concatenate s1 and s2 in the given order to create a new result. Either *)
(* of s1 and s2 may be NIL: ConcatSS(Nil,s) is identical to CopySS(s).     *)
PROCEDURE AppendCS(VAR chars : ARRAY OF CHAR;  s : STRING) : STRING;
PROCEDURE AppendCC(VAR chars1, chars2 : ARRAY OF CHAR);
PROCEDURE AppendLS(literal : ARRAY OF CHAR;  s : STRING) : STRING;
PROCEDURE AppendLC(literal : ARRAY OF CHAR;  VAR chars : ARRAY OF CHAR);
PROCEDURE PrependCS(VAR chars : ARRAY OF CHAR;  s : STRING) : STRING; 
PROCEDURE PrependCC(VAR chars1, chars2 : ARRAY OF CHAR);     
PROCEDURE PrependLS(literal : ARRAY OF CHAR;  s : STRING) : STRING;
PROCEDURE PrependLC(literal : ARRAY OF CHAR;  VAR chars : ARRAY OF CHAR);

(* *** comparison and equality primitives *** *)

PROCEDURE CompareSS(s1, s2 : STRING) : COMPARISON;
PROCEDURE CompareCC(VAR chars1, chars2 : ARRAY OF CHAR) : COMPARISON;
PROCEDURE CompareCS(VAR chars : ARRAY OF CHAR;  s : STRING) : COMPARISON;
PROCEDURE CompareLS(literal : ARRAY OF CHAR;  s : STRING) : COMPARISON;
PROCEDURE CompareLC(literal : ARRAY OF CHAR;
                    VAR chars : ARRAY OF CHAR) : COMPARISON;

PROCEDURE EqualSS(s1, s2 : STRING) : BOOLEAN;
PROCEDURE EqualCC(VAR chars1, chars2 : ARRAY OF CHAR) : BOOLEAN;
PROCEDURE EqualCS(VAR chars : ARRAY OF CHAR;  s : STRING) : BOOLEAN;
PROCEDURE EqualLS(literal : ARRAY OF CHAR;  s : STRING) : BOOLEAN;
PROCEDURE EqualLC(literal : ARRAY OF CHAR;
                    VAR chars : ARRAY OF CHAR) : BOOLEAN;

(*------------------------------------------------------------------------*)
(*                *** sub-string Extraction primitives ***                *)
(*   In each case, the result is source[i], from <= i < to.  NOTE: the to *)
(*   bound is NOT included. This is essential if from and to are to be of *)
(*   CARDINAL type AND a leading null string is to be extractable.        *)
(*------------------------------------------------------------------------*)

PROCEDURE ExtractCC(VAR source : ARRAY OF CHAR;  from, to : CARDINAL;
                                      VAR destination : ARRAY OF CHAR);
PROCEDURE ExtractCS(VAR source : ARRAY OF CHAR;  from, to : CARDINAL): STRING;
PROCEDURE ExtractSC(source : STRING;  from, to : CARDINAL;
                                      VAR destination : ARRAY OF CHAR);

PROCEDURE ExtractSS(source : STRING;  from, to : CARDINAL) : STRING;

END String.
