| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- // 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
- // [email protected] .
- //
- ////////////////////////////////////////////////////////////////////
- #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));
- }
- }
|