00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cppManifest.h"
00021 #include "cppExpression.h"
00022
00023 #include <ctype.h>
00024
00025
00026
00027
00028
00029
00030 CPPManifest::ExpansionNode::
00031 ExpansionNode(int parm_number) :
00032 _parm_number(parm_number)
00033 {
00034 }
00035
00036
00037
00038
00039
00040
00041 CPPManifest::ExpansionNode::
00042 ExpansionNode(const string &str) :
00043 _parm_number(-1), _str(str)
00044 {
00045 }
00046
00047
00048
00049
00050
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
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
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
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
00093
00094
00095
00096 CPPManifest::
00097 ~CPPManifest() {
00098 if (_expr != (CPPExpression *)NULL) {
00099 delete _expr;
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108
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
00134
00135
00136
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
00148
00149
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
00183
00184
00185
00186 void CPPManifest::
00187 parse_parameters(const string &args, size_t &p,
00188 vector_string ¶meter_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
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
00207 while (p < args.size() && isspace(args[p])) {
00208 p++;
00209 }
00210
00211 if (p < args.size() && args[p] == ',') {
00212 p++;
00213
00214 while (p < args.size() && isspace(args[p])) {
00215 p++;
00216 }
00217 }
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226 void CPPManifest::
00227 save_expansion(const string &exp, const vector_string ¶meter_names) {
00228 if (parameter_names.empty()) {
00229
00230 _expansion.push_back(ExpansionNode(exp));
00231 return;
00232 }
00233
00234
00235
00236 size_t p = 0;
00237 size_t last = 0;
00238 while (p < exp.size()) {
00239 if (isalpha(exp[p]) || exp[p] == '_') {
00240
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
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
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 }