Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dtool/src/cppparser/cppManifest.cxx

Go to the documentation of this file.
00001 // Filename: cppManifest.cxx
00002 // Created by:  drose (22Oct99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 
00020 #include "cppManifest.h"
00021 #include "cppExpression.h"
00022 
00023 #include <ctype.h>
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: CPPManifest::ExpansionNode::Constructor
00027 //       Access: Public
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 CPPManifest::ExpansionNode::
00031 ExpansionNode(int parm_number) :
00032   _parm_number(parm_number)
00033 {
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: CPPManifest::ExpansionNode::Constructor
00038 //       Access: Public
00039 //  Description:
00040 ////////////////////////////////////////////////////////////////////
00041 CPPManifest::ExpansionNode::
00042 ExpansionNode(const string &str) :
00043   _parm_number(-1), _str(str)
00044 {
00045 }
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: CPPManifest::Constructor
00049 //       Access: Public
00050 //  Description:
00051 ////////////////////////////////////////////////////////////////////
00052 CPPManifest::
00053 CPPManifest(const string &args, const CPPFile &file) : _file(file) {
00054   assert(!args.empty());
00055   assert(!isspace(args[0]));
00056 
00057   _expr = (CPPExpression *)NULL;
00058   _vis = V_public;
00059 
00060   // First, identify the manifest name.
00061 
00062   size_t p = 0;
00063   while (p < args.size() && !isspace(args[p]) && args[p] != '(') {
00064     p++;
00065   }
00066 
00067   _name = args.substr(0, p);
00068 
00069   vector_string parameter_names;
00070 
00071   if (args[p] == '(') {
00072     // Hmm, parameters.
00073     _has_parameters = true;
00074     parse_parameters(args, p, parameter_names);
00075     _num_parameters = parameter_names.size();
00076     p++;
00077   } else {
00078     _has_parameters = false;
00079     _num_parameters = 0;
00080   }
00081 
00082   // Now identify the expansion.  Skip whitespace.
00083   while (p < args.size() && isspace(args[p])) {
00084     p++;
00085   }
00086 
00087   save_expansion(args.substr(p), parameter_names);
00088 }
00089 
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: CPPManifest::Destructor
00093 //       Access: Public
00094 //  Description:
00095 ////////////////////////////////////////////////////////////////////
00096 CPPManifest::
00097 ~CPPManifest() {
00098   if (_expr != (CPPExpression *)NULL) {
00099     delete _expr;
00100   }
00101 }
00102 
00103 
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: CPPManifest::expand
00107 //       Access: Public
00108 //  Description:
00109 ////////////////////////////////////////////////////////////////////
00110 string CPPManifest::
00111 expand(const vector_string &args) const {
00112   string result;
00113 
00114   Expansion::const_iterator ei;
00115   for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
00116     if ((*ei)._parm_number >= 0) {
00117       int i = (*ei)._parm_number;
00118       if (i < (int)args.size()) {
00119         result += " " + args[i] + " ";
00120       } else {
00121         result += " ";
00122       }
00123     }
00124     if (!(*ei)._str.empty()) {
00125       result += (*ei)._str;
00126     }
00127   }
00128 
00129   return result;
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: CPPManifest::determine_type
00134 //       Access: Public
00135 //  Description: Returns the type of the manifest, if it is known,
00136 //               or NULL if the type cannot be determined.
00137 ////////////////////////////////////////////////////////////////////
00138 CPPType *CPPManifest::
00139 determine_type() const {
00140   if (_expr != (CPPExpression *)NULL) {
00141     return _expr->determine_type();
00142   }
00143   return (CPPType *)NULL;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: CPPManifest::output
00148 //       Access: Public
00149 //  Description:
00150 ////////////////////////////////////////////////////////////////////
00151 void CPPManifest::
00152 output(ostream &out) const {
00153   out << _name;
00154 
00155   if (_has_parameters) {
00156     out << "(";
00157     if (_num_parameters > 0) {
00158       out << "$1";
00159       for (int i = 1; i < _num_parameters; i++) {
00160         out << ", $" << i + 1;
00161       }
00162     }
00163     out << ")";
00164   }
00165 
00166   out << " ";
00167 
00168   Expansion::const_iterator ei;
00169   for (ei = _expansion.begin(); ei != _expansion.end(); ++ei) {
00170     if ((*ei)._parm_number >= 0) {
00171       out << " $" << (*ei)._parm_number + 1 << " ";
00172     }
00173     if (!(*ei)._str.empty()) {
00174       out << (*ei)._str;
00175     }
00176   }
00177 }
00178 
00179 
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: CPPManifest::parse_parameters
00183 //       Access: Private
00184 //  Description:
00185 ////////////////////////////////////////////////////////////////////
00186 void CPPManifest::
00187 parse_parameters(const string &args, size_t &p,
00188                  vector_string &parameter_names) {
00189   assert(p < args.size());
00190   assert(args[p] == '(');
00191 
00192   p++;
00193   while (p < args.size() && isspace(args[p])) {
00194     p++;
00195   }
00196 
00197   while (p < args.size() && args[p] != ')') {
00198     // Here's the beginning of a parm.
00199     size_t q = p;
00200     while (p < args.size() && !isspace(args[p]) &&
00201            args[p] != ')' && args[p] != ',') {
00202       p++;
00203     }
00204     parameter_names.push_back(args.substr(q, p - q));
00205 
00206     // Skip whitespace after the parameter name.
00207     while (p < args.size() && isspace(args[p])) {
00208       p++;
00209     }
00210 
00211     if (p < args.size() && args[p] == ',') {
00212       p++;
00213       // Skip whitespace after a comma.
00214       while (p < args.size() && isspace(args[p])) {
00215         p++;
00216       }
00217     }
00218   }
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: CPPManifest::save_expansion
00223 //       Access: Private
00224 //  Description:
00225 ////////////////////////////////////////////////////////////////////
00226 void CPPManifest::
00227 save_expansion(const string &exp, const vector_string &parameter_names) {
00228   if (parameter_names.empty()) {
00229     // No parameters; this is an easy case.
00230     _expansion.push_back(ExpansionNode(exp));
00231     return;
00232   }
00233 
00234   // Walk through the expansion string.  For each substring that is an
00235   // identifier, check it against parameter_names.
00236   size_t p = 0;
00237   size_t last = 0;
00238   while (p < exp.size()) {
00239     if (isalpha(exp[p]) || exp[p] == '_') {
00240       // Here's the start of an identifier.  Find the end of it.
00241       size_t q = p;
00242       p++;
00243       while (p < exp.size() && isalnum(exp[p]) || exp[p] == '_') {
00244         p++;
00245       }
00246 
00247       string ident = exp.substr(q, p - q);
00248 
00249       // Is this identifier one of our parameters?
00250       int pnum = -1;
00251       for (int i = 0; pnum == -1 && i < (int)parameter_names.size(); i++) {
00252         if (parameter_names[i] == ident) {
00253           pnum = i;
00254         }
00255       }
00256 
00257       if (pnum != -1) {
00258         // Yep!
00259         if (last != q) {
00260           _expansion.push_back(ExpansionNode(exp.substr(last, q - last)));
00261         }
00262         _expansion.push_back(pnum);
00263         last = p;
00264       }
00265     } else {
00266       p++;
00267     }
00268   }
00269 
00270   if (last != p) {
00271     _expansion.push_back(exp.substr(last, p - last));
00272   }
00273 }

Generated on Thu May 1 22:12:52 2003 for DTool by doxygen1.3