X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9d55bfef2cb35ac07972e76c786d265c9b35d230..62795f413a7222863b4aee76c08764071f94bd87:/src/common/config.cpp diff --git a/src/common/config.cpp b/src/common/config.cpp index c139a2c832..852dd13f17 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -4,7 +4,6 @@ // Author: Vadim Zeitlin // Modified by: // Created: 07.04.98 -// RCS-ID: $Id$ // Copyright: (c) 1997 Karsten Ballueder Ballueder@usa.net // Vadim Zeitlin // Licence: wxWindows licence @@ -43,6 +42,7 @@ #include #include #include // for INT_MAX +#include // for FLT_MAX // ---------------------------------------------------------------------------- // global and class static variables @@ -62,10 +62,8 @@ bool wxConfigBase::ms_bAutoCreate = true; wxConfigBase *wxAppTraitsBase::CreateConfig() { return new - #if defined(__WXMSW__) && wxUSE_CONFIG_NATIVE + #if defined(__WINDOWS__) && wxUSE_CONFIG_NATIVE wxRegConfig(wxTheApp->GetAppName(), wxTheApp->GetVendorName()); - #elif defined(__WXPALMOS__) && wxUSE_CONFIG_NATIVE - wxPrefConfig(wxTheApp->GetAppName()); #else // either we're under Unix or wish to use files even under Windows wxFileConfig(wxTheApp->GetAppName()); #endif @@ -105,7 +103,7 @@ wxConfigBase *wxConfigBase::Create() { if ( ms_bAutoCreate && ms_pConfig == NULL ) { wxAppTraits * const traits = wxTheApp ? wxTheApp->GetTraits() : NULL; - wxCHECK_MSG( traits, NULL, _T("create wxApp before calling this") ); + wxCHECK_MSG( traits, NULL, wxT("create wxApp before calling this") ); ms_pConfig = traits->CreateConfig(); } @@ -121,7 +119,7 @@ wxConfigBase *wxConfigBase::Create() #define IMPLEMENT_READ_FOR_TYPE(name, type, deftype, extra) \ bool wxConfigBase::Read(const wxString& key, type *val) const \ { \ - wxCHECK_MSG( val, false, _T("wxConfig::Read(): NULL parameter") ); \ + wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") ); \ \ if ( !DoRead##name(key, val) ) \ return false; \ @@ -135,7 +133,7 @@ wxConfigBase *wxConfigBase::Create() type *val, \ deftype defVal) const \ { \ - wxCHECK_MSG( val, false, _T("wxConfig::Read(): NULL parameter") ); \ + wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") ); \ \ bool read = DoRead##name(key, val); \ if ( !read ) \ @@ -166,7 +164,7 @@ bool wxConfigBase::Read(const wxString& key, int *pi) const { long l = *pi; bool r = Read(key, &l); - wxASSERT_MSG( l < INT_MAX, _T("int overflow in wxConfig::Read") ); + wxASSERT_MSG( l < INT_MAX, wxT("int overflow in wxConfig::Read") ); *pi = (int)l; return r; } @@ -175,22 +173,60 @@ bool wxConfigBase::Read(const wxString& key, int *pi, int defVal) const { long l = *pi; bool r = Read(key, &l, defVal); - wxASSERT_MSG( l < INT_MAX, _T("int overflow in wxConfig::Read") ); + wxASSERT_MSG( l < INT_MAX, wxT("int overflow in wxConfig::Read") ); *pi = (int)l; 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(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 { - wxCHECK_MSG( val, false, _T("wxConfig::Read(): NULL parameter") ); + wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") ); long l; if ( !DoReadLong(key, &l) ) return false; - wxASSERT_MSG( l == 0 || l == 1, _T("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; @@ -202,7 +238,14 @@ bool wxConfigBase::DoReadDouble(const wxString& key, double* val) const 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; @@ -225,7 +268,10 @@ wxString wxConfigBase::ExpandEnvVars(const wxString& str) const bool wxConfigBase::DoWriteDouble(const wxString& key, double val) { - return DoWriteString(key, wxString::Format(_T("%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) @@ -241,10 +287,11 @@ wxConfigPathChanger::wxConfigPathChanger(const wxConfigBase *pContainer, const wxString& strEntry) { m_bChanged = false; - m_pContainer = (wxConfigBase *)pContainer; + m_pContainer = const_cast(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() && @@ -269,20 +316,13 @@ wxConfigPathChanger::wxConfigPathChanger(const wxConfigBase *pContainer, pConfig->SetPath(wxT("MySettings")); pConfig->SetPath(wxT("..")); int value; - pConfig->Read(_T("MainWindowX"), & value); + pConfig->Read(wxT("MainWindowX"), & value); */ m_strOldPath = m_pContainer->GetPath().wc_str(); if ( *m_strOldPath.c_str() != wxCONFIG_PATH_SEPARATOR ) 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; } } @@ -344,7 +384,7 @@ enum Bracket Bracket_None, Bracket_Normal = ')', Bracket_Curly = '}', -#ifdef __WXMSW__ +#ifdef __WINDOWS__ Bracket_Windows = '%', // yeah, Windows people are a bit strange ;-) #endif Bracket_Max @@ -358,17 +398,17 @@ wxString wxExpandEnvVars(const wxString& str) size_t m; for ( size_t n = 0; n < str.length(); n++ ) { switch ( str[n].GetValue() ) { -#ifdef __WXMSW__ +#ifdef __WINDOWS__ case wxT('%'): -#endif //WINDOWS +#endif // __WINDOWS__ case wxT('$'): { Bracket bracket; - #ifdef __WXMSW__ + #ifdef __WINDOWS__ if ( str[n] == wxT('%') ) bracket = Bracket_Windows; else - #endif //WINDOWS + #endif // __WINDOWS__ if ( n == str.length() - 1 ) { bracket = Bracket_None; } @@ -393,7 +433,7 @@ wxString wxExpandEnvVars(const wxString& str) while ( m < str.length() && (wxIsalnum(str[m]) || str[m] == wxT('_')) ) m++; - + wxString strVarName(str.c_str() + n + 1, m - n - 1); #ifdef __WXWINCE__ @@ -412,7 +452,7 @@ wxString wxExpandEnvVars(const wxString& str) #endif { // variable doesn't exist => don't change anything - #ifdef __WXMSW__ + #ifdef __WINDOWS__ if ( bracket != Bracket_Windows ) #endif if ( bracket != Bracket_None ) @@ -429,10 +469,10 @@ wxString wxExpandEnvVars(const wxString& str) // // under Unix, OTOH, this warning could be useful for the user to // understand why isn't the variable expanded as intended - #ifndef __WXMSW__ + #ifndef __WINDOWS__ wxLogWarning(_("Environment variables expansion failed: missing '%c' at position %u in '%s'."), (char)bracket, (unsigned int) (m + 1), str.c_str()); - #endif // __WXMSW__ + #endif // __WINDOWS__ } else { // skip closing bracket unless the variables wasn't expanded @@ -479,9 +519,13 @@ void wxSplitPath(wxArrayString& aParts, const wxString& path) else if ( strCurrent == wxT("..") ) { // go up one level if ( aParts.size() == 0 ) + { wxLogWarning(_("'%s' has extra '..', ignored."), path); + } else + { aParts.erase(aParts.end() - 1); + } strCurrent.Empty(); }