#include <stdlib.h>
#include <ctype.h>
#include <limits.h> // for INT_MAX
+#include <float.h> // for FLT_MAX
// ----------------------------------------------------------------------------
// global and class static variables
return r;
}
+// Read floats as doubles then just type cast it down.
+bool wxConfigBase::Read(const wxString& key, float* val) const
+{
+ wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") );
+
+ double temp;
+ if ( !Read(key, &temp) )
+ return false;
+
+ wxCHECK_MSG( fabs(temp) <= FLT_MAX, false,
+ wxT("float overflow in wxConfig::Read") );
+ wxCHECK_MSG( (temp == 0.0) || (fabs(temp) >= FLT_MIN), false,
+ wxT("float underflow in wxConfig::Read") );
+
+ *val = static_cast<float>(temp);
+
+ return true;
+}
+
+bool wxConfigBase::Read(const wxString& key, float* val, float defVal) const
+{
+ wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") );
+
+ if ( Read(key, val) )
+ return true;
+
+ *val = defVal;
+ return false;
+}
+
// the DoReadXXX() for the other types have implementation in the base class
// but can be overridden in the derived ones
bool wxConfigBase::DoReadBool(const wxString& key, bool* val) const
if ( !DoReadLong(key, &l) )
return false;
- wxASSERT_MSG( l == 0 || l == 1, wxT("bad bool value in wxConfig::DoReadInt") );
+ if ( l != 0 && l != 1 )
+ {
+ // Don't assert here as this could happen in the result of user editing
+ // the file directly and this not indicate a bug in the program but
+ // still complain that something is wrong.
+ wxLogWarning(_("Invalid value %ld for a boolean key \"%s\" in "
+ "config file."),
+ l, key);
+ }
*val = l != 0;
wxString str;
if ( Read(key, &str) )
{
- return str.ToDouble(val);
+ if ( str.ToCDouble(val) )
+ return true;
+
+ // Previous versions of wxFileConfig wrote the numbers out using the
+ // current locale and not the C one as now, so attempt to parse the
+ // string as a number in the current locale too, for compatibility.
+ if ( str.ToDouble(val) )
+ return true;
}
return false;
bool wxConfigBase::DoWriteDouble(const wxString& key, double val)
{
- return DoWriteString(key, wxString::Format(wxT("%g"), val));
+ // Notice that we always write out the numbers in C locale and not the
+ // current one. This makes the config files portable between machines using
+ // different locales.
+ return DoWriteString(key, wxString::FromCDouble(val));
}
bool wxConfigBase::DoWriteBool(const wxString& key, bool value)
const wxString& strEntry)
{
m_bChanged = false;
- m_pContainer = (wxConfigBase *)pContainer;
+ m_pContainer = const_cast<wxConfigBase *>(pContainer);
- // the path is everything which precedes the last slash
- wxString strPath = strEntry.BeforeLast(wxCONFIG_PATH_SEPARATOR);
+ // the path is everything which precedes the last slash and the name is
+ // everything after it -- and this works correctly if there is no slash too
+ wxString strPath = strEntry.BeforeLast(wxCONFIG_PATH_SEPARATOR, &m_strName);
// except in the special case of "/keyname" when there is nothing before "/"
if ( strPath.empty() &&
m_strOldPath += wxCONFIG_PATH_SEPARATOR;
m_pContainer->SetPath(strPath);
}
-
- // in any case, use the just the name, not full path
- m_strName = strEntry.AfterLast(wxCONFIG_PATH_SEPARATOR);
- }
- else {
- // it's a name only, without path - nothing to do
- m_strName = strEntry;
}
}