mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
add some 1.05 features: #push, better #output .. #end matching, #printvar
This commit is contained in:
parent
563772fd77
commit
988658f58e
@ -80,5 +80,5 @@
|
||||
** Also be sure to change the version number **
|
||||
** at the beginning of configure.in. **
|
||||
**************** ****************/
|
||||
#define VERSION "1.04"
|
||||
#define VERSION "1.05"
|
||||
/**************** UPDATE VERSION NUMBER HERE ****************/
|
||||
|
@ -5,7 +5,7 @@ dnl **************** UPDATE VERSION NUMBER HERE ****************
|
||||
dnl ** Also be sure to change the version number **
|
||||
dnl ** at the end of config_msvc.h. **
|
||||
dnl **************** ****************
|
||||
AM_INIT_AUTOMAKE(ppremake, 1.04)
|
||||
AM_INIT_AUTOMAKE(ppremake, 1.05)
|
||||
dnl **************** UPDATE VERSION NUMBER HERE ****************
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
@ -59,7 +59,7 @@
|
||||
// pathnames.
|
||||
#ifdef HAVE_CYGWIN
|
||||
extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32);
|
||||
//extern "C" void cygwin_conv_to_posix_path(const char *path, char *posix);
|
||||
extern "C" void cygwin_conv_to_posix_path(const char *path, char *posix);
|
||||
#endif
|
||||
|
||||
static string
|
||||
@ -1294,7 +1294,21 @@ bool Filename::
|
||||
touch() const {
|
||||
#ifdef HAVE_UTIME_H
|
||||
// Most Unix systems can do this explicitly.
|
||||
|
||||
string os_specific = to_os_specific();
|
||||
#ifdef HAVE_CYGWIN
|
||||
// In the Cygwin case, it seems we need to be sure to use the
|
||||
// Cygwin-style name; some broken utime() implementation. That's
|
||||
// almost the same thing as the original Panda-style name, but not
|
||||
// exactly, so we first convert the Panda name to a Windows name,
|
||||
// then convert it back to Cygwin, to ensure we get it exactly right
|
||||
// by Cygwin rules.
|
||||
{
|
||||
char result[4096] = "";
|
||||
cygwin_conv_to_posix_path(os_specific.c_str(), result);
|
||||
os_specific = result;
|
||||
}
|
||||
#endif // HAVE_CYGWIN
|
||||
int result = utime(os_specific.c_str(), NULL);
|
||||
if (result < 0) {
|
||||
if (errno == ENOENT) {
|
||||
@ -1311,14 +1325,14 @@ touch() const {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
#else // HAVE_UTIME_H
|
||||
// Other systems may not have an explicit control over the
|
||||
// modification time. For these systems, we'll just temporarily
|
||||
// open the file in append mode, then close it again (it gets closed
|
||||
// when the ofstream goes out of scope).
|
||||
ofstream file;
|
||||
return open_append(file);
|
||||
#endif
|
||||
#endif // HAVE_UTIME_H
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -74,7 +74,7 @@ pop(PPCommandFile *file) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PPCommandFile::WriteState::
|
||||
WriteState() {
|
||||
_out = &cout;
|
||||
_out = NULL;
|
||||
_format = WF_collapse;
|
||||
_last_blank = true;
|
||||
}
|
||||
@ -99,6 +99,13 @@ WriteState(const WriteState ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PPCommandFile::WriteState::
|
||||
write_line(const string &line) {
|
||||
if (_out == (ostream *)NULL || _format == WF_error) {
|
||||
if (!line.empty()) {
|
||||
cerr << "Ignoring: " << line << "\n";
|
||||
}
|
||||
return true;
|
||||
|
||||
} else {
|
||||
switch (_format) {
|
||||
case WF_straight:
|
||||
(*_out) << line << "\n";
|
||||
@ -113,6 +120,7 @@ write_line(const string &line) {
|
||||
|
||||
cerr << "Unsupported write format: " << (int)_format << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -276,8 +284,8 @@ set_output(ostream *out) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPCommandFile::
|
||||
set_scope(PPScope *scope) {
|
||||
_scope = scope;
|
||||
_native_scope = scope;
|
||||
_scope = scope;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -622,6 +630,9 @@ handle_command(const string &line) {
|
||||
} else if (_command == "print") {
|
||||
return handle_print_command();
|
||||
|
||||
} else if (_command == "printvar") {
|
||||
return handle_printvar_command();
|
||||
|
||||
} else if (_command == "include") {
|
||||
return handle_include_command();
|
||||
|
||||
@ -648,6 +659,9 @@ handle_command(const string &line) {
|
||||
|
||||
} else if (_command == "addmap") {
|
||||
return handle_addmap_command();
|
||||
|
||||
} else if (_command == "push") {
|
||||
return handle_push_command();
|
||||
}
|
||||
|
||||
cerr << "Invalid command: " << COMMAND_PREFIX << _command << "\n";
|
||||
@ -792,7 +806,7 @@ handle_endif_command() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PPCommandFile::
|
||||
handle_begin_command() {
|
||||
string name = trim_blanks(_scope->expand_string(_params));
|
||||
string name = trim_blanks(_params);
|
||||
BlockNesting *nest = new BlockNesting(BS_begin, name);
|
||||
|
||||
if (contains_whitespace(name)) {
|
||||
@ -828,7 +842,7 @@ handle_begin_command() {
|
||||
bool PPCommandFile::
|
||||
handle_forscopes_command() {
|
||||
BlockState state = _in_for ? BS_nested_forscopes : BS_forscopes;
|
||||
string name = trim_blanks(_scope->expand_string(_params));
|
||||
string name = trim_blanks(_params);
|
||||
BlockNesting *nest = new BlockNesting(state, name);
|
||||
nest->push(this);
|
||||
|
||||
@ -985,18 +999,25 @@ handle_defsub_command(bool is_defsub) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PPCommandFile::
|
||||
handle_output_command() {
|
||||
vector<string> words;
|
||||
tokenize_whitespace(_scope->expand_string(_params), words);
|
||||
// We must get the filename out (the first parameter) without
|
||||
// expanding it, because it might involve a string that has to be
|
||||
// expanded later.
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string name = _params.substr(0, p);
|
||||
|
||||
if (words.empty()) {
|
||||
if (name.empty()) {
|
||||
cerr << "#output command requires one parameter.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
BlockNesting *nest = new BlockNesting(BS_output, words[0]);
|
||||
// Now get the remaining parameters out; these we will expand immediately.
|
||||
vector<string> words;
|
||||
tokenize_whitespace(_scope->expand_string(_params.substr(p)), words);
|
||||
|
||||
BlockNesting *nest = new BlockNesting(BS_output, name);
|
||||
|
||||
// Also check the output flags.
|
||||
for (int i = 1; i < (int)words.size(); i++) {
|
||||
for (int i = 0; i < (int)words.size(); i++) {
|
||||
if (words[i] == "notouch") {
|
||||
nest->_flags |= OF_notouch;
|
||||
} else {
|
||||
@ -1007,7 +1028,7 @@ handle_output_command() {
|
||||
nest->push(this);
|
||||
|
||||
if (!_in_for) {
|
||||
string filename = nest->_name;
|
||||
string filename = trim_blanks(_scope->expand_string(nest->_name));
|
||||
if (filename.empty()) {
|
||||
cerr << "Attempt to output to empty filename\n";
|
||||
return false;
|
||||
@ -1041,7 +1062,13 @@ handle_end_command() {
|
||||
return false;
|
||||
}
|
||||
|
||||
string name = trim_blanks(_scope->expand_string(_params));
|
||||
// We don't expand the closing name string, because we didn't expand
|
||||
// the opening string. (This is especially true for an #output
|
||||
// statement. On some of the other statements, we might have
|
||||
// inadvertently expanded this string, but probably that was a
|
||||
// mistake; and there's no reason for programmers to take advantage
|
||||
// of an expansion there.)
|
||||
string name = trim_blanks(_params);
|
||||
if (name != _block_nesting->_name) {
|
||||
cerr << "end " << name << " encountered where end "
|
||||
<< _block_nesting->_name << " expected.\n";
|
||||
@ -1158,6 +1185,33 @@ handle_print_command() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPCommandFile::handle_printvar_command
|
||||
// Access: Protected
|
||||
// Description: Writes the literal contents of the named variable(s)
|
||||
// (the variables are named directly without enclosing
|
||||
// $[ ... ] syntax) to cerr, for debugging.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PPCommandFile::
|
||||
handle_printvar_command() {
|
||||
size_t p = 0;
|
||||
|
||||
while (p < _params.length()) {
|
||||
// Pull off the next varname.
|
||||
size_t q = _scope->scan_to_whitespace(_params, p);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(p, q)));
|
||||
|
||||
cerr << varname << " = \"" << _scope->get_variable(varname)
|
||||
<< "\" ";
|
||||
p = q;
|
||||
while (p < _params.length() && isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
cerr << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPCommandFile::handle_include_command
|
||||
// Access: Protected
|
||||
@ -1288,11 +1342,8 @@ handle_error_command() {
|
||||
bool PPCommandFile::
|
||||
handle_defer_command() {
|
||||
// Pull off the first word and the rest of the params.
|
||||
size_t p = 0;
|
||||
while (p < _params.length() && !isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
string varname = _params.substr(0, p);
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(0, p)));
|
||||
|
||||
if (PPSubroutine::get_func(varname) != (const PPSubroutine *)NULL) {
|
||||
cerr << "Warning: variable " << varname
|
||||
@ -1310,7 +1361,6 @@ handle_defer_command() {
|
||||
// should expand any simple self-reference immediately, to allow for
|
||||
// recursive definitions.
|
||||
def = _scope->expand_self_reference(def, varname);
|
||||
|
||||
_scope->define_variable(varname, def);
|
||||
|
||||
return true;
|
||||
@ -1327,11 +1377,8 @@ handle_defer_command() {
|
||||
bool PPCommandFile::
|
||||
handle_define_command() {
|
||||
// Pull off the first word and the rest of the params.
|
||||
size_t p = 0;
|
||||
while (p < _params.length() && !isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
string varname = _params.substr(0, p);
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(0, p)));
|
||||
|
||||
if (PPSubroutine::get_func(varname) != (const PPSubroutine *)NULL) {
|
||||
cerr << "Warning: variable " << varname
|
||||
@ -1366,11 +1413,8 @@ handle_define_command() {
|
||||
bool PPCommandFile::
|
||||
handle_set_command() {
|
||||
// Pull off the first word and the rest of the params.
|
||||
size_t p = 0;
|
||||
while (p < _params.length() && !isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
string varname = _params.substr(0, p);
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(0, p)));
|
||||
|
||||
if (PPSubroutine::get_func(varname) != (const PPSubroutine *)NULL) {
|
||||
cerr << "Warning: variable " << varname
|
||||
@ -1403,18 +1447,14 @@ handle_set_command() {
|
||||
bool PPCommandFile::
|
||||
handle_map_command() {
|
||||
// Pull off the first word and the rest of the params.
|
||||
size_t p = 0;
|
||||
while (p < _params.length() && !isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
string varname = _params.substr(0, p);
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(0, p)));
|
||||
|
||||
// Skip whitespace between the variable name and its definition.
|
||||
while (p < _params.length() && isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
string def = trim_blanks(_params.substr(p));
|
||||
|
||||
_scope->define_map_variable(varname, def);
|
||||
return true;
|
||||
}
|
||||
@ -1428,11 +1468,8 @@ handle_map_command() {
|
||||
bool PPCommandFile::
|
||||
handle_addmap_command() {
|
||||
// Pull off the first word and the rest of the params.
|
||||
size_t p = 0;
|
||||
while (p < _params.length() && !isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
string varname = _params.substr(0, p);
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(0, p)));
|
||||
|
||||
// Skip whitespace between the variable name and the key.
|
||||
while (p < _params.length() && isspace(_params[p])) {
|
||||
@ -1444,6 +1481,61 @@ handle_addmap_command() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPCommandFile::handle_push_command
|
||||
// Access: Protected
|
||||
// Description: Handles the #push command: push a variable definition
|
||||
// out to the enclosing scope. Useful for defining
|
||||
// variables within a #forscopes block that you want to
|
||||
// persist longer than the block itself.
|
||||
//
|
||||
// Syntax is:
|
||||
//
|
||||
// #push n varname [varname2 ... ]
|
||||
//
|
||||
// Where n is the number of levels out to push.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PPCommandFile::
|
||||
handle_push_command() {
|
||||
// The first word is the number of levels.
|
||||
size_t p = _scope->scan_to_whitespace(_params);
|
||||
string levels_str = trim_blanks(_scope->expand_string(_params.substr(0, p)));
|
||||
|
||||
// Validate the number.
|
||||
const char *param = levels_str.c_str();
|
||||
char *n;
|
||||
int levels = strtol(param, &n, 10);
|
||||
if (n == param || levels < 0) {
|
||||
// Invalid integer.
|
||||
cerr << "#push with invalid level count: " << levels_str << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
PPScope *enclosing_scope = _scope;
|
||||
if (levels > 0) {
|
||||
enclosing_scope = _scope->get_enclosing_scope(levels - 1);
|
||||
}
|
||||
|
||||
// Skip whitespace to the first variable name.
|
||||
while (p < _params.length() && isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
|
||||
while (p < _params.length()) {
|
||||
// Pull off the next varname.
|
||||
size_t q = _scope->scan_to_whitespace(_params, p);
|
||||
string varname = trim_blanks(_scope->expand_string(_params.substr(p, q)));
|
||||
string def = _scope->get_variable(varname);
|
||||
enclosing_scope->define_variable(varname, def);
|
||||
|
||||
p = q;
|
||||
while (p < _params.length() && isspace(_params[p])) {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPCommandFile::include_file
|
||||
|
@ -54,6 +54,7 @@ protected:
|
||||
|
||||
bool handle_format_command();
|
||||
bool handle_print_command();
|
||||
bool handle_printvar_command();
|
||||
bool handle_include_command();
|
||||
bool handle_sinclude_command();
|
||||
bool handle_call_command();
|
||||
@ -64,6 +65,7 @@ protected:
|
||||
bool handle_set_command();
|
||||
bool handle_map_command();
|
||||
bool handle_addmap_command();
|
||||
bool handle_push_command();
|
||||
|
||||
bool include_file(Filename filename);
|
||||
bool replay_forscopes(const string &name);
|
||||
@ -121,6 +123,7 @@ private:
|
||||
};
|
||||
|
||||
enum WriteFormat {
|
||||
WF_error, // anything other than whitespace is an error.
|
||||
WF_straight, // write lines directly as they come in
|
||||
WF_collapse, // collapse out consecutive blank lines
|
||||
WF_makefile // fancy makefile formatting
|
||||
|
@ -571,6 +571,25 @@ get_bottom_scope() {
|
||||
return _scope_stack.front();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPScope::get_enclosing_scope
|
||||
// Access: Public, Static
|
||||
// Description: Returns the scope n below the top of the stack, or
|
||||
// the bottom scope if the stack has exactly n or fewer
|
||||
// scopes.
|
||||
//
|
||||
// This will be the scope associated with the nth
|
||||
// enclosing syntax in the source file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PPScope *PPScope::
|
||||
get_enclosing_scope(int n) {
|
||||
assert(n >= 0);
|
||||
if (n >= _scope_stack.size()) {
|
||||
return get_bottom_scope();
|
||||
}
|
||||
return _scope_stack[_scope_stack.size() - 1 - n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPScope::tokenize_params
|
||||
// Access: Public
|
||||
@ -665,6 +684,42 @@ tokenize_numeric_pair(const string &str, double &a, double &b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPScope::scan_to_whitespace
|
||||
// Access: Public
|
||||
// Description: Scans to the end of the first whitespace-delimited
|
||||
// word in the indicated string, even if it includes a
|
||||
// nested variable reference (which is itself allowed to
|
||||
// contain whitespace).
|
||||
//
|
||||
// On input, str is a string, and start is the starting
|
||||
// position within the string of the scan; it should
|
||||
// point to a non-whitespace character.
|
||||
//
|
||||
// The return value is the position within the string of
|
||||
// the first whitespace character encountered at its
|
||||
// original position or later, that is not part of a
|
||||
// variable reference. All variable references are left
|
||||
// unexpanded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
size_t PPScope::
|
||||
scan_to_whitespace(const string &str, size_t start) {
|
||||
size_t p = start;
|
||||
while (p < str.length() && !isspace(str[p])) {
|
||||
string token;
|
||||
if (p + 1 < str.length() && str[p] == VARIABLE_PREFIX &&
|
||||
str[p + 1] == VARIABLE_OPEN_BRACE) {
|
||||
// Skip a nested variable reference.
|
||||
r_scan_variable(str, p);
|
||||
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPScope::p_set_variable
|
||||
// Access: Private
|
||||
|
@ -56,10 +56,12 @@ public:
|
||||
static void push_scope(PPScope *scope);
|
||||
static PPScope *pop_scope();
|
||||
static PPScope *get_bottom_scope();
|
||||
static PPScope *get_enclosing_scope(int n);
|
||||
|
||||
void tokenize_params(const string &str, vector<string> &tokens,
|
||||
bool expand);
|
||||
bool tokenize_numeric_pair(const string &str, double &a, double &b);
|
||||
size_t scan_to_whitespace(const string &str, size_t start = 0);
|
||||
|
||||
static MapVariableDefinition _null_map_def;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user