-////////////////////////////////////////////////////////////////////////////////
-
-// Author: Andy Rushton
-// Copyright: (c) Southampton University 1999-2004
-// (c) Andy Rushton 2004-2009
-// License: BSD License, see ../docs/license.html
-
-// Simple wildcard matching function.
-
-// WARNING: wheel re-invention follows
-// Given that all shells perform wildcard matching, why don't the library writers put it in the C run-time????????
-
-////////////////////////////////////////////////////////////////////////////////
-#include "wildcard.hpp"
-
-namespace stlplus
-{
-
- // function for testing whether a character matches a set
- // I can't remember the exact rules and I have no definitive references but:
- // a set contains characters, escaped characters (I think) and ranges in the form a-z
- // The character '-' can only appear at the start of the set where it is not interpreted as a range
- // This is a horrible mess - blame the Unix folks for making a hash of wildcards
- // first expand any ranges and remove escape characters to make life more palatable
-
- static bool match_set (const std::string& set, char match)
- {
- std::string simple_set;
- for (std::string::const_iterator i = set.begin(); i != set.end(); ++i)
- {
- switch(*i)
- {
- case '-':
- {
- if (i == set.begin())
- {
- simple_set += *i;
- }
- else if (i+1 == set.end())
- {
- return false;
- }
- else
- {
- // found a set. The first character is already in the result, so first remove it (the set might be empty)
- simple_set.erase(simple_set.end()-1);
- char last = *++i;
- for (char ch = *(i-2); ch <= last; ch++)
- {
- simple_set += ch;
- }
- }
- break;
- }
- case '\\':
- if (i+1 == set.end()) {return false;}
- simple_set += *++i;
- break;
- default:
- simple_set += *i;
- break;
- }
- }
- std::string::size_type result = simple_set.find(match);
- return result != std::string::npos;
- }
-
- // the recursive bit - basically whenever a * is found you recursively call this for each candidate substring match
- // until either it succeeds or you run out of string to match
- // for each * in the wildcard another level of recursion is created
-
- static bool match_remainder (const std::string& wild, std::string::const_iterator wildi, const std::string& match, std::string::const_iterator matchi)
- {
- //cerr << "match_remainder called at " << *matchi << " with wildcard " << *wildi << endl;
- while (wildi != wild.end() && matchi != match.end())
- {
- //cerr << "trying to match " << *matchi << " with wildcard " << *wildi << endl;
- switch(*wildi)
- {
- case '*':
- {
- ++wildi;
- ++matchi;
- for (std::string::const_iterator i = matchi; i != match.end(); ++i)
- {
- // deal with * at the end of the wildcard - there is no remainder then
- if (wildi == wild.end())
- {
- if (i == match.end()-1)
- return true;
- }
- else if (match_remainder(wild, wildi, match, i))
- {
- return true;
- }
- }
- return false;
- }
- case '[':
- {
- // scan for the end of the set using a similar method for avoiding escaped characters
- bool found = false;
- std::string::const_iterator end = wildi + 1;
- for (; !found && end != wild.end(); ++end)
- {
- switch(*end)
- {
- case ']':
- {
- // found the set, now match with its contents excluding the brackets
- if (!match_set(wild.substr(wildi - wild.begin() + 1, end - wildi - 1), *matchi))
- return false;
- found = true;
- break;
- }
- case '\\':
- if (end == wild.end()-1)
- return false;
- ++end;
- break;
- default:
- break;
- }
- }
- if (!found)
- return false;
- ++matchi;
- wildi = end;
- break;
- }
- case '?':
- ++wildi;
- ++matchi;
- break;
- case '\\':
- if (wildi == wild.end()-1)
- return false;
- ++wildi;
- if (*wildi != *matchi)
- return false;
- ++wildi;
- ++matchi;
- break;
- default:
- if (*wildi != *matchi)
- return false;
- ++wildi;
- ++matchi;
- break;
- }
- }
- bool result = wildi == wild.end() && matchi == match.end();
- return result;
- }
-
- // like all recursions the exported function has a simpler interface than the
- // recursive function and is just a 'seed' to the recursion itself
-
- bool wildcard(const std::string& wild, const std::string& match)
- {
- return match_remainder(wild, wild.begin(), match, match.begin());
- }
-
-} // end namespace stlplus
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Author: Andy Rushton\r
+// Copyright: (c) Southampton University 1999-2004\r
+// (c) Andy Rushton 2004 onwards\r
+// License: BSD License, see ../docs/license.html\r
+\r
+// Simple wildcard matching function.\r
+\r
+// WARNING: wheel re-invention follows\r
+// Given that all shells perform wildcard matching, why don't the library writers put it in the C run-time????????\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+#include "wildcard.hpp"\r
+\r
+namespace stlplus\r
+{\r
+\r
+ // function for testing whether a character matches a set\r
+ // I can't remember the exact rules and I have no definitive references but:\r
+ // a set contains characters, escaped characters (I think) and ranges in the form a-z\r
+ // The character '-' can only appear at the start of the set where it is not interpreted as a range\r
+ // This is a horrible mess - blame the Unix folks for making a hash of wildcards\r
+ // first expand any ranges and remove escape characters to make life more palatable\r
+\r
+ static bool match_set (const std::string& set, char match)\r
+ {\r
+ std::string simple_set;\r
+ for (std::string::const_iterator i = set.begin(); i != set.end(); ++i)\r
+ {\r
+ switch(*i)\r
+ {\r
+ case '-':\r
+ {\r
+ if (i == set.begin())\r
+ {\r
+ simple_set += *i;\r
+ }\r
+ else if (i+1 == set.end())\r
+ {\r
+ return false;\r
+ }\r
+ else\r
+ {\r
+ // found a set. The first character is already in the result, so first remove it (the set might be empty)\r
+ simple_set.erase(simple_set.end()-1);\r
+ char last = *++i;\r
+ for (char ch = *(i-2); ch <= last; ch++)\r
+ {\r
+ simple_set += ch;\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ case '\\':\r
+ if (i+1 == set.end()) {return false;}\r
+ simple_set += *++i;\r
+ break;\r
+ default:\r
+ simple_set += *i;\r
+ break;\r
+ }\r
+ }\r
+ std::string::size_type result = simple_set.find(match);\r
+ return result != std::string::npos;\r
+ }\r
+\r
+ // the recursive bit - basically whenever a * is found you recursively call this for each candidate substring match\r
+ // until either it succeeds or you run out of string to match\r
+ // for each * in the wildcard another level of recursion is created\r
+\r
+ static bool match_remainder (const std::string& wild, std::string::const_iterator wildi, const std::string& match, std::string::const_iterator matchi)\r
+ {\r
+ //cerr << "match_remainder called at " << *matchi << " with wildcard " << *wildi << endl;\r
+ while (wildi != wild.end() && matchi != match.end())\r
+ {\r
+ //cerr << "trying to match " << *matchi << " with wildcard " << *wildi << endl;\r
+ switch(*wildi)\r
+ {\r
+ case '*':\r
+ {\r
+ ++wildi;\r
+ ++matchi;\r
+ for (std::string::const_iterator i = matchi; i != match.end(); ++i)\r
+ {\r
+ // deal with * at the end of the wildcard - there is no remainder then\r
+ if (wildi == wild.end())\r
+ {\r
+ if (i == match.end()-1)\r
+ return true;\r
+ }\r
+ else if (match_remainder(wild, wildi, match, i))\r
+ {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ case '[':\r
+ {\r
+ // scan for the end of the set using a similar method for avoiding escaped characters\r
+ bool found = false;\r
+ std::string::const_iterator end = wildi + 1;\r
+ for (; !found && end != wild.end(); ++end)\r
+ {\r
+ switch(*end)\r
+ {\r
+ case ']':\r
+ {\r
+ // found the set, now match with its contents excluding the brackets\r
+ if (!match_set(wild.substr(wildi - wild.begin() + 1, end - wildi - 1), *matchi))\r
+ return false;\r
+ found = true;\r
+ break;\r
+ }\r
+ case '\\':\r
+ if (end == wild.end()-1)\r
+ return false;\r
+ ++end;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ if (!found)\r
+ return false;\r
+ ++matchi;\r
+ wildi = end;\r
+ break;\r
+ }\r
+ case '?':\r
+ ++wildi;\r
+ ++matchi;\r
+ break;\r
+ case '\\':\r
+ if (wildi == wild.end()-1)\r
+ return false;\r
+ ++wildi;\r
+ if (*wildi != *matchi)\r
+ return false;\r
+ ++wildi;\r
+ ++matchi;\r
+ break;\r
+ default:\r
+ if (*wildi != *matchi)\r
+ return false;\r
+ ++wildi;\r
+ ++matchi;\r
+ break;\r
+ }\r
+ }\r
+ bool result = wildi == wild.end() && matchi == match.end();\r
+ return result;\r
+ }\r
+\r
+ // like all recursions the exported function has a simpler interface than the\r
+ // recursive function and is just a 'seed' to the recursion itself\r
+\r
+ bool wildcard(const std::string& wild, const std::string& match)\r
+ {\r
+ return match_remainder(wild, wild.begin(), match, match.begin());\r
+ }\r
+\r
+} // end namespace stlplus\r