On 19 Mar 2003, Robert Collins wrote:

> Looks good.
>
> Ok, can you:
> Merge in the HEAD changes, so that the patch will apply cleanly.
> Regenerate the patch.
>
> Max, I'm going to be very busy for a few days - can you please merge
> this patch in once Igor gets it to apply cleanly to HEAD.
>
> Thanks,
> Rob

Sorry about that.  I was trying to juggle three patches, and a stale hunk
slipped in.  Should be fixed now.
        Igor
==============================================================================
ChangeLog:
2003-03-18  Igor Pechtchanski <[EMAIL PROTECTED]>

        * postinstall.cc (do_postinstall): Filter out '*.done'.
        * FilterVisitor.h: New header file.  Declare the
        FilterVisitor, Filter, and ExcludeNameFilter classes.
        * FilterVisitor.cc: New file.  Implement FilterVisitor,
        Filter, and ExcludeNameFilter.
        * String++.h (String::matches): New instance function.
        * String++.cc (String::matches): Implement.
        (strmatch) Import and adapt for <buf,len> strings.
        * Makefile.am (setup_SOURCES): Add FilterVisitor.cc and
        FilterVisitor.h to value.

-- 
                                http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_                [EMAIL PROTECTED]
ZZZzz /,`.-'`'    -.  ;-;;,_            [EMAIL PROTECTED]
     |,4-  ) )-,_. ,\ (  `'-'           Igor Pechtchanski
    '---''(_/--'  `-'\_) fL     a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

Oh, boy, virtual memory! Now I'm gonna make myself a really *big* RAMdisk!
  -- /usr/games/fortune
Index: FilterVisitor.cc
===================================================================
RCS file: FilterVisitor.cc
diff -N FilterVisitor.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ FilterVisitor.cc    18 Mar 2003 14:01:36 -0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2003 Igor Pechtchanski.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ * Written by Igor Pechtchanski <[EMAIL PROTECTED]>
+ *
+ */
+
+#if 0
+static const char *cvsid =
+  "\n%%% $Id$\n";
+#endif
+
+#include "FilterVisitor.h"
+#include "String++.h"
+#include "find.h"
+
+#include <iostream>
+
+FilterVisitor::FilterVisitor(FindVisitor *visitor, Filter *filter)
+  : _visitor(visitor), _filter(filter) {}
+
+FilterVisitor::~FilterVisitor() {}
+
+void
+FilterVisitor::visitFile(String const &basePath, WIN32_FIND_DATA const *aFile)
+{
+  if (_filter->matchFile(basePath, aFile))
+    _visitor->visitFile(basePath, aFile);
+}
+
+void
+FilterVisitor::visitDirectory(String const &basePath, WIN32_FIND_DATA const *aDir)
+{
+  if (_filter->matchDirectory(basePath, aDir))
+    _visitor->visitDirectory(basePath, aDir);
+}
+
+Filter::Filter() {}
+Filter::~Filter() {}
+
+bool
+Filter::matchFile(String const &basePath, WIN32_FIND_DATA const *aFile)
+{
+  return true;
+}
+
+bool
+Filter::matchDirectory(String const &basePath, WIN32_FIND_DATA const *aDir)
+{
+  return true;
+}
+
+ExcludeNameFilter::ExcludeNameFilter() : _filePattern(""), _dirPattern("") {}
+
+ExcludeNameFilter::~ExcludeNameFilter(){}
+
+ExcludeNameFilter::ExcludeNameFilter(String const &filePattern,
+                                    String const &dirPattern)
+  : _filePattern(filePattern), _dirPattern(dirPattern) {}
+
+bool
+ExcludeNameFilter::matchFile(String const &basePath, WIN32_FIND_DATA const *aFile)
+{
+  return !(basePath + aFile->cFileName).matches(_filePattern);
+}
+
+bool
+ExcludeNameFilter::matchDirectory(String const &basePath, WIN32_FIND_DATA const *aDir)
+{
+  return !(basePath + aDir->cFileName).matches(_dirPattern);
+}
+
Index: FilterVisitor.h
===================================================================
RCS file: FilterVisitor.h
diff -N FilterVisitor.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ FilterVisitor.h     18 Mar 2003 14:01:36 -0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2003 Igor Pechtchanski.
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ * Written by Igor Pechtchanski <[EMAIL PROTECTED]>
+ *
+ */
+
+#ifndef _FILTERVISITOR_H_
+#define _FILTERVISITOR_H_
+
+#include "FindVisitor.h"
+#include "String++.h"
+
+/* For the wfd definition. See the TODO in find.cc */
+#include "win32.h"
+
+class Filter
+{
+public:
+  virtual bool matchFile(String const &basePath, WIN32_FIND_DATA const *);
+  virtual bool matchDirectory(String const &basePath, WIN32_FIND_DATA const *);
+  virtual ~ Filter();
+protected:
+  Filter();
+  Filter(Filter const &);
+  Filter & operator= (Filter const &);
+};
+
+class FilterVisitor : public FindVisitor
+{
+public:
+  virtual void visitFile(String const &basePath, WIN32_FIND_DATA const *);
+  virtual void visitDirectory(String const &basePath, WIN32_FIND_DATA const *);
+  FilterVisitor (FindVisitor *visitor, Filter *filter);
+  virtual ~ FilterVisitor ();
+protected:
+  FilterVisitor ();
+  FilterVisitor (FilterVisitor const &);
+  FilterVisitor & operator= (FilterVisitor const &);
+private:
+  FindVisitor *_visitor;
+  Filter *_filter;
+};
+
+class ExcludeNameFilter : public Filter
+{
+public:
+  ExcludeNameFilter (String const &filePattern, String const &dirPattern = "");
+  virtual ~ ExcludeNameFilter ();
+
+  virtual bool matchFile(String const &basePath, WIN32_FIND_DATA const *);
+  virtual bool matchDirectory(String const &basePath, WIN32_FIND_DATA const *);
+protected:
+  ExcludeNameFilter ();
+  ExcludeNameFilter (ExcludeNameFilter const &);
+  ExcludeNameFilter & operator= (ExcludeNameFilter const &);
+private:
+  String _filePattern;
+  String _dirPattern;
+};
+
+#endif // _FILTERVISITOR_H_
Index: Makefile.am
===================================================================
RCS file: /cvs/cygwin-apps/setup/Makefile.am,v
retrieving revision 2.27
diff -u -p -r2.27 Makefile.am
--- Makefile.am 10 Mar 2003 15:47:53 -0000      2.27
+++ Makefile.am 18 Mar 2003 14:01:36 -0000
@@ -153,6 +153,8 @@ setup_SOURCES = \
        find.h \
        FindVisitor.cc \
        FindVisitor.h \
+       FilterVisitor.cc \
+       FilterVisitor.h \
        filemanip.cc \
        filemanip.h \
        fromcwd.cc \
Index: String++.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/String++.cc,v
retrieving revision 2.9
diff -u -p -r2.9 String++.cc
--- String++.cc 17 Mar 2003 22:23:33 -0000      2.9
+++ String++.cc 18 Mar 2003 14:01:36 -0000
@@ -252,6 +252,149 @@ String::casecompare (String const lhs, S
   return lhs.casecompare (rhs);
 }
 
+/*
+ * This supports two wildcard characters, '*' and '?', as well as the
+ * '[]'-style character sets ('^' to invert).
+ * Use '\' to escape special characters.
+ * Shamelessly stolen from fileutils-4.1 (adapted for <buf,len> strings).
+ */
+static bool
+strmatch (const unsigned char *pattern, size_t plen,
+         const unsigned char *name, size_t nlen)
+{
+  register const unsigned char *pend = pattern + plen, *nend = name + nlen;
+  register const unsigned char *p = pattern, *n = name;
+  register unsigned char c;
+
+  while (p < pend)
+    {
+      c = *p++;
+      switch (c)
+       {
+       case '?':  /* A '?' matches exactly one character */
+         if (n == nend)
+           return false;
+         break;
+
+       case '\\':  /* Escape next character */
+         if (p == pend)
+           return false;
+         c = *p++;
+         if (n == nend || *n != c)
+           return false;
+         break;
+
+       case '*':  /* A '*' matches any number of characters */
+         while (p < pend && (c == '?' || c == '*'))
+           {
+             c = *p++;
+             if (c == '?')
+               {
+                 /* A '?' needs to match one character.  */
+                 if (n == nend)
+                   /* There isn't another character; no match.  */
+                   return false;
+                 else
+                   /* One character of the name is consumed in matching
+                      this ? wildcard, so *??? won't match if there are
+                      less than three characters.  */
+                   ++n;
+               }
+           }
+
+         if (p == pend)
+           return true;
+
+         {
+           unsigned char c1 = (c == '\\') ? *p : c;
+           for (--p; n != nend; ++n)  /* Eat up all chars */
+             if ((c == '[' || *n == c1) && strmatch (p, pend-p, n, nend-n))
+               return true;
+           return false;
+         }
+
+       case '[':  /* A '[A-Z]' matches any char between 'A' and 'Z' */
+         {
+           /* Nonzero if the sense of the character class is inverted.  */
+           register bool invert;
+
+           if (n == nend)
+             return false;
+
+           invert = (*p == '^');
+           if (invert)
+             ++p;
+
+           if (p == pend)
+             /* [ (unterminated) loses.  */
+             return false;
+
+           c = *p++;
+           for (;;)
+             {
+               register unsigned char cstart = c, cend = c;
+
+               if (p == pend)
+                 /* [ (unterminated) loses.  */
+                 return false;
+
+               c = *p++;
+
+               if (c == '-' && *p != ']')
+                 {
+                   if (p == pend)
+                     return false;
+                   cend = *p++;
+
+                   c = *p++;
+                 }
+
+               if (*n >= cstart && *n <= cend)
+                 goto matched;
+
+               if (c == ']')
+                 break;
+             }
+           if (!invert)
+             return false;
+           break;
+
+         matched:;
+           /* Skip the rest of the [...] that already matched.  */
+           while (c != ']')
+             {
+               if (p == pend)
+                 /* [... (unterminated) loses.  */
+                 return false;
+
+               c = *p++;
+             }
+           if (invert)
+             return false;
+         }
+         break;
+
+       default:
+         if (n == nend || c != *n)
+           return false;
+       }
+
+      ++n;
+    }
+
+  if (n == nend)
+    return true;
+
+  return false;
+}
+
+bool
+String::matches (String const &pattern) const
+{
+  return strmatch (pattern.theData->theString, pattern.theData->length,
+                  theData->theString, theData->length);
+}
+
 /* TODO: research how wide char and unicode interoperate with
  * C++ streams
  */
Index: String++.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/String++.h,v
retrieving revision 2.9
diff -u -p -r2.9 String++.h
--- String++.h  17 Mar 2003 22:23:33 -0000      2.9
+++ String++.h  18 Mar 2003 14:01:36 -0000
@@ -62,6 +62,7 @@ public:
        {
          return s1.casecompare (s2) < 0;
        }};
+  bool matches (String const &pattern) const;
     
 private:
   class _data {
Index: postinstall.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v
retrieving revision 2.9
diff -u -p -r2.9 postinstall.cc
--- postinstall.cc      19 May 2002 03:07:51 -0000      2.9
+++ postinstall.cc      17 Mar 2003 18:01:51 -0000
@@ -26,6 +26,7 @@ static const char *cvsid =
 #include "mount.h"
 #include "script.h"
 #include "FindVisitor.h"
+#include "FilterVisitor.h"
 #include "package_db.h"
 #include "package_meta.h"
 
@@ -60,7 +61,8 @@ do_postinstall (HINSTANCE h, HWND owner)
       ++i;
     }
   RunFindVisitor myVisitor;
+  ExcludeNameFilter notDone("*.done");
+  FilterVisitor excludeDoneVisitor(&myVisitor, &notDone);
   String postinst = cygpath ("/etc/postinstall");
-  Find (postinst).accept (myVisitor);
-  
+  Find (postinst).accept (excludeDoneVisitor);
 }

Reply via email to