[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: KConfig borkage
From:       "Thomas Braxton" <kde.braxton () gmail ! com>
Date:       2007-10-29 2:57:30
Message-ID: 928c3f1b0710281957s4ac33d34v2d3e261eb1778980 () mail ! gmail ! com
[Download RAW message or body]

On 10/28/07, Thomas Braxton <kde.braxton@gmail.com> wrote:
>
>
>
> On 10/28/07, Oswald Buddenhagen <ossi@kde.org> wrote:
> >
> > On Sun, Oct 28, 2007 at 07:19:19AM -0400, Jeff Mitchell wrote:
> > > On Sunday 28 October 2007, Thomas Braxton wrote:
> > > > On 10/28/07, Jeff Mitchell <kde-dev@emailgoeshere.com > wrote:
> > > > > There is a [PortableDevices] section that is occasionally added to
> > > > > or deleted from.  The problem is that whenever the last
> > > > > (positionally, not numerically) entry is removed, it's not
> > > > > actually removed, but rather gets corrupted somehow.
> > > >
> > > > actually is not getting corrupted, it's being marked as deleted.
> > >
> > > Why actually delete some, and only mark others?
> > >
> > if there is no default, there is no point in overshadowing it.
> > if you don't understand it, revisit the cascading config concept.
> >
> > > > Is there a default set for those keys in
> > KDEDIR/share/config/amarokrc?
> > > > because the entries shouldn't be marked as deleted unless there was
> > a
> > > > default, I'll look into this.
> > >
> > > No, there isn't.  No defaults.
> > >
> > maybe a real bug then. thomas, your turn. :-P
>
>
>
> yeah a bug, I'm still trying to figure out why it's treating some entries
> as having defaults when they don't. It's in the backend when the entries are
> actually written to disk. I have a fix, but it's not quite right, it breaks
> something else, something wierd happening here. I'll try to get this fixed
> today.
>

Ok, I've had time to work on this. This patch fixes the wierdness and
removes entries from other locales from the entryMap, since I was already in
the area ;) I also added a test, since the test for "stringEntry1[fr]" was
wrong since KConfigGroup was saving the key as "stringEntry1\x5cfr\x5d", I
think those are the right codes. So take a look and let me know what you
think.

 Index: tests/kconfigtest.cpp
===================================================================
--- tests/kconfigtest.cpp (revision 730047)
+++ tests/kconfigtest.cpp (working copy)
@@ -90,7 +90,6 @@
   cg.writeEntry( ESCAPEKEY, ESCAPEENTRY );
   cg.writeEntry( "emptyEntry", "");
   cg.writeEntry( "stringEntry1", STRINGENTRY1 );
-  cg.writeEntry( "stringEntry1[fr]", TRANSLATEDSTRINGENTRY1 );
   cg.writeEntry( "stringEntry2", STRINGENTRY2 );
   cg.writeEntry( "stringEntry3", STRINGENTRY3 );
   cg.writeEntry( "stringEntry4", STRINGENTRY4 );
@@ -258,6 +257,36 @@
   QCOMPARE( sc3.readEntry( "doubleEntry1", 0.0 ), DOUBLEENTRY );
 }

+void KConfigTest::testLocale()
+{
+    KConfig config("kconfigtest");
+    config.setLocale("fr");
+    KConfigGroup group = config.group("Hello");
+    group.writeEntry("stringEntry1", QString(TRANSLATEDSTRINGENTRY1),
KConfig::Localized|KConfig::Persistent);
+    config.sync();
+
+    int count=0;
+    foreach(const QByteArray& line, readLines())
+        if (line.startsWith("stringEntry1[fr]"))
+            count++;
+    QVERIFY(count == 1);
+    QCOMPARE(group.readEntry("stringEntry1", QString()),
QString(TRANSLATEDSTRINGENTRY1));
+
+    config.setLocale("C"); // strings written in the "C" locale are written
as nonlocalized
+    group.writeEntry("stringEntry1", QString(STRINGENTRY1),
KConfig::Localized|KConfig::Persistent);
+    config.sync();
+
+    count=0;
+    foreach(const QByteArray& line, readLines()) {
+        if (line.startsWith("stringEntry1"))
+            count++;
+        if (line.contains("[C]"))
+            count--;
+    }
+    QVERIFY(count == 1);
+    QCOMPARE(group.readEntry("stringEntry1", QString()),
QString(STRINGENTRY1));
+}
+
 void KConfigTest::testLists()
 {
   KConfig sc2( "kconfigtest" );
@@ -388,8 +417,6 @@
     QMap<QString, QString> entryMap = cg.entryMap();
     qDebug() << entryMap.keys();
     QCOMPARE(entryMap.value("stringEntry1"), QString(STRINGENTRY1));
-    // #### Why is this translated entry here? This just bloats the
entryMap.
-    QCOMPARE(entryMap.value("stringEntry1[fr]"),
QString(TRANSLATEDSTRINGENTRY1));
     QCOMPARE(entryMap.value("stringEntry2"), QString(STRINGENTRY2));
     QCOMPARE(entryMap.value("stringEntry3"), QString(STRINGENTRY3));
     QCOMPARE(entryMap.value("stringEntry4"), QString(STRINGENTRY4));
@@ -500,6 +527,23 @@
   QVERIFY( sc.entryMap("AAA").isEmpty() );
   QVERIFY( !sc.entryMap("Hello").isEmpty() ); //not deleted group
   QVERIFY( sc.entryMap("FooBar").isEmpty() ); //inexistant group
+
+  // test for entries that are marked as deleted when there is no default
+  KConfig config("kconfigtest", KConfig::SimpleConfig); // make sure there
are no defaults
+  cg = config.group("Portable Devices");
+  cg.writeEntry("devices|manual|(null)", "whatever");
+  cg.writeEntry("devices|manual|/mnt/ipod", "/mnt/ipod");
+  cg.sync();
+
+  int count=0;
+  foreach(const QByteArray& item, readLines())
+      if (item.startsWith("devices|"))
+          count++;
+  QVERIFY(count == 2);
+  cg.deleteEntry("devices|manual|/mnt/ipod");
+  cg.sync();
+  foreach(const QByteArray& item, readLines())
+      QVERIFY(item != "devices|manual|/mnt/ipod[$d]");
 }

 void KConfigTest::testDefaultGroup()
Index: tests/kconfigtest.h
===================================================================
--- tests/kconfigtest.h (revision 730047)
+++ tests/kconfigtest.h (working copy)
@@ -36,6 +36,7 @@
     void initTestCase();
     void cleanupTestCase();
     void testSimple();
+    void testLocale();
     void testLists();
     void testPath();
     void testPersistenceOfExpandFlagForPath();
Index: config/kconfigdata.h
===================================================================
--- config/kconfigdata.h (revision 730047)
+++ config/kconfigdata.h (working copy)
@@ -302,6 +302,18 @@
         {
             return getEntryOption(findEntry(group, key, flags), option);
         }
+        void removeEntry(const KEntryKey& key)
+        {
+            remove(key);
+            int count=0;
+            foreach(const KEntryKey& item, keys())
+                if(item.mGroup == key.mGroup && !item.mKey.isEmpty())
+                    count++;
+            if (!count) {
+                const KEntryKey groupKey(key.mGroup);
+                remove(groupKey);
+            }
+        }

         void setEntryOption(Iterator it, EntryOption option, bool bf)
         {
Index: config/kconfigini.cpp
===================================================================
--- config/kconfigini.cpp (revision 730047)
+++ config/kconfigini.cpp (working copy)
@@ -202,10 +202,8 @@
             if (!locale.isEmpty()) {
                 if (locale != currentLocale) {
                     // backward compatibility. C == en_US
-                    if (locale.at(0) != 'C' || currentLocale != "en_US") {
-                        aKey += '[' + locale + ']';
-                        locale = QByteArray();
-                    }
+                    if (locale.at(0) != 'C' || currentLocale != "en_US")
+                        goto next_line;
                 }
             }

@@ -234,28 +232,11 @@
         if ((key.mGroup != "<default>") == defaultGroup)
             continue; // skip

-        // Skip default values and group headers
-        if (key.bDefault || key.mKey.isNull())
+        // Skip group headers
+        if (key.mKey.isNull())
             continue; // skip

         const KEntry& currentEntry = *it;
-        KEntryMapConstIterator testIt = it;
-        ++testIt;
-        if (testIt != end) { // might have a default
-            const KEntryKey& defaultKey = testIt.key();
-            if (defaultKey.bDefault ||
-                 defaultKey.mGroup != key.mGroup ||
-                 defaultKey.mKey != key.mKey ||
-                 defaultKey.bLocal != key.bLocal) {
-                if (currentEntry.bDeleted)
-                    continue; // Don't write deleted entries if there is no
default
-            } else {
-                if (currentEntry.mValue == testIt->mValue &&
-                    currentEntry.bDeleted == testIt->bDeleted)
-                    continue; // same as default, don't write
-            }
-        }
-
         if (!defaultGroup && currentGroup != key.mGroup) {
             if (!firstEntry)
                 file.putChar('\n');
@@ -270,7 +251,7 @@

         file.write(stringToPrintable(key.mKey)); // Key

-        if (currentEntry.bNLS) {
+        if (currentEntry.bNLS && locale != "C") {
             file.putChar('[');
             file.write(locale); // Locale tag
             file.putChar(']');
@@ -298,29 +279,37 @@
 {
     Q_ASSERT(!filePath().isEmpty());

-    KEntryMap tempMap = toMerge;
+    KEntryMap writeMap = toMerge;
     bool bGlobal = options & WriteGlobal;

-    int mergeCount = toMerge.count();
     const KEntryMapIterator end = entryMap.end();
     for (KEntryMapIterator it=entryMap.begin(); it != end; ++it) {
-        const KEntryKey& key = it.key();
-        if (key.bDefault) {
-            tempMap[key] = *it; // store default values in tempMap
+        if (!it->bDirty) // not dirty, doesn't overwrite entry in writeMap
             continue;
-        }
-        if (mergeCount > 0 && !it->bDirty)
-            continue;

-        // only write back dirty entries that have the same
-        // "globality" as the file
-        if (it->bGlobal == bGlobal && it->bDirty) {
-            tempMap[key] = *it;
+        const KEntryKey& key = it.key();
+
+        // only write back dirty entries that have the same "globality" as
the file
+        if (it->bGlobal == bGlobal) {
+            KEntryKey defaultKey = key;
+            defaultKey.bDefault = true;
+            if (it->bDeleted && !entryMap.contains(defaultKey))
+                writeMap.removeEntry(key); // remove the deleted entry if
there is no default
+            else
+                writeMap[key] = *it;
+
             it->bDirty = false;
         }
     }

-    // now tempMap should contain all entries to be written
+    if (writeMap.isEmpty()) {
+        QFile file(filePath());
+        if (file.exists())
+            file.remove(); // delete the file since it's going to be empty
anyways
+        return true;
+    }
+
+    // now writeMap should contain only entries to be written
     // so write it out to disk

     // check if file exists
@@ -352,8 +341,9 @@
     if (createNew)
         file.setPermissions(QFile::ReadUser|QFile::WriteUser);

-    writeEntries(locale, file, tempMap);
+    writeEntries(locale, file, writeMap);

+    // FIXME is this needed anymore?
     if ( !file.size() && ((fileMode == -1) || (fileMode == 0600)) ) {
         // File is empty and doesn't have special permissions: delete it.
         file.abort();
@@ -432,7 +422,6 @@
     if (lockFile->lock() == KLockFile::LockStale) // attempt to break the
lock
         lockFile->lock(KLockFile::ForceFlag);
     return lockFile->isLocked();
-    return true;
 }

 void KConfigIniBackend::unlock()

[Attachment #3 (text/html)]

<br><br><div><span class="gmail_quote">On 10/28/07, <b \
class="gmail_sendername">Thomas Braxton</b> &lt;<a \
href="mailto:kde.braxton@gmail.com">kde.braxton@gmail.com</a>&gt; \
wrote:</span><blockquote class="gmail_quote" \
style="margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"> \
<br><br><div><span class="q"><span class="gmail_quote">On 10/28/07, <b \
class="gmail_sendername">Oswald Buddenhagen</b> &lt;<a href="mailto:ossi@kde.org" \
target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"> \
ossi@kde.org</a>&gt; wrote:</span><blockquote class="gmail_quote" \
style="margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"> On \
Sun, Oct 28, 2007 at 07:19:19AM -0400, Jeff Mitchell wrote:<br>&gt; On Sunday 28 \
October 2007, Thomas Braxton wrote:<br>&gt; &gt; On 10/28/07, Jeff Mitchell &lt;<a \
href="mailto:kde-dev@emailgoeshere.com" target="_blank" onclick="return \
top.js.OpenExtLink(window,event,this)"> kde-dev@emailgoeshere.com
</a>&gt; wrote:<br>&gt; &gt; &gt; There is a [PortableDevices] section that is \
occasionally added to<br>&gt; &gt; &gt; or deleted from.&nbsp;&nbsp;The problem is \
that whenever the last<br>&gt; &gt; &gt; (positionally, not numerically) entry is \
removed, it&#39;s not <br>&gt; &gt; &gt; actually removed, but rather gets corrupted \
somehow.<br>&gt; &gt;<br>&gt; &gt; actually is not getting corrupted, it&#39;s being \
marked as deleted.<br>&gt;<br>&gt; Why actually delete some, and only mark others? \
<br>&gt;<br>if there is no default, there is no point in overshadowing it.<br>if you \
don&#39;t understand it, revisit the cascading config concept.<br><br>&gt; &gt; Is \
there a default set for those keys in KDEDIR/share/config/amarokrc? <br>&gt; &gt; \
because the entries shouldn&#39;t be marked as deleted unless there was a<br>&gt; \
&gt; default, I&#39;ll look into this.<br>&gt;<br>&gt; No, there \
isn&#39;t.&nbsp;&nbsp;No defaults.<br>&gt;<br>maybe a real bug then. thomas, your \
turn. :-P </blockquote><div><br>&nbsp;</div></span><div>yeah a bug, I&#39;m still \
trying to figure out why it&#39;s treating some entries as having defaults when they \
don&#39;t. It&#39;s in the backend when the entries are actually written to disk. I \
have a fix, but it&#39;s not quite right, it breaks something else, something wierd \
happening here. I&#39;ll try to get this fixed today. \
</div></div></blockquote><div><br class="webkit-block-placeholder"></div><div>Ok, \
I&#39;ve had time to work on this. This patch fixes the wierdness and removes entries \
from other locales from the entryMap, since I was already in the area ;) I also added \
a test, since the test for &quot;stringEntry1[fr]&quot; was wrong since KConfigGroup \
was saving the key as &quot;stringEntry1\x5cfr\x5d&quot;, I think those are the right \
codes. So take a look and let me know what you think. </div><div><br \
class="webkit-block-placeholder"></div><div>&nbsp;Index: \
tests/kconfigtest.cpp</div><div>===================================================================</div><div>--- \
tests/kconfigtest.cpp<span class="Apple-tab-span" style="white-space:pre">  \
</span>(revision 730047)</div><div>+++ tests/kconfigtest.cpp<span \
class="Apple-tab-span" style="white-space:pre">	</span>(working copy)</div><div>@@ \
-90,7 +90,6 @@</div><div>&nbsp;&nbsp; cg.writeEntry( ESCAPEKEY, ESCAPEENTRY );</div> \
<div>&nbsp;&nbsp; cg.writeEntry( &quot;emptyEntry&quot;, \
&quot;&quot;);</div><div>&nbsp;&nbsp; cg.writeEntry( &quot;stringEntry1&quot;, \
STRINGENTRY1 );</div><div>- &nbsp;cg.writeEntry( &quot;stringEntry1[fr]&quot;, \
TRANSLATEDSTRINGENTRY1 );</div> <div>&nbsp;&nbsp; cg.writeEntry( \
&quot;stringEntry2&quot;, STRINGENTRY2 );</div><div>&nbsp;&nbsp; cg.writeEntry( \
&quot;stringEntry3&quot;, STRINGENTRY3 );</div><div>&nbsp;&nbsp; cg.writeEntry( \
&quot;stringEntry4&quot;, STRINGENTRY4 );</div><div>@@ -258,6 +257,36 @@ \
</div><div>&nbsp;&nbsp; QCOMPARE( sc3.readEntry( &quot;doubleEntry1&quot;, 0.0 ), \
DOUBLEENTRY );</div><div>&nbsp;}</div><div>&nbsp;</div><div>+void \
KConfigTest::testLocale()</div><div>+{</div><div>+ &nbsp; &nbsp;KConfig \
config(&quot;kconfigtest&quot;); </div><div>+ &nbsp; \
&nbsp;config.setLocale(&quot;fr&quot;);</div><div>+ &nbsp; &nbsp;KConfigGroup group = \
config.group(&quot;Hello&quot;);</div><div>+ &nbsp; \
&nbsp;group.writeEntry(&quot;stringEntry1&quot;, QString(TRANSLATEDSTRINGENTRY1), \
KConfig::Localized|KConfig::Persistent); </div><div>+ &nbsp; \
&nbsp;config.sync();</div><div>+</div><div>+ &nbsp; &nbsp;int count=0;</div><div>+ \
&nbsp; &nbsp;foreach(const QByteArray&amp; line, readLines())</div><div>+ &nbsp; \
&nbsp; &nbsp; &nbsp;if (line.startsWith(&quot;stringEntry1[fr]&quot;))</div><div>+ \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;count++; </div><div>+ &nbsp; \
&nbsp;QVERIFY(count == 1);</div><div>+ &nbsp; \
&nbsp;QCOMPARE(group.readEntry(&quot;stringEntry1&quot;, QString()), \
QString(TRANSLATEDSTRINGENTRY1));</div><div>+</div><div>+ &nbsp; \
&nbsp;config.setLocale(&quot;C&quot;); // strings written in the &quot;C&quot; locale \
are written as nonlocalized </div><div>+ &nbsp; \
&nbsp;group.writeEntry(&quot;stringEntry1&quot;, QString(STRINGENTRY1), \
KConfig::Localized|KConfig::Persistent);</div><div>+ &nbsp; \
&nbsp;config.sync();</div><div>+</div><div>+ &nbsp; &nbsp;count=0;</div><div>+ &nbsp; \
&nbsp;foreach(const QByteArray&amp; line, readLines()) { </div><div>+ &nbsp; &nbsp; \
&nbsp; &nbsp;if (line.startsWith(&quot;stringEntry1&quot;))</div><div>+ &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;count++;</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;if \
(line.contains(&quot;[C]&quot;))</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;count--;</div><div>+ &nbsp; &nbsp;}</div><div>+ &nbsp; &nbsp;QVERIFY(count == \
1); </div><div>+ &nbsp; &nbsp;QCOMPARE(group.readEntry(&quot;stringEntry1&quot;, \
QString()), QString(STRINGENTRY1));</div><div>+}</div><div>+</div><div>&nbsp;void \
KConfigTest::testLists()</div><div>&nbsp;{</div><div>&nbsp;&nbsp; KConfig sc2( \
&quot;kconfigtest&quot; ); </div><div>@@ -388,8 +417,6 @@</div><div>&nbsp;&nbsp; \
&nbsp; QMap&lt;QString, QString&gt; entryMap = cg.entryMap();</div><div>&nbsp;&nbsp; \
&nbsp; qDebug() &lt;&lt; entryMap.keys();</div><div>&nbsp;&nbsp; &nbsp; \
QCOMPARE(entryMap.value(&quot;stringEntry1&quot;), QString(STRINGENTRY1)); \
</div><div>- &nbsp; &nbsp;// #### Why is this translated entry here? This just bloats \
the entryMap.</div><div>- &nbsp; \
&nbsp;QCOMPARE(entryMap.value(&quot;stringEntry1[fr]&quot;), \
QString(TRANSLATEDSTRINGENTRY1));</div><div>&nbsp;&nbsp; &nbsp; \
QCOMPARE(entryMap.value (&quot;stringEntry2&quot;), \
QString(STRINGENTRY2));</div><div>&nbsp;&nbsp; &nbsp; \
QCOMPARE(entryMap.value(&quot;stringEntry3&quot;), \
QString(STRINGENTRY3));</div><div>&nbsp;&nbsp; &nbsp; \
QCOMPARE(entryMap.value(&quot;stringEntry4&quot;), QString(STRINGENTRY4)); \
</div><div>@@ -500,6 +527,23 @@</div><div>&nbsp;&nbsp; QVERIFY( \
sc.entryMap(&quot;AAA&quot;).isEmpty() );</div><div>&nbsp;&nbsp; QVERIFY( \
!sc.entryMap(&quot;Hello&quot;).isEmpty() ); //not deleted \
group</div><div>&nbsp;&nbsp; QVERIFY( sc.entryMap(&quot;FooBar&quot;).isEmpty() ); \
//inexistant group </div><div>+ &nbsp;</div><div>+ &nbsp;// test for entries that are \
marked as deleted when there is no default</div><div>+ &nbsp;KConfig \
config(&quot;kconfigtest&quot;, KConfig::SimpleConfig); // make sure there are no \
defaults</div><div> + &nbsp;cg = config.group(&quot;Portable \
Devices&quot;);</div><div>+ &nbsp;cg.writeEntry(&quot;devices|manual|(null)&quot;, \
&quot;whatever&quot;);</div><div>+ \
&nbsp;cg.writeEntry(&quot;devices|manual|/mnt/ipod&quot;, &quot;/mnt/ipod&quot;); \
</div><div>+ &nbsp;cg.sync();</div><div>+ &nbsp;</div><div>+ &nbsp;int \
count=0;</div><div>+ &nbsp;foreach(const QByteArray&amp; item, \
readLines())</div><div>+ &nbsp; &nbsp; &nbsp;if \
(item.startsWith(&quot;devices|&quot;))</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;count++;</div> <div>+ &nbsp;QVERIFY(count == 2);</div><div>+ \
&nbsp;cg.deleteEntry(&quot;devices|manual|/mnt/ipod&quot;);</div><div>+ \
&nbsp;cg.sync();</div><div>+ &nbsp;foreach(const QByteArray&amp; item, \
readLines())</div><div>+ &nbsp; &nbsp; &nbsp;QVERIFY(item != \
&quot;devices|manual|/mnt/ipod[$d]&quot;); \
</div><div>&nbsp;}</div><div>&nbsp;</div><div>&nbsp;void \
KConfigTest::testDefaultGroup()</div><div>Index: \
tests/kconfigtest.h</div><div>===================================================================</div><div>--- \
tests/kconfigtest.h <span class="Apple-tab-span" \
style="white-space:pre">	</span>(revision 730047)</div><div>+++ \
tests/kconfigtest.h<span class="Apple-tab-span" \
style="white-space:pre">	</span>(working copy)</div><div>@@ -36,6 +36,7 @@</div> \
<div>&nbsp;&nbsp; &nbsp; void initTestCase();</div><div>&nbsp;&nbsp; &nbsp; void \
cleanupTestCase();</div><div>&nbsp;&nbsp; &nbsp; void testSimple();</div><div>+ \
&nbsp; &nbsp;void testLocale();</div><div>&nbsp;&nbsp; &nbsp; void \
testLists();</div><div>&nbsp;&nbsp; &nbsp; void testPath();</div><div>&nbsp;&nbsp; \
&nbsp; void testPersistenceOfExpandFlagForPath(); </div><div>Index: \
config/kconfigdata.h</div><div>===================================================================</div><div>--- \
config/kconfigdata.h<span class="Apple-tab-span" \
style="white-space:pre">	</span>(revision 730047) </div><div>+++ \
config/kconfigdata.h<span class="Apple-tab-span" \
style="white-space:pre">	</span>(working copy)</div><div>@@ -302,6 +302,18 \
@@</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; return getEntryOption(findEntry(group, key, flags), option); \
</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp;void removeEntry(const KEntryKey&amp; key)</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp;{</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;remove(key);</div><div>+ \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int count=0;</div><div>+ &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;foreach(const KEntryKey&amp; item, keys()) </div><div>+ \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(item.mGroup == key.mGroup \
&amp;&amp; !item.mKey.isEmpty())</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;count++;</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;if (!count) {</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;const KEntryKey groupKey(key.mGroup );</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;remove(groupKey);</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp;}</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp;}</div><div>&nbsp;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; void \
setEntryOption(Iterator it, EntryOption option, bool bf)</div><div>&nbsp;&nbsp; \
&nbsp; &nbsp; &nbsp; {</div><div>Index: config/kconfigini.cpp \
</div><div>===================================================================</div><div>--- \
config/kconfigini.cpp<span class="Apple-tab-span" \
style="white-space:pre">	</span>(revision 730047)</div><div>+++ config/kconfigini.cpp \
<span class="Apple-tab-span" style="white-space:pre">	</span>(working \
copy)</div><div>@@ -202,10 +202,8 @@</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; if (!locale.isEmpty()) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; if (locale != currentLocale) {</div><div> &nbsp;&nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // backward \
compatibility. C == en_US</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;if (locale.at(0) != &#39;C&#39; || currentLocale != \
&quot;en_US&quot;) {</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;aKey += &#39;[&#39; + locale + &#39;]&#39;; \
</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;locale = QByteArray();</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (locale.at(0) != &#39;C&#39; || currentLocale != \
&quot;en_US&quot;)</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto next_line; </div><div>&nbsp;&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp;&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; }</div><div>&nbsp;</div><div>@@ -234,28 +232,11 \
@@</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if ((key.mGroup != \
&quot;&lt;default&gt;&quot;) == defaultGroup)</div><div>&nbsp;&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; continue; // skip </div><div>&nbsp;</div><div>- &nbsp; &nbsp; \
&nbsp; &nbsp;// Skip default values and group headers</div><div>- &nbsp; &nbsp; \
&nbsp; &nbsp;if (key.bDefault || key.mKey.isNull())</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp;// Skip group headers</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;if \
(key.mKey.isNull())</div><div> &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
continue; // skip</div><div>&nbsp;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; const \
KEntry&amp; currentEntry = *it;</div><div>- &nbsp; &nbsp; &nbsp; \
&nbsp;KEntryMapConstIterator testIt = it;</div><div>- &nbsp; &nbsp; &nbsp; \
&nbsp;++testIt;</div><div>- &nbsp; &nbsp; &nbsp; &nbsp;if (testIt != end) { // might \
have a default </div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const \
KEntryKey&amp; defaultKey = testIt.key();</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;if (defaultKey.bDefault ||</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; defaultKey.mGroup != key.mGroup ||</div><div>- &nbsp; \
                &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaultKey.mKey
 != key.mKey ||</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
defaultKey.bLocal != key.bLocal) {</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp;if (currentEntry.bDeleted)</div><div>- &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue; // Don&#39;t write deleted \
entries if there is no default </div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;} else {</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if \
(currentEntry.mValue == testIt-&gt;mValue &amp;&amp;</div><div>- &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;currentEntry.bDeleted == \
testIt-&gt;bDeleted)</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp;continue; // same as default, don&#39;t write </div><div>- &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div>- &nbsp; &nbsp; &nbsp; \
&nbsp;}</div><div>-</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if (!defaultGroup \
&amp;&amp; currentGroup != key.mGroup) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; if (!firstEntry)</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; file.putChar(&#39;\n&#39;); </div><div>@@ -270,7 +251,7 \
@@</div><div>&nbsp;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
file.write(stringToPrintable(key.mKey)); // Key</div><div>&nbsp;</div><div>- &nbsp; \
&nbsp; &nbsp; &nbsp;if (currentEntry.bNLS) {</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp;if (currentEntry.bNLS &amp;&amp; locale != &quot;C&quot;) { \
</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
file.putChar(&#39;[&#39;);</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
file.write(locale); // Locale tag</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; file.putChar(&#39;]&#39;);</div><div>@@ -298,29 +279,37 \
@@</div><div>&nbsp;{</div><div>&nbsp;&nbsp; &nbsp; Q_ASSERT(!filePath().isEmpty()); \
</div><div>&nbsp;</div><div>- &nbsp; &nbsp;KEntryMap tempMap = toMerge;</div><div>+ \
&nbsp; &nbsp;KEntryMap writeMap = toMerge;</div><div>&nbsp;&nbsp; &nbsp; bool bGlobal \
= options &amp; WriteGlobal;</div><div>&nbsp;</div><div>- &nbsp; &nbsp;int mergeCount \
= toMerge.count();</div> <div>&nbsp;&nbsp; &nbsp; const KEntryMapIterator end = \
entryMap.end();</div><div>&nbsp;&nbsp; &nbsp; for (KEntryMapIterator \
it=entryMap.begin(); it != end; ++it) {</div><div>- &nbsp; &nbsp; &nbsp; &nbsp;const \
KEntryKey&amp; key = it.key();</div><div>- &nbsp; &nbsp; &nbsp; &nbsp;if \
(key.bDefault ) {</div><div>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tempMap[key] = \
*it; // store default values in tempMap</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;if \
(!it-&gt;bDirty) // not dirty, doesn&#39;t overwrite entry in \
writeMap</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
continue;</div><div>- &nbsp; &nbsp; &nbsp; &nbsp;} </div><div>- &nbsp; &nbsp; &nbsp; \
&nbsp;if (mergeCount &gt; 0 &amp;&amp; !it-&gt;bDirty)</div><div>- &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div>&nbsp;</div><div>- &nbsp; &nbsp; \
&nbsp; &nbsp;// only write back dirty entries that have the same</div><div>- &nbsp; \
&nbsp; &nbsp; &nbsp;// &quot;globality&quot; as the file </div><div>- &nbsp; &nbsp; \
&nbsp; &nbsp;if (it-&gt;bGlobal == bGlobal &amp;&amp; it-&gt;bDirty) {</div><div>- \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tempMap[key] = *it;</div><div>+ &nbsp; \
&nbsp; &nbsp; &nbsp;const KEntryKey&amp; key = it.key();</div><div>+</div><div>+ \
&nbsp; &nbsp; &nbsp; &nbsp;// only write back dirty entries that have the same \
&quot;globality&quot; as the file </div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;if \
(it-&gt;bGlobal == bGlobal) {</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;KEntryKey defaultKey = key;</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;defaultKey.bDefault = true;</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;if (it-&gt;bDeleted &amp;&amp; !entryMap.contains(defaultKey)) </div><div>+ \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;writeMap.removeEntry(key); // \
remove the deleted entry if there is no default</div><div>+ &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp;else</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;writeMap[key] = *it;</div><div>+</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; it-&gt;bDirty = false; </div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
}</div><div>&nbsp;&nbsp; &nbsp; }</div><div>&nbsp;</div><div>- &nbsp; &nbsp;// now \
tempMap should contain all entries to be written</div><div>+ &nbsp; &nbsp;if \
(writeMap.isEmpty()) {</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;QFile \
file(filePath());</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp;if ( \
file.exists())</div><div>+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;file.remove(); // \
delete the file since it&#39;s going to be empty anyways</div><div>+ &nbsp; &nbsp; \
&nbsp; &nbsp;return true;</div><div>+ &nbsp; &nbsp;}</div><div>+</div><div>+ &nbsp; \
&nbsp;// now writeMap should contain only entries to be written \
</div><div>&nbsp;&nbsp; &nbsp; // so write it out to \
disk</div><div>&nbsp;</div><div>&nbsp;&nbsp; &nbsp; // check if file \
exists</div><div>@@ -352,8 +341,9 @@</div><div>&nbsp;&nbsp; &nbsp; if \
(createNew)</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
file.setPermissions(QFile::ReadUser|QFile::WriteUser); </div><div>&nbsp;</div><div>- \
&nbsp; &nbsp;writeEntries(locale, file, tempMap);</div><div>+ &nbsp; \
&nbsp;writeEntries(locale, file, writeMap);</div><div>&nbsp;</div><div>+ &nbsp; \
&nbsp;// FIXME is this needed anymore?</div><div>&nbsp;&nbsp; &nbsp; if ( \
!file.size() &amp;&amp; ((fileMode == -1) || (fileMode == 0600)) ) { \
</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // File is empty and doesn&#39;t have \
special permissions: delete it.</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
file.abort();</div><div>@@ -432,7 +422,6 @@</div><div>&nbsp;&nbsp; &nbsp; if \
(lockFile-&gt;lock() == KLockFile::LockStale) // attempt to break the lock \
</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; \
lockFile-&gt;lock(KLockFile::ForceFlag);</div><div>&nbsp;&nbsp; &nbsp; return \
lockFile-&gt;isLocked();</div><div>- &nbsp; &nbsp;return \
true;</div><div>&nbsp;}</div><div>&nbsp;</div><div>&nbsp;void \
KConfigIniBackend::unlock()</div><div><br class="webkit-block-placeholder"> \
</div></div>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic