From 02d259fb03bee39b5409b070e4e50d382da02820 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 18 Jun 2004 21:08:02 +0000 Subject: [PATCH] allow undefined typedefs like classes --- direct/src/dcparser/dcArrayParameter.cxx | 12 ++++++++ direct/src/dcparser/dcArrayParameter.h | 1 + direct/src/dcparser/dcFile.cxx | 18 ++++++++---- direct/src/dcparser/dcFile.h | 4 +-- direct/src/dcparser/dcParameter.h | 1 + direct/src/dcparser/dcParser.yxx | 35 ++++++++++++++++------- direct/src/dcparser/dcSimpleParameter.cxx | 12 ++++++++ direct/src/dcparser/dcSimpleParameter.h | 1 + direct/src/dcparser/dcTypedef.cxx | 31 +++++++++++++++++++- direct/src/dcparser/dcTypedef.h | 4 +++ 10 files changed, 100 insertions(+), 19 deletions(-) diff --git a/direct/src/dcparser/dcArrayParameter.cxx b/direct/src/dcparser/dcArrayParameter.cxx index 3b992e05e3..8ecaee59fc 100644 --- a/direct/src/dcparser/dcArrayParameter.cxx +++ b/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 diff --git a/direct/src/dcparser/dcArrayParameter.h b/direct/src/dcparser/dcArrayParameter.h index 66dcf749e9..9c4a21ffa0 100644 --- a/direct/src/dcparser/dcArrayParameter.h +++ b/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; diff --git a/direct/src/dcparser/dcFile.cxx b/direct/src/dcparser/dcFile.cxx index 8006c06a5a..2cc4f0a2fe 100644 --- a/direct/src/dcparser/dcFile.cxx +++ b/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; } diff --git a/direct/src/dcparser/dcFile.h b/direct/src/dcparser/dcFile.h index 93900704dd..95b6860854 100644 --- a/direct/src/dcparser/dcFile.h +++ b/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 TypedefsByName; TypedefsByName _typedefs_by_name; - bool _all_classes_valid; + bool _all_objects_valid; }; #endif diff --git a/direct/src/dcparser/dcParameter.h b/direct/src/dcparser/dcParameter.h index 6be367677b..247def1995 100644 --- a/direct/src/dcparser/dcParameter.h +++ b/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; diff --git a/direct/src/dcparser/dcParser.yxx b/direct/src/dcparser/dcParser.yxx index b1a014a6a0..da180098c8 100644 --- a/direct/src/dcparser/dcParser.yxx +++ b/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(); } ; diff --git a/direct/src/dcparser/dcSimpleParameter.cxx b/direct/src/dcparser/dcSimpleParameter.cxx index f011e315ce..99e6a4399b 100644 --- a/direct/src/dcparser/dcSimpleParameter.cxx +++ b/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 diff --git a/direct/src/dcparser/dcSimpleParameter.h b/direct/src/dcparser/dcSimpleParameter.h index e8866aa140..aa9358b307 100644 --- a/direct/src/dcparser/dcSimpleParameter.h +++ b/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; diff --git a/direct/src/dcparser/dcTypedef.cxx b/direct/src/dcparser/dcTypedef.cxx index b9a61d30ff..035cea28fc 100644 --- a/direct/src/dcparser/dcTypedef.cxx +++ b/direct/src/dcparser/dcTypedef.cxx @@ -23,16 +23,31 @@ //////////////////////////////////////////////////////////////////// // 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); +} + //////////////////////////////////////////////////////////////////// // Function: DCTypedef::Destructor // Access: Public, Virtual @@ -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 diff --git a/direct/src/dcparser/dcTypedef.h b/direct/src/dcparser/dcTypedef.h index 1101708893..e1c63e3e49 100644 --- a/direct/src/dcparser/dcTypedef.h +++ b/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; };