Browse Source

attempt to implement <auto>, use _composite build rules

David Rose 21 years ago
parent
commit
67faec5f8d

+ 48 - 22
dtool/src/prc/Sources.pp

@@ -3,31 +3,57 @@
 
 #begin lib_target
   #define TARGET prc
+
+  #define COMBINED_SOURCES $[TARGET]_composite1.cxx  $[TARGET]_composite2.cxx
   
   #define SOURCES \
-    config_prc.cxx config_prc.h \
-    configDeclaration.cxx configDeclaration.I configDeclaration.h \
-    configFlags.cxx configFlags.I configFlags.h \
-    configPage.cxx configPage.I configPage.h \
-    configPageManager.cxx configPageManager.I configPageManager.h \
-    configVariable.cxx configVariable.I configVariable.h \
-    configVariableBase.cxx configVariableBase.I configVariableBase.h \
-    configVariableBool.cxx configVariableBool.I configVariableBool.h \
-    configVariableCore.cxx configVariableCore.I configVariableCore.h \
-    configVariableDouble.cxx configVariableDouble.I configVariableDouble.h \
-    configVariableEnum.cxx configVariableEnum.I configVariableEnum.h \
-    configVariableFilename.cxx configVariableFilename.I configVariableFilename.h \
-    configVariableInt.cxx configVariableInt.I configVariableInt.h \
-    configVariableList.cxx configVariableList.I configVariableList.h \
-    configVariableManager.cxx configVariableManager.I configVariableManager.h \
-    configVariableSearchPath.cxx configVariableSearchPath.I configVariableSearchPath.h \
-    configVariableString.cxx configVariableString.I configVariableString.h \
-    globPattern.cxx globPattern.I globPattern.h \
-    notify.cxx notify.I notify.h \
-    notifyCategory.cxx notifyCategory.I notifyCategory.h \
+    config_prc.h \
+    configDeclaration.I configDeclaration.h \
+    configFlags.I configFlags.h \
+    configPage.I configPage.h \
+    configPageManager.I configPageManager.h \
+    configVariable.I configVariable.h \
+    configVariableBase.I configVariableBase.h \
+    configVariableBool.I configVariableBool.h \
+    configVariableCore.I configVariableCore.h \
+    configVariableDouble.I configVariableDouble.h \
+    configVariableEnum.I configVariableEnum.h \
+    configVariableFilename.I configVariableFilename.h \
+    configVariableInt.I configVariableInt.h \
+    configVariableList.I configVariableList.h \
+    configVariableManager.I configVariableManager.h \
+    configVariableSearchPath.I configVariableSearchPath.h \
+    configVariableString.I configVariableString.h \
+    globPattern.I globPattern.h \
+    notify.I notify.h \
+    notifyCategory.I notifyCategory.h \
     notifyCategoryProxy.I notifyCategoryProxy.h \
-    notifySeverity.cxx notifySeverity.h \
-    prcKeyRegistry.cxx prcKeyRegistry.h \
+    notifySeverity.h \
+    prcKeyRegistry.h
+  
+  #define INCLUDED_SOURCES \
+    config_prc.cxx \
+    configDeclaration.cxx \
+    configFlags.cxx \
+    configPage.cxx \
+    configPageManager.cxx \
+    configVariable.cxx \
+    configVariableBase.cxx \
+    configVariableBool.cxx \
+    configVariableCore.cxx \
+    configVariableDouble.cxx \
+    configVariableEnum.cxx \
+    configVariableFilename.cxx \
+    configVariableInt.cxx \
+    configVariableList.cxx \
+    configVariableManager.cxx \
+    configVariableSearchPath.cxx \
+    configVariableString.cxx \
+    globPattern.cxx \
+    notify.cxx \
+    notifyCategory.cxx \
+    notifySeverity.cxx \
+    prcKeyRegistry.cxx
   
   #define INSTALL_HEADERS \
     config_prc.h \

+ 143 - 40
dtool/src/prc/configPageManager.cxx

@@ -96,7 +96,44 @@ reload_implicit_pages() {
   }
   _implicit_pages.clear();
 
-  // Build up the search path for .prc files.
+  // PRC_PATTERNS lists one or more filename templates separated by
+  // spaces.  Pull them out and store them in _prc_patterns.
+  _prc_patterns.clear();
+
+  string prc_patterns = PRC_PATTERNS;
+  if (!prc_patterns.empty()) {
+    vector_string pat_list;
+    ConfigDeclaration::extract_words(prc_patterns, pat_list);
+    _prc_patterns.reserve(pat_list.size());
+    for (size_t i = 0; i < pat_list.size(); ++i) {
+      GlobPattern glob(pat_list[i]);
+#ifdef WIN32
+      // On windows, the file system is case-insensitive, so the
+      // pattern should be too.
+      glob.set_case_sensitive(false);
+#endif  // WIN32
+      _prc_patterns.push_back(glob);
+    }
+  }
+
+  // Similarly for PRC_EXECUTABLE_PATTERNS.
+  _prc_executable_patterns.clear();
+
+  string prc_executable_patterns = PRC_EXECUTABLE_PATTERNS;
+  if (!prc_executable_patterns.empty()) {
+    vector_string pat_list;
+    ConfigDeclaration::extract_words(prc_executable_patterns, pat_list);
+    _prc_executable_patterns.reserve(pat_list.size());
+    for (size_t i = 0; i < pat_list.size(); ++i) {
+      GlobPattern glob(pat_list[i]);
+#ifdef WIN32
+      glob.set_case_sensitive(false);
+#endif  // WIN32
+      _prc_executable_patterns.push_back(glob);
+    }
+  }
+
+  // Now build up the search path for .prc files.
   _search_path.clear();
 
   // PRC_DIR_ENVVARS lists one or more environment variables separated
@@ -109,7 +146,10 @@ reload_implicit_pages() {
     for (size_t i = 0; i < prc_dir_envvar_list.size(); ++i) {
       string prc_dir = ExecutionEnvironment::get_environment_variable(prc_dir_envvar_list[i]);
       if (!prc_dir.empty()) {
-        _search_path.append_directory(Filename::from_os_specific(prc_dir));
+        Filename prc_dir_filename = Filename::from_os_specific(prc_dir);
+        if (scan_auto_prc_dir(prc_dir_filename)) {
+          _search_path.append_directory(prc_dir_filename);
+        }
       }
     }
   }
@@ -136,44 +176,10 @@ reload_implicit_pages() {
     string default_prc_dir = DEFAULT_PRC_DIR;
     if (!default_prc_dir.empty()) {
       // It's already from-os-specific by ppremake.
-      _search_path.append_directory(default_prc_dir);
-    }
-  }
-
-  // PRC_PATTERNS lists one or more filename templates separated by
-  // spaces.  Pull them out too.
-  _prc_patterns.clear();
-
-  string prc_patterns = PRC_PATTERNS;
-  if (!prc_patterns.empty()) {
-    vector_string pat_list;
-    ConfigDeclaration::extract_words(prc_patterns, pat_list);
-    _prc_patterns.reserve(pat_list.size());
-    for (size_t i = 0; i < pat_list.size(); ++i) {
-      GlobPattern glob(pat_list[i]);
-#ifdef WIN32
-      // On windows, the file system is case-insensitive, so the
-      // pattern should be too.
-      glob.set_case_sensitive(false);
-#endif  // WIN32
-      _prc_patterns.push_back(glob);
-    }
-  }
-
-  // Similarly for PRC_EXECUTABLE_PATTERNS.
-  _prc_executable_patterns.clear();
-
-  string prc_executable_patterns = PRC_EXECUTABLE_PATTERNS;
-  if (!prc_executable_patterns.empty()) {
-    vector_string pat_list;
-    ConfigDeclaration::extract_words(prc_executable_patterns, pat_list);
-    _prc_executable_patterns.reserve(pat_list.size());
-    for (size_t i = 0; i < pat_list.size(); ++i) {
-      GlobPattern glob(pat_list[i]);
-#ifdef WIN32
-      glob.set_case_sensitive(false);
-#endif  // WIN32
-      _prc_executable_patterns.push_back(glob);
+      Filename prc_dir_filename = default_prc_dir;
+      if (scan_auto_prc_dir(prc_dir_filename)) {
+        _search_path.append_directory(default_prc_dir);
+      }
     }
   }
 
@@ -415,3 +421,100 @@ sort_pages() {
 
   _pages_sorted = true;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigPageManager::scan_auto_prc_dir
+//       Access: Private
+//  Description: Checks for the prefix "<auto>" in the value of the
+//               $PRC_DIR environment variable (or in the compiled-in
+//               DEFAULT_PRC_DIR value).  If it is found, then the
+//               actual directory is determined by searching upward
+//               from the executable's starting directory, or from the
+//               current working directory, until at least one .prc
+//               file is found.
+//
+//               Returns true if the prc_dir has been filled with a
+//               valid directory name, false if no good directory name
+//               was found.
+////////////////////////////////////////////////////////////////////
+bool ConfigPageManager::
+scan_auto_prc_dir(Filename &prc_dir) const {
+  string prc_dir_string = prc_dir;
+  if (prc_dir_string.substr(0, 6) == "<auto>") {
+    Filename suffix = prc_dir_string.substr(6);
+    
+    // Start at the executable directory.
+    Filename binary = ExecutionEnvironment::get_binary_name();
+    Filename dir = binary.get_dirname();
+
+    if (scan_up_from(prc_dir, dir, suffix)) {
+      return true;
+    }
+    
+    // Try the current working directory.
+    dir = ExecutionEnvironment::get_cwd();
+    if (scan_up_from(prc_dir, dir, suffix)) {
+      return true;
+    }
+
+    // Didn't find it; too bad.
+    cerr << "Warning: unable to auto-locate config files in directory named by \""
+         << prc_dir << "\".\n";
+    return false;
+  }
+
+  // The filename did not begin with "<auto>", so it stands unchanged.
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConfigPageManager::scan_up_from
+//       Access: Private
+//  Description: Used to implement scan_auto_prc_dir(), above, this
+//               scans upward from the indicated directory name until
+//               a directory is found that includes at least one .prc
+//               file, or the root directory is reached.  
+//
+//               If a match is found, puts it result and returns true;
+//               otherwise, returns false.
+////////////////////////////////////////////////////////////////////
+bool ConfigPageManager::
+scan_up_from(Filename &result, const Filename &dir, 
+             const Filename &suffix) const {
+  Filename consider(dir, suffix);
+
+  vector_string files;
+  if (consider.scan_directory(files)) {
+    vector_string::const_iterator fi;
+    for (fi = files.begin(); fi != files.end(); ++fi) {
+      Globs::const_iterator gi;
+      for (gi = _prc_patterns.begin();
+           gi != _prc_patterns.end();
+           ++gi) {
+        if ((*gi).matches(*fi)) {
+          result = consider;
+          return true;
+        }
+      }
+      
+      for (gi = _prc_executable_patterns.begin();
+           gi != _prc_executable_patterns.end();
+           ++gi) {
+        if ((*gi).matches(*fi)) {
+          result = consider;
+          return true;
+        }
+      }
+    }
+  }
+
+  Filename parent = dir.get_dirname();
+
+  if (dir == parent) {
+    // Too bad; couldn't find a match.
+    return false;
+  }
+
+  // Recursively try again on the parent.
+  return scan_up_from(result, parent, suffix);
+}

+ 4 - 0
dtool/src/prc/configPageManager.h

@@ -69,6 +69,10 @@ private:
   INLINE void check_sort_pages() const;
   void sort_pages();
 
+  bool scan_auto_prc_dir(Filename &prc_dir) const;
+  bool scan_up_from(Filename &result, const Filename &dir, 
+                    const Filename &suffix) const;
+
   typedef pvector<ConfigPage *> Pages;
   Pages _implicit_pages;
   Pages _explicit_pages;

+ 11 - 0
dtool/src/prc/prc_composite1.cxx

@@ -0,0 +1,11 @@
+#include "config_prc.cxx"
+#include "configDeclaration.cxx"
+#include "configFlags.cxx"
+#include "configPage.cxx"
+#include "configPageManager.cxx"
+#include "configVariable.cxx"
+#include "configVariableBase.cxx"
+#include "configVariableBool.cxx"
+#include "configVariableCore.cxx"
+#include "configVariableDouble.cxx"
+#include "configVariableEnum.cxx"

+ 11 - 0
dtool/src/prc/prc_composite2.cxx

@@ -0,0 +1,11 @@
+#include "configVariableFilename.cxx"
+#include "configVariableInt.cxx"
+#include "configVariableList.cxx"
+#include "configVariableManager.cxx"
+#include "configVariableSearchPath.cxx"
+#include "configVariableString.cxx"
+#include "globPattern.cxx"
+#include "notify.cxx"
+#include "notifyCategory.cxx"
+#include "notifySeverity.cxx"
+#include "prcKeyRegistry.cxx"