Checking the existing match function used in the dlls I found some problems and I cannot pass the blame for them to anyone else - I did it. So before changing them I thought I would get others to check it. I know there is an additional compare but it does speed things when the case is the same - common when files supplied from list. I hope it works right but am not certain how it compares to earlier Windows. Windows (XP at least) treats *t* as any name including 't', but *.* is any name with or without '.'. I think this function should give consistant results (but are they correct?) - Russell Peters Builder version - #include <ctype.h> /* =========================================================================== * Nonrecursively compare the sh pattern p, with the string s, * and return 1 if they match, and 0 if they don't. *p :: pattern to match (ex: *.*). *s :: String to match it to (ex: FNAME.DAT). pe :: past end of pattern se :: past end of string */ static int pat_match( const char *p, const char *s, const char *pe, const char *se) { char c,cs; const char *pa=0; // pattern position last '*' - null = none const char *sa; // string position last '*' for ( ;; ) { // keep scanning until end or unrecoverable mismatch if ( s==se ) { // run out of string - only '*''s allowed in pattern while ( *p=='*' ) p++; return ( p>=pe ); // ok if end of pattern } // more string to process if ( ( c=*p ) =='*' ) { // on mask if ( ++p>=pe ) // last char - rest of string must match return 1; // note scan point incase must back up pa=p; sa=s; } else { cs=*s; // if successful match, inc pointers and keep trying if ( ( cs==c ) || ( toupper( cs ) ==toupper( c ) ) || (cs=='\\' && c=='/') || (cs=='/' && c=='\\') || ( c=='?' && cs ) ) { p++; s++; } else { // no match if ( !pa ) // any asterisk? return 0; // no - no match p=pa; // back up s=++sa; // next char in string } } } } /* =========================================================================== * Adapted by R.Peters from many sources * Break the pattern and string into name and extension parts and match * each separately using pat_match(). *s :: Filename to match against wildcard pattern. *p :: Dos wildcard pattern to match. */ int PatternMatch(const char *p, const char *s) { const char *pe, *p2e; // pattern sections e=end const char *se, *s2e; // string sections 2=start of second part char c; // find extension (and eos) pe=0; for ( p2e=p;(c=*p2e)!=0; p2e++ ) { if ( c == '.' ) pe=p2e; else if ( c == '\\' || c == '/') pe=0; // still in path } if (!pe) // no dot in pattern { for ( s2e= s;*s2e; s2e++ ) // find eos ; return pat_match( p, s, p2e, s2e); } // find extension (and eos) se=0; for ( s2e= s;(c=*s2e)!=0; s2e++ ) { if ( c == '.' ) se=s2e; // at last '.' else if ( c == '\\' || c == '/') // still in path se=0; } if (!se) // no sExt se=s2e; // end // if pattern ext <> '.*' then exts must match if ((pe[1]!='*' || pe[2]) && !pat_match( pe, se, p2e,s2e)) return false; return pat_match( p, s, pe, se); // match rest } Delphi version - I found the problems when porting it to Delphi unit m1; interface uses classes; function PatternMatch(const pat: string; const str: string): boolean; implementation function PatternMatch(const pat: string; const str: string): boolean; var pl, px, sl, sx: cardinal; c: char; function pat_match(ps, pe: cardinal; ss, se: cardinal): boolean; var c, cs : char; pa, sa : cardinal; // position of current '*' begin pa := 0; // no '*' sa := 0; repeat // scan till end or unrecoverable error if ss > se then // run out of string - only '*' allowed in pattern begin while pat[ps] = '*' do inc(ps); Result := (ps > pe); // ok end of pattern exit; end; // more string to process c := pat[ps]; if c = '*' then begin // on mask inc(ps); if (ps > pe) then // last char - matches rest of string begin Result := true; exit end; // note scan point incase must back up pa := ps; sa := ss;//succ(ss); end else begin // if successful match, inc pointers and keep trying cs := str[ss]; if (cs = c) or (UpCase(cs) = UpCase(c)) or ((c = '\') and (cs = '/')) or ((c = '/') and (cs = '\')) or ((c = '?') and (cs <> char(0))) then begin inc(ps); inc(ss); end else // no match begin if (pa = 0) then // any asterisk? begin Result := false; // no - no match exit; end; ps := pa; // backup inc(sa); ss := sa; end; end; until false; end; begin // Result := false; pl := length(pat); // find start of ext sl := length(str); px := pl; while px >= 1 do begin c:= pat[px]; if (c='\') or (c='/') then px:=0 // no name left - skip path else if c='.' then break else dec(px); end; if px = 0 then begin Result := pat_match(1, pl, 1, sl); exit; end; sx := sl; while sx >= 1 do begin c:= str[sx]; if (c='\') or (c='/') then sx:=0 // no name left - skip path else if c<>'.' then dec(sx) else break; end; if (sx = 0) then sx:= succ(sl); // past end Result := pat_match(1, pred(px), 1, pred(sx)); if Result and ((px <> pred(pl)) or (pat[pl]<>'*')) then Result := pat_match(px, pl, sx, sl); // test exts end; end. ----------- To unsubscribe from this list, send an empty e-mail message to: delphizip-request@xxxxxxxxxxxxx and put the word unsubscribe in the subject.