Browse Source

allow undefined typedefs like classes

David Rose 21 years ago
parent
commit
02d259fb03

+ 12 - 0
direct/src/dcparser/dcArrayParameter.cxx

@@ -85,6 +85,18 @@ make_copy() const {
   return new DCArrayParameter(*this);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::is_valid
+//       Access: Published, Virtual
+//  Description: Returns false if the type is an invalid type
+//               (e.g. declared from an undefined typedef), true if
+//               it is valid.
+////////////////////////////////////////////////////////////////////
+bool DCArrayParameter::
+is_valid() const {
+  return _element_type->is_valid();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCArrayParameter::get_element_type
 //       Access: Published

+ 1 - 0
direct/src/dcparser/dcArrayParameter.h

@@ -38,6 +38,7 @@ public:
 PUBLISHED:
   virtual DCArrayParameter *as_array_parameter();
   virtual DCParameter *make_copy() const;
+  virtual bool is_valid() const;
 
   DCParameter *get_element_type() const;
   int get_array_size() const;

+ 12 - 6
direct/src/dcparser/dcFile.cxx

@@ -37,7 +37,7 @@
 ////////////////////////////////////////////////////////////////////
 DCFile::
 DCFile() {
-  _all_classes_valid = true;
+  _all_objects_valid = true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -237,7 +237,9 @@ write(ostream &out, bool brief) const {
   if (!_typedefs.empty()) {
     Typedefs::const_iterator ti;
     for (ti = _typedefs.begin(); ti != _typedefs.end(); ++ti) {
-      (*ti)->write(out, brief, 0);
+      if (!(*ti)->is_bogus_typedef()) {
+        (*ti)->write(out, brief, 0);
+      }
     }
     out << "\n";
   }
@@ -293,7 +295,7 @@ get_class_by_name(const string &name) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DCFile::all_classes_valid
+//     Function: DCFile::all_objects_valid
 //       Access: Published
 //  Description: Returns true if all of the classes read from the DC
 //               file were defined and valid, or false if any of them
@@ -301,8 +303,8 @@ get_class_by_name(const string &name) const {
 //               we might have read a partial file.
 ////////////////////////////////////////////////////////////////////
 bool DCFile::
-all_classes_valid() const {
-  return _all_classes_valid;
+all_objects_valid() const {
+  return _all_objects_valid;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -447,7 +449,7 @@ add_class(DCClass *dclass) {
   _classes.push_back(dclass);
 
   if (dclass->is_bogus_class()) {
-    _all_classes_valid = false;
+    _all_objects_valid = false;
   }
 
   return true;
@@ -504,5 +506,9 @@ add_typedef(DCTypedef *dtypedef) {
   dtypedef->set_number(get_num_typedefs());
   _typedefs.push_back(dtypedef);
 
+  if (dtypedef->is_bogus_typedef()) {
+    _all_objects_valid = false;
+  }
+
   return true;
 }

+ 2 - 2
direct/src/dcparser/dcFile.h

@@ -51,7 +51,7 @@ PUBLISHED:
   DCClass *get_class(int n) const;
   DCClass *get_class_by_name(const string &name) const;
 
-  bool all_classes_valid() const;
+  bool all_objects_valid() const;
 
   int get_num_import_modules() const;
   string get_import_module(int n) const;
@@ -94,7 +94,7 @@ private:
   typedef pmap<string, DCTypedef *> TypedefsByName;
   TypedefsByName _typedefs_by_name;
 
-  bool _all_classes_valid;
+  bool _all_objects_valid;
 };
 
 #endif

+ 1 - 0
direct/src/dcparser/dcParameter.h

@@ -52,6 +52,7 @@ PUBLISHED:
   virtual DCArrayParameter *as_array_parameter();
 
   virtual DCParameter *make_copy() const=0;
+  virtual bool is_valid() const=0;
 
   const DCTypedef *get_typedef() const;
 

+ 25 - 10
direct/src/dcparser/dcParser.yxx

@@ -209,7 +209,16 @@ import_symbol_list:
 typedef_decl:
         KW_TYPEDEF parameter
 {
-  dc_file->add_typedef(new DCTypedef($2));
+  DCTypedef *dtypedef = new DCTypedef($2);
+
+  if (!dc_file->add_typedef(dtypedef)) {
+    DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
+    if (old_typedef->is_bogus_typedef()) {
+      yyerror("typedef defined after its first reference: " + dtypedef->get_name());
+    } else {
+      yyerror("Duplicate typedef name: " + dtypedef->get_name());
+    }
+  }
 }
 	;
 
@@ -290,14 +299,20 @@ atomic_element:
 }
 	parameter_value
 {
-  if (!current_packer->end_pack()) {
-    yyerror("Invalid default value for type");
+  bool is_valid = $1->is_valid();
+  atomic_element = DCAtomicField::ElementType($1);
+  if (current_packer->end_pack()) {
+    atomic_element.set_default_value(current_packer->get_string());
 
   } else {
-    atomic_element = DCAtomicField::ElementType($1);
-    atomic_element.set_default_value(current_packer->get_string());
-    current_atomic->add_element(atomic_element);
+    if (is_valid) {
+      yyerror("Invalid default value for type");
+    }
+    // If the current parameter isn't valid, we don't mind a pack
+    // error (there's no way for us to validate the syntax).  So we'll
+    // just ignore the default value in this case.
   }
+  current_atomic->add_element(atomic_element);
 }
 	;
 
@@ -333,11 +348,11 @@ type_name:
 {
   DCTypedef *dtypedef = dc_file->get_typedef_by_name($1);
   if (dtypedef == (DCTypedef *)NULL) {
-    yyerror("Invalid type name");
-
-  } else {
-    $$ = dtypedef->make_new_parameter();
+    dtypedef = new DCTypedef($1);
+    dc_file->add_typedef(dtypedef);
   }
+
+  $$ = dtypedef->make_new_parameter();
 }
 	;
 

+ 12 - 0
direct/src/dcparser/dcSimpleParameter.cxx

@@ -218,6 +218,18 @@ make_copy() const {
   return new DCSimpleParameter(*this);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCSimpleParameter::is_valid
+//       Access: Published, Virtual
+//  Description: Returns false if the type is an invalid type
+//               (e.g. declared from an undefined typedef), true if
+//               it is valid.
+////////////////////////////////////////////////////////////////////
+bool DCSimpleParameter::
+is_valid() const {
+  return _type != ST_invalid;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCSimpleParameter::get_type
 //       Access: Published

+ 1 - 0
direct/src/dcparser/dcSimpleParameter.h

@@ -40,6 +40,7 @@ public:
 PUBLISHED:
   virtual DCSimpleParameter *as_simple_parameter();
   virtual DCParameter *make_copy() const;
+  virtual bool is_valid() const;
 
   DCSubatomicType get_type() const;
   int get_divisor() const;

+ 30 - 1
direct/src/dcparser/dcTypedef.cxx

@@ -23,14 +23,29 @@
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCTypedef::Constructor
-//       Access: Protected
+//       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
 DCTypedef::
 DCTypedef(DCParameter *parameter) :
   _parameter(parameter),
+  _bogus_typedef(false),
+  _number(-1)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::Constructor
+//       Access: Public
+//  Description: Creates a bogus typedef reference.
+////////////////////////////////////////////////////////////////////
+DCTypedef::
+DCTypedef(const string &name) :
+  _parameter(new DCSimpleParameter(ST_invalid)),
+  _bogus_typedef(true),
   _number(-1)
 {
+  _parameter->set_name(name);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -78,6 +93,20 @@ get_description() const {
   return strm.str();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::is_bogus_typedef
+//       Access: Public
+//  Description: Returns true if the typedef has been flagged as a bogus
+//               typedef.  This is set for typedefs that are generated by
+//               the parser as placeholder for missing typedefs, as
+//               when reading a partial file; it should not occur in a
+//               normal valid dc file.
+////////////////////////////////////////////////////////////////////
+bool DCTypedef::
+is_bogus_typedef() const {
+  return _bogus_typedef;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCTypedef::make_new_parameter
 //       Access: Public

+ 4 - 0
direct/src/dcparser/dcTypedef.h

@@ -32,6 +32,7 @@ class DCParameter;
 class EXPCL_DIRECT DCTypedef {
 public:
   DCTypedef(DCParameter *parameter);
+  DCTypedef(const string &name);
   ~DCTypedef();
 
 PUBLISHED:
@@ -39,6 +40,8 @@ PUBLISHED:
   const string &get_name() const;
   string get_description() const;
 
+  bool is_bogus_typedef() const;
+
 public:
   DCParameter *make_new_parameter() const;
 
@@ -47,6 +50,7 @@ public:
 
 private:
   DCParameter *_parameter;
+  bool _bogus_typedef;
   int _number;
 };