| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file dcparse.cxx
- * @author drose
- * @date 2000-10-05
- */
- #include "dcbase.h"
- #include "dcFile.h"
- #include "dcClass.h"
- #include "dcTypedef.h"
- #include "memoryUsage.h"
- #include "indent.h"
- #include "panda_getopt.h"
- using std::cerr;
- using std::cout;
- void
- usage() {
- cerr <<
- "\n"
- "Usage:\n\n"
- "dcparse [options] [file1 file2 ...]\n"
- "dcparse -h\n\n";
- }
- void
- help() {
- usage();
- cerr <<
- "This program reads one or more DC files, which are used to describe the\n"
- "communication channels in the distributed class system. By default,\n"
- "the file(s) are read and concatenated, and a single hash code is printed\n"
- "corresponding to the file's contents.\n\n"
- "Options:\n\n"
- " -v Writes a complete parseable version of the file to standard\n"
- " output instead of printing a hash code.\n\n"
- " -b Writes a brief parseable version of the file instead of a full\n"
- " version. This is semantically the same as the output produced\n"
- " the above -v option--reading it would produce exactly the same\n"
- " results--but it is designed to be slightly obfuscated. The\n"
- " comments and parameter names are not included.\n\n"
- " -c Write a list of class names, showing the inheritance hierarchy.\n"
- " Some class names will be listed twice in the presence of multiple\n"
- " inheritance.\n\n"
- " -f Write a complete list of field names available for each class,\n"
- " including all inherited fields.\n\n";
- }
- void
- write_class_hierarchy(int indent_level, const DCFile &file,
- const DCClass *this_dclass) {
- indent(cout, indent_level)
- << this_dclass->get_name() << "\n";
- int num_classes = file.get_num_classes();
- for (int i = 0; i < num_classes; ++i) {
- const DCClass *dclass = file.get_class(i);
- bool is_my_child = false;
- int num_parents = dclass->get_num_parents();
- for (int j = 0; j < num_parents && !is_my_child; ++j) {
- is_my_child = (dclass->get_parent(j) == this_dclass);
- }
- if (is_my_child) {
- write_class_hierarchy(indent_level + 2, file, dclass);
- }
- }
- }
- void
- write_class_hierarchy(const DCFile &file) {
- int num_classes = file.get_num_classes();
- for (int i = 0; i < num_classes; ++i) {
- const DCClass *dclass = file.get_class(i);
- if (dclass->get_num_parents() == 0) {
- write_class_hierarchy(0, file, dclass);
- cout << "\n";
- }
- }
- }
- void
- write_complete_field_list(const DCFile &file) {
- int num_classes = file.get_num_classes();
- for (int i = 0; i < num_classes; ++i) {
- const DCClass *dclass = file.get_class(i);
- cout << "\n" << dclass->get_name() << "\n";
- int num_inherited_fields = dclass->get_num_inherited_fields();
- for (int j = 0; j < num_inherited_fields; ++j) {
- const DCField *field = dclass->get_inherited_field(j);
- cout << " ";
- if (field->get_class() != dclass) {
- cout << field->get_class()->get_name() << "::";
- }
- cout << field->get_name();
- if (field->as_atomic_field() != nullptr ||
- field->as_molecular_field() != nullptr) {
- // It's a "method".
- cout << "()";
- }
- field->output_keywords(cout);
- cout << "\n";
- }
- }
- }
- int
- main(int argc, char *argv[]) {
- // extern char *optarg;
- extern int optind;
- const char *optstr = "bvcfh";
- bool dump_verbose = false;
- bool dump_brief = false;
- bool dump_classes = false;
- bool dump_fields = false;
- int flag = getopt(argc, argv, optstr);
- while (flag != EOF) {
- switch (flag) {
- case 'b':
- dump_brief = true;
- break;
- case 'v':
- dump_verbose = true;
- break;
- case 'c':
- dump_classes = true;
- break;
- case 'f':
- dump_fields = true;
- break;
- case 'h':
- help();
- exit(1);
- default:
- exit(1);
- }
- flag = getopt(argc, argv, optstr);
- }
- argc -= (optind-1);
- argv += (optind-1);
- if (argc < 2) {
- usage();
- exit(1);
- }
- DCFile file;
- for (int i = 1; i < argc; i++) {
- if (!file.read(argv[i])) {
- return (1);
- }
- }
- if (!file.all_objects_valid() && !dump_brief) {
- cerr << "File is incomplete. The following objects are undefined:\n";
- int num_typedefs = file.get_num_typedefs();
- int i;
- for (i = 0; i < num_typedefs; i++) {
- DCTypedef *dtypedef = file.get_typedef(i);
- if (dtypedef->is_bogus_typedef()) {
- cerr << " " << dtypedef->get_name() << "\n";
- }
- }
- int num_classes = file.get_num_classes();
- for (i = 0; i < num_classes; i++) {
- DCClass *dclass = file.get_class(i);
- if (dclass->is_bogus_class()) {
- cerr << " " << dclass->get_name() << "\n";
- }
- }
- return 1;
- }
- if (dump_verbose || dump_brief) {
- if (!file.write(cout, dump_brief)) {
- return 1;
- }
- } else if (dump_classes) {
- write_class_hierarchy(file);
- } else if (dump_fields) {
- write_complete_field_list(file);
- } else {
- unsigned long hash = file.get_hash();
- cerr << "File hash is " << hash << " (signed " << (long)hash << ")\n";
- }
- #ifdef DO_MEMORY_USAGE
- if (MemoryUsage::is_tracking()) {
- file.clear();
- MemoryUsage::show_current_types();
- for (int i = 1; i < argc; i++) {
- file.read(argv[i]);
- }
- file.clear();
- MemoryUsage::show_current_types();
- }
- #endif
- return 0;
- }
|