• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • config
kconfigini.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3 Copyright (c) 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
4 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
5 Copyright (C) 1997-1999 Matthias Kalle Dalheimer (kalle@kde.org)
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "kconfigini_p.h"
24
25#include "kconfig.h"
26#include "kconfigbackend.h"
27#include "bufferfragment_p.h"
28#include "kconfigdata.h"
29#include <ksavefile.h>
30#include <kde_file.h>
31#include "kstandarddirs.h"
32
33#include <qdatetime.h>
34#include <qdir.h>
35#include <qfile.h>
36#include <qfileinfo.h>
37#include <qdebug.h>
38#include <qmetaobject.h>
39#include <qregexp.h>
40
41extern bool kde_kiosk_exception;
42
43static QByteArray lookup(const KConfigIniBackend::BufferFragment& fragment, QHash<KConfigIniBackend::BufferFragment, QByteArray>* cache)
44{
45 QHash<KConfigIniBackend::BufferFragment, QByteArray>::iterator it = cache->find(fragment);
46 if (it == cache->end()) {
47 it = cache->insert(fragment, fragment.toByteArray());
48 }
49 return it.value();
50}
51
52QString KConfigIniBackend::warningProlog(const QFile &file, int line)
53{
54 return QString::fromLatin1("KConfigIni: In file %2, line %1: ")
55 .arg(line).arg(file.fileName());
56}
57
58KConfigIniBackend::KConfigIniBackend()
59 : KConfigBackend()
60{
61}
62
63KConfigIniBackend::~KConfigIniBackend()
64{
65}
66
67KConfigBackend::ParseInfo
68 KConfigIniBackend::parseConfig(const QByteArray& currentLocale, KEntryMap& entryMap,
69 ParseOptions options)
70{
71 return parseConfig(currentLocale, entryMap, options, false);
72}
73
74// merging==true is the merging that happens at the beginning of writeConfig:
75// merge changes in the on-disk file with the changes in the KConfig object.
76KConfigBackend::ParseInfo
77KConfigIniBackend::parseConfig(const QByteArray& currentLocale, KEntryMap& entryMap,
78 ParseOptions options, bool merging)
79{
80 if (filePath().isEmpty() || !QFile::exists(filePath()))
81 return ParseOk;
82
83 bool bDefault = options&ParseDefaults;
84 bool allowExecutableValues = options&ParseExpansions;
85
86 QByteArray currentGroup("<default>");
87
88 QFile file(filePath());
89 if (!file.open(QIODevice::ReadOnly|QIODevice::Text))
90 return ParseOpenError;
91
92 QList<QByteArray> immutableGroups;
93
94 bool fileOptionImmutable = false;
95 bool groupOptionImmutable = false;
96 bool groupSkip = false;
97
98 int lineNo = 0;
99 // on systems using \r\n as end of line, \r will be taken care of by
100 // trim() below
101 QByteArray buffer = file.readAll();
102 BufferFragment contents(buffer.data(), buffer.size());
103 unsigned int len = contents.length();
104 unsigned int startOfLine = 0;
105
106 // Reduce memory overhead by making use of implicit sharing
107 // This assumes that config files contain only a small amount of
108 // different fragments which are repeated often.
109 // This is often the case, especially sub groups will all have
110 // the same list of keys and similar values as well.
111 QHash<BufferFragment, QByteArray> cache;
112 cache.reserve(4096);
113
114 while (startOfLine < len) {
115 BufferFragment line = contents.split('\n', &startOfLine);
116 line.trim();
117 lineNo++;
118
119 // skip empty lines and lines beginning with '#'
120 if (line.isEmpty() || line.at(0) == '#')
121 continue;
122
123 if (line.at(0) == '[') { // found a group
124 groupOptionImmutable = fileOptionImmutable;
125
126 QByteArray newGroup;
127 int start = 1, end;
128 do {
129 end = start;
130 for (;;) {
131 if (end == line.length()) {
132 qWarning() << warningProlog(file, lineNo) << "Invalid group header.";
133 // XXX maybe reset the current group here?
134 goto next_line;
135 }
136 if (line.at(end) == ']')
137 break;
138 end++;
139 }
140 if (end + 1 == line.length() && start + 2 == end &&
141 line.at(start) == '$' && line.at(start + 1) == 'i')
142 {
143 if (newGroup.isEmpty())
144 fileOptionImmutable = !kde_kiosk_exception;
145 else
146 groupOptionImmutable = !kde_kiosk_exception;
147 }
148 else {
149 if (!newGroup.isEmpty())
150 newGroup += '\x1d';
151 BufferFragment namePart=line.mid(start, end - start);
152 printableToString(&namePart, file, lineNo);
153 newGroup += namePart.toByteArray();
154 }
155 } while ((start = end + 2) <= line.length() && line.at(end + 1) == '[');
156 currentGroup = newGroup;
157
158 groupSkip = entryMap.getEntryOption(currentGroup, 0, 0, KEntryMap::EntryImmutable);
159
160 if (groupSkip && !bDefault)
161 continue;
162
163 if (groupOptionImmutable)
164 // Do not make the groups immutable until the entries from
165 // this file have been added.
166 immutableGroups.append(currentGroup);
167 } else {
168 if (groupSkip && !bDefault)
169 continue; // skip entry
170
171 BufferFragment aKey;
172 int eqpos = line.indexOf('=');
173 if (eqpos < 0) {
174 aKey = line;
175 line.clear();
176 } else {
177 BufferFragment temp = line.left(eqpos);
178 temp.trim();
179 aKey = temp;
180 line.truncateLeft(eqpos + 1);
181 }
182 if (aKey.isEmpty()) {
183 qWarning() << warningProlog(file, lineNo) << "Invalid entry (empty key)";
184 continue;
185 }
186
187 KEntryMap::EntryOptions entryOptions=0;
188 if (groupOptionImmutable)
189 entryOptions |= KEntryMap::EntryImmutable;
190
191 BufferFragment locale;
192 int start;
193 while ((start = aKey.lastIndexOf('[')) >= 0) {
194 int end = aKey.indexOf(']', start);
195 if (end < 0) {
196 qWarning() << warningProlog(file, lineNo)
197 << "Invalid entry (missing ']')";
198 goto next_line;
199 } else if (end > start + 1 && aKey.at(start + 1) == '$') { // found option(s)
200 int i = start + 2;
201 while (i < end) {
202 switch (aKey.at(i)) {
203 case 'i':
204 if (!kde_kiosk_exception)
205 entryOptions |= KEntryMap::EntryImmutable;
206 break;
207 case 'e':
208 if (allowExecutableValues)
209 entryOptions |= KEntryMap::EntryExpansion;
210 break;
211 case 'd':
212 entryOptions |= KEntryMap::EntryDeleted;
213 aKey = aKey.left(start);
214 printableToString(&aKey, file, lineNo);
215 entryMap.setEntry(currentGroup, aKey.toByteArray(), QByteArray(), entryOptions);
216 goto next_line;
217 default:
218 break;
219 }
220 i++;
221 }
222 } else { // found a locale
223 if (!locale.isNull()) {
224 qWarning() << warningProlog(file, lineNo)
225 << "Invalid entry (second locale!?)";
226 goto next_line;
227 }
228
229 locale = aKey.mid(start + 1,end - start - 1);
230 }
231 aKey.truncate(start);
232 }
233 if (eqpos < 0) { // Do this here after [$d] was checked
234 qWarning() << warningProlog(file, lineNo) << "Invalid entry (missing '=')";
235 continue;
236 }
237 printableToString(&aKey, file, lineNo);
238 if (!locale.isEmpty()) {
239 if (locale != currentLocale) {
240 // backward compatibility. C == en_US
241 if (locale.at(0) != 'C' || currentLocale != "en_US") {
242 if (merging)
243 entryOptions |= KEntryMap::EntryRawKey;
244 else
245 goto next_line; // skip this entry if we're not merging
246 }
247 }
248 }
249
250 if (!(entryOptions & KEntryMap::EntryRawKey))
251 printableToString(&aKey, file, lineNo);
252
253 if (options&ParseGlobal)
254 entryOptions |= KEntryMap::EntryGlobal;
255 if (bDefault)
256 entryOptions |= KEntryMap::EntryDefault;
257 if (!locale.isNull())
258 entryOptions |= KEntryMap::EntryLocalized;
259 printableToString(&line, file, lineNo);
260 if (entryOptions & KEntryMap::EntryRawKey) {
261 QByteArray rawKey;
262 rawKey.reserve(aKey.length() + locale.length() + 2);
263 rawKey.append(aKey.toVolatileByteArray());
264 rawKey.append('[').append(locale.toVolatileByteArray()).append(']');
265 entryMap.setEntry(currentGroup, rawKey, lookup(line, &cache), entryOptions);
266 } else {
267 entryMap.setEntry(currentGroup, lookup(aKey, &cache), lookup(line, &cache), entryOptions);
268 }
269 }
270next_line:
271 continue;
272 }
273
274 // now make sure immutable groups are marked immutable
275 foreach(const QByteArray& group, immutableGroups) {
276 entryMap.setEntry(group, QByteArray(), QByteArray(), KEntryMap::EntryImmutable);
277 }
278
279 return fileOptionImmutable ? ParseImmutable : ParseOk;
280}
281
282void KConfigIniBackend::writeEntries(const QByteArray& locale, QFile& file,
283 const KEntryMap& map, bool defaultGroup, bool &firstEntry)
284{
285 QByteArray currentGroup;
286 bool groupIsImmutable = false;
287 const KEntryMapConstIterator end = map.constEnd();
288 for (KEntryMapConstIterator it = map.constBegin(); it != end; ++it) {
289 const KEntryKey& key = it.key();
290
291 // Either process the default group or all others
292 if ((key.mGroup != "<default>") == defaultGroup)
293 continue; // skip
294
295 // the only thing we care about groups is, is it immutable?
296 if (key.mKey.isNull()) {
297 groupIsImmutable = it->bImmutable;
298 continue; // skip
299 }
300
301 const KEntry& currentEntry = *it;
302 if (!defaultGroup && currentGroup != key.mGroup) {
303 if (!firstEntry)
304 file.putChar('\n');
305 currentGroup = key.mGroup;
306 for (int start = 0, end;; start = end + 1) {
307 file.putChar('[');
308 end = currentGroup.indexOf('\x1d', start);
309 if (end < 0) {
310 int cgl = currentGroup.length();
311 if (currentGroup.at(start) == '$' && cgl - start <= 10) {
312 for (int i = start + 1; i < cgl; i++) {
313 char c = currentGroup.at(i);
314 if (c < 'a' || c > 'z')
315 goto nope;
316 }
317 file.write("\\x24");
318 start++;
319 }
320 nope:
321 file.write(stringToPrintable(currentGroup.mid(start), GroupString));
322 file.putChar(']');
323 if (groupIsImmutable) {
324 file.write("[$i]", 4);
325 }
326 file.putChar('\n');
327 break;
328 } else {
329 file.write(stringToPrintable(currentGroup.mid(start, end - start), GroupString));
330 file.putChar(']');
331 }
332 }
333 }
334
335 firstEntry = false;
336 // it is data for a group
337
338 if (key.bRaw) // unprocessed key with attached locale from merge
339 file.write(key.mKey);
340 else {
341 file.write(stringToPrintable(key.mKey, KeyString)); // Key
342 if (key.bLocal && locale != "C") { // 'C' locale == untranslated
343 file.putChar('[');
344 file.write(locale); // locale tag
345 file.putChar(']');
346 }
347 }
348 if (currentEntry.bDeleted) {
349 if (currentEntry.bImmutable)
350 file.write("[$di]", 5); // Deleted + immutable
351 else
352 file.write("[$d]", 4); // Deleted
353 } else {
354 if (currentEntry.bImmutable || currentEntry.bExpand) {
355 file.write("[$", 2);
356 if (currentEntry.bImmutable)
357 file.putChar('i');
358 if (currentEntry.bExpand)
359 file.putChar('e');
360 file.putChar(']');
361 }
362 file.putChar('=');
363 file.write(stringToPrintable(currentEntry.mValue, ValueString));
364 }
365 file.putChar('\n');
366 }
367}
368
369void KConfigIniBackend::writeEntries(const QByteArray& locale, QFile& file, const KEntryMap& map)
370{
371 bool firstEntry = true;
372
373 // write default group
374 writeEntries(locale, file, map, true, firstEntry);
375
376 // write all other groups
377 writeEntries(locale, file, map, false, firstEntry);
378}
379
380bool KConfigIniBackend::writeConfig(const QByteArray& locale, KEntryMap& entryMap,
381 WriteOptions options, const KComponentData &data)
382{
383 Q_ASSERT(!filePath().isEmpty());
384
385 KEntryMap writeMap;
386 const bool bGlobal = options & WriteGlobal;
387
388 // First, reparse the file on disk, to merge our changes with the ones done by other apps
389 // Store the result into writeMap.
390 {
391 ParseOptions opts = ParseExpansions;
392 if (bGlobal)
393 opts |= ParseGlobal;
394 ParseInfo info = parseConfig(locale, writeMap, opts, true);
395 if (info != ParseOk) // either there was an error or the file became immutable
396 return false;
397 }
398
399 const KEntryMapIterator end = entryMap.end();
400 for (KEntryMapIterator it=entryMap.begin(); it != end; ++it) {
401 if (!it.key().mKey.isEmpty() && !it->bDirty) // not dirty, doesn't overwrite entry in writeMap. skips default entries, too.
402 continue;
403
404 const KEntryKey& key = it.key();
405
406 // only write entries that have the same "globality" as the file
407 if (it->bGlobal == bGlobal) {
408 if (it->bReverted) {
409 writeMap.remove(key);
410 } else if (!it->bDeleted) {
411 writeMap[key] = *it;
412 } else {
413 KEntryKey defaultKey = key;
414 defaultKey.bDefault = true;
415 if (!entryMap.contains(defaultKey)) {
416 writeMap.remove(key); // remove the deleted entry if there is no default
417 //qDebug() << "Detected as deleted=>removed:" << key.mGroup << key.mKey << "global=" << bGlobal;
418 } else {
419 writeMap[key] = *it; // otherwise write an explicitly deleted entry
420 //qDebug() << "Detected as deleted=>[$d]:" << key.mGroup << key.mKey << "global=" << bGlobal;
421 }
422 }
423 it->bDirty = false;
424 }
425 }
426
427 // now writeMap should contain only entries to be written
428 // so write it out to disk
429
430 // check if file exists
431 QFile::Permissions fileMode = QFile::ReadUser | QFile::WriteUser;
432 bool createNew = true;
433
434 QFileInfo fi(filePath());
435 if (fi.exists())
436 {
437 if (fi.ownerId() == ::getuid())
438 {
439 // Preserve file mode if file exists and is owned by user.
440 fileMode = fi.permissions();
441 }
442 else
443 {
444 // File is not owned by user:
445 // Don't create new file but write to existing file instead.
446 createNew = false;
447 }
448 }
449
450 if (createNew) {
451 KSaveFile file( filePath(), data );
452 if (!file.open()) {
453 return false;
454 }
455
456 file.setPermissions(fileMode);
457
458 file.setTextModeEnabled(true); // to get eol translation
459 writeEntries(locale, file, writeMap);
460
461 if (!file.flush()) {
462 // Couldn't write. Disk full?
463 kWarning() << "Couldn't write" << filePath() << ". Disk full?";
464 file.abort();
465 return false;
466 }
467
468 if (!file.size() && (fileMode == (QFile::ReadUser | QFile::WriteUser))) {
469 // File is empty and doesn't have special permissions: delete it.
470 file.abort();
471
472 if (fi.exists()) {
473 // also remove the old file in case it existed. this can happen
474 // when we delete all the entries in an existing config file.
475 // if we don't do this, then deletions and revertToDefault's
476 // will mysteriously fail
477 QFile::remove(filePath());
478 }
479 } else {
480 // Normal case: Close the file
481 return file.finalize();
482 }
483 } else {
484 // Open existing file. *DON'T* create it if it suddenly does not exist!
485#ifdef Q_OS_UNIX
486 int fd = KDE_open(QFile::encodeName(filePath()), O_WRONLY | O_TRUNC);
487 if (fd < 0) {
488 return false;
489 }
490 FILE *fp = KDE_fdopen(fd, "w");
491 if (!fp) {
492 close(fd);
493 return false;
494 }
495 QFile f;
496 if (!f.open(fp, QIODevice::WriteOnly)) {
497 fclose(fp);
498 return false;
499 }
500 writeEntries(locale, f, writeMap);
501 f.close();
502 fclose(fp);
503#else
504 QFile f( filePath() );
505 // XXX This is broken - it DOES create the file if it is suddenly gone.
506 if (!f.open( QIODevice::WriteOnly | QIODevice::Truncate )) {
507 return false;
508 }
509 f.setTextModeEnabled(true);
510 writeEntries(locale, f, writeMap);
511#endif
512 }
513 return true;
514}
515
516bool KConfigIniBackend::isWritable() const
517{
518 if (!filePath().isEmpty()) {
519 if (KStandardDirs::checkAccess(filePath(), W_OK)) {
520 return true;
521 }
522 // The check might have failed because any of the containing dirs
523 // did not exist. If the file does not exist, check if the deepest
524 // existing dir is writable.
525 QFileInfo file(filePath());
526 if (!file.exists()) {
527 QFileInfo dir(file.absolutePath());
528 while (!dir.exists()) {
529 QString parent = dir.absolutePath(); // Go up. Can't use cdUp() on non-existing dirs.
530 if (parent == dir.filePath()) {
531 // no parent
532 return false;
533 }
534 dir.setFile(parent);
535 }
536 return dir.isDir() && dir.isWritable();
537 }
538 }
539
540 return false;
541}
542
543QString KConfigIniBackend::nonWritableErrorMessage() const
544{
545 return i18n("Configuration file \"%1\" not writable.\n", filePath());
546}
547
548void KConfigIniBackend::createEnclosing()
549{
550 const QString file = filePath();
551 if (file.isEmpty())
552 return; // nothing to do
553
554 // Create the containing dir, maybe it wasn't there
555 QDir dir;
556 dir.mkpath(QFileInfo(file).absolutePath());
557}
558
559void KConfigIniBackend::setFilePath(const QString& file)
560{
561 if (file.isEmpty())
562 return;
563
564 Q_ASSERT(QDir::isAbsolutePath(file));
565
566 const QFileInfo info(file);
567 if (info.exists()) {
568 setLocalFilePath(info.canonicalFilePath());
569 setLastModified(info.lastModified());
570 setSize(info.size());
571 } else {
572 setLocalFilePath(file);
573 setSize(0);
574 QDateTime dummy;
575 dummy.setTime_t(0);
576 setLastModified(dummy);
577 }
578}
579
580KConfigBase::AccessMode KConfigIniBackend::accessMode() const
581{
582 if (filePath().isEmpty())
583 return KConfigBase::NoAccess;
584
585 if (isWritable())
586 return KConfigBase::ReadWrite;
587
588 return KConfigBase::ReadOnly;
589}
590
591bool KConfigIniBackend::lock(const KComponentData& componentData)
592{
593 Q_ASSERT(!filePath().isEmpty());
594
595 if (!lockFile) {
596 lockFile = new KLockFile(filePath() + QLatin1String(".lock"), componentData);
597 }
598
599 if (lockFile->lock() == KLockFile::LockStale) // attempt to break the lock
600 lockFile->lock(KLockFile::ForceFlag);
601 return lockFile->isLocked();
602}
603
604void KConfigIniBackend::unlock()
605{
606 lockFile->unlock();
607 lockFile.clear();
608}
609
610bool KConfigIniBackend::isLocked() const
611{
612 return lockFile && lockFile->isLocked();
613}
614
615QByteArray KConfigIniBackend::stringToPrintable(const QByteArray& aString, StringType type)
616{
617 static const char nibbleLookup[] = {
618 '0', '1', '2', '3', '4', '5', '6', '7',
619 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
620 };
621
622 if (aString.isEmpty())
623 return aString;
624 const int l = aString.length();
625
626 QByteArray result; // Guesstimated that it's good to avoid data() initialization for a length of l*4
627 result.resize(l * 4); // Maximum 4x as long as source string due to \x<ab> escape sequences
628 register const char *s = aString.constData();
629 int i = 0;
630 char *data = result.data();
631 char *start = data;
632
633 // Protect leading space
634 if (s[0] == ' ' && type != GroupString) {
635 *data++ = '\\';
636 *data++ = 's';
637 i++;
638 }
639
640 for (; i < l; ++i/*, r++*/) {
641 switch (s[i]) {
642 default:
643 // The \n, \t, \r cases (all < 32) are handled below; we can ignore them here
644 if (((unsigned char)s[i]) < 32)
645 goto doEscape;
646 *data++ = s[i];
647 break;
648 case '\n':
649 *data++ = '\\';
650 *data++ = 'n';
651 break;
652 case '\t':
653 *data++ = '\\';
654 *data++ = 't';
655 break;
656 case '\r':
657 *data++ = '\\';
658 *data++ = 'r';
659 break;
660 case '\\':
661 *data++ = '\\';
662 *data++ = '\\';
663 break;
664 case '=':
665 if (type != KeyString) {
666 *data++ = s[i];
667 break;
668 }
669 goto doEscape;
670 case '[':
671 case ']':
672 // Above chars are OK to put in *value* strings as plaintext
673 if (type == ValueString) {
674 *data++ = s[i];
675 break;
676 }
677 doEscape:
678 *data++ = '\\';
679 *data++ = 'x';
680 *data++ = nibbleLookup[((unsigned char)s[i]) >> 4];
681 *data++ = nibbleLookup[((unsigned char)s[i]) & 0x0f];
682 break;
683 }
684 }
685 *data = 0;
686 result.resize(data - start);
687
688 // Protect trailing space
689 if (result.endsWith(' ') && type != GroupString) {
690 result.replace(result.length() - 1, 1, "\\s");
691 }
692 result.squeeze();
693
694 return result;
695}
696
697char KConfigIniBackend::charFromHex(const char *str, const QFile& file, int line)
698{
699 unsigned char ret = 0;
700 for (int i = 0; i < 2; i++) {
701 ret <<= 4;
702 quint8 c = quint8(str[i]);
703
704 if (c >= '0' && c <= '9') {
705 ret |= c - '0';
706 } else if (c >= 'a' && c <= 'f') {
707 ret |= c - 'a' + 0x0a;
708 } else if (c >= 'A' && c <= 'F') {
709 ret |= c - 'A' + 0x0a;
710 } else {
711 QByteArray e(str, 2);
712 e.prepend("\\x");
713 qWarning() << warningProlog(file, line) << "Invalid hex character " << c
714 << " in \\x<nn>-type escape sequence \"" << e.constData() << "\".";
715 return 'x';
716 }
717 }
718 return char(ret);
719}
720
721void KConfigIniBackend::printableToString(BufferFragment* aString, const QFile& file, int line)
722{
723 if (aString->isEmpty() || aString->indexOf('\\')==-1)
724 return;
725 aString->trim();
726 int l = aString->length();
727 char *r = aString->data();
728 char *str=r;
729
730 for(int i = 0; i < l; i++, r++) {
731 if (str[i]!= '\\') {
732 *r=str[i];
733 } else {
734 // Probable escape sequence
735 i++;
736 if (i >= l) { // Line ends after backslash - stop.
737 *r = '\\';
738 break;
739 }
740
741 switch(str[i]) {
742 case 's':
743 *r = ' ';
744 break;
745 case 't':
746 *r = '\t';
747 break;
748 case 'n':
749 *r = '\n';
750 break;
751 case 'r':
752 *r = '\r';
753 break;
754 case '\\':
755 *r = '\\';
756 break;
757 case 'x':
758 if (i + 2 < l) {
759 *r = charFromHex(str + i + 1, file, line);
760 i += 2;
761 } else {
762 *r = 'x';
763 i = l - 1;
764 }
765 break;
766 default:
767 *r = '\\';
768 qWarning() << warningProlog(file, line)
769 << QString::fromLatin1("Invalid escape sequence \"\\%1\".").arg(str[i]);
770 }
771 }
772 }
773 aString->truncate(r - aString->constData());
774}
bufferfragment_p.h
KComponentData
Per component data.
Definition: kcomponentdata.h:47
KConfigBackend
Provides the implementation for accessing configuration sources.
Definition: kconfigbackend.h:56
KConfigBackend::setLastModified
void setLastModified(const QDateTime &dt)
Definition: kconfigbackend.cpp:108
KConfigBackend::setSize
void setSize(qint64 sz)
Definition: kconfigbackend.cpp:118
KConfigBackend::setLocalFilePath
void setLocalFilePath(const QString &file)
Definition: kconfigbackend.cpp:128
KConfigBackend::WriteGlobal
@ WriteGlobal
Definition: kconfigbackend.h:103
KConfigBackend::filePath
QString filePath() const
Definition: kconfigbackend.cpp:123
KConfigBackend::ParseExpansions
@ ParseExpansions
entries should be marked as default
Definition: kconfigbackend.h:96
KConfigBackend::ParseGlobal
@ ParseGlobal
Definition: kconfigbackend.h:94
KConfigBackend::ParseDefaults
@ ParseDefaults
entries should be marked as global
Definition: kconfigbackend.h:95
KConfigBackend::ParseInfo
ParseInfo
Return value from parseConfig()
Definition: kconfigbackend.h:109
KConfigBackend::ParseOpenError
@ ParseOpenError
the configuration is immutable
Definition: kconfigbackend.h:112
KConfigBackend::ParseOk
@ ParseOk
Definition: kconfigbackend.h:110
KConfigBackend::ParseImmutable
@ ParseImmutable
the configuration was opened read/write
Definition: kconfigbackend.h:111
KConfigBase::AccessMode
AccessMode
Possible return values for accessMode().
Definition: kconfigbase.h:133
KConfigBase::NoAccess
@ NoAccess
Definition: kconfigbase.h:133
KConfigBase::ReadWrite
@ ReadWrite
Definition: kconfigbase.h:133
KConfigBase::ReadOnly
@ ReadOnly
Definition: kconfigbase.h:133
KConfigIniBackend::BufferFragment
Definition: bufferfragment_p.h:37
KConfigIniBackend::BufferFragment::data
char * data() const
Definition: bufferfragment_p.h:70
KConfigIniBackend::BufferFragment::truncateLeft
void truncateLeft(unsigned int size)
Definition: bufferfragment_p.h:109
KConfigIniBackend::BufferFragment::left
BufferFragment left(unsigned int size) const
Definition: bufferfragment_p.h:104
KConfigIniBackend::BufferFragment::clear
void clear()
Definition: bufferfragment_p.h:60
KConfigIniBackend::BufferFragment::truncate
void truncate(unsigned int pos)
Definition: bufferfragment_p.h:116
KConfigIniBackend::BufferFragment::length
int length() const
Definition: bufferfragment_p.h:49
KConfigIniBackend::BufferFragment::lastIndexOf
int lastIndexOf(char c) const
Definition: bufferfragment_p.h:160
KConfigIniBackend::BufferFragment::constData
const char * constData() const
Definition: bufferfragment_p.h:65
KConfigIniBackend::BufferFragment::mid
BufferFragment mid(unsigned int pos, int length=-1) const
Definition: bufferfragment_p.h:126
KConfigIniBackend::BufferFragment::trim
void trim()
Definition: bufferfragment_p.h:75
KConfigIniBackend::BufferFragment::split
BufferFragment split(char c, unsigned int *start)
Definition: bufferfragment_p.h:87
KConfigIniBackend::BufferFragment::isEmpty
bool isEmpty() const
Definition: bufferfragment_p.h:99
KConfigIniBackend::BufferFragment::indexOf
int indexOf(char c, unsigned int from=0) const
Definition: bufferfragment_p.h:150
KConfigIniBackend::BufferFragment::toVolatileByteArray
QByteArray toVolatileByteArray() const
Definition: bufferfragment_p.h:177
KConfigIniBackend::BufferFragment::toByteArray
QByteArray toByteArray() const
Definition: bufferfragment_p.h:171
KConfigIniBackend::BufferFragment::at
char at(unsigned int i) const
Definition: bufferfragment_p.h:54
KConfigIniBackend::printableToString
static void printableToString(BufferFragment *aString, const QFile &file, int line)
Definition: kconfigini.cpp:721
KConfigIniBackend::writeEntries
void writeEntries(const QByteArray &locale, QFile &file, const KEntryMap &map)
Definition: kconfigini.cpp:369
KConfigIniBackend::charFromHex
static char charFromHex(const char *str, const QFile &file, int line)
Definition: kconfigini.cpp:697
KConfigIniBackend::parseConfig
ParseInfo parseConfig(const QByteArray &locale, KEntryMap &entryMap, ParseOptions options)
Read persistent storage.
Definition: kconfigini.cpp:68
KConfigIniBackend::StringType
StringType
Definition: kconfigini_p.h:61
KConfigIniBackend::ValueString
@ ValueString
Definition: kconfigini_p.h:64
KConfigIniBackend::KeyString
@ KeyString
Definition: kconfigini_p.h:63
KConfigIniBackend::GroupString
@ GroupString
Definition: kconfigini_p.h:62
KConfigIniBackend::KConfigIniBackend
KConfigIniBackend()
Definition: kconfigini.cpp:58
KConfigIniBackend::setFilePath
void setFilePath(const QString &path)
Set the file path.
Definition: kconfigini.cpp:559
KConfigIniBackend::createEnclosing
void createEnclosing()
Create the enclosing object of the configuration object.
Definition: kconfigini.cpp:548
KConfigIniBackend::isLocked
bool isLocked() const
Definition: kconfigini.cpp:610
KConfigIniBackend::nonWritableErrorMessage
QString nonWritableErrorMessage() const
When isWritable() returns false, return an error message to explain to the user why saving configurat...
Definition: kconfigini.cpp:543
KConfigIniBackend::isWritable
bool isWritable() const
If isWritable() returns false, writeConfig() will always fail.
Definition: kconfigini.cpp:516
KConfigIniBackend::~KConfigIniBackend
~KConfigIniBackend()
Definition: kconfigini.cpp:63
KConfigIniBackend::writeConfig
bool writeConfig(const QByteArray &locale, KEntryMap &entryMap, WriteOptions options, const KComponentData &data)
Write the dirty entries to permanent storage.
Definition: kconfigini.cpp:380
KConfigIniBackend::stringToPrintable
static QByteArray stringToPrintable(const QByteArray &aString, StringType type)
Definition: kconfigini.cpp:615
KConfigIniBackend::accessMode
KConfigBase::AccessMode accessMode() const
Definition: kconfigini.cpp:580
KConfigIniBackend::warningProlog
static QString warningProlog(const QFile &file, int line)
Definition: kconfigini.cpp:52
KConfigIniBackend::lock
bool lock(const KComponentData &componentData)
Lock the file.
Definition: kconfigini.cpp:591
KConfigIniBackend::unlock
void unlock()
Release the lock on the file.
Definition: kconfigini.cpp:604
KEntryMap
type specifying a map of entries (key,value pairs).
Definition: kconfigdata.h:153
KEntryMap::getEntryOption
bool getEntryOption(const ConstIterator &it, EntryOption option) const
KEntryMap::EntryImmutable
@ EntryImmutable
Definition: kconfigdata.h:164
KEntryMap::EntryLocalized
@ EntryLocalized
Definition: kconfigdata.h:169
KEntryMap::EntryExpansion
@ EntryExpansion
Definition: kconfigdata.h:166
KEntryMap::EntryGlobal
@ EntryGlobal
Definition: kconfigdata.h:163
KEntryMap::EntryRawKey
@ EntryRawKey
Definition: kconfigdata.h:167
KEntryMap::EntryDeleted
@ EntryDeleted
Definition: kconfigdata.h:165
KEntryMap::EntryDefault
@ EntryDefault
Definition: kconfigdata.h:168
KEntryMap::setEntry
bool setEntry(const QByteArray &group, const QByteArray &key, const QByteArray &value, EntryOptions options)
Returns true if the entry gets dirtied or false in other case.
KLockFile
The KLockFile class provides NFS safe lockfiles.
Definition: klockfile.h:37
KLockFile::LockStale
@ LockStale
A stale lock has been detected.
Definition: klockfile.h:70
KLockFile::unlock
void unlock()
Release the lock.
Definition: klockfile_unix.cpp:487
KLockFile::lock
LockResult lock(LockFlags flags=LockFlags())
Attempt to acquire the lock.
Definition: klockfile_unix.cpp:386
KLockFile::isLocked
bool isLocked() const
Returns whether the lock is held or not.
Definition: klockfile_unix.cpp:482
KLockFile::ForceFlag
@ ForceFlag
Automatically remove a lock when a lock is detected that is stale for more than staleTime() seconds,...
Definition: klockfile.h:84
KSaveFile
Class to allow for atomic file I/O, as well as utility functions.
Definition: ksavefile.h:97
KSaveFile::finalize
bool finalize()
Finalize changes to the file.
Definition: ksavefile.cpp:219
KSaveFile::open
virtual bool open(OpenMode flags=QIODevice::ReadWrite)
Open the save file.
Definition: ksavefile.cpp:81
KSaveFile::abort
void abort()
Discard changes without affecting the target file.
Definition: ksavefile.cpp:204
KSharedPtr::clear
void clear()
Clear the pointer, i.e.
Definition: ksharedptr.h:220
KStandardDirs::checkAccess
static bool checkAccess(const QString &pathname, int mode)
Check, if a file may be accessed in a given mode.
Definition: kstandarddirs.cpp:2120
QDateTime
QHash
Definition: ksycocafactory.h:28
QList
Definition: kaboutdata.h:33
QString
kWarning
#define kWarning
Definition: kdebug.h:322
kconfig.h
kconfigbackend.h
kconfigdata.h
lookup
static QByteArray lookup(const KConfigIniBackend::BufferFragment &fragment, QHash< KConfigIniBackend::BufferFragment, QByteArray > *cache)
Definition: kconfigini.cpp:43
kde_kiosk_exception
bool kde_kiosk_exception
Definition: kcomponentdata.cpp:162
kconfigini_p.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
ksavefile.h
kstandarddirs.h
KEntryKey
key structure holding both the actual key and the group to which it belongs.
Definition: kconfigdata.h:90
KEntryKey::mKey
QByteArray mKey
The actual key of the entry in question.
Definition: kconfigdata.h:103
KEntryKey::bDefault
bool bDefault
Entry indicates if this is a default value.
Definition: kconfigdata.h:111
KEntryKey::bRaw
bool bRaw
Definition: kconfigdata.h:116
KEntryKey::mGroup
QByteArray mGroup
The "group" to which this EntryKey belongs.
Definition: kconfigdata.h:99
KEntryKey::bLocal
bool bLocal
Entry is localised or not.
Definition: kconfigdata.h:107
KEntry
map/dict/list config node entry.
Definition: kconfigdata.h:36
KEntry::bImmutable
bool bImmutable
Entry can not be modified.
Definition: kconfigdata.h:54
KEntry::bExpand
bool bExpand
Whether to apply dollar expansion or not.
Definition: kconfigdata.h:62
KEntry::bDeleted
bool bDeleted
Entry has been deleted.
Definition: kconfigdata.h:58
KEntry::mValue
QByteArray mValue
Definition: kconfigdata.h:42
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal