00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <cppParser.h>
00020 #include <cppManifest.h>
00021 #include <cppStructType.h>
00022 #include <cppFunctionGroup.h>
00023 #include <cppTypedef.h>
00024 #include <cppExpressionParser.h>
00025 #include <cppExpression.h>
00026 #include <cppType.h>
00027 #include <cppGlobals.h>
00028
00029 #include <stdlib.h>
00030
00031 #ifndef HAVE_GETOPT
00032 #include <gnu_getopt.h>
00033 #else
00034 #include <getopt.h>
00035 #endif
00036
00037 CPPParser parser;
00038
00039 void
00040 predefine_macro(CPPParser &parser, const string &option) {
00041 string macro_name, macro_def;
00042
00043 size_t eq = option.find('=');
00044 if (eq != string::npos) {
00045 macro_name = option.substr(0, eq);
00046 macro_def = option.substr(eq + 1);
00047 } else {
00048 macro_name = option;
00049 }
00050
00051 cerr << "Predefining " << macro_name << " as " << macro_def << "\n";
00052
00053 CPPManifest *macro = new CPPManifest(macro_name + " " + macro_def);
00054 parser._manifests[macro->_name] = macro;
00055 }
00056
00057 void
00058 show_type_or_expression(const string &str) {
00059 CPPExpression *expr = parser.parse_expr(str);
00060 if (expr != NULL) {
00061 cout << "\nExpression: " << *expr << "\n";
00062 CPPType *type = expr->determine_type();
00063 if (type == NULL) {
00064 cout << "type is unknown\n";
00065 } else {
00066 cout << "type is " << *type << "\n";
00067 }
00068 cout << "value is " << expr->evaluate() << "\n\n";
00069
00070 } else {
00071 CPPType *type = parser.parse_type(str);
00072 if (type != NULL) {
00073 cout << "\nType: " << *type << "\n"
00074 << "Defined in: " << type->_file << "\n"
00075 << "Subtype code is: " << (int)type->get_subtype() << "\n\n";
00076
00077 CPPStructType *stype = type->as_struct_type();
00078 if (stype != (CPPStructType *)NULL) {
00079 stype->check_virtual();
00080 }
00081
00082 type->output(cout, 0, &parser, true);
00083 cout << "\n\n"
00084 << "is_template = " << type->is_template() << "\n"
00085 << "is_fully_specified = " << type->is_fully_specified() << "\n"
00086 << "is_tbd = " << type->is_tbd() << "\n";
00087 if (type->has_typedef_name()) {
00088 cout << "get_typedef_name = " << type->get_typedef_name() << "\n";
00089 }
00090 cout << "get_simple_name = " << type->get_simple_name() << "\n"
00091 << "get_local_name = " << type->get_local_name() << "\n"
00092 << "get_fully_scoped_name = " << type->get_fully_scoped_name() << "\n"
00093 << "get_preferred_name = " << type->get_preferred_name() << "\n"
00094 << "is_incomplete = " << type->is_incomplete() << "\n";
00095
00096 if (stype != (CPPStructType *)NULL) {
00097 cout << "scope = " << stype->get_scope()->get_fully_scoped_name() << "\n";
00098 bool is_abstract = stype->is_abstract();
00099 cout << "is_abstract = " << is_abstract << "\n";
00100 if (is_abstract) {
00101 cout << "pure virtual functions:\n";
00102 CPPStructType::VFunctions vf;
00103 stype->get_pure_virtual_funcs(vf);
00104 CPPStructType::VFunctions::const_iterator fi;
00105 for (fi = vf.begin(); fi != vf.end(); ++fi) {
00106 cout << " " << *(*fi) << "\n";
00107 }
00108 }
00109 }
00110
00111 cout << "\n";
00112 } else {
00113 cout << "Invalid expression or type.\n";
00114 }
00115 }
00116 }
00117
00118 void
00119 show_methods(const string &str) {
00120 CPPType *type = parser.parse_type(str);
00121 if (type == NULL) {
00122 cerr << "Invalid type: " << str << "\n";
00123 return;
00124 }
00125
00126 CPPStructType *stype = type->as_struct_type();
00127 if (stype == NULL) {
00128 cerr << "Type is not a structure or class.\n";
00129 return;
00130 }
00131
00132 CPPScope *scope = stype->get_scope();
00133 assert(scope != (CPPScope *)NULL);
00134
00135 cerr << "Methods in " << *stype << ":\n";
00136
00137 CPPScope::Functions::const_iterator fi;
00138 for (fi = scope->_functions.begin(); fi != scope->_functions.end(); ++fi) {
00139 CPPFunctionGroup *fgroup = (*fi).second;
00140
00141 CPPFunctionGroup::Instances::const_iterator ii;
00142 for (ii = fgroup->_instances.begin();
00143 ii != fgroup->_instances.end();
00144 ++ii) {
00145 CPPInstance *inst = (*ii);
00146 cerr << " " << *inst << "\n";
00147 }
00148 }
00149 }
00150
00151 void
00152 show_data_members(const string &str) {
00153 CPPType *type = parser.parse_type(str);
00154 if (type == NULL) {
00155 cerr << "Invalid type: " << str << "\n";
00156 return;
00157 }
00158
00159 CPPStructType *stype = type->as_struct_type();
00160 if (stype == NULL) {
00161 cerr << "Type is not a structure or class.\n";
00162 return;
00163 }
00164
00165 CPPScope *scope = stype->get_scope();
00166 assert(scope != (CPPScope *)NULL);
00167
00168 cerr << "Data members in " << *stype << ":\n";
00169
00170 CPPScope::Variables::const_iterator vi;
00171 for (vi = scope->_variables.begin(); vi != scope->_variables.end(); ++vi) {
00172 CPPInstance *inst = (*vi).second;
00173 cerr << " " << *inst << "\n";
00174 }
00175 }
00176
00177 void
00178 show_typedefs(const string &str) {
00179 CPPType *type = parser.parse_type(str);
00180 if (type == NULL) {
00181 cerr << "Invalid type: " << str << "\n";
00182 return;
00183 }
00184
00185 CPPStructType *stype = type->as_struct_type();
00186 if (stype == NULL) {
00187 cerr << "Type is not a structure or class.\n";
00188 return;
00189 }
00190
00191 CPPScope *scope = stype->get_scope();
00192 assert(scope != (CPPScope *)NULL);
00193
00194 cerr << "Typedefs in " << *stype << ":\n";
00195
00196 CPPScope::Typedefs::const_iterator ti;
00197 for (ti = scope->_typedefs.begin(); ti != scope->_typedefs.end(); ++ti) {
00198 CPPTypedef *td = (*ti).second;
00199 cerr << " " << *td << "\n";
00200 }
00201 }
00202
00203
00204 int
00205 main(int argc, char *argv[]) {
00206 extern char *optarg;
00207 extern int optind;
00208 const char *optstr = "I:S:D:o:l:vp";
00209
00210 parser.set_verbose(2);
00211 bool prompt = false;
00212
00213 int flag = getopt(argc, argv, optstr);
00214
00215 while (flag != EOF) {
00216 switch (flag) {
00217 case 'I':
00218 parser._include_path.append_directory(optarg);
00219 break;
00220
00221 case 'S':
00222 parser._system_include_path.append_directory(optarg);
00223 break;
00224
00225 case 'D':
00226 predefine_macro(parser, optarg);
00227 break;
00228
00229 case 'o':
00230 cerr << "Ignoring output file " << optarg << "\n";
00231 break;
00232
00233 case 'l':
00234 cpp_longlong_keyword = optarg;
00235 break;
00236
00237 case 'v':
00238 parser.set_verbose(parser.get_verbose() + 1);
00239 break;
00240
00241 case 'p':
00242 prompt = true;
00243 break;
00244
00245 default:
00246 exit(1);
00247 }
00248 flag = getopt(argc, argv, optstr);
00249 }
00250
00251 argc -= (optind-1);
00252 argv += (optind-1);
00253
00254
00255 if (argc < 2) {
00256 cerr << "parse-file [opts] file1.h [file2.h ... ]\n"
00257 << "\nOptions:\n\n"
00258 << " -I include_path\n"
00259 << " -S system_include_path\n"
00260 << " -D manifest_name\n"
00261 << " -D manifest_name=manifest_definition\n"
00262 << " -o output_file (ignored)\n"
00263 << " -v (increase verbosity)\n"
00264 << " -p (prompt for expression instead of dumping output)\n";
00265
00266 exit(1);
00267 }
00268
00269 for (int i = 1; i < argc; i++) {
00270 if (!parser.parse_file(argv[i])) {
00271 cerr << "Error in parsing.\n";
00272 exit(1);
00273 }
00274 }
00275
00276 cerr << "Finished parsing.\n";
00277
00278 if (prompt) {
00279 while (cin) {
00280 string str;
00281 cout << "Enter an expression or type name:\n";
00282 getline(cin, str);
00283 if (!str.empty()) {
00284
00285 size_t space = str.find(' ');
00286 if (space != string::npos) {
00287 string first_word = str.substr(0, space);
00288 string remainder = str.substr(space + 1);
00289
00290 if (first_word == "methods") {
00291 show_methods(remainder);
00292 } else if (first_word == "members") {
00293 show_data_members(remainder);
00294 } else if (first_word == "typedefs") {
00295 show_typedefs(remainder);
00296 } else {
00297 show_type_or_expression(str);
00298 }
00299 } else {
00300 show_type_or_expression(str);
00301 }
00302 }
00303 }
00304 } else {
00305 parser.write(cout, 0, &parser);
00306 cout << "\n";
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 return (0);
00359 }
00360
00361
00362