X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f905dc575e7fecaa80da130abb82d8c4370b095..db138a4c2a47b02fa9b3d0a361e626df00316ba9:/src/common/fileconf.cpp diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 9a0f899135..bc0e8aa5ac 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -2,7 +2,7 @@ // Name: fileconf.cpp // Purpose: implementation of wxFileConfig derivation of wxConfig // Author: Vadim Zeitlin -// Modified by: +// Modified by: // Created: 07.04.98 (adapted from appconf.cpp) // RCS-ID: $Id$ // Copyright: (c) 1997 Karsten Ballüder & Vadim Zeitlin @@ -10,6 +10,10 @@ // Licence: wxWindows license /////////////////////////////////////////////////////////////////////////////// +#ifdef __GNUG__ +#pragma implementation "fileconf.h" +#endif + // ============================================================================ // declarations // ============================================================================ @@ -36,8 +40,8 @@ #include // _WINDOWS_ is defined when windows.h is included, -// __WINDOWS__ is defined for MS Windows compilation -#if defined(__WINDOWS__) && !defined(_WINDOWS_) +// __WXMSW__ is defined for MS Windows compilation +#if defined(__WXMSW__) && !defined(_WINDOWS_) #include #endif //windows.h @@ -51,7 +55,7 @@ // is 'c' a valid character in group name? // NB: APPCONF_IMMUTABLE_PREFIX and APPCONF_PATH_SEPARATOR must be valid chars, // but _not_ ']' (group name delimiter) -inline bool IsValid(char c) { return isalnum(c) || strchr("_/-!.*%", c); } +inline bool IsValid(char c) { return isalnum(c) || strchr("@_/-!.*%", c); } // filter strings static wxString FilterIn(const wxString& str); @@ -127,7 +131,7 @@ wxString wxFileConfig::GetLocalFileName(const char *szFile) void wxFileConfig::Init() { - m_pCurrentGroup = + m_pCurrentGroup = m_pRootGroup = new ConfigGroup(NULL, "", this); m_linesHead = @@ -177,6 +181,13 @@ wxFileConfig::~wxFileConfig() { Flush(); delete m_pRootGroup; + + LineList *pCur = m_linesHead; + while ( pCur != NULL ) { + LineList *pNext = pCur->Next(); + delete pCur; + pCur = pNext; + } } // ---------------------------------------------------------------------------- @@ -187,7 +198,7 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal) { const char *pStart; const char *pEnd; - + for ( uint n = 0; n < file.GetLineCount(); n++ ) { // add the line to linked list if ( bLocal ) @@ -234,12 +245,12 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal) case ';': bCont = FALSE; break; - + case ' ': case '\t': // ignore whitespace ('\n' impossible here) break; - + default: wxLogWarning("file '%s', line %d: '%s' ignored after group header.", file.GetName(), n + 1, pEnd); @@ -255,7 +266,7 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal) wxString strKey(pStart, pEnd); // skip whitespace - while ( isspace(*pEnd) ) + while ( isspace(*pEnd) ) pEnd++; if ( *pEnd++ != '=' ) { @@ -284,7 +295,7 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal) // (c) key from global file now found in local one // which is exactly what we want. else if ( !bLocal || pEntry->IsLocal() ) { - wxLogWarning("file '%s', line %d: key '%s' was first found at line %d.", + wxLogWarning("file '%s', line %d: key '%s' was first found at line %d.", file.GetName(), n + 1, strKey.c_str(), pEntry->Line()); if ( bLocal ) @@ -293,7 +304,7 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal) } // skip whitespace - while ( isspace(*pEnd) ) + while ( isspace(*pEnd) ) pEnd++; wxString strValue; @@ -321,8 +332,10 @@ void wxFileConfig::SetPath(const wxString& strPath) { wxArrayString aParts; - if ( strPath.IsEmpty() ) + if ( strPath.IsEmpty() ) { + SetRootPath(); return; + } if ( strPath[0] == APPCONF_PATH_SEPARATOR ) { // absolute path @@ -388,6 +401,26 @@ bool wxFileConfig::GetNextEntry (wxString& str, long& lIndex) return FALSE; } +// ---------------------------------------------------------------------------- +// tests for existence +// ---------------------------------------------------------------------------- + +bool wxFileConfig::HasGroup(const wxString& strName) const +{ + PathChanger path(this, strName); + + ConfigGroup *pGroup = m_pCurrentGroup->FindSubgroup(path.Name()); + return pGroup != NULL; +} + +bool wxFileConfig::HasEntry(const wxString& strName) const +{ + PathChanger path(this, strName); + + ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name()); + return pEntry != NULL; +} + // ---------------------------------------------------------------------------- // read/write values // ---------------------------------------------------------------------------- @@ -536,25 +569,57 @@ wxFileConfig::LineList *wxFileConfig::LineListAppend(const wxString& str) else { // adjust pointers m_linesTail->SetNext(pLine); + pLine->SetPrev(m_linesTail); } m_linesTail = pLine; return m_linesTail; } -// insert a new line after the given one -wxFileConfig::LineList *wxFileConfig::LineListInsert(const wxString& str, +// insert a new line after the given one or in the very beginning if !pLine +wxFileConfig::LineList *wxFileConfig::LineListInsert(const wxString& str, LineList *pLine) { - if ( pLine == NULL ) + if ( pLine == m_linesTail ) return LineListAppend(str); - LineList *pNewLine = new LineList(str, pLine->Next()); - pLine->SetNext(pNewLine); + LineList *pNewLine = new LineList(str); + if ( pLine == NULL ) { + // prepend to the list + pNewLine->SetNext(m_linesHead); + m_linesHead->SetPrev(pNewLine); + m_linesHead = pNewLine; + } + else { + // insert before pLine + LineList *pNext = pLine->Next(); + pNewLine->SetNext(pNext); + pNewLine->SetPrev(pLine); + pNext->SetPrev(pNewLine); + pLine->SetNext(pNewLine); + } return pNewLine; } +void wxFileConfig::LineListRemove(LineList *pLine) +{ + LineList *pPrev = pLine->Prev(), + *pNext = pLine->Next(); + if ( pPrev == NULL ) { + // deleting the first entry + m_linesHead = pNext; + } + else { + // not the first entry + pPrev->SetNext(pNext); + } + + pNext->SetPrev(pPrev); + + delete pLine; +} + bool wxFileConfig::LineListIsEmpty() { return m_linesHead == NULL; @@ -578,9 +643,8 @@ wxFileConfig::ConfigGroup::ConfigGroup(wxFileConfig::ConfigGroup *pParent, m_pParent = pParent; m_pLine = NULL; m_bDirty = FALSE; - - m_nLastEntry = - m_nLastGroup = NOT_FOUND; + m_pLastEntry = NULL; + m_pLastGroup = NULL; } // dtor deletes all children @@ -616,13 +680,13 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetGroupLine() if ( Parent() != NULL ) { wxString strFullName; strFullName << "[" << GetFullName().c_str() + 1 << "]"; // +1: no '/' - m_pLine = m_pConfig->LineListInsert(strFullName, + m_pLine = m_pConfig->LineListInsert(strFullName, Parent()->GetLastGroupLine()); + Parent()->SetLastGroup(this); } else { - // we're the root group, yet we were not in the local file => there were - // only comments and blank lines in config file or nothing at all - // we return NULL, so that LineListInsert() will do Append() + // we return NULL, so that LineListInsert() will insert us in the + // very beginning } } @@ -635,14 +699,12 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastGroupLine() { // if we have any subgroups, our last line is the last line of the last // subgroup - if ( m_nLastGroup != NOT_FOUND ) { - return m_aSubgroups[m_nLastGroup]->GetLastGroupLine(); - } + if ( m_pLastGroup != NULL ) + return m_pLastGroup->GetLastGroupLine(); // if we have any entries, our last line is the last entry - if ( m_nLastEntry != NOT_FOUND ) { - return m_aEntries[m_nLastEntry]->GetLine(); - } + if ( m_pLastEntry != NULL ) + return m_pLastEntry->GetLine(); // nothing at all: last line is the first one return GetGroupLine(); @@ -652,10 +714,15 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastGroupLine() // (after which we can add a new entry) wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastEntryLine() { - if ( m_nLastEntry != NOT_FOUND ) - return m_aEntries[m_nLastEntry]->GetLine(); - else - return GetGroupLine(); + if ( m_pLastEntry != NULL ) { + wxFileConfig::LineList *pLine = m_pLastEntry->GetLine(); + + wxASSERT( pLine != NULL ); // last entry must have !NULL associated line + return pLine; + } + + // no entrues: insert after the group header + return GetGroupLine(); } // ---------------------------------------------------------------------------- @@ -741,7 +808,21 @@ bool wxFileConfig::ConfigGroup::DeleteSubgroup(const char *szName) if ( n == nCount ) return FALSE; - delete m_aSubgroups[n]; + nCount = m_aEntries.Count(); + for ( n = 0; n < nCount; n++ ) { + LineList *pLine = m_aEntries[n]->GetLine(); + if ( pLine != NULL ) + m_pConfig->LineListRemove(pLine); + } + + ConfigGroup *pGroup = m_aSubgroups[n]; + LineList *pLine = pGroup->m_pLine; + if ( pLine != NULL ) + m_pConfig->LineListRemove(pLine); + delete pGroup; + + SetDirty(); + m_aSubgroups.Remove(n); return TRUE; } @@ -757,13 +838,20 @@ bool wxFileConfig::ConfigGroup::DeleteEntry(const char *szName) if ( n == nCount ) return FALSE; - delete m_aEntries[n]; + ConfigEntry *pEntry = m_aEntries[n]; + LineList *pLine = pEntry->GetLine(); + if ( pLine != NULL ) + m_pConfig->LineListRemove(pLine); + delete pEntry; + + SetDirty(); + m_aEntries.Remove(n); return TRUE; } // ---------------------------------------------------------------------------- -// +// // ---------------------------------------------------------------------------- void wxFileConfig::ConfigGroup::SetDirty() { @@ -779,7 +867,7 @@ void wxFileConfig::ConfigGroup::SetDirty() // ---------------------------------------------------------------------------- // ctor // ---------------------------------------------------------------------------- -wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent, +wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent, const wxString& strName, int nLine) : m_strName(strName) @@ -807,6 +895,7 @@ void wxFileConfig::ConfigEntry::SetLine(LineList *pLine) } m_pLine = pLine; + Group()->SetLastEntry(this); } // second parameter is FALSE if we read the value from file and prevents the @@ -814,7 +903,7 @@ void wxFileConfig::ConfigEntry::SetLine(LineList *pLine) void wxFileConfig::ConfigEntry::SetValue(const wxString& strValue, bool bUser) { if ( bUser && IsImmutable() ) { - wxLogWarning("Attempt to change immutable key '%s' ignored.", + wxLogWarning("Attempt to change immutable key '%s' ignored.", Name().c_str()); return; } @@ -838,7 +927,9 @@ void wxFileConfig::ConfigEntry::SetValue(const wxString& strValue, bool bUser) // add a new line to the file wxASSERT( m_nLine == NOT_FOUND ); // consistency check - Group()->Config()->LineListInsert(strLine, Group()->GetLastEntryLine()); + m_pLine = Group()->Config()->LineListInsert(strLine, + Group()->GetLastEntryLine()); + Group()->SetLastEntry(this); } SetDirty();