|
|
|
|
||
|
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.
|
||
|
|
|