Browse Source

typedefs and arrays

David Rose 21 years ago
parent
commit
ac1f745525

+ 4 - 2
direct/src/dcparser/Sources.pp

@@ -21,7 +21,8 @@
      dcPackData.h dcPackData.I \
      dcPacker.h dcPacker.I \
      dcPackerInterface.h \
-     dcParameter.h dcSimpleParameter.h \
+     dcParameter.h dcArrayParameter.h dcSimpleParameter.h \
+     dcTypedef.h \
      dcbase.h dcindent.h hashGenerator.h  \
      primeNumberGenerator.h  
 
@@ -31,7 +32,8 @@
      dcPackData.cxx \
      dcPacker.cxx \
      dcPackerInterface.cxx \
-     dcParameter.cxx dcSimpleParameter.cxx \
+     dcParameter.cxx dcArrayParameter.cxx dcSimpleParameter.cxx \
+     dcTypedef.cxx \
      dcindent.cxx  \
      hashGenerator.cxx primeNumberGenerator.cxx 
 

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

@@ -0,0 +1,178 @@
+// Filename: dcArrayParameter.cxx
+// Created by:  drose (17Jun04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dcArrayParameter.h"
+#include "hashGenerator.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCArrayParameter::
+DCArrayParameter(DCParameter *element_type, int array_size) :
+  _element_type(element_type),
+  _array_size(array_size)
+{
+  set_name(element_type->get_name());
+
+  if (_array_size >= 0 && _element_type->has_fixed_byte_size()) {
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = _array_size * _element_type->get_fixed_byte_size();
+  }
+
+  _num_length_bytes = 2;
+  _has_nested_fields = true;
+  _num_nested_fields = _array_size;
+  _pack_type = PT_array;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCArrayParameter::
+DCArrayParameter(const DCArrayParameter &copy) :
+  DCParameter(copy),
+  _element_type(copy._element_type->make_copy()),
+  _array_size(copy._array_size)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::Destructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCArrayParameter::
+~DCArrayParameter() {
+  delete _element_type;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::as_array_parameter
+//       Access: Published, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCArrayParameter *DCArrayParameter::
+as_array_parameter() {
+  return this;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::make_copy
+//       Access: Published, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCParameter *DCArrayParameter::
+make_copy() const {
+  return new DCArrayParameter(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::get_element_type
+//       Access: Published
+//  Description: Returns the type of the individual elements of this
+//               array.
+////////////////////////////////////////////////////////////////////
+DCParameter *DCArrayParameter::
+get_element_type() const {
+  return _element_type;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::get_array_size
+//       Access: Published
+//  Description: Returns the fixed number of elements in this array,
+//               or -1 if the array may contain any number of
+//               elements.
+////////////////////////////////////////////////////////////////////
+int DCArrayParameter::
+get_array_size() const {
+  return _array_size;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::calc_num_nested_fields
+//       Access: Public, Virtual
+//  Description: This flavor of get_num_nested_fields is used during
+//               unpacking.  It returns the number of nested fields to
+//               expect, given a certain length in bytes (as read from
+//               the get_num_length_bytes() stored in the stream on the
+//               pack).  This will only be called if
+//               get_num_length_bytes() returns nonzero.
+////////////////////////////////////////////////////////////////////
+int DCArrayParameter::
+calc_num_nested_fields(size_t length_bytes) const {
+  if (_element_type->has_fixed_byte_size()) {
+    return length_bytes / _element_type->get_fixed_byte_size();
+  }
+  return -1;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::get_nested_field
+//       Access: Public, Virtual
+//  Description: Returns the DCPackerInterface object that represents
+//               the nth nested field.  This may return NULL if there
+//               is no such field (but it shouldn't do this if n is in
+//               the range 0 <= n < get_num_nested_fields()).
+////////////////////////////////////////////////////////////////////
+DCPackerInterface *DCArrayParameter::
+get_nested_field(int) const {
+  return _element_type;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::output_instance
+//       Access: Public, Virtual
+//  Description: Formats the parameter in the C++-like dc syntax as a
+//               typename and identifier.
+////////////////////////////////////////////////////////////////////
+void DCArrayParameter::
+output_instance(ostream &out, const string &prename, const string &name,
+                const string &postname) const {
+  if (get_typedef() != (DCTypedef *)NULL) {
+    output_typedef_name(out, prename, name, postname);
+
+  } else {
+    ostringstream strm;
+    
+    if (_array_size >= 0) {
+      strm << "[" << _array_size << "]";
+    } else {
+      strm << "[]";
+    }
+    
+    _element_type->output_instance(out, prename, name, strm.str() + postname);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCArrayParameter::generate_hash
+//       Access: Public, Virtual
+//  Description: Accumulates the properties of this type into the
+//               hash.
+////////////////////////////////////////////////////////////////////
+void DCArrayParameter::
+generate_hash(HashGenerator &hashgen) const {
+  DCParameter::generate_hash(hashgen);
+  _element_type->generate_hash(hashgen);
+  hashgen.add_int(_array_size);
+}

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

@@ -0,0 +1,58 @@
+// Filename: dcArrayParameter.h
+// Created by:  drose (17Jun04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DCARRAYPARAMETER_H
+#define DCARRAYPARAMETER_H
+
+#include "dcbase.h"
+#include "dcParameter.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DCArrayParameter
+// Description : This represents an array of some other kind of
+//               object, meaning this parameter type accepts an
+//               arbitrary (or possibly fixed) number of nested
+//               fields, all of which are of the same type.
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT DCArrayParameter : public DCParameter {
+public:
+  DCArrayParameter(DCParameter *element_type, int array_size = -1);
+  DCArrayParameter(const DCArrayParameter &copy);
+  ~DCArrayParameter();
+
+PUBLISHED:
+  virtual DCArrayParameter *as_array_parameter();
+  virtual DCParameter *make_copy() const;
+
+  DCParameter *get_element_type() const;
+  int get_array_size() const;
+
+public:
+  virtual int calc_num_nested_fields(size_t length_bytes) const;
+  virtual DCPackerInterface *get_nested_field(int n) const;
+
+  virtual void output_instance(ostream &out, const string &prename, 
+                               const string &name, const string &postname) const;
+  virtual void generate_hash(HashGenerator &hash) const;
+
+private:
+  DCParameter *_element_type;
+  int _array_size;
+};
+
+#endif

+ 51 - 30
direct/src/dcparser/dcAtomicField.cxx

@@ -104,7 +104,7 @@ output(ostream &out, bool brief) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::as_atomic_field
-//       Access: Public, Virtual
+//       Access: Published, Virtual
 //  Description: Returns the same field pointer converted to an atomic
 //               field pointer, if this is in fact an atomic field;
 //               otherwise, returns NULL.
@@ -116,7 +116,7 @@ as_atomic_field() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_num_elements
-//       Access: Public
+//       Access: Published
 //  Description: Returns the number of elements (parameters) of the
 //               atomic field.
 ////////////////////////////////////////////////////////////////////
@@ -127,7 +127,7 @@ get_num_elements() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_element
-//       Access: Public
+//       Access: Published
 //  Description: Returns the parameter object describing the
 //               nth element.
 ////////////////////////////////////////////////////////////////////
@@ -139,7 +139,7 @@ get_element(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_element_default
-//       Access: Public
+//       Access: Published
 //  Description: Returns the pre-formatted default value associated
 //               with the nth element of the field.  This is only
 //               valid if has_element_default() returns true, in which
@@ -160,7 +160,7 @@ get_element_default(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::has_element_default
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the nth element of the field has a
 //               default value specified, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -172,7 +172,7 @@ has_element_default(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_element_name
-//       Access: Public
+//       Access: Published
 //  Description: Returns the name of the nth element of the field.
 //               This name is strictly for documentary purposes; it
 //               does not generally affect operation.  If a name is
@@ -189,7 +189,7 @@ get_element_name(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_element_type
-//       Access: Public
+//       Access: Published
 //  Description: Returns the numeric type of the nth element of the
 //               field.  This method is deprecated; use
 //               get_element() instead.
@@ -204,7 +204,7 @@ get_element_type(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_element_divisor
-//       Access: Public
+//       Access: Published
 //  Description: Returns the divisor associated with the nth element
 //               of the field.  This implements an implicit
 //               fixed-point system; floating-point values are to be
@@ -224,7 +224,7 @@ get_element_divisor(int n) const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_required
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "required" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -235,7 +235,7 @@ is_required() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_broadcast
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "broadcast" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -246,7 +246,7 @@ is_broadcast() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_p2p
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "p2p" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -257,7 +257,7 @@ is_p2p() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_ram
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "ram" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -268,7 +268,7 @@ is_ram() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_db
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "db" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -279,7 +279,7 @@ is_db() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_clsend
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "clsend" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -290,7 +290,7 @@ is_clsend() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_clrecv
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "clrecv" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -301,7 +301,7 @@ is_clrecv() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_ownsend
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "ownsend" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -312,7 +312,7 @@ is_ownsend() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::is_airecv
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the "airecv" flag is set for this
 //               field, false otherwise.
 ////////////////////////////////////////////////////////////////////
@@ -321,6 +321,18 @@ is_airecv() const {
   return (_flags & F_airecv) != 0;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCAtomicField::compare_flags
+//       Access: Published
+//  Description: Returns true if this field has the same flags
+//               settings as the other field, false if some flags
+//               differ.
+////////////////////////////////////////////////////////////////////
+bool DCAtomicField::
+compare_flags(const DCAtomicField &other) const {
+  return _flags == other._flags;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::Constructor
 //       Access: Public
@@ -408,19 +420,6 @@ generate_hash(HashGenerator &hashgen) const {
   hashgen.add_int(_flags);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCAtomicField::get_num_nested_fields
-//       Access: Public, Virtual
-//  Description: Returns the number of nested fields required by this
-//               field type.  These may be array elements or structure
-//               elements.  The return value may be -1 to indicate the
-//               number of nested fields is variable.
-////////////////////////////////////////////////////////////////////
-int DCAtomicField::
-get_num_nested_fields() const {
-  return _elements.size();
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DCAtomicField::get_nested_field
 //       Access: Public, Virtual
@@ -434,3 +433,25 @@ get_nested_field(int n) const {
   nassertr(n >= 0 && n < (int)_elements.size(), NULL);
   return _elements[n]._param;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCAtomicField::add_element
+//       Access: Public
+//  Description: Adds a new element (parameter) to the field.
+//               Normally this is called only during parsing.
+////////////////////////////////////////////////////////////////////
+void DCAtomicField::
+add_element(const DCAtomicField::ElementType &element) {
+  _elements.push_back(element);
+  _num_nested_fields = (int)_elements.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCAtomicField::add_flag
+//       Access: Public
+//  Description: Adds a new flag to the field.
+////////////////////////////////////////////////////////////////////
+void DCAtomicField::
+add_flag(enum Flags flag) {
+  _flags |= flag;
+}

+ 9 - 6
direct/src/dcparser/dcAtomicField.h

@@ -59,17 +59,16 @@ PUBLISHED:
   bool is_ownsend() const;
   bool is_airecv() const;
 
+  bool compare_flags(const DCAtomicField &other) const;
+  
 public:
   DCAtomicField(const string &name);
   virtual void write(ostream &out, bool brief, int indent_level) const;
   virtual void generate_hash(HashGenerator &hash) const;
 
-  virtual int get_num_nested_fields() const;
   virtual DCPackerInterface *get_nested_field(int n) const;
 
 public:
-  // These members define the primary interface to the atomic field
-  // definition as read from the file.
   class ElementType {
   public:
     ElementType(DCParameter *param);
@@ -86,9 +85,6 @@ public:
     bool _has_default_value;
   };
 
-  typedef pvector<ElementType> Elements;
-  Elements _elements;
-
   enum Flags {
     F_required        = 0x0001,
     F_broadcast       = 0x0002,
@@ -101,6 +97,13 @@ public:
     F_airecv          = 0x0100,
   };
 
+  void add_element(const ElementType &element);
+  void add_flag(enum Flags flag);
+
+private:
+  typedef pvector<ElementType> Elements;
+  Elements _elements;
+
   int _flags;  // A bitmask union of any of the above values.
 };
 

+ 13 - 0
direct/src/dcparser/dcClass.cxx

@@ -640,3 +640,16 @@ void DCClass::
 add_parent(DCClass *parent) {
   _parents.push_back(parent);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCClass::set_number
+//       Access: Public
+//  Description: Assigns the unique number to this class.  This is
+//               normally called only by the DCFile interface as the
+//               class is added.
+////////////////////////////////////////////////////////////////////
+void DCClass::
+set_number(int number) {
+  _number = number;
+}
+

+ 4 - 11
direct/src/dcparser/dcClass.h

@@ -80,11 +80,9 @@ public:
 
   bool add_field(DCField *field);
   void add_parent(DCClass *parent);
+  void set_number(int number);
 
 private:
-
-  // These members define the primary interface to the distributed
-  // class as read from the file.
   bool _bogus_class;
   int _number;
 
@@ -94,17 +92,12 @@ private:
   typedef pvector<DCField *> Fields;
   Fields _fields;
 
-#ifdef HAVE_PYTHON
-  PyObject *_class_def;
-#endif
-
-public:
-  // These members are built up during parsing for the convenience of
-  // the parser.
   typedef pmap<string, DCField *> FieldsByName;
   FieldsByName _fields_by_name;
 
-  friend class DCFile;
+#ifdef HAVE_PYTHON
+  PyObject *_class_def;
+#endif
 };
 
 #endif

+ 3 - 24
direct/src/dcparser/dcField.cxx

@@ -254,6 +254,9 @@ ai_format_update(int do_id, int to_id, int from_id, PyObject *args) const {
 DCField::
 DCField(const string &name) : DCPackerInterface(name) {
   _number = 0;
+  _has_nested_fields = true;
+  _num_nested_fields = 0;
+  _pack_type = PT_field;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -279,27 +282,3 @@ generate_hash(HashGenerator &hashgen) const {
   // redundant.  However, the field name is significant.
   hashgen.add_string(_name);
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::has_nested_fields
-//       Access: Public, Virtual
-//  Description: Returns true if this field type has any nested fields
-//               (and thus expects a push() .. pop() interface to the
-//               DCPacker), or false otherwise.  If this returns true,
-//               get_num_nested_fields() may be called to determine
-//               how many nested fields are expected.
-////////////////////////////////////////////////////////////////////
-bool DCField::
-has_nested_fields() const {
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::get_pack_type
-//       Access: Public, Virtual
-//  Description: Returns the type of value expected by this field.
-////////////////////////////////////////////////////////////////////
-DCPackType DCField::
-get_pack_type() const {
-  return PT_field;
-}

+ 0 - 3
direct/src/dcparser/dcField.h

@@ -68,9 +68,6 @@ public:
   virtual void write(ostream &out, bool brief, int indent_level) const=0;
   virtual void generate_hash(HashGenerator &hash) const;
 
-  virtual bool has_nested_fields() const;
-  virtual DCPackType get_pack_type() const;
-
 protected:
   int _number;
 

+ 93 - 19
direct/src/dcparser/dcFile.cxx

@@ -19,6 +19,7 @@
 #include "dcFile.h"
 #include "dcParserDefs.h"
 #include "dcLexerDefs.h"
+#include "dcTypedef.h"
 #include "hashGenerator.h"
 
 #ifdef WITHIN_PANDA
@@ -212,24 +213,34 @@ write(Filename filename, bool brief) const {
 ////////////////////////////////////////////////////////////////////
 bool DCFile::
 write(ostream &out, bool brief) const {
-  Imports::const_iterator ii;
-  for (ii = _imports.begin(); ii != _imports.end(); ++ii) {
-    const Import &import = (*ii);
-    if (import._symbols.empty()) {
-      out << "import " << import._module << "\n";
-    } else {
-      out << "from " << import._module << " import ";
-      ImportSymbols::const_iterator si = import._symbols.begin();
-      out << *si;
-      ++si;
-      while (si != import._symbols.end()) {
-        out << ", " << *si;
+  if (!_imports.empty()) {
+    Imports::const_iterator ii;
+    for (ii = _imports.begin(); ii != _imports.end(); ++ii) {
+      const Import &import = (*ii);
+      if (import._symbols.empty()) {
+        out << "import " << import._module << "\n";
+      } else {
+        out << "from " << import._module << " import ";
+        ImportSymbols::const_iterator si = import._symbols.begin();
+        out << *si;
         ++si;
+        while (si != import._symbols.end()) {
+          out << ", " << *si;
+        ++si;
+        }
+        out << "\n";
       }
-      out << "\n";
     }
+    out << "\n";
+  }
+
+  if (!_typedefs.empty()) {
+    Typedefs::const_iterator ti;
+    for (ti = _typedefs.begin(); ti != _typedefs.end(); ++ti) {
+      (*ti)->write(out, brief, 0);
+    }
+    out << "\n";
   }
-  out << "\n";
 
   Classes::const_iterator ci;
   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
@@ -249,7 +260,7 @@ write(ostream &out, bool brief) const {
 //               file(s).
 ////////////////////////////////////////////////////////////////////
 int DCFile::
-get_num_classes() {
+get_num_classes() const {
   return _classes.size();
 }
 
@@ -259,7 +270,7 @@ get_num_classes() {
 //  Description: Returns the nth class read from the .dc file(s).
 ////////////////////////////////////////////////////////////////////
 DCClass *DCFile::
-get_class(int n) {
+get_class(int n) const {
   nassertr(n >= 0 && n < (int)_classes.size(), NULL);
   return _classes[n];
 }
@@ -271,7 +282,7 @@ get_class(int n) {
 //               NULL if there is no such class.
 ////////////////////////////////////////////////////////////////////
 DCClass *DCFile::
-get_class_by_name(const string &name) {
+get_class_by_name(const string &name) const {
   ClassesByName::const_iterator ni;
   ni = _classes_by_name.find(name);
   if (ni != _classes_by_name.end()) {
@@ -344,6 +355,45 @@ get_import_symbol(int n, int i) const {
   return _imports[n]._symbols[i];
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_num_typedefs
+//       Access: Published
+//  Description: Returns the number of typedefs read from the .dc
+//               file(s).
+////////////////////////////////////////////////////////////////////
+int DCFile::
+get_num_typedefs() const {
+  return _typedefs.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_typedef
+//       Access: Published
+//  Description: Returns the nth typedef read from the .dc file(s).
+////////////////////////////////////////////////////////////////////
+DCTypedef *DCFile::
+get_typedef(int n) const {
+  nassertr(n >= 0 && n < (int)_typedefs.size(), NULL);
+  return _typedefs[n];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_typedef_by_name
+//       Access: Published
+//  Description: Returns the typedef that has the indicated name, or
+//               NULL if there is no such typedef name.
+////////////////////////////////////////////////////////////////////
+DCTypedef *DCFile::
+get_typedef_by_name(const string &name) const {
+  TypedefsByName::const_iterator ni;
+  ni = _typedefs_by_name.find(name);
+  if (ni != _typedefs_by_name.end()) {
+    return (*ni).second;
+  }
+
+  return NULL;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCFile::get_hash
 //       Access: Published
@@ -387,13 +437,13 @@ generate_hash(HashGenerator &hashgen) const {
 bool DCFile::
 add_class(DCClass *dclass) {
   bool inserted = _classes_by_name.insert
-    (ClassesByName::value_type(dclass->_name, dclass)).second;
+    (ClassesByName::value_type(dclass->get_name(), dclass)).second;
 
   if (!inserted) {
     return false;
   }
 
-  dclass->_number = get_num_classes();
+  dclass->set_number(get_num_classes());
   _classes.push_back(dclass);
 
   if (dclass->is_bogus_class()) {
@@ -432,3 +482,27 @@ add_import_symbol(const string &import_symbol) {
   nassertv(!_imports.empty());
   _imports.back()._symbols.push_back(import_symbol);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::add_typedef
+//       Access: Public
+//  Description: Adds the newly-allocated distributed typedef definition
+//               to the file.  The DCFile becomes the owner of the
+//               pointer and will delete it when it destructs.
+//               Returns true if the typedef is successfully added, or
+//               false if there was a name conflict.
+////////////////////////////////////////////////////////////////////
+bool DCFile::
+add_typedef(DCTypedef *dtypedef) {
+  bool inserted = _typedefs_by_name.insert
+    (TypedefsByName::value_type(dtypedef->get_name(), dtypedef)).second;
+
+  if (!inserted) {
+    return false;
+  }
+
+  dtypedef->set_number(get_num_typedefs());
+  _typedefs.push_back(dtypedef);
+
+  return true;
+}

+ 19 - 11
direct/src/dcparser/dcFile.h

@@ -23,6 +23,7 @@
 #include "dcClass.h"
 
 class HashGenerator;
+class DCTypedef;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : DCFile
@@ -46,9 +47,9 @@ PUBLISHED:
   bool write(Filename filename, bool brief) const;
   bool write(ostream &out, bool brief) const;
 
-  int get_num_classes();
-  DCClass *get_class(int n);
-  DCClass *get_class_by_name(const string &name);
+  int get_num_classes() const;
+  DCClass *get_class(int n) const;
+  DCClass *get_class_by_name(const string &name) const;
 
   bool all_classes_valid() const;
 
@@ -57,6 +58,10 @@ PUBLISHED:
   int get_num_import_symbols(int n) const;
   string get_import_symbol(int n, int i) const;
 
+  int get_num_typedefs() const;
+  DCTypedef *get_typedef(int n) const;
+  DCTypedef *get_typedef_by_name(const string &name) const;
+
   unsigned long get_hash() const;
 
 public:
@@ -64,13 +69,15 @@ public:
   bool add_class(DCClass *dclass);
   void add_import_module(const string &import_module);
   void add_import_symbol(const string &import_symbol);
+  bool add_typedef(DCTypedef *dtypedef);
 
-public:
-  // This vector is the primary interface to the distributed classes
-  // read from the file.
+private:
   typedef pvector<DCClass *> Classes;
   Classes _classes;
 
+  typedef pmap<string, DCClass *> ClassesByName;
+  ClassesByName _classes_by_name;
+
   typedef pvector<string> ImportSymbols;
   class Import {
   public:
@@ -81,12 +88,13 @@ public:
   typedef pvector<Import> Imports;
   Imports _imports;
 
-  bool _all_classes_valid;
+  typedef pvector<DCTypedef *> Typedefs;
+  Typedefs _typedefs;
 
-public:
-  // This map is built up during parsing for the convenience of the parser.
-  typedef pmap<string, DCClass *> ClassesByName;
-  ClassesByName _classes_by_name;
+  typedef pmap<string, DCTypedef *> TypedefsByName;
+  TypedefsByName _typedefs_by_name;
+
+  bool _all_classes_valid;
 };
 
 #endif

+ 231 - 202
direct/src/dcparser/dcLexer.cxx.prebuilt

@@ -300,29 +300,29 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 	*yy_cp = '\0'; \
 	yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 44
-#define YY_END_OF_BUFFER 45
-static yyconst short int yy_accept[173] =
+#define YY_NUM_RULES 45
+#define YY_END_OF_BUFFER 46
+static yyconst short int yy_accept[180] =
     {   0,
-        0,    0,   45,   43,    2,    1,   40,   43,   43,   43,
-       37,   37,   41,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   42,    1,    0,   37,   39,
-        4,    3,   39,   38,   42,   42,   42,   42,   42,   32,
-       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,    0,    3,   38,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   42,   42,   30,   31,   42,
-       42,   42,    0,   39,   42,   18,   42,   42,   42,   42,
-       42,    6,   42,   42,   42,   42,    8,   27,   42,   42,
-       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
-
-        9,   10,   11,   42,   42,   42,   42,   42,   42,   42,
-       12,   36,   19,   42,   34,   33,    5,   42,    7,   42,
-       42,   42,   42,   42,   17,   13,   14,   15,   42,   42,
-       16,   42,   42,   42,   35,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   28,   42,   42,   42,   42,   29,
-       42,   42,   20,   42,   42,   42,   42,   21,   22,   42,
-       42,   42,   23,   24,   25,   42,   42,   42,   42,   42,
-       26,    0
+        0,    0,   46,   44,    2,    1,   41,   44,   44,   44,
+       38,   38,   42,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,   43,    1,    0,   38,
+       40,    4,    3,   40,   39,   43,   43,   43,   43,   43,
+       33,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,    0,    3,   39,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,   43,   43,   43,   31,
+       32,   43,   43,   43,   43,    0,   40,   43,   19,   43,
+       43,   43,   43,   43,    6,   43,   43,   43,   43,    9,
+       28,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+
+       43,   43,   43,   43,   10,   11,   12,   43,   43,   43,
+       43,   43,   43,   43,   43,   13,   37,   20,   43,   35,
+       34,    5,   43,    7,   43,   43,   43,   43,   43,   18,
+       43,   14,   15,   16,   43,   43,   17,   43,   43,   43,
+       36,   43,    8,   43,   43,   43,   43,   43,   43,   43,
+       43,   29,   43,   43,   43,   43,   30,   43,   43,   21,
+       43,   43,   43,   43,   22,   23,   43,   43,   43,   24,
+       25,   26,   43,   43,   43,   43,   43,   27,    0
     } ;
 
 static yyconst int yy_ec[256] =
@@ -366,114 +366,118 @@ static yyconst int yy_meta[43] =
         7,    7
     } ;
 
-static yyconst short int yy_base[180] =
+static yyconst short int yy_base[187] =
     {   0,
-        0,    0,  215,  216,  216,    0,  216,  207,    0,   38,
-       37,  206,  216,    0,  184,   16,  182,   25,   20,   22,
-      178,  169,  197,   29,  170,  178,    0,    0,  198,   37,
-      216,    0,    0,    0,    0,  169,  171,  170,   22,    0,
-      172,  168,  167,  165,  160,  167,  164,  161,  163,  158,
-      156,  159,  183,    0,    0,  163,  165,  165,  160,  159,
-      162,  161,  151,  148,   49,   70,  143,    0,    0,  140,
-      149,  139,  169,  168,  150,  160,  147,  147,  138,  132,
-      130,    0,  131,  150,  153,  150,  141,    0,  136,  132,
-      128,   56,  119,  146,  133,  116,  130,  117,  137,  114,
-
-      129,  128,    0,  113,  116,  111,  118,  129,  132,  129,
-      120,    0,    0,  119,    0,    0,    0,  126,    0,  103,
-      102,  101,  111,  109,    0,  112,   39,    0,   97,   95,
-        0,   95,   94,  107,    0,  103,   91,   90,   96,   88,
-       85,  100,   99,   77,    0,   83,   82,   85,   94,    0,
-       72,   71,    0,   91,   90,   72,   58,    0,    0,   46,
-       34,   59,    0,    0,    0,   53,   38,   35,   48,   25,
-        0,  216,   86,   90,   58,   91,   98,  101,  105
+        0,    0,  221,  222,  222,    0,  222,  213,    0,   38,
+       37,  212,  222,    0,  190,   16,  188,   25,   20,   22,
+      184,  175,  203,   29,  176,  170,  183,    0,    0,  203,
+       37,  222,    0,    0,    0,    0,  174,  176,  175,   22,
+        0,  177,  173,  172,  170,  165,  172,  169,  166,  168,
+      163,  161,  162,  163,  187,    0,    0,  167,  169,  169,
+      164,  163,  166,  165,  155,  152,   49,   70,  147,    0,
+        0,  144,  153,  155,  142,  172,  171,  153,  163,  150,
+      150,  141,  135,  133,    0,  134,  153,  156,  153,  144,
+        0,  139,  135,  131,  137,   56,  121,  148,  135,  118,
+
+      132,  119,  139,  116,  131,  130,    0,  115,  118,  113,
+      120,  121,  130,  133,  130,  121,    0,    0,  120,    0,
+        0,    0,  127,    0,  104,  103,  102,  112,  110,    0,
+      108,  112,   39,    0,   97,   95,    0,   95,   94,  107,
+        0,  103,    0,   91,   90,   96,   88,   85,  100,   99,
+       77,    0,   83,   82,   85,   94,    0,   72,   71,    0,
+       91,   90,   72,   58,    0,    0,   46,   34,   59,    0,
+        0,    0,   53,   38,   35,   48,   25,    0,  222,   86,
+       90,   58,   91,   98,  101,  105
     } ;
 
-static yyconst short int yy_def[180] =
+static yyconst short int yy_def[187] =
     {   0,
-      172,    1,  172,  172,  172,  173,  172,  174,  175,  172,
-      174,  174,  172,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  173,  175,  174,  175,
-      172,  177,   30,  178,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  179,  177,  178,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  179,  179,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,   66,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
-      176,    0,  172,  172,  172,  172,  172,  172,  172
+      179,    1,  179,  179,  179,  180,  179,  181,  182,  179,
+      181,  181,  179,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  180,  182,  181,
+      182,  179,  184,   31,  185,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  186,  184,  185,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  186,  186,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+       68,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
+      183,  183,  183,  183,  183,  183,  183,  183,    0,  179,
+      179,  179,  179,  179,  179,  179
     } ;
 
-static yyconst short int yy_nxt[259] =
+static yyconst short int yy_nxt[265] =
     {   0,
         4,    5,    6,    7,    4,    8,    9,   10,   11,   12,
        12,   12,   12,   12,   12,   12,   13,   14,   14,   14,
        15,   16,   17,   18,   14,   19,   14,   20,   14,   21,
-       14,   22,   23,   14,   24,   25,   14,   26,   14,   14,
-       14,   14,   31,   33,   37,   32,   40,   41,   42,   49,
-       38,   44,   45,   50,   43,   53,   59,   60,   84,  138,
-       85,   53,   30,   86,   87,  108,  171,  109,  170,  169,
-      110,  111,  168,  167,  166,  165,  139,   34,   88,   88,
-       88,   88,   88,   88,   88,   88,   27,  164,   27,   27,
-       27,   27,   27,   29,   29,   35,   35,   35,   54,  163,
-
-       54,   54,   54,   54,   54,   55,   55,   74,  162,   74,
-      161,  160,  159,  158,  157,  156,  155,  154,  153,  152,
-      151,  150,  149,  148,  147,  146,  145,  144,  143,  142,
-      141,  140,  137,  136,  135,  134,  133,  132,  131,  130,
-      129,  128,  127,  126,  125,  124,  123,  122,  121,  120,
-      119,  118,  117,  116,  115,  114,  113,  112,  107,  106,
-      105,  104,  103,  102,  101,  100,   99,   98,   97,   96,
-       95,   94,   93,  172,  172,   92,   91,   90,   89,   83,
-       82,   81,   80,   79,   78,   77,   76,   75,   73,   72,
-       71,   70,   69,   68,   67,   66,   65,   64,   63,   62,
-
-       61,   58,   57,   56,   33,   52,   51,   48,   47,   46,
-       39,   36,   33,   28,  172,    3,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172
+       14,   22,   23,   14,   24,   25,   26,   27,   14,   14,
+       14,   14,   32,   34,   38,   33,   41,   42,   43,   50,
+       39,   45,   46,   51,   44,   55,   61,   62,   87,  145,
+       88,   55,   31,   89,   90,  113,  178,  114,  177,  176,
+      115,  116,  175,  174,  173,  172,  146,   35,   91,   91,
+       91,   91,   91,   91,   91,   91,   28,  171,   28,   28,
+       28,   28,   28,   30,   30,   36,   36,   36,   56,  170,
+
+       56,   56,   56,   56,   56,   57,   57,   77,  169,   77,
+      168,  167,  166,  165,  164,  163,  162,  161,  160,  159,
+      158,  157,  156,  155,  154,  153,  152,  151,  150,  149,
+      148,  147,  144,  143,  142,  141,  140,  139,  138,  137,
+      136,  135,  134,  133,  132,  131,  130,  129,  128,  127,
+      126,  125,  124,  123,  122,  121,  120,  119,  118,  117,
+      112,  111,  110,  109,  108,  107,  106,  105,  104,  103,
+      102,  101,  100,   99,   98,   97,  179,  179,   96,   95,
+       94,   93,   92,   86,   85,   84,   83,   82,   81,   80,
+       79,   78,   76,   75,   74,   73,   72,   71,   70,   69,
+
+       68,   67,   66,   65,   64,   63,   60,   59,   58,   34,
+       54,   53,   52,   49,   48,   47,   40,   37,   34,   29,
+      179,    3,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179
     } ;
 
-static yyconst short int yy_chk[259] =
+static yyconst short int yy_chk[265] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,   10,   11,   16,   10,   18,   18,   19,   24,
-       16,   20,   20,   24,   19,   30,   39,   39,   65,  127,
-       65,   30,  175,   65,   65,   92,  170,   92,  169,  168,
-       92,   92,  167,  166,  162,  161,  127,   11,   66,   66,
-       66,   66,   66,   66,   66,   66,  173,  160,  173,  173,
-      173,  173,  173,  174,  174,  176,  176,  176,  177,  157,
-
-      177,  177,  177,  177,  177,  178,  178,  179,  156,  179,
-      155,  154,  152,  151,  149,  148,  147,  146,  144,  143,
-      142,  141,  140,  139,  138,  137,  136,  134,  133,  132,
-      130,  129,  126,  124,  123,  122,  121,  120,  118,  114,
-      111,  110,  109,  108,  107,  106,  105,  104,  102,  101,
-      100,   99,   98,   97,   96,   95,   94,   93,   91,   90,
-       89,   87,   86,   85,   84,   83,   81,   80,   79,   78,
-       77,   76,   75,   74,   73,   72,   71,   70,   67,   64,
-       63,   62,   61,   60,   59,   58,   57,   56,   53,   52,
-       51,   50,   49,   48,   47,   46,   45,   44,   43,   42,
-
-       41,   38,   37,   36,   29,   26,   25,   23,   22,   21,
-       17,   15,   12,    8,    3,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
-      172,  172,  172,  172,  172,  172,  172,  172
+       16,   20,   20,   24,   19,   31,   40,   40,   67,  133,
+       67,   31,  182,   67,   67,   96,  177,   96,  176,  175,
+       96,   96,  174,  173,  169,  168,  133,   11,   68,   68,
+       68,   68,   68,   68,   68,   68,  180,  167,  180,  180,
+      180,  180,  180,  181,  181,  183,  183,  183,  184,  164,
+
+      184,  184,  184,  184,  184,  185,  185,  186,  163,  186,
+      162,  161,  159,  158,  156,  155,  154,  153,  151,  150,
+      149,  148,  147,  146,  145,  144,  142,  140,  139,  138,
+      136,  135,  132,  131,  129,  128,  127,  126,  125,  123,
+      119,  116,  115,  114,  113,  112,  111,  110,  109,  108,
+      106,  105,  104,  103,  102,  101,  100,   99,   98,   97,
+       95,   94,   93,   92,   90,   89,   88,   87,   86,   84,
+       83,   82,   81,   80,   79,   78,   77,   76,   75,   74,
+       73,   72,   69,   66,   65,   64,   63,   62,   61,   60,
+       59,   58,   55,   54,   53,   52,   51,   50,   49,   48,
+
+       47,   46,   45,   44,   43,   42,   39,   38,   37,   30,
+       27,   26,   25,   23,   22,   21,   17,   15,   12,    8,
+        3,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
+      179,  179,  179,  179
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -529,6 +533,10 @@ static istream *inp = NULL;
 // can print it out for error messages.
 static string dc_filename;
 
+// This is the initial token state returned by the lexer.  It allows
+// the yacc grammar to start from initial points.
+static int initial_token;
+
 
 ////////////////////////////////////////////////////////////////////
 // Defining the interface to the lexer.
@@ -542,6 +550,14 @@ dc_init_lexer(istream &in, const string &filename) {
   col_number = 0;
   error_count = 0;
   warning_count = 0;
+  initial_token = START_DC;
+}
+
+void
+dc_start_parameter_value() {
+  /* Set the initial state to begin parsing a parameter value, instead
+     of at the beginning of the dc file. */
+  initial_token = START_PARAMETER_VALUE;
 }
 
 int
@@ -776,7 +792,7 @@ inline void accept() {
   col_number += yyleng;
 }
 
-#line 781 "lex.yy.c"
+#line 797 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -927,13 +943,18 @@ YY_DECL
 	register char *yy_cp = NULL, *yy_bp = NULL;
 	register int yy_act;
 
-#line 295 "dcLexer.lxx"
+#line 307 "dcLexer.lxx"
 
 
 
+  if (initial_token != 0) {
+    int t = initial_token;
+    initial_token = 0;
+    return t;
+  }
 
 
-#line 938 "lex.yy.c"
+#line 959 "lex.yy.c"
 
 	if ( yy_init )
 		{
@@ -984,13 +1005,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 173 )
+				if ( yy_current_state >= 180 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 216 );
+		while ( yy_base[yy_current_state] != 222 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -1018,7 +1039,7 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 300 "dcLexer.lxx"
+#line 317 "dcLexer.lxx"
 {
   // New line.  Save a copy of the line so we can print it out for the
   // benefit of the user in case we get an error.
@@ -1035,7 +1056,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 314 "dcLexer.lxx"
+#line 331 "dcLexer.lxx"
 { 
   // Eat whitespace.
   accept();
@@ -1043,7 +1064,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 319 "dcLexer.lxx"
+#line 336 "dcLexer.lxx"
 { 
   // Eat C++-style comments.
   accept();
@@ -1051,7 +1072,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 324 "dcLexer.lxx"
+#line 341 "dcLexer.lxx"
 {
   // Eat C-style comments.
   accept();
@@ -1060,7 +1081,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 331 "dcLexer.lxx"
+#line 348 "dcLexer.lxx"
 {
   accept();
   return KW_DCLASS;
@@ -1068,7 +1089,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 336 "dcLexer.lxx"
+#line 353 "dcLexer.lxx"
 {
   accept();
   return KW_FROM;
@@ -1076,7 +1097,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 341 "dcLexer.lxx"
+#line 358 "dcLexer.lxx"
 {
   accept();
   return KW_IMPORT;
@@ -1084,159 +1105,167 @@ YY_RULE_SETUP
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 346 "dcLexer.lxx"
+#line 363 "dcLexer.lxx"
 {
   accept();
-  return KW_INT8;
+  return KW_TYPEDEF;
 }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 351 "dcLexer.lxx"
+#line 368 "dcLexer.lxx"
 {
   accept();
-  return KW_INT16;
+  return KW_INT8;
 }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 356 "dcLexer.lxx"
+#line 373 "dcLexer.lxx"
 {
   accept();
-  return KW_INT32;
+  return KW_INT16;
 }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 361 "dcLexer.lxx"
+#line 378 "dcLexer.lxx"
 {
   accept();
-  return KW_INT64;
+  return KW_INT32;
 }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 366 "dcLexer.lxx"
+#line 383 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT8;
+  return KW_INT64;
 }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 371 "dcLexer.lxx"
+#line 388 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT16;
+  return KW_UINT8;
 }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 376 "dcLexer.lxx"
+#line 393 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT32;
+  return KW_UINT16;
 }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 381 "dcLexer.lxx"
+#line 398 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT64;
+  return KW_UINT32;
 }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 386 "dcLexer.lxx"
+#line 403 "dcLexer.lxx"
 {
   accept();
-  return KW_FLOAT64;
+  return KW_UINT64;
 }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 391 "dcLexer.lxx"
+#line 408 "dcLexer.lxx"
 {
   accept();
-  return KW_STRING;
+  return KW_FLOAT64;
 }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 396 "dcLexer.lxx"
+#line 413 "dcLexer.lxx"
 {
   accept();
-  return KW_BLOB;
+  return KW_STRING;
 }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 401 "dcLexer.lxx"
+#line 418 "dcLexer.lxx"
 {
   accept();
-  return KW_BLOB32;
+  return KW_BLOB;
 }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 406 "dcLexer.lxx"
+#line 423 "dcLexer.lxx"
 {
   accept();
-  return KW_INT8ARRAY;
+  return KW_BLOB32;
 }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 411 "dcLexer.lxx"
+#line 428 "dcLexer.lxx"
 {
   accept();
-  return KW_INT16ARRAY;
+  return KW_INT8ARRAY;
 }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 416 "dcLexer.lxx"
+#line 433 "dcLexer.lxx"
 {
   accept();
-  return KW_INT32ARRAY;
+  return KW_INT16ARRAY;
 }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 421 "dcLexer.lxx"
+#line 438 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT8ARRAY;
+  return KW_INT32ARRAY;
 }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 426 "dcLexer.lxx"
+#line 443 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT16ARRAY;
+  return KW_UINT8ARRAY;
 }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 431 "dcLexer.lxx"
+#line 448 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT32ARRAY;
+  return KW_UINT16ARRAY;
 }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 436 "dcLexer.lxx"
+#line 453 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT32UINT8ARRAY;
+  return KW_UINT32ARRAY;
 }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 441 "dcLexer.lxx"
+#line 458 "dcLexer.lxx"
+{
+  accept();
+  return KW_UINT32UINT8ARRAY;
+}
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 463 "dcLexer.lxx"
 {
   // A molecular keyword.
   accept();
@@ -1245,81 +1274,81 @@ YY_RULE_SETUP
   return KW_MOL; 
 }
 	YY_BREAK
-case 28:
+case 29:
 YY_RULE_SETUP
-#line 449 "dcLexer.lxx"
+#line 471 "dcLexer.lxx"
 {
   accept();
   return KW_REQUIRED;
 }
 	YY_BREAK
-case 29:
+case 30:
 YY_RULE_SETUP
-#line 454 "dcLexer.lxx"
+#line 476 "dcLexer.lxx"
 {
   accept();
   return KW_BROADCAST;
 }
 	YY_BREAK
-case 30:
+case 31:
 YY_RULE_SETUP
-#line 459 "dcLexer.lxx"
+#line 481 "dcLexer.lxx"
 {
   accept();
   return KW_P2P;
 }
 	YY_BREAK
-case 31:
+case 32:
 YY_RULE_SETUP
-#line 464 "dcLexer.lxx"
+#line 486 "dcLexer.lxx"
 {
   accept();
   return KW_RAM;
 }
 	YY_BREAK
-case 32:
+case 33:
 YY_RULE_SETUP
-#line 469 "dcLexer.lxx"
+#line 491 "dcLexer.lxx"
 {
   accept();
   return KW_DB;
 }
 	YY_BREAK
-case 33:
+case 34:
 YY_RULE_SETUP
-#line 474 "dcLexer.lxx"
+#line 496 "dcLexer.lxx"
 {
   accept();
   return KW_CLSEND;
 }
 	YY_BREAK
-case 34:
+case 35:
 YY_RULE_SETUP
-#line 479 "dcLexer.lxx"
+#line 501 "dcLexer.lxx"
 {
   accept();
   return KW_CLRECV;
 }
 	YY_BREAK
-case 35:
+case 36:
 YY_RULE_SETUP
-#line 484 "dcLexer.lxx"
+#line 506 "dcLexer.lxx"
 {
   accept();
   return KW_OWNSEND;
 }
 	YY_BREAK
-case 36:
+case 37:
 YY_RULE_SETUP
-#line 489 "dcLexer.lxx"
+#line 511 "dcLexer.lxx"
 {
   accept();
   return KW_AIRECV;
 }
 	YY_BREAK
-case 37:
+case 38:
 YY_RULE_SETUP
-#line 494 "dcLexer.lxx"
+#line 516 "dcLexer.lxx"
 { 
   // An integer number.
   accept(); 
@@ -1328,9 +1357,9 @@ YY_RULE_SETUP
   return INTEGER; 
 }
 	YY_BREAK
-case 38:
+case 39:
 YY_RULE_SETUP
-#line 502 "dcLexer.lxx"
+#line 524 "dcLexer.lxx"
 {
   // A hexadecimal integer number.
   accept(); 
@@ -1339,9 +1368,9 @@ YY_RULE_SETUP
   return INTEGER; 
 }
 	YY_BREAK
-case 39:
+case 40:
 YY_RULE_SETUP
-#line 510 "dcLexer.lxx"
+#line 532 "dcLexer.lxx"
 { 
   // A floating-point number.
   accept(); 
@@ -1350,9 +1379,9 @@ YY_RULE_SETUP
   return REAL; 
 }
 	YY_BREAK
-case 40:
+case 41:
 YY_RULE_SETUP
-#line 518 "dcLexer.lxx"
+#line 540 "dcLexer.lxx"
 {
   // Quoted string.
   accept();
@@ -1360,9 +1389,9 @@ YY_RULE_SETUP
   return STRING;
 }
 	YY_BREAK
-case 41:
+case 42:
 YY_RULE_SETUP
-#line 525 "dcLexer.lxx"
+#line 547 "dcLexer.lxx"
 {
   // Long hex string.
   accept();
@@ -1370,9 +1399,9 @@ YY_RULE_SETUP
   return HEX_STRING;
 }
 	YY_BREAK
-case 42:
+case 43:
 YY_RULE_SETUP
-#line 532 "dcLexer.lxx"
+#line 554 "dcLexer.lxx"
 { 
   // Identifier.
   accept();
@@ -1380,21 +1409,21 @@ YY_RULE_SETUP
   return IDENTIFIER;
 }
 	YY_BREAK
-case 43:
+case 44:
 YY_RULE_SETUP
-#line 540 "dcLexer.lxx"
+#line 562 "dcLexer.lxx"
 {
   // Send any other printable character as itself.
   accept(); 
   return dcyytext[0];
 }
 	YY_BREAK
-case 44:
+case 45:
 YY_RULE_SETUP
-#line 546 "dcLexer.lxx"
+#line 568 "dcLexer.lxx"
 ECHO;
 	YY_BREAK
-#line 1399 "lex.yy.c"
+#line 1428 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1686,7 +1715,7 @@ static yy_state_type yy_get_previous_state()
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 173 )
+			if ( yy_current_state >= 180 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1721,11 +1750,11 @@ yy_state_type yy_current_state;
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 173 )
+		if ( yy_current_state >= 180 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 172);
+	yy_is_jam = (yy_current_state == 179);
 
 	return yy_is_jam ? 0 : yy_current_state;
 	}
@@ -2275,4 +2304,4 @@ int main()
 	return 0;
 	}
 #endif
-#line 546 "dcLexer.lxx"
+#line 568 "dcLexer.lxx"

+ 5 - 0
direct/src/dcparser/dcLexer.lxx

@@ -360,6 +360,11 @@ REALNUM          ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   return KW_IMPORT;
 }
 
+"typedef" {
+  accept();
+  return KW_TYPEDEF;
+}
+
 "int8" {
   accept();
   return KW_INT8;

+ 4 - 15
direct/src/dcparser/dcMolecularField.cxx

@@ -81,10 +81,12 @@ void DCMolecularField::
 add_atomic(DCAtomicField *atomic) {
   _fields.push_back(atomic);
 
-  int num_nested_fields = atomic->get_num_nested_fields();
-  for (int i = 0; i < num_nested_fields; i++) {
+  int num_atomic_fields = atomic->get_num_nested_fields();
+  for (int i = 0; i < num_atomic_fields; i++) {
     _nested_fields.push_back(atomic->get_nested_field(i));
   }
+
+  _num_nested_fields = _nested_fields.size();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -132,19 +134,6 @@ generate_hash(HashGenerator &hashgen) const {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCMolecularField::get_num_nested_fields
-//       Access: Public, Virtual
-//  Description: Returns the number of nested fields required by this
-//               field type.  These may be array elements or structure
-//               elements.  The return value may be -1 to indicate the
-//               number of nested fields is variable.
-////////////////////////////////////////////////////////////////////
-int DCMolecularField::
-get_num_nested_fields() const {
-  return _nested_fields.size();
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DCMolecularField::get_nested_field
 //       Access: Public, Virtual

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

@@ -46,7 +46,6 @@ public:
   virtual void write(ostream &out, bool brief, int indent_level) const;
   virtual void generate_hash(HashGenerator &hash) const;
 
-  virtual int get_num_nested_fields() const;
   virtual DCPackerInterface *get_nested_field(int n) const;
 
 private:

+ 16 - 15
direct/src/dcparser/dcPacker.cxx

@@ -189,7 +189,7 @@ push() {
     // Now deal with the length prefix that might or might not be
     // before a sequence of nested fields.
     int num_nested_fields = _current_parent->get_num_nested_fields();
-    size_t length_bytes = _current_parent->get_length_bytes();
+    size_t length_bytes = _current_parent->get_num_length_bytes();
     
     if (_mode == M_pack) {
       // Reserve length_bytes for when we figure out what the length
@@ -224,7 +224,11 @@ push() {
         
           // The explicit length trumps the number of nested fields
           // reported by get_num_nested_fields().
-          num_nested_fields = _current_parent->get_num_nested_fields(length);
+          if (length == 0) {
+            num_nested_fields = 0;
+          } else {
+            num_nested_fields = _current_parent->calc_num_nested_fields(length);
+          }
         }
       }
     }
@@ -273,7 +277,7 @@ pop() {
 
   } else {
     if (_mode == M_pack) {
-      size_t length_bytes = _current_parent->get_length_bytes();
+      size_t length_bytes = _current_parent->get_num_length_bytes();
       if (length_bytes != 0) {
         // Now go back and fill in the length of the array.
         char buffer[4];
@@ -478,28 +482,24 @@ unpack_and_format(ostream &out) {
   DCPackType pack_type = get_pack_type();
 
   switch (pack_type) {
+  case PT_invalid:
+    out << "<invalid>";
+    break;
+
   case PT_double:
-    {
-      out << unpack_double();
-    }
+    out << unpack_double();
     break;
       
   case PT_int:
-    {
-      out << unpack_int();
-    }
+    out << unpack_int();
     break;
       
   case PT_int64:
-    {
-      out << unpack_int64();
-    }
+    out << unpack_int64();
     break;
 
   case PT_string:
-    {
-      out << '"' << unpack_string() << '"';
-    }
+    out << '"' << unpack_string() << '"';
     break;
 
   default:
@@ -516,6 +516,7 @@ unpack_and_format(ostream &out) {
       case PT_struct:
       default:
         out << '{';
+        abort();
         break;
       }
 

+ 70 - 25
direct/src/dcparser/dcPackerInterface.cxx

@@ -26,6 +26,29 @@
 DCPackerInterface::
 DCPackerInterface(const string &name) :
   _name(name)
+{
+  _has_fixed_byte_size = false;
+  _fixed_byte_size = 0;
+  _num_length_bytes = 0;
+  _has_nested_fields = false;
+  _num_nested_fields = -1;
+  _pack_type = PT_invalid;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCPackerInterface::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCPackerInterface::
+DCPackerInterface(const DCPackerInterface &copy) :
+  _name(copy._name),
+  _has_fixed_byte_size(copy._has_fixed_byte_size),
+  _fixed_byte_size(copy._fixed_byte_size),
+  _num_length_bytes(copy._num_length_bytes),
+  _has_nested_fields(copy._has_nested_fields),
+  _num_nested_fields(copy._num_nested_fields),
+  _pack_type(copy._pack_type)
 {
 }
 
@@ -59,9 +82,45 @@ set_name(const string &name) {
   _name = name;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCPackerInterface::has_fixed_byte_size
+//       Access: Public
+//  Description: Returns true if this field type always packs to the
+//               same number of bytes, false if it is variable.
+////////////////////////////////////////////////////////////////////
+bool DCPackerInterface::
+has_fixed_byte_size() const {
+  return _has_fixed_byte_size;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCPackerInterface::get_fixed_byte_size
+//       Access: Public
+//  Description: If has_fixed_byte_size() returns true, this returns
+//               the number of bytes this field type will use.
+////////////////////////////////////////////////////////////////////
+size_t DCPackerInterface::
+get_fixed_byte_size() const {
+  return _fixed_byte_size;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCPackerInterface::get_num_length_bytes
+//       Access: Public
+//  Description: Returns the number of bytes that should be written
+//               into the stream on a push() to record the number of
+//               bytes in the record up until the next pop().  This is
+//               only meaningful if _has_nested_fields is true.
+////////////////////////////////////////////////////////////////////
+size_t DCPackerInterface::
+get_num_length_bytes() const {
+  return _num_length_bytes;
+}
+
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCPackerInterface::has_nested_fields
-//       Access: Public, Virtual
+//       Access: Public
 //  Description: Returns true if this field type has any nested fields
 //               (and thus expects a push() .. pop() interface to the
 //               DCPacker), or false otherwise.  If this returns true,
@@ -70,12 +129,12 @@ set_name(const string &name) {
 ////////////////////////////////////////////////////////////////////
 bool DCPackerInterface::
 has_nested_fields() const {
-  return false;
+  return _has_nested_fields;
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCPackerInterface::get_num_nested_fields
-//       Access: Public, Virtual
+//       Access: Public
 //  Description: Returns the number of nested fields required by this
 //               field type.  These may be array elements or structure
 //               elements.  The return value may be -1 to indicate the
@@ -83,21 +142,21 @@ has_nested_fields() const {
 ////////////////////////////////////////////////////////////////////
 int DCPackerInterface::
 get_num_nested_fields() const {
-  return 0;
+  return _num_nested_fields;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DCPackerInterface::get_num_nested_fields
+//     Function: DCPackerInterface::calc_num_nested_fields
 //       Access: Public, Virtual
 //  Description: This flavor of get_num_nested_fields is used during
 //               unpacking.  It returns the number of nested fields to
 //               expect, given a certain length in bytes (as read from
-//               the get_length_bytes() stored in the stream on the
-//               pack).  This will only be called if
-//               get_length_bytes() returns nonzero.
+//               the _num_length_bytes stored in the stream on the
+//               push).  This will only be called if _num_length_bytes
+//               is nonzero.
 ////////////////////////////////////////////////////////////////////
 int DCPackerInterface::
-get_num_nested_fields(size_t length_bytes) const {
+calc_num_nested_fields(size_t length_bytes) const {
   return 0;
 }
 
@@ -114,28 +173,14 @@ get_nested_field(int n) const {
   return NULL;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCPackerInterface::get_length_bytes
-//       Access: Public, Virtual
-//  Description: If has_nested_fields() returns true, this should
-//               return either 0, 2, or 4, indicating the number of
-//               bytes this field's data should be prefixed with to
-//               record its length.  This is respected by push() and
-//               pop().
-////////////////////////////////////////////////////////////////////
-size_t DCPackerInterface::
-get_length_bytes() const {
-  return 0;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DCPackerInterface::get_pack_type
-//       Access: Public, Virtual
+//       Access: Public
 //  Description: Returns the type of value expected by this field.
 ////////////////////////////////////////////////////////////////////
 DCPackType DCPackerInterface::
 get_pack_type() const {
-  return PT_invalid;
+  return _pack_type;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 16 - 5
direct/src/dcparser/dcPackerInterface.h

@@ -61,6 +61,7 @@ END_PUBLISH
 class EXPCL_DIRECT DCPackerInterface {
 public:
   DCPackerInterface(const string &name = string());
+  DCPackerInterface(const DCPackerInterface &copy);
   virtual ~DCPackerInterface();
 
 PUBLISHED:
@@ -68,13 +69,17 @@ PUBLISHED:
   void set_name(const string &name);
 
 public:
-  virtual bool has_nested_fields() const;
-  virtual int get_num_nested_fields() const;
-  virtual int get_num_nested_fields(size_t length_bytes) const;
+  bool has_fixed_byte_size() const;
+  size_t get_fixed_byte_size() const;
+  size_t get_num_length_bytes() const;
+
+  bool has_nested_fields() const;
+  int get_num_nested_fields() const;
+  virtual int calc_num_nested_fields(size_t length_bytes) const;
   virtual DCPackerInterface *get_nested_field(int n) const;
-  virtual size_t get_length_bytes() const;
 
-  virtual DCPackType get_pack_type() const;
+  DCPackType get_pack_type() const;
+
   virtual bool pack_double(DCPackData &pack_data, double value) const;
   virtual bool pack_int(DCPackData &pack_data, int value) const;
   virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const;
@@ -87,6 +92,12 @@ public:
 
 protected:
   string _name;
+  bool _has_fixed_byte_size;
+  size_t _fixed_byte_size;
+  size_t _num_length_bytes;
+  bool _has_nested_fields;
+  int _num_nested_fields;
+  DCPackType _pack_type;
 };
 
 #endif

+ 63 - 5
direct/src/dcparser/dcParameter.cxx

@@ -18,6 +18,8 @@
 
 #include "dcParameter.h"
 #include "hashGenerator.h"
+#include "dcindent.h"
+#include "dcTypedef.h"
 
 
 ////////////////////////////////////////////////////////////////////
@@ -27,6 +29,19 @@
 ////////////////////////////////////////////////////////////////////
 DCParameter::
 DCParameter() {
+  _typedef = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCParameter::Copy Constructor
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCParameter::
+DCParameter(const DCParameter &copy) :
+  DCPackerInterface(copy),
+  _typedef(copy._typedef)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -69,13 +84,56 @@ as_array_parameter() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DCParameter::as_typedef_parameter
-//       Access: Published, Virtual
+//     Function: DCParameter::get_typedef
+//       Access: Published
+//  Description: If this type has been referenced from a typedef,
+//               returns the DCTypedef instance, or NULL if the
+//               type was declared on-the-fly.
+////////////////////////////////////////////////////////////////////
+const DCTypedef *DCParameter::
+get_typedef() const {
+  return _typedef;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCParameter::set_typedef
+//       Access: Published
+//  Description: Records the DCTypedef object that generated this
+//               parameter.  This is normally called only from
+//               DCTypedef::make_new_parameter().
+////////////////////////////////////////////////////////////////////
+void DCParameter::
+set_typedef(const DCTypedef *dtypedef) {
+  _typedef = dtypedef;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCParameter::output
+//       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-DCTypedefParameter *DCParameter::
-as_typedef_parameter() {
-  return NULL;
+void DCParameter::
+output(ostream &out, bool brief) const {
+  string name;
+  if (!brief) {
+    name = get_name();
+  }
+  output_instance(out, "", name, "");
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCParameter::output_typedef_name
+//       Access: Public
+//  Description: Formats the instance like output_instance, but uses
+//               the typedef name instead.
+////////////////////////////////////////////////////////////////////
+void DCParameter::
+output_typedef_name(ostream &out, const string &prename, const string &name, 
+                    const string &postname) const {
+  out << get_typedef()->get_name();
+  if (!prename.empty() || !name.empty() || !postname.empty()) {
+    out << " " << prename << name << postname;
+  }
 }
 
 ////////////////////////////////////////////////////////////////////

+ 14 - 14
direct/src/dcparser/dcParameter.h

@@ -22,21 +22,10 @@
 #include "dcbase.h"
 #include "dcPackerInterface.h"
 
-#ifdef HAVE_PYTHON
-
-#undef HAVE_LONG_LONG  // NSPR and Python both define this.
-#include <Python.h>
-
-// We only need these headers if we are also building a Python interface.
-#include "datagram.h"
-#include "datagramIterator.h"
-
-#endif  // HAVE_PYTHON
-
 class DCSimpleParameter;
 class DCClassParameter;
 class DCArrayParameter;
-class DCTypedefParameter;
+class DCTypedef;
 class HashGenerator;
 
 ////////////////////////////////////////////////////////////////////
@@ -53,6 +42,7 @@ class HashGenerator;
 class EXPCL_DIRECT DCParameter : public DCPackerInterface {
 protected:
   DCParameter();
+  DCParameter(const DCParameter &copy);
 public:
   virtual ~DCParameter();
 
@@ -60,13 +50,23 @@ PUBLISHED:
   virtual DCSimpleParameter *as_simple_parameter();
   virtual DCClassParameter *as_class_parameter();
   virtual DCArrayParameter *as_array_parameter();
-  virtual DCTypedefParameter *as_typedef_parameter();
 
   virtual DCParameter *make_copy() const=0;
 
+  const DCTypedef *get_typedef() const;
+
 public:
-  virtual void output(ostream &out, bool brief) const=0;
+  void set_typedef(const DCTypedef *dtypedef);
+
+  void output(ostream &out, bool brief) const;
+  virtual void output_instance(ostream &out, const string &prename, 
+                               const string &name, const string &postname) const=0;
+  void output_typedef_name(ostream &out, const string &prename, 
+                           const string &name, const string &postname) const;
   virtual void generate_hash(HashGenerator &hash) const;
+
+private:
+  const DCTypedef *_typedef;
 };
 
 #endif

File diff suppressed because it is too large
+ 400 - 315
direct/src/dcparser/dcParser.cxx.prebuilt


+ 32 - 31
direct/src/dcparser/dcParser.h.prebuilt

@@ -9,37 +9,38 @@
 # define	KW_DCLASS	262
 # define	KW_FROM	263
 # define	KW_IMPORT	264
-# define	KW_INT8	265
-# define	KW_INT16	266
-# define	KW_INT32	267
-# define	KW_INT64	268
-# define	KW_UINT8	269
-# define	KW_UINT16	270
-# define	KW_UINT32	271
-# define	KW_UINT64	272
-# define	KW_FLOAT64	273
-# define	KW_STRING	274
-# define	KW_BLOB	275
-# define	KW_BLOB32	276
-# define	KW_INT8ARRAY	277
-# define	KW_INT16ARRAY	278
-# define	KW_INT32ARRAY	279
-# define	KW_UINT8ARRAY	280
-# define	KW_UINT16ARRAY	281
-# define	KW_UINT32ARRAY	282
-# define	KW_UINT32UINT8ARRAY	283
-# define	KW_MOL	284
-# define	KW_REQUIRED	285
-# define	KW_BROADCAST	286
-# define	KW_P2P	287
-# define	KW_RAM	288
-# define	KW_DB	289
-# define	KW_CLSEND	290
-# define	KW_CLRECV	291
-# define	KW_OWNSEND	292
-# define	KW_AIRECV	293
-# define	START_DC	294
-# define	START_PARAMETER_VALUE	295
+# define	KW_TYPEDEF	265
+# define	KW_INT8	266
+# define	KW_INT16	267
+# define	KW_INT32	268
+# define	KW_INT64	269
+# define	KW_UINT8	270
+# define	KW_UINT16	271
+# define	KW_UINT32	272
+# define	KW_UINT64	273
+# define	KW_FLOAT64	274
+# define	KW_STRING	275
+# define	KW_BLOB	276
+# define	KW_BLOB32	277
+# define	KW_INT8ARRAY	278
+# define	KW_INT16ARRAY	279
+# define	KW_INT32ARRAY	280
+# define	KW_UINT8ARRAY	281
+# define	KW_UINT16ARRAY	282
+# define	KW_UINT32ARRAY	283
+# define	KW_UINT32UINT8ARRAY	284
+# define	KW_MOL	285
+# define	KW_REQUIRED	286
+# define	KW_BROADCAST	287
+# define	KW_P2P	288
+# define	KW_RAM	289
+# define	KW_DB	290
+# define	KW_CLSEND	291
+# define	KW_CLRECV	292
+# define	KW_OWNSEND	293
+# define	KW_AIRECV	294
+# define	START_DC	295
+# define	START_PARAMETER_VALUE	296
 
 
 extern YYSTYPE dcyylval;

+ 95 - 28
direct/src/dcparser/dcParser.yxx

@@ -10,7 +10,9 @@
 #include "dcClass.h"
 #include "dcAtomicField.h"
 #include "dcMolecularField.h"
+#include "dcArrayParameter.h"
 #include "dcSimpleParameter.h"
+#include "dcTypedef.h"
 #include "dcPacker.h"
 
 // Because our token type contains objects of type string, which
@@ -63,6 +65,7 @@ dc_cleanup_parser() {
 %token KW_DCLASS 
 %token KW_FROM 
 %token KW_IMPORT 
+%token KW_TYPEDEF 
 
 %token KW_INT8
 %token KW_INT16
@@ -105,7 +108,10 @@ dc_cleanup_parser() {
 %type <u.dclass> dclass_name
 %type <u.atomic> atomic_name
 %type <u.subatomic> type_token
+%type <u.parameter> type_name
+%type <u.parameter> type_definition
 %type <u.parameter> parameter
+%type <u.parameter> parameter_definition
 %type <str> import_identifier
 %type <str> slash_identifier
 
@@ -121,6 +127,7 @@ dc:
         | dc ';'
         | dc dclass
         | dc import
+        | dc typedef_decl
         ;
 
 dclass:
@@ -142,14 +149,13 @@ dclass:
 dclass_name:
         IDENTIFIER
 {
-  DCFile::ClassesByName::const_iterator ni;
-  ni = dc_file->_classes_by_name.find($1);
-  if (ni == dc_file->_classes_by_name.end()) {
-    $$ = new DCClass($1, true);
-    dc_file->add_class($$);
-  } else {
-    $$ = (*ni).second;
+  DCClass *dclass = dc_file->get_class_by_name($1);
+  if (dclass == (DCClass *)NULL) {
+    dclass = new DCClass($1, true);
+    dc_file->add_class(dclass);
   }
+  
+  $$ = dclass;
 }
 	;
 
@@ -200,6 +206,13 @@ import_symbol_list:
 }
 	;
 
+typedef_decl:
+        KW_TYPEDEF parameter
+{
+  dc_file->add_typedef(new DCTypedef($2));
+}
+	;
+
 dclass_derivation:
         empty
         | ':' base_list
@@ -268,7 +281,7 @@ atomic_element:
         parameter
 {
   atomic_element = DCAtomicField::ElementType($1);
-  current_atomic->_elements.push_back(atomic_element);
+  current_atomic->add_element(atomic_element);
 }
 	| parameter '=' 
 {
@@ -283,36 +296,90 @@ atomic_element:
   } else {
     atomic_element = DCAtomicField::ElementType($1);
     atomic_element.set_default_value(current_packer->get_string());
-    current_atomic->_elements.push_back(atomic_element);
+    current_atomic->add_element(atomic_element);
   }
 }
 	;
 
 parameter:
-        type_token 
+        type_definition
 {
-  current_parameter = new DCSimpleParameter($1);
+  current_parameter = $1;
 }
         parameter_definition
 {
-  $$ = current_parameter;
+  $$ = $3;
 }
+        | type_definition
         ;
 
+type_name:
+        type_token
+{
+  $$ = new DCSimpleParameter($1);
+}
+        | type_token '/' INTEGER
+{
+  DCSimpleParameter *simple_param = new DCSimpleParameter($1);
+  if ($3 == 0) {
+    yyerror("Invalid divisor.");
+
+  } else if (!simple_param->set_divisor($3)) {
+    yyerror("A divisor is only valid on a numeric type.");
+  }
+  $$ = simple_param;
+}
+	| IDENTIFIER
+{
+  DCTypedef *dtypedef = dc_file->get_typedef_by_name($1);
+  if (dtypedef == (DCTypedef *)NULL) {
+    yyerror("Invalid type name");
+
+  } else {
+    $$ = dtypedef->make_new_parameter();
+  }
+}
+	;
+
+type_definition:
+        type_name
+	| type_definition '[' ']'
+{
+  $$ = new DCArrayParameter($1);
+}
+	| type_definition '[' INTEGER ']'
+{
+  $$ = new DCArrayParameter($1, $3);
+}
+	;
+
 parameter_definition:
-        empty
+        IDENTIFIER
+{
+  current_parameter->set_name($1);
+  $$ = current_parameter;
+}
         | parameter_definition '/' INTEGER
 {
-  if (current_parameter->as_simple_parameter() == NULL) {
-    yyerror("Invalid divisor on complex type");
+  if ($3 == 0) {
+    yyerror("Invalid divisor.");
+
+  } else if ($1->as_simple_parameter() == NULL || $1->get_typedef() != (DCTypedef *)NULL) {
+    yyerror("A divisor is only allowed on a primitive type.");
 
   } else {
-    current_parameter->as_simple_parameter()->set_divisor($3);
+    if (!$1->as_simple_parameter()->set_divisor($3)) {
+      yyerror("A divisor is only valid on a numeric type.");
+    }
   }
 }
-        | parameter_definition IDENTIFIER
+	| parameter_definition '[' ']'
+{
+  $$ = new DCArrayParameter($1);
+}
+	| parameter_definition '[' INTEGER ']'
 {
-  current_parameter->set_name($2);
+  $$ = new DCArrayParameter($1, $3);
 }
 	;
 
@@ -475,39 +542,39 @@ atomic_flags:
         empty
         | atomic_flags KW_REQUIRED
 {
-  current_atomic->_flags |= DCAtomicField::F_required;
+  current_atomic->add_flag(DCAtomicField::F_required);
 }
         | atomic_flags KW_BROADCAST
 {
-  current_atomic->_flags |= DCAtomicField::F_broadcast;
+  current_atomic->add_flag(DCAtomicField::F_broadcast);
 }
         | atomic_flags KW_P2P
 {
-  current_atomic->_flags |= DCAtomicField::F_p2p;
+  current_atomic->add_flag(DCAtomicField::F_p2p);
 }
         | atomic_flags KW_RAM
 {
-  current_atomic->_flags |= DCAtomicField::F_ram;
+  current_atomic->add_flag(DCAtomicField::F_ram);
 }
         | atomic_flags KW_DB
 {
-  current_atomic->_flags |= DCAtomicField::F_db;
+  current_atomic->add_flag(DCAtomicField::F_db);
 }
         | atomic_flags KW_CLSEND
 {
-  current_atomic->_flags |= DCAtomicField::F_clsend;
+  current_atomic->add_flag(DCAtomicField::F_clsend);
 }
         | atomic_flags KW_CLRECV
 {
-  current_atomic->_flags |= DCAtomicField::F_clrecv;
+  current_atomic->add_flag(DCAtomicField::F_clrecv);
 }
         | atomic_flags KW_OWNSEND
 {
-  current_atomic->_flags |= DCAtomicField::F_ownsend;
+  current_atomic->add_flag(DCAtomicField::F_ownsend);
 }
         | atomic_flags KW_AIRECV
 {
-  current_atomic->_flags |= DCAtomicField::F_airecv;
+  current_atomic->add_flag(DCAtomicField::F_airecv);
 }
         ;
 
@@ -533,7 +600,7 @@ molecular_atom_list:
 {
   if ($3 != (DCAtomicField *)NULL) {
     current_molecular->add_atomic($3);
-    if (current_molecular->get_atomic(0)->_flags != $3->_flags) {
+    if (!current_molecular->get_atomic(0)->compare_flags(*$3)) {
       yyerror("Mismatched flags in molecule between " + 
               current_molecular->get_atomic(0)->get_name() + " and " +
               $3->get_name());

+ 92 - 140
direct/src/dcparser/dcSimpleParameter.cxx

@@ -18,6 +18,7 @@
 
 #include "dcSimpleParameter.h"
 #include "dcPackData.h"
+#include "dcTypedef.h"
 #include "hashGenerator.h"
 
 DCSimpleParameter::NestedFieldMap DCSimpleParameter::_nested_field_map;
@@ -31,8 +32,14 @@ DCSimpleParameter::Uint32Uint8Type *DCSimpleParameter::_uint32uint8_type = NULL;
 DCSimpleParameter::
 DCSimpleParameter(DCSubatomicType type, int divisor) :
   _type(type),
-  _divisor(divisor)
+  _divisor(1)
 {
+  _pack_type = PT_invalid;
+  _nested_type = ST_invalid;
+  _has_nested_fields = false;
+  _bytes_per_element = 0;
+  _num_length_bytes = 2;
+
   // Check for one of the built-in array types.  For these types, we
   // must present a packing interface that has a variable number of
   // nested fields of the appropriate type.
@@ -40,135 +47,127 @@ DCSimpleParameter(DCSubatomicType type, int divisor) :
   case ST_int8array:
     _pack_type = PT_array;
     _nested_type = ST_int8;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 1;
     break;
 
   case ST_int16array:
     _pack_type = PT_array;
     _nested_type = ST_int16;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 2;
     break;
 
   case ST_int32array:
     _pack_type = PT_array;
     _nested_type = ST_int32;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 4;
     break;
 
   case ST_uint8array:
     _pack_type = PT_array;
     _nested_type = ST_uint8;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 1;
     break;
 
   case ST_uint16array:
     _pack_type = PT_array;
     _nested_type = ST_uint16;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 2;
     break;
 
   case ST_uint32array:
     _pack_type = PT_array;
     _nested_type = ST_uint32;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 4;
     break;
 
   case ST_uint32uint8array:
     _pack_type = PT_array;
-    _nested_type = ST_invalid;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 5;
     break;
 
-  case ST_blob:
   case ST_blob32:
+    _num_length_bytes = 4;
+    // fall through
+
+  case ST_blob:
   case ST_string: 
     // For these types, we will present an array interface as an array
     // of uint8, but we will also accept a set_value() with a string
     // parameter.
     _pack_type = PT_string;
     _nested_type = ST_uint8;
-    _is_array = true;
+    _has_nested_fields = true;
     _bytes_per_element = 1;
     break;
 
     // The simple types can be packed directly.
   case ST_int8:
     _pack_type = PT_int;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 1;
     break;
 
   case ST_int16:
     _pack_type = PT_int;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 2;
     break;
 
   case ST_int32:
     _pack_type = PT_int;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 4;
     break;
 
   case ST_int64:
     _pack_type = PT_int64;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 8;
     break;
 
   case ST_uint8:
     _pack_type = PT_int;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 1;
     break;
 
   case ST_uint16:
     _pack_type = PT_int;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 2;
     break;
 
   case ST_uint32:
     _pack_type = PT_int;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 4;
     break;
 
   case ST_uint64:
     _pack_type = PT_int64;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 8;
     break;
 
   case ST_float64:
     _pack_type = PT_double;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    _has_fixed_byte_size = true;
+    _fixed_byte_size = 8;
     break;
 
   case ST_invalid:
-    _pack_type = PT_invalid;
-    _nested_type = ST_invalid;
-    _is_array = false;
-    _bytes_per_element = 0;
+    break;
   }
 
+  set_divisor(divisor);
+
   if (_nested_type != ST_invalid) {
     _nested_field = create_nested_field(_nested_type, _divisor);
 
@@ -183,6 +182,21 @@ DCSimpleParameter(DCSubatomicType type, int divisor) :
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCSimpleParameter::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCSimpleParameter::
+DCSimpleParameter(const DCSimpleParameter &copy) :
+  DCParameter(copy),
+  _type(copy._type),
+  _divisor(copy._divisor),
+  _nested_field(copy._nested_field),
+  _bytes_per_element(copy._bytes_per_element)
+{
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCSimpleParameter::as_simple_parameter
 //       Access: Published, Virtual
@@ -231,57 +245,39 @@ get_divisor() const {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DCSimpleParameter::set_divisor
-//       Access: Published
-//  Description: See get_divisor().
+//       Access: Public
+//  Description: Assigns the indicated divisor to the simple type.
+//               Returns true if assigned, false if this type cannot
+//               accept a divisor.
 ////////////////////////////////////////////////////////////////////
-void DCSimpleParameter::
+bool DCSimpleParameter::
 set_divisor(int divisor) {
+  if (_pack_type == PT_string || divisor == 0) {
+    return false;
+  }
+
   _divisor = divisor;
-  if (_pack_type == PT_int || _pack_type == PT_int64) {
+  if ((_divisor != 1) &&
+      (_pack_type == PT_int || _pack_type == PT_int64)) {
     _pack_type = PT_double;
   }
-}
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::has_nested_fields
-//       Access: Public, Virtual
-//  Description: Returns true if this field type has any nested fields
-//               (and thus expects a push() .. pop() interface to the
-//               DCPacker), or false otherwise.  If this returns true,
-//               get_num_nested_fields() may be called to determine
-//               how many nested fields are expected.
-////////////////////////////////////////////////////////////////////
-bool DCSimpleParameter::
-has_nested_fields() const {
-  return _is_array;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::get_num_nested_fields
-//       Access: Public, Virtual
-//  Description: Returns the number of nested fields required by this
-//               field type.  These may be array elements or structure
-//               elements.  The return value may be -1 to indicate the
-//               number of nested fields is variable.
-////////////////////////////////////////////////////////////////////
-int DCSimpleParameter::
-get_num_nested_fields() const {
-  return _is_array ? -1 : 0;
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::get_num_nested_fields
+//     Function: DCSimpleParameter::calc_num_nested_fields
 //       Access: Public, Virtual
 //  Description: This flavor of get_num_nested_fields is used during
 //               unpacking.  It returns the number of nested fields to
 //               expect, given a certain length in bytes (as read from
-//               the get_length_bytes() stored in the stream on the
-//               pack).  This will only be called if
-//               get_length_bytes() returns nonzero.
+//               the _num_length_bytes stored in the stream on the
+//               push).  This will only be called if _num_length_bytes
+//               is nonzero.
 ////////////////////////////////////////////////////////////////////
 int DCSimpleParameter::
-get_num_nested_fields(size_t length_bytes) const {
-  if (_is_array) {
+calc_num_nested_fields(size_t length_bytes) const {
+  if (_bytes_per_element != 0) {
     return length_bytes / _bytes_per_element;
   }
   return 0;
@@ -296,34 +292,10 @@ get_num_nested_fields(size_t length_bytes) const {
 //               the range 0 <= n < get_num_nested_fields()).
 ////////////////////////////////////////////////////////////////////
 DCPackerInterface *DCSimpleParameter::
-get_nested_field(int n) const {
+get_nested_field(int) const {
   return _nested_field;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::get_length_bytes
-//       Access: Public, Virtual
-//  Description: If has_nested_fields() returns true, this should
-//               return either 0, 2, or 4, indicating the number of
-//               bytes this field's data should be prefixed with to
-//               record its length.  This is respected by push() and
-//               pop().
-////////////////////////////////////////////////////////////////////
-size_t DCSimpleParameter::
-get_length_bytes() const {
-  return _type == ST_blob32 ? 4 : 2;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::get_pack_type
-//       Access: Public, Virtual
-//  Description: Returns the type of value expected by this field.
-////////////////////////////////////////////////////////////////////
-DCPackType DCSimpleParameter::
-get_pack_type() const {
-  return _pack_type;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DCSimpleParameter::pack_double
 //       Access: Published, Virtual
@@ -1020,18 +992,25 @@ unpack_string(const char *data, size_t length, size_t &p, string &value) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::output
+//     Function: DCSimpleParameter::output_instance
 //       Access: Public, Virtual
-//  Description: 
+//  Description: Formats the parameter in the C++-like dc syntax as a
+//               typename and identifier.
 ////////////////////////////////////////////////////////////////////
 void DCSimpleParameter::
-output(ostream &out, bool brief) const {
-  out << _type;
+output_instance(ostream &out, const string &prename, const string &name, 
+                const string &postname) const {
+  if (get_typedef() != (DCTypedef *)NULL) {
+    out << get_typedef()->get_name();
+  } else {
+    out << _type;
+  }
   if (_divisor != 1) {
-    out << " / " << _divisor;
+    out << "/" << _divisor;
   }
-  if (!brief && !_name.empty()) {
-    out << " " << _name;
+
+  if (!prename.empty() || !name.empty() || !postname.empty()) {
+    out << " " << prename << name << postname;
   }
 }
 
@@ -1096,26 +1075,9 @@ DCSimpleParameter::Uint32Uint8Type::
 Uint32Uint8Type() {
   _uint32_type = new DCSimpleParameter(ST_uint32);
   _uint8_type = new DCSimpleParameter(ST_uint8);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::Uint32Uint8Type::has_nested_fields
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-bool DCSimpleParameter::Uint32Uint8Type::
-has_nested_fields() const {
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::Uint32Uint8Type::get_num_nested_fields
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-int DCSimpleParameter::Uint32Uint8Type::
-get_num_nested_fields() const {
-  return 2;
+  _has_nested_fields = true;
+  _num_nested_fields = 2;
+  _pack_type = PT_struct;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1136,13 +1098,3 @@ get_nested_field(int n) const {
     return NULL;
   }
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCSimpleParameter::Uint32Uint8Type::get_pack_type
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-DCPackType DCSimpleParameter::Uint32Uint8Type::
-get_pack_type() const {
-  return PT_struct;
-}

+ 6 - 12
direct/src/dcparser/dcSimpleParameter.h

@@ -35,6 +35,7 @@
 class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
 public:
   DCSimpleParameter(DCSubatomicType type, int divisor = 1);
+  DCSimpleParameter(const DCSimpleParameter &copy);
 
 PUBLISHED:
   virtual DCSimpleParameter *as_simple_parameter();
@@ -42,16 +43,13 @@ PUBLISHED:
 
   DCSubatomicType get_type() const;
   int get_divisor() const;
-  void set_divisor(int divisor);
 
 public:
-  virtual bool has_nested_fields() const;
-  virtual int get_num_nested_fields() const;
-  virtual int get_num_nested_fields(size_t length_bytes) const;
+  bool set_divisor(int divisor);
+
+  virtual int calc_num_nested_fields(size_t length_bytes) const;
   virtual DCPackerInterface *get_nested_field(int n) const;
-  virtual size_t get_length_bytes() const;
 
-  virtual DCPackType get_pack_type() const;
   virtual bool pack_double(DCPackData &pack_data, double value) const;
   virtual bool pack_int(DCPackData &pack_data, int value) const;
   virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const;
@@ -62,7 +60,8 @@ public:
   virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const;
   virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const;
 
-  virtual void output(ostream &out, bool brief) const;
+  virtual void output_instance(ostream &out, const string &prename, 
+                               const string &name, const string &postname) const;
   virtual void generate_hash(HashGenerator &hash) const;
 
 private:
@@ -73,8 +72,6 @@ private:
   DCSubatomicType _type;
   int _divisor;
 
-  DCPackType _pack_type;
-  bool _is_array;
   DCSubatomicType _nested_type;
   DCPackerInterface *_nested_field;
   size_t _bytes_per_element;
@@ -89,10 +86,7 @@ private:
   class Uint32Uint8Type : public DCPackerInterface {
   public:
     Uint32Uint8Type();
-    virtual bool has_nested_fields() const;
-    virtual int get_num_nested_fields() const;
     virtual DCPackerInterface *get_nested_field(int n) const;
-    virtual DCPackType get_pack_type() const;
 
     DCSimpleParameter *_uint32_type;
     DCSimpleParameter *_uint8_type;

+ 127 - 0
direct/src/dcparser/dcTypedef.cxx

@@ -0,0 +1,127 @@
+// Filename: dcTypedef.cxx
+// Created by:  drose (17Jun04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dcParameter.h"
+#include "hashGenerator.h"
+#include "dcParameter.h"
+#include "dcindent.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::Constructor
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCTypedef::
+DCTypedef(DCParameter *parameter) :
+  _parameter(parameter),
+  _number(-1)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCTypedef::
+~DCTypedef() {
+  delete _parameter;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::get_number
+//       Access: Published
+//  Description: Returns a unique index number associated with this
+//               typedef definition.  This is defined implicitly when
+//               the .dc file(s) are read.
+////////////////////////////////////////////////////////////////////
+int DCTypedef::
+get_number() const {
+  return _number;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::get_name
+//       Access: Published
+//  Description: Returns the name of this typedef.
+////////////////////////////////////////////////////////////////////
+const string &DCTypedef::
+get_name() const {
+  return _parameter->get_name();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::get_description
+//       Access: Published
+//  Description: Returns a brief decription of the typedef, useful for
+//               human consumption.
+////////////////////////////////////////////////////////////////////
+string DCTypedef::
+get_description() const {
+  ostringstream strm;
+  _parameter->output(strm, true);
+  return strm.str();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::make_new_parameter
+//       Access: Public
+//  Description: Returns a newly-allocated DCParameter object that
+//               uses the same type as that named by the typedef.
+////////////////////////////////////////////////////////////////////
+DCParameter *DCTypedef::
+make_new_parameter() const {
+  DCParameter *new_parameter = _parameter->make_copy();
+  new_parameter->set_name(string());
+  new_parameter->set_typedef(this);
+  return new_parameter;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::set_number
+//       Access: Public
+//  Description: Assigns the unique number to this typedef.  This is
+//               normally called only by the DCFile interface as the
+//               typedef is added.
+////////////////////////////////////////////////////////////////////
+void DCTypedef::
+set_number(int number) {
+  _number = number;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCTypedef::write
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCTypedef::
+write(ostream &out, bool brief, int indent_level) const {
+  indent(out, indent_level)
+    << "typedef ";
+
+  // We need to preserve the parameter name in the typedef (this is
+  // the typedef name); hence, we pass brief = false to output().
+  _parameter->output(out, false);
+  out << ";";
+
+  if (!brief) {
+    out << "  // typedef " << _number;
+  }
+  out << "\n";
+}
+

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

@@ -0,0 +1,53 @@
+// Filename: dcTypedef.h
+// Created by:  drose (17Jun04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DCTYPEDEF_H
+#define DCTYPEDEF_H
+
+#include "dcbase.h"
+
+class DCParameter;
+
+////////////////////////////////////////////////////////////////////
+//       Class : DCTypedef
+// Description : This represents a single typedef declaration in the
+//               dc file.  It assigns a particular type to a new name,
+//               just like a C typedef.
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT DCTypedef {
+public:
+  DCTypedef(DCParameter *parameter);
+  ~DCTypedef();
+
+PUBLISHED:
+  int get_number() const;
+  const string &get_name() const;
+  string get_description() const;
+
+public:
+  DCParameter *make_new_parameter() const;
+
+  void set_number(int number);
+  void write(ostream &out, bool brief, int indent_level) const;
+
+private:
+  DCParameter *_parameter;
+  int _number;
+};
+
+#endif

+ 1 - 0
direct/src/dcparser/dcparser_composite1.cxx

@@ -6,4 +6,5 @@
 #include "dcPackData.cxx"
 #include "dcPacker.cxx"
 #include "dcPackerInterface.cxx"
+#include "dcindent.cxx"
 

+ 2 - 1
direct/src/dcparser/dcparser_composite2.cxx

@@ -1,8 +1,9 @@
 
 #include "dcParameter.cxx"
+#include "dcArrayParameter.cxx"
 #include "dcSimpleParameter.cxx"
 #include "dcField.cxx"
 #include "dcFile.cxx"
 #include "dcMolecularField.cxx"
 #include "dcSubatomicType.cxx"
-#include "dcindent.cxx"
+#include "dcTypedef.cxx"

Some files were not shown because too many files changed in this diff