diff --git a/dtool/src/prc/Sources.pp b/dtool/src/prc/Sources.pp index a18362054c..bb03164559 100644 --- a/dtool/src/prc/Sources.pp +++ b/dtool/src/prc/Sources.pp @@ -21,6 +21,7 @@ configVariableEnum.I configVariableEnum.h \ configVariableFilename.I configVariableFilename.h \ configVariableInt.I configVariableInt.h \ + configVariableInt64.I configVariableInt64.h \ configVariableList.I configVariableList.h \ configVariableManager.I configVariableManager.h \ configVariableSearchPath.I configVariableSearchPath.h \ @@ -51,6 +52,7 @@ configVariableEnum.cxx \ configVariableFilename.cxx \ configVariableInt.cxx \ + configVariableInt64.cxx \ configVariableList.cxx \ configVariableManager.cxx \ configVariableSearchPath.cxx \ @@ -80,6 +82,7 @@ configVariableEnum.I configVariableEnum.h \ configVariableFilename.I configVariableFilename.h \ configVariableInt.I configVariableInt.h \ + configVariableInt64.I configVariableInt64.h \ configVariableList.I configVariableList.h \ configVariableManager.I configVariableManager.h \ configVariableSearchPath.I configVariableSearchPath.h \ diff --git a/dtool/src/prc/configDeclaration.I b/dtool/src/prc/configDeclaration.I index 4354266183..ef5b7ea085 100644 --- a/dtool/src/prc/configDeclaration.I +++ b/dtool/src/prc/configDeclaration.I @@ -144,6 +144,21 @@ has_int_word(int n) const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: ConfigDeclaration::has_int64_word +// Access: Public +// Description: Returns true if the declaration's value has a valid +// int64 value for the nth word. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigDeclaration:: +has_int64_word(int n) const { + if (has_string_word(n)) { + ((ConfigDeclaration *)this)->check_int64_word(n); + return (_words[n]._flags & F_valid_int64) != 0; + } + return false; +} + //////////////////////////////////////////////////////////////////// // Function: ConfigDeclaration::has_double_word // Access: Public @@ -210,6 +225,24 @@ get_int_word(int n) const { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: ConfigDeclaration::get_int64_word +// Access: Public +// Description: Returns the int64 value of the nth word of the +// declaration's value, or 0 if there is no nth value. +// See also has_int64_word(). +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigDeclaration:: +get_int64_word(int n) const { + // We use has_string_word() instead of has_int64_word(), so we can + // return a partial answer if there was one. + if (has_string_word(n)) { + ((ConfigDeclaration *)this)->check_int64_word(n); + return _words[n]._int64; + } + return 0; +} + //////////////////////////////////////////////////////////////////// // Function: ConfigDeclaration::get_double_word // Access: Public diff --git a/dtool/src/prc/configDeclaration.cxx b/dtool/src/prc/configDeclaration.cxx index 8b775eff43..29180865d3 100644 --- a/dtool/src/prc/configDeclaration.cxx +++ b/dtool/src/prc/configDeclaration.cxx @@ -123,6 +123,23 @@ set_int_word(int n, int value) { invalidate_cache(); } +//////////////////////////////////////////////////////////////////// +// Function: ConfigDeclaration::set_int64_word +// Access: Public +// Description: Changes the nth word to the indicated value without +// affecting the other words. +//////////////////////////////////////////////////////////////////// +void ConfigDeclaration:: +set_int64_word(int n, PN_int64 value) { + ostringstream strm; + strm << value; + set_string_word(n, strm.str()); + + _words[n]._flags |= (F_checked_int64 | F_valid_int64); + _words[n]._int64 = value; + invalidate_cache(); +} + //////////////////////////////////////////////////////////////////// // Function: ConfigDeclaration::set_double_word // Access: Public @@ -225,6 +242,10 @@ check_bool_word(int n) { } else { word._bool = false; } + + prc_cat->warning() + << "Invalid bool value for ConfigVariable " + << get_variable()->get_name() << ": " << word._str << "\n"; return; } @@ -250,12 +271,102 @@ check_int_word(int n) { if ((word._flags & F_checked_int) == 0) { word._flags |= F_checked_int; - const char *nptr = word._str.c_str(); - char *endptr; - word._int = strtol(nptr, &endptr, 0); + // We scan the word by hand, rather than relying on strtol(), so + // we can check for overflow of the 32-bit value. + word._int = 0; + bool overflow = false; - if (*endptr == '\0') { + string::const_iterator pi = word._str.begin(); + if (pi != word._str.end() && (*pi) == '-') { + ++pi; + // Negative number. + while (pi != word._str.end() && isdigit(*pi)) { + int next = word._int * 10 - (int)((*pi) - '0'); + if ((int)(next / 10) != word._int) { + // Overflow. + overflow = true; + } + word._int = next; + ++pi; + } + + } else { + // Positive number. + while (pi != word._str.end() && isdigit(*pi)) { + int next = word._int * 10 + (int)((*pi) - '0'); + if ((int)(next / 10) != word._int) { + // Overflow. + overflow = true; + } + word._int = next; + ++pi; + } + } + + if (pi == word._str.end() && !overflow) { word._flags |= F_valid_int; + } else { + prc_cat->warning() + << "Invalid integer value for ConfigVariable " + << get_variable()->get_name() << ": " << word._str << "\n"; + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigDeclaration::check_int64_word +// Access: Private +// Description: Checks whether the nth word can be interpreted as an +// integer value. +//////////////////////////////////////////////////////////////////// +void ConfigDeclaration:: +check_int64_word(int n) { + if (!_got_words) { + get_words(); + } + + if (n >= 0 && n < (int)_words.size()) { + Word &word = _words[n]; + if ((word._flags & F_checked_int64) == 0) { + word._flags |= F_checked_int64; + + word._int64 = 0; + bool overflow = false; + + string::const_iterator pi = word._str.begin(); + if (pi != word._str.end() && (*pi) == '-') { + ++pi; + // Negative number. + while (pi != word._str.end() && isdigit(*pi)) { + PN_int64 next = word._int64 * 10 - (int)((*pi) - '0'); + if ((PN_int64)(next / 10) != word._int64) { + // Overflow. + overflow = true; + } + word._int64 = next; + ++pi; + } + + } else { + // Positive number. + while (pi != word._str.end() && isdigit(*pi)) { + PN_int64 next = word._int64 * 10 + (int)((*pi) - '0'); + if ((PN_int64)(next / 10) != word._int64) { + // Overflow. + overflow = true; + } + word._int64 = next; + ++pi; + } + } + + if (pi == word._str.end() && !overflow) { + word._flags |= F_valid_int64; + } else { + prc_cat->warning() + << "Invalid int64 value for ConfigVariable " + << get_variable()->get_name() << ": " << word._str << "\n"; } } } @@ -284,6 +395,10 @@ check_double_word(int n) { if (*endptr == '\0') { word._flags |= F_valid_double; + } else { + prc_cat->warning() + << "Invalid floating-point value for ConfigVariable " + << get_variable()->get_name() << ": " << word._str << "\n"; } } } diff --git a/dtool/src/prc/configDeclaration.h b/dtool/src/prc/configDeclaration.h index 179b274acc..b9dc5c179d 100644 --- a/dtool/src/prc/configDeclaration.h +++ b/dtool/src/prc/configDeclaration.h @@ -23,6 +23,7 @@ #include "configFlags.h" #include "configPage.h" #include "vector_string.h" +#include "numeric_types.h" #include @@ -57,16 +58,19 @@ public: INLINE bool has_string_word(int n) const; INLINE bool has_bool_word(int n) const; INLINE bool has_int_word(int n) const; + INLINE bool has_int64_word(int n) const; INLINE bool has_double_word(int n) const; INLINE string get_string_word(int n) const; INLINE bool get_bool_word(int n) const; INLINE int get_int_word(int n) const; + INLINE PN_int64 get_int64_word(int n) const; INLINE double get_double_word(int n) const; void set_string_word(int n, const string &value); void set_bool_word(int n, bool value); void set_int_word(int n, int value); + void set_int64_word(int n, PN_int64 value); void set_double_word(int n, double value); INLINE int get_decl_seq() const; @@ -82,6 +86,7 @@ private: void get_words(); void check_bool_word(int n); void check_int_word(int n); + void check_int64_word(int n); void check_double_word(int n); private: @@ -97,6 +102,8 @@ private: F_valid_int = 0x0008, F_checked_double = 0x0010, F_valid_double = 0x0020, + F_checked_int64 = 0x0040, + F_valid_int64 = 0x0080, }; class Word { @@ -104,6 +111,7 @@ private: string _str; bool _bool; int _int; + PN_int64 _int64; double _double; short _flags; }; diff --git a/dtool/src/prc/configFlags.cxx b/dtool/src/prc/configFlags.cxx index 698b39a8a1..535572a3e3 100644 --- a/dtool/src/prc/configFlags.cxx +++ b/dtool/src/prc/configFlags.cxx @@ -53,6 +53,9 @@ operator << (ostream &out, ConfigFlags::ValueType type) { case ConfigFlags::VT_search_path: return out << "search-path"; + + case ConfigFlags::VT_int64: + return out << "int64"; } return out << "**invalid(" << (int)type << ")**"; diff --git a/dtool/src/prc/configFlags.h b/dtool/src/prc/configFlags.h index 9f4165c273..d00e03a7a4 100644 --- a/dtool/src/prc/configFlags.h +++ b/dtool/src/prc/configFlags.h @@ -42,6 +42,7 @@ PUBLISHED: VT_double, VT_enum, VT_search_path, + VT_int64, }; enum VariableFlags { diff --git a/dtool/src/prc/configVariable.I b/dtool/src/prc/configVariable.I index ffa5ca677d..78df451774 100644 --- a/dtool/src/prc/configVariable.I +++ b/dtool/src/prc/configVariable.I @@ -161,6 +161,19 @@ has_int_word(int n) const { return decl->has_int_word(n); } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariable::has_int64_word +// Access: Published +// Description: Returns true if the variable's value has a valid +// 64-bit integer value for the nth word. +//////////////////////////////////////////////////////////////////// +INLINE bool ConfigVariable:: +has_int64_word(int n) const { + nassertr(_core != (ConfigVariableCore *)NULL, false); + const ConfigDeclaration *decl = _core->get_declaration(0); + return decl->has_int64_word(n); +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariable::has_double_word // Access: Published @@ -216,6 +229,20 @@ get_int_word(int n) const { return decl->get_int_word(n); } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariable::get_int64_word +// Access: Published +// Description: Returns the int64 value of the nth word of the +// variable's value, or 0 if there is no nth value. +// See also has_int_word(). +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigVariable:: +get_int64_word(int n) const { + nassertr(_core != (ConfigVariableCore *)NULL, 0); + const ConfigDeclaration *decl = _core->get_declaration(0); + return decl->get_int64_word(n); +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariable::get_double_word // Access: Published @@ -266,6 +293,18 @@ set_int_word(int n, int value) { _core->make_local_value()->set_int_word(n, value); } +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariable::set_int64_word +// Access: Published +// Description: Changes the nth word to the indicated value without +// affecting the other words. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariable:: +set_int64_word(int n, PN_int64 value) { + nassertv(_core != (ConfigVariableCore *)NULL); + _core->make_local_value()->set_int_word(n, value); +} + //////////////////////////////////////////////////////////////////// // Function: ConfigVariable::set_double_word // Access: Published diff --git a/dtool/src/prc/configVariable.h b/dtool/src/prc/configVariable.h index d7b0fe99c2..91902ef140 100644 --- a/dtool/src/prc/configVariable.h +++ b/dtool/src/prc/configVariable.h @@ -21,6 +21,7 @@ #include "dtoolbase.h" #include "configVariableBase.h" +#include "numeric_types.h" //////////////////////////////////////////////////////////////////// // Class : ConfigVariable @@ -55,16 +56,19 @@ PUBLISHED: INLINE bool has_string_word(int n) const; INLINE bool has_bool_word(int n) const; INLINE bool has_int_word(int n) const; + INLINE bool has_int64_word(int n) const; INLINE bool has_double_word(int n) const; INLINE string get_string_word(int n) const; INLINE bool get_bool_word(int n) const; INLINE int get_int_word(int n) const; + INLINE PN_int64 get_int64_word(int n) const; INLINE double get_double_word(int n) const; INLINE void set_string_word(int n, const string &value); INLINE void set_bool_word(int n, bool value); INLINE void set_int_word(int n, int value); + INLINE void set_int64_word(int n, PN_int64 value); INLINE void set_double_word(int n, double value); }; diff --git a/dtool/src/prc/configVariableInt64.I b/dtool/src/prc/configVariableInt64.I new file mode 100644 index 0000000000..766471b866 --- /dev/null +++ b/dtool/src/prc/configVariableInt64.I @@ -0,0 +1,171 @@ +// Filename: configVariableInt64.I +// Created by: drose (19Dec07) +// +//////////////////////////////////////////////////////////////////// +// +// 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 +// aPN_int64 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableInt64:: +ConfigVariableInt64(const string &name) : + ConfigVariable(name, VT_int64), + _local_modified(initial_invalid_cache()) +{ + _core->set_used(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableInt64:: +ConfigVariableInt64(const string &name, PN_int64 default_value, + const string &description, PN_int64 flags) : +#ifdef PRC_SAVE_DESCRIPTIONS + ConfigVariable(name, ConfigVariableCore::VT_int64, description, flags), +#else + ConfigVariable(name, ConfigVariableCore::VT_int64, string(), flags), +#endif + _local_modified(initial_invalid_cache()) +{ + set_default_value(default_value); + _core->set_used(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableInt64:: +ConfigVariableInt64(const string &name, const string &default_value, + const string &description, PN_int64 flags) : +#ifdef PRC_SAVE_DESCRIPTIONS + ConfigVariable(name, ConfigVariableCore::VT_int64, description, flags), +#else + ConfigVariable(name, ConfigVariableCore::VT_int64, string(), flags), +#endif + _local_modified(initial_invalid_cache()) +{ + _core->set_default_value(default_value); + _core->set_used(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::operator = +// Access: Published +// Description: Reassigns the variable's local value. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableInt64:: +operator = (PN_int64 value) { + set_value(value); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::typecast operator +// Access: Published +// Description: Returns the variable's value. +//////////////////////////////////////////////////////////////////// +INLINE ConfigVariableInt64:: +operator PN_int64 () const { + return get_value(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::size() +// Access: Published +// Description: Returns the number of unique words in the variable. +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigVariableInt64:: +size() const { + return get_num_words(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::operator [] +// Access: Published +// Description: Returns the value of the variable's nth word. +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigVariableInt64:: +operator [] (int n) const { + return get_word(n); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::set_value +// Access: Published +// Description: Reassigns the variable's local value. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableInt64:: +set_value(PN_int64 value) { + set_string_value(""); + set_int64_word(0, value); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::get_value +// Access: Published +// Description: Returns the variable's value. +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigVariableInt64:: +get_value() const { + TAU_PROFILE("PN_int64 ConfigVariableInt64::get_value() const", " ", TAU_USER); + if (!is_cache_valid(_local_modified)) { + mark_cache_valid(((ConfigVariableInt64 *)this)->_local_modified); + ((ConfigVariableInt64 *)this)->_cache = get_int64_word(0); + } + return _cache; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::get_default_value +// Access: Published +// Description: Returns the variable's default value. +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigVariableInt64:: +get_default_value() const { + const ConfigDeclaration *decl = ConfigVariable::get_default_value(); + if (decl != (ConfigDeclaration *)NULL) { + return decl->get_int64_word(0); + } + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::get_word +// Access: Published +// Description: Returns the variable's nth value. +//////////////////////////////////////////////////////////////////// +INLINE PN_int64 ConfigVariableInt64:: +get_word(int n) const { + return get_int64_word(n); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::set_word +// Access: Published +// Description: Reassigns the variable's nth value. This makes a +// local copy of the variable's overall value. +//////////////////////////////////////////////////////////////////// +INLINE void ConfigVariableInt64:: +set_word(int n, PN_int64 value) { + set_int64_word(n, value); +} + diff --git a/dtool/src/prc/configVariableInt64.cxx b/dtool/src/prc/configVariableInt64.cxx new file mode 100644 index 0000000000..061e54a48f --- /dev/null +++ b/dtool/src/prc/configVariableInt64.cxx @@ -0,0 +1,32 @@ +// Filename: configVariableInt64.cxx +// Created by: drose (19Dec07) +// +//////////////////////////////////////////////////////////////////// +// +// 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 +// aPN_int64 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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "configVariableInt64.h" + +//////////////////////////////////////////////////////////////////// +// Function: ConfigVariableInt64::set_default_value +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void ConfigVariableInt64:: +set_default_value(PN_int64 default_value) { + ostringstream strm; + strm << default_value; + + _core->set_default_value(strm.str()); +} diff --git a/dtool/src/prc/configVariableInt64.h b/dtool/src/prc/configVariableInt64.h new file mode 100644 index 0000000000..c8bedffb18 --- /dev/null +++ b/dtool/src/prc/configVariableInt64.h @@ -0,0 +1,64 @@ +// Filename: configVariableInt64.h +// Created by: drose (19Dec07) +// +//////////////////////////////////////////////////////////////////// +// +// 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 +// aint64 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 maint64ainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef CONFIGVARIABLEINT64_H +#define CONFIGVARIABLEINT64_H + +#include "dtoolbase.h" +#include "configVariable.h" +#include "numeric_types.h" + +//////////////////////////////////////////////////////////////////// +// Class : ConfigVariableInt64 +// Description : This is a convenience class to specialize +// ConfigVariable as a 64-bit integer type. +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOLCONFIG ConfigVariableInt64 : public ConfigVariable { +PUBLISHED: + INLINE ConfigVariableInt64(const string &name); + INLINE ConfigVariableInt64(const string &name, PN_int64 default_value, + const string &description = string(), + PN_int64 flags = 0); + INLINE ConfigVariableInt64(const string &name, const string &default_value, + const string &description = string(), + PN_int64 flags = 0); + + INLINE void operator = (PN_int64 value); + INLINE operator PN_int64 () const; + + INLINE PN_int64 size() const; + INLINE PN_int64 operator [] (int n) const; + + INLINE void set_value(PN_int64 value); + INLINE PN_int64 get_value() const; + INLINE PN_int64 get_default_value() const; + + INLINE PN_int64 get_word(int n) const; + INLINE void set_word(int n, PN_int64 value); + +private: + void set_default_value(PN_int64 default_value); + +private: + AtomicAdjust::Integer _local_modified; + PN_int64 _cache; +}; + +#include "configVariableInt64.I" + +#endif diff --git a/dtool/src/prc/prc_composite1.cxx b/dtool/src/prc/prc_composite1.cxx index c24895a458..2510bce8fb 100644 --- a/dtool/src/prc/prc_composite1.cxx +++ b/dtool/src/prc/prc_composite1.cxx @@ -11,4 +11,5 @@ #include "configVariableEnum.cxx" #include "configVariableFilename.cxx" #include "configVariableInt.cxx" +#include "configVariableInt64.cxx" #include "configVariableList.cxx" diff --git a/panda/src/express/config_express.N b/panda/src/express/config_express.N index 1a9b2c467b..fbc98fa0ad 100644 --- a/panda/src/express/config_express.N +++ b/panda/src/express/config_express.N @@ -26,6 +26,7 @@ forcetype ConfigVariableBool forcetype ConfigVariableDouble forcetype ConfigVariableFilename forcetype ConfigVariableInt +forcetype ConfigVariableInt64 forcetype ConfigVariableList forcetype ConfigVariableManager forcetype ConfigVariableSearchPath diff --git a/panda/src/express/config_express.h b/panda/src/express/config_express.h index d2e74cc4ce..dd67f50a68 100644 --- a/panda/src/express/config_express.h +++ b/panda/src/express/config_express.h @@ -36,6 +36,7 @@ #include "configVariableDouble.h" #include "configVariableFilename.h" #include "configVariableInt.h" +#include "configVariableInt64.h" #include "configVariableList.h" #include "configVariableManager.h" #include "configVariableSearchPath.h" diff --git a/panda/src/express/memoryUsage.cxx b/panda/src/express/memoryUsage.cxx index 63a14b705c..cc74349c49 100644 --- a/panda/src/express/memoryUsage.cxx +++ b/panda/src/express/memoryUsage.cxx @@ -400,7 +400,7 @@ MemoryUsage(const MemoryHook ©) : MemoryHook(copy) { _count_memory_usage = false; - int max_heap_size = ConfigVariableInt + PN_int64 max_heap_size = ConfigVariableInt64 ("max-heap-size", 0, PRC_DESC("If this is nonzero, it is the maximum number of bytes expected " "to be allocated on the heap before we enter report-memory-usage "