Poodletooth-iLand/build/nirai/panda3d/ppremake/ppNamedScopes.cxx
2015-11-14 14:28:53 -05:00

173 lines
5.9 KiB
C++

// Filename: ppNamedScopes.cxx
// Created by: drose (27Sep00)
//
////////////////////////////////////////////////////////////////////
#include "ppNamedScopes.h"
#include "ppScope.h"
#include "ppDirectory.h"
#include <assert.h>
#include <algorithm>
// An STL object to sort named scopes in order by dependency and then
// by directory name, used in sort_by_dependency().
class SortScopesByDependencyAndName {
public:
bool operator () (PPScope *a, PPScope *b) const {
PPDirectory *da = a->get_directory();
PPDirectory *db = b->get_directory();
// Scopes without associated directories appear first in the list.
bool da_is_null = (da == (PPDirectory *)NULL);
bool db_is_null = (db == (PPDirectory *)NULL);
if (da_is_null != db_is_null) {
return da_is_null > db_is_null;
} else if (da_is_null) {
// If two scopes have no associated directories (!) they are
// considered equivalent.
return false;
} else {
// Otherwise, both scopes have associated directories, and we
// can properly put them in order by dependencies.
assert(da != (PPDirectory *)NULL);
assert(db != (PPDirectory *)NULL);
if (da->get_depends_index() != db->get_depends_index()) {
return da->get_depends_index() < db->get_depends_index();
}
return da->get_dirname() < db->get_dirname();
}
}
};
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PPNamedScopes::
PPNamedScopes() {
}
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PPNamedScopes::
~PPNamedScopes() {
}
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::make_scope
// Access: Public
// Description: Creates a new scope in the current directory name
// with the indicated scope name.
////////////////////////////////////////////////////////////////////
PPScope *PPNamedScopes::
make_scope(const string &name) {
PPScope *scope = new PPScope(this);
_directories[_current][name].push_back(scope);
return scope;
}
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::get_scopes
// Access: Public
// Description: Returns a list of all the named scopes matching the
// given scope name. The scope name may be of the form
// "dirname/scopename", in which case the dirname may be
// another directory name, or "." or "*". If the
// dirname is ".", it is the same as the current
// directory name; if it is "*", it represents all
// directory names. If omitted, the current directory
// name is implied.
//
// It is the responsibility of the user to ensure that
// scopes is empty before calling this function; this
// will append to the existing vector without first
// clearing it.
////////////////////////////////////////////////////////////////////
void PPNamedScopes::
get_scopes(const string &name, Scopes &scopes) const {
string dirname = _current;
string scopename = name;
size_t slash = name.find(SCOPE_DIRNAME_SEPARATOR);
if (slash != string::npos) {
dirname = name.substr(0, slash);
scopename = name.substr(slash + 1);
if (dirname == SCOPE_DIRNAME_CURRENT) {
dirname = _current;
}
}
Directories::const_iterator di;
if (dirname == SCOPE_DIRNAME_WILDCARD) {
for (di = _directories.begin(); di != _directories.end(); ++di) {
p_get_scopes((*di).second, scopename, scopes);
}
} else {
di = _directories.find(dirname);
if (di != _directories.end()) {
p_get_scopes((*di).second, scopename, scopes);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::sort_by_dependency
// Access: Public, Static
// Description: Sorts the previously-generated list of scopes into
// order such that the later scopes depend on the
// earlier scopes.
////////////////////////////////////////////////////////////////////
void PPNamedScopes::
sort_by_dependency(PPNamedScopes::Scopes &scopes) {
sort(scopes.begin(), scopes.end(), SortScopesByDependencyAndName());
}
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::set_current
// Access: Public
// Description: Changes the currently-active directory, i.e. the
// dirname represented by ".".
////////////////////////////////////////////////////////////////////
void PPNamedScopes::
set_current(const string &dirname) {
_current = dirname;
}
////////////////////////////////////////////////////////////////////
// Function: PPNamedScopes::p_get_scopes
// Access: Private
// Description: Adds the scopes from the given directory with the
// matching name into the returned vector.
////////////////////////////////////////////////////////////////////
void PPNamedScopes::
p_get_scopes(const PPNamedScopes::Named &named, const string &name,
Scopes &scopes) const {
Named::const_iterator ni;
if (name == "*") {
// Scope name "*" means all nested scopes in this directory,
// except for the empty-name scope (which is the outer scope).
for (ni = named.begin(); ni != named.end(); ++ni) {
if (!(*ni).first.empty()) {
const Scopes &s = (*ni).second;
scopes.insert(scopes.end(), s.begin(), s.end());
}
}
} else {
ni = named.find(name);
if (ni != named.end()) {
const Scopes &s = (*ni).second;
scopes.insert(scopes.end(), s.begin(), s.end());
}
}
}