From ffc1a43c62807a435fe33c721575ed0bda6d93b2 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 11 Jan 2001 17:04:13 +0000 Subject: [PATCH] *** empty log message *** --- dtool/src/dtoolutil/executionEnvironment.cxx | 513 ++++++++++--------- dtool/src/dtoolutil/pfstream.cxx | 2 +- 2 files changed, 261 insertions(+), 254 deletions(-) diff --git a/dtool/src/dtoolutil/executionEnvironment.cxx b/dtool/src/dtoolutil/executionEnvironment.cxx index 12be49a7af..c6502519cc 100644 --- a/dtool/src/dtoolutil/executionEnvironment.cxx +++ b/dtool/src/dtoolutil/executionEnvironment.cxx @@ -1,280 +1,287 @@ -// Filename: dSearchPath.C -// Created by: drose (01Jul00) +// Filename: executionEnvironment.C +// Created by: drose (15May00) // //////////////////////////////////////////////////////////////////// -#include "dSearchPath.h" -#include "filename.h" +#include "executionEnvironment.h" +#include +#include +#include // for perror + +#ifdef WIN32_VC +// Windows requires this for getcwd(). +#include +#define getcwd _getcwd +#endif + + +// We define the symbol PREREAD_ENVIRONMENT if we cannot rely on +// getenv() to read environment variables at static init time. In +// this case, we must read all of the environment variables directly +// and cache them locally. + +#ifndef STATIC_INIT_GETENV +#define PREREAD_ENVIRONMENT +#endif + + +// We define the symbol HAVE_GLOBAL_ARGV if we have global variables +// named GLOBAL_ARGC/GLOBAL_ARGV that we can read at static init time +// to determine our command-line arguments. + +#if defined(HAVE_GLOBAL_ARGV) && defined(PROTOTYPE_GLOBAL_ARGV) +extern char **GLOBAL_ARGV; +extern int GLOBAL_ARGC; +#endif + +// Linux with GNU libc does have global argv/argc variables, but we +// can't safely access them at stat init time--at least, not in libc5. +// (It does seem to work with glibc2, however.) + +ExecutionEnvironment *ExecutionEnvironment::_global_ptr = NULL; + //////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::Constructor -// Access: Public -// Description: +// Function: ExecutionEnvironment::Constructor +// Access: Private +// Description: You shouldn't need to construct one of these; there's +// only one and it constructs itself. //////////////////////////////////////////////////////////////////// -DSearchPath::Results:: -Results() { +ExecutionEnvironment:: +ExecutionEnvironment() { + read_environment_variables(); + read_args(); } //////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::Copy Constructor -// Access: Public -// Description: +// Function: ExecutionEnviroment::get_cwd +// Access: Public, Static +// Description: Returns the name of the current working directory. //////////////////////////////////////////////////////////////////// -DSearchPath::Results:: -Results(const DSearchPath::Results ©) : - _files(copy._files) -{ -} +Filename ExecutionEnvironment:: +get_cwd() { + // getcwd() requires us to allocate a dynamic buffer and grow it on + // demand. + static size_t bufsize = 1024; + static char *buffer = NULL; -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::Copy Assignment Operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void DSearchPath::Results:: -operator = (const DSearchPath::Results ©) { - _files = copy._files; -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -DSearchPath::Results:: -~Results() { -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::clear -// Access: Public -// Description: Removes all the files from the list. -//////////////////////////////////////////////////////////////////// -void DSearchPath::Results:: -clear() { - _files.clear(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::get_num_files -// Access: Public -// Description: Returns the number of files on the result list. -//////////////////////////////////////////////////////////////////// -int DSearchPath::Results:: -get_num_files() const { - return _files.size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Results::get_file -// Access: Public -// Description: Returns the nth file on the result list. -//////////////////////////////////////////////////////////////////// -Filename DSearchPath::Results:: -get_file(int n) const { - assert(n >= 0 && n < (int)_files.size()); - return _files[n]; -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Default Constructor -// Access: Public -// Description: Creates an empty search path. -//////////////////////////////////////////////////////////////////// -DSearchPath:: -DSearchPath() { -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -DSearchPath:: -DSearchPath(const string &path, const string &delimiters) { - append_path(path, delimiters); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -DSearchPath:: -DSearchPath(const DSearchPath ©) : - _directories(copy._directories) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Copy Assignment Operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -operator = (const DSearchPath ©) { - _directories = copy._directories; -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -DSearchPath:: -~DSearchPath() { -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::clear -// Access: Public -// Description: Removes all the directories from the search list. -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -clear() { - _directories.clear(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::append_directory -// Access: Public -// Description: Adds a new directory to the end of the search list. -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -append_directory(const Filename &directory) { - _directories.push_back(directory); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::prepend_directory -// Access: Public -// Description: Adds a new directory to the front of the search list. -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -prepend_directory(const Filename &directory) { - _directories.insert(_directories.begin(), directory); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::append_path -// Access: Public -// Description: Adds all of the directories listed in the search path -// to the end of the search list. -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -append_path(const string &path, const string &delimiters) { - size_t p = 0; - while (p < path.length()) { - size_t q = path.find_first_of(delimiters, p); - if (q == string::npos) { - _directories.push_back(path.substr(p)); - return; - } - if (q != p) { - _directories.push_back(path.substr(p, q - p)); - } - p = q + 1; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::get_num_directories -// Access: Public -// Description: Returns the number of directories on the search list. -//////////////////////////////////////////////////////////////////// -int DSearchPath:: -get_num_directories() const { - return _directories.size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::get_directory -// Access: Public -// Description: Returns the nth directory on the search list. -//////////////////////////////////////////////////////////////////// -Filename DSearchPath:: -get_directory(int n) const { - assert(n >= 0 && n < (int)_directories.size()); - return _directories[n]; -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::find_file -// Access: Public -// Description: Searches all the directories in the search list for -// the indicated file, in order. Returns the full -// matching pathname of the first match if found, or the -// empty string if not found. -//////////////////////////////////////////////////////////////////// -Filename DSearchPath:: -find_file(const Filename &filename) const { - Directories::const_iterator di; - for (di = _directories.begin(); di != _directories.end(); ++di) { - Filename match((*di), filename); - if (match.exists()) { - return match; - } + if (buffer == (char *)NULL) { + buffer = new char[bufsize]; } + while (getcwd(buffer, bufsize) == (char *)NULL) { + if (errno != ERANGE) { + perror("getcwd"); + return string(); + } + delete[] buffer; + bufsize = bufsize * 2; + buffer = new char[bufsize]; + assert(buffer != (char *)NULL); + } + + return Filename::from_os_specific(buffer); +} + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::ns_has_environment_variable +// Access: Private +// Description: Returns true if the indicated environment variable +// is defined. The nonstatic implementation. +//////////////////////////////////////////////////////////////////// +bool ExecutionEnvironment:: +ns_has_environment_variable(const string &var) const { +#ifdef PREREAD_ENVIRONMENT + return _variables.count(var) != 0; +#else + return getenv(var.c_str()) != (char *)NULL; +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::ns_get_environment_variable +// Access: Private +// Description: Returns the definition of the indicated environment +// variable, or the empty string if the variable is +// undefined. The nonstatic implementation. +//////////////////////////////////////////////////////////////////// +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; + } return string(); +#else + const char *def = getenv(var.c_str()); + if (def != (char *)NULL) { + return def; + } + return string(); +#endif } //////////////////////////////////////////////////////////////////// -// Function: DSearchPath::find_all_files -// Access: Public -// Description: Searches all the directories in the search list for -// the indicated file, in order. Fills up the results -// list with *all* of the matching filenames found, if -// any. Returns the number of matches found. +// Function: ExecutionEnvironment::ns_get_num_args +// Access: Private +// Description: Returns the number of command-line arguments +// available, not counting arg 0, the binary name. The +// nonstatic implementation. //////////////////////////////////////////////////////////////////// -int DSearchPath:: -find_all_files(const Filename &filename, - DSearchPath::Results &results) const { - results._files.clear(); +int ExecutionEnvironment:: +ns_get_num_args() const { + return _args.size(); +} - Directories::const_iterator di; - for (di = _directories.begin(); di != _directories.end(); ++di) { - Filename match((*di), filename); - if (match.exists()) { - results._files.push_back(match); - } +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::ns_get_arg +// Access: Private +// Description: Returns the nth command-line argument. The index n +// must be in the range [0 .. get_num_args()). The +// first parameter, n == 0, is the first actual +// parameter, not the binary name. The nonstatic +// implementation. +//////////////////////////////////////////////////////////////////// +string ExecutionEnvironment:: +ns_get_arg(int n) const { + assert(n >= 0 && n < ns_get_num_args()); + return _args[n]; +} + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::ns_get_binary_name +// Access: Private +// Description: Returns the name of the binary executable that +// started this program, if it can be determined. The +// nonstatic implementation. +//////////////////////////////////////////////////////////////////// +string ExecutionEnvironment:: +ns_get_binary_name() const { + if (_binary_name.empty()) { + return "unknown"; + } + return _binary_name; +} + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::get_ptr +// Access: Private, Static +// Description: Returns a static pointer that may be used to access +// the global ExecutionEnvironment object. +//////////////////////////////////////////////////////////////////// +ExecutionEnvironment *ExecutionEnvironment:: +get_ptr() { + if (_global_ptr == (ExecutionEnvironment *)NULL) { + _global_ptr = new ExecutionEnvironment; + } + return _global_ptr; +} + + +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::read_environment_variables +// Access: Private +// Description: Fills up the internal table of existing environment +// variables, if we are in PREREAD_ENVIRONMENT mode. +// Otherwise, does nothing. +//////////////////////////////////////////////////////////////////// +void ExecutionEnvironment:: +read_environment_variables() { +#ifdef PREREAD_ENVIRONMENT +#if defined(HAVE_PROC_SELF_ENVIRON) + // In Linux, and possibly in other systems, we might not be able to + // use getenv() at static init time. However, we may be lucky and + // have a file called /proc/self/environ that may be read to + // determine all of our environment variables. + + ifstream proc("/proc/self/environ"); + if (proc.fail()) { + cerr << "Cannot read /proc/self/environ; environment variables unavailable.\n"; + return; } - return results._files.size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::output -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -output(ostream &out, const string &separator) const { - if (!_directories.empty()) { - Directories::const_iterator di = _directories.begin(); - out << (*di); - ++di; - while (di != _directories.end()) { - out << separator << (*di); - ++di; + int ch = proc.get(); + while (!proc.eof() && !proc.fail()) { + string variable; + string value; + + while (!proc.eof() && !proc.fail() && ch != '=' && ch != '\0') { + variable += (char)ch; + ch = proc.get(); } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DSearchPath::write -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void DSearchPath:: -write(ostream &out, int indent_level) const { - Directories::const_iterator di; - for (di = _directories.begin(); di != _directories.end(); ++di) { - for (int i = 0; i < indent_level; i++) { - out << ' '; + + if (ch == '=') { + ch = proc.get(); + while (!proc.eof() && !proc.fail() && ch != '\0') { + value += (char)ch; + ch = proc.get(); + } } - out << (*di) << "\n"; + + if (!variable.empty()) { + _variables[variable] = value; + } + ch = proc.get(); } +#else + cerr << "Warning: environment variables unavailable to dconfig.\n"; +#endif +#endif // PREREAD_ENVIRONMENT } +//////////////////////////////////////////////////////////////////// +// Function: ExecutionEnvironment::read_args +// Access: Private +// Description: Reads all the command-line arguments and the name of +// the binary file, if possible. +//////////////////////////////////////////////////////////////////// +void ExecutionEnvironment:: +read_args() { +#if defined(HAVE_GLOBAL_ARGV) + int argc = GLOBAL_ARGC; + if (argc > 0) { + _binary_name = GLOBAL_ARGV[0]; + } + for (int i = 1; i < argc; i++) { + _args.push_back(GLOBAL_ARGV[i]); + } + +#elif defined(HAVE_PROC_SELF_CMDLINE) + // In Linux, and possibly in other systems as well, we might not be + // able to use the global ARGC/ARGV variables at static init time. + // However, we may be lucky and have a file called + // /proc/self/cmdline that may be read to determine all of our + // command-line arguments. + + ifstream proc("/proc/self/cmdline"); + if (proc.fail()) { + cerr << "Cannot read /proc/self/cmdline; command-line arguments unavailable to config.\n"; + return; + } + + int ch = proc.get(); + int index = 0; + while (!proc.eof() && !proc.fail()) { + string arg; + + while (!proc.eof() && !proc.fail() && ch != '\0') { + arg += (char)ch; + ch = proc.get(); + } + + if (index == 0) { + _binary_name = arg; + } else { + _args.push_back(arg); + } + index++; + + ch = proc.get(); + } +#else + cerr << "Warning: command line parameters unavailable to dconfig.\n"; +#endif +} diff --git a/dtool/src/dtoolutil/pfstream.cxx b/dtool/src/dtoolutil/pfstream.cxx index 6df3cd30e3..dbc6e74712 100644 --- a/dtool/src/dtoolutil/pfstream.cxx +++ b/dtool/src/dtoolutil/pfstream.cxx @@ -1,4 +1,4 @@ -// Filename: pfstream.h +// Filename: pfstream.cxx // Created by: cary (09Jan01) // ////////////////////////////////////////////////////////////////////