|
|
@@ -19,6 +19,7 @@
|
|
|
#include "findApproxPath.h"
|
|
|
#include "config_pgraph.h"
|
|
|
|
|
|
+#include "string_utils.h"
|
|
|
#include "pandaNode.h"
|
|
|
|
|
|
|
|
|
@@ -37,6 +38,10 @@ matches(PandaNode *node) const {
|
|
|
// Match the node's name exactly.
|
|
|
return (_name == node->get_name());
|
|
|
|
|
|
+ case CT_match_name_insensitive:
|
|
|
+ // Match the node's name exactly, with case-insensitive comparison.
|
|
|
+ return cmp_nocase(_name, node->get_name()) == 0;
|
|
|
+
|
|
|
case CT_match_name_glob:
|
|
|
// Match the node's name according to filename globbing rules.
|
|
|
return (_glob.matches(node->get_name()));
|
|
|
@@ -86,6 +91,7 @@ output(ostream &out) const {
|
|
|
out << _type;
|
|
|
switch (_type) {
|
|
|
case CT_match_name:
|
|
|
+ case CT_match_name_insensitive:
|
|
|
case CT_match_name_glob:
|
|
|
case CT_match_tag:
|
|
|
out << " \"" << _name << "\"";
|
|
|
@@ -119,12 +125,13 @@ output(ostream &out) const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
bool FindApproxPath::
|
|
|
add_string(const string &str_path) {
|
|
|
+ // First, chop the string up by slashes into its components.
|
|
|
+ vector_string components;
|
|
|
+
|
|
|
size_t start = 0;
|
|
|
size_t slash = str_path.find('/');
|
|
|
while (slash != string::npos) {
|
|
|
- if (!add_component(str_path.substr(start, slash - start))) {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ components.push_back(str_path.substr(start, slash - start));
|
|
|
start = slash + 1;
|
|
|
slash = str_path.find('/', start);
|
|
|
}
|
|
|
@@ -139,12 +146,20 @@ add_string(const string &str_path) {
|
|
|
semicolon = string::npos;
|
|
|
}
|
|
|
|
|
|
- if (!add_component(str_path.substr(start, semicolon - start))) {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ components.push_back(str_path.substr(start, semicolon - start));
|
|
|
|
|
|
if (semicolon != string::npos) {
|
|
|
- return add_flags(str_path.substr(semicolon + 1));
|
|
|
+ if (!add_flags(str_path.substr(semicolon + 1))) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Now decode each component and add it to the path.
|
|
|
+ vector_string::const_iterator ci;
|
|
|
+ for (ci = components.begin(); ci != components.end(); ++ci) {
|
|
|
+ if (!add_component(*ci)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
@@ -192,6 +207,10 @@ add_flags(const string &str_flags) {
|
|
|
_return_stashed = on;
|
|
|
break;
|
|
|
|
|
|
+ case 'i':
|
|
|
+ _case_insensitive = on;
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
pgraph_cat.error()
|
|
|
<< "Invalid control flag string: " << str_flags << "\n";
|
|
|
@@ -278,6 +297,152 @@ add_component(string str_component) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_name
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that must match the name of a node
|
|
|
+// exactly.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_name(const string &name, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = _case_insensitive ? CT_match_name_insensitive : CT_match_name;
|
|
|
+ comp._name = name;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_name_glob
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that must match the name of a node
|
|
|
+// using standard shell globbing rules, with wildcard
|
|
|
+// characters accepted.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_name_glob(const string &name, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_name_glob;
|
|
|
+ comp._name = name;
|
|
|
+ comp._glob.set_pattern(name);
|
|
|
+ comp._glob.set_case_sensitive(!_case_insensitive);
|
|
|
+ comp._flags = flags;
|
|
|
+ if (!comp._glob.has_glob_characters()) {
|
|
|
+ // The glob pattern contains no special characters; make it a
|
|
|
+ // literal match for efficiency.
|
|
|
+ add_match_name(name, flags);
|
|
|
+ } else {
|
|
|
+ _path.push_back(comp);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_exact_type
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that must match the type of a node
|
|
|
+// exactly, with no derived types matching.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_exact_type(TypeHandle type, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_exact_type;
|
|
|
+ comp._type_handle = type;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_inexact_type
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that must match the type of a node
|
|
|
+// or be a base class of the node's type.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_inexact_type(TypeHandle type, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_inexact_type;
|
|
|
+ comp._type_handle = type;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_tag
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that will match a node that has a
|
|
|
+// tag with the indicated key, no matter what the value
|
|
|
+// is.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_tag(const string &name, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_tag;
|
|
|
+ comp._name = name;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_tag_value
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that will match a node that has a
|
|
|
+// tag with the indicated key. The value may be "*" to
|
|
|
+// match any value, or a particular glob pattern to
|
|
|
+// match only those nodes with the indicated value.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_tag_value(const string &name, const string &value, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_tag_value;
|
|
|
+ comp._name = name;
|
|
|
+ comp._glob.set_pattern(value);
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_one
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that will match any node (but not a
|
|
|
+// chain of many nodes).
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_one(int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_one;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_many
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that will match a chain of zero or
|
|
|
+// more consecutive nodes.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_many(int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_many;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: FindApproxPath::add_match_pointer
|
|
|
+// Access: Public
|
|
|
+// Description: Adds a component that must match a particular node
|
|
|
+// exactly, by pointer.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void FindApproxPath::
|
|
|
+add_match_pointer(PandaNode *pointer, int flags) {
|
|
|
+ Component comp;
|
|
|
+ comp._type = CT_match_pointer;
|
|
|
+ comp._pointer = pointer;
|
|
|
+ comp._flags = flags;
|
|
|
+ _path.push_back(comp);
|
|
|
+}
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: FindApproxPath::output
|
|
|
// Access: Public
|
|
|
@@ -304,6 +469,9 @@ operator << (ostream &out, FindApproxPath::ComponentType type) {
|
|
|
case FindApproxPath::CT_match_name:
|
|
|
return out << "match_name";
|
|
|
|
|
|
+ case FindApproxPath::CT_match_name_insensitive:
|
|
|
+ return out << "match_name_insensitive";
|
|
|
+
|
|
|
case FindApproxPath::CT_match_name_glob:
|
|
|
return out << "match_name_glob";
|
|
|
|