wildcards (was Re: a problem I'm having with rsync-4.5.4)

Wayne Davison wayned at users.sourceforge.net
Wed May 8 10:05:08 EST 2002

On Wed, 8 May 2002, Dave Dykstra wrote:
> And in fact I think the non-wildcard-matching code actually succeeds,
> doesn't it?

Yes, sorry for the unclear sentence.

> I doubt it's worth trying to fix the fnmatch() code, because fnmatch
> is a standard function and it would be a lot of work to maintain our
> own modified version.

The thing is, we don't really want what fnmatch() does.  I hadn't
realized until I read the old bug email you cited that rsync can treat
"*" characters as "**" (even though we mention that fact in the man
page).  I think this in itself is a good reason to replace the fnmatch()
call with something that can distinguish between the two idioms.  The
wildmat.c code I used to create such a solution is much simpler than the
GNU fnmatch.c code, and the test suite I used to test it indicates that
it is working quite well.  This change also means that we could get rid
of the fnmatch() compatibility code that is in the lib dir, and I've
already gotten rid of the code that tested if fnmatch() was broken on
the current machine (meaning less worries for oddball architectures).

As for the anchoring discrepancy, it's a simple matter to add a loop to
the match test to check if the pattern matches later in the string.
(This could even be done for the current fnmatch() call).  This is as
efficient as adding "**/" to the front of the string (without affecting
its matching of base-directory names).

Appended is a patch that tweaks my wildmat patch.  I've optimized the
wildmat_tail() routine to avoid an extra (useless) match loop if the
pattern starts with "**".


---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: lib/wildmat.c
--- save/lib/wildmat.c	Wed May  8 09:36:28 2002
+++ ./lib/wildmat.c	Wed May  8 09:20:09 2002
@@ -103,6 +103,8 @@
 wildmat_tail(const char *text, const char *p)
+    if (strncmp(p, "**", 2) == 0)
+	return wildmat(text, p);
     while (1) {
 	if (wildmat(text, p))
 	    return TRUE;
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---

More information about the rsync mailing list