CPUnit 0.95 (beta)
The REAL C++ port of JUnit.
/Users/Shared/Development/cpp/sourceforge/cpunit_095/src/cpunit_GlobMatcher.cpp
Go to the documentation of this file.
00001 /*
00002    Copyright (c) 2011 Daniel Bakkelund.
00003    All rights reserved.
00004 
00005    Redistribution and use in source and binary forms, with or without
00006    modification, are permitted provided that the following conditions
00007    are met:
00008     1. Redistributions of source code must retain the above copyright
00009        notice, this list of conditions and the following disclaimer.
00010     2. Redistributions in binary form must reproduce the above copyright
00011        notice, this list of conditions and the following disclaimer in the
00012        documentation and/or other materials provided with the distribution.
00013     3. Neither the name of the copyright holders nor the names of its
00014        contributors may be used to endorse or promote products derived from
00015        this software without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00027    THE POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 
00031 
00032 #include "cpunit_GlobMatcher.hpp"
00033 #include "cpunit_WrongSetupException.hpp"
00034 #include <sstream>
00035 #include "cpunit_trace.hpp"
00036 
00037 #ifdef GLOB_DEBUG
00038 #include <iostream>
00039 #define CPUNIT_GLOB_TRACE(x) {std::clog<<x<<std::endl;}
00040 #else
00041 #define CPUNIT_GLOB_TRACE(x)
00042 #endif
00043 
00044 const char cpunit::GlobMatcher::wc('*');
00045 
00046 cpunit::GlobMatcher::GlobMatcher(const std::string _pattern) 
00047   : pattern(contract_wildcards(_pattern)) 
00048 {
00049   CPUNIT_GLOB_TRACE("GlobMatcher instantiated with pattern '"<<_pattern<<"' ~ '"<<pattern<<'\'');
00050 }
00051 
00052 cpunit::GlobMatcher::~GlobMatcher() 
00053 {}
00054 
00055 std::string
00056 cpunit::GlobMatcher::contract_wildcards(const std::string &s) {
00057   std::string result(s);
00058   std::string::iterator it = result.begin();
00059   while (it != result.end() - 1) {
00060     if (*it == wc && *(it+1) == wc) {
00061       it = result.erase(it);
00062     } else {
00063       ++it;
00064     }
00065   }
00066   return result;
00067 }
00068 
00069 bool
00070 cpunit::GlobMatcher::matches(const std::string &str) const {
00071   CPUNIT_GLOB_TRACE("Matching '"<<str<<"' against pattern '"<<pattern<<'\'');
00072   return attempt_match(str, 0, 0);
00073 }
00074 
00075 bool 
00076 cpunit::GlobMatcher::attempt_match(const std::string& s, const std::size_t si, const std::size_t pi) const {
00077   CPUNIT_GLOB_TRACE("attempt_match(s="<<s<<",si="<<si<<",ps="<<pi<<") with p="<<pattern);
00078   CPUNIT_GLOB_TRACE("              str[si]="<<s[si]<<", pattern[pi]="<<pattern[pi]);
00079   std::size_t i=0;
00080   for (; si+i < s.length() && pi+i < pattern.length() ; i++) {
00081     CPUNIT_GLOB_TRACE("              i="<<i);
00082     if (pattern[pi+i] == wc) {
00083       return on_wildcard(s, si+i, pi+i);
00084     } else if (pattern[pi+i] != s[si+i]) {
00085       return false;
00086     }
00087     CPUNIT_GLOB_TRACE("              str[si+i]="<<s[si+i]<<", pattern[pi+i]="<<pattern[pi+i]);
00088   }
00089   CPUNIT_GLOB_TRACE("              si+i="<<(si+i)<<", s.length()="<<s.length()<<", pi+i="<<(pi+i)<<", pattern.length()="<<pattern.length());
00090   return si+i == s.length() && (pi+i == pattern.length() || (pi+i+1 == pattern.length() && pattern[pi+i] == wc));
00091 }
00092 
00093 bool 
00094 cpunit::GlobMatcher::on_wildcard(const std::string& s, const std::size_t si, const std::size_t wci) const {
00095   CPUNIT_GLOB_TRACE("on_wildcard(s="<<s<<",si="<<si<<",wci="<<wci<<") with pattern="<<pattern);
00096   CPUNIT_GLOB_TRACE("            s[si]="<<s[si]<<", pattern[wci]="<<pattern[wci]);
00097   if (wci == pattern.length() - 1) {
00098       CPUNIT_GLOB_TRACE("            T <-- wci=|pattern|-1");
00099     return true;
00100   }
00101   for (std::size_t i=0; si+i < s.length() ; ++i) {
00102     if (attempt_match(s, si+i, wci+1)) {
00103       CPUNIT_GLOB_TRACE("            T <-- attempt_match");
00104       return true;
00105     }
00106   }
00107   return false;
00108 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines