// get the last line belonging to an entry/subgroup of this group
wxFileConfigLineList *GetGroupLine(); // line which contains [group]
+ // may be NULL for "/" only
wxFileConfigLineList *GetLastEntryLine(); // after which our subgroups start
wxFileConfigLineList *GetLastGroupLine(); // after which the next group starts
}
else
{
- wxLogWarning(_("can't open user configuration file '%s'."), m_fnLocalFile.GetFullPath().c_str() );
+ const wxString path = m_fnLocalFile.GetFullPath();
+ wxLogWarning(_("can't open user configuration file '%s'."),
+ path.c_str());
+
+ if ( m_fnLocalFile.FileExists() )
+ {
+ wxLogWarning(_("Changes won't be saved to avoid overwriting the existing file \"%s\""),
+ path.c_str());
+ m_fnLocalFile.Clear();
+ }
}
}
#if wxUSE_UNICODE
size_t len;
- cbuf = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen(), &len);
+ cbuf = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen() + 1, &len);
if ( !len && buf.GetDataLen() )
{
wxLogError(_("Failed to read config options."));
// notice that we throw away the original EOL kind here, maybe we
// should preserve it?
- memText.AddLine(wxString(s, e));
+ if ( e != s )
+ memText.AddLine(wxString(s, e));
if ( *e == '\0' )
break;
// add the line to linked list
if ( bLocal )
- {
LineListAppend(strLine);
- // let the root group have its start line as well
- if ( !n )
- {
- m_pCurrentGroup->SetLine(m_linesTail);
- }
- }
-
// skip leading spaces
for ( pStart = buf; wxIsspace(*pStart); pStart++ )
if ( !Read(key, &str) )
return false;
- *buf = wxBase64Decode(str.ToAscii());
+ *buf = wxBase64Decode(str);
return true;
}
SetDirty();
- // this will add a line for this group if it didn't have it before
-
+ // this will add a line for this group if it didn't have it before (or
+ // do nothing for the root but it's ok as it always exists anyhow)
(void)m_pCurrentGroup->GetGroupLine();
}
else
else
pNext->SetPrev(pPrev);
- if ( m_pRootGroup->GetGroupLine() == pLine )
- m_pRootGroup->SetLine(m_linesHead);
-
wxLogTrace( FILECONF_TRACE_MASK,
_T(" head: %s"),
((m_linesHead) ? (const wxChar*)m_linesHead->Text().c_str()
// our last entry is being deleted - find the last one which stays
wxASSERT( m_pLine != NULL ); // if we have an entry with !NULL pLine...
- // go back until we find another entry or reach the group's line
+ // find the previous entry (if any)
wxFileConfigEntry *pNewLast = NULL;
- size_t n, nEntries = m_aEntries.GetCount();
- wxFileConfigLineList *pl;
- for ( pl = pLine->Prev(); pl != m_pLine; pl = pl->Prev() ) {
- // is it our subgroup?
- for ( n = 0; (pNewLast == NULL) && (n < nEntries); n++ ) {
- if ( m_aEntries[n]->GetLine() == m_pLine )
- pNewLast = m_aEntries[n];
- }
-
- if ( pNewLast != NULL ) // found?
+ const wxFileConfigLineList * const
+ pNewLastLine = m_pLastEntry->GetLine()->Prev();
+ const size_t nEntries = m_aEntries.GetCount();
+ for ( size_t n = 0; n < nEntries; n++ ) {
+ if ( m_aEntries[n]->GetLine() == pNewLastLine ) {
+ pNewLast = m_aEntries[n];
break;
+ }
}
- if ( pl == m_pLine ) {
- wxASSERT( !pNewLast ); // how comes it has the same line as we?
-
- // we've reached the group line without finding any subgroups
- m_pLastEntry = NULL;
- }
- else
- m_pLastEntry = pNewLast;
+ // pNewLast can be NULL here -- it's ok and can happen if we have no
+ // entries left
+ m_pLastEntry = pNewLast;
}
m_pConfig->LineListRemove(pLine);
// undo FilterOutValue
static wxString FilterInValue(const wxString& str)
{
- wxString strResult;
- strResult.Alloc(str.Len());
+ wxString strResult;
+ if ( str.empty() )
+ return strResult;
- bool bQuoted = !str.empty() && str[0] == '"';
+ strResult.reserve(str.length());
- for ( size_t n = bQuoted ? 1 : 0; n < str.Len(); n++ ) {
- if ( str[n] == wxT('\\') ) {
- switch ( str[++n].GetValue() ) {
- case wxT('n'):
- strResult += wxT('\n');
- break;
+ wxString::const_iterator i = str.begin();
+ const bool bQuoted = *i == '"';
+ if ( bQuoted )
+ ++i;
- case wxT('r'):
- strResult += wxT('\r');
- break;
+ for ( const wxString::const_iterator end = str.end(); i != end; ++i )
+ {
+ if ( *i == wxT('\\') )
+ {
+ if ( ++i == end )
+ {
+ wxLogWarning(_("trailing backslash ignored in '%s'"), str.c_str());
+ break;
+ }
- case wxT('t'):
- strResult += wxT('\t');
- break;
+ switch ( (*i).GetValue() )
+ {
+ case wxT('n'):
+ strResult += wxT('\n');
+ break;
- case wxT('\\'):
- strResult += wxT('\\');
- break;
+ case wxT('r'):
+ strResult += wxT('\r');
+ break;
- case wxT('"'):
- strResult += wxT('"');
- break;
- }
- }
- else {
- if ( str[n] != wxT('"') || !bQuoted )
- strResult += str[n];
- else if ( n != str.Len() - 1 ) {
- wxLogWarning(_("unexpected \" at position %d in '%s'."),
- n, str.c_str());
- }
- //else: it's the last quote of a quoted string, ok
+ case wxT('t'):
+ strResult += wxT('\t');
+ break;
+
+ case wxT('\\'):
+ strResult += wxT('\\');
+ break;
+
+ case wxT('"'):
+ strResult += wxT('"');
+ break;
+ }
+ }
+ else // not a backslash
+ {
+ if ( *i != wxT('"') || !bQuoted )
+ {
+ strResult += *i;
+ }
+ else if ( i != end - 1 )
+ {
+ wxLogWarning(_("unexpected \" at position %d in '%s'."),
+ i - str.begin(), str.c_str());
+ }
+ //else: it's the last quote of a quoted string, ok
+ }
}
- }
- return strResult;
+ return strResult;
}
// quote the string before writing it to file