diff --git a/dtool/src/dtoolutil/executionEnvironment.I b/dtool/src/dtoolutil/executionEnvironment.I index 1b4c08e075..52ea458b67 100644 --- a/dtool/src/dtoolutil/executionEnvironment.I +++ b/dtool/src/dtoolutil/executionEnvironment.I @@ -51,6 +51,33 @@ set_environment_variable(const string &var, const string &value) { get_ptr()->ns_set_environment_variable(var, value); } +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::shadow_environment_variable +// Access: Public, Static +// Description: Changes the apparent definition of the indicated +// environment variable by masking it within this class +// with a new value. This does not change the actual +// environment variable, but future calls to +// get_environment_variable() will return this new +// value. +//////////////////////////////////////////////////////////////////// +INLINE void ExecutionEnvironment:: +shadow_environment_variable(const string &var, const string &value) { + get_ptr()->ns_shadow_environment_variable(var, value); +} + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::clear_shadow +// Access: Public, Static +// Description: Removes a value set by a previous call to +// shadow_environment_variable(), and lets the actual +// value of the variable show again. +//////////////////////////////////////////////////////////////////// +INLINE void ExecutionEnvironment:: +clear_shadow(const string &var) { + get_ptr()->ns_clear_shadow(var); +} + //////////////////////////////////////////////////////////////////// // Function: ExecutionEnvironment::get_num_args // Access: Public, Static diff --git a/dtool/src/dtoolutil/executionEnvironment.cxx b/dtool/src/dtoolutil/executionEnvironment.cxx index 878c0e6ffc..7ac74a4882 100644 --- a/dtool/src/dtoolutil/executionEnvironment.cxx +++ b/dtool/src/dtoolutil/executionEnvironment.cxx @@ -182,12 +182,12 @@ ns_has_environment_variable(const string &var) const { //////////////////////////////////////////////////////////////////// string ExecutionEnvironment:: ns_get_environment_variable(const string &var) const { -#ifdef PREREAD_ENVIRONMENT EnvironmentVariables::const_iterator evi; evi = _variables.find(var); if (evi != _variables.end()) { return (*evi).second; } +#ifdef PREREAD_ENVIRONMENT return string(); #else const char *def = getenv(var.c_str()); @@ -215,6 +215,40 @@ ns_set_environment_variable(const string &var, const string &value) { putenv(put); } +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::ns_shadow_environment_variable +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void ExecutionEnvironment:: +ns_shadow_environment_variable(const string &var, const string &value) { + _variables[var] = value; + string putstr = var + "=" + value; +} + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::ns_clear_shadow +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void ExecutionEnvironment:: +ns_clear_shadow(const string &var) { + EnvironmentVariables::iterator vi = _variables.find(var); + if (vi == _variables.end()) { + return; + } + +#ifdef PREREAD_ENVIRONMENT + // Now we have to replace the value in the table. + const char *def = getenv(var.c_str()); + if (def != (char *)NULL) { + (*vi).second = def; + } else { + _variables.erase(vi); + } +#endif // PREREAD_ENVIRONMENT +} + //////////////////////////////////////////////////////////////////// // Function: ExecutionEnvironment::ns_get_num_args // Access: Private diff --git a/dtool/src/dtoolutil/executionEnvironment.h b/dtool/src/dtoolutil/executionEnvironment.h index dc88bba0ed..33cc896bb3 100644 --- a/dtool/src/dtoolutil/executionEnvironment.h +++ b/dtool/src/dtoolutil/executionEnvironment.h @@ -43,6 +43,9 @@ public: INLINE static string get_environment_variable(const string &var); INLINE static void set_environment_variable(const string &var, const string &value); + INLINE static void shadow_environment_variable(const string &var, const string &value); + INLINE static void clear_shadow(const string &var); + static string expand_string(const string &str); INLINE static int get_num_args(); @@ -56,6 +59,8 @@ private: bool ns_has_environment_variable(const string &var) const; string ns_get_environment_variable(const string &var) const; void ns_set_environment_variable(const string &var, const string &value); + void ns_shadow_environment_variable(const string &var, const string &value); + void ns_clear_shadow(const string &var); int ns_get_num_args() const; string ns_get_arg(int n) const; diff --git a/dtool/src/prc/configVariableFilename.cxx b/dtool/src/prc/configVariableFilename.cxx index 4fd429de6a..7ae5ac61f2 100644 --- a/dtool/src/prc/configVariableFilename.cxx +++ b/dtool/src/prc/configVariableFilename.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "configVariableFilename.h" +#include "executionEnvironment.h" //////////////////////////////////////////////////////////////////// // Function: ConfigVariableFilename::reload_value @@ -26,7 +27,17 @@ //////////////////////////////////////////////////////////////////// void ConfigVariableFilename:: reload_value() { - _value = Filename::expand_from(get_string_value()); + nassertv(_core != (ConfigVariableCore *)NULL); + + const ConfigDeclaration *decl = _core->get_declaration(0); + const ConfigPage *page = decl->get_page(); + + Filename page_filename(page->get_name()); + Filename page_dirname = page_filename.get_dirname(); + ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific()); + + _value = Filename::expand_from(decl->get_string_value()); + ExecutionEnvironment::clear_shadow("THIS_PRC_DIR"); _value_seq = _core->get_value_seq(); _value_stale = false; diff --git a/dtool/src/prc/configVariableSearchPath.cxx b/dtool/src/prc/configVariableSearchPath.cxx index 3c4a4a9ef4..a842520cfd 100644 --- a/dtool/src/prc/configVariableSearchPath.cxx +++ b/dtool/src/prc/configVariableSearchPath.cxx @@ -47,8 +47,14 @@ reload_search_path() { _value.append_path(_prefix); int num_unique_references = _core->get_num_unique_references(); for (int i = 0; i < num_unique_references; i++) { - string dirname = _core->get_unique_reference(i)->get_string_value(); - string expanded = ExecutionEnvironment::expand_string(dirname); + const ConfigDeclaration *decl = _core->get_unique_reference(i); + const ConfigPage *page = decl->get_page(); + + Filename page_filename(page->get_name()); + Filename page_dirname = page_filename.get_dirname(); + ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific()); + string expanded = ExecutionEnvironment::expand_string(decl->get_string_value()); + ExecutionEnvironment::clear_shadow("THIS_PRC_DIR"); if (!expanded.empty()) { _value.append_directory(Filename::from_os_specific(expanded)); }