K6Syntax10.Scn.FntInfoElemsAlloc#Syntax10.Scn.FntHH"Title": Several string manipulating procedures (all those I've needed up to now). "Copyright": 1996, 1997 by Claudio Nieder . This module is free software; you can redistribute it and/or modify it under the terms of the GNU Library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 8Syntax10b.Scn.Fnt  X Courier10.Scn.Fnt     8FoldElemsNew#Syntax10.Scn.Fnt'' Returns the length of the string. 8u8#Syntax10.Scn.Fntii VAR i:LONGINT; BEGIN i:=0; WHILE (in); k:=length(str); FOR i:=k TO n-1 DO str[i]:=pad; END; str[n]:=0X; END left; 8  Xe8{Syntax10.Scn.FntSyntax10b.Scn.Fnt! Compares a part of length characters each of string1 and string2. start1 and start2 define the first character of the stretch of characters to compare. This procedure assumes, that the two stretches are define correctly, i.e. do not extend beyond the logical end (0X) of the string. 8 8{Syntax10.Scn.Fnt]Syntax10b.Scn.Fnt!x-z VAR end1,end2:LONGINT; i,j:LONGINT; BEGIN end1:=length(string1); end2:=length(string2); ASSERT(start1+stretchLength<=end1+1); ASSERT(start2+stretchLength<=end2+1); j:=start2; FOR i:=start1 TO start1+stretchLength-1 DO IF string1[i]>string2[j] THEN RETURN greater; ELSIF string1[i]string2[i] THEN RETURN greater; ELSIF string1[i]wordStop THEN (* can't match, because pattern prefix longer than unmatched word prefix. *) RETURN FALSE; END; IF (wildcardPosition>0) & (compareParts(word,pattern,0,0,wildcardPosition)#equal) THEN (* prefix didn't match *) RETURN FALSE; END; (* Finally, after we got rid of any part before the first, or after the last wildcard character, we can just take all stretches of characters enclosed between successive wildcard characters and search them in in the word which has to match. If they occur there in the same sequence, then the word matches the pattern. *) patternStart:=wildcardPosition+1; wordStart:=wildcardPosition; WHILE patternStartwordStop-stretchLength THEN RETURN FALSE; END; (* no match possible because of lack of characters. *) IF compareParts(word,pattern,wordStart,patternStart,stretchLength)=equal THEN EXIT; END; (* match *) INC(wordStart); END; wordStart:=wordStart+stretchLength; patternStart:=wildcardPosition+1; END; RETURN TRUE; (* A match was found for all non-wildcard parts of the pattern. *) END match;8eO8#Syntax10.Scn.Fnt Test if a word matches a pattern. Wherever a '*' is part of the pattern, every sequence of 0, 1 or more letter of the word will match. 88Syntax10.Scn.Fnt_8FoldElemsNewSyntax10.Scn.Fnt[Syntax10b.Scn.Fnt7@ce7TNQ VAR res:SHORTINT; BEGIN LOOP (* exact match *) IF p[pi]='*' THEN INC(pi); EXIT; (* go to wildcard match *) ELSIF p[pi]#s[si] THEN RETURN wordMismatch; (* no match found here *) ELSIF p[pi]=0X THEN RETURN matched; (* reached end of both strings *) END; INC(si); INC(pi); END; IF p[pi]=0X THEN RETURN matched; END; (* wildcard at end, no need to compare further. *) LOOP (* wildcard match *) res:=M(si,pi); (* Let's see if the rest matches too. *) IF res=matched THEN RETURN matched; (* it matched, so we are through it. *) ELSIF res=patternMismatch THEN RETURN patternMismatch; (* it can't match, so we give up. *) ELSIF s[si]=0X THEN RETURN patternMismatch; (* no more characters for matching, give up. *) END; INC(si); (* didn't match at this position, maybe at next one. *) END END M;8 8#Syntax10.Scn.Fnt RETURN M(0,0)=matched;8 w CONST matched=0; wordMismatch=1; patternMismatch=2; PROCEDURE M(si,pi:LONGINT):SHORTINT; BEGIN END match;8 }MODULE string;  (*enum: CompareResult=(less,equal,greater); *) CONST less*=0; equal*=1; greater*=2; TYPE CompareResult*=SHORTINT; (*enum: ConvertError=(noConversion,converted,conversionUnknown) *) CONST noConversion*=0; converted*=1; conversionUnknown*=2; TYPE ConvertError*=SHORTINT; TYPE String*=ARRAY OF CHAR; StringPtr*=POINTER TO String; PROCEDURE length*(VAR str:String):LONGINT;(**) PROCEDURE append*(VAR dst:String; src:String);(**) VAR i,j:LONGINT; BEGIN i:=0; WHILE (i