diff --git a/dtool/src/prc/Sources.pp b/dtool/src/prc/Sources.pp index e0f11d6fcf..2d1817547e 100644 --- a/dtool/src/prc/Sources.pp +++ b/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 \ diff --git a/dtool/src/prc/configPageManager.cxx b/dtool/src/prc/configPageManager.cxx index 04adb94d48..6114fb7034 100644 --- a/dtool/src/prc/configPageManager.cxx +++ b/dtool/src/prc/configPageManager.cxx @@ -96,52 +96,8 @@ reload_implicit_pages() { } _implicit_pages.clear(); - // Build up the search path for .prc files. - _search_path.clear(); - - // PRC_DIR_ENVVARS lists one or more environment variables separated - // by spaces. Pull them out, and each of those contains the name of - // a single directory to search. Add it to the search path. - string prc_dir_envvars = PRC_DIR_ENVVARS; - if (!prc_dir_envvars.empty()) { - vector_string prc_dir_envvar_list; - ConfigDeclaration::extract_words(prc_dir_envvars, prc_dir_envvar_list); - 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)); - } - } - } - - // PRC_PATH_ENVVARS lists one or more environment variables separated - // by spaces. Pull them out, and then each one of those contains a - // list of directories to search. Add each of those to the search - // path. - string prc_path_envvars = PRC_PATH_ENVVARS; - if (!prc_path_envvars.empty()) { - vector_string prc_path_envvar_list; - ConfigDeclaration::extract_words(prc_path_envvars, prc_path_envvar_list); - for (size_t i = 0; i < prc_path_envvar_list.size(); ++i) { - string prc_path = ExecutionEnvironment::get_environment_variable(prc_path_envvar_list[i]); - if (!prc_path.empty()) { - _search_path.append_path(prc_path); - } - } - } - - if (_search_path.is_empty()) { - // If nothing's on the search path (PRC_DIR and PRC_PATH were not - // defined), then use the DEFAULT_PRC_DIR. - 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. + // spaces. Pull them out and store them in _prc_patterns. _prc_patterns.clear(); string prc_patterns = PRC_PATTERNS; @@ -177,6 +133,56 @@ reload_implicit_pages() { } } + // Now build up the search path for .prc files. + _search_path.clear(); + + // PRC_DIR_ENVVARS lists one or more environment variables separated + // by spaces. Pull them out, and each of those contains the name of + // a single directory to search. Add it to the search path. + string prc_dir_envvars = PRC_DIR_ENVVARS; + if (!prc_dir_envvars.empty()) { + vector_string prc_dir_envvar_list; + ConfigDeclaration::extract_words(prc_dir_envvars, prc_dir_envvar_list); + 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()) { + 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); + } + } + } + } + + // PRC_PATH_ENVVARS lists one or more environment variables separated + // by spaces. Pull them out, and then each one of those contains a + // list of directories to search. Add each of those to the search + // path. + string prc_path_envvars = PRC_PATH_ENVVARS; + if (!prc_path_envvars.empty()) { + vector_string prc_path_envvar_list; + ConfigDeclaration::extract_words(prc_path_envvars, prc_path_envvar_list); + for (size_t i = 0; i < prc_path_envvar_list.size(); ++i) { + string prc_path = ExecutionEnvironment::get_environment_variable(prc_path_envvar_list[i]); + if (!prc_path.empty()) { + _search_path.append_path(prc_path); + } + } + } + + if (_search_path.is_empty()) { + // If nothing's on the search path (PRC_DIR and PRC_PATH were not + // defined), then use the DEFAULT_PRC_DIR. + string default_prc_dir = DEFAULT_PRC_DIR; + if (!default_prc_dir.empty()) { + // It's already from-os-specific by ppremake. + Filename prc_dir_filename = default_prc_dir; + if (scan_auto_prc_dir(prc_dir_filename)) { + _search_path.append_directory(default_prc_dir); + } + } + } + // Now find all of the *.prc files (or whatever matches // PRC_PATTERNS) on the path. ConfigFiles config_files; @@ -415,3 +421,100 @@ sort_pages() { _pages_sorted = true; } + +//////////////////////////////////////////////////////////////////// +// Function: ConfigPageManager::scan_auto_prc_dir +// Access: Private +// Description: Checks for the prefix "" 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) == "") { + 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 "", 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); +} diff --git a/dtool/src/prc/configPageManager.h b/dtool/src/prc/configPageManager.h index 9830a18b69..9ea3d57d25 100644 --- a/dtool/src/prc/configPageManager.h +++ b/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 Pages; Pages _implicit_pages; Pages _explicit_pages; diff --git a/dtool/src/prc/prc_composite1.cxx b/dtool/src/prc/prc_composite1.cxx new file mode 100644 index 0000000000..d2894e7f94 --- /dev/null +++ b/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" diff --git a/dtool/src/prc/prc_composite2.cxx b/dtool/src/prc/prc_composite2.cxx new file mode 100644 index 0000000000..2fb0ea44a1 --- /dev/null +++ b/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"