*** empty log message ***

This commit is contained in:
David Rose 2000-11-14 00:44:14 +00:00
parent 2ac5613ff4
commit f8720f2230
8 changed files with 416 additions and 150 deletions

View File

@ -299,6 +299,26 @@ read_file(const string &filename) {
return false;
}
return read_stream(in, filename);
}
////////////////////////////////////////////////////////////////////
// Function: PPCommandFile::read_stream
// Access: Public
// Description: Reads input from the given stream. Each line is
// read, commands are processed, variables are expanded,
// and the resulting output is sent to write_line()
// one line at a time. The return value is true if the
// entire file is read with no errors, false if there is
// some problem.
//
// The filename is just informational; it is used to
// update the variables like THISFILENAME and
// THISDIRPREFIX as appropriate, and to report errors to
// the user.
////////////////////////////////////////////////////////////////////
bool PPCommandFile::
read_stream(istream &in, const string &filename) {
PushFilename pushed(_scope, filename);
if (!read_stream(in)) {
@ -307,7 +327,6 @@ read_file(const string &filename) {
}
return false;
}
return true;
}
@ -320,6 +339,10 @@ read_file(const string &filename) {
// one line at a time. The return value is true if the
// entire file is read with no errors, false if there is
// some problem.
//
// This flavor of read_stream() does not take a
// filename. It does not, therefore, adjust
// THISFILENAME and THISDIRPREFIX.
////////////////////////////////////////////////////////////////////
bool PPCommandFile::
read_stream(istream &in) {
@ -1746,13 +1769,18 @@ PushFilename(PPScope *scope, const string &filename) {
_old_thisdirprefix = _scope->get_variable("THISDIRPREFIX");
_old_thisfilename = _scope->get_variable("THISFILENAME");
_scope->define_variable("THISFILENAME", filename);
string thisfilename = filename;
string thisdirprefix;
size_t slash = filename.rfind('/');
if (slash == string::npos) {
_scope->define_variable("THISDIRPREFIX", string());
thisdirprefix = string();
} else {
_scope->define_variable("THISDIRPREFIX", filename.substr(0, slash + 1));
thisdirprefix = filename.substr(0, slash + 1);
}
_scope->define_variable("THISFILENAME", thisfilename);
_scope->define_variable("THISDIRPREFIX", thisdirprefix);
}
////////////////////////////////////////////////////////////////////
@ -1762,6 +1790,6 @@ PushFilename(PPScope *scope, const string &filename) {
////////////////////////////////////////////////////////////////////
PPCommandFile::PushFilename::
~PushFilename() {
_scope->define_variable("THISDIRPREFIX", _old_thisdirprefix);
_scope->define_variable("THISFILENAME", _old_thisfilename);
_scope->define_variable("THISDIRPREFIX", _old_thisdirprefix);
}

View File

@ -30,6 +30,7 @@ public:
PPScope *get_scope() const;
bool read_file(const string &filename);
bool read_stream(istream &in, const string &filename);
bool read_stream(istream &in);
void begin_read();
bool read_line(string line);

View File

@ -397,10 +397,23 @@ r_scan(const string &prefix) {
return false;
}
// Collect all the filenames in the directory in this vector first,
// so we can sort them.
vector<string> filenames;
struct dirent *d;
d = readdir(root);
while (d != (struct dirent *)NULL) {
string filename = d->d_name;
filenames.push_back(d->d_name);
d = readdir(root);
}
closedir(root);
sort(filenames.begin(), filenames.end());
vector<string>::const_iterator fi;
for (fi = filenames.begin(); fi != filenames.end(); ++fi) {
string filename = (*fi);
if (!filename.empty() && filename[0] != '.') {
// Is this possibly a subdirectory with its own Sources.pp
@ -408,19 +421,16 @@ r_scan(const string &prefix) {
string next_prefix = prefix + filename + "/";
string source_filename = next_prefix + SOURCE_FILENAME;
if (access(source_filename.c_str(), F_OK) == 0) {
PPDirectory *subtree = new PPDirectory(filename, this);
if (!subtree->r_scan(next_prefix)) {
closedir(root);
return false;
}
}
}
d = readdir(root);
}
closedir(root);
return true;
}
@ -451,8 +461,7 @@ read_source_file(const string &prefix, PPNamedScopes *named_scopes) {
_source = new PPCommandFile(_scope);
if (!_source->read_stream(in)) {
cerr << "Error when reading " << source_filename << "\n";
if (!_source->read_stream(in, source_filename)) {
return false;
}
}

View File

@ -14,6 +14,8 @@
#include <errno.h>
#include <stdio.h> // for perror
string PPMain::_root;
////////////////////////////////////////////////////////////////////
// Function: PPMain::Constructor
// Access: Public
@ -81,12 +83,12 @@ read_source(const string &root) {
return false;
}
string cwd = get_cwd();
cerr << "Root is " << cwd << "\n";
_root = get_cwd();
cerr << "Root is " << _root << "\n";
_def_scope = new PPScope(&_named_scopes);
_def_scope->define_variable("PACKAGEFILE", package_file);
_def_scope->define_variable("TOPDIR", cwd);
_def_scope->define_variable("TOPDIR", _root);
_defs = new PPCommandFile(_def_scope);
if (!_defs->read_file(PACKAGE_FILENAME)) {
@ -218,6 +220,37 @@ report_needs(const string &dirname) const {
dir->report_needs();
}
////////////////////////////////////////////////////////////////////
// Function: PPMain::get_root
// Access: Public, Static
// Description: Returns the full path to the root directory of the
// source hierarchy; this is the directory in which the
// runs most of the time.
////////////////////////////////////////////////////////////////////
string PPMain::
get_root() {
return _root;
}
////////////////////////////////////////////////////////////////////
// Function: PPMain::chdir_root
// Access: Public, Static
// Description: Changes the current directory to the root directory
// of the source hierarchy. This should be executed
// after a temporary change to another directory, to
// restore the current directory to a known state.
////////////////////////////////////////////////////////////////////
void PPMain::
chdir_root() {
if (chdir(_root.c_str()) < 0) {
perror("chdir");
// This is a real error! We can't get back to our starting
// directory!
cerr << "Error! Source directory is invalid!\n";
exit(1);
}
}
////////////////////////////////////////////////////////////////////
// Function: PPMain::r_process_all
// Access: Private

View File

@ -32,6 +32,9 @@ public:
void report_depends(const string &dirname) const;
void report_needs(const string &dirname) const;
static string get_root();
static void chdir_root();
private:
bool r_process_all(PPDirectory *dir);
bool p_process(PPDirectory *dir);
@ -46,6 +49,8 @@ private:
PPDirectoryTree _tree;
PPNamedScopes _named_scopes;
PPScope *_parent_scope;
static string _root;
};
#endif

View File

@ -14,7 +14,7 @@
// by directory name, used in sort_by_dependency().
class SortScopesByDependencyAndName {
public:
bool operator () (const PPScope *a, const PPScope *b) const {
bool operator () (PPScope *a, PPScope *b) const {
PPDirectory *da = a->get_directory();
PPDirectory *db = b->get_directory();

View File

@ -10,6 +10,7 @@
#include "ppSubroutine.h"
#include "ppCommandFile.h"
#include "ppDependableFile.h"
#include "ppMain.h"
#include "tokenize.h"
#include "find_searchpath.h"
#include "filename.h"
@ -59,7 +60,7 @@ PPScope(PPNamedScopes *named_scopes) :
// NULL.
////////////////////////////////////////////////////////////////////
PPNamedScopes *PPScope::
get_named_scopes() const {
get_named_scopes() {
return _named_scopes;
}
@ -84,7 +85,7 @@ set_parent(PPScope *parent) {
// See set_parent().
////////////////////////////////////////////////////////////////////
PPScope *PPScope::
get_parent() const {
get_parent() {
return _parent_scope;
}
@ -300,7 +301,7 @@ define_formals(const string &subroutine_name,
// indicated variable name.
////////////////////////////////////////////////////////////////////
string PPScope::
get_variable(const string &varname) const {
get_variable(const string &varname) {
// Is it a user-defined function?
const PPSubroutine *sub = PPSubroutine::get_func(varname);
if (sub != (const PPSubroutine *)NULL) {
@ -337,7 +338,7 @@ get_variable(const string &varname) const {
// definition is in turn expanded.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_variable(const string &varname) const {
expand_variable(const string &varname) {
return expand_string(get_variable(varname));
}
@ -350,7 +351,7 @@ expand_variable(const string &varname) const {
// not.
////////////////////////////////////////////////////////////////////
PPScope::MapVariableDefinition &PPScope::
find_map_variable(const string &varname) const {
find_map_variable(const string &varname) {
MapVariableDefinition &def = p_find_map_variable(varname);
if (&def != &_null_map_def) {
return def;
@ -377,7 +378,7 @@ find_map_variable(const string &varname) const {
// scope.
////////////////////////////////////////////////////////////////////
PPDirectory *PPScope::
get_directory() const {
get_directory() {
if (_directory != (PPDirectory *)NULL) {
return _directory;
}
@ -417,7 +418,7 @@ set_directory(PPDirectory *directory) {
// expanded.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_string(const string &str) const {
expand_string(const string &str) {
return r_expand_string(str, (ExpandedVariable *)NULL);
}
@ -431,7 +432,7 @@ expand_string(const string &str) const {
// definition.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_self_reference(const string &str, const string &varname) const {
expand_self_reference(const string &str, const string &varname) {
// Look for a simple reference to the named variable. A more
// complex reference, like a computed variable name or something
// equally loopy, won't work with this simple test. Too bad.
@ -512,7 +513,7 @@ get_bottom_scope() {
////////////////////////////////////////////////////////////////////
void PPScope::
tokenize_params(const string &str, vector<string> &tokens,
bool expand) const {
bool expand) {
size_t p = 0;
while (p < str.length()) {
// Skip initial whitespace.
@ -564,7 +565,7 @@ tokenize_params(const string &str, vector<string> &tokens,
// error.
////////////////////////////////////////////////////////////////////
bool PPScope::
tokenize_numeric_pair(const string &str, double &a, double &b) const {
tokenize_numeric_pair(const string &str, double &a, double &b) {
vector<string> words;
tokenize_params(str, words, true);
if (words.size() != 2) {
@ -623,7 +624,7 @@ p_set_variable(const string &varname, const string &definition) {
// false otherwise..
////////////////////////////////////////////////////////////////////
bool PPScope::
p_get_variable(const string &varname, string &result) const {
p_get_variable(const string &varname, string &result) {
Variables::const_iterator vi;
vi = _variables.find(varname);
if (vi != _variables.end()) {
@ -669,7 +670,7 @@ p_get_variable(const string &varname, string &result) const {
// have thus far been expanded in the linked list.
////////////////////////////////////////////////////////////////////
string PPScope::
r_expand_string(const string &str, PPScope::ExpandedVariable *expanded) const {
r_expand_string(const string &str, PPScope::ExpandedVariable *expanded) {
string result;
// Search for a variable reference.
@ -704,7 +705,7 @@ r_expand_string(const string &str, PPScope::ExpandedVariable *expanded) const {
// itself is returned.
////////////////////////////////////////////////////////////////////
string PPScope::
r_scan_variable(const string &str, size_t &vp) const {
r_scan_variable(const string &str, size_t &vp) {
// Search for the end of the variable name: an unmatched square
// bracket.
@ -749,7 +750,7 @@ r_scan_variable(const string &str, size_t &vp) const {
////////////////////////////////////////////////////////////////////
string PPScope::
r_expand_variable(const string &str, size_t &vp,
PPScope::ExpandedVariable *expanded) const {
PPScope::ExpandedVariable *expanded) {
string varname;
size_t whitespace_at = 0;
@ -869,6 +870,8 @@ r_expand_variable(const string &str, size_t &vp,
return expand_sort(params);
} else if (funcname == "unique") {
return expand_unique(params);
} else if (funcname == "matrix") {
return expand_matrix(params);
} else if (funcname == "if") {
return expand_if(params);
} else if (funcname == "eq") {
@ -905,6 +908,10 @@ r_expand_variable(const string &str, size_t &vp,
return expand_unmapped(params);
} else if (funcname == "dependencies") {
return expand_dependencies(params);
} else if (funcname == "foreach") {
return expand_foreach(params);
} else if (funcname == "forscopes") {
return expand_forscopes(params);
}
// It must be a map variable.
@ -1003,7 +1010,7 @@ r_expand_variable(const string &str, size_t &vp,
////////////////////////////////////////////////////////////////////
string PPScope::
expand_variable_nested(const string &varname,
const string &scope_names) const {
const string &scope_names) {
if (_named_scopes == (PPNamedScopes *)NULL) {
return string();
}
@ -1051,7 +1058,7 @@ expand_variable_nested(const string &varname,
// drive leterr, for windows_platform.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_isfullpath(const string &params) const {
expand_isfullpath(const string &params) {
string filename = trim_blanks(expand_string(params));
string result;
@ -1078,7 +1085,7 @@ expand_isfullpath(const string &params) const {
// reverse slashes.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_osfilename(const string &params) const {
expand_osfilename(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1109,7 +1116,7 @@ expand_osfilename(const string &params) const {
// reverse slashes.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_unixfilename(const string &params) const {
expand_unixfilename(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1132,7 +1139,7 @@ expand_unixfilename(const string &params) const {
// not running under Cygwin.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_cygpath_w(const string &params) const {
expand_cygpath_w(const string &params) {
string filename = trim_blanks(expand_string(params));
#ifdef __CYGWIN__
@ -1154,7 +1161,7 @@ expand_cygpath_w(const string &params) const {
// not running under Cygwin.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_cygpath_p(const string &params) const {
expand_cygpath_p(const string &params) {
string filename = trim_blanks(expand_string(params));
#ifdef __CYGWIN__
@ -1175,7 +1182,7 @@ expand_cygpath_p(const string &params) const {
// with shell matching characters.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_wildcard(const string &params) const {
expand_wildcard(const string &params) {
vector<string> results;
glob_string(expand_string(params), results);
@ -1194,7 +1201,7 @@ expand_wildcard(const string &params) const {
// the first expansion.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_isdir(const string &params) const {
expand_isdir(const string &params) {
vector<string> results;
glob_string(expand_string(params), results);
@ -1227,7 +1234,7 @@ expand_isdir(const string &params) const {
// looks only at the first expansion.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_isfile(const string &params) const {
expand_isfile(const string &params) {
vector<string> results;
glob_string(expand_string(params), results);
@ -1258,7 +1265,7 @@ expand_isfile(const string &params) const {
// indicated search path, or on the system search path.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_libtest(const string &params) const {
expand_libtest(const string &params) {
// Get the parameters out based on commas. The first parameter is a
// space-separated set of directories to search, the second
// parameter is a space-separated set of library names.
@ -1347,7 +1354,7 @@ expand_libtest(const string &params) const {
// path.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_bintest(const string &params) const {
expand_bintest(const string &params) {
// We only have one parameter: the filename of the executable. We
// always search for it on the path.
string binname = expand_string(params);
@ -1418,7 +1425,12 @@ expand_bintest(const string &params) const {
// standard output.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_shell(const string &params) const {
expand_shell(const string &params) {
// We run $[shell] commands within the directory indicated by
// $[THISDIRPREFIX]. This way, local filenames will be expanded the
// way we expect.
string dirname = trim_blanks(expand_variable("THISDIRPREFIX"));
string command = expand_string(params);
int pid, status;
@ -1438,6 +1450,16 @@ expand_shell(const string &params) const {
if (pid == 0) {
// Child.
if (!dirname.empty()) {
// We don't have to restore the directory after we're done,
// because we're doing the chdir() call only within the child
// process.
if (chdir(dirname.c_str()) < 0) {
perror("chdir");
}
}
close(pd[0]);
dup2(pd[1], STDOUT_FILENO);
char *argv[4];
@ -1502,7 +1524,7 @@ expand_shell(const string &params) const {
// where possible.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_standardize(const string &params) const {
expand_standardize(const string &params) {
string filename = trim_blanks(expand_string(params));
if (filename.empty()) {
return string();
@ -1558,7 +1580,7 @@ expand_standardize(const string &params) const {
// the length of the argument in characters.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_length(const string &params) const {
expand_length(const string &params) {
string word = trim_blanks(expand_string(params));
char buffer[32];
@ -1576,7 +1598,7 @@ expand_length(const string &params) const {
// character E, inclusive.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_substr(const string &params) const {
expand_substr(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -1618,7 +1640,7 @@ expand_substr(const string &params) const {
// if the words contain no slash.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_dir(const string &params) const {
expand_dir(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1647,7 +1669,7 @@ expand_dir(const string &params) const {
// string itself if there is no slash.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_notdir(const string &params) const {
expand_notdir(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1673,7 +1695,7 @@ expand_notdir(const string &params) const {
// the filename extension, including a dot, if any.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_suffix(const string &params) const {
expand_suffix(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1707,7 +1729,7 @@ expand_suffix(const string &params) const {
// directory, if any).
////////////////////////////////////////////////////////////////////
string PPScope::
expand_basename(const string &params) const {
expand_basename(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1737,7 +1759,7 @@ expand_basename(const string &params) const {
// words in the second parameter.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_word(const string &params) const {
expand_word(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -1768,7 +1790,7 @@ expand_word(const string &params) const {
// space-separated list of words in the third parameter.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_wordlist(const string &params) const {
expand_wordlist(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -1817,7 +1839,7 @@ expand_wordlist(const string &params) const {
// list.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_words(const string &params) const {
expand_words(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1836,7 +1858,7 @@ expand_words(const string &params) const {
// whitespace.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_firstword(const string &params) const {
expand_firstword(const string &params) {
// Split the parameter into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -1853,7 +1875,7 @@ expand_firstword(const string &params) const {
// Description: Expands the "patsubst" function variable.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_patsubst(const string &params, bool separate_words) const {
expand_patsubst(const string &params, bool separate_words) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -1931,7 +1953,7 @@ expand_patsubst(const string &params, bool separate_words) const {
// Description: Expands the "filter" function variable.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_filter(const string &params) const {
expand_filter(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -1987,7 +2009,7 @@ expand_filter(const string &params) const {
// Description: Expands the "filter_out" function variable.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_filter_out(const string &params) const {
expand_filter_out(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2043,7 +2065,7 @@ expand_filter_out(const string &params) const {
// Description: Expands the "subst" function variable.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_subst(const string &params) const {
expand_subst(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2084,7 +2106,7 @@ expand_subst(const string &params) const {
// like "subst" except it only replaces whole words.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_wordsubst(const string &params) const {
expand_wordsubst(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2125,7 +2147,7 @@ expand_wordsubst(const string &params) const {
// into alphabetical order, and also remove duplicates.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_sort(const string &params) const {
expand_sort(const string &params) {
// Split the string up into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -2146,7 +2168,7 @@ expand_sort(const string &params) const {
// remains.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_unique(const string &params) const {
expand_unique(const string &params) {
// Split the string up into tokens based on the spaces.
vector<string> words;
tokenize_whitespace(expand_string(params), words);
@ -2169,6 +2191,36 @@ expand_unique(const string &params) const {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::expand_matrix
// Access: Private
// Description: Expands the "matrix" function variable. This
// combines the different words of the n parameters in
// all possible ways, like the shell {a,b,c} expansion
// characters. For example, $[matrix a b,c,10 20 30]
// expands to ac10 ac20 ac30 bc10 bc20 bc30.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_matrix(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
// Each token gets split up into words based on the spaces.
vector<vector<string> > words;
for (int i = 0; i < (int)tokens.size(); i++) {
words.push_back(vector<string>());
tokenize_whitespace(tokens[i], words.back());
}
// Now synthesize the results recursively.
vector<string> results;
r_expand_matrix(results, words, 0, "");
string result = repaste(results, " ");
return result;
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::expand_if
// Access: Private
@ -2179,7 +2231,7 @@ expand_unique(const string &params) const {
// (i.e. empty).
////////////////////////////////////////////////////////////////////
string PPScope::
expand_if(const string &params) const {
expand_if(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2209,7 +2261,7 @@ expand_if(const string &params) const {
// string equivalence.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_eq(const string &params) const {
expand_eq(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2234,7 +2286,7 @@ expand_eq(const string &params) const {
// string equivalence.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_ne(const string &params) const {
expand_ne(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2259,7 +2311,7 @@ expand_ne(const string &params) const {
// numeric equivalence.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_eqn(const string &params) const {
expand_eqn(const string &params) {
double a, b;
if (!tokenize_numeric_pair(params, a, b)) {
return string();
@ -2279,7 +2331,7 @@ expand_eqn(const string &params) const {
// numeric equivalence.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_nen(const string &params) const {
expand_nen(const string &params) {
double a, b;
if (!tokenize_numeric_pair(params, a, b)) {
return string();
@ -2299,7 +2351,7 @@ expand_nen(const string &params) const {
// numeric relationships.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_ltn(const string &params) const {
expand_ltn(const string &params) {
double a, b;
if (!tokenize_numeric_pair(params, a, b)) {
return string();
@ -2319,7 +2371,7 @@ expand_ltn(const string &params) const {
// numeric relationships.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_len(const string &params) const {
expand_len(const string &params) {
double a, b;
if (!tokenize_numeric_pair(params, a, b)) {
return string();
@ -2339,7 +2391,7 @@ expand_len(const string &params) const {
// numeric relationships.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_gtn(const string &params) const {
expand_gtn(const string &params) {
double a, b;
if (!tokenize_numeric_pair(params, a, b)) {
return string();
@ -2359,7 +2411,7 @@ expand_gtn(const string &params) const {
// numeric relationships.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_gen(const string &params) const {
expand_gen(const string &params) {
double a, b;
if (!tokenize_numeric_pair(params, a, b)) {
return string();
@ -2380,7 +2432,7 @@ expand_gen(const string &params) const {
// argument is nonempty.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_not(const string &params) const {
expand_not(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2406,7 +2458,7 @@ expand_not(const string &params) const {
// Specifically, it returns the first nonempty argument.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_or(const string &params) const {
expand_or(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2428,7 +2480,7 @@ expand_or(const string &params) const {
// Specifically, it returns the last argument.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_and(const string &params) const {
expand_and(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, true);
@ -2454,7 +2506,7 @@ expand_and(const string &params) const {
// Description: Expands the "upcase" function variable.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_upcase(const string &params) const {
expand_upcase(const string &params) {
string result = expand_string(params);
string::iterator si;
for (si = result.begin(); si != result.end(); ++si) {
@ -2469,7 +2521,7 @@ expand_upcase(const string &params) const {
// Description: Expands the "downcase" function variable.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_downcase(const string &params) const {
expand_downcase(const string &params) {
string result = expand_string(params);
string::iterator si;
for (si = result.begin(); si != result.end(); ++si) {
@ -2491,7 +2543,7 @@ expand_downcase(const string &params) const {
// config.h file.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_cdefine(const string &params) const {
expand_cdefine(const string &params) {
string varname = trim_blanks(params);
string expansion = trim_blanks(expand_variable(varname));
@ -2514,7 +2566,7 @@ expand_cdefine(const string &params) const {
// definitions have been encountered.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_closure(const string &params) const {
expand_closure(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, false);
@ -2600,7 +2652,7 @@ expand_closure(const string &params) const {
// the keys in the map.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_unmapped(const string &params) const {
expand_unmapped(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, false);
@ -2646,7 +2698,7 @@ expand_unmapped(const string &params) const {
// #include directives appearing within the files.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_dependencies(const string &params) const {
expand_dependencies(const string &params) {
// Split the string up into filenames based on whitespace.
vector<string> filenames;
tokenize_whitespace(expand_string(params), filenames);
@ -2674,6 +2726,90 @@ expand_dependencies(const string &params) const {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::expand_foreach
// Access: Private
// Description: Expands the "foreach" function variable. This
// evaluates an expression once for each word of a list.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_foreach(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, false);
if (tokens.size() != 3) {
cerr << "foreach requires three parameters.\n";
return string();
}
// The first parameter is the temporary variable name that holds
// each word as it is expanded; the second parameter is the
// space-separated list of words. The third parameter is the
// expression to evaluate.
string varname = trim_blanks(expand_string(tokens[0]));
vector<string> words;
tokenize_whitespace(expand_string(tokens[1]), words);
vector<string> results;
vector<string>::const_iterator wi;
for (wi = words.begin(); wi != words.end(); ++wi) {
define_variable(varname, *wi);
results.push_back(expand_string(tokens[2]));
}
string result = repaste(results, " ");
return result;
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::expand_forscopes
// Access: Private
// Description: Expands the "forscopes" function variable. This
// evaluates an expression once within each of a number
// of named nested scopes.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_forscopes(const string &params) {
// Split the string up into tokens based on the commas.
vector<string> tokens;
tokenize_params(params, tokens, false);
if (tokens.size() != 2) {
cerr << "forscopes requires two parameters.\n";
return string();
}
// The first parameter is the space-separated list of nested scope
// names. The second parameter is the expression to evaluate.
vector<string> scope_names;
tokenize_whitespace(expand_string(tokens[0]), scope_names);
if (_named_scopes == (PPNamedScopes *)NULL) {
return string();
}
// Now build up the list of scopes with these names.
PPNamedScopes::Scopes scopes;
vector<string>::const_iterator wi;
for (wi = scope_names.begin(); wi != scope_names.end(); ++wi) {
_named_scopes->get_scopes(*wi, scopes);
}
PPNamedScopes::sort_by_dependency(scopes);
// Now evaluate the expression within each scope.
vector<string> results;
PPNamedScopes::Scopes::const_iterator si;
for (si = scopes.begin(); si != scopes.end(); ++si) {
PPScope *scope = *si;
results.push_back(scope->expand_string(tokens[1]));
}
string result = repaste(results, " ");
return result;
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::expand_function
// Access: Private
@ -2684,7 +2820,7 @@ expand_dependencies(const string &params) const {
////////////////////////////////////////////////////////////////////
string PPScope::
expand_function(const string &funcname,
const PPSubroutine *sub, const string &params) const {
const PPSubroutine *sub, const string &params) {
PPScope::push_scope((PPScope *)this);
PPScope nested_scope(_named_scopes);
nested_scope.define_formals(funcname, sub->_formals, params);
@ -2731,7 +2867,7 @@ expand_function(const string &funcname,
// first parameter for each corresponding scope.
////////////////////////////////////////////////////////////////////
string PPScope::
expand_map_variable(const string &varname, const string &params) const {
expand_map_variable(const string &varname, const string &params) {
// Split the string up into tokens based on the commas, but don't
// expand the variables yet.
vector<string> tokens;
@ -2760,7 +2896,7 @@ expand_map_variable(const string &varname, const string &params) const {
////////////////////////////////////////////////////////////////////
string PPScope::
expand_map_variable(const string &varname, const string &expression,
const vector<string> &keys) const {
const vector<string> &keys) {
const MapVariableDefinition &def = find_map_variable(varname);
if (&def == &_null_map_def) {
cerr << "Warning: undefined map variable: " << varname << "\n";
@ -2788,6 +2924,31 @@ expand_map_variable(const string &varname, const string &expression,
return result;
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::r_expand_matrix
// Access: Private
// Description: The recursive implementation of expand_matrix().
// This generates all of the combinations from the
// indicated index into the words array, with the given
// prefix.
////////////////////////////////////////////////////////////////////
void PPScope::
r_expand_matrix(vector<string> &results, const vector<vector<string> > &words,
int index, const string &prefix) {
if (index >= (int)words.size()) {
// This is the terminal condition.
results.push_back(prefix);
} else {
// Otherwise, tack on the next set of words, and recurse.
const vector<string> &w = words[index];
vector<string>::const_iterator wi;
for (wi = w.begin(); wi != w.end(); ++wi) {
r_expand_matrix(results, words, index + 1, prefix + (*wi));
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PPScope::p_find_map_variable
// Access: Private
@ -2795,7 +2956,7 @@ expand_map_variable(const string &varname, const string &expression,
// particular static scope, without checking the stack.
////////////////////////////////////////////////////////////////////
PPScope::MapVariableDefinition &PPScope::
p_find_map_variable(const string &varname) const {
p_find_map_variable(const string &varname) {
MapVariables::const_iterator mvi;
mvi = _map_variables.find(varname);
if (mvi != _map_variables.end()) {
@ -2819,7 +2980,20 @@ p_find_map_variable(const string &varname) const {
// files that actually match the globbing characters.
////////////////////////////////////////////////////////////////////
void PPScope::
glob_string(const string &str, vector<string> &results) const {
glob_string(const string &str, vector<string> &results) {
// We run glob_string() within the directory indicated by
// $[THISDIRPREFIX]. This way, local filenames will be expanded the
// way we expect.
string dirname = trim_blanks(expand_variable("THISDIRPREFIX"));
bool changed_dir = false;
if (!dirname.empty()) {
if (chdir(dirname.c_str()) < 0) {
perror("chdir");
} else {
changed_dir = true;
}
}
vector<string> words;
tokenize_whitespace(str, words);
@ -2839,4 +3013,12 @@ glob_string(const string &str, vector<string> &results) const {
}
globfree(&pglob);
// Sort the results into alphabetical order.
sort(results.begin(), results.end());
if (changed_dir) {
// Now restore the current directory back to where it should be.
PPMain::chdir_root();
}
}

View File

@ -28,10 +28,10 @@ public:
PPScope(PPNamedScopes *named_scopes);
PPNamedScopes *get_named_scopes() const;
PPNamedScopes *get_named_scopes();
void set_parent(PPScope *parent);
PPScope *get_parent() const;
PPScope *get_parent();
void define_variable(const string &varname, const string &definition);
bool set_variable(const string &varname, const string &definition);
@ -43,23 +43,23 @@ public:
void define_formals(const string &subroutine_name,
const vector<string> &formals, const string &actuals);
string get_variable(const string &varname) const;
string expand_variable(const string &varname) const;
MapVariableDefinition &find_map_variable(const string &varname) const;
string get_variable(const string &varname);
string expand_variable(const string &varname);
MapVariableDefinition &find_map_variable(const string &varname);
PPDirectory *get_directory() const;
PPDirectory *get_directory();
void set_directory(PPDirectory *directory);
string expand_string(const string &str) const;
string expand_self_reference(const string &str, const string &varname) const;
string expand_string(const string &str);
string expand_self_reference(const string &str, const string &varname);
static void push_scope(PPScope *scope);
static PPScope *pop_scope();
static PPScope *get_bottom_scope();
void tokenize_params(const string &str, vector<string> &tokens,
bool expand) const;
bool tokenize_numeric_pair(const string &str, double &a, double &b) const;
bool expand);
bool tokenize_numeric_pair(const string &str, double &a, double &b);
static MapVariableDefinition _null_map_def;
@ -71,72 +71,80 @@ private:
};
bool p_set_variable(const string &varname, const string &definition);
bool p_get_variable(const string &varname, string &result) const;
bool p_get_variable(const string &varname, string &result);
string r_expand_string(const string &str, ExpandedVariable *expanded) const;
string r_scan_variable(const string &str, size_t &vp) const;
string r_expand_string(const string &str, ExpandedVariable *expanded);
string r_scan_variable(const string &str, size_t &vp);
string r_expand_variable(const string &str, size_t &vp,
PPScope::ExpandedVariable *expanded) const;
PPScope::ExpandedVariable *expanded);
string expand_variable_nested(const string &varname,
const string &scope_names) const;
const string &scope_names);
string expand_isfullpath(const string &params) const;
string expand_osfilename(const string &params) const;
string expand_unixfilename(const string &params) const;
string expand_cygpath_w(const string &params) const;
string expand_cygpath_p(const string &params) const;
string expand_wildcard(const string &params) const;
string expand_isdir(const string &params) const;
string expand_isfile(const string &params) const;
string expand_libtest(const string &params) const;
string expand_bintest(const string &params) const;
string expand_shell(const string &params) const;
string expand_standardize(const string &params) const;
string expand_length(const string &params) const;
string expand_substr(const string &params) const;
string expand_dir(const string &params) const;
string expand_notdir(const string &params) const;
string expand_suffix(const string &params) const;
string expand_basename(const string &params) const;
string expand_word(const string &params) const;
string expand_wordlist(const string &params) const;
string expand_words(const string &params) const;
string expand_firstword(const string &params) const;
string expand_patsubst(const string &params, bool separate_words) const;
string expand_filter(const string &params) const;
string expand_filter_out(const string &params) const;
string expand_wordsubst(const string &params) const;
string expand_subst(const string &params) const;
string expand_sort(const string &params) const;
string expand_unique(const string &params) const;
string expand_if(const string &params) const;
string expand_eq(const string &params) const;
string expand_ne(const string &params) const;
string expand_eqn(const string &params) const;
string expand_nen(const string &params) const;
string expand_ltn(const string &params) const;
string expand_len(const string &params) const;
string expand_gtn(const string &params) const;
string expand_gen(const string &params) const;
string expand_not(const string &params) const;
string expand_or(const string &params) const;
string expand_and(const string &params) const;
string expand_upcase(const string &params) const;
string expand_downcase(const string &params) const;
string expand_cdefine(const string &params) const;
string expand_closure(const string &params) const;
string expand_unmapped(const string &params) const;
string expand_dependencies(const string &params) const;
string expand_isfullpath(const string &params);
string expand_osfilename(const string &params);
string expand_unixfilename(const string &params);
string expand_cygpath_w(const string &params);
string expand_cygpath_p(const string &params);
string expand_wildcard(const string &params);
string expand_isdir(const string &params);
string expand_isfile(const string &params);
string expand_libtest(const string &params);
string expand_bintest(const string &params);
string expand_shell(const string &params);
string expand_standardize(const string &params);
string expand_length(const string &params);
string expand_substr(const string &params);
string expand_dir(const string &params);
string expand_notdir(const string &params);
string expand_suffix(const string &params);
string expand_basename(const string &params);
string expand_word(const string &params);
string expand_wordlist(const string &params);
string expand_words(const string &params);
string expand_firstword(const string &params);
string expand_patsubst(const string &params, bool separate_words);
string expand_filter(const string &params);
string expand_filter_out(const string &params);
string expand_wordsubst(const string &params);
string expand_subst(const string &params);
string expand_sort(const string &params);
string expand_unique(const string &params);
string expand_matrix(const string &params);
string expand_if(const string &params);
string expand_eq(const string &params);
string expand_ne(const string &params);
string expand_eqn(const string &params);
string expand_nen(const string &params);
string expand_ltn(const string &params);
string expand_len(const string &params);
string expand_gtn(const string &params);
string expand_gen(const string &params);
string expand_not(const string &params);
string expand_or(const string &params);
string expand_and(const string &params);
string expand_upcase(const string &params);
string expand_downcase(const string &params);
string expand_cdefine(const string &params);
string expand_closure(const string &params);
string expand_unmapped(const string &params);
string expand_dependencies(const string &params);
string expand_foreach(const string &params);
string expand_forscopes(const string &params);
string expand_function(const string &funcname, const PPSubroutine *sub,
const string &params) const;
string expand_map_variable(const string &varname, const string &params) const;
const string &params);
string expand_map_variable(const string &varname, const string &params);
string expand_map_variable(const string &varname, const string &expression,
const vector<string> &keys) const;
const vector<string> &keys);
void
r_expand_matrix(vector<string> &results,
const vector<vector<string> > &words,
int index, const string &prefix);
MapVariableDefinition &
p_find_map_variable(const string &varname) const;
p_find_map_variable(const string &varname);
void glob_string(const string &str, vector<string> &results) const;
void glob_string(const string &str, vector<string> &results);
PPNamedScopes *_named_scopes;