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

dtool/src/interrogate/parse_file.cxx

Go to the documentation of this file.
00001 // Filename: parse_file.cxx
00002 // Created by:  drose (20Oct99)
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 #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   cout << "Opened the following files:\n";
00311   CPPParser::ParsedFiles::const_iterator fi;
00312   for (fi = parser._parsed_files.begin();
00313        fi != parser._parsed_files.end();
00314        ++fi) {
00315     cout << "   ";
00316 
00317     switch ((*fi)._source) {
00318     case CPPFile::S_local:
00319       cout << "L";
00320       break;
00321     case CPPFile::S_alternate:
00322       cout << "A";
00323       break;
00324     case CPPFile::S_system:
00325       cout << "S";
00326       break;
00327     default:
00328       cout << " ";
00329     }
00330 
00331     cout << " " << (*fi) << "\n";
00332   }
00333   */
00334 
00335   /*
00336   CPPParser::Comments::const_iterator ci;
00337   for (ci = parser._comments.begin(); ci != parser._comments.end(); ++ci) {
00338     const CPPParser::CommentBlock &c = (*ci);
00339     cout << "Comment in file " << c._file << " at line " << c._line_number
00340          << ":\n" << c._comment << "\n\n";
00341   }
00342   */
00343 
00344   /*
00345   CPPParser::Manifests::const_iterator mi;
00346   for (mi = parser._manifests.begin(); mi != parser._manifests.end(); ++mi) {
00347     const CPPManifest *m = (*mi).second;
00348     cout << "Manifest " << m->_name << " defined in " << m->_file;
00349     CPPType *type = m->determine_type();
00350     if (type == (CPPType *)NULL) {
00351       cout << " (no type)\n";
00352     } else {
00353       cout << " has type " << *type << "\n";
00354     }
00355   }
00356   */
00357 
00358   return (0);
00359 }
00360 
00361 
00362 

Generated on Thu May 1 22:13:04 2003 for DTool by doxygen1.3