]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fileconf.cpp
ODBC compile (and link) fixes
[wxWidgets.git] / src / common / fileconf.cpp
index 2482693f65c857e8711b32a928e6a13ac5650432..a3f3df3f2c02acc6c0f5fbc283f074b0e72b226f 100644 (file)
 //     but _not_ ']' (group name delimiter)
 inline bool IsValid(char c) { return isalnum(c) || strchr("@_/-!.*%", c); }
 
+// compare functions for sorting the arrays
+static int CompareEntries(wxFileConfig::ConfigEntry *p1,
+                          wxFileConfig::ConfigEntry *p2);
+static int CompareGroups(wxFileConfig::ConfigGroup *p1,
+                         wxFileConfig::ConfigGroup *p2);
+
 // filter strings
 static wxString FilterIn(const wxString& str);
 static wxString FilterOut(const wxString& str);
@@ -101,7 +107,7 @@ wxString wxFileConfig::GetLocalFileName(const char *szFile)
     const char *szHome = getenv("HOME");
     if ( szHome == NULL ) {
       // we're homeless...
-      wxLogWarning("can't find user's HOME, using current directory.");
+      wxLogWarning(_("can't find user's HOME, using current directory."));
       szHome = ".";
     }
     str << szHome << "/." << szFile;
@@ -159,7 +165,7 @@ wxFileConfig::wxFileConfig(const wxString& strLocal, const wxString& strGlobal)
         SetRootPath();
       }
       else
-        wxLogWarning("Can't open global configuration file '%s'.",
+        wxLogWarning(_("can't open global configuration file '%s'."),
                      strGlobal.c_str());
     }
   }
@@ -172,7 +178,7 @@ wxFileConfig::wxFileConfig(const wxString& strLocal, const wxString& strGlobal)
       SetRootPath();
     }
     else
-      wxLogWarning("Can't open user configuration file '%s'.",
+      wxLogWarning(_("can't open user configuration file '%s'."),
                    strLocal.c_str());
   }
 }
@@ -181,6 +187,13 @@ wxFileConfig::~wxFileConfig()
 {
   Flush();
   delete m_pRootGroup;
+
+  LineList *pCur = m_linesHead;
+  while ( pCur != NULL ) {
+    LineList *pNext = pCur->Next();
+    delete pCur;
+    pCur = pNext;
+  }
 }
 
 // ----------------------------------------------------------------------------
@@ -214,8 +227,8 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
       }
 
       if ( *pEnd != ']' ) {
-        wxLogError("file '%s': unexpected character at line %d (missing ']'?)",
-                   file.GetName(), n + 1);
+        wxLogError(_("file '%s': unexpected character %c at line %d."),
+                   file.GetName(), *pEnd, n + 1);
         continue; // skip this line
       }
 
@@ -245,7 +258,8 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
             break;
 
           default:
-            wxLogWarning("file '%s', line %d: '%s' ignored after group header.",
+            wxLogWarning(_("file '%s', line %d: '%s' "
+                           "ignored after group header."),
                          file.GetName(), n + 1, pEnd);
             bCont = FALSE;
         }
@@ -263,7 +277,8 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
         pEnd++;
 
       if ( *pEnd++ != '=' ) {
-        wxLogError("file '%s', line %d: '=' expected.", file.GetName(), n + 1);
+        wxLogError(_("file '%s', line %d: '=' expected."),
+                   file.GetName(), n + 1);
       }
       else {
         ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(strKey);
@@ -278,7 +293,8 @@ void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
         else {
           if ( bLocal && pEntry->IsImmutable() ) {
             // immutable keys can't be changed by user
-            wxLogWarning("file '%s', line %d: value for immutable key '%s' ignored.",
+            wxLogWarning(_("file '%s', line %d: value for "
+                           "immutable key '%s' ignored."),
                          file.GetName(), n + 1, strKey.c_str());
             continue;
           }
@@ -288,7 +304,8 @@ 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 )
@@ -485,14 +502,14 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
   wxTempFile file(m_strLocalFile);
 
   if ( !file.IsOpened() ) {
-    wxLogError("Can't open user configuration file.");
+    wxLogError(_("can't open user configuration file."));
     return FALSE;
   }
 
   // write all strings to file
   for ( LineList *p = m_linesHead; p != NULL; p = p->Next() ) {
     if ( !file.Write(p->Text() + wxTextFile::GetEOL()) ) {
-      wxLogError("Can't write user configuration file.");
+      wxLogError(_("can't write user configuration file."));
       return FALSE;
     }
   }
@@ -537,11 +554,11 @@ bool wxFileConfig::DeleteAll()
   Init();
 
   if ( remove(szFile) == -1 )
-    wxLogSysError("Can't delete user configuration file '%s'", szFile);
+    wxLogSysError(_("can't delete user configuration file '%s'"), szFile);
 
   szFile = m_strGlobalFile;
   if ( remove(szFile) )
-    wxLogSysError("Can't delete system configuration file '%s'", szFile);
+    wxLogSysError(_("can't delete system configuration file '%s'"), szFile);
 
   return TRUE;
 }
@@ -630,7 +647,9 @@ bool wxFileConfig::LineListIsEmpty()
 wxFileConfig::ConfigGroup::ConfigGroup(wxFileConfig::ConfigGroup *pParent,
                                        const wxString& strName,
                                        wxFileConfig *pConfig)
-                         : m_strName(strName)
+                         : m_aEntries(CompareEntries),
+                           m_aSubgroups(CompareGroups),
+                           m_strName(strName)
 {
   m_pConfig = pConfig;
   m_pParent = pParent;
@@ -734,13 +753,32 @@ wxString wxFileConfig::ConfigGroup::GetFullName() const
 // find an item
 // ----------------------------------------------------------------------------
 
+// use binary search because the array is sorted
 wxFileConfig::ConfigEntry *
 wxFileConfig::ConfigGroup::FindEntry(const char *szName) const
 {
-  uint nCount = m_aEntries.Count();
-  for ( uint n = 0; n < nCount; n++ ) {
-    if ( m_aEntries[n]->Name().IsSameAs(szName, APPCONF_CASE_SENSITIVE) )
-      return m_aEntries[n];
+  uint i,
+       lo = 0,
+       hi = m_aEntries.Count();
+  int res;
+  wxFileConfig::ConfigEntry *pEntry;
+
+  while ( lo < hi ) {
+    i = (lo + hi)/2;
+    pEntry = m_aEntries[i];
+
+    #if APPCONF_CASE_SENSITIVE
+      res = strcmp(pEntry->Name(), szName);
+    #else
+      res = Stricmp(pEntry->Name(), szName);
+    #endif
+
+    if ( res < 0 )
+      hi = i;
+    else if ( res > 0 )
+      lo = i + 1;
+    else
+      return pEntry;
   }
 
   return NULL;
@@ -749,10 +787,28 @@ wxFileConfig::ConfigGroup::FindEntry(const char *szName) const
 wxFileConfig::ConfigGroup *
 wxFileConfig::ConfigGroup::FindSubgroup(const char *szName) const
 {
-  uint nCount = m_aSubgroups.Count();
-  for ( uint n = 0; n < nCount; n++ ) {
-    if ( m_aSubgroups[n]->Name().IsSameAs(szName, APPCONF_CASE_SENSITIVE) )
-      return m_aSubgroups[n];
+  uint i,
+       lo = 0,
+       hi = m_aSubgroups.Count();
+  int res;
+  wxFileConfig::ConfigGroup *pGroup;
+
+  while ( lo < hi ) {
+    i = (lo + hi)/2;
+    pGroup = m_aSubgroups[i];
+
+    #if APPCONF_CASE_SENSITIVE
+      res = strcmp(pGroup->Name(), szName);
+    #else
+      res = Stricmp(pGroup->Name(), szName);
+    #endif
+
+    if ( res < 0 )
+      hi = i;
+    else if ( res > 0 )
+      lo = i + 1;
+    else
+      return pGroup;
   }
 
   return NULL;
@@ -883,7 +939,7 @@ wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent,
 void wxFileConfig::ConfigEntry::SetLine(LineList *pLine)
 {
   if ( m_pLine != NULL ) {
-    wxLogWarning("Entry '%s' appears more than once in group '%s'",
+    wxLogWarning(_("entry '%s' appears more than once in group '%s'"),
                  Name().c_str(), m_pParent->GetFullName().c_str());
   }
 
@@ -896,7 +952,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;
   }
@@ -939,10 +995,39 @@ void wxFileConfig::ConfigEntry::SetDirty()
 // global functions
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// compare functions for array sorting
+// ----------------------------------------------------------------------------
+
+int CompareEntries(wxFileConfig::ConfigEntry *p1,
+                   wxFileConfig::ConfigEntry *p2)
+{
+  #if APPCONF_CASE_SENSITIVE
+    return strcmp(p1->Name(), p2->Name());
+  #else
+    return Stricmp(p1->Name(), p2->Name());
+  #endif
+}
+
+int CompareGroups(wxFileConfig::ConfigGroup *p1,
+                  wxFileConfig::ConfigGroup *p2)
+{
+  #if APPCONF_CASE_SENSITIVE
+    return strcmp(p1->Name(), p2->Name());
+  #else
+    return Stricmp(p1->Name(), p2->Name());
+  #endif
+}
+
+// ----------------------------------------------------------------------------
+// filter functions
+// ----------------------------------------------------------------------------
+
 // undo FilterOut
 wxString FilterIn(const wxString& str)
 {
   wxString strResult;
+  strResult.Alloc(str.Len());
 
   bool bQuoted = !str.IsEmpty() && str[0] == '"';
 
@@ -953,6 +1038,10 @@ wxString FilterIn(const wxString& str)
           strResult += '\n';
           break;
 
+        case 'r':
+          strResult += '\r';
+          break;
+
         case 't':
           strResult += '\t';
           break;
@@ -969,8 +1058,10 @@ wxString FilterIn(const wxString& str)
     else {
       if ( str[n] != '"' || !bQuoted )
         strResult += str[n];
-      else if ( n != str.Len() - 1 )
-        wxLogWarning("unexpected \" at position %d in '%s'.", n, str.c_str());
+      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
     }
   }
@@ -982,6 +1073,7 @@ wxString FilterIn(const wxString& str)
 wxString FilterOut(const wxString& str)
 {
   wxString strResult;
+  strResult.Alloc(str.Len());
 
   // quoting is necessary to preserve spaces in the beginning of the string
   bool bQuote = isspace(str[0]) || str[0] == '"';
@@ -996,6 +1088,10 @@ wxString FilterOut(const wxString& str)
         c = 'n';
         break;
 
+      case '\r':
+        c = 'r';
+        break;
+
       case '\t':
         c = 't';
         break;