unit WildMat;

interface

function WildCardMatch(const WildCard, TestStr : string) : boolean ;

(* Many thanks to Dr John Stockton, jrs@merlyn.demon.co.uk *)

{
>I was just wondering if you had a piece of code to match wildcards...

Not yet, unless there's one in BP7 distribution or SWAG.

>As I see it, the way to implement wildcards would be a function:
>function WildCardMatch(FullText, WildText:string): boolean;
>so  WildCardMatch('Hello','H*') = True
>and WildCardMatch('tomw@tsys.demon.co.uk','*uk') = True

Agreed, though the parameters should if possible be "const", and I'd put
them in the other order.

>
> c) My guess is that recursion is the technique to swear by.  Do you also know
>    of a routine which does not use recursion?

Yes.   No - seeing that I don't yet know of one anyhow!

Assuming '*' can be matched by '', both your examples can be done with
Pos :  Pos('H', 'Hello')>0 ;
(* to test if S1 is in a short list of words, I often use
Pos(#32+S1, ' Word1 Word2 Word3 ...')>0 or similar. *)

Pause for a bit of programming :

I've changed it to pass Seek & Within unmodified and also to pass the
current position reached in each.  It has been VERY SLIGHTLY tested.}

implementation

function WildCardMatch(const WildCard, TestStr : string) : boolean ;
function WCM(const WildPos, TestPos : byte) : boolean ;
{ N.B. WildPos, TestPos point to the first relevant character in
  Seek, Within; problems with 255-long strings might be avoided by
  using instead the index of the last irrelevant character. }
var NextLetter : byte ;
begin

  if (WildPos>Length(WildCard)) and (TestPos>Length(TestStr)) then
     begin WCM := true ; EXIT end;
  if (WildPos>Length(WildCard)) or  (TestPos>Length(TestStr)) then
     begin WCM := false; EXIT end;

  if WildCard[WildPos]='*' then begin
    if Length(WildCard)=WildPos then begin WCM := true ; EXIT end ;
    NextLetter:=Pos(WildCard[Succ(WildPos)], Copy(TestStr, TestPos, 255))
      { Improve that line as a for/while/repeat without Copy!
        & adjust other B if needed } ;
    if NextLetter=0 then begin WCM := false ; EXIT end ;
    if WCM(WildPos+2, TestPos+NextLetter) then begin WCM := true ; EXIT end ;
    WCM := WCM(WildPos, TestPos+NextLetter) ;
    EXIT end ;
  if (WildCard[WildPos]='?') or (WildCard[WildPos]=TestStr[TestPos]) then begin
    WCM := WCM(Succ(WildPos), Succ(TestPos)) ;
    EXIT end ;
  WCM := false end {WC} ;
begin
{  Writeln('wcm: ''',Wildcard,''',''',TestStr,'''');}
  WildCardMatch := WCM(1,1) end;
end.