diff --git a/direct/src/dcparser/dcArrayParameter.cxx b/direct/src/dcparser/dcArrayParameter.cxx index 9cdac824b3..1d7780c212 100644 --- a/direct/src/dcparser/dcArrayParameter.cxx +++ b/direct/src/dcparser/dcArrayParameter.cxx @@ -25,19 +25,28 @@ // Description: //////////////////////////////////////////////////////////////////// DCArrayParameter:: -DCArrayParameter(DCParameter *element_type, int array_size) : +DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size) : _element_type(element_type), - _array_size(array_size) + _array_size_range(size) { set_name(_element_type->get_name()); _element_type->set_name(string()); + _array_size = -1; + if (_array_size_range.has_one_value()) { + _array_size = _array_size_range.get_one_value(); + } + 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(); + + } else { + // We only need to store the length bytes if the array has a + // variable size. + _num_length_bytes = 2; } - _num_length_bytes = 2; _has_nested_fields = true; _num_nested_fields = _array_size; _pack_type = PT_array; @@ -52,7 +61,8 @@ DCArrayParameter:: DCArrayParameter(const DCArrayParameter ©) : DCParameter(copy), _element_type(copy._element_type->make_copy()), - _array_size(copy._array_size) + _array_size(copy._array_size), + _array_size_range(copy._array_size_range) { } @@ -113,7 +123,7 @@ get_element_type() const { // 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 +// or -1 if the array may contain a variable number of // elements. //////////////////////////////////////////////////////////////////// int DCArrayParameter:: @@ -152,6 +162,24 @@ get_nested_field(int) const { return _element_type; } +//////////////////////////////////////////////////////////////////// +// Function: DCArrayParameter::validate_num_nested_fields +// Access: Public, Virtual +// Description: After a number of fields have been packed via push() +// .. pack_*() .. pop(), this is called to confirm that +// the number of nested fields that were added is valid +// for this type. This is primarily useful for array +// types with dynamic ranges that can't validate the +// number of fields any other way. +//////////////////////////////////////////////////////////////////// +bool DCArrayParameter:: +validate_num_nested_fields(int num_nested_fields) const { + bool range_error = false; + _array_size_range.validate(num_nested_fields, range_error); + + return !range_error; +} + //////////////////////////////////////////////////////////////////// // Function: DCArrayParameter::output_instance // Access: Public, Virtual @@ -167,11 +195,9 @@ output_instance(ostream &out, const string &prename, const string &name, } else { ostringstream strm; - if (_array_size >= 0) { - strm << "[" << _array_size << "]"; - } else { - strm << "[]"; - } + strm << "["; + _array_size_range.output(strm); + strm << "]"; _element_type->output_instance(out, prename, name, strm.str() + postname); } @@ -187,5 +213,5 @@ void DCArrayParameter:: generate_hash(HashGenerator &hashgen) const { DCParameter::generate_hash(hashgen); _element_type->generate_hash(hashgen); - hashgen.add_int(_array_size); + _array_size_range.generate_hash(hashgen); } diff --git a/direct/src/dcparser/dcArrayParameter.h b/direct/src/dcparser/dcArrayParameter.h index 0e8612b163..2063f80110 100644 --- a/direct/src/dcparser/dcArrayParameter.h +++ b/direct/src/dcparser/dcArrayParameter.h @@ -21,6 +21,7 @@ #include "dcbase.h" #include "dcParameter.h" +#include "dcNumericRange.h" //////////////////////////////////////////////////////////////////// // Class : DCArrayParameter @@ -31,7 +32,8 @@ //////////////////////////////////////////////////////////////////// class EXPCL_DIRECT DCArrayParameter : public DCParameter { public: - DCArrayParameter(DCParameter *element_type, int array_size = -1); + DCArrayParameter(DCParameter *element_type, + const DCUnsignedIntRange &size = DCUnsignedIntRange()); DCArrayParameter(const DCArrayParameter ©); virtual ~DCArrayParameter(); @@ -46,6 +48,7 @@ PUBLISHED: public: virtual int calc_num_nested_fields(size_t length_bytes) const; virtual DCPackerInterface *get_nested_field(int n) const; + virtual bool validate_num_nested_fields(int num_nested_fields) const; virtual void output_instance(ostream &out, const string &prename, const string &name, const string &postname) const; @@ -54,6 +57,7 @@ public: private: DCParameter *_element_type; int _array_size; + DCUnsignedIntRange _array_size_range; }; #endif diff --git a/direct/src/dcparser/dcNumericRange.I b/direct/src/dcparser/dcNumericRange.I index c71ae5743d..7d861a9ba6 100644 --- a/direct/src/dcparser/dcNumericRange.I +++ b/direct/src/dcparser/dcNumericRange.I @@ -90,16 +90,41 @@ is_in_range(Number num) const { // Description: Convenience function to validate the indicated // number. If the number is within the specified range, // does nothing; otherwise, if it is outside the range, -// sets validation_error to true. +// sets range_error to true. //////////////////////////////////////////////////////////////////// template INLINE void DCNumericRange:: -validate(Number num, bool &validation_error) const { +validate(Number num, bool &range_error) const { if (!is_in_range(num)) { - validation_error = true; + range_error = true; } } +//////////////////////////////////////////////////////////////////// +// Function: DCNumericRange::has_one_value +// Access: Public +// Description: Returns true if the numeric range specifies exactly +// one legal value, false if multiple values are legal. +//////////////////////////////////////////////////////////////////// +template +INLINE bool DCNumericRange:: +has_one_value() const { + return _ranges.size() == 1 && _ranges[0]._min == _ranges[0]._max; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCNumericRange::get_one_value +// Access: Public +// Description: If has_one_value() returns true, this returns the one +// legal value accepted by the numeric range. +//////////////////////////////////////////////////////////////////// +template +INLINE DCNumericRange::Number DCNumericRange:: +get_one_value() const { + nassertr(has_one_value(), 0); + return _ranges[0]._min; +} + //////////////////////////////////////////////////////////////////// // Function: DCNumericRange::generate_hash // Access: Public diff --git a/direct/src/dcparser/dcNumericRange.h b/direct/src/dcparser/dcNumericRange.h index f5257fbb24..7744431054 100644 --- a/direct/src/dcparser/dcNumericRange.h +++ b/direct/src/dcparser/dcNumericRange.h @@ -39,7 +39,10 @@ public: INLINE void operator = (const DCNumericRange ©); bool is_in_range(Number num) const; - INLINE void validate(Number num, bool &validation_error) const; + INLINE void validate(Number num, bool &range_error) const; + + INLINE bool has_one_value() const; + INLINE Number get_one_value() const; void generate_hash(HashGenerator &hashgen) const; diff --git a/direct/src/dcparser/dcPacker.cxx b/direct/src/dcparser/dcPacker.cxx index 83952c6fa8..93134442d9 100755 --- a/direct/src/dcparser/dcPacker.cxx +++ b/direct/src/dcparser/dcPacker.cxx @@ -463,6 +463,11 @@ pop() { _pack_error = true; } else { + if (!_current_parent->validate_num_nested_fields(_current_field_index)) { + // Incorrect number of nested elements. + _pack_error = true; + } + if (_mode == M_pack || _mode == M_repack) { size_t length_bytes = _current_parent->get_num_length_bytes(); if (length_bytes != 0) { diff --git a/direct/src/dcparser/dcPackerInterface.cxx b/direct/src/dcparser/dcPackerInterface.cxx index 9c1422b80c..f76d2f691c 100755 --- a/direct/src/dcparser/dcPackerInterface.cxx +++ b/direct/src/dcparser/dcPackerInterface.cxx @@ -95,6 +95,21 @@ get_nested_field(int n) const { return NULL; } +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::validate_num_nested_fields +// Access: Public, Virtual +// Description: After a number of fields have been packed via push() +// .. pack_*() .. pop(), this is called to confirm that +// the number of nested fields that were added is valid +// for this type. This is primarily useful for array +// types with dynamic ranges that can't validate the +// number of fields any other way. +//////////////////////////////////////////////////////////////////// +bool DCPackerInterface:: +validate_num_nested_fields(int) const { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_double // Access: Public, Virtual diff --git a/direct/src/dcparser/dcPackerInterface.h b/direct/src/dcparser/dcPackerInterface.h index 4ed421bf30..d611af7ec4 100755 --- a/direct/src/dcparser/dcPackerInterface.h +++ b/direct/src/dcparser/dcPackerInterface.h @@ -81,6 +81,8 @@ public: virtual int calc_num_nested_fields(size_t length_bytes) const; virtual DCPackerInterface *get_nested_field(int n) const; + virtual bool validate_num_nested_fields(int num_nested_fields) const; + INLINE DCPackType get_pack_type() const; virtual void pack_double(DCPackData &pack_data, double value, diff --git a/direct/src/dcparser/dcParser.cxx.prebuilt b/direct/src/dcparser/dcParser.cxx.prebuilt index ad14c478db..b65624d5f8 100644 --- a/direct/src/dcparser/dcParser.cxx.prebuilt +++ b/direct/src/dcparser/dcParser.cxx.prebuilt @@ -83,6 +83,7 @@ static DCParameter *current_parameter = (DCParameter *)NULL; static DCPacker default_packer; static DCPacker *current_packer; static DCDoubleRange double_range; +static DCUnsignedIntRange uint_range; //////////////////////////////////////////////////////////////////// // Defining the interface to the parser. @@ -114,12 +115,12 @@ dc_cleanup_parser() { -#define YYFINAL 177 +#define YYFINAL 185 #define YYFLAG -32768 #define YYNTBASE 57 /* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 102) +#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 103) /* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ static const char yytranslate[] = @@ -165,52 +166,54 @@ static const short yyprhs[] = 83, 86, 89, 92, 96, 99, 100, 107, 109, 111, 113, 115, 119, 121, 122, 127, 128, 132, 134, 136, 138, 140, 145, 149, 156, 163, 165, 167, 169, 173, - 176, 180, 186, 191, 193, 197, 202, 204, 208, 212, - 217, 219, 221, 223, 225, 227, 229, 230, 235, 236, - 241, 242, 247, 251, 255, 259, 261, 264, 266, 268, - 270, 274, 276, 278, 280, 282, 284, 286, 288, 290, - 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, - 312, 314, 317, 320, 323, 326, 329, 332, 335, 338, - 341, 342, 347, 349, 353 + 176, 180, 186, 191, 193, 195, 199, 202, 206, 212, + 217, 219, 224, 226, 230, 235, 237, 239, 241, 243, + 245, 247, 248, 253, 254, 259, 260, 265, 269, 273, + 277, 279, 282, 284, 286, 288, 292, 294, 296, 298, + 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, + 320, 322, 324, 326, 328, 330, 332, 335, 338, 341, + 344, 347, 350, 353, 356, 359, 360, 365, 367, 371 }; static const short yyrhs[] = { - 41, 58, 0, 42, 89, 0, 101, 0, 58, 43, + 41, 58, 0, 42, 90, 0, 102, 0, 58, 43, 0, 58, 59, 0, 58, 65, 0, 58, 69, 0, 0, 61, 7, 60, 70, 44, 72, 45, 0, 9, 0, 8, 0, 7, 0, 7, 0, 63, 46, 7, 0, 63, 0, 64, 47, 63, 0, 11, 64, 0, 0, 10, 64, 11, 66, 67, 0, 68, 0, 48, 0, 63, 0, 68, 49, 63, 0, 12, 83, 0, - 101, 0, 50, 71, 0, 62, 0, 71, 49, 62, - 0, 101, 0, 72, 43, 0, 72, 73, 0, 72, - 98, 0, 72, 82, 43, 0, 72, 80, 0, 0, - 7, 51, 74, 76, 52, 97, 0, 7, 0, 101, + 102, 0, 50, 71, 0, 62, 0, 71, 49, 62, + 0, 102, 0, 72, 43, 0, 72, 73, 0, 72, + 99, 0, 72, 82, 43, 0, 72, 80, 0, 0, + 7, 51, 74, 76, 52, 98, 0, 7, 0, 102, 0, 77, 0, 78, 0, 77, 49, 78, 0, 83, - 0, 0, 83, 53, 79, 89, 0, 0, 86, 81, - 87, 0, 86, 0, 80, 0, 82, 0, 96, 0, - 96, 51, 85, 52, 0, 96, 46, 3, 0, 96, - 46, 3, 51, 85, 52, 0, 96, 51, 85, 52, - 46, 3, 0, 7, 0, 101, 0, 88, 0, 88, - 54, 88, 0, 88, 88, 0, 85, 49, 88, 0, - 85, 49, 88, 54, 88, 0, 85, 49, 88, 88, - 0, 84, 0, 86, 55, 56, 0, 86, 55, 3, - 56, 0, 7, 0, 87, 46, 3, 0, 87, 55, - 56, 0, 87, 55, 3, 56, 0, 3, 0, 4, - 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, - 44, 90, 93, 45, 0, 0, 55, 91, 93, 56, - 0, 0, 51, 92, 93, 52, 0, 3, 48, 3, - 0, 4, 48, 3, 0, 6, 48, 3, 0, 94, - 0, 95, 94, 0, 101, 0, 49, 0, 89, 0, - 95, 49, 89, 0, 13, 0, 14, 0, 15, 0, - 16, 0, 17, 0, 18, 0, 19, 0, 20, 0, - 21, 0, 22, 0, 23, 0, 24, 0, 25, 0, - 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, - 31, 0, 101, 0, 97, 32, 0, 97, 33, 0, - 97, 34, 0, 97, 35, 0, 97, 36, 0, 97, - 37, 0, 97, 38, 0, 97, 39, 0, 97, 40, - 0, 0, 7, 50, 99, 100, 0, 75, 0, 100, - 49, 75, 0, 0 + 0, 0, 83, 53, 79, 90, 0, 0, 87, 81, + 88, 0, 87, 0, 80, 0, 82, 0, 97, 0, + 97, 51, 85, 52, 0, 97, 46, 3, 0, 97, + 46, 3, 51, 85, 52, 0, 97, 51, 85, 52, + 46, 3, 0, 7, 0, 102, 0, 89, 0, 89, + 54, 89, 0, 89, 89, 0, 85, 49, 89, 0, + 85, 49, 89, 54, 89, 0, 85, 49, 89, 89, + 0, 102, 0, 3, 0, 3, 54, 3, 0, 3, + 3, 0, 86, 49, 3, 0, 86, 49, 3, 54, + 3, 0, 86, 49, 3, 3, 0, 84, 0, 87, + 55, 86, 56, 0, 7, 0, 88, 46, 3, 0, + 88, 55, 86, 56, 0, 3, 0, 4, 0, 3, + 0, 4, 0, 5, 0, 6, 0, 0, 44, 91, + 94, 45, 0, 0, 55, 92, 94, 56, 0, 0, + 51, 93, 94, 52, 0, 3, 48, 3, 0, 4, + 48, 3, 0, 6, 48, 3, 0, 95, 0, 96, + 95, 0, 102, 0, 49, 0, 90, 0, 96, 49, + 90, 0, 13, 0, 14, 0, 15, 0, 16, 0, + 17, 0, 18, 0, 19, 0, 20, 0, 21, 0, + 22, 0, 23, 0, 24, 0, 25, 0, 26, 0, + 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, + 102, 0, 98, 32, 0, 98, 33, 0, 98, 34, + 0, 98, 35, 0, 98, 36, 0, 98, 37, 0, + 98, 38, 0, 98, 39, 0, 98, 40, 0, 0, + 7, 50, 100, 101, 0, 75, 0, 101, 49, 75, + 0, 0 }; #endif @@ -219,19 +222,19 @@ static const short yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const short yyrline[] = { - 0, 126, 128, 131, 133, 134, 135, 136, 139, 139, - 155, 160, 166, 179, 181, 187, 189, 195, 200, 200, - 207, 209, 215, 220, 226, 242, 244, 247, 254, 262, - 264, 265, 266, 267, 271, 279, 279, 290, 306, 308, - 311, 313, 316, 322, 322, 346, 346, 357, 361, 363, - 366, 371, 379, 390, 404, 418, 439, 444, 451, 458, - 468, 474, 480, 491, 493, 497, 503, 509, 523, 527, - 533, 538, 541, 546, 550, 554, 558, 558, 566, 566, - 574, 574, 582, 588, 594, 602, 604, 607, 609, 612, - 614, 617, 622, 626, 630, 634, 638, 642, 646, 650, - 654, 658, 662, 666, 670, 674, 678, 682, 686, 690, - 696, 698, 702, 706, 710, 714, 718, 722, 726, 730, - 736, 736, 747, 754, 767 + 0, 127, 129, 132, 134, 135, 136, 137, 140, 140, + 156, 161, 167, 180, 182, 188, 190, 196, 201, 201, + 208, 210, 216, 221, 227, 243, 245, 248, 255, 263, + 265, 266, 267, 268, 272, 280, 280, 291, 307, 309, + 312, 314, 317, 323, 323, 347, 347, 358, 362, 364, + 367, 372, 380, 391, 405, 419, 440, 445, 452, 459, + 468, 474, 480, 490, 495, 506, 517, 528, 536, 544, + 556, 558, 564, 570, 584, 590, 595, 598, 603, 607, + 611, 615, 615, 623, 623, 631, 631, 639, 645, 651, + 659, 661, 664, 666, 669, 671, 674, 679, 683, 687, + 691, 695, 699, 703, 707, 711, 715, 719, 723, 727, + 731, 735, 739, 743, 747, 753, 755, 759, 763, 767, + 771, 775, 779, 783, 787, 793, 793, 804, 811, 824 }; #endif @@ -257,10 +260,10 @@ static const char *const yytname[] = "dclass_derivation", "base_list", "dclass_fields", "atomic_field", "@3", "atomic_name", "parameter_list", "nonempty_parameter_list", "atomic_element", "@4", "named_parameter", "@5", "unnamed_parameter", - "parameter", "type_name", "double_range", "type_definition", - "parameter_definition", "number", "parameter_value", "@6", "@7", "@8", - "array", "maybe_comma", "array_def", "type_token", "atomic_flags", - "molecular_field", "@9", "molecular_atom_list", "empty", 0 + "parameter", "type_name", "double_range", "uint_range", + "type_definition", "parameter_definition", "number", "parameter_value", + "@6", "@7", "@8", "array", "maybe_comma", "array_def", "type_token", + "atomic_flags", "molecular_field", "@9", "molecular_atom_list", "empty", 0 }; #endif @@ -273,13 +276,13 @@ static const short yyr1[] = 72, 72, 72, 72, 72, 74, 73, 75, 76, 76, 77, 77, 78, 79, 78, 81, 80, 82, 83, 83, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, - 85, 85, 85, 86, 86, 86, 87, 87, 87, 87, - 88, 88, 89, 89, 89, 89, 90, 89, 91, 89, - 92, 89, 89, 89, 89, 93, 93, 94, 94, 95, - 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 85, 85, 85, 86, 86, 86, 86, 86, 86, 86, + 87, 87, 88, 88, 88, 89, 89, 90, 90, 90, + 90, 91, 90, 92, 90, 93, 90, 90, 90, 90, + 94, 94, 95, 95, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 99, 98, 100, 100, 101 + 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 100, 99, 101, 101, 102 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -291,13 +294,13 @@ static const short yyr2[] = 2, 2, 2, 3, 2, 0, 6, 1, 1, 1, 1, 3, 1, 0, 4, 0, 3, 1, 1, 1, 1, 4, 3, 6, 6, 1, 1, 1, 3, 2, - 3, 5, 4, 1, 3, 4, 1, 3, 3, 4, - 1, 1, 1, 1, 1, 1, 0, 4, 0, 4, - 0, 4, 3, 3, 3, 1, 2, 1, 1, 1, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 5, 4, 1, 1, 3, 2, 3, 5, 4, + 1, 4, 1, 3, 4, 1, 1, 1, 1, 1, + 1, 0, 4, 0, 4, 0, 4, 3, 3, 3, + 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 4, 1, 3, 0 + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 4, 1, 3, 0 }; /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE @@ -305,110 +308,116 @@ static const short yyr2[] = error. */ static const short yydefact[] = { - 0, 124, 0, 1, 3, 72, 73, 74, 75, 76, - 80, 78, 2, 11, 10, 0, 0, 0, 4, 5, - 0, 6, 7, 0, 0, 0, 124, 124, 124, 13, - 15, 0, 17, 55, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 48, 49, 24, 63, 47, 50, 8, - 82, 83, 84, 88, 89, 0, 85, 124, 87, 0, - 0, 0, 18, 0, 0, 0, 0, 124, 124, 77, - 88, 86, 81, 79, 14, 0, 16, 0, 64, 66, - 46, 52, 70, 71, 0, 57, 56, 0, 0, 25, - 90, 21, 22, 19, 20, 65, 0, 0, 124, 0, - 51, 0, 59, 12, 27, 26, 124, 0, 67, 0, - 68, 0, 60, 0, 58, 0, 0, 29, 23, 69, - 53, 0, 62, 54, 28, 55, 30, 9, 31, 34, - 0, 32, 61, 120, 35, 33, 0, 124, 37, 122, - 121, 0, 39, 40, 42, 38, 0, 124, 0, 43, - 123, 36, 110, 41, 0, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 44, 0, 0, 0 + 0, 129, 0, 1, 3, 77, 78, 79, 80, 81, + 85, 83, 2, 11, 10, 0, 0, 0, 4, 5, + 0, 6, 7, 0, 0, 0, 129, 129, 129, 13, + 15, 0, 17, 55, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 48, 49, 24, 70, 47, 50, 8, + 87, 88, 89, 93, 94, 0, 90, 129, 92, 0, + 0, 0, 18, 0, 129, 0, 0, 129, 129, 82, + 93, 91, 86, 84, 14, 0, 16, 64, 0, 63, + 72, 46, 52, 75, 76, 0, 57, 56, 0, 0, + 25, 95, 21, 22, 19, 20, 66, 0, 0, 71, + 0, 129, 129, 0, 51, 0, 59, 12, 27, 26, + 129, 0, 65, 67, 73, 0, 0, 60, 0, 58, + 0, 0, 29, 23, 69, 0, 74, 53, 0, 62, + 54, 28, 55, 30, 9, 31, 34, 0, 32, 68, + 61, 125, 35, 33, 0, 129, 37, 127, 126, 0, + 39, 40, 42, 38, 0, 129, 0, 43, 128, 36, + 115, 41, 0, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 44, 0, 0, 0 }; static const short yydefgoto[] = { - 175, 3, 19, 78, 20, 114, 30, 31, 21, 85, - 103, 104, 22, 98, 115, 126, 138, 147, 149, 151, - 152, 153, 164, 53, 75, 54, 154, 56, 94, 57, - 90, 95, 64, 26, 28, 27, 65, 66, 67, 58, - 161, 141, 146, 150, 68 + 183, 3, 19, 78, 20, 118, 30, 31, 21, 85, + 104, 105, 22, 99, 119, 131, 145, 155, 157, 159, + 160, 161, 172, 53, 75, 54, 162, 56, 95, 88, + 57, 91, 96, 64, 26, 28, 27, 65, 66, 67, + 58, 169, 148, 154, 158, 68 }; static const short yypact[] = { - -3,-32768, 9, 25,-32768, -8, -4,-32768, 0,-32768, - -32768,-32768,-32768,-32768,-32768, 49, 49, 107,-32768,-32768, - 58,-32768,-32768, 63, 66, 67, 3, 3, 3,-32768, - 26, 12, 24,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 28,-32768, 7, 25,-32768, -21, -16,-32768, -8,-32768, + -32768,-32768,-32768,-32768,-32768, 16, 16, 111,-32768,-32768, + 50,-32768,-32768, 44, 51, 58, 1, 1, 1,-32768, + 18, 8, 30,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768, -6, -20,-32768, - -32768,-32768,-32768,-32768,-32768, 28,-32768, 27,-32768, 22, - 21, 93,-32768, 49, -1, 105, 112, 39, 89,-32768, - 9,-32768,-32768,-32768,-32768, 15, 26, 60,-32768,-32768, - -26, 90,-32768,-32768, -25, 7,-32768, 110, 75,-32768, - -32768,-32768, 26,-32768, 91,-32768, 139, 1, 39, 39, - 97, 39,-32768,-32768,-32768, 95,-32768, 49,-32768, 92, - -32768, -24, 13, 142,-32768, 110, 68,-32768, 26,-32768, - -32768, 39,-32768,-32768,-32768, -5,-32768,-32768,-32768,-32768, - 103,-32768,-32768,-32768,-32768,-32768, 140, 107,-32768,-32768, - 101, 99, 104,-32768, 102,-32768, 140,-32768, 107,-32768, - -32768, 69,-32768,-32768, 9,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768, 152, 154,-32768 + -32768,-32768,-32768,-32768,-32768,-32768,-32768, -6, -26,-32768, + -32768,-32768,-32768,-32768,-32768, 37,-32768, 34,-32768, 32, + 29, 79,-32768, 16, 103, 100, 105, 40, 59,-32768, + 7,-32768,-32768,-32768,-32768, 15, 18, -1, -28,-32768, + -32768, -29, 60,-32768,-32768, -11, 5,-32768, 108, 66, + -32768,-32768,-32768, 18,-32768, 63,-32768, 113, 117,-32768, + 118, 103, 40, 40, 77, 40,-32768,-32768,-32768, 94, + -32768, 16,-32768, 13,-32768, -25, -10, 11, 150,-32768, + 108, 74,-32768, 18,-32768, 151,-32768,-32768, 40,-32768, + -32768,-32768, 22,-32768,-32768,-32768,-32768, 115,-32768,-32768, + -32768,-32768,-32768,-32768, 148, 111,-32768,-32768, 107, 109, + 110,-32768, 116,-32768, 148,-32768, 111,-32768,-32768, 112, + -32768,-32768, 7,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768, 160, 162,-32768 }; static const short yypgoto[] = { - -32768,-32768,-32768,-32768,-32768, 31, -55, 141,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 4,-32768, - -32768, 5,-32768, 32,-32768, 35, 147,-32768, 57,-32768, - -32768, -90, -2,-32768,-32768,-32768, 23, 100,-32768,-32768, - -32768,-32768,-32768,-32768, 2 + -32768,-32768,-32768,-32768,-32768, 33, -55, 149,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 0,-32768, + -32768, 6,-32768, 35,-32768, 42, 154,-32768, 56, 64, + -32768,-32768, -67, -2,-32768,-32768,-32768, 47, 114,-32768, + -32768,-32768,-32768,-32768,-32768, 2 }; -#define YYLAST 167 +#define YYLAST 181 static const short yytable[] = { - 12, -45, 87, 4, 119, 112, 5, 6, 7, 8, - 92, 93, 5, 6, 7, 8, 92, 93, 86, 122, - 106, 124, 29, 72, 109, 109, 76, 110, 130, 107, - 102, 77, 132, 13, 14, 15, 16, 17, 1, 2, - 23, 142, 92, 93, 24, 143, 144, 9, 25, 74, - 69, 70, 63, 9, 10, 88, 29, 120, 11, 73, - 10, 111, 128, 101, 11, 59, 60, 131, 18, 61, - 62, 73, 71, 79, 82, 135, 80, 83, 100, 96, - 99, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 84, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 96, 136, 89, 137, 33, 91, 105, 113, 127, 116, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 97, - 117, 108, 118, 123, 125, 133, 145, 148, 129, 155, - 156, 157, 176, 158, 177, 159, 134, 32, 139, 162, - 160, 140, 174, 163, 55, 121, 0, 81 + 12, -45, 106, 4, 5, 6, 7, 8, 93, 94, + 5, 6, 7, 8, 93, 94, 134, 110, 86, 72, + 76, 108, 29, 29, 108, 77, 111, 23, 109, 116, + 103, 136, 24, 13, 14, 15, 16, 17, 113, 113, + 25, 114, 137, 93, 94, 9, 127, 60, 129, 74, + 63, 9, 10, 107, 61, 73, 11, 59, 10, 115, + 139, 62, 11, 102, 71, 138, 133, 135, 18, 1, + 2, 150, 151, 152, 69, 70, 89, 73, 101, 97, + 100, 142, 79, 80, 82, 83, 84, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 87, 90, 92, 98, + 120, 112, 121, 89, 97, 117, 122, 143, 33, 144, + 123, 124, 132, 128, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 130, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 140, 149, 156, 164, 163, 153, 166, + 184, 165, 185, 141, 168, 32, 146, 170, 126, 167, + 182, 55, 171, 147, 0, 125, 0, 0, 0, 0, + 0, 81 }; static const short yycheck[] = { - 2, 7, 3, 1, 3, 95, 3, 4, 5, 6, - 3, 4, 3, 4, 5, 6, 3, 4, 73, 109, - 46, 111, 7, 11, 49, 49, 46, 52, 52, 55, - 85, 51, 122, 8, 9, 10, 11, 12, 41, 42, - 48, 131, 3, 4, 48, 50, 51, 44, 48, 55, - 27, 28, 49, 44, 51, 56, 7, 56, 55, 47, - 51, 54, 117, 48, 55, 7, 3, 54, 43, 3, - 3, 47, 46, 45, 52, 7, 49, 56, 80, 77, - 78, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 7, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 108, 43, 7, 45, 7, 3, 56, 7, 116, 44, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 50, - 49, 51, 3, 46, 49, 3, 43, 7, 56, 147, - 49, 52, 0, 49, 0, 53, 125, 16, 126, 157, - 156, 126, 164, 158, 17, 108, -1, 67 + 2, 7, 3, 1, 3, 4, 5, 6, 3, 4, + 3, 4, 5, 6, 3, 4, 3, 46, 73, 11, + 46, 49, 7, 7, 49, 51, 55, 48, 56, 96, + 85, 56, 48, 8, 9, 10, 11, 12, 49, 49, + 48, 52, 52, 3, 4, 44, 113, 3, 115, 55, + 49, 44, 51, 54, 3, 47, 55, 7, 51, 54, + 127, 3, 55, 48, 46, 54, 121, 54, 43, 41, + 42, 138, 50, 51, 27, 28, 74, 47, 80, 77, + 78, 7, 45, 49, 52, 56, 7, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 3, 7, 3, 50, + 44, 51, 49, 111, 112, 7, 3, 43, 7, 45, + 3, 3, 120, 46, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 49, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 3, 3, 7, 49, 155, 43, 49, + 0, 52, 0, 130, 164, 16, 131, 165, 112, 53, + 172, 17, 166, 131, -1, 111, -1, -1, -1, -1, + -1, 67 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison/bison.simple" @@ -1118,7 +1127,7 @@ yyreduce: switch (yyn) { case 8: -#line 141 "dcParser.yxx" +#line 142 "dcParser.yxx" { current_class = new DCClass(yyvsp[0].str, yyvsp[-1].u.flag, false); if (!dc_file->add_class(current_class)) { @@ -1132,19 +1141,19 @@ case 8: } break; case 10: -#line 157 "dcParser.yxx" +#line 158 "dcParser.yxx" { yyval.u.flag = true; } break; case 11: -#line 161 "dcParser.yxx" +#line 162 "dcParser.yxx" { yyval.u.flag = false; } break; case 12: -#line 168 "dcParser.yxx" +#line 169 "dcParser.yxx" { DCClass *dclass = dc_file->get_class_by_name(yyvsp[0].str); if (dclass == (DCClass *)NULL) { @@ -1156,49 +1165,49 @@ case 12: } break; case 14: -#line 182 "dcParser.yxx" +#line 183 "dcParser.yxx" { yyval.str = yyvsp[-2].str + string("/") + yyvsp[0].str; } break; case 16: -#line 190 "dcParser.yxx" +#line 191 "dcParser.yxx" { yyval.str = yyvsp[-2].str + string(".") + yyvsp[0].str; } break; case 17: -#line 197 "dcParser.yxx" +#line 198 "dcParser.yxx" { dc_file->add_import_module(yyvsp[0].str); } break; case 18: -#line 201 "dcParser.yxx" +#line 202 "dcParser.yxx" { dc_file->add_import_module(yyvsp[-1].str); } break; case 21: -#line 210 "dcParser.yxx" +#line 211 "dcParser.yxx" { dc_file->add_import_symbol("*"); } break; case 22: -#line 217 "dcParser.yxx" +#line 218 "dcParser.yxx" { dc_file->add_import_symbol(yyvsp[0].str); } break; case 23: -#line 221 "dcParser.yxx" +#line 222 "dcParser.yxx" { dc_file->add_import_symbol(yyvsp[0].str); } break; case 24: -#line 228 "dcParser.yxx" +#line 229 "dcParser.yxx" { DCTypedef *dtypedef = new DCTypedef(yyvsp[0].u.parameter); @@ -1213,7 +1222,7 @@ case 24: } break; case 27: -#line 249 "dcParser.yxx" +#line 250 "dcParser.yxx" { if (yyvsp[0].u.dclass != (DCClass *)NULL) { current_class->add_parent(yyvsp[0].u.dclass); @@ -1221,7 +1230,7 @@ case 27: } break; case 28: -#line 255 "dcParser.yxx" +#line 256 "dcParser.yxx" { if (yyvsp[0].u.dclass != (DCClass *)NULL) { current_class->add_parent(yyvsp[0].u.dclass); @@ -1229,13 +1238,13 @@ case 28: } break; case 33: -#line 268 "dcParser.yxx" +#line 269 "dcParser.yxx" { current_class->add_parameter(yyvsp[-1].u.parameter); } break; case 34: -#line 272 "dcParser.yxx" +#line 273 "dcParser.yxx" { if (!current_class->add_parameter(yyvsp[0].u.parameter)) { yyerror("Duplicate parameter name: " + yyvsp[0].u.parameter->get_name()); @@ -1243,7 +1252,7 @@ case 34: } break; case 35: -#line 281 "dcParser.yxx" +#line 282 "dcParser.yxx" { current_atomic = new DCAtomicField(yyvsp[-1].str); if (!current_class->add_field(current_atomic)) { @@ -1252,7 +1261,7 @@ case 35: } break; case 37: -#line 292 "dcParser.yxx" +#line 293 "dcParser.yxx" { DCField *field = current_class->get_field_by_name(yyvsp[0].str); yyval.u.atomic = (DCAtomicField *)NULL; @@ -1267,21 +1276,21 @@ case 37: } break; case 42: -#line 318 "dcParser.yxx" +#line 319 "dcParser.yxx" { atomic_element = DCAtomicField::ElementType(yyvsp[0].u.parameter); current_atomic->add_element(atomic_element); } break; case 43: -#line 323 "dcParser.yxx" +#line 324 "dcParser.yxx" { current_packer = &default_packer; current_packer->begin_pack(yyvsp[-1].u.parameter); } break; case 44: -#line 328 "dcParser.yxx" +#line 329 "dcParser.yxx" { bool is_valid = yyvsp[-3].u.parameter->is_valid(); atomic_element = DCAtomicField::ElementType(yyvsp[-3].u.parameter); @@ -1300,25 +1309,25 @@ case 44: } break; case 45: -#line 348 "dcParser.yxx" +#line 349 "dcParser.yxx" { current_parameter = yyvsp[0].u.parameter; } break; case 46: -#line 352 "dcParser.yxx" +#line 353 "dcParser.yxx" { yyval.u.parameter = yyvsp[0].u.parameter; } break; case 50: -#line 368 "dcParser.yxx" +#line 369 "dcParser.yxx" { yyval.u.parameter = new DCSimpleParameter(yyvsp[0].u.subatomic); } break; case 51: -#line 372 "dcParser.yxx" +#line 373 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-3].u.subatomic); if (!simple_param->set_range(double_range)) { @@ -1328,7 +1337,7 @@ case 51: } break; case 52: -#line 380 "dcParser.yxx" +#line 381 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-2].u.subatomic); if (yyvsp[0].u.integer == 0) { @@ -1341,7 +1350,7 @@ case 52: } break; case 53: -#line 391 "dcParser.yxx" +#line 392 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); if (yyvsp[-3].u.integer == 0) { @@ -1357,7 +1366,7 @@ case 53: } break; case 54: -#line 405 "dcParser.yxx" +#line 406 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); if (yyvsp[0].u.integer == 0) { @@ -1373,7 +1382,7 @@ case 54: } break; case 55: -#line 419 "dcParser.yxx" +#line 420 "dcParser.yxx" { DCTypedef *dtypedef = dc_file->get_typedef_by_name(yyvsp[0].str); if (dtypedef == (DCTypedef *)NULL) { @@ -1394,13 +1403,13 @@ case 55: } break; case 56: -#line 441 "dcParser.yxx" +#line 442 "dcParser.yxx" { double_range.clear(); } break; case 57: -#line 445 "dcParser.yxx" +#line 446 "dcParser.yxx" { double_range.clear(); if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { @@ -1409,7 +1418,7 @@ case 57: } break; case 58: -#line 452 "dcParser.yxx" +#line 453 "dcParser.yxx" { double_range.clear(); if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { @@ -1418,13 +1427,12 @@ case 58: } break; case 59: -#line 459 "dcParser.yxx" +#line 460 "dcParser.yxx" { double_range.clear(); if (yyvsp[0].u.real >= 0) { yyerror("Syntax error"); - } - if (!double_range.add_range(yyvsp[-1].u.real, -yyvsp[0].u.real)) { + } else if (!double_range.add_range(yyvsp[-1].u.real, -yyvsp[0].u.real)) { yyerror("Overlapping range"); } } @@ -1450,33 +1458,103 @@ case 62: { if (yyvsp[0].u.real >= 0) { yyerror("Syntax error"); - } - if (!double_range.add_range(yyvsp[-1].u.real, -yyvsp[0].u.real)) { + } else if (!double_range.add_range(yyvsp[-1].u.real, -yyvsp[0].u.real)) { yyerror("Overlapping range"); } } break; -case 64: -#line 494 "dcParser.yxx" +case 63: +#line 492 "dcParser.yxx" { - yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter); + uint_range.clear(); +} + break; +case 64: +#line 496 "dcParser.yxx" +{ + if (yyvsp[0].u.integer < 0) { + yyerror("Nonnegative values only"); + } else { + uint_range.clear(); + if (!uint_range.add_range(yyvsp[0].u.integer, yyvsp[0].u.integer)) { + yyerror("Overlapping range"); + } + } } break; case 65: -#line 498 "dcParser.yxx" +#line 507 "dcParser.yxx" { - yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer); + if (yyvsp[-2].u.integer < 0 || yyvsp[0].u.integer < 0) { + yyerror("Nonnegative values only"); + } else { + uint_range.clear(); + if (!uint_range.add_range(yyvsp[-2].u.integer, yyvsp[0].u.integer)) { + yyerror("Overlapping range"); + } + } } break; case 66: -#line 505 "dcParser.yxx" +#line 518 "dcParser.yxx" +{ + uint_range.clear(); + if (yyvsp[0].u.integer >= 0) { + yyerror("Syntax error"); + } else if (yyvsp[-1].u.integer < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range(yyvsp[-1].u.integer, -yyvsp[0].u.integer)) { + yyerror("Overlapping range"); + } +} + break; +case 67: +#line 529 "dcParser.yxx" +{ + if (yyvsp[0].u.integer < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range(yyvsp[0].u.integer, yyvsp[0].u.integer)) { + yyerror("Overlapping range"); + } +} + break; +case 68: +#line 537 "dcParser.yxx" +{ + if (yyvsp[-2].u.integer < 0 || yyvsp[0].u.integer < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range(yyvsp[-2].u.integer, yyvsp[0].u.integer)) { + yyerror("Overlapping range"); + } +} + break; +case 69: +#line 545 "dcParser.yxx" +{ + if (yyvsp[0].u.integer >= 0) { + yyerror("Syntax error"); + } else if (yyvsp[-1].u.integer < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range(yyvsp[-1].u.integer, -yyvsp[0].u.integer)) { + yyerror("Overlapping range"); + } +} + break; +case 71: +#line 559 "dcParser.yxx" +{ + yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, uint_range); +} + break; +case 72: +#line 566 "dcParser.yxx" { current_parameter->set_name(yyvsp[0].str); yyval.u.parameter = current_parameter; } break; -case 67: -#line 510 "dcParser.yxx" +case 73: +#line 571 "dcParser.yxx" { if (yyvsp[0].u.integer == 0) { yyerror("Invalid divisor."); @@ -1491,278 +1569,272 @@ case 67: } } break; -case 68: -#line 524 "dcParser.yxx" +case 74: +#line 585 "dcParser.yxx" { - yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter); + yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, uint_range); } break; -case 69: -#line 528 "dcParser.yxx" -{ - yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer); -} - break; -case 70: -#line 535 "dcParser.yxx" +case 75: +#line 592 "dcParser.yxx" { yyval.u.real = (double)yyvsp[0].u.integer; } break; -case 72: -#line 543 "dcParser.yxx" +case 77: +#line 600 "dcParser.yxx" { current_packer->pack_int64(yyvsp[0].u.integer); } break; -case 73: -#line 547 "dcParser.yxx" +case 78: +#line 604 "dcParser.yxx" { current_packer->pack_double(yyvsp[0].u.real); } break; -case 74: -#line 551 "dcParser.yxx" +case 79: +#line 608 "dcParser.yxx" { current_packer->pack_string(yyvsp[0].str); } break; -case 75: -#line 555 "dcParser.yxx" +case 80: +#line 612 "dcParser.yxx" { current_packer->pack_literal_value(yyvsp[0].str); } break; -case 76: -#line 559 "dcParser.yxx" -{ - current_packer->push(); -} - break; -case 77: -#line 563 "dcParser.yxx" -{ - current_packer->pop(); -} - break; -case 78: -#line 567 "dcParser.yxx" -{ - current_packer->push(); -} - break; -case 79: -#line 571 "dcParser.yxx" -{ - current_packer->pop(); -} - break; -case 80: -#line 575 "dcParser.yxx" -{ - current_packer->push(); -} - break; case 81: -#line 579 "dcParser.yxx" +#line 616 "dcParser.yxx" { - current_packer->pop(); + current_packer->push(); } break; case 82: -#line 583 "dcParser.yxx" +#line 620 "dcParser.yxx" +{ + current_packer->pop(); +} + break; +case 83: +#line 624 "dcParser.yxx" +{ + current_packer->push(); +} + break; +case 84: +#line 628 "dcParser.yxx" +{ + current_packer->pop(); +} + break; +case 85: +#line 632 "dcParser.yxx" +{ + current_packer->push(); +} + break; +case 86: +#line 636 "dcParser.yxx" +{ + current_packer->pop(); +} + break; +case 87: +#line 640 "dcParser.yxx" { for (int i = 0; i < yyvsp[0].u.integer; i++) { current_packer->pack_int64(yyvsp[-2].u.integer); } } break; -case 83: -#line 589 "dcParser.yxx" +case 88: +#line 646 "dcParser.yxx" { for (int i = 0; i < yyvsp[0].u.integer; i++) { current_packer->pack_double(yyvsp[-2].u.real); } } break; -case 84: -#line 595 "dcParser.yxx" +case 89: +#line 652 "dcParser.yxx" { for (int i = 0; i < yyvsp[0].u.integer; i++) { current_packer->pack_literal_value(yyvsp[-2].str); } } break; -case 91: -#line 619 "dcParser.yxx" +case 96: +#line 676 "dcParser.yxx" { yyval.u.subatomic = ST_int8; } break; -case 92: -#line 623 "dcParser.yxx" +case 97: +#line 680 "dcParser.yxx" { yyval.u.subatomic = ST_int16; } break; -case 93: -#line 627 "dcParser.yxx" +case 98: +#line 684 "dcParser.yxx" { yyval.u.subatomic = ST_int32; } break; -case 94: -#line 631 "dcParser.yxx" +case 99: +#line 688 "dcParser.yxx" { yyval.u.subatomic = ST_int64; } break; -case 95: -#line 635 "dcParser.yxx" +case 100: +#line 692 "dcParser.yxx" { yyval.u.subatomic = ST_uint8; } break; -case 96: -#line 639 "dcParser.yxx" +case 101: +#line 696 "dcParser.yxx" { yyval.u.subatomic = ST_uint16; } break; -case 97: -#line 643 "dcParser.yxx" +case 102: +#line 700 "dcParser.yxx" { yyval.u.subatomic = ST_uint32; } break; -case 98: -#line 647 "dcParser.yxx" +case 103: +#line 704 "dcParser.yxx" { yyval.u.subatomic = ST_uint64; } break; -case 99: -#line 651 "dcParser.yxx" +case 104: +#line 708 "dcParser.yxx" { yyval.u.subatomic = ST_float64; } break; -case 100: -#line 655 "dcParser.yxx" +case 105: +#line 712 "dcParser.yxx" { yyval.u.subatomic = ST_string; } break; -case 101: -#line 659 "dcParser.yxx" +case 106: +#line 716 "dcParser.yxx" { yyval.u.subatomic = ST_blob; } break; -case 102: -#line 663 "dcParser.yxx" +case 107: +#line 720 "dcParser.yxx" { yyval.u.subatomic = ST_blob32; } break; -case 103: -#line 667 "dcParser.yxx" +case 108: +#line 724 "dcParser.yxx" { yyval.u.subatomic = ST_int8array; } break; -case 104: -#line 671 "dcParser.yxx" +case 109: +#line 728 "dcParser.yxx" { yyval.u.subatomic = ST_int16array; } break; -case 105: -#line 675 "dcParser.yxx" +case 110: +#line 732 "dcParser.yxx" { yyval.u.subatomic = ST_int32array; } break; -case 106: -#line 679 "dcParser.yxx" +case 111: +#line 736 "dcParser.yxx" { yyval.u.subatomic = ST_uint8array; } break; -case 107: -#line 683 "dcParser.yxx" +case 112: +#line 740 "dcParser.yxx" { yyval.u.subatomic = ST_uint16array; } break; -case 108: -#line 687 "dcParser.yxx" +case 113: +#line 744 "dcParser.yxx" { yyval.u.subatomic = ST_uint32array; } break; -case 109: -#line 691 "dcParser.yxx" +case 114: +#line 748 "dcParser.yxx" { yyval.u.subatomic = ST_uint32uint8array; } break; -case 111: -#line 699 "dcParser.yxx" +case 116: +#line 756 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_required); } break; -case 112: -#line 703 "dcParser.yxx" +case 117: +#line 760 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_broadcast); } break; -case 113: -#line 707 "dcParser.yxx" +case 118: +#line 764 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_p2p); } break; -case 114: -#line 711 "dcParser.yxx" +case 119: +#line 768 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_ram); } break; -case 115: -#line 715 "dcParser.yxx" +case 120: +#line 772 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_db); } break; -case 116: -#line 719 "dcParser.yxx" +case 121: +#line 776 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_clsend); } break; -case 117: -#line 723 "dcParser.yxx" +case 122: +#line 780 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_clrecv); } break; -case 118: -#line 727 "dcParser.yxx" +case 123: +#line 784 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_ownsend); } break; -case 119: -#line 731 "dcParser.yxx" +case 124: +#line 788 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_airecv); } break; -case 120: -#line 738 "dcParser.yxx" +case 125: +#line 795 "dcParser.yxx" { current_molecular = new DCMolecularField(yyvsp[-1].str); if (!current_class->add_field(current_molecular)) { @@ -1770,16 +1842,16 @@ case 120: } } break; -case 122: -#line 749 "dcParser.yxx" +case 127: +#line 806 "dcParser.yxx" { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { current_molecular->add_atomic(yyvsp[0].u.atomic); } } break; -case 123: -#line 755 "dcParser.yxx" +case 128: +#line 812 "dcParser.yxx" { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { current_molecular->add_atomic(yyvsp[0].u.atomic); @@ -2024,4 +2096,4 @@ yyreturn: #endif return yyresult; } -#line 770 "dcParser.yxx" +#line 827 "dcParser.yxx" diff --git a/direct/src/dcparser/dcParser.yxx b/direct/src/dcparser/dcParser.yxx index 5d78bdf2bf..db61b76052 100644 --- a/direct/src/dcparser/dcParser.yxx +++ b/direct/src/dcparser/dcParser.yxx @@ -34,6 +34,7 @@ static DCParameter *current_parameter = (DCParameter *)NULL; static DCPacker default_packer; static DCPacker *current_packer; static DCDoubleRange double_range; +static DCUnsignedIntRange uint_range; //////////////////////////////////////////////////////////////////// // Defining the interface to the parser. @@ -460,8 +461,7 @@ double_range: double_range.clear(); if ($2 >= 0) { yyerror("Syntax error"); - } - if (!double_range.add_range($1, -$2)) { + } else if (!double_range.add_range($1, -$2)) { yyerror("Overlapping range"); } } @@ -481,8 +481,73 @@ double_range: { if ($4 >= 0) { yyerror("Syntax error"); + } else if (!double_range.add_range($3, -$4)) { + yyerror("Overlapping range"); } - if (!double_range.add_range($3, -$4)) { +} + ; + +uint_range: + empty +{ + uint_range.clear(); +} + | INTEGER +{ + if ($1 < 0) { + yyerror("Nonnegative values only"); + } else { + uint_range.clear(); + if (!uint_range.add_range($1, $1)) { + yyerror("Overlapping range"); + } + } +} + | INTEGER '-' INTEGER +{ + if ($1 < 0 || $3 < 0) { + yyerror("Nonnegative values only"); + } else { + uint_range.clear(); + if (!uint_range.add_range($1, $3)) { + yyerror("Overlapping range"); + } + } +} + | INTEGER INTEGER +{ + uint_range.clear(); + if ($2 >= 0) { + yyerror("Syntax error"); + } else if ($1 < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range($1, -$2)) { + yyerror("Overlapping range"); + } +} + | uint_range ',' INTEGER +{ + if ($3 < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range($3, $3)) { + yyerror("Overlapping range"); + } +} + | uint_range ',' INTEGER '-' INTEGER +{ + if ($3 < 0 || $5 < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range($3, $5)) { + yyerror("Overlapping range"); + } +} + | uint_range ',' INTEGER INTEGER +{ + if ($4 >= 0) { + yyerror("Syntax error"); + } else if ($3 < 0) { + yyerror("Nonnegative values only"); + } else if (!uint_range.add_range($3, -$4)) { yyerror("Overlapping range"); } } @@ -490,13 +555,9 @@ double_range: type_definition: type_name - | type_definition '[' ']' + | type_definition '[' uint_range ']' { - $$ = new DCArrayParameter($1); -} - | type_definition '[' INTEGER ']' -{ - $$ = new DCArrayParameter($1, $3); + $$ = new DCArrayParameter($1, uint_range); } ; @@ -520,13 +581,9 @@ parameter_definition: } } } - | parameter_definition '[' ']' + | parameter_definition '[' uint_range ']' { - $$ = new DCArrayParameter($1); -} - | parameter_definition '[' INTEGER ']' -{ - $$ = new DCArrayParameter($1, $3); + $$ = new DCArrayParameter($1, uint_range); } ; diff --git a/direct/src/dcparser/dcSimpleParameter.cxx b/direct/src/dcparser/dcSimpleParameter.cxx index 91e3e2ac7d..7103744935 100644 --- a/direct/src/dcparser/dcSimpleParameter.cxx +++ b/direct/src/dcparser/dcSimpleParameter.cxx @@ -358,8 +358,6 @@ set_range(const DCDoubleRange &range) { case ST_uint16: case ST_uint16array: - case ST_string: - case ST_blob: _uint_range.clear(); for (i = 0; i < num_ranges; i++) { unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); @@ -372,7 +370,6 @@ set_range(const DCDoubleRange &range) { case ST_uint32: case ST_uint32array: - case ST_blob32: _uint_range.clear(); for (i = 0; i < num_ranges; i++) { unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); @@ -399,6 +396,47 @@ set_range(const DCDoubleRange &range) { } break; + case ST_string: + case ST_blob: + _uint_range.clear(); + for (i = 0; i < num_ranges; i++) { + unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); + unsigned int max = (unsigned int)floor(range.get_max(i) * _divisor + 0.5); + validate_uint_limits(min, 16, range_error); + validate_uint_limits(max, 16, range_error); + _uint_range.add_range(min, max); + } + if (_uint_range.has_one_value()) { + // If we now have a fixed-length string requirement, we don't + // need a leading number of bytes. + _num_length_bytes = 0; + _has_fixed_byte_size = true; + _fixed_byte_size = _uint_range.get_one_value(); + } else { + _num_length_bytes = 2; + _has_fixed_byte_size = false; + } + break; + + case ST_blob32: + _uint_range.clear(); + for (i = 0; i < num_ranges; i++) { + unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); + unsigned int max = (unsigned int)floor(range.get_max(i) * _divisor + 0.5); + _uint_range.add_range(min, max); + } + if (_uint_range.has_one_value()) { + // If we now have a fixed-length string requirement, we don't + // need a leading number of bytes. + _num_length_bytes = 0; + _has_fixed_byte_size = true; + _fixed_byte_size = _uint_range.get_one_value(); + } else { + _num_length_bytes = 4; + _has_fixed_byte_size = false; + } + break; + default: return false; } @@ -811,12 +849,16 @@ pack_string(DCPackData &pack_data, const string &value, case ST_string: case ST_blob: validate_uint_limits(string_length, 16, range_error); - do_pack_uint16(pack_data.get_write_pointer(2), string_length); + if (_num_length_bytes != 0) { + do_pack_uint16(pack_data.get_write_pointer(2), string_length); + } pack_data.append_data(value.data(), string_length); break; case ST_blob32: - do_pack_uint32(pack_data.get_write_pointer(4), string_length); + if (_num_length_bytes != 0) { + do_pack_uint32(pack_data.get_write_pointer(4), string_length); + } pack_data.append_data(value.data(), string_length); break; @@ -1488,30 +1530,36 @@ unpack_string(const char *data, size_t length, size_t &p, string &value, bool &pack_error, bool &range_error) const { size_t string_length; - switch (_type) { - case ST_string: - case ST_blob: - if (p + 2 > length) { + if (_num_length_bytes == 0) { + string_length = _fixed_byte_size; + + } else { + switch (_type) { + case ST_string: + case ST_blob: + if (p + 2 > length) { + pack_error = true; + return; + } + string_length = do_unpack_uint16(data + p); + p += 2; + break; + + case ST_blob32: + if (p + 4 > length) { + pack_error = true; + return; + } + string_length = do_unpack_uint32(data + p); + p += 4; + break; + + default: pack_error = true; return; } - string_length = do_unpack_uint16(data + p); - p += 2; - break; - - case ST_blob32: - if (p + 4 > length) { - pack_error = true; - return; - } - string_length = do_unpack_uint32(data + p); - p += 4; - break; - - default: - pack_error = true; - return; } + _uint_range.validate(string_length, range_error); if (p + string_length > length) { @@ -1647,7 +1695,10 @@ unpack_validate(const char *data, size_t length, size_t &p, case ST_string: case ST_blob: - { + if (_num_length_bytes == 0) { + p += _fixed_byte_size; + + } else { if (p + 2 > length) { pack_error = true; return true; @@ -1659,7 +1710,10 @@ unpack_validate(const char *data, size_t length, size_t &p, break; case ST_blob32: - { + if (_num_length_bytes == 0) { + p += _fixed_byte_size; + + } else { if (p + 4 > length) { pack_error = true; return true; @@ -1713,19 +1767,29 @@ unpack_skip(const char *data, size_t length, size_t &p) const { case ST_string: case ST_blob: - if (p + 2 > length) { - return false; + if (_num_length_bytes == 0) { + p += _fixed_byte_size; + + } else { + if (p + 2 > length) { + return false; + } + string_length = do_unpack_uint16(data + p); + p += 2 + string_length; } - string_length = do_unpack_uint16(data + p); - p += 2 + string_length; break; case ST_blob32: - if (p + 4 > length) { - return false; + if (_num_length_bytes == 0) { + p += _fixed_byte_size; + + } else { + if (p + 4 > length) { + return false; + } + string_length = do_unpack_uint32(data + p); + p += 4 + string_length; } - string_length = do_unpack_uint32(data + p); - p += 4 + string_length; break; default: @@ -1749,7 +1813,7 @@ void DCSimpleParameter:: output_instance(ostream &out, const string &prename, const string &name, const string &postname) const { if (get_typedef() != (DCTypedef *)NULL) { - out << get_typedef()->get_name(); + output_typedef_name(out, prename, name, postname); } else { out << _type; @@ -1757,7 +1821,6 @@ output_instance(ostream &out, const string &prename, const string &name, out << "/" << _divisor; } - switch (_type) { case ST_int8: case ST_int16: @@ -1806,10 +1869,10 @@ output_instance(ostream &out, const string &prename, const string &name, default: break; } - } - if (!prename.empty() || !name.empty() || !postname.empty()) { - out << " " << prename << name << postname; + if (!prename.empty() || !name.empty() || !postname.empty()) { + out << " " << prename << name << postname; + } } }