mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-21 14:41:11 -04:00
274 lines
7.0 KiB
C++
274 lines
7.0 KiB
C++
// Filename: cppManifest.cxx
|
|
// Created by: drose (22Oct99)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://www.panda3d.org/license.txt .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d@yahoogroups.com .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include "cppManifest.h"
|
|
#include "cppExpression.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::ExpansionNode::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPManifest::ExpansionNode::
|
|
ExpansionNode(int parm_number) :
|
|
_parm_number(parm_number)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::ExpansionNode::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPManifest::ExpansionNode::
|
|
ExpansionNode(const string &str) :
|
|
_parm_number(-1), _str(str)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPManifest::
|
|
CPPManifest(const string &args, const CPPFile &file) : _file(file) {
|
|
assert(!args.empty());
|
|
assert(!isspace(args[0]));
|
|
|
|
_expr = (CPPExpression *)NULL;
|
|
_vis = V_public;
|
|
|
|
// First, identify the manifest name.
|
|
|
|
size_t p = 0;
|
|
while (p < args.size() && !isspace(args[p]) && args[p] != '(') {
|
|
p++;
|
|
}
|
|
|
|
_name = args.substr(0, p);
|
|
|
|
vector_string parameter_names;
|
|
|
|
if (args[p] == '(') {
|
|
// Hmm, parameters.
|
|
_has_parameters = true;
|
|
parse_parameters(args, p, parameter_names);
|
|
_num_parameters = parameter_names.size();
|
|
p++;
|
|
} else {
|
|
_has_parameters = false;
|
|
_num_parameters = 0;
|
|
}
|
|
|
|
// Now identify the expansion. Skip whitespace.
|
|
while (p < args.size() && isspace(args[p])) {
|
|
p++;
|
|
}
|
|
|
|
save_expansion(args.substr(p), parameter_names);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::Destructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPManifest::
|
|
~CPPManifest() {
|
|
if (_expr != (CPPExpression *)NULL) {
|
|
delete _expr;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::expand
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
string CPPManifest::
|
|
expand(const vector_string &args) const {
|
|
string result;
|
|
|
|
Expansion::const_iterator ei;
|
|
for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
|
|
if ((*ei)._parm_number >= 0) {
|
|
int i = (*ei)._parm_number;
|
|
if (i < (int)args.size()) {
|
|
result += " " + args[i] + " ";
|
|
} else {
|
|
result += " ";
|
|
}
|
|
}
|
|
if (!(*ei)._str.empty()) {
|
|
result += (*ei)._str;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::determine_type
|
|
// Access: Public
|
|
// Description: Returns the type of the manifest, if it is known,
|
|
// or NULL if the type cannot be determined.
|
|
////////////////////////////////////////////////////////////////////
|
|
CPPType *CPPManifest::
|
|
determine_type() const {
|
|
if (_expr != (CPPExpression *)NULL) {
|
|
return _expr->determine_type();
|
|
}
|
|
return (CPPType *)NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::output
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void CPPManifest::
|
|
output(ostream &out) const {
|
|
out << _name;
|
|
|
|
if (_has_parameters) {
|
|
out << "(";
|
|
if (_num_parameters > 0) {
|
|
out << "$1";
|
|
for (int i = 1; i < _num_parameters; i++) {
|
|
out << ", $" << i + 1;
|
|
}
|
|
}
|
|
out << ")";
|
|
}
|
|
|
|
out << " ";
|
|
|
|
Expansion::const_iterator ei;
|
|
for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
|
|
if ((*ei)._parm_number >= 0) {
|
|
out << " $" << (*ei)._parm_number + 1 << " ";
|
|
}
|
|
if (!(*ei)._str.empty()) {
|
|
out << (*ei)._str;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::parse_parameters
|
|
// Access: Private
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void CPPManifest::
|
|
parse_parameters(const string &args, size_t &p,
|
|
vector_string ¶meter_names) {
|
|
assert(p < args.size());
|
|
assert(args[p] == '(');
|
|
|
|
p++;
|
|
while (p < args.size() && isspace(args[p])) {
|
|
p++;
|
|
}
|
|
|
|
while (p < args.size() && args[p] != ')') {
|
|
// Here's the beginning of a parm.
|
|
size_t q = p;
|
|
while (p < args.size() && !isspace(args[p]) &&
|
|
args[p] != ')' && args[p] != ',') {
|
|
p++;
|
|
}
|
|
parameter_names.push_back(args.substr(q, p - q));
|
|
|
|
// Skip whitespace after the parameter name.
|
|
while (p < args.size() && isspace(args[p])) {
|
|
p++;
|
|
}
|
|
|
|
if (p < args.size() && args[p] == ',') {
|
|
p++;
|
|
// Skip whitespace after a comma.
|
|
while (p < args.size() && isspace(args[p])) {
|
|
p++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CPPManifest::save_expansion
|
|
// Access: Private
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void CPPManifest::
|
|
save_expansion(const string &exp, const vector_string ¶meter_names) {
|
|
if (parameter_names.empty()) {
|
|
// No parameters; this is an easy case.
|
|
_expansion.push_back(ExpansionNode(exp));
|
|
return;
|
|
}
|
|
|
|
// Walk through the expansion string. For each substring that is an
|
|
// identifier, check it against parameter_names.
|
|
size_t p = 0;
|
|
size_t last = 0;
|
|
while (p < exp.size()) {
|
|
if (isalpha(exp[p]) || exp[p] == '_') {
|
|
// Here's the start of an identifier. Find the end of it.
|
|
size_t q = p;
|
|
p++;
|
|
while (p < exp.size() && isalnum(exp[p]) || exp[p] == '_') {
|
|
p++;
|
|
}
|
|
|
|
string ident = exp.substr(q, p - q);
|
|
|
|
// Is this identifier one of our parameters?
|
|
int pnum = -1;
|
|
for (int i = 0; pnum == -1 && i < (int)parameter_names.size(); i++) {
|
|
if (parameter_names[i] == ident) {
|
|
pnum = i;
|
|
}
|
|
}
|
|
|
|
if (pnum != -1) {
|
|
// Yep!
|
|
if (last != q) {
|
|
_expansion.push_back(ExpansionNode(exp.substr(last, q - last)));
|
|
}
|
|
_expansion.push_back(pnum);
|
|
last = p;
|
|
}
|
|
} else {
|
|
p++;
|
|
}
|
|
}
|
|
|
|
if (last != p) {
|
|
_expansion.push_back(exp.substr(last, p - last));
|
|
}
|
|
}
|