Bläddra i källkod

Removed static const char[] as much as possible.

Provided convenient functions for streq, strieq, startsWith,
istartsWith, endsWith, iendsWith to support this move.
Tatsuhiro Tsujikawa 13 år sedan
förälder
incheckning
9331f6a43d
14 ändrade filer med 140 tillägg och 177 borttagningar
  1. 2 7
      src/HttpConnection.cc
  2. 2 6
      src/HttpRequest.cc
  3. 1 3
      src/HttpServer.cc
  4. 8 21
      src/Netrc.cc
  5. 2 5
      src/NsCookieParser.cc
  6. 3 9
      src/OptionHandlerImpl.cc
  7. 1 3
      src/bittorrent_helper.cc
  8. 6 12
      src/cookie_helper.cc
  9. 4 12
      src/json.cc
  10. 1 3
      src/magnet.cc
  11. 1 3
      src/option_processing.cc
  12. 52 56
      src/util.cc
  13. 41 7
      src/util.h
  14. 16 30
      test/UtilTest.cc

+ 2 - 7
src/HttpConnection.cc

@@ -83,18 +83,13 @@ HttpConnection::~HttpConnection() {}
 
 std::string HttpConnection::eraseConfidentialInfo(const std::string& request)
 {
-  static const char A2_AUTH_HEADER[] = "Authorization: Basic";
-  static const char A2_PROXY_AUTH_HEADER[] = "Proxy-Authorization: Basic";
   std::istringstream istr(request);
   std::string result;
   std::string line;
   while(getline(istr, line)) {
-    if(util::startsWith(line.begin(), line.end(),
-                        A2_AUTH_HEADER, vend(A2_AUTH_HEADER)-1)) {
+    if(util::startsWith(line, "Authorization: Basic")) {
       result += "Authorization: Basic ********\n";
-    } else if(util::startsWith(line.begin(), line.end(),
-                               A2_PROXY_AUTH_HEADER,
-                               vend(A2_PROXY_AUTH_HEADER)-1)) {
+    } else if(util::startsWith(line, "Proxy-Authorization: Basic")) {
       result += "Proxy-Authorization: Basic ********\n";
     } else {
       result += line;

+ 2 - 6
src/HttpRequest.cc

@@ -444,14 +444,10 @@ bool HttpRequest::conditionalRequest() const
   if(!ifModSinceHeader_.empty()) {
     return true;
   }
-  static const char A2_IF_MOD_SINCE[] = "if-modified-since";
-  static const char A2_IF_NONE_MATCH[] = "if-none-match";
   for(std::vector<std::string>::const_iterator i = headers_.begin(),
         eoi = headers_.end(); i != eoi; ++i) {
-    if(util::istartsWith((*i).begin(), (*i).end(),
-                        A2_IF_MOD_SINCE, vend(A2_IF_MOD_SINCE)-1) ||
-       util::istartsWith((*i).begin(), (*i).end(),
-                        A2_IF_NONE_MATCH, vend(A2_IF_NONE_MATCH)-1)) {
+    if(util::istartsWith(*i, "if-modified-since") ||
+       util::istartsWith(*i, "if-none-match")) {
       return true;
     }
   }

+ 1 - 3
src/HttpServer.cc

@@ -235,9 +235,7 @@ bool HttpServer::authenticate()
   }
   std::pair<Scip, Scip> p;
   util::divide(p, authHeader.begin(), authHeader.end(), ' ');
-  static const char A2_AUTHMETHOD[] = "Basic";
-  if(!util::streq(p.first.first, p.first.second,
-                  A2_AUTHMETHOD, vend(A2_AUTHMETHOD)-1)) {
+  if(!util::streq(p.first.first, p.first.second, "Basic")) {
     return false;
   }
   std::string userpass = base64::decode(p.second.first, p.second.second);

+ 8 - 21
src/Netrc.cc

@@ -154,25 +154,16 @@ void Netrc::parse(const std::string& path)
       continue;
     }
     std::vector<Scip> tokens;
-    static const char A2_DELIMS[] = " \t";
-    util::splitIterM(&buf[0], &buf[len], std::back_inserter(tokens),
-                     A2_DELIMS, vend(A2_DELIMS)-1, true);
-    static const char A2_MACHINE[] = "machine";
-    static const char A2_DEFAULT[] = "default";
-    static const char A2_LOGIN[] = "login";
-    static const char A2_PASSWORD[] = "password";
-    static const char A2_ACCOUNT[] = "account";
-    static const char A2_MACDEF[] = "macdef";
+    util::splitIterM(&buf[0], &buf[len], std::back_inserter(tokens), " \t",
+                     true);
     for(std::vector<Scip>::const_iterator iter = tokens.begin(),
           eoi = tokens.end(); iter != eoi; ++iter) {
       if(state == GET_TOKEN) {
-        if(util::streq((*iter).first, (*iter).second,
-                       A2_MACHINE, vend(A2_MACHINE)-1)) {
+        if(util::streq((*iter).first, (*iter).second, "machine")) {
           storeAuthenticator(authenticator);
           authenticator.reset(new Authenticator());
           state = SET_MACHINE;
-        } else if(util::streq((*iter).first, (*iter).second,
-                              A2_DEFAULT, vend(A2_DEFAULT)-1)) {
+        } else if(util::streq((*iter).first, (*iter).second, "default")) {
           storeAuthenticator(authenticator);
           authenticator.reset(new DefaultAuthenticator());
         } else {
@@ -182,17 +173,13 @@ void Netrc::parse(const std::string& path)
                    " or 'default' expected.",
                    std::string((*iter).first, (*iter).second).c_str()));
           }
-          if(util::streq((*iter).first, (*iter).second,
-                         A2_LOGIN, vend(A2_LOGIN)-1)) {
+          if(util::streq((*iter).first, (*iter).second, "login")) {
             state = SET_LOGIN;
-          } else if(util::streq((*iter).first, (*iter).second,
-                                A2_PASSWORD, vend(A2_PASSWORD)-1)) {
+          } else if(util::streq((*iter).first, (*iter).second, "password")) {
             state = SET_PASSWORD;
-          } else if(util::streq((*iter).first, (*iter).second,
-                                A2_ACCOUNT, vend(A2_ACCOUNT)-1)) {
+          } else if(util::streq((*iter).first, (*iter).second, "account")) {
             state = SET_ACCOUNT;
-          } else if(util::streq((*iter).first, (*iter).second,
-                                A2_MACDEF, vend(A2_MACDEF)-1)) {
+          } else if(util::streq((*iter).first, (*iter).second, "macdef")) {
             state = SET_MACDEF;
           }
         }

+ 2 - 5
src/NsCookieParser.cc

@@ -88,13 +88,10 @@ bool parseNsCookie
   // aria2 treats expiryTime == 0 means session cookie.
   cookie.setPersistent(expiryTime != 0);
   cookie.setDomain(vs[0].first, vs[0].second);
-  static const char C_TRUE[] = "TRUE";
   cookie.setHostOnly(util::isNumericHost(cookie.getDomain()) ||
-                     !util::streq(vs[1].first, vs[1].second,
-                                  C_TRUE, vend(C_TRUE)-1));
+                     !util::streq(vs[1].first, vs[1].second, "TRUE"));
   cookie.setPath(vs[2].first, vs[2].second);
-  cookie.setSecure(util::streq(vs[3].first, vs[3].second,
-                               C_TRUE, vend(C_TRUE)-1));
+  cookie.setSecure(util::streq(vs[3].first, vs[3].second, "TRUE"));
   cookie.setCreationTime(creationTime);
   return true;
 }

+ 3 - 9
src/OptionHandlerImpl.cc

@@ -528,15 +528,9 @@ void HttpProxyOptionHandler::parseArg(Option& option, const std::string& optarg)
     option.put(pref_, optarg);
   } else {
     std::string uri;
-    static const char A2_HTTP[] = "http://";
-    static const char A2_HTTPS[] = "https://";
-    static const char A2_FTP[] = "ftp://";
-    if(util::startsWith(optarg.begin(), optarg.end(),
-                        A2_HTTP, vend(A2_HTTP)-1) ||
-       util::startsWith(optarg.begin(), optarg.end(),
-                        A2_HTTPS, vend(A2_HTTPS)-1) ||
-       util::startsWith(optarg.begin(), optarg.end(),
-                        A2_FTP, vend(A2_FTP)-1)) {
+    if(util::startsWith(optarg.begin(), optarg.end(), "http://") ||
+       util::startsWith(optarg.begin(), optarg.end(), "https://") ||
+       util::startsWith(optarg.begin(), optarg.end(), "ftp://")) {
       uri = optarg;
     } else {
       uri = "http://";

+ 1 - 3
src/bittorrent_helper.cc

@@ -875,12 +875,10 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
   }
   SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
   std::string infoHash;
-  static const char A2_URN_BTIH[] = "urn:btih:";
   for(List::ValueType::const_iterator xtiter = xts->begin(),
         eoi = xts->end(); xtiter != eoi && infoHash.empty(); ++xtiter) {
     const String* xt = downcast<String>(*xtiter);
-    if(util::startsWith(xt->s().begin(), xt->s().end(),
-                        A2_URN_BTIH, vend(A2_URN_BTIH)-1)) {
+    if(util::startsWith(xt->s(), "urn:btih:")) {
       size_t size = xt->s().end()-xt->s().begin()-9;
       if(size == 32) {
         std::string rawhash = base32::decode(xt->s().begin()+9, xt->s().end());

+ 6 - 12
src/cookie_helper.cc

@@ -243,12 +243,6 @@ bool parse
   if(nvEnd != end) {
     ++nvEnd;
   }
-  static const char A2_EXPIRES[] = "expires";
-  static const char A2_MAX_AGE[] = "max-age";
-  static const char A2_DOMAIN[] = "domain";
-  static const char A2_PATH[] = "path";
-  static const char A2_SECURE[] = "secure";
-  static const char A2_HTTPONLY[] = "httponly";
   for(std::string::const_iterator i = nvEnd; i != end;) {
     std::string::const_iterator j = std::find(i, end, ';');
     std::string::const_iterator eq = std::find(i, j, '=');
@@ -264,13 +258,13 @@ bool parse
     if(j != end) {
       ++i;
     }
-    if(util::strieq(p.first, p.second, A2_EXPIRES, vend(A2_EXPIRES)-1)) {
+    if(util::strieq(p.first, p.second, "expires")) {
       if(parseDate(expiryTime, attrp.first, attrp.second)) {
         foundExpires = true;
       } else {
         return false;
       }
-    } else if(util::strieq(p.first, p.second, A2_MAX_AGE, vend(A2_MAX_AGE)-1)) {
+    } else if(util::strieq(p.first, p.second, "max-age")) {
       if(attrp.first == attrp.second ||
          (!in(static_cast<unsigned char>(*attrp.first), 0x30u, 0x39u) &&
           *attrp.first != '-')) {
@@ -300,7 +294,7 @@ bool parse
       } else {
         return false;
       }
-    } else if(util::strieq(p.first, p.second, A2_DOMAIN, vend(A2_DOMAIN)-1)) {
+    } else if(util::strieq(p.first, p.second, "domain")) {
       if(attrp.first == attrp.second) {
         return false;
       }
@@ -311,15 +305,15 @@ bool parse
         return false;
       }
       cookieDomain.assign(noDot, end);
-    } else if(util::strieq(p.first, p.second, A2_PATH, vend(A2_PATH)-1)) {
+    } else if(util::strieq(p.first, p.second, "path")) {
       if(goodPath(attrp.first, attrp.second)) {
         cookiePath.assign(attrp.first, attrp.second);
       } else {
         cookiePath = defaultPath;
       }
-    } else if(util::strieq(p.first, p.second, A2_SECURE, vend(A2_SECURE)-1)) {
+    } else if(util::strieq(p.first, p.second, "secure")) {
       secure = true;
-    } else if(util::strieq(p.first, p.second, A2_HTTPONLY, vend(A2_HTTPONLY)-1)) {
+    } else if(util::strieq(p.first, p.second, "httponly")) {
       httpOnly = true;
     }
   }

+ 4 - 12
src/json.cc

@@ -540,26 +540,18 @@ decodeGetParams(const std::string& query)
     std::vector<Scip> getParams;
     util::splitIter(query.begin()+1, query.end(), std::back_inserter(getParams),
                     '&');
-    static const char A2_METHOD[] = "method=";
-    static const char A2_ID[] = "id=";
-    static const char A2_PARAMS[] = "params=";
-    static const char A2_JSONCB[] = "jsoncallback=";
     for(std::vector<Scip>::const_iterator i =
           getParams.begin(), eoi = getParams.end(); i != eoi; ++i) {
-      if(util::startsWith((*i).first, (*i).second,
-                          A2_METHOD, vend(A2_METHOD)-1)) {
+      if(util::startsWith((*i).first, (*i).second, "method=")) {
         method.first = (*i).first+7;
         method.second = (*i).second;
-      } else if(util::startsWith((*i).first, (*i).second,
-                                 A2_ID, vend(A2_ID)-1)) {
+      } else if(util::startsWith((*i).first, (*i).second, "id=")) {
         id.first = (*i).first+3;
         id.second = (*i).second;
-      } else if(util::startsWith((*i).first, (*i).second,
-                                 A2_PARAMS, vend(A2_PARAMS)-1)) {
+      } else if(util::startsWith((*i).first, (*i).second, "params=")) {
         params.first = (*i).first+7;
         params.second = (*i).second;
-      } else if(util::startsWith((*i).first, (*i).second,
-                                 A2_JSONCB, vend(A2_JSONCB)-1)) {
+      } else if(util::startsWith((*i).first, (*i).second, "jsoncallback=")) {
         callback.assign((*i).first+13, (*i).second);
       }
     }

+ 1 - 3
src/magnet.cc

@@ -43,9 +43,7 @@ namespace magnet {
 SharedHandle<Dict> parse(const std::string& magnet)
 {
   SharedHandle<Dict> dict;
-  static const char A2_MSGNET[] = "magnet:?";
-  if(!util::startsWith(magnet.begin(), magnet.end(),
-                       A2_MSGNET, vend(A2_MSGNET)-1)) {
+  if(!util::startsWith(magnet, "magnet:?")) {
     return dict;
   }
   dict.reset(new Dict());

+ 1 - 3
src/option_processing.cc

@@ -201,9 +201,7 @@ void option_processing(Option& op, std::vector<std::string>& uris,
           keyword = TAG_BASIC;
         } else {
           keyword = op.get(PREF_HELP);
-          static const char A2_HH[] = "--";
-          if(util::startsWith(keyword.begin(), keyword.end(),
-                              A2_HH, vend(A2_HH)-1)) {
+          if(util::startsWith(keyword, "--")) {
             keyword.erase(keyword.begin(), keyword.begin()+2);
           }
           std::string::size_type eqpos = keyword.find("=");

+ 52 - 56
src/util.cc

@@ -730,24 +730,18 @@ void parsePrioritizePieceRange
 {
   std::vector<size_t> indexes;
   std::vector<Scip> parts;
-  static const char A2_HEAD[] = "head";
-  static const char A2_HEADEQ[] = "head=";
-  static const char A2_TAIL[] = "tail";
-  static const char A2_TAILEQ[] = "tail=";
   splitIter(src.begin(), src.end(), std::back_inserter(parts), ',', true);
   for(std::vector<Scip>::const_iterator i = parts.begin(),
         eoi = parts.end(); i != eoi; ++i) {
-    if(util::streq((*i).first, (*i).second, A2_HEAD, vend(A2_HEAD)-1)) {
+    if(util::streq((*i).first, (*i).second, "head")) {
       computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize);
-    } else if(util::startsWith((*i).first, (*i).second,
-                               A2_HEADEQ, vend(A2_HEADEQ)-1)) {
+    } else if(util::startsWith((*i).first, (*i).second, "head=")) {
       std::string sizestr((*i).first+5, (*i).second);
       computeHeadPieces(indexes, fileEntries, pieceLength,
                         std::max((int64_t)0, getRealSize(sizestr)));
-    } else if(util::streq((*i).first, (*i).second, A2_TAIL, vend(A2_TAIL)-1)) {
+    } else if(util::streq((*i).first, (*i).second, "tail")) {
       computeTailPieces(indexes, fileEntries, pieceLength, defaultSize);
-    } else if(util::startsWith((*i).first, (*i).second,
-                               A2_TAILEQ, vend(A2_TAILEQ)-1)) {
+    } else if(util::startsWith((*i).first, (*i).second, "tail=")) {
       std::string sizestr((*i).first+5, (*i).second);
       computeTailPieces(indexes, fileEntries, pieceLength,
                         std::max((int64_t)0, getRealSize(sizestr)));
@@ -835,8 +829,7 @@ std::string getContentDispositionFilename(const std::string& header)
   for(std::vector<std::string>::const_iterator i = params.begin(),
         eoi = params.end(); i != eoi; ++i) {
     const std::string& param = *i;
-    if(!istartsWith(param.begin(), param.end(),
-                   A2_KEYNAME, vend(A2_KEYNAME)-1) ||
+    if(!istartsWith(param, A2_KEYNAME) ||
        param.size() == sizeof(A2_KEYNAME)-1) {
       continue;
     }
@@ -893,13 +886,10 @@ std::string getContentDispositionFilename(const std::string& header)
       }
       std::string value =
         percentDecode(extValues[2].first, extValues[2].second);
-      static const char A2_ISO88591[] = "iso-8859-1";
-      if(util::strieq(extValues[0].first, extValues[0].second,
-                      A2_ISO88591, vend(A2_ISO88591)-1)) {
+      if(util::strieq(extValues[0].first, extValues[0].second, "iso-8859-1")) {
         value = iso8859ToUtf8(value);
       }
-      if(!detectDirTraversal(value) &&
-         value.find(A2STR::SLASH_C) == std::string::npos) {
+      if(!detectDirTraversal(value) && value.find("/") == std::string::npos) {
         filename = value;
       }
       if(!filename.empty()) {
@@ -929,8 +919,7 @@ std::string getContentDispositionFilename(const std::string& header)
       value = percentDecode(value.begin(), filenameLast);
       value = strip(value, TRIMMED);
       value.erase(std::remove(value.begin(), value.end(), '\\'), value.end());
-      if(!detectDirTraversal(value) &&
-         value.find(A2STR::SLASH_C) == std::string::npos) {
+      if(!detectDirTraversal(value) && value.find("/") == std::string::npos) {
         filename = value;
       }
       // continue because there is a chance we can find filename*=...
@@ -940,11 +929,12 @@ std::string getContentDispositionFilename(const std::string& header)
 }
 
 std::string randomAlpha(size_t length, const RandomizerHandle& randomizer) {
-  static const char *random_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+  static const char randomChars[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   std::string str;
   for(size_t i = 0; i < length; ++i) {
-    size_t index = randomizer->getRandomNumber(strlen(random_chars));
-    str += random_chars[index];
+    size_t index = randomizer->getRandomNumber(sizeof(randomChars)-1);
+    str += randomChars[index];
   }
   return str;
 }
@@ -1368,17 +1358,11 @@ void generateRandomKey(unsigned char* key)
 // 192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
 bool inPrivateAddress(const std::string& ipv4addr)
 {
-  static const char A2_IP10[] = "10.";
-  static const char A2_IP192[] = "192.168.";
-  static const char A2_IP172[] = "172.";
-  if(util::startsWith(ipv4addr.begin(), ipv4addr.end(),
-                      A2_IP10, vend(A2_IP10)-1) ||
-     util::startsWith(ipv4addr.begin(), ipv4addr.end(),
-                      A2_IP192, vend(A2_IP192)-1)) {
+  if(util::startsWith(ipv4addr, "10.") ||
+     util::startsWith(ipv4addr, "192.168.")) {
     return true;
   }
-  if(util::startsWith(ipv4addr.begin(), ipv4addr.end(),
-                      A2_IP172, vend(A2_IP172)-1)) {
+  if(util::startsWith(ipv4addr, "172.")) {
     for(int i = 16; i <= 31; ++i) {
       std::string t(fmt("%d.", i));
       if(util::startsWith(ipv4addr.begin()+4, ipv4addr.end(),
@@ -1401,25 +1385,12 @@ bool detectDirTraversal(const std::string& s)
       return true;
     }
   }
-
-  static const char A2_DS[] = "./";
-  static const char A2_DDS[] = "../";
-  static const char A2_SD[] = "/.";
-  static const char A2_SDD[] = "/..";
-  static const char A2_SDDS[] = "/../";
-  static const char A2_SDS[] = "/./";
-  static const char A2_DD[] = "..";
-
-  return s == A2STR::DOT_C ||
-    s == A2_DD ||
-    s[0] == '/' ||
-    util::startsWith(s.begin(), s.end(), A2_DS, vend(A2_DS)-1) ||
-    util::startsWith(s.begin(), s.end(), A2_DDS, vend(A2_DDS)-1) ||
-    s.find(A2_SDDS) != std::string::npos ||
-    s.find(A2_SDS) != std::string::npos ||
+  return s == "." || s == ".." || s[0] == '/' ||
+    util::startsWith(s, "./") || util::startsWith(s, "../") ||
+    s.find("/../") != std::string::npos ||
+    s.find("/./") != std::string::npos ||
     s[s.size()-1] == '/' ||
-    util::endsWith(s.begin(), s.end(), A2_SD, vend(A2_SD)-1) ||
-    util::endsWith(s.begin(), s.end(), A2_SDD, vend(A2_SDD)-1);
+    util::endsWith(s, "/.") || util::endsWith(s, "/..");
 }
 
 std::string escapePath(const std::string& s)
@@ -1523,12 +1494,8 @@ void executeHook
 
   memset(&si, 0, sizeof (si));
   si.cb = sizeof(STARTUPINFO);
-
   memset(&pi, 0, sizeof (pi));
-
-  static const char A2_BAT[] = ".bat";
-  bool batch = util::iendsWith(command.begin(), command.end(),
-                               A2_BAT, vend(A2_BAT)-1);
+  bool batch = util::iendsWith(command, ".bat");
   std::string cmdline;
   std::string cmdexe;
   if(batch) {
@@ -1638,13 +1605,42 @@ bool noProxyDomainMatch
  const std::string& domain)
 {
   if(!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) {
-    return util::endsWith(hostname.begin(), hostname.end(),
-                          domain.begin(), domain.end());
+    return util::endsWith(hostname, domain);
   } else {
     return hostname == domain;
   }
 }
 
+bool startsWith(const std::string& a, const char* b)
+{
+  return startsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool istartsWith(const std::string& a, const char* b)
+{
+  return istartsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool endsWith(const std::string& a, const char* b)
+{
+  return endsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool endsWith(const std::string& a, const std::string& b)
+{
+  return endsWith(a.begin(), a.end(), b.begin(), b.end());
+}
+
+bool iendsWith(const std::string& a, const char* b)
+{
+  return iendsWith(a.begin(), a.end(), b, b+strlen(b));
+}
+
+bool iendsWith(const std::string& a, const std::string& b)
+{
+  return iendsWith(a.begin(), a.end(), b.begin(), b.end());
+}
+
 } // namespace util
 
 } // namespace aria2

+ 41 - 7
src/util.h

@@ -42,6 +42,7 @@
 #include <stdint.h>
 
 #include <cstdio>
+#include <cstring>
 #include <string>
 #include <utility>
 #include <iosfwd>
@@ -478,21 +479,20 @@ OutputIterator splitIter
   return out;
 }
 
-template<typename InputIterator,
-         typename InputIterator2,
-         typename OutputIterator>
+template<typename InputIterator, typename OutputIterator>
 OutputIterator splitIterM
 (InputIterator first,
  InputIterator last,
  OutputIterator out,
- InputIterator2 dfirst,
- InputIterator2 dlast,
+ const char* delims,
  bool doStrip = false,
  bool allowEmpty = false)
 {
+  size_t numDelims = strlen(delims);
+  const char* dlast = delims+numDelims;
   for(InputIterator i = first; i != last;) {
     InputIterator j = i;
-    for(; j != last && std::find(dfirst, dlast, *j) == dlast; ++j);
+    for(; j != last && std::find(delims, dlast, *j) == dlast; ++j);
     std::pair<InputIterator, InputIterator> p(i, j);
     if(doStrip) {
       p = stripIter(i, j);
@@ -507,7 +507,7 @@ OutputIterator splitIterM
   }
   if(allowEmpty &&
      (first == last ||
-      std::find(dfirst, dlast, *(last-1)) != dlast)) {
+      std::find(delims, dlast, *(last-1)) != dlast)) {
     *out++ = std::make_pair(last, last);
   }
   return out;
@@ -556,6 +556,12 @@ bool streq
   return std::equal(first1, last1, first2);
 }
 
+template<typename InputIterator>
+bool streq(InputIterator first, InputIterator last, const char* b)
+{
+  return streq(first, last, b, b+strlen(b));
+}
+
 struct CaseCmp {
   bool operator()(char lhs, char rhs) const
   {
@@ -592,6 +598,12 @@ bool strieq
   return std::equal(first1, last1, first2, CaseCmp());
 }
 
+template<typename InputIterator>
+bool strieq(InputIterator first, InputIterator last, const char* b)
+{
+  return strieq(first, last, b, b+strlen(b));
+}
+
 template<typename InputIterator1, typename InputIterator2>
 bool startsWith
 (InputIterator1 first1,
@@ -605,6 +617,14 @@ bool startsWith
   return std::equal(first2, last2, first1);
 }
 
+template<typename InputIterator>
+bool startsWith(InputIterator first, InputIterator last, const char* b)
+{
+  return startsWith(first, last, b, b+strlen(b));
+}
+
+bool startsWith(const std::string& a, const char* b);
+
 template<typename InputIterator1, typename InputIterator2>
 bool istartsWith
 (InputIterator1 first1,
@@ -618,6 +638,14 @@ bool istartsWith
   return std::equal(first2, last2, first1, CaseCmp());
 }
 
+template<typename InputIterator>
+bool istartsWith(InputIterator first, InputIterator last, const char* b)
+{
+  return istartsWith(first, last, b, b+strlen(b));
+}
+
+bool istartsWith(const std::string& a, const char* b);
+
 template<typename InputIterator1, typename InputIterator2>
 bool endsWith
 (InputIterator1 first1,
@@ -631,6 +659,9 @@ bool endsWith
   return std::equal(first2, last2, last1-(last2-first2));
 }
 
+bool endsWith(const std::string& a, const char* b);
+bool endsWith(const std::string& a, const std::string& b);
+
 template<typename InputIterator1, typename InputIterator2>
 bool iendsWith
 (InputIterator1 first1,
@@ -644,6 +675,9 @@ bool iendsWith
   return std::equal(first2, last2, last1-(last2-first2), CaseCmp());
 }
 
+bool iendsWith(const std::string& a, const char* b);
+bool iendsWith(const std::string& a, const std::string& b);
+
 void generateRandomData(unsigned char* data, size_t length);
 
 // Saves data to file whose name is filename. If overwrite is true,

+ 16 - 30
test/UtilTest.cc

@@ -506,12 +506,11 @@ void UtilTest::testSplitIter() {
 }
 
 void UtilTest::testSplitIterM() {
-  std::string d = ";";
-  std::string md = "; ";
+  const char d[] = ";";
+  const char md[] = "; ";
   std::vector<Scip> v;
   std::string s = "k1; k2;; k3";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, true);
   CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
@@ -520,8 +519,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k1; k2; k3";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string(" k2"),
@@ -532,8 +530,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k1; k2; k3";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   md.begin(), md.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), md);
   CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
@@ -542,8 +539,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k1; k2; k3;";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   md.begin(), md.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), md, false, true);
   CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
@@ -555,8 +551,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k=v";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
   CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k=v"),
                        std::string(v[0].first, v[0].second));
@@ -564,8 +559,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = ";;k1;;k2;";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
   CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
@@ -577,8 +571,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = ";;k1;;k2;";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
@@ -586,8 +579,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "k; ";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string("k"), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[1].first, v[1].second));
@@ -595,38 +587,33 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = " ";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), true, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, true, true);
   CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
 
   v.clear();
 
   s = " ";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, true);
   CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
 
   v.clear();
 
   s = " ";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[0].first, v[0].second));
 
   v.clear();
 
   s = ";";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end());
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
   CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
 
   v.clear();
 
   s = ";";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
   CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
@@ -634,8 +621,7 @@ void UtilTest::testSplitIterM() {
   v.clear();
 
   s = "";
-  util::splitIterM(s.begin(), s.end(), std::back_inserter(v),
-                   d.begin(), d.end(), false, true);
+  util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
   CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
   CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
 }