Browse Source

pick up vc9 fixes from panda

David Rose 15 years ago
parent
commit
d9102227c7
3 changed files with 154 additions and 8 deletions
  1. 85 1
      ppremake/globPattern.I
  2. 56 7
      ppremake/globPattern.cxx
  3. 13 0
      ppremake/globPattern.h

+ 85 - 1
ppremake/globPattern.I

@@ -20,6 +20,7 @@
 ////////////////////////////////////////////////////////////////////
 INLINE GlobPattern::
 GlobPattern(const string &pattern) : _pattern(pattern) {
+  _case_sensitive = true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -28,7 +29,10 @@ GlobPattern(const string &pattern) : _pattern(pattern) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE GlobPattern::
-GlobPattern(const GlobPattern &copy) : _pattern(copy._pattern) {
+GlobPattern(const GlobPattern &copy) : 
+  _pattern(copy._pattern),
+  _case_sensitive(copy._case_sensitive)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -39,6 +43,40 @@ GlobPattern(const GlobPattern &copy) : _pattern(copy._pattern) {
 INLINE void GlobPattern::
 operator = (const GlobPattern &copy) {
   _pattern = copy._pattern;
+  _case_sensitive = copy._case_sensitive;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::operator ==
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool GlobPattern::
+operator == (const GlobPattern &other) const {
+  return (_pattern == other._pattern && _case_sensitive == other._case_sensitive);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::operator !=
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool GlobPattern::
+operator != (const GlobPattern &other) const {
+  return !operator == (other);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::operator <
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool GlobPattern::
+operator < (const GlobPattern &other) const {
+  if (_case_sensitive != other._case_sensitive) {
+    return (int)_case_sensitive < (int)other._case_sensitive;
+  }
+  return _pattern < other._pattern;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -63,6 +101,52 @@ get_pattern() const {
   return _pattern;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::set_case_sensitive
+//       Access: Public
+//  Description: Sets whether the match is case sensitive (true) or
+//               case insensitive (false).  The default is case
+//               sensitive.
+////////////////////////////////////////////////////////////////////
+INLINE void GlobPattern::
+set_case_sensitive(bool case_sensitive) {
+  _case_sensitive = case_sensitive;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::get_case_sensitive
+//       Access: Public
+//  Description: Returns whether the match is case sensitive (true) or
+//               case insensitive (false).  The default is case
+//               sensitive.
+////////////////////////////////////////////////////////////////////
+INLINE bool GlobPattern::
+get_case_sensitive() const {
+  return _case_sensitive;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::set_nomatch_chars
+//       Access: Public
+//  Description: Specifies a set of characters that are not matched by
+//               * or ?.
+////////////////////////////////////////////////////////////////////
+INLINE void GlobPattern::
+set_nomatch_chars(const string &nomatch_chars) {
+  _nomatch_chars = nomatch_chars;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::get_nomatch_chars
+//       Access: Public
+//  Description: Returns the set of characters that are not matched by
+//               * or ?.
+////////////////////////////////////////////////////////////////////
+INLINE const string &GlobPattern::
+get_nomatch_chars() const {
+  return _nomatch_chars;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GlobPattern::matches
 //       Access: Public

+ 56 - 7
ppremake/globPattern.cxx

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "globPattern.h"
+#include <ctype.h>
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GlobPattern::has_glob_characters
@@ -43,6 +44,39 @@ has_glob_characters() const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::get_const_prefix
+//       Access: Public
+//  Description: Returns the initial part of the pattern before the
+//               first glob character.  Since many glob patterns begin
+//               with a sequence of static characters and end with one
+//               or more glob characters, this can be used to
+//               optimized searches through sorted indices.
+////////////////////////////////////////////////////////////////////
+string GlobPattern::
+get_const_prefix() const {
+  string prefix;
+
+  size_t p = 0;  // current point
+  size_t q = 0;  // starting point
+  while (p < _pattern.size()) {
+    switch (_pattern[p]) {
+    case '*':
+    case '?':
+    case '[':
+      return prefix + _pattern.substr(q, p - q);
+
+    case '\\':
+      // Skip over the backslash.
+      prefix += _pattern.substr(q, p - q);
+      ++p;
+      q = p;
+    }
+    ++p;
+  }
+  return prefix += _pattern.substr(q, p - q);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GlobPattern::match_files
 //       Access: Public
@@ -179,7 +213,7 @@ matches_substr(string::const_iterator pi, string::const_iterator pend,
     // A special exception: we allow ci to reach the end before pi,
     // only if pi is one character before the end and that last
     // character is '*'.
-    if ((ci == cend) && (pi + 1 == pend) && (*pi) == '*') {
+    if ((ci == cend) && (std::distance(pi, pend) == 1) && (*pi) == '*') {
       return true;
     }
     return (pi == pend && ci == cend);
@@ -193,9 +227,15 @@ matches_substr(string::const_iterator pi, string::const_iterator pend,
     // to recurse twice: either consume one character of the candidate
     // string and continue to try matching the *, or stop trying to
     // match the * here.
-    return
-      matches_substr(pi, pend, ci + 1, cend) ||
-      matches_substr(pi + 1, pend, ci, cend);
+    if (_nomatch_chars.find(*ci) == string::npos) {
+      return
+        matches_substr(pi, pend, ci + 1, cend) ||
+        matches_substr(pi + 1, pend, ci, cend);
+    } else {
+      // On the other hand, if this is one of the nomatch chars, we
+      // can only stop here.
+      return matches_substr(pi + 1, pend, ci, cend);
+    }
 
   case '?':
     // A '?' in the pattern string means to match exactly one
@@ -231,8 +271,14 @@ matches_substr(string::const_iterator pi, string::const_iterator pend,
 
   default:
     // Anything else means to match exactly that.
-    if ((*pi) != (*ci)) {
-      return false;
+    if (_case_sensitive) {
+      if ((*pi) != (*ci)) {
+        return false;
+      }
+    } else {
+      if (tolower(*pi) != tolower(*ci)) {
+        return false;
+      }
     }
     return matches_substr(pi + 1, pend, ci + 1, cend);
   }
@@ -286,7 +332,10 @@ matches_set(string::const_iterator &pi, string::const_iterator pend,
         char end = (*pi);
         ++pi;
 
-        if (ch >= start && ch <= end) {
+        if (ch >= start && ch <= end || 
+            (!_case_sensitive && 
+             ((tolower(ch) >= start && tolower(ch) <= end) ||
+              (toupper(ch) >= start && toupper(ch) <= end)))) {
           matched = true;
         }
       } else {

+ 13 - 0
ppremake/globPattern.h

@@ -40,14 +40,25 @@ public:
   INLINE GlobPattern(const GlobPattern &copy);
   INLINE void operator = (const GlobPattern &copy);
 
+  INLINE bool operator == (const GlobPattern &other) const;
+  INLINE bool operator != (const GlobPattern &other) const;
+  INLINE bool operator < (const GlobPattern &other) const;
+
   INLINE void set_pattern(const string &pattern);
   INLINE const string &get_pattern() const;
 
+  INLINE void set_case_sensitive(bool case_sensitive);
+  INLINE bool get_case_sensitive() const;
+
+  INLINE void set_nomatch_chars(const string &nomatch_chars);
+  INLINE const string &get_nomatch_chars() const;
+
   INLINE bool matches(const string &candidate) const;
 
   INLINE void output(ostream &out) const;
 
   bool has_glob_characters() const;
+  string get_const_prefix() const;
   int match_files(vector_string &results, const Filename &cwd = Filename());
 
 private:
@@ -64,6 +75,8 @@ private:
                     vector_string &results, const Filename &cwd);
 
   string _pattern;
+  bool _case_sensitive;
+  string _nomatch_chars;
 };
 
 INLINE ostream &operator << (ostream &out, const GlobPattern &glob) {