CPUnit 0.95 (beta)
The REAL C++ port of JUnit.
|
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 }