ETHZ_Logo RAMSES_Logo_Right   RAMSES   RAMSES_Logo_Left Systems Ecology  
Start    search button      Modules:   A-Z   Function   Layer        QuickRefs:   DM   AuxLib   AuxLibE   SciLib   EasyMW   MW   ISIS   RMSLib

DEFINITION MODULE DMStrings;

  (*******************************************************************

    Module  DMStrings     ('Dialog Machine' DM_V3.0)

      Copyright (c) 1987-2006 by Andreas Fischlin and ETH Zurich.

    Purpose   Provides string handling as required
              by the 'Dialog Machine'.

    Remarks   This module belongs to the 'Dialog Machine'.


    Programming

      o Design
        Andreas Fischlin          17/03/1987

      o Implementation
        Andreas Fischlin          17/03/1987


    ETH Zurich
    Systems Ecology
    CHN E 35.1
    Universitaetstrasse 16
    8092 Zurich
    SWITZERLAND

    URLs:
        <mailto:RAMSES@env.ethz.ch>
        <http://www.sysecol.ethz.ch>
        <http://www.sysecol.ethz.ch/SimSoftware/RAMSES>


    Last revision of definition:  30/01/1992  AF

  *******************************************************************)


  TYPE
    String;
    StringRelation = ( smaller, equal, greater );


  VAR
    notAllocatedStr: String;
    (*
      Read only variable which may be used for variables of type
      String to denote that no memory has yet been allocated for
      that string, i.e. NewString has never been called.  It is a
      good programming practice to assign this value to all string
      variables during the initialization phase.
    *)

    ResourceStringsDone: BOOLEAN;
    (*
      Read only variable returning the success of the routines
      LoadString, GetRString, and StoreString
    *)


  (**********************************)
  (*#####   Ordinary Strings   #####*)
  (**********************************)

  (*----------------------*)
  (*=====   Basics   =====*)
  (*----------------------*)

  PROCEDURE Length(VAR string: ARRAY OF CHAR): INTEGER;
    (*VAR parameter only for speed-up reasons*)


  (*-----------------------------------*)
  (*=====   Assignment, Copying   =====*)
  (*-----------------------------------*)

  PROCEDURE AssignString(s: ARRAY OF CHAR; VAR d: ARRAY OF CHAR);
    (*assign source string s to destination string d*)

  PROCEDURE CopyString (VAR from: ARRAY OF CHAR;   i1,nrChs: INTEGER;
                        VAR to: ARRAY OF CHAR; VAR i2: INTEGER);
  (*
    Efficient, versatile, general purpose string copying routine.
    Copies the content of string 'from' beginning with position i1
    into string 'to' by starting the writing process at position i2
    in the destination string 'to'.  String 'from' is passed as var
    parameter only for speed-up reasons, otherwise it is left
    untouched.  In case that nrChs<0 then the copy process stops as
    soon 0C is encountered in string 'from' or if 'from's upper
    boundary is encountered. In case that nrChs>=0 the copy process
    stops after nrChs characters have been copied or if 'from's
    upper boundary is encountered.  Whenever possible the
    destination string 'to' is always properly terminated with a 0C
    character (even if no copying should have taken place). After
    the call i2 points to the char in string 'to' which contains
    the termination char 0C (or beyond its range if the string 'to'
    is too short to hold 0C). Hence this routine may be easily used
    for string assignments or consecutive concatenations.
  *)

  PROCEDURE CopyStr( from: String; VAR to: String );
  (*
    Given 'from' does point to an existing string, this procedure
    creates a new storage for this string in memory, copies the content
    of the string 'from' to this new location, and returns the pointer
    'to'.  Otherwise the returned pointer 'to' points to an empty
    string ('to' differs always from 'notAllocatedStr').
  *)

  PROCEDURE Copy(from: ARRAY OF CHAR; startIndex, nrOfChars: INTEGER;
                 VAR to: ARRAY OF CHAR);
  (*
    Copies nrOfChars characters from string from starting at index
    position in from of value startIndex into the string to (Mainly
    provided for IBM PC DM compatibility.  See also CopyString).
  *)


  (*-------------------------*)
  (*=====   Appending   =====*)
  (*-------------------------*)

  PROCEDURE Append(VAR dest: ARRAY OF CHAR; s: ARRAY OF CHAR);
    (*append string s at end of destination string dest*)

  PROCEDURE AppendCh(VAR dest: ARRAY OF CHAR; ch: CHAR);
    (*append character ch at end of destination string dest*)


  (*-----------------------------*)
  (*=====   Concatenation   =====*)
  (*-----------------------------*)

  PROCEDURE Concatenate(first,second: ARRAY OF CHAR; VAR result: ARRAY OF CHAR);
    (*Concatenates the strings first and second to the string result *)


  (*-------------------------------------*)
  (*=====   Extracting Substrings   =====*)
  (*-------------------------------------*)

  PROCEDURE ExtractSubString(VAR curPosInSrcS: INTEGER;
                             VAR srcS,destS: ARRAY OF CHAR;
                             delimiter: CHAR);
    (*
      Extracts string destS from source string srcS starting with char
      position curPosInSrcS and stopping with extraction upon
      encountering the delimiter.  After a successful extraction
      curPosInSrcS points on the first character after the delimiter
      found.  If no more strings can be extracted desS becomes the nul
      string and curPosInSrcS returns the value atend (=MAX(INTEGER)).
      A typical usage would be to extract in a sequence the sub
      strings delimited by "|" from a source string srcS like
      "Yes|No|Cancel".  If no empty string elements are expected in
      srcS, the termination condition of the extracting loop is
      destS[0] = 0C.  E.g. with the following code fragment:

        i := 0; ExtractSubString(i,srcS,destS,"|");
        WHILE destS[0]<>0C DO
          Process(destS);
          ExtractSubString(i,srcS,destS,"|");
        END(*WHILE*);

      However, if empty elements may be present it is better to test
      for curPosInSrcS = atend.  E.g.  with the following code:

        i := 0;
        REPEAT
          ExtractSubString(i,srcS,destS,"|");
          Process(destS);
        UNTIL i=atend;

    *)


  (*******************************************)
  (*#####   Dynamic String Management   #####*)
  (*******************************************)

  (*-----------------------------*)
  (*=====   Instantiation   =====*)
  (*-----------------------------*)

  (*strings are dynamically managed, i.e. stored in heap*)

  PROCEDURE AllocateStr(VAR strRef: String; s: ARRAY OF CHAR);
    (*
      Allocate memory and store string s, a reference is returned
      pointing to the string which is NIL if no more memory is
      available.
    *)

  PROCEDURE NewString(VAR(*speed-up*) s: ARRAY OF CHAR): String;
    (* same functionality as AllocateStr *)



  PROCEDURE DeallocateStr(VAR strRef: String);
    (*
      Dispose of memory which has been allocated for string
      storing.
    *)

  (*--------------------------*)
  (*=====   Assignment   =====*)
  (*--------------------------*)

  PROCEDURE SetStr   (VAR strRef: String;     s: ARRAY OF CHAR);
    (*
      Overwrite string pointed at by strRef with new value s.
      IMPORTANT NOTE: Since the previously allocated memory could
      be insufficient in case that s is longer than what was held
      by strRef, the value of strRef may change when calling
      SetStr.
    *)

  PROCEDURE PutString(VAR strRef: String; VAR s: ARRAY OF CHAR);


  (*-------------------------*)
  (*=====   Retrieval   =====*)
  (*-------------------------*)

  PROCEDURE GetStr(strRef: String; VAR s: ARRAY OF CHAR);
    (*retrieve string s pointed at by strRef*)

  PROCEDURE StrLength(strRef: String): INTEGER;

  PROCEDURE StrLevel(strRef: String): CARDINAL;
    (*
      Returns the level of the sub-program on which the string
      strRef has been created. If the string does not exist
      DMSystem.startUpLevel-1, i.e. 0 is returned.
    *)

  (*-------------------------*)
  (*=====   Appending   =====*)
  (*-------------------------*)

  PROCEDURE AppendStr(VAR destStrRef: String; s: ARRAY OF CHAR);
    (*append source string s at end of destination string destStrRef*)

  PROCEDURE AppendChr(VAR destStrRef: String; ch: CHAR);
    (*append character ch at end of destination string destStrRef*)



  (**********************************)
  (*#####   String Relations   #####*)
  (**********************************)

  PROCEDURE CompareStrings( s1,s2: ARRAY OF CHAR): StringRelation;
  PROCEDURE CompVarStrings( VAR a, b: ARRAY OF CHAR): StringRelation;
  PROCEDURE CompStr( VAR a: ARRAY OF CHAR;  bS: String): StringRelation;
   (*
     All three procedures do basically the same, but differ in
     respect to their parameters; e.g. CompVarStrings has VAR
     parameters only to increase performance. The standard function
     ORD(CHAR) is used to determine the relation and the comparison is
     made case sensitive.
   *)



  (**********************************)
  (*#####   Substring Search   #####*)
  (**********************************)


  PROCEDURE FindInString (VAR theString: ARRAY OF CHAR; searchStr: ARRAY OF CHAR;
                          VAR firstCh,lastCh: INTEGER): BOOLEAN;
  (*
    Finds in string theString (var paramater only for speed-up
    reasons) the string searchStr.  In case that firstCh=lastCh the
    searching starts at this position else it starts by 1 position
    after lastCh.  After a successful search FindInString returns
    TRUE and the values of firstCh and lastCh point to the begin
    respectively the end position of the found substring within
    theString.  If the searchStr is empty or firstCh resp. lastCh
    input values are such that the search process would start
    outside of the boundaries of theString, FALSE is returned and
    the values of firstCh and lastCh are left unmodified. If the
    searchStr could not be found FALSE is returned and the values
    of firstCh and lastCh are negative.
  *)


  (**********************************************)
  (*#####   Storing Strings in Resources   #####*)
  (**********************************************)


  (* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    The following routines serve to store permamently on disk
    media the values of strings in so-called resources.  This serves
    the need to save values from one use of an application to the
    next usage at a later time.
   = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = *)

  PROCEDURE LoadString(fileName: ARRAY OF CHAR; stringID: INTEGER;
                       VAR string: ARRAY OF CHAR);
    (*
      LoadString retrieves a so-called predefined string from the
      resource fork of the file "fileName".  It may have been
      stored there by means of procedure StoreString (see below).
      LoadString may be used to read strings, or default values as
      a Macintosh resource of type 'STR ' from permanent disk
      storage.  Hence, it becomes possible to modify such texts by
      means of a resource editor (e.g.ResEdit) without having to
      recompile the program.

      The file specified by fileName is searched according to the
      following default search strategy:  First the file is
      searched according to the pathes specified in the
      User.Profile.  Then the currently running application's
      resource fork is searched, finally the System file.  If
      during this process neither a file with name fileName, nor
      the running application, nor the System file could be found
      which have a resource fork containing a resource of type 'STR
      ' with an IDÊ=ÊstringID, then the string returned is the
      empty string (string[0] = 0C, ResourceStringsDone = FALSE).

      HINT:  When you generate a stand alone application
      (With the MacMETH Linker Link using option /A), you should
      copy all resources into your application (e.g. with the
      program ResEdit). In this case the resources will be found
      regardless of the fileName you have specified. However, once
      you've finished your development, it is recommended to call
      in your final program version LoadString with an empty
      fileName or to call GetRString. This speeds-up the access to
      the resources considerably.

    *)

  PROCEDURE GetRString(stringID: INTEGER; VAR str: ARRAY OF CHAR);
    (*
      Fast Access to String resources, which must reside in the
      application's resource fork only.  Otherwise same as LoadString.
    *)

  PROCEDURE StoreString(fileName: ARRAY OF CHAR;
                        VAR stringID: INTEGER;
                        string: ARRAY OF CHAR);
    (*
      This procedure offers a simple method to save parameters and
      other values together with the program on the disk, which may
      be read and reused when the program is executed the next
      time.  Write any string into the resource fork of the file
      specified by filename.

      Note the following behavior of StoreString:  If a file with
      name fileName exists, which has a resource fork containing a
      string resource with the same stringID, then the latter's
      value will be completely overwritten with the passed value in
      parameter string.  In case there couldn«t be found any string
      resource with this stringID, but the file exists AND contains
      a resource fork (regardless of its content), then StoreString
      creates a new resource string of type 'STR ' and ID stringID.

      The file with name fileName is searched according to the
      following default search strategy: First the file is searched
      according to the pathes specified in the User.Profile.  If there
      can't be found a file with this name AND with an already
      existing resource fork, the resource will be stored in the
      currently running application's resource fork, e.g.  the MacMETH
      resp.  the RAMSES shell.  Hence, it is unlikely that StoreString
      fails completely, but often resources end up elsewhere than the
      programer expects, which may lead to confusing and surprising
      results.

      NOTE: DMFiles.Lookup creates just a data fork only. To
      create a resource fork for a file newly created by means of
      DMFiles, use ResEdit or DMOpSys.CopyResourceFork.

    *)


  PROCEDURE SetRStringName (fileName: ARRAY OF CHAR; stringID: INTEGER;
                                name: ARRAY OF CHAR);
  PROCEDURE GetRStringName (fileName: ARRAY OF CHAR; stringID: INTEGER;
                            VAR name: ARRAY OF CHAR);
    (*
      Strings stored as resources may have a name associated with
      them (string with up to 255 characters).  The above two
      routines allow to set or get such a name. This allows for
      easier identification of the resource if the utility ResEdit 
      or any other resource editor should be used to edit the
      resource.
    *)


END DMStrings.

  Contact RAMSES@env.ethz.ch Last updated: 25-Jul-2011 [Top of page]