summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Storz <eduard.braun2@gmx.de>2019-07-22 20:33:48 +0000
committerPatrick Storz <eduard.braun2@gmx.de>2019-07-22 23:15:57 +0000
commit624aeeae6ae43c2c298462cbd1108f2e5ad7fbef (patch)
treedd202b8cbd2088698ce8281d9d024d91643b5e42
parentUpdate jhbuild (diff)
downloadinkscape-624aeeae6ae43c2c298462cbd1108f2e5ad7fbef.tar.gz
inkscape-624aeeae6ae43c2c298462cbd1108f2e5ad7fbef.zip
Preferences: add methods to set/get unsigned integers
Those should be used for RGBA color values, which would overflow the signed type otherwise. Replacement will be seamless and fully backwards-compatible, as we can read the overflowed (i.e. negative) signed integers we used to save and they will be properly unwrapped. Also reading the unsigned ints as signed ints in older versions of Inkscape will still work, as we always depended on the undefined behavior of atoi in case of out of range numbers (which luckily is means overflowing in gcc).
-rw-r--r--src/preferences.cpp31
-rw-r--r--src/preferences.h80
2 files changed, 101 insertions, 10 deletions
diff --git a/src/preferences.cpp b/src/preferences.cpp
index dc0c0d609..018ba7b01 100644
--- a/src/preferences.cpp
+++ b/src/preferences.cpp
@@ -391,6 +391,17 @@ void Preferences::setInt(Glib::ustring const &pref_path, int value)
}
/**
+ * Set an unsigned integer attribute of a preference.
+ *
+ * @param pref_path Path of the preference to modify.
+ * @param value The new value of the pref attribute.
+ */
+void Preferences::setUInt(Glib::ustring const &pref_path, unsigned int value)
+{
+ _setRawValue(pref_path, Glib::ustring::compose("%1",value));
+}
+
+/**
* Set a floating point attribute of a preference.
*
* @param pref_path Path of the preference to modify.
@@ -804,6 +815,26 @@ int Preferences::_extractInt(Entry const &v)
}
}
+unsigned int Preferences::_extractUInt(Entry const &v)
+{
+ if (v.cached_uint) return v.value_uint;
+ v.cached_uint = true;
+ gchar const *s = static_cast<gchar const *>(v._value);
+
+ // Note: 'strtoul' can also read overflowed (i.e. negative) signed int values that we used to save before we
+ // had the unsigned type, so this is fully backwards compatible and can be replaced seamlessly
+ unsigned int val = 0;
+ errno = 0;
+ val = (unsigned int)strtoul(s, nullptr, 0);
+ if (errno == ERANGE) {
+ g_warning("Unsigned integer preference out of range: '%s' (raw value: %s)", v._pref_path.c_str(), s);
+ val = 0;
+ }
+
+ v.value_uint = val;
+ return v.value_uint;
+}
+
double Preferences::_extractDouble(Entry const &v)
{
if (v.cached_double) return v.value_double;
diff --git a/src/preferences.h b/src/preferences.h
index 0ec81a6fd..d977fd73c 100644
--- a/src/preferences.h
+++ b/src/preferences.h
@@ -127,11 +127,17 @@ public:
friend class Preferences; // Preferences class has to access _value
public:
~Entry() = default;
- Entry() : _pref_path(""), _value(nullptr),
- cached_bool(false), cached_point(false), cached_int(false), cached_double(false), cached_unit(false), cached_color(false), cached_style(false) {
-
-
- } // needed to enable use in maps
+ Entry()
+ : _pref_path("")
+ , _value(nullptr)
+ , cached_bool(false)
+ , cached_point(false)
+ , cached_int(false)
+ , cached_uint(false)
+ , cached_double(false)
+ , cached_unit(false)
+ , cached_color(false)
+ , cached_style(false) {} // needed to enable use in maps
Entry(Entry const &other) = default;
/**
@@ -176,6 +182,13 @@ public:
inline int getIntLimited(int def=0, int min=INT_MIN, int max=INT_MAX) const;
/**
+ * Interpret the preference as an unsigned integer.
+ *
+ * @param def Default value if the preference is not set.
+ */
+ inline unsigned int getUInt(unsigned int def=0) const;
+
+ /**
* Interpret the preference as a floating point value.
*
* @param def Default value if the preference is not set.
@@ -243,22 +256,38 @@ public:
*/
Glib::ustring getEntryName() const;
private:
- Entry(Glib::ustring path, void const *v) : _pref_path(std::move(path)), _value(v),
- cached_bool(false), cached_point (false), cached_int (false), cached_double(false), cached_unit(false), cached_color(false), cached_style(false) {}
+ Entry(Glib::ustring path, void const *v)
+ : _pref_path(std::move(path))
+ , _value(v)
+ , cached_bool(false)
+ , cached_point(false)
+ , cached_int(false)
+ , cached_uint(false)
+ , cached_double(false)
+ , cached_unit(false)
+ , cached_color(false)
+ , cached_style(false) {}
Glib::ustring _pref_path;
void const *_value;
-
+
mutable bool value_bool;
mutable Geom::Point value_point;
mutable int value_int;
+ mutable unsigned int value_uint;
mutable double value_double;
mutable Glib::ustring value_unit;
mutable guint32 value_color;
mutable SPCSSAttr* value_style;
- mutable bool cached_bool, cached_point, cached_int, cached_double, cached_unit, cached_color, cached_style;
-
+ mutable bool cached_bool;
+ mutable bool cached_point;
+ mutable bool cached_int;
+ mutable bool cached_uint;
+ mutable bool cached_double;
+ mutable bool cached_unit;
+ mutable bool cached_color;
+ mutable bool cached_style;
};
// disable copying
@@ -372,6 +401,22 @@ public:
return getEntry(pref_path).getIntLimited(def, min, max);
}
+ /**
+ * Retrieve an unsigned integer.
+ *
+ * @param pref_path Path to the retrieved preference.
+ * @param def The default value to return if the preference is not set.
+ */
+ unsigned int getUInt(Glib::ustring const &pref_path, unsigned int def=0) {
+ return getEntry(pref_path).getUInt(def);
+ }
+
+ /**
+ * Retrieve a floating point value.
+ *
+ * @param pref_path Path to the retrieved preference.
+ * @param def The default value to return if the preference is not set.
+ */
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit = "") {
return getEntry(pref_path).getDouble(def, unit);
}
@@ -470,6 +515,11 @@ public:
void setInt(Glib::ustring const &pref_path, int value);
/**
+ * Set an unsigned integer value.
+ */
+ void setUInt(Glib::ustring const &pref_path, unsigned int value);
+
+ /**
* Set a floating point value.
*/
void setDouble(Glib::ustring const &pref_path, double value);
@@ -567,6 +617,7 @@ protected:
bool _extractBool(Entry const &v);
Geom::Point _extractPoint(Entry const &v);
int _extractInt(Entry const &v);
+ unsigned int _extractUInt(Entry const &v);
double _extractDouble(Entry const &v);
double _extractDouble(Entry const &v, Glib::ustring const &requested_unit);
Glib::ustring _extractString(Entry const &v);
@@ -656,6 +707,15 @@ inline int Preferences::Entry::getIntLimited(int def, int min, int max) const
}
}
+inline unsigned int Preferences::Entry::getUInt(unsigned int def) const
+{
+ if (!this->isValid()) {
+ return def;
+ } else {
+ return Inkscape::Preferences::get()->_extractUInt(*this);
+ }
+}
+
inline double Preferences::Entry::getDouble(double def, Glib::ustring const &unit) const
{
if (!this->isValid()) {