ppNamedScopes.cxx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Filename: ppNamedScopes.cxx
  2. // Created by: drose (27Sep00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. #include "ppNamedScopes.h"
  6. #include "ppScope.h"
  7. #include "ppDirectory.h"
  8. #include <assert.h>
  9. #include <algorithm>
  10. // An STL object to sort named scopes in order by dependency and then
  11. // by directory name, used in sort_by_dependency().
  12. class SortScopesByDependencyAndName {
  13. public:
  14. bool operator () (PPScope *a, PPScope *b) const {
  15. PPDirectory *da = a->get_directory();
  16. PPDirectory *db = b->get_directory();
  17. // Scopes without associated directories appear first in the list.
  18. bool da_is_null = (da == (PPDirectory *)NULL);
  19. bool db_is_null = (db == (PPDirectory *)NULL);
  20. if (da_is_null != db_is_null) {
  21. return da_is_null > db_is_null;
  22. } else if (da_is_null) {
  23. // If two scopes have no associated directories (!) they are
  24. // considered equivalent.
  25. return false;
  26. } else {
  27. // Otherwise, both scopes have associated directories, and we
  28. // can properly put them in order by dependencies.
  29. assert(da != (PPDirectory *)NULL);
  30. assert(db != (PPDirectory *)NULL);
  31. if (da->get_depends_index() != db->get_depends_index()) {
  32. return da->get_depends_index() < db->get_depends_index();
  33. }
  34. return da->get_dirname() < db->get_dirname();
  35. }
  36. }
  37. };
  38. ////////////////////////////////////////////////////////////////////
  39. // Function: PPNamedScopes::Constructor
  40. // Access: Public
  41. // Description:
  42. ////////////////////////////////////////////////////////////////////
  43. PPNamedScopes::
  44. PPNamedScopes() {
  45. }
  46. ////////////////////////////////////////////////////////////////////
  47. // Function: PPNamedScopes::Destructor
  48. // Access: Public
  49. // Description:
  50. ////////////////////////////////////////////////////////////////////
  51. PPNamedScopes::
  52. ~PPNamedScopes() {
  53. }
  54. ////////////////////////////////////////////////////////////////////
  55. // Function: PPNamedScopes::make_scope
  56. // Access: Public
  57. // Description: Creates a new scope in the current directory name
  58. // with the indicated scope name.
  59. ////////////////////////////////////////////////////////////////////
  60. PPScope *PPNamedScopes::
  61. make_scope(const string &name) {
  62. PPScope *scope = new PPScope(this);
  63. _directories[_current][name].push_back(scope);
  64. return scope;
  65. }
  66. ////////////////////////////////////////////////////////////////////
  67. // Function: PPNamedScopes::get_scopes
  68. // Access: Public
  69. // Description: Returns a list of all the named scopes matching the
  70. // given scope name. The scope name may be of the form
  71. // "dirname/scopename", in which case the dirname may be
  72. // another directory name, or "." or "*". If the
  73. // dirname is ".", it is the same as the current
  74. // directory name; if it is "*", it represents all
  75. // directory names. If omitted, the current directory
  76. // name is implied.
  77. //
  78. // It is the responsibility of the user to ensure that
  79. // scopes is empty before calling this function; this
  80. // will append to the existing vector without first
  81. // clearing it.
  82. ////////////////////////////////////////////////////////////////////
  83. void PPNamedScopes::
  84. get_scopes(const string &name, Scopes &scopes) const {
  85. string dirname = _current;
  86. string scopename = name;
  87. size_t slash = name.find(SCOPE_DIRNAME_SEPARATOR);
  88. if (slash != string::npos) {
  89. dirname = name.substr(0, slash);
  90. scopename = name.substr(slash + 1);
  91. if (dirname == SCOPE_DIRNAME_CURRENT) {
  92. dirname = _current;
  93. }
  94. }
  95. Directories::const_iterator di;
  96. if (dirname == SCOPE_DIRNAME_WILDCARD) {
  97. for (di = _directories.begin(); di != _directories.end(); ++di) {
  98. p_get_scopes((*di).second, scopename, scopes);
  99. }
  100. } else {
  101. di = _directories.find(dirname);
  102. if (di != _directories.end()) {
  103. p_get_scopes((*di).second, scopename, scopes);
  104. }
  105. }
  106. }
  107. ////////////////////////////////////////////////////////////////////
  108. // Function: PPNamedScopes::sort_by_dependency
  109. // Access: Public, Static
  110. // Description: Sorts the previously-generated list of scopes into
  111. // order such that the later scopes depend on the
  112. // earlier scopes.
  113. ////////////////////////////////////////////////////////////////////
  114. void PPNamedScopes::
  115. sort_by_dependency(PPNamedScopes::Scopes &scopes) {
  116. sort(scopes.begin(), scopes.end(), SortScopesByDependencyAndName());
  117. }
  118. ////////////////////////////////////////////////////////////////////
  119. // Function: PPNamedScopes::set_current
  120. // Access: Public
  121. // Description: Changes the currently-active directory, i.e. the
  122. // dirname represented by ".".
  123. ////////////////////////////////////////////////////////////////////
  124. void PPNamedScopes::
  125. set_current(const string &dirname) {
  126. _current = dirname;
  127. }
  128. ////////////////////////////////////////////////////////////////////
  129. // Function: PPNamedScopes::p_get_scopes
  130. // Access: Private
  131. // Description: Adds the scopes from the given directory with the
  132. // matching name into the returned vector.
  133. ////////////////////////////////////////////////////////////////////
  134. void PPNamedScopes::
  135. p_get_scopes(const PPNamedScopes::Named &named, const string &name,
  136. Scopes &scopes) const {
  137. Named::const_iterator ni;
  138. if (name == "*") {
  139. // Scope name "*" means all nested scopes in this directory,
  140. // except for the empty-name scope (which is the outer scope).
  141. for (ni = named.begin(); ni != named.end(); ++ni) {
  142. if (!(*ni).first.empty()) {
  143. const Scopes &s = (*ni).second;
  144. scopes.insert(scopes.end(), s.begin(), s.end());
  145. }
  146. }
  147. } else {
  148. ni = named.find(name);
  149. if (ni != named.end()) {
  150. const Scopes &s = (*ni).second;
  151. scopes.insert(scopes.end(), s.begin(), s.end());
  152. }
  153. }
  154. }