X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/894d74dcc233b7f9a936767558f3e061593dd062..761598d4e5b9f59bfc773e06f843c070d920f8b9:/src/common/fileconf.cpp diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 2cfdd601b5..3a25662db7 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: fileconf.cpp +// Name: src/common/fileconf.cpp // Purpose: implementation of wxFileConfig derivation of wxConfig // Author: Vadim Zeitlin // Modified by: @@ -10,10 +10,6 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "fileconf.h" -#endif - // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- @@ -275,7 +271,7 @@ wxString wxFileConfig::GetGlobalDir() strDir = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ; #elif defined( __UNIX__ ) strDir = wxT("/etc/"); -#elif defined(__WXPM__) +#elif defined(__OS2__) ULONG aulSysInfo[QSV_MAX] = {0}; UINT drive; APIRET rc; @@ -291,7 +287,7 @@ wxString wxFileConfig::GetGlobalDir() #elif defined(__DOS__) // There's no such thing as global cfg dir in MS-DOS, let's return // current directory (FIXME_MGL?) - return wxT(".\\"); + strDir = wxT(".\\"); #elif defined(__WXWINCE__) strDir = wxT("\\Windows\\"); #else // Windows @@ -454,16 +450,16 @@ wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName, { if ( !m_strLocalFile.empty() && !wxIsAbsolutePath(m_strLocalFile) ) { - wxString strLocal = m_strLocalFile; + const wxString strLocalOrig = m_strLocalFile; m_strLocalFile = GetLocalDir(); - m_strLocalFile << strLocal; + m_strLocalFile << strLocalOrig; } if ( !m_strGlobalFile.empty() && !wxIsAbsolutePath(m_strGlobalFile) ) { - wxString strGlobal = m_strGlobalFile; + const wxString strGlobalOrig = m_strGlobalFile; m_strGlobalFile = GetGlobalDir(); - m_strGlobalFile << strGlobal; + m_strGlobalFile << strGlobalOrig; } } @@ -495,7 +491,7 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, wxMBConv& conv) char buf[1024]; do { - inStream.Read(buf, WXSIZEOF(buf)); + inStream.Read(buf, WXSIZEOF(buf)-1); // leave room for the NULL const wxStreamError err = inStream.GetLastError(); @@ -555,28 +551,28 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, wxMBConv& conv) void wxFileConfig::CleanUp() { - delete m_pRootGroup; + delete m_pRootGroup; - wxFileConfigLineList *pCur = m_linesHead; - while ( pCur != NULL ) { - wxFileConfigLineList *pNext = pCur->Next(); - delete pCur; - pCur = pNext; - } + wxFileConfigLineList *pCur = m_linesHead; + while ( pCur != NULL ) { + wxFileConfigLineList *pNext = pCur->Next(); + delete pCur; + pCur = pNext; + } } wxFileConfig::~wxFileConfig() { - Flush(); + Flush(); - CleanUp(); + CleanUp(); } // ---------------------------------------------------------------------------- // parse a config file // ---------------------------------------------------------------------------- -void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal) +void wxFileConfig::Parse(const wxTextBuffer& buffer, bool bLocal) { const wxChar *pStart; const wxChar *pEnd; @@ -668,7 +664,7 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal) } } else { // a key - const wxChar *pEnd = pStart; + pEnd = pStart; while ( *pEnd && *pEnd != wxT('=') /* && !wxIsspace(*pEnd)*/ ) { if ( *pEnd == wxT('\\') ) { // next character may be space or not - still take it because it's @@ -742,45 +738,59 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal) void wxFileConfig::SetRootPath() { - m_strPath.Empty(); - m_pCurrentGroup = m_pRootGroup; + m_strPath.Empty(); + m_pCurrentGroup = m_pRootGroup; } -void wxFileConfig::SetPath(const wxString& strPath) +bool +wxFileConfig::DoSetPath(const wxString& strPath, bool createMissingComponents) { - wxArrayString aParts; + wxArrayString aParts; - if ( strPath.empty() ) { - SetRootPath(); - return; - } + if ( strPath.empty() ) { + SetRootPath(); + return true; + } - if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) { - // absolute path - wxSplitPath(aParts, strPath); - } - else { - // relative path, combine with current one - wxString strFullPath = m_strPath; - strFullPath << wxCONFIG_PATH_SEPARATOR << strPath; - wxSplitPath(aParts, strFullPath); - } + if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) { + // absolute path + wxSplitPath(aParts, strPath); + } + else { + // relative path, combine with current one + wxString strFullPath = m_strPath; + strFullPath << wxCONFIG_PATH_SEPARATOR << strPath; + wxSplitPath(aParts, strFullPath); + } - // change current group - size_t n; - m_pCurrentGroup = m_pRootGroup; - for ( n = 0; n < aParts.Count(); n++ ) { - wxFileConfigGroup *pNextGroup = m_pCurrentGroup->FindSubgroup(aParts[n]); - if ( pNextGroup == NULL ) - pNextGroup = m_pCurrentGroup->AddSubgroup(aParts[n]); - m_pCurrentGroup = pNextGroup; - } + // change current group + size_t n; + m_pCurrentGroup = m_pRootGroup; + for ( n = 0; n < aParts.Count(); n++ ) { + wxFileConfigGroup *pNextGroup = m_pCurrentGroup->FindSubgroup(aParts[n]); + if ( pNextGroup == NULL ) + { + if ( !createMissingComponents ) + return false; - // recombine path parts in one variable - m_strPath.Empty(); - for ( n = 0; n < aParts.Count(); n++ ) { - m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n]; - } + pNextGroup = m_pCurrentGroup->AddSubgroup(aParts[n]); + } + + m_pCurrentGroup = pNextGroup; + } + + // recombine path parts in one variable + m_strPath.Empty(); + for ( n = 0; n < aParts.Count(); n++ ) { + m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n]; + } + + return true; +} + +void wxFileConfig::SetPath(const wxString& strPath) +{ + DoSetPath(strPath, true /* create missing path components */); } // ---------------------------------------------------------------------------- @@ -789,66 +799,66 @@ void wxFileConfig::SetPath(const wxString& strPath) bool wxFileConfig::GetFirstGroup(wxString& str, long& lIndex) const { - lIndex = 0; - return GetNextGroup(str, lIndex); + lIndex = 0; + return GetNextGroup(str, lIndex); } bool wxFileConfig::GetNextGroup (wxString& str, long& lIndex) const { - if ( size_t(lIndex) < m_pCurrentGroup->Groups().Count() ) { - str = m_pCurrentGroup->Groups()[(size_t)lIndex++]->Name(); - return true; - } - else - return false; + if ( size_t(lIndex) < m_pCurrentGroup->Groups().Count() ) { + str = m_pCurrentGroup->Groups()[(size_t)lIndex++]->Name(); + return true; + } + else + return false; } bool wxFileConfig::GetFirstEntry(wxString& str, long& lIndex) const { - lIndex = 0; - return GetNextEntry(str, lIndex); + lIndex = 0; + return GetNextEntry(str, lIndex); } bool wxFileConfig::GetNextEntry (wxString& str, long& lIndex) const { - if ( size_t(lIndex) < m_pCurrentGroup->Entries().Count() ) { - str = m_pCurrentGroup->Entries()[(size_t)lIndex++]->Name(); - return true; - } - else - return false; + if ( size_t(lIndex) < m_pCurrentGroup->Entries().Count() ) { + str = m_pCurrentGroup->Entries()[(size_t)lIndex++]->Name(); + return true; + } + else + return false; } size_t wxFileConfig::GetNumberOfEntries(bool bRecursive) const { - size_t n = m_pCurrentGroup->Entries().Count(); - if ( bRecursive ) { - wxFileConfigGroup *pOldCurrentGroup = m_pCurrentGroup; - size_t nSubgroups = m_pCurrentGroup->Groups().Count(); - for ( size_t nGroup = 0; nGroup < nSubgroups; nGroup++ ) { - CONST_CAST m_pCurrentGroup = m_pCurrentGroup->Groups()[nGroup]; - n += GetNumberOfEntries(true); - CONST_CAST m_pCurrentGroup = pOldCurrentGroup; + size_t n = m_pCurrentGroup->Entries().Count(); + if ( bRecursive ) { + wxFileConfigGroup *pOldCurrentGroup = m_pCurrentGroup; + size_t nSubgroups = m_pCurrentGroup->Groups().Count(); + for ( size_t nGroup = 0; nGroup < nSubgroups; nGroup++ ) { + CONST_CAST m_pCurrentGroup = m_pCurrentGroup->Groups()[nGroup]; + n += GetNumberOfEntries(true); + CONST_CAST m_pCurrentGroup = pOldCurrentGroup; + } } - } - return n; + return n; } size_t wxFileConfig::GetNumberOfGroups(bool bRecursive) const { - size_t n = m_pCurrentGroup->Groups().Count(); - if ( bRecursive ) { - wxFileConfigGroup *pOldCurrentGroup = m_pCurrentGroup; - size_t nSubgroups = m_pCurrentGroup->Groups().Count(); - for ( size_t nGroup = 0; nGroup < nSubgroups; nGroup++ ) { - CONST_CAST m_pCurrentGroup = m_pCurrentGroup->Groups()[nGroup]; - n += GetNumberOfGroups(true); - CONST_CAST m_pCurrentGroup = pOldCurrentGroup; + size_t n = m_pCurrentGroup->Groups().Count(); + if ( bRecursive ) { + wxFileConfigGroup *pOldCurrentGroup = m_pCurrentGroup; + size_t nSubgroups = m_pCurrentGroup->Groups().Count(); + for ( size_t nGroup = 0; nGroup < nSubgroups; nGroup++ ) { + CONST_CAST m_pCurrentGroup = m_pCurrentGroup->Groups()[nGroup]; + n += GetNumberOfGroups(true); + CONST_CAST m_pCurrentGroup = pOldCurrentGroup; + } } - } - return n; + return n; } // ---------------------------------------------------------------------------- @@ -857,18 +867,28 @@ size_t wxFileConfig::GetNumberOfGroups(bool bRecursive) const bool wxFileConfig::HasGroup(const wxString& strName) const { - wxConfigPathChanger path(this, strName); + // special case: DoSetPath("") does work as it's equivalent to DoSetPath("/") + // but there is no group with empty name so treat this separately + if ( strName.empty() ) + return false; + + const wxString pathOld = GetPath(); - wxFileConfigGroup *pGroup = m_pCurrentGroup->FindSubgroup(path.Name()); - return pGroup != NULL; + wxFileConfig *self = wx_const_cast(wxFileConfig *, this); + const bool + rc = self->DoSetPath(strName, false /* don't create missing components */); + + self->SetPath(pathOld); + + return rc; } bool wxFileConfig::HasEntry(const wxString& strName) const { - wxConfigPathChanger path(this, strName); + wxConfigPathChanger path(this, strName); - wxFileConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name()); - return pEntry != NULL; + wxFileConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name()); + return pEntry != NULL; } // ---------------------------------------------------------------------------- @@ -877,16 +897,16 @@ bool wxFileConfig::HasEntry(const wxString& strName) const bool wxFileConfig::DoReadString(const wxString& key, wxString* pStr) const { - wxConfigPathChanger path(this, key); + wxConfigPathChanger path(this, key); - wxFileConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name()); - if (pEntry == NULL) { - return false; - } + wxFileConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name()); + if (pEntry == NULL) { + return false; + } - *pStr = pEntry->Value(); + *pStr = pEntry->Value(); - return true; + return true; } bool wxFileConfig::DoReadLong(const wxString& key, long *pl) const @@ -1098,12 +1118,13 @@ bool wxFileConfig::DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso) if ( !m_pCurrentGroup->DeleteEntry(path.Name()) ) return false; + SetDirty(); + if ( bGroupIfEmptyAlso && m_pCurrentGroup->IsEmpty() ) { if ( m_pCurrentGroup != m_pRootGroup ) { wxFileConfigGroup *pGroup = m_pCurrentGroup; SetPath(wxT("..")); // changes m_pCurrentGroup! - if ( m_pCurrentGroup->DeleteSubgroupByName(pGroup->Name()) ) - SetDirty(); + m_pCurrentGroup->DeleteSubgroupByName(pGroup->Name()); } //else: never delete the root group } @@ -1326,8 +1347,11 @@ wxFileConfigGroup::~wxFileConfigGroup() void wxFileConfigGroup::SetLine(wxFileConfigLineList *pLine) { - // shouldn't be called twice unless we are resetting the line - wxASSERT( m_pLine == 0 || pLine == 0 ); + // for a normal (i.e. not root) group this method shouldn't be called twice + // unless we are resetting the line + wxASSERT_MSG( !m_pParent || !m_pLine || !pLine, + _T("changing line for a non-root group?") ); + m_pLine = pLine; } @@ -1851,20 +1875,11 @@ void wxFileConfigEntry::SetValue(const wxString& strValue, bool bUser) } else // this entry didn't exist in the local file { - // add a new line to the file: note the hack for the root group - // which is special in that it doesn't have its own group line - // (something like "[/]") and so the line we get for it may be not - // its line at all if it doesn't have any entries - // - // this is definitely not the right place to fix it but changing - // the root group to have NULL m_pLine will probably break too - // much stuff elsewhere so I don't dare to do it... + // add a new line to the file: note that line returned by + // GetLastEntryLine() may be NULL if we're in the root group and it + // doesn't have any entries yet, but this is ok as passing NULL + // line to LineListInsert() means to prepend new line to the list wxFileConfigLineList *line = Group()->GetLastEntryLine(); - if ( !Group()->Parent() && line == Group()->GetGroupLine() ) - { - // prepend the first root group entry to the head of the list - line = NULL; - } m_pLine = Group()->Config()->LineListInsert(strLine, line); Group()->SetLastEntry(this); @@ -2061,4 +2076,3 @@ static wxString GetAppName(const wxString& appName) } #endif // wxUSE_CONFIG -