diff --git a/direct/src/dcparser/dcArrayParameter.cxx b/direct/src/dcparser/dcArrayParameter.cxx index 90677a6a7a..7a26e6b0ed 100644 --- a/direct/src/dcparser/dcArrayParameter.cxx +++ b/direct/src/dcparser/dcArrayParameter.cxx @@ -35,6 +35,8 @@ DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) : _array_size = -1; if (_array_size_range.has_one_value()) { _array_size = _array_size_range.get_one_value(); + } else { + _has_range_limits = true; } if (_array_size >= 0 && _element_type->has_fixed_byte_size()) { @@ -48,6 +50,10 @@ DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) : _num_length_bytes = 2; } + if (_element_type->has_range_limits()) { + _has_range_limits = true; + } + _has_nested_fields = true; _num_nested_fields = _array_size; _pack_type = PT_array; diff --git a/direct/src/dcparser/dcAtomicField.cxx b/direct/src/dcparser/dcAtomicField.cxx index fa7c9eed00..81d9ee72eb 100644 --- a/direct/src/dcparser/dcAtomicField.cxx +++ b/direct/src/dcparser/dcAtomicField.cxx @@ -246,6 +246,9 @@ add_element(const DCAtomicField::ElementType &element) { if (_has_fixed_structure) { _has_fixed_structure = element._param->has_fixed_structure(); } + if (!_has_range_limits) { + _has_range_limits = element._param->has_range_limits(); + } } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/dcparser/dcClass.cxx b/direct/src/dcparser/dcClass.cxx index 926026131f..146727c917 100644 --- a/direct/src/dcparser/dcClass.cxx +++ b/direct/src/dcparser/dcClass.cxx @@ -22,6 +22,8 @@ #include "dcindent.h" #include "dcmsgtypes.h" +#include "dcClassParameter.h" + //////////////////////////////////////////////////////////////////// // Function: DCClass::Constructor // Access: Public diff --git a/direct/src/dcparser/dcClassParameter.cxx b/direct/src/dcparser/dcClassParameter.cxx index 7fe5331cbe..e0cafb43cc 100644 --- a/direct/src/dcparser/dcClassParameter.cxx +++ b/direct/src/dcparser/dcClassParameter.cxx @@ -26,7 +26,7 @@ // Description: //////////////////////////////////////////////////////////////////// DCClassParameter:: -DCClassParameter(DCClass *dclass) : +DCClassParameter(const DCClass *dclass) : _dclass(dclass) { set_name(dclass->get_name()); @@ -44,7 +44,8 @@ DCClassParameter(DCClass *dclass) : if (_dclass->has_constructor()) { _nested_fields.push_back(_dclass->get_constructor()); } - for (int i = 0 ; i < num_fields; i++) { + int i; + for (i = 0 ; i < num_fields; i++) { _nested_fields.push_back(_dclass->get_inherited_field(i)); } @@ -54,11 +55,13 @@ DCClassParameter(DCClass *dclass) : _has_fixed_byte_size = true; _fixed_byte_size = 0; _has_fixed_structure = true; - for (int i = 0; i < _num_nested_fields && _has_fixed_byte_size; i++) { + for (i = 0; i < _num_nested_fields; i++) { DCPackerInterface *field = get_nested_field(i); _has_fixed_byte_size = _has_fixed_byte_size && field->has_fixed_byte_size(); _fixed_byte_size += field->get_fixed_byte_size(); _has_fixed_structure = _has_fixed_structure && field->has_fixed_structure(); + + _has_range_limits = _has_range_limits || field->has_range_limits(); } } @@ -112,7 +115,7 @@ is_valid() const { // Access: Published // Description: Returns the class object this parameter represents. //////////////////////////////////////////////////////////////////// -DCClass *DCClassParameter:: +const DCClass *DCClassParameter:: get_class() const { return _dclass; } diff --git a/direct/src/dcparser/dcClassParameter.h b/direct/src/dcparser/dcClassParameter.h index 4fac13642e..ccc262b101 100644 --- a/direct/src/dcparser/dcClassParameter.h +++ b/direct/src/dcparser/dcClassParameter.h @@ -32,7 +32,7 @@ class DCClass; //////////////////////////////////////////////////////////////////// class EXPCL_DIRECT DCClassParameter : public DCParameter { public: - DCClassParameter(DCClass *dclass); + DCClassParameter(const DCClass *dclass); DCClassParameter(const DCClassParameter ©); PUBLISHED: @@ -40,7 +40,7 @@ PUBLISHED: virtual DCParameter *make_copy() const; virtual bool is_valid() const; - DCClass *get_class() const; + const DCClass *get_class() const; public: virtual DCPackerInterface *get_nested_field(int n) const; @@ -53,7 +53,7 @@ private: typedef pvector Fields; Fields _nested_fields; - DCClass *_dclass; + const DCClass *_dclass; }; #endif diff --git a/direct/src/dcparser/dcFile.cxx b/direct/src/dcparser/dcFile.cxx index 9035ceb25a..666fa4d381 100644 --- a/direct/src/dcparser/dcFile.cxx +++ b/direct/src/dcparser/dcFile.cxx @@ -60,14 +60,23 @@ DCFile:: //////////////////////////////////////////////////////////////////// void DCFile:: clear() { - Classes::iterator ci; - for (ci = _classes.begin(); ci != _classes.end(); ++ci) { - delete (*ci); + Declarations::iterator di; + for (di = _declarations.begin(); di != _declarations.end(); ++di) { + delete (*di); + } + for (di = _things_to_delete.begin(); di != _things_to_delete.end(); ++di) { + delete (*di); } _classes.clear(); _imports.clear(); _things_by_name.clear(); + _typedefs.clear(); + _typedefs_by_name.clear(); + _declarations.clear(); + _things_to_delete.clear(); + + _all_objects_valid = true; } #ifdef WITHIN_PANDA @@ -135,7 +144,17 @@ read(Filename filename) { return false; } bool okflag = read(*in, filename); + + // For some reason--compiler bug in gcc 3.2?--explicitly deleting + // the in pointer does not call the appropriate global delete + // function; instead apparently calling the system delete + // function. So we call the delete function by hand instead. +#ifndef NDEBUG + (*global_operator_delete)(in); +#else delete in; +#endif + return okflag; } filename.open_read(in); @@ -465,6 +484,8 @@ add_class(DCClass *dclass) { if (!dclass->is_bogus_class()) { _declarations.push_back(dclass); + } else { + _things_to_delete.push_back(dclass); } return true; @@ -552,7 +573,23 @@ add_typedef(DCTypedef *dtypedef) { if (!dtypedef->is_bogus_typedef() && !dtypedef->is_implicit_typedef()) { _declarations.push_back(dtypedef); + } else { + _things_to_delete.push_back(dtypedef); } return true; } + +//////////////////////////////////////////////////////////////////// +// Function: DCFile::add_thing_to_delete +// Access: Public +// Description: Adds the indicated declaration to the list of +// declarations that are not reported with the file, but +// will be deleted when the DCFile object destructs. +// That is, transfers ownership of the indicated pointer +// to the DCFile. +//////////////////////////////////////////////////////////////////// +void DCFile:: +add_thing_to_delete(DCDeclaration *decl) { + _things_to_delete.push_back(decl); +} diff --git a/direct/src/dcparser/dcFile.h b/direct/src/dcparser/dcFile.h index 2cb2e638c2..07d73c6f8a 100644 --- a/direct/src/dcparser/dcFile.h +++ b/direct/src/dcparser/dcFile.h @@ -74,6 +74,7 @@ public: void add_import_module(const string &import_module); void add_import_symbol(const string &import_symbol); bool add_typedef(DCTypedef *dtypedef); + void add_thing_to_delete(DCDeclaration *decl); private: typedef pvector Classes; @@ -100,6 +101,7 @@ private: typedef pvector Declarations; Declarations _declarations; + Declarations _things_to_delete; bool _all_objects_valid; }; diff --git a/direct/src/dcparser/dcMolecularField.cxx b/direct/src/dcparser/dcMolecularField.cxx index 4735cf0882..ffc0e1b64e 100644 --- a/direct/src/dcparser/dcMolecularField.cxx +++ b/direct/src/dcparser/dcMolecularField.cxx @@ -102,6 +102,9 @@ add_atomic(DCAtomicField *atomic) { if (_has_fixed_structure) { _has_fixed_structure = atomic->has_fixed_structure(); } + if (!_has_range_limits) { + _has_range_limits = atomic->has_range_limits(); + } } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/dcparser/dcPacker.cxx b/direct/src/dcparser/dcPacker.cxx index 28675861ac..b516ec7150 100755 --- a/direct/src/dcparser/dcPacker.cxx +++ b/direct/src/dcparser/dcPacker.cxx @@ -603,12 +603,9 @@ unpack_skip() { if (_current_field == NULL) { _pack_error = true; - } else if (_current_field->has_fixed_byte_size()) { - _unpack_p += _current_field->get_fixed_byte_size(); - advance(); - } else { - if (_current_field->unpack_skip(_unpack_data, _unpack_length, _unpack_p)) { + if (_current_field->unpack_skip(_unpack_data, _unpack_length, _unpack_p, + _pack_error)) { advance(); } else { @@ -657,7 +654,7 @@ pack_object(PyObject *object) { int size = PySequence_Size(object); bool is_instance = false; - DCClass *dclass = NULL; + const DCClass *dclass = NULL; const DCClassParameter *class_param = ((DCPackerInterface *)get_current_field())->as_class_parameter(); if (class_param != (DCClassParameter *)NULL) { dclass = class_param->get_class(); @@ -794,7 +791,7 @@ unpack_object() { { const DCClassParameter *class_param = ((DCPackerInterface *)get_current_field())->as_class_parameter(); if (class_param != (DCClassParameter *)NULL) { - DCClass *dclass = class_param->get_class(); + const DCClass *dclass = class_param->get_class(); if (dclass->has_class_def()) { // If we know what kind of class object this is and it has a // valid constructor, create the class object instead of @@ -1095,7 +1092,7 @@ clear() { // appropriate values from the class object and pack in. //////////////////////////////////////////////////////////////////// void DCPacker:: -pack_class_object(DCClass *dclass, PyObject *object) { +pack_class_object(const DCClass *dclass, PyObject *object) { PyObject *str = PyObject_Str(object); cerr << "pack_class_object(" << dclass->get_name() << ", " << PyString_AsString(str) << ")\n"; @@ -1122,7 +1119,7 @@ pack_class_object(DCClass *dclass, PyObject *object) { // constructor, unpack it and fill in its values. //////////////////////////////////////////////////////////////////// PyObject *DCPacker:: -unpack_class_object(DCClass *dclass) { +unpack_class_object(const DCClass *dclass) { PyObject *class_def = dclass->get_class_def(); nassertr(class_def != (PyObject *)NULL, NULL); diff --git a/direct/src/dcparser/dcPacker.h b/direct/src/dcparser/dcPacker.h index 7df73daafa..ccffcb3431 100755 --- a/direct/src/dcparser/dcPacker.h +++ b/direct/src/dcparser/dcPacker.h @@ -178,8 +178,8 @@ private: void clear(); #ifdef HAVE_PYTHON - void pack_class_object(DCClass *dclass, PyObject *object); - PyObject *unpack_class_object(DCClass *dclass); + void pack_class_object(const DCClass *dclass, PyObject *object); + PyObject *unpack_class_object(const DCClass *dclass); void set_class_element(PyObject *class_def, PyObject *&object, const DCField *field); #endif diff --git a/direct/src/dcparser/dcPackerInterface.I b/direct/src/dcparser/dcPackerInterface.I index da214f2fcb..5624fa7a84 100644 --- a/direct/src/dcparser/dcPackerInterface.I +++ b/direct/src/dcparser/dcPackerInterface.I @@ -78,6 +78,19 @@ has_fixed_structure() const { return _has_fixed_structure; } +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::has_range_limits +// Access: Public +// Description: Returns true if this field, or any sub-field of this +// field, has a limit imposed in the DC file on its +// legal values. If this is false, then +// unpack_validate() is trivial. +//////////////////////////////////////////////////////////////////// +INLINE bool DCPackerInterface:: +has_range_limits() const { + return _has_range_limits; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::get_num_length_bytes // Access: Public diff --git a/direct/src/dcparser/dcPackerInterface.cxx b/direct/src/dcparser/dcPackerInterface.cxx index 6347721f9a..f9b1c3fa9e 100755 --- a/direct/src/dcparser/dcPackerInterface.cxx +++ b/direct/src/dcparser/dcPackerInterface.cxx @@ -31,6 +31,7 @@ DCPackerInterface(const string &name) : _has_fixed_byte_size = false; _fixed_byte_size = 0; _has_fixed_structure = false; + _has_range_limits = false; _num_length_bytes = 0; _has_nested_fields = false; _num_nested_fields = -1; @@ -49,6 +50,7 @@ DCPackerInterface(const DCPackerInterface ©) : _has_fixed_byte_size(copy._has_fixed_byte_size), _fixed_byte_size(copy._fixed_byte_size), _has_fixed_structure(copy._has_fixed_structure), + _has_range_limits(copy._has_range_limits), _num_length_bytes(copy._num_length_bytes), _has_nested_fields(copy._has_nested_fields), _num_nested_fields(copy._num_nested_fields), @@ -284,7 +286,11 @@ unpack_string(const char *, size_t, size_t &, string &, bool &pack_error, bool & // validate this field). //////////////////////////////////////////////////////////////////// bool DCPackerInterface:: -unpack_validate(const char *, size_t, size_t &, bool &, bool &) const { +unpack_validate(const char *data, size_t length, size_t &p, + bool &pack_error, bool &) const { + if (!_has_range_limits) { + return unpack_skip(data, length, p, pack_error); + } return false; } @@ -297,7 +303,15 @@ unpack_validate(const char *, size_t, size_t &, bool &, bool &) const { // failure (e.g. we don't know how to skip this field). //////////////////////////////////////////////////////////////////// bool DCPackerInterface:: -unpack_skip(const char *, size_t, size_t &) const { +unpack_skip(const char *data, size_t length, size_t &p, + bool &pack_error) const { + if (_has_fixed_byte_size) { + p += _fixed_byte_size; + if (p > length) { + pack_error = true; + } + return true; + } return false; } diff --git a/direct/src/dcparser/dcPackerInterface.h b/direct/src/dcparser/dcPackerInterface.h index bf611df915..1c3ac9c549 100755 --- a/direct/src/dcparser/dcPackerInterface.h +++ b/direct/src/dcparser/dcPackerInterface.h @@ -85,6 +85,7 @@ public: INLINE bool has_fixed_byte_size() const; INLINE size_t get_fixed_byte_size() const; INLINE bool has_fixed_structure() const; + INLINE bool has_range_limits() const; INLINE size_t get_num_length_bytes() const; INLINE bool has_nested_fields() const; @@ -123,7 +124,8 @@ public: string &value, bool &pack_error, bool &range_error) const; virtual bool unpack_validate(const char *data, size_t length, size_t &p, bool &pack_error, bool &range_error) const; - virtual bool unpack_skip(const char *data, size_t length, size_t &p) const; + virtual bool unpack_skip(const char *data, size_t length, size_t &p, + bool &pack_error) const; // These are the low-level interfaces for packing and unpacking // numbers from a buffer. You're responsible for making sure the @@ -167,6 +169,7 @@ protected: bool _has_fixed_byte_size; size_t _fixed_byte_size; bool _has_fixed_structure; + bool _has_range_limits; size_t _num_length_bytes; bool _has_nested_fields; int _num_nested_fields; diff --git a/direct/src/dcparser/dcParser.cxx.prebuilt b/direct/src/dcparser/dcParser.cxx.prebuilt index 9b9512b317..c63e0bdf4f 100644 --- a/direct/src/dcparser/dcParser.cxx.prebuilt +++ b/direct/src/dcparser/dcParser.cxx.prebuilt @@ -240,21 +240,21 @@ static const short yyrhs[] = static const short yyrline[] = { 0, 147, 149, 152, 154, 155, 166, 172, 173, 176, - 176, 189, 194, 200, 213, 215, 221, 223, 229, 234, - 234, 241, 243, 249, 254, 260, 276, 278, 281, 288, - 296, 298, 299, 307, 309, 310, 315, 322, 322, 336, - 338, 341, 343, 346, 352, 352, 377, 377, 388, 392, - 394, 397, 402, 410, 421, 435, 449, 475, 479, 485, - 490, 497, 504, 513, 519, 525, 535, 540, 547, 554, - 560, 568, 570, 576, 582, 596, 602, 612, 615, 626, - 630, 634, 639, 643, 646, 656, 660, 665, 669, 673, - 677, 681, 681, 689, 689, 697, 697, 705, 711, 717, - 723, 731, 733, 736, 738, 741, 743, 746, 751, 755, - 759, 763, 767, 771, 775, 779, 783, 787, 791, 795, - 799, 803, 807, 811, 815, 819, 823, 829, 834, 838, - 842, 846, 850, 854, 858, 862, 866, 872, 872, 883, - 899, 906, 919, 924, 927, 927, 941, 943, 944, 945, - 955, 955, 972, 977, 983 + 176, 189, 194, 200, 214, 216, 222, 224, 230, 235, + 235, 242, 244, 250, 255, 261, 277, 279, 282, 289, + 297, 299, 300, 308, 310, 311, 316, 323, 323, 337, + 339, 342, 344, 347, 353, 353, 378, 378, 389, 393, + 395, 398, 403, 411, 422, 436, 450, 476, 482, 490, + 495, 502, 509, 518, 524, 530, 540, 545, 552, 559, + 565, 573, 575, 581, 587, 601, 607, 617, 620, 631, + 635, 639, 644, 648, 651, 661, 665, 670, 674, 678, + 682, 686, 686, 694, 694, 702, 702, 710, 716, 722, + 728, 736, 738, 741, 743, 746, 748, 751, 756, 760, + 764, 768, 772, 776, 780, 784, 788, 792, 796, 800, + 804, 808, 812, 816, 820, 824, 828, 834, 839, 843, + 847, 851, 855, 859, 863, 867, 871, 877, 877, 888, + 904, 911, 924, 929, 932, 932, 946, 948, 949, 950, + 960, 960, 977, 982, 988 }; #endif @@ -1237,6 +1237,7 @@ case 13: { DCClass *dclass = dc_file->get_class_by_name(yyvsp[0].str); if (dclass == (DCClass *)NULL) { + // Create a bogus class as a forward reference. dclass = new DCClass(yyvsp[0].str, false, true); dc_file->add_class(dclass); } @@ -1245,49 +1246,49 @@ case 13: } break; case 15: -#line 216 "dcParser.yxx" +#line 217 "dcParser.yxx" { yyval.str = yyvsp[-2].str + string("/") + yyvsp[0].str; } break; case 17: -#line 224 "dcParser.yxx" +#line 225 "dcParser.yxx" { yyval.str = yyvsp[-2].str + string(".") + yyvsp[0].str; } break; case 18: -#line 231 "dcParser.yxx" +#line 232 "dcParser.yxx" { dc_file->add_import_module(yyvsp[0].str); } break; case 19: -#line 235 "dcParser.yxx" +#line 236 "dcParser.yxx" { dc_file->add_import_module(yyvsp[-1].str); } break; case 22: -#line 244 "dcParser.yxx" +#line 245 "dcParser.yxx" { dc_file->add_import_symbol("*"); } break; case 23: -#line 251 "dcParser.yxx" +#line 252 "dcParser.yxx" { dc_file->add_import_symbol(yyvsp[0].str); } break; case 24: -#line 255 "dcParser.yxx" +#line 256 "dcParser.yxx" { dc_file->add_import_symbol(yyvsp[0].str); } break; case 25: -#line 262 "dcParser.yxx" +#line 263 "dcParser.yxx" { DCTypedef *dtypedef = new DCTypedef(yyvsp[0].u.parameter); @@ -1302,7 +1303,7 @@ case 25: } break; case 28: -#line 283 "dcParser.yxx" +#line 284 "dcParser.yxx" { if (yyvsp[0].u.dclass != (DCClass *)NULL) { current_class->add_parent(yyvsp[0].u.dclass); @@ -1310,7 +1311,7 @@ case 28: } break; case 29: -#line 289 "dcParser.yxx" +#line 290 "dcParser.yxx" { if (yyvsp[0].u.dclass != (DCClass *)NULL) { current_class->add_parent(yyvsp[0].u.dclass); @@ -1318,7 +1319,7 @@ case 29: } break; case 32: -#line 300 "dcParser.yxx" +#line 301 "dcParser.yxx" { if (!current_class->add_field(yyvsp[0].u.field)) { yyerror("Duplicate field name: " + yyvsp[0].u.field->get_name()); @@ -1326,28 +1327,28 @@ case 32: } break; case 35: -#line 311 "dcParser.yxx" +#line 312 "dcParser.yxx" { yyval.u.field = yyvsp[-2].u.parameter; yyval.u.field->set_flags(yyvsp[-1].u.s_int); } break; case 36: -#line 316 "dcParser.yxx" +#line 317 "dcParser.yxx" { yyval.u.field = yyvsp[-1].u.parameter; yyval.u.field->set_flags(yyvsp[0].u.s_int); } break; case 37: -#line 324 "dcParser.yxx" +#line 325 "dcParser.yxx" { yyval.u.field = current_atomic; current_atomic = new DCAtomicField(yyvsp[-1].str); } break; case 38: -#line 329 "dcParser.yxx" +#line 330 "dcParser.yxx" { yyval.u.field = current_atomic; current_atomic = yyvsp[-3].u.atomic; @@ -1355,14 +1356,14 @@ case 38: } break; case 43: -#line 348 "dcParser.yxx" +#line 349 "dcParser.yxx" { atomic_element = DCAtomicField::ElementType(yyvsp[0].u.parameter); current_atomic->add_element(atomic_element); } break; case 44: -#line 353 "dcParser.yxx" +#line 354 "dcParser.yxx" { current_packer = &default_packer; current_packer->clear_data(); @@ -1370,7 +1371,7 @@ case 44: } break; case 45: -#line 359 "dcParser.yxx" +#line 360 "dcParser.yxx" { bool is_valid = yyvsp[-3].u.parameter->is_valid(); atomic_element = DCAtomicField::ElementType(yyvsp[-3].u.parameter); @@ -1389,25 +1390,25 @@ case 45: } break; case 46: -#line 379 "dcParser.yxx" +#line 380 "dcParser.yxx" { current_parameter = yyvsp[0].u.parameter; } break; case 47: -#line 383 "dcParser.yxx" +#line 384 "dcParser.yxx" { yyval.u.parameter = yyvsp[0].u.parameter; } break; case 51: -#line 399 "dcParser.yxx" +#line 400 "dcParser.yxx" { yyval.u.parameter = new DCSimpleParameter(yyvsp[0].u.subatomic); } break; case 52: -#line 403 "dcParser.yxx" +#line 404 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-3].u.subatomic); if (!simple_param->set_range(double_range)) { @@ -1417,7 +1418,7 @@ case 52: } break; case 53: -#line 411 "dcParser.yxx" +#line 412 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-2].u.subatomic); if (yyvsp[0].u.s_uint == 0) { @@ -1430,7 +1431,7 @@ case 53: } break; case 54: -#line 422 "dcParser.yxx" +#line 423 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); if (yyvsp[-3].u.s_uint == 0) { @@ -1446,7 +1447,7 @@ case 54: } break; case 55: -#line 436 "dcParser.yxx" +#line 437 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); if (yyvsp[0].u.s_uint == 0) { @@ -1462,7 +1463,7 @@ case 55: } break; case 56: -#line 450 "dcParser.yxx" +#line 451 "dcParser.yxx" { DCTypedef *dtypedef = dc_file->get_typedef_by_name(yyvsp[0].str); if (dtypedef == (DCTypedef *)NULL) { @@ -1490,25 +1491,29 @@ case 56: } break; case 57: -#line 476 "dcParser.yxx" +#line 477 "dcParser.yxx" { + // This is an inline class definition. + dc_file->add_thing_to_delete(yyvsp[0].u.dclass); yyval.u.parameter = new DCClassParameter(yyvsp[0].u.dclass); } break; case 58: -#line 480 "dcParser.yxx" +#line 483 "dcParser.yxx" { + // This is an inline switch definition. + dc_file->add_thing_to_delete(yyvsp[0].u.dswitch); yyval.u.parameter = new DCSwitchParameter(yyvsp[0].u.dswitch); } break; case 59: -#line 487 "dcParser.yxx" +#line 492 "dcParser.yxx" { double_range.clear(); } break; case 60: -#line 491 "dcParser.yxx" +#line 496 "dcParser.yxx" { double_range.clear(); if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { @@ -1517,7 +1522,7 @@ case 60: } break; case 61: -#line 498 "dcParser.yxx" +#line 503 "dcParser.yxx" { double_range.clear(); if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { @@ -1526,7 +1531,7 @@ case 61: } break; case 62: -#line 505 "dcParser.yxx" +#line 510 "dcParser.yxx" { double_range.clear(); if (yyvsp[0].u.real >= 0) { @@ -1537,7 +1542,7 @@ case 62: } break; case 63: -#line 514 "dcParser.yxx" +#line 519 "dcParser.yxx" { if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { yyerror("Overlapping range"); @@ -1545,7 +1550,7 @@ case 63: } break; case 64: -#line 520 "dcParser.yxx" +#line 525 "dcParser.yxx" { if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { yyerror("Overlapping range"); @@ -1553,7 +1558,7 @@ case 64: } break; case 65: -#line 526 "dcParser.yxx" +#line 531 "dcParser.yxx" { if (yyvsp[0].u.real >= 0) { yyerror("Syntax error"); @@ -1563,13 +1568,13 @@ case 65: } break; case 66: -#line 537 "dcParser.yxx" +#line 542 "dcParser.yxx" { uint_range.clear(); } break; case 67: -#line 541 "dcParser.yxx" +#line 546 "dcParser.yxx" { uint_range.clear(); if (!uint_range.add_range(yyvsp[0].u.s_uint, yyvsp[0].u.s_uint)) { @@ -1578,7 +1583,7 @@ case 67: } break; case 68: -#line 548 "dcParser.yxx" +#line 553 "dcParser.yxx" { uint_range.clear(); if (!uint_range.add_range(yyvsp[-2].u.s_uint, yyvsp[0].u.s_uint)) { @@ -1587,7 +1592,7 @@ case 68: } break; case 69: -#line 555 "dcParser.yxx" +#line 560 "dcParser.yxx" { if (!uint_range.add_range(yyvsp[0].u.s_uint, yyvsp[0].u.s_uint)) { yyerror("Overlapping range"); @@ -1595,7 +1600,7 @@ case 69: } break; case 70: -#line 561 "dcParser.yxx" +#line 566 "dcParser.yxx" { if (!uint_range.add_range(yyvsp[-2].u.s_uint, yyvsp[0].u.s_uint)) { yyerror("Overlapping range"); @@ -1603,20 +1608,20 @@ case 70: } break; case 72: -#line 571 "dcParser.yxx" +#line 576 "dcParser.yxx" { yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, uint_range); } break; case 73: -#line 578 "dcParser.yxx" +#line 583 "dcParser.yxx" { current_parameter->set_name(yyvsp[0].str); yyval.u.parameter = current_parameter; } break; case 74: -#line 583 "dcParser.yxx" +#line 588 "dcParser.yxx" { if (yyvsp[0].u.s_uint == 0) { yyerror("Invalid divisor."); @@ -1632,13 +1637,13 @@ case 74: } break; case 75: -#line 597 "dcParser.yxx" +#line 602 "dcParser.yxx" { yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, uint_range); } break; case 76: -#line 604 "dcParser.yxx" +#line 609 "dcParser.yxx" { if (yyvsp[0].str.length() != 1) { yyerror("Single character required."); @@ -1649,7 +1654,7 @@ case 76: } break; case 78: -#line 617 "dcParser.yxx" +#line 622 "dcParser.yxx" { yyval.u.s_uint = (unsigned int)yyvsp[0].u.uint64; if (yyval.u.s_uint != yyvsp[0].u.uint64) { @@ -1659,19 +1664,19 @@ case 78: } break; case 81: -#line 636 "dcParser.yxx" +#line 641 "dcParser.yxx" { yyval.u.real = (double)yyvsp[0].u.uint64; } break; case 82: -#line 640 "dcParser.yxx" +#line 645 "dcParser.yxx" { yyval.u.real = (double)yyvsp[0].u.int64; } break; case 84: -#line 648 "dcParser.yxx" +#line 653 "dcParser.yxx" { if (yyvsp[0].str.length() != 1) { yyerror("Single character required."); @@ -1682,73 +1687,73 @@ case 84: } break; case 86: -#line 662 "dcParser.yxx" +#line 667 "dcParser.yxx" { current_packer->pack_int64(yyvsp[0].u.int64); } break; case 87: -#line 666 "dcParser.yxx" +#line 671 "dcParser.yxx" { current_packer->pack_uint64(yyvsp[0].u.uint64); } break; case 88: -#line 670 "dcParser.yxx" +#line 675 "dcParser.yxx" { current_packer->pack_double(yyvsp[0].u.real); } break; case 89: -#line 674 "dcParser.yxx" +#line 679 "dcParser.yxx" { current_packer->pack_string(yyvsp[0].str); } break; case 90: -#line 678 "dcParser.yxx" +#line 683 "dcParser.yxx" { current_packer->pack_literal_value(yyvsp[0].str); } break; case 91: -#line 682 "dcParser.yxx" +#line 687 "dcParser.yxx" { current_packer->push(); } break; case 92: -#line 686 "dcParser.yxx" +#line 691 "dcParser.yxx" { current_packer->pop(); } break; case 93: -#line 690 "dcParser.yxx" +#line 695 "dcParser.yxx" { current_packer->push(); } break; case 94: -#line 694 "dcParser.yxx" +#line 699 "dcParser.yxx" { current_packer->pop(); } break; case 95: -#line 698 "dcParser.yxx" +#line 703 "dcParser.yxx" { current_packer->push(); } break; case 96: -#line 702 "dcParser.yxx" +#line 707 "dcParser.yxx" { current_packer->pop(); } break; case 97: -#line 706 "dcParser.yxx" +#line 711 "dcParser.yxx" { for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) { current_packer->pack_int64(yyvsp[-2].u.int64); @@ -1756,7 +1761,7 @@ case 97: } break; case 98: -#line 712 "dcParser.yxx" +#line 717 "dcParser.yxx" { for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) { current_packer->pack_uint64(yyvsp[-2].u.uint64); @@ -1764,7 +1769,7 @@ case 98: } break; case 99: -#line 718 "dcParser.yxx" +#line 723 "dcParser.yxx" { for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) { current_packer->pack_double(yyvsp[-2].u.real); @@ -1772,7 +1777,7 @@ case 99: } break; case 100: -#line 724 "dcParser.yxx" +#line 729 "dcParser.yxx" { for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) { current_packer->pack_literal_value(yyvsp[-2].str); @@ -1780,199 +1785,199 @@ case 100: } break; case 107: -#line 748 "dcParser.yxx" +#line 753 "dcParser.yxx" { yyval.u.subatomic = ST_int8; } break; case 108: -#line 752 "dcParser.yxx" +#line 757 "dcParser.yxx" { yyval.u.subatomic = ST_int16; } break; case 109: -#line 756 "dcParser.yxx" +#line 761 "dcParser.yxx" { yyval.u.subatomic = ST_int32; } break; case 110: -#line 760 "dcParser.yxx" +#line 765 "dcParser.yxx" { yyval.u.subatomic = ST_int64; } break; case 111: -#line 764 "dcParser.yxx" +#line 769 "dcParser.yxx" { yyval.u.subatomic = ST_uint8; } break; case 112: -#line 768 "dcParser.yxx" +#line 773 "dcParser.yxx" { yyval.u.subatomic = ST_uint16; } break; case 113: -#line 772 "dcParser.yxx" +#line 777 "dcParser.yxx" { yyval.u.subatomic = ST_uint32; } break; case 114: -#line 776 "dcParser.yxx" +#line 781 "dcParser.yxx" { yyval.u.subatomic = ST_uint64; } break; case 115: -#line 780 "dcParser.yxx" +#line 785 "dcParser.yxx" { yyval.u.subatomic = ST_float64; } break; case 116: -#line 784 "dcParser.yxx" +#line 789 "dcParser.yxx" { yyval.u.subatomic = ST_string; } break; case 117: -#line 788 "dcParser.yxx" +#line 793 "dcParser.yxx" { yyval.u.subatomic = ST_blob; } break; case 118: -#line 792 "dcParser.yxx" +#line 797 "dcParser.yxx" { yyval.u.subatomic = ST_blob32; } break; case 119: -#line 796 "dcParser.yxx" +#line 801 "dcParser.yxx" { yyval.u.subatomic = ST_int8array; } break; case 120: -#line 800 "dcParser.yxx" +#line 805 "dcParser.yxx" { yyval.u.subatomic = ST_int16array; } break; case 121: -#line 804 "dcParser.yxx" +#line 809 "dcParser.yxx" { yyval.u.subatomic = ST_int32array; } break; case 122: -#line 808 "dcParser.yxx" +#line 813 "dcParser.yxx" { yyval.u.subatomic = ST_uint8array; } break; case 123: -#line 812 "dcParser.yxx" +#line 817 "dcParser.yxx" { yyval.u.subatomic = ST_uint16array; } break; case 124: -#line 816 "dcParser.yxx" +#line 821 "dcParser.yxx" { yyval.u.subatomic = ST_uint32array; } break; case 125: -#line 820 "dcParser.yxx" +#line 825 "dcParser.yxx" { yyval.u.subatomic = ST_uint32uint8array; } break; case 126: -#line 824 "dcParser.yxx" +#line 829 "dcParser.yxx" { yyval.u.subatomic = ST_char; } break; case 127: -#line 831 "dcParser.yxx" +#line 836 "dcParser.yxx" { yyval.u.s_int = 0; } break; case 128: -#line 835 "dcParser.yxx" +#line 840 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_required; } break; case 129: -#line 839 "dcParser.yxx" +#line 844 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_broadcast; } break; case 130: -#line 843 "dcParser.yxx" +#line 848 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_p2p; } break; case 131: -#line 847 "dcParser.yxx" +#line 852 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_ram; } break; case 132: -#line 851 "dcParser.yxx" +#line 856 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_db; } break; case 133: -#line 855 "dcParser.yxx" +#line 860 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_clsend; } break; case 134: -#line 859 "dcParser.yxx" +#line 864 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_clrecv; } break; case 135: -#line 863 "dcParser.yxx" +#line 868 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_ownsend; } break; case 136: -#line 867 "dcParser.yxx" +#line 872 "dcParser.yxx" { yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_airecv; } break; case 137: -#line 874 "dcParser.yxx" +#line 879 "dcParser.yxx" { current_molecular = new DCMolecularField(yyvsp[-1].str); } break; case 138: -#line 878 "dcParser.yxx" +#line 883 "dcParser.yxx" { yyval.u.field = current_molecular; } break; case 139: -#line 885 "dcParser.yxx" +#line 890 "dcParser.yxx" { DCField *field = current_class->get_field_by_name(yyvsp[0].str); yyval.u.atomic = (DCAtomicField *)NULL; @@ -1987,7 +1992,7 @@ case 139: } break; case 140: -#line 901 "dcParser.yxx" +#line 906 "dcParser.yxx" { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { current_molecular->add_atomic(yyvsp[0].u.atomic); @@ -1995,7 +2000,7 @@ case 140: } break; case 141: -#line 907 "dcParser.yxx" +#line 912 "dcParser.yxx" { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { current_molecular->add_atomic(yyvsp[0].u.atomic); @@ -2008,27 +2013,27 @@ case 141: } break; case 142: -#line 921 "dcParser.yxx" +#line 926 "dcParser.yxx" { yyval.str = ""; } break; case 144: -#line 929 "dcParser.yxx" +#line 934 "dcParser.yxx" { yyval.u.dswitch = current_switch; current_switch = new DCSwitch(yyvsp[-4].str, yyvsp[-2].u.parameter); } break; case 145: -#line 934 "dcParser.yxx" +#line 939 "dcParser.yxx" { yyval.u.dswitch = current_switch; current_switch = (DCSwitch *)yyvsp[-2].u.parameter; } break; case 149: -#line 946 "dcParser.yxx" +#line 951 "dcParser.yxx" { if (current_switch->get_num_cases() == 0) { yyerror("case declaration required before first element"); @@ -2038,7 +2043,7 @@ case 149: } break; case 150: -#line 957 "dcParser.yxx" +#line 962 "dcParser.yxx" { current_packer = &default_packer; current_packer->clear_data(); @@ -2046,7 +2051,7 @@ case 150: } break; case 151: -#line 963 "dcParser.yxx" +#line 968 "dcParser.yxx" { if (!current_packer->end_pack()) { yyerror("Invalid value for switch parameter"); @@ -2056,13 +2061,13 @@ case 151: } break; case 152: -#line 974 "dcParser.yxx" +#line 979 "dcParser.yxx" { yyval.u.field = yyvsp[-1].u.parameter; } break; case 153: -#line 978 "dcParser.yxx" +#line 983 "dcParser.yxx" { yyval.u.field = yyvsp[0].u.parameter; } @@ -2300,4 +2305,4 @@ yyreturn: #endif return yyresult; } -#line 986 "dcParser.yxx" +#line 991 "dcParser.yxx" diff --git a/direct/src/dcparser/dcParser.yxx b/direct/src/dcparser/dcParser.yxx index a8d9d9ebc8..9b2dce5957 100644 --- a/direct/src/dcparser/dcParser.yxx +++ b/direct/src/dcparser/dcParser.yxx @@ -202,6 +202,7 @@ dclass_name: { DCClass *dclass = dc_file->get_class_by_name($1); if (dclass == (DCClass *)NULL) { + // Create a bogus class as a forward reference. dclass = new DCClass($1, false, true); dc_file->add_class(dclass); } @@ -474,10 +475,14 @@ type_name: } | dclass { + // This is an inline class definition. + dc_file->add_thing_to_delete($1); $$ = new DCClassParameter($1); } | switch { + // This is an inline switch definition. + dc_file->add_thing_to_delete($1); $$ = new DCSwitchParameter($1); } ; diff --git a/direct/src/dcparser/dcSimpleParameter.cxx b/direct/src/dcparser/dcSimpleParameter.cxx index 547c976286..0eaa464393 100644 --- a/direct/src/dcparser/dcSimpleParameter.cxx +++ b/direct/src/dcparser/dcSimpleParameter.cxx @@ -312,6 +312,8 @@ set_range(const DCDoubleRange &range) { int num_ranges = range.get_num_ranges(); int i; + _has_range_limits = (num_ranges != 0); + switch (_type) { case ST_int8: case ST_int8array: @@ -1713,7 +1715,10 @@ unpack_string(const char *data, size_t length, size_t &p, string &value, //////////////////////////////////////////////////////////////////// bool DCSimpleParameter:: unpack_validate(const char *data, size_t length, size_t &p, - bool &pack_error, bool &range_error) const { + bool &pack_error, bool &range_error) const { + if (!_has_range_limits) { + return unpack_skip(data, length, p, pack_error); + } switch (_type) { case ST_int8: { @@ -1871,7 +1876,8 @@ unpack_validate(const char *data, size_t length, size_t &p, // failure (e.g. we don't know how to skip this field). //////////////////////////////////////////////////////////////////// bool DCSimpleParameter:: -unpack_skip(const char *data, size_t length, size_t &p) const { +unpack_skip(const char *data, size_t length, size_t &p, + bool &pack_error) const { size_t string_length; switch (_type) { @@ -1929,7 +1935,7 @@ unpack_skip(const char *data, size_t length, size_t &p) const { } if (p > length) { - return false; + pack_error = true; } return true; @@ -2046,7 +2052,7 @@ generate_hash(HashGenerator &hashgen) const { //////////////////////////////////////////////////////////////////// DCSimpleParameter *DCSimpleParameter:: create_nested_field(DCSubatomicType type, unsigned int divisor) { - DivisorMap divisor_map = _nested_field_map[type]; + DivisorMap &divisor_map = _nested_field_map[type]; DivisorMap::iterator di; di = divisor_map.find(divisor); if (di != divisor_map.end()) { diff --git a/direct/src/dcparser/dcSimpleParameter.h b/direct/src/dcparser/dcSimpleParameter.h index bdb6498ba7..bcef313aae 100644 --- a/direct/src/dcparser/dcSimpleParameter.h +++ b/direct/src/dcparser/dcSimpleParameter.h @@ -80,7 +80,8 @@ public: string &value, bool &pack_error, bool &range_error) const; virtual bool unpack_validate(const char *data, size_t length, size_t &p, bool &pack_error, bool &range_error) const; - virtual bool unpack_skip(const char *data, size_t length, size_t &p) const; + virtual bool unpack_skip(const char *data, size_t length, size_t &p, + bool &pack_error) const; virtual void output_instance(ostream &out, bool brief, const string &prename, const string &name, const string &postname) const; diff --git a/direct/src/dcparser/dcSwitch.cxx b/direct/src/dcparser/dcSwitch.cxx index 8c91efc4de..c970aeb987 100644 --- a/direct/src/dcparser/dcSwitch.cxx +++ b/direct/src/dcparser/dcSwitch.cxx @@ -378,6 +378,29 @@ SwitchCase(const string &name, const string &value) : _has_fixed_byte_size = true; _fixed_byte_size = 0; _has_fixed_structure = true; + _has_range_limits = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCSwitch::SwitchCase::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +DCSwitch::SwitchCase:: +~SwitchCase() { + Fields::iterator fi = _fields.begin(); + + // Be careful not to delete the _key_parameter, which is added to + // the beginning of each case. + nassertv(fi != _fields.end()); + ++fi; + + // But we do want to delete all of the other fields. + while (fi != _fields.end()) { + delete (*fi); + ++fi; + } + _fields.clear(); } //////////////////////////////////////////////////////////////////// @@ -423,5 +446,8 @@ add_field(DCField *field) { if (_has_fixed_structure) { _has_fixed_structure = field->has_fixed_structure(); } + if (!_has_range_limits) { + _has_range_limits = field->has_range_limits(); + } return true; } diff --git a/direct/src/dcparser/dcSwitch.h b/direct/src/dcparser/dcSwitch.h index f1bff04117..192f1f3697 100644 --- a/direct/src/dcparser/dcSwitch.h +++ b/direct/src/dcparser/dcSwitch.h @@ -78,6 +78,7 @@ private: class SwitchCase : public DCPackerInterface { public: SwitchCase(const string &name, const string &value); + ~SwitchCase(); virtual DCPackerInterface *get_nested_field(int n) const; bool add_field(DCField *field); diff --git a/direct/src/dcparser/dcSwitchParameter.cxx b/direct/src/dcparser/dcSwitchParameter.cxx index c368d844f5..7054819b6b 100755 --- a/direct/src/dcparser/dcSwitchParameter.cxx +++ b/direct/src/dcparser/dcSwitchParameter.cxx @@ -26,12 +26,13 @@ // Description: //////////////////////////////////////////////////////////////////// DCSwitchParameter:: -DCSwitchParameter(DCSwitch *dswitch) : +DCSwitchParameter(const DCSwitch *dswitch) : _dswitch(dswitch) { set_name(dswitch->get_name()); - _has_fixed_byte_size = false; + _has_fixed_byte_size = true; + _fixed_byte_size = 0; _has_fixed_structure = false; // The DCSwitch presents just one nested field initially, which is @@ -44,30 +45,27 @@ DCSwitchParameter(DCSwitch *dswitch) : _pack_type = PT_switch; DCParameter *key_parameter = dswitch->get_key_parameter(); - if (key_parameter->has_fixed_byte_size()) { - // See if we have a fixed byte size for the overall switch. This - // will be true only if all of the individual cases have the same - // fixed byte size. - int num_cases = _dswitch->get_num_cases(); - _has_fixed_byte_size = true; - _fixed_byte_size = 0; + _has_fixed_byte_size = _has_fixed_byte_size && key_parameter->has_fixed_byte_size(); + _has_range_limits = _has_range_limits || key_parameter->has_range_limits(); - if (num_cases > 0) { - _fixed_byte_size = _dswitch->get_case(0)->get_fixed_byte_size(); - - for (int i = 0; i < num_cases && _has_fixed_byte_size; i++) { - const DCPackerInterface *dcase = _dswitch->get_case(i); - if (!dcase->has_fixed_byte_size() || - dcase->get_fixed_byte_size() != _fixed_byte_size) { - - // Nope, we have a variable byte size. - _has_fixed_byte_size = false; - } + int num_cases = _dswitch->get_num_cases(); + if (num_cases > 0) { + _fixed_byte_size = _dswitch->get_case(0)->get_fixed_byte_size(); + + for (int i = 0; i < num_cases; i++) { + const DCPackerInterface *dcase = _dswitch->get_case(i); + if (!dcase->has_fixed_byte_size() || + dcase->get_fixed_byte_size() != _fixed_byte_size) { + + // Nope, we have a variable byte size. + _has_fixed_byte_size = false; } - } - _fixed_byte_size += key_parameter->get_fixed_byte_size(); + _has_range_limits = _has_range_limits || dcase->has_range_limits(); + } } + + _fixed_byte_size += key_parameter->get_fixed_byte_size(); } //////////////////////////////////////////////////////////////////// @@ -119,7 +117,7 @@ is_valid() const { // Access: Published // Description: Returns the switch object this parameter represents. //////////////////////////////////////////////////////////////////// -DCSwitch *DCSwitchParameter:: +const DCSwitch *DCSwitchParameter:: get_switch() const { return _dswitch; } diff --git a/direct/src/dcparser/dcSwitchParameter.h b/direct/src/dcparser/dcSwitchParameter.h index 30de81ff59..190c4d885c 100755 --- a/direct/src/dcparser/dcSwitchParameter.h +++ b/direct/src/dcparser/dcSwitchParameter.h @@ -32,7 +32,7 @@ class DCSwitch; //////////////////////////////////////////////////////////////////// class EXPCL_DIRECT DCSwitchParameter : public DCParameter { public: - DCSwitchParameter(DCSwitch *dswitch); + DCSwitchParameter(const DCSwitch *dswitch); DCSwitchParameter(const DCSwitchParameter ©); PUBLISHED: @@ -40,7 +40,7 @@ PUBLISHED: virtual DCParameter *make_copy() const; virtual bool is_valid() const; - DCSwitch *get_switch() const; + const DCSwitch *get_switch() const; public: virtual DCPackerInterface *get_nested_field(int n) const; @@ -55,7 +55,7 @@ public: virtual void generate_hash(HashGenerator &hashgen) const; private: - DCSwitch *_dswitch; + const DCSwitch *_dswitch; }; #endif diff --git a/direct/src/dcparser/dcTypedef.cxx b/direct/src/dcparser/dcTypedef.cxx index 8746f45ce2..6465b82de2 100644 --- a/direct/src/dcparser/dcTypedef.cxx +++ b/direct/src/dcparser/dcTypedef.cxx @@ -24,7 +24,9 @@ //////////////////////////////////////////////////////////////////// // Function: DCTypedef::Constructor // Access: Public -// Description: +// Description: The DCTypedef object becomes the owner of the +// supplied parameter pointer and will delete it upon +// destruction. //////////////////////////////////////////////////////////////////// DCTypedef:: DCTypedef(DCParameter *parameter, bool implicit) :